Commit f8ec916 ("Allow helpers to report in "list" command that the ref is unchanged", 2009-11-17) allowed a remote helper to report that a ref is unchanged even if it did not know the contents of a ref. However, that commit also made Git assume that such a remote ref has the contents of the local ref of the same name. If I'm not missing anything, this assumption seems wrong; the attached test illustrates one case of local edits being made after cloning with default parameters. The original e-mail thread [1] seems to indicate that this feature is meant for a remote helper with no Git-specific code (which is possible if it supports "import" but not "fetch" - in this case, it would not deal with SHA-1s at all) to nevertheless indicate "unchanged", most likely to support optimizations on the client side. But it seems to me that Git cannot perform this optimization. In other words, it should just ignore "unchanged". If this makes sense, I'll prepare a patch to do this. [1] "[PATCH 00/13] Native and foreign helpers" <alpine.LNX.2.00.0908050052390.2147@xxxxxxxxxxxx> --- git-remote-testgit.sh | 8 +++++++- t/t5801-remote-helpers.sh | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh index 752c763..6357868 100755 --- a/git-remote-testgit.sh +++ b/git-remote-testgit.sh @@ -52,7 +52,13 @@ do echo ;; list) - git for-each-ref --format='? %(refname)' 'refs/heads/' + if test -n "$GIT_REMOTE_TESTGIT_UNCHANGED_BRANCH_REGEX" + then + git for-each-ref --format='? %(refname)' 'refs/heads/' | + sed "/${GIT_REMOTE_TESTGIT_UNCHANGED_BRANCH_REGEX}/s/$/ unchanged/" + else + git for-each-ref --format='? %(refname)' 'refs/heads/' + fi head=$(git symbolic-ref HEAD) echo "@$head HEAD" echo diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 362b158..4a48f2b 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -301,4 +301,44 @@ test_expect_success 'fetch url' ' compare_refs server HEAD local FETCH_HEAD ' +test_expect_success 'setup remote repository and divergent clone' ' + git init s2 && + ( + cd s2 && + test_commit M1 && + git checkout -b mybranch && + test_commit B1 + ) && + git clone "testgit::${PWD}/s2" divergent && + + ( + cd divergent && + git checkout master && + test_commit M2 && + git checkout mybranch && + test_commit B2 + ) +' + +test_expect_success 'fetch with unchanged claims' ' + rm -rf local && + cp -r divergent local && + + # No unchanged branches + + GIT_REMOTE_TESTGIT_UNCHANGED_BRANCH_REGEX=ABCDE git -C local fetch && + compare_refs s2 M1 local refs/remotes/origin/master && + compare_refs s2 B1 local refs/remotes/origin/mybranch && + + # One unchanged branch + + GIT_REMOTE_TESTGIT_UNCHANGED_BRANCH_REGEX=mybranch git -C local fetch && + compare_refs s2 M1 local refs/remotes/origin/master && + + # I (Jonathan Tan) would expect refs/remotes/origin/mybranch to be B1, + # but it is B2. + test_must_fail compare_refs s2 B1 local refs/remotes/origin/mybranch && + compare_refs local B2 local refs/remotes/origin/mybranch +' + test_done -- 2.8.0.rc3.226.g39d4020