[PATCH 03/15] t5510: document fetch with "./"-prefixed branch.<name>.merge
- From
Jon Simons <jon@jonsimons.org>
- Date
- Oct 9, 2026, 19:29 UTC
- Message-ID
- <20261009192953.81794-4-jon@jonsimons.org>
- In-Reply-To
- <20261009192953.81794-1-jon@jonsimons.org>
refname_match() formats each candidate through mkpath(), which strips a leading "./", so a branch.<name>.merge value of "./refs/heads/main" matches "refs/heads/main" in both places that fetch compares them:
- branch_merge_matches() when marking fetched refs for merge in FETCH_HEAD
- find_ref_by_name_abbrev() when the merge source is not covered by the fetch refspec and is looked up amongst the remote advertised refs
Only a hand-edited config reaches these paths: clone, branch --set-upstream-to, fetch --set-upstream, and push -u write only names that have passed check_refname_format(), which rejects a leading "./".
Add two fetch tests asserting that such a "./"-prefixed value does not match for these cases. Both are test_expect_failure because the name matches today:
- The default fetch refspec should not match "./refs/heads/main" with fetched "refs/heads/main" and mark the ref for merge.
- A protocol v0 fetch with refspec that omits "refs/heads/main" should not match "./refs/heads/main" against the remote advertised "refs/heads/main".
An upcoming commit stops using mkpath() in refname_match(), at which point the tests are toggled to test_expect_success.
Signed-off-by: Jon Simons <jon@jonsimons.org> --- t/t5510-fetch.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 300bd5396d..0303784b1f 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -1074,6 +1074,50 @@ test_expect_success 'LHS of refspec follows ref disambiguation rules' ' ) ' +test_expect_failure 'fetch with "./"-prefixed branch.<name>.merge does not mark any ref for merge' ' + mkdir dotslash-merge-default-refspec && + ( + cd dotslash-merge-default-refspec && + git init -b main server && + test_commit -C server one && + git -C server branch other && + test_commit -C server two && + + # The bogus ./refs/heads/main should not match the remote refs/heads/main. + git clone server client && + git -C client config branch.main.merge ./refs/heads/main && + git -C client fetch && + { + echo "$(git -C server rev-parse main) not-for-merge" && + echo "$(git -C server rev-parse other) not-for-merge" + } >expect && + cut -f -2 client/.git/FETCH_HEAD >actual && + test_cmp expect actual + ) +' + +test_expect_failure 'fetch protocol v0 with "./"-prefixed branch.<name>.merge does not match any remote ref' ' + mkdir dotslash-merge-fetch-protocol-v0 && + ( + cd dotslash-merge-fetch-protocol-v0 && + git init -b main server && + test_commit -C server one && + git -C server branch other && + test_commit -C server two && + + # Omit refs/heads/main from the fetch refspec so that the merge + # source is instead looked up among the refs the remote advertised. + git clone server client-v0 && + git -C client-v0 config remote.origin.fetch \ + +refs/heads/other:refs/remotes/origin/other && + git -C client-v0 config branch.main.merge ./refs/heads/main && + git -C client-v0 -c protocol.version=0 fetch && + echo "$(git -C server rev-parse other) not-for-merge" >expect && + cut -f -2 client-v0/.git/FETCH_HEAD >actual && + test_cmp expect actual + ) +' + test_expect_success 'fetch.writeCommitGraph' ' git clone three write && (
-- 2.55.0