path: root/Documentation/git-filter-branch.txt
diff options
authorJohannes Schindelin <>2007-07-23 17:34:13 (GMT)
committerJunio C Hamano <>2007-07-24 06:15:09 (GMT)
commitdfd05e38f07f76505158399cc433b0b1870a769a (patch)
treed2daafb585a03a6f988b4082e55941453c49b1b8 /Documentation/git-filter-branch.txt
parent3b38ec16d51a84bb5d4ef349f441de5f7ecd54f2 (diff)
filter-branch: Big syntax change; support rewriting multiple refs
We used to take the first non-option argument as the name for the new branch. This syntax is not extensible to support rewriting more than just HEAD. Instead, we now have the following syntax: git filter-branch [<filter options>...] [<rev-list options>] All positive refs given in <rev-list options> are rewritten. Yes, in-place. If a ref was changed, the original head is stored in refs/original/$ref now, for your inspecting pleasure, in addition to the reflogs (since it is easier to inspect "git show-ref | grep original" than to inspect all the reflogs). This commit also adds the --force option to remove .git-rewrite/ and all refs from refs/original/ before filtering. Signed-off-by: Johannes Schindelin <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'Documentation/git-filter-branch.txt')
1 files changed, 28 insertions, 23 deletions
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index eaea82d..915258f 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -12,7 +12,7 @@ SYNOPSIS
[--index-filter <command>] [--parent-filter <command>]
[--msg-filter <command>] [--commit-filter <command>]
[--tag-name-filter <command>] [--subdirectory-filter <directory>]
- [-d <directory>] <new-branch-name> [<rev-list options>...]
+ [-d <directory>] [-f | --force] [<rev-list options>...]
@@ -26,10 +26,9 @@ information) will be preserved.
The command takes the new branch name as a mandatory argument and
the filters as optional arguments. If you specify no filters, the
commits will be recommitted without any changes, which would normally
-have no effect and result in the new branch pointing to the same
-branch as your current branch. Nevertheless, this may be useful in
-the future for compensating for some git bugs or such, therefore
-such a usage is permitted.
+have no effect. Nevertheless, this may be useful in the future for
+compensating for some git bugs or such, therefore such a usage is
*WARNING*! The rewritten history will have different object names for all
the objects and will not converge with the original branch. You will not
@@ -38,8 +37,9 @@ original branch. Please do not use this command if you do not know the
full implications, and avoid using it anyway, if a simple single commit
would suffice to fix your problem.
-Always verify that the rewritten version is correct before disposing
-the original branch.
+Always verify that the rewritten version is correct: The original refs,
+if different from the rewritten ones, will be stored in the namespace
Note that since this operation is extensively I/O expensive, it might
be a good idea to redirect the temporary directory off-disk, e.g. on
@@ -142,6 +142,11 @@ definition impossible to preserve signatures at any rate.)
does this in the '.git-rewrite/' directory but you can override
that choice by this parameter.
+ `git filter-branch` refuses to start with an existing temporary
+ directory or when there are already refs starting with
+ 'refs/original/', unless forced.
When options are given after the new branch name, they will
be passed to gitlink:git-rev-list[1]. Only commits in the resulting
@@ -156,14 +161,14 @@ Suppose you want to remove a file (containing confidential information
or copyright violation) from all commits:
-git filter-branch --tree-filter 'rm filename' newbranch
+git filter-branch --tree-filter 'rm filename' HEAD
A significantly faster version:
-git filter-branch --index-filter 'git update-index --remove filename' newbranch
+git filter-branch --index-filter 'git update-index --remove filename' HEAD
Now, you will get the rewritten history saved in the branch 'newbranch'
(your current branch is left untouched).
@@ -172,25 +177,25 @@ To set a commit (which typically is at the tip of another
history) to be the parent of the current initial commit, in
order to paste the other history behind the current history:
-git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' newbranch
+git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD
(if the parent string is empty - therefore we are dealing with the
initial commit - add graftcommit as a parent). Note that this assumes
history with a single root (that is, no merge without common ancestors
happened). If this is not the case, use:
git filter-branch --parent-filter \
- 'cat; test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>"' newbranch
+ 'cat; test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>"' HEAD
or even simpler:
echo "$commit-id $graft-id" >> .git/info/grafts
-git filter-branch newbranch $graft-id..
+git filter-branch $graft-id..HEAD
To remove commits authored by "Darl McBribe" from the history:
@@ -208,7 +213,7 @@ git filter-branch --commit-filter '
git commit-tree "$@";
- fi' newbranch
+ fi' HEAD
The shift magic first throws away the tree id and then the -p
@@ -238,14 +243,14 @@ A--B-----C
To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use:
-git filter-branch ... new-H C..H
+git filter-branch ... C..H
To rewrite commits E,F,G,H, use one of these:
-git filter-branch ... new-H C..H --not D
-git filter-branch ... new-H D..H --not C
+git filter-branch ... C..H --not D
+git filter-branch ... D..H --not C
To move the whole tree into a subdirectory, or remove it from there:
@@ -255,7 +260,7 @@ git filter-branch --index-filter \
'git ls-files -s | sed "s-\t-&newsubdir/-" |
git update-index --index-info &&
- mv $ $GIT_INDEX_FILE' directorymoved