1GIT-FILTER-BRANCH(1) Git Manual GIT-FILTER-BRANCH(1)
2
3
4
6 git-filter-branch - Rewrite branches
7
9 git-filter-branch [--env-filter <command>] [--tree-filter <command>]
10 [--index-filter <command>] [--parent-filter <command>]
11 [--msg-filter <command>] [--commit-filter <command>]
12 [--tag-name-filter <command>] [--subdirectory-filter <directory>]
13 [--original <namespace>] [-d <directory>] [-f | --force]
14 [<rev-list options>...]
15
17 Lets you rewrite git revision history by rewriting the branches
18 mentioned in the <rev-list options>, applying custom filters on each
19 revision. Those filters can modify each tree (e.g. removing a file or
20 running a perl rewrite on all files) or information about each commit.
21 Otherwise, all information (including original commit times or merge
22 information) will be preserved.
23
24 The command will only rewrite the positive refs mentioned in the
25 command line (i.e. if you pass a..b, only b will be rewritten). If you
26 specify no filters, the commits will be recommitted without any
27 changes, which would normally have no effect. Nevertheless, this may be
28 useful in the future for compensating for some git bugs or such,
29 therefore such a usage is permitted.
30
31 WARNING! The rewritten history will have different object names for all
32 the objects and will not converge with the original branch. You will
33 not be able to easily push and distribute the rewritten branch on top
34 of the original branch. Please do not use this command if you do not
35 know the full implications, and avoid using it anyway, if a simple
36 single commit would suffice to fix your problem.
37
38 Always verify that the rewritten version is correct: The original refs,
39 if different from the rewritten ones, will be stored in the namespace
40 refs/original/.
41
42 Note that since this operation is extensively I/O expensive, it might
43 be a good idea to redirect the temporary directory off-disk with the -d
44 option, e.g. on tmpfs. Reportedly the speedup is very noticeable.
45
46 Filters
47 The filters are applied in the order as listed below. The <command>
48 argument is always evaluated in shell using the eval command (with the
49 notable exception of the commit filter, for technical reasons). Prior
50 to that, the $GIT_COMMIT environment variable will be set to contain
51 the id of the commit being rewritten. Also, GIT_AUTHOR_NAME,
52 GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME,
53 GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE are set according to the
54 current commit.
55
56 A map function is available that takes an "original sha1 id" argument
57 and outputs a "rewritten sha1 id" if the commit has been already
58 rewritten, and "original sha1 id" otherwise; the map function can
59 return several ids on separate lines if your commit filter emitted
60 multiple commits.
61
63 --env-filter <command>
64 This is the filter for modifying the environment in which the
65 commit will be performed. Specifically, you might want to rewrite
66 the author/committer name/email/time environment variables (see
67 git-commit(1) for details). Do not forget to re-export the
68 variables.
69
70 --tree-filter <command>
71 This is the filter for rewriting the tree and its contents. The
72 argument is evaluated in shell with the working directory set to
73 the root of the checked out tree. The new tree is then used as-is
74 (new files are auto-added, disappeared files are auto-removed -
75 neither .gitignore files nor any other ignore rules HAVE ANY
76 EFFECT!).
77
78 --index-filter <command>
79 This is the filter for rewriting the index. It is similar to the
80 tree filter but does not check out the tree, which makes it much
81 faster. For hairy cases, see git-update-index(1).
82
83 --parent-filter <command>
84 This is the filter for rewriting the commit´s parent list. It will
85 receive the parent string on stdin and shall output the new parent
86 string on stdout. The parent string is in a format accepted by git-
87 commit-tree(1): empty for the initial commit, "-p parent" for a
88 normal commit and "-p parent1 -p parent2 -p parent3 ..." for a
89 merge commit.
90
91 --msg-filter <command>
92 This is the filter for rewriting the commit messages. The argument
93 is evaluated in the shell with the original commit message on
94 standard input; its standard output is used as the new commit
95 message.
96
97 --commit-filter <command>
98 This is the filter for performing the commit. If this filter is
99 specified, it will be called instead of the git-commit-tree(1)
100 command, with arguments of the form "<TREE_ID> [-p
101 <PARENT_COMMIT_ID>]..." and the log message on stdin. The commit id
102 is expected on stdout.
103
104 As a special extension, the commit filter may emit multiple commit
105 ids; in that case, ancestors of the original commit will have all
106 of them as parents.
107
108 You can use the map convenience function in this filter, and other
109 convenience functions, too. For example, calling skip_commit "$@"
110 will leave out the current commit (but not its changes! If you want
111 that, use git-rebase(1) instead).
112
113 --tag-name-filter <command>
114 This is the filter for rewriting tag names. When passed, it will be
115 called for every tag ref that points to a rewritten object (or to a
116 tag object which points to a rewritten object). The original tag
117 name is passed via standard input, and the new tag name is expected
118 on standard output.
119
120 The original tags are not deleted, but can be overwritten; use
121 "--tag-name-filter cat" to simply update the tags. In this case, be
122 very careful and make sure you have the old tags backed up in case
123 the conversion has run afoul.
124
125 Note that there is currently no support for proper rewriting of tag
126 objects; in layman terms, if the tag has a message or signature
127 attached, the rewritten tag won´t have it. Sorry. (It is by
128 definition impossible to preserve signatures at any rate.)
129
130 --subdirectory-filter <directory>
131 Only look at the history which touches the given subdirectory. The
132 result will contain that directory (and only that) as its project
133 root.
134
135 --original <namespace>
136 Use this option to set the namespace where the original commits
137 will be stored. The default value is refs/original.
138
139 -d <directory>
140 Use this option to set the path to the temporary directory used for
141 rewriting. When applying a tree filter, the command needs to
142 temporary checkout the tree to some directory, which may consume
143 considerable space in case of large projects. By default it does
144 this in the .git-rewrite/ directory but you can override that
145 choice by this parameter.
146
147 -f\|--force
148 git filter-branch refuses to start with an existing temporary
149 directory or when there are already refs starting with
150 refs/original/, unless forced.
151
152 <rev-list-options>
153 When options are given after the new branch name, they will be
154 passed to git-rev-list(1). Only commits in the resulting output
155 will be filtered, although the filtered commits can still reference
156 parents which are outside of that set.
157
159 Suppose you want to remove a file (containing confidential information
160 or copyright violation) from all commits:
161
162
163
164 git filter-branch --tree-filter ´rm filename´ HEAD
165
166 A significantly faster version:
167
168
169
170 git filter-branch --index-filter ´git update-index --remove filename´ HEAD
171
172 Now, you will get the rewritten history saved in the branch newbranch
173 (your current branch is left untouched).
174
175 To set a commit (which typically is at the tip of another history) to
176 be the parent of the current initial commit, in order to paste the
177 other history behind the current history:
178
179
180
181 git filter-branch --parent-filter ´sed "s/^\$/-p <graft-id>/"´ HEAD
182
183 (if the parent string is empty - which happens when we are dealing with
184 the initial commit - add graftcommit as a parent). Note that this
185 assumes history with a single root (that is, no merge without common
186 ancestors happened). If this is not the case, use:
187
188
189
190 git filter-branch --parent-filter \
191 ´cat; test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>"´ HEAD
192
193 or even simpler:
194
195
196
197 echo "$commit-id $graft-id" >> .git/info/grafts
198 git filter-branch $graft-id..HEAD
199
200 To remove commits authored by "Darl McBribe" from the history:
201
202
203
204 git filter-branch --commit-filter ´
205 if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
206 then
207 skip_commit "$@";
208 else
209 git commit-tree "$@";
210 fi´ HEAD
211
212 The function skip_commits is defined as follows:
213
214
215
216 skip_commit()
217 {
218 shift;
219 while [ -n "$1" ];
220 do
221 shift;
222 map "$1";
223 shift;
224 done;
225 }
226
227 The shift magic first throws away the tree id and then the -p
228 parameters. Note that this handles merges properly! In case Darl
229 committed a merge between P1 and P2, it will be propagated properly and
230 all children of the merge will become merge commits with P1,P2 as their
231 parents instead of the merge commit.
232
233 To restrict rewriting to only part of the history, specify a revision
234 range in addition to the new branch name. The new branch name will
235 point to the top-most revision that a git rev-list of this range will
236 print.
237
238 NOTE the changes introduced by the commits, and which are not reverted
239 by subsequent commits, will still be in the rewritten branch. If you
240 want to throw out changes together with the commits, you should use the
241 interactive mode of git-rebase(1).
242
243 Consider this history:
244
245
246
247 D--E--F--G--H
248 / /
249 A--B-----C
250
251 To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use:
252
253
254
255 git filter-branch ... C..H
256
257 To rewrite commits E,F,G,H, use one of these:
258
259
260
261 git filter-branch ... C..H --not D
262 git filter-branch ... D..H --not C
263
264 To move the whole tree into a subdirectory, or remove it from there:
265
266
267
268 git filter-branch --index-filter \
269 ´git ls-files -s | sed "s-\t-&newsubdir/-" |
270 GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
271 git update-index --index-info &&
272 mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE´ HEAD
273
274
276 Written by Petr "Pasky" Baudis <pasky@suse.cz>, and the git list
277 <git@vger.kernel.org>
278
280 Documentation by Petr Baudis and the git list.
281
283 Part of the git(7) suite
284
285
286
287
288Git 1.5.3.3 10/09/2007 GIT-FILTER-BRANCH(1)