From 9840906026be807d0882f96396de3a3cdb9fb43e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 5 Jun 2007 16:58:13 +0100 Subject: [PATCH] filter-branch: fix behaviour of '-k' The option '-k' says that the given commit and _all_ of its ancestors are kept as-is. However, if a to-be-rewritten commit branched from an ancestor of an ancestor of a commit given with '-k', filter-branch would fail. Example: A - B \ C If filter-branch was called with '-k B -s C', it would actually keep B (and A as its parent), but would rewrite C, and its parent. Noticed by Johannes Sixt. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 29 +++++++++++++++++------------ t/t7003-filter-branch.sh | 9 +++++++++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 2929925a0..f2b0e273b 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -327,11 +327,6 @@ ret=0 mkdir ../map # map old->new commit ids for rewriting parents -# seed with identity mappings for the parents where we start off -for commit in $unchanged; do - echo $commit > ../map/$commit -done - git-rev-list --reverse --topo-order $srcbranch --not $unchanged >../revs commits=$(cat ../revs | wc -l | tr -d " ") @@ -372,7 +367,8 @@ while read commit; do parentstr="$parentstr -p $reparent" done else - die "assertion failed: parent $parent for commit $commit not found in rewritten ones" + # if it was not rewritten, take the original + parentstr="$parentstr -p $parent" fi done if [ "$filter_parent" ]; then @@ -385,12 +381,21 @@ while read commit; do tee ../map/$commit done <../revs -git-update-ref refs/heads/"$dstbranch" $(head -n 1 ../map/$(tail -n 1 ../revs)) -if [ "$(cat ../map/$(tail -n 1 ../revs) | wc -l)" -gt 1 ]; then - echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2 - sed 's/^/ /' ../map/$(tail -n 1 ../revs) >&2 - ret=1 -fi +src_head=$(tail -n 1 ../revs) +target_head=$(head -n 1 ../map/$src_head) +case "$target_head" in +'') + echo Nothing rewritten + ;; +*) + git-update-ref refs/heads/"$dstbranch" $target_head + if [ $(cat ../map/$src_head | wc -l) -gt 1 ]; then + echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2 + sed 's/^/ /' ../map/$src_head >&2 + ret=1 + fi + ;; +esac if [ "$filter_tag_name" ]; then git-for-each-ref --format='%(objectname) %(objecttype) %(refname)' refs/tags | diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index c82ff1d6e..6e2be5be0 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -45,4 +45,13 @@ test_expect_success 'test that the file was renamed' ' test d = $(git show H3:doh) ' +git tag oldD H3~4 +test_expect_success 'rewrite one branch, keeping a side branch' ' + git-filter-branch --tree-filter "mv b boh || :" -k D -s oldD modD +' + +test_expect_success 'common ancestor is still common (unchanged)' ' + test "$(git-merge-base modD D)" = "$(git-rev-parse B)" +' + test_done -- 2.30.2