From 6d875d19fd7346f4a6dc47d2a1363db91e9643d5 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 10 Mar 2021 12:07:19 -0500 Subject: t7003: test ref rewriting explicitly After it has rewritten all of the commits, filter-branch will then rewrite each of the input refs based on the resulting map of old/new commits. But we don't have any explicit test coverage of this code. Let's make sure we are covering each of those cases: - deleting a ref when all of its commits were pruned - rewriting a ref based on the mapping (this happens throughout the script, but let's make sure we generate the correct messages) - rewriting a ref whose tip was excluded, in which case we rewrite to the nearest ancestor. Note in this case that we still insist that no "warning" line is present (even though it looks like we'd trigger the "... was rewritten into multiple commits" one). See the next commit for more details. Note these all pass currently, but the latter two will fail when run with GIT_TEST_DEFAULT_HASH=sha256. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 36477cb1f4..a47324f664 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -503,4 +503,35 @@ test_expect_success 'rewrite repository including refs that point at non-commit ! fgrep fatal filter-output ' +test_expect_success 'filter-branch handles ref deletion' ' + git switch --orphan empty-commit && + git commit --allow-empty -m "empty commit" && + git tag empty && + git branch to-delete && + git filter-branch -f --prune-empty to-delete >out 2>&1 && + grep "to-delete.*was deleted" out && + test_must_fail git rev-parse --verify to-delete +' + +test_expect_success 'filter-branch handles ref rewrite' ' + git checkout empty && + test_commit to-drop && + git branch rewrite && + git filter-branch -f \ + --index-filter "git rm --ignore-unmatch --cached to-drop.t" \ + rewrite >out 2>&1 && + grep "rewrite.*was rewritten" out && + ! grep -i warning out && + git diff-tree empty rewrite +' + +test_expect_success 'filter-branch handles ancestor rewrite' ' + test_commit to-exclude && + git branch ancestor && + git filter-branch -f ancestor -- :^to-exclude.t >out 2>&1 && + grep "ancestor.*was rewritten" out && + ! grep -i warning out && + git diff-tree HEAD^ ancestor +' + test_done -- cgit v1.2.3 From 98fe9e666fe4a595cf5396fd8d5c57b380c782b2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 10 Mar 2021 12:07:27 -0500 Subject: filter-branch: drop multiple-ancestor warning When a ref maps to a commit that is neither rewritten nor kept by filter-branch (e.g., because it was eliminated by rev-list's pathspec selection), we rewrite it to its nearest ancestor. Since the initial commit in 6f6826c52b (Add git-filter-branch, 2007-06-03), we have warned when there are multiple such ancestors in the map file. However, the warning code is impossible to trigger these days. Since a0e46390d3 (filter-branch: fix ref rewriting with --subdirectory-filter, 2008-08-12), we find the ancestor using "rev-list -1", so it can only ever have a single value. This code is made doubly confusing by the fact that we append to the map file when mapping ancestors. However, this can never yield multiple values because: - we explicitly check whether the map already exists, and if so, do nothing (so our "append" will always be to a file that does not exist) - even if we were to try mapping twice, the process to do so is deterministic. I.e., we'd always end up with the same ancestor for a given sha1. So warning about it would be pointless; there is no ambiguity. So swap out the warning code for a BUG (which we'll simplify further in the next commit). And let's stop using the append operator to make the ancestor-mapping code less confusing. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/git-filter-branch.sh b/git-filter-branch.sh index fea7964617..a1e80bd552 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -492,7 +492,7 @@ then sha1=$(git rev-parse "$ref"^0) test -f "$workdir"/../map/$sha1 && continue ancestor=$(git rev-list --simplify-merges -1 "$ref" "$@") - test "$ancestor" && echo $(map $ancestor) >> "$workdir"/../map/$sha1 + test "$ancestor" && echo $(map $ancestor) >"$workdir"/../map/$sha1 done < "$tempdir"/heads fi @@ -534,14 +534,7 @@ do fi ;; *) - # NEEDSWORK: possibly add -Werror, making this an error - warn "WARNING: '$ref' was rewritten into multiple commits:" - warn "$rewritten" - warn "WARNING: Ref '$ref' points to the first one now." - rewritten=$(echo "$rewritten" | head -n 1) - git update-ref -m "filter-branch: rewrite to first" \ - "$ref" $rewritten $sha1 || - die "Could not rewrite $ref" + die "BUG: multiple ancestors in map file?" ;; esac git update-ref -m "filter-branch: backup" "$orig_namespace$ref" $sha1 || -- cgit v1.2.3 From 42efa1231aee85932058cc6d1571ab4ceb3e7eff Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 10 Mar 2021 12:07:37 -0500 Subject: filter-branch: drop $_x40 glob When checking whether a commit was rewritten to a single object id, we use a glob that insists on a 40-hex result. This works for sha1, but fails t7003 when run with GIT_TEST_DEFAULT_HASH=sha256. Since the previous commit simplified the case statement here, we only have two arms: an empty string or a single object id. We can just loosen our glob to match anything, and still distinguish those cases (we lose the ability to notice bogus input, but that's not a problem; we are the one who wrote the map in the first place, and anyway update-ref will complain loudly if the input isn't a valid hash). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/git-filter-branch.sh b/git-filter-branch.sh index a1e80bd552..cb89372813 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -498,8 +498,6 @@ fi # Finally update the refs -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" echo while read ref do @@ -519,7 +517,7 @@ do git update-ref -m "filter-branch: delete" -d "$ref" $sha1 || die "Could not delete $ref" ;; - $_x40) + *) echo "Ref '$ref' was rewritten" if ! git update-ref -m "filter-branch: rewrite" \ "$ref" $rewritten $sha1 2>/dev/null; then @@ -533,9 +531,6 @@ do fi fi ;; - *) - die "BUG: multiple ancestors in map file?" - ;; esac git update-ref -m "filter-branch: backup" "$orig_namespace$ref" $sha1 || exit -- cgit v1.2.3