From 6f6826c52bb751450e2bfa28f07c817dfa5802d6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Jun 2007 01:31:28 +0100 Subject: Add git-filter-branch This script is derived from Pasky's cg-admin-rewritehist. In fact, it _is_ the same script, minimally adapted to work without cogito. It _should_ be able to perform the same tasks, even if only relying on core-git programs. All the work is Pasky's, just the adaption is mine. Signed-off-by: Johannes Schindelin Hopefully-signed-off-by: Petr "cogito master" Baudis Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100755 t/t7003-filter-branch.sh (limited to 't') diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh new file mode 100755 index 0000000000..9a4dae44f2 --- /dev/null +++ b/t/t7003-filter-branch.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +test_description='git-filter-branch' +. ./test-lib.sh + +make_commit () { + lower=$(echo $1 | tr A-Z a-z) + echo $lower > $lower + git add $lower + git commit -m $1 + git tag $1 +} + +test_expect_success 'setup' ' + make_commit A + make_commit B + git checkout -b branch B + make_commit D + make_commit E + git checkout master + make_commit C + git checkout branch + git merge C + git tag F + make_commit G + make_commit H +' + +H=$(git-rev-parse H) + +test_expect_success 'rewrite identically' ' + git-filter-branch H2 +' + +test_expect_success 'result is really identical' ' + test $H = $(git-rev-parse H2) +' + +test_expect_success 'rewrite, renaming a specific file' ' + git-filter-branch --tree-filter "mv d doh || :" H3 +' + +test_expect_success 'test that the file was renamed' ' + test d = $(git show H3:doh) +' + +test_done -- cgit v1.2.3 From aee078bf81d5810cb461e86950f6807d2d45befa Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 5 Jun 2007 00:07:31 -0700 Subject: t7003: make test repeatable Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 1 + 1 file changed, 1 insertion(+) (limited to 't') diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 9a4dae44f2..c82ff1d6e9 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -7,6 +7,7 @@ make_commit () { lower=$(echo $1 | tr A-Z a-z) echo $lower > $lower git add $lower + test_tick git commit -m $1 git tag $1 } -- cgit v1.2.3 From 9840906026be807d0882f96396de3a3cdb9fb43e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 5 Jun 2007 16:58:13 +0100 Subject: 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 --- t/t7003-filter-branch.sh | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 't') diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index c82ff1d6e9..6e2be5be0e 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 -- cgit v1.2.3 From 2766ce28150597677bb91c424e6033a298c71510 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 6 Jun 2007 09:43:41 +0200 Subject: filter-branch: Use rev-list arguments to specify revision ranges. A subset of commits in a branch used to be specified by options (-k, -r) as well as the branch tip itself (-s). It is more natural (for git users) to specify revision ranges like 'master..next' instead. This makes it so. If no range is specified it defaults to 'HEAD'. As a consequence, the new name of the filtered branch must be the first non-option argument. All remaining arguments are passed to 'git rev-list' unmodified. The tip of the branch that gets filtered is implied: It is the first commit that git rev-list would print for the specified range. Signed-off-by: Johannes Sixt Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 6e2be5be0e..3739cb191d 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -47,7 +47,7 @@ test_expect_success 'test that the file was renamed' ' 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 + git-filter-branch --tree-filter "mv b boh || :" modD D..oldD ' test_expect_success 'common ancestor is still common (unchanged)' ' -- cgit v1.2.3 From 685ef546b62d063c72b401cd38b83a879301aac4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 8 Jun 2007 01:30:35 +0100 Subject: Teach filter-branch about subdirectory filtering With git-filter-branch --subdirectory-filter you can get at the history, as seen by a certain subdirectory. The history of the rewritten branch will only contain commits that touched that subdirectory, and the subdirectory will be rewritten to be the new project root. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 't') diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 3739cb191d..292b83766d 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -54,4 +54,28 @@ test_expect_success 'common ancestor is still common (unchanged)' ' test "$(git-merge-base modD D)" = "$(git-rev-parse B)" ' +test_expect_success 'filter subdirectory only' ' + mkdir subdir && + touch subdir/new && + git add subdir/new && + test_tick && + git commit -m "subdir" && + echo H > a && + test_tick && + git commit -m "not subdir" a && + echo A > subdir/new && + test_tick && + git commit -m "again subdir" subdir/new && + git rm a && + test_tick && + git commit -m "again not subdir" && + git-filter-branch --subdirectory-filter subdir sub +' + +test_expect_success 'subdirectory filter result looks okay' ' + test 2 = $(git-rev-list sub | wc -l) && + git show sub:new && + ! git show sub:subdir +' + test_done -- cgit v1.2.3 From cfabd6eee1745cfec58cfcb794ce8847e43b888a Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 8 Jun 2007 23:28:50 +0200 Subject: filter-branch: subdirectory filter needs --full-history When two branches are merged that modify a subdirectory (possibly in different intermediate steps) such that both end up identical, then rev-list chooses only one branch. But when we filter history, we want to keep both branches. Therefore, we must use --full-history. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 't') diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 292b83766d..0fabe4904f 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -78,4 +78,25 @@ test_expect_success 'subdirectory filter result looks okay' ' ! git show sub:subdir ' +test_expect_success 'setup and filter history that requires --full-history' ' + git checkout master && + mkdir subdir && + echo A > subdir/new && + git add subdir/new && + test_tick && + git commit -m "subdir on master" subdir/new && + git rm a && + test_tick && + git commit -m "again subdir on master" && + git merge branch && + git-filter-branch --subdirectory-filter subdir sub-master +' + +test_expect_success 'subdirectory filter result looks okay' ' + test 3 = $(git-rev-list -1 --parents sub-master | wc -w) && + git show sub-master^:new && + git show sub-master^2:new && + ! git show sub:subdir +' + test_done -- cgit v1.2.3