diff --git a/.github/workflows/check-style.yml b/.github/workflows/check-style.yml index 108a2de903310c..b265fe35cbfc51 100644 --- a/.github/workflows/check-style.yml +++ b/.github/workflows/check-style.yml @@ -20,7 +20,7 @@ jobs: jobname: ClangFormat runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 with: fetch-depth: 0 diff --git a/.github/workflows/check-whitespace.yml b/.github/workflows/check-whitespace.yml index ea6f49f742108e..3379f89a814abd 100644 --- a/.github/workflows/check-whitespace.yml +++ b/.github/workflows/check-whitespace.yml @@ -19,7 +19,7 @@ jobs: check-whitespace: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 with: fetch-depth: 0 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 205325eb33b064..44337a67422e01 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -63,7 +63,7 @@ jobs: echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT - name: skip if the commit or tree was already tested id: skip-if-redundant - uses: actions/github-script@v9 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 if: steps.check-ref.outputs.enabled == 'yes' with: github-token: ${{secrets.GITHUB_TOKEN}} @@ -112,8 +112,10 @@ jobs: group: windows-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2.2.1 + with: + architecture: mingw64 - name: build shell: bash env: @@ -123,7 +125,7 @@ jobs: - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: windows-artifacts path: artifacts @@ -140,14 +142,16 @@ jobs: cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - name: download tracked files and build artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: windows-artifacts path: ${{github.workspace}} - name: extract tracked files and build artifacts shell: bash run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2.2.1 + with: + architecture: mingw64 - name: test shell: bash run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10 @@ -157,7 +161,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: failed-tests-windows-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -173,20 +177,22 @@ jobs: group: vs-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2.2.1 + with: + architecture: mingw64 - name: initialize vcpkg - uses: actions/checkout@v6 + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 with: repository: 'microsoft/vcpkg' path: 'compat/vcbuild/vcpkg' - name: download vcpkg artifacts - uses: git-for-windows/get-azure-pipelines-artifact@v0 + uses: git-for-windows/get-azure-pipelines-artifact@2e424b98e1251b725d6064c5f1a9f854a33e5b88 # v0 with: repository: git/git definitionId: 9 - name: add msbuild to PATH - uses: microsoft/setup-msbuild@v3 + uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3 - name: copy dlls to root shell: cmd run: compat\vcbuild\vcpkg_copy_dlls.bat release @@ -208,7 +214,7 @@ jobs: - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: vs-artifacts path: artifacts @@ -224,9 +230,11 @@ jobs: group: vs-test-${{ matrix.nr }}-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2.2.1 + with: + architecture: mingw64 - name: download tracked files and build artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: vs-artifacts path: ${{github.workspace}} @@ -244,7 +252,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: failed-tests-windows-vs-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -258,8 +266,8 @@ jobs: group: windows-meson-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 - name: Set up dependencies shell: pwsh run: pip install meson ninja @@ -270,7 +278,7 @@ jobs: shell: pwsh run: meson compile -C build - name: Upload build artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: windows-meson-artifacts path: build @@ -286,13 +294,13 @@ jobs: group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 - name: Set up dependencies shell: pwsh run: pip install meson ninja - name: Download build artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: windows-meson-artifacts path: build @@ -305,7 +313,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: failed-tests-windows-meson-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -341,7 +349,7 @@ jobs: TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t runs-on: ${{matrix.vector.pool}} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - run: ci/install-dependencies.sh - run: ci/run-build-and-tests.sh - name: print test failures @@ -349,7 +357,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -362,7 +370,7 @@ jobs: CI_JOB_IMAGE: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - run: ci/install-dependencies.sh - run: ci/run-build-and-minimal-fuzzers.sh dockerized: @@ -411,9 +419,9 @@ jobs: # A RHEL 8 compatible distro. Supported until 2029-05-31. - jobname: almalinux-8 image: almalinux:8 - # Supported until 2026-08-31. - - jobname: debian-11 - image: debian:11 + # Supported until 2028-06-30. + - jobname: debian-12 + image: debian:12 env: jobname: ${{matrix.vector.jobname}} CC: ${{matrix.vector.cc}} @@ -441,7 +449,7 @@ jobs: else apt-get -q update && apt-get -q -y install git fi - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - run: ci/install-dependencies.sh - run: useradd builder --create-home - run: chown -R builder . @@ -451,7 +459,7 @@ jobs: run: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -466,7 +474,7 @@ jobs: group: static-analysis-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - run: ci/install-dependencies.sh - run: ci/run-static-analysis.sh - run: ci/check-directional-formatting.bash @@ -482,7 +490,7 @@ jobs: group: rust-analysis-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - run: ci/install-dependencies.sh - run: ci/run-rust-checks.sh sparse: @@ -496,7 +504,7 @@ jobs: group: sparse-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - name: Install other dependencies run: ci/install-dependencies.sh - run: make sparse @@ -512,6 +520,6 @@ jobs: CI_JOB_IMAGE: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - run: ci/install-dependencies.sh - run: ci/test-documentation.sh diff --git a/fetch-pack.c b/fetch-pack.c index 5d0296f970e464..21dbe93307907e 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -2143,10 +2143,14 @@ struct ref *fetch_pack(struct fetch_pack_args *args, enum protocol_version version) { struct ref *ref_cpy; + struct ref **original_sought; + int original_nr_sought = nr_sought; + int i; struct shallow_info si; struct oid_array shallows_scratch = OID_ARRAY_INIT; fetch_pack_setup(); + DUP_ARRAY(original_sought, sought, nr_sought); if (nr_sought) nr_sought = remove_duplicates_in_refs(sought, nr_sought); @@ -2166,6 +2170,19 @@ struct ref *fetch_pack(struct fetch_pack_args *args, ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, &si, pack_lockfiles); } + + /* + * Callers can use distinct ref objects for FETCH_HEAD and each tracking + * destination. A wanted-refs response updates the deduplicated entry; + * propagate its object ID to every original entry before callers use it. + */ + for (i = 0; i < original_nr_sought; i++) { + struct ref **found = bsearch(original_sought[i]->name, sought, + nr_sought, sizeof(*sought), cmp_name_ref); + if (found) + oidcpy(&original_sought[i]->old_oid, &(*found)->old_oid); + } + free(original_sought); odb_reprepare(the_repository->objects); if (!args->cloning && args->deepen) { diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 330d049b2c05b5..ab4575d67ec19e 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -522,6 +522,104 @@ test_expect_success PERL_TEST_HELPERS 'server is initially behind - ref in want' test_cmp expected actual ' +test_expect_success PERL_TEST_HELPERS 'moving want-ref updates FETCH_HEAD and tracking ref' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency main "main^" && + git -C local fetch origin main && + + git -C "$REPO" rev-parse main main >expected && + git -C local rev-parse FETCH_HEAD refs/remotes/origin/main >actual && + test_cmp expected actual +' + +test_expect_success PERL_TEST_HELPERS 'moving want-ref updates every mapped destination' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency main "main^" && + git -C local fetch origin main:refs/heads/actual main:refs/heads/extra && + + git -C "$REPO" rev-parse main main main main >expected && + git -C local rev-parse FETCH_HEAD refs/heads/actual refs/heads/extra \ + refs/remotes/origin/main >actual && + test_cmp expected actual +' + +test_expect_success PERL_TEST_HELPERS 'moving want-ref without a tracking mapping' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + git -C local config remote.origin.fetch "+refs/heads/other:refs/remotes/origin/other" && + git -C local rev-parse refs/remotes/origin/main >before && + inconsistency main "main^" && + git -C local fetch origin main && + + git -C "$REPO" rev-parse main >expected && + git -C local rev-parse FETCH_HEAD >actual && + test_cmp expected actual && + git -C local rev-parse refs/remotes/origin/main >after && + test_cmp before after +' + +test_expect_success PERL_TEST_HELPERS 'moving ref without ref-in-want keeps the discovery OID' ' + git -C "$REPO" config uploadpack.allowRefInWant false && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency main "main^" && + git -C local fetch origin main && + + git -C "$REPO" rev-parse "main^" "main^" >expected && + git -C local rev-parse FETCH_HEAD refs/remotes/origin/main >actual && + test_cmp expected actual +' + +test_expect_success PERL_TEST_HELPERS 'setup a divergent ref' ' + git -C "$REPO" checkout -b divergent "main~2" && + test_commit -C "$REPO" divergent-tip && + git -C "$REPO" tag -d divergent-tip && + git -C "$REPO" checkout main +' + +test_expect_success PERL_TEST_HELPERS 'moving want-ref does not require the discovery object' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + discovery=$(git -C "$REPO" rev-parse "main^") && + test_must_fail git -C local cat-file -e "$discovery" && + inconsistency divergent "main^" && + git -C local fetch origin divergent && + + git -C "$REPO" rev-parse divergent divergent >expected && + git -C local rev-parse FETCH_HEAD refs/remotes/origin/divergent >actual && + test_cmp expected actual && + test_must_fail git -C local cat-file -e "$discovery" && + git -C local fsck --no-dangling +' + +test_expect_success PERL_TEST_HELPERS 'moving want-refs update their own tracking refs' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + main=$(git -C "$REPO" rev-parse main) && + divergent=$(git -C "$REPO" rev-parse divergent) && + discovery=$(git -C "$REPO" rev-parse "main^") && + write_script "$HTTPD_ROOT_PATH/one-time-script" <<-EOF && + sed -e "s/$main/$discovery/" -e "s/$divergent/$discovery/" "\$1" + EOF + git -C local fetch origin main divergent && + + git -C "$REPO" rev-parse main divergent >expected && + git -C local rev-parse refs/remotes/origin/main \ + refs/remotes/origin/divergent >actual && + test_cmp expected actual && + sort expected >expected_heads && + cut -f1 local/.git/FETCH_HEAD | sort >actual_heads && + test_cmp expected_heads actual_heads && + git -C local fsck --no-dangling +' + test_expect_success PERL_TEST_HELPERS 'server loses a ref - ref in want' ' git -C "$REPO" config uploadpack.allowRefInWant true && rm -rf local &&