1GIT-FILTER-BRANCH(1)              Git Manual              GIT-FILTER-BRANCH(1)
2
3
4

NAME

6       git-filter-branch - Rewrite branches
7

SYNOPSIS

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               [--prune-empty]
14               [--original <namespace>] [-d <directory>] [-f | --force]
15               [--] [<rev-list options>...]
16
17

DESCRIPTION

19       Lets you rewrite Git revision history by rewriting the branches
20       mentioned in the <rev-list options>, applying custom filters on each
21       revision. Those filters can modify each tree (e.g. removing a file or
22       running a perl rewrite on all files) or information about each commit.
23       Otherwise, all information (including original commit times or merge
24       information) will be preserved.
25
26       The command will only rewrite the positive refs mentioned in the
27       command line (e.g. if you pass a..b, only b will be rewritten). If you
28       specify no filters, the commits will be recommitted without any
29       changes, which would normally have no effect. Nevertheless, this may be
30       useful in the future for compensating for some Git bugs or such,
31       therefore such a usage is permitted.
32
33       NOTE: This command honors .git/info/grafts file and refs in the
34       refs/replace/ namespace. If you have any grafts or replacement refs
35       defined, running this command will make them permanent.
36
37       WARNING! The rewritten history will have different object names for all
38       the objects and will not converge with the original branch. You will
39       not be able to easily push and distribute the rewritten branch on top
40       of the original branch. Please do not use this command if you do not
41       know the full implications, and avoid using it anyway, if a simple
42       single commit would suffice to fix your problem. (See the "RECOVERING
43       FROM UPSTREAM REBASE" section in git-rebase(1) for further information
44       about rewriting published history.)
45
46       Always verify that the rewritten version is correct: The original refs,
47       if different from the rewritten ones, will be stored in the namespace
48       refs/original/.
49
50       Note that since this operation is very I/O expensive, it might be a
51       good idea to redirect the temporary directory off-disk with the -d
52       option, e.g. on tmpfs. Reportedly the speedup is very noticeable.
53
54   Filters
55       The filters are applied in the order as listed below. The <command>
56       argument is always evaluated in the shell context using the eval
57       command (with the notable exception of the commit filter, for technical
58       reasons). Prior to that, the $GIT_COMMIT environment variable will be
59       set to contain the id of the commit being rewritten. Also,
60       GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME,
61       GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE are taken from the current
62       commit and exported to the environment, in order to affect the author
63       and committer identities of the replacement commit created by git-
64       commit-tree(1) after the filters have run.
65
66       If any evaluation of <command> returns a non-zero exit status, the
67       whole operation will be aborted.
68
69       A map function is available that takes an "original sha1 id" argument
70       and outputs a "rewritten sha1 id" if the commit has been already
71       rewritten, and "original sha1 id" otherwise; the map function can
72       return several ids on separate lines if your commit filter emitted
73       multiple commits.
74

OPTIONS

76       --env-filter <command>
77           This filter may be used if you only need to modify the environment
78           in which the commit will be performed. Specifically, you might want
79           to rewrite the author/committer name/email/time environment
80           variables (see git-commit-tree(1) for details). Do not forget to
81           re-export the variables.
82
83       --tree-filter <command>
84           This is the filter for rewriting the tree and its contents. The
85           argument is evaluated in shell with the working directory set to
86           the root of the checked out tree. The new tree is then used as-is
87           (new files are auto-added, disappeared files are auto-removed -
88           neither .gitignore files nor any other ignore rules HAVE ANY
89           EFFECT!).
90
91       --index-filter <command>
92           This is the filter for rewriting the index. It is similar to the
93           tree filter but does not check out the tree, which makes it much
94           faster. Frequently used with git rm --cached --ignore-unmatch ...,
95           see EXAMPLES below. For hairy cases, see git-update-index(1).
96
97       --parent-filter <command>
98           This is the filter for rewriting the commit’s parent list. It will
99           receive the parent string on stdin and shall output the new parent
100           string on stdout. The parent string is in the format described in
101           git-commit-tree(1): empty for the initial commit, "-p parent" for a
102           normal commit and "-p parent1 -p parent2 -p parent3 ..." for a
103           merge commit.
104
105       --msg-filter <command>
106           This is the filter for rewriting the commit messages. The argument
107           is evaluated in the shell with the original commit message on
108           standard input; its standard output is used as the new commit
109           message.
110
111       --commit-filter <command>
112           This is the filter for performing the commit. If this filter is
113           specified, it will be called instead of the git commit-tree
114           command, with arguments of the form "<TREE_ID> [(-p
115           <PARENT_COMMIT_ID>)...]" and the log message on stdin. The commit
116           id is expected on stdout.
117
118           As a special extension, the commit filter may emit multiple commit
119           ids; in that case, the rewritten children of the original commit
120           will have all of them as parents.
121
122           You can use the map convenience function in this filter, and other
123           convenience functions, too. For example, calling skip_commit "$@"
124           will leave out the current commit (but not its changes! If you want
125           that, use git rebase instead).
126
127           You can also use the git_commit_non_empty_tree "$@" instead of git
128           commit-tree "$@" if you don’t wish to keep commits with a single
129           parent and that makes no change to the tree.
130
131       --tag-name-filter <command>
132           This is the filter for rewriting tag names. When passed, it will be
133           called for every tag ref that points to a rewritten object (or to a
134           tag object which points to a rewritten object). The original tag
135           name is passed via standard input, and the new tag name is expected
136           on standard output.
137
138           The original tags are not deleted, but can be overwritten; use
139           "--tag-name-filter cat" to simply update the tags. In this case, be
140           very careful and make sure you have the old tags backed up in case
141           the conversion has run afoul.
142
143           Nearly proper rewriting of tag objects is supported. If the tag has
144           a message attached, a new tag object will be created with the same
145           message, author, and timestamp. If the tag has a signature
146           attached, the signature will be stripped. It is by definition
147           impossible to preserve signatures. The reason this is "nearly"
148           proper, is because ideally if the tag did not change (points to the
149           same object, has the same name, etc.) it should retain any
150           signature. That is not the case, signatures will always be removed,
151           buyer beware. There is also no support for changing the author or
152           timestamp (or the tag message for that matter). Tags which point to
153           other tags will be rewritten to point to the underlying commit.
154
155       --subdirectory-filter <directory>
156           Only look at the history which touches the given subdirectory. The
157           result will contain that directory (and only that) as its project
158           root. Implies the section called “Remap to ancestor”.
159
160       --prune-empty
161           Some kind of filters will generate empty commits, that left the
162           tree untouched. This switch allow git-filter-branch to ignore such
163           commits. Though, this switch only applies for commits that have one
164           and only one parent, it will hence keep merges points. Also, this
165           option is not compatible with the use of --commit-filter. Though
166           you just need to use the function git_commit_non_empty_tree "$@"
167           instead of the git commit-tree "$@" idiom in your commit filter to
168           make that happen.
169
170       --original <namespace>
171           Use this option to set the namespace where the original commits
172           will be stored. The default value is refs/original.
173
174       -d <directory>
175           Use this option to set the path to the temporary directory used for
176           rewriting. When applying a tree filter, the command needs to
177           temporarily check out the tree to some directory, which may consume
178           considerable space in case of large projects. By default it does
179           this in the .git-rewrite/ directory but you can override that
180           choice by this parameter.
181
182       -f, --force
183           git filter-branch refuses to start with an existing temporary
184           directory or when there are already refs starting with
185           refs/original/, unless forced.
186
187       <rev-list options>...
188           Arguments for git rev-list. All positive refs included by these
189           options are rewritten. You may also specify options such as --all,
190           but you must use -- to separate them from the git filter-branch
191           options. Implies the section called “Remap to ancestor”.
192
193   Remap to ancestor
194       By using rev-list(1) arguments, e.g., path limiters, you can limit the
195       set of revisions which get rewritten. However, positive refs on the
196       command line are distinguished: we don’t let them be excluded by such
197       limiters. For this purpose, they are instead rewritten to point at the
198       nearest ancestor that was not excluded.
199

EXAMPLES

201       Suppose you want to remove a file (containing confidential information
202       or copyright violation) from all commits:
203
204           git filter-branch --tree-filter 'rm filename' HEAD
205
206
207       However, if the file is absent from the tree of some commit, a simple
208       rm filename will fail for that tree and commit. Thus you may instead
209       want to use rm -f filename as the script.
210
211       Using --index-filter with git rm yields a significantly faster version.
212       Like with using rm filename, git rm --cached filename will fail if the
213       file is absent from the tree of a commit. If you want to "completely
214       forget" a file, it does not matter when it entered history, so we also
215       add --ignore-unmatch:
216
217           git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
218
219
220       Now, you will get the rewritten history saved in HEAD.
221
222       To rewrite the repository to look as if foodir/ had been its project
223       root, and discard all other history:
224
225           git filter-branch --subdirectory-filter foodir -- --all
226
227
228       Thus you can, e.g., turn a library subdirectory into a repository of
229       its own. Note the -- that separates filter-branch options from revision
230       options, and the --all to rewrite all branches and tags.
231
232       To set a commit (which typically is at the tip of another history) to
233       be the parent of the current initial commit, in order to paste the
234       other history behind the current history:
235
236           git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD
237
238
239       (if the parent string is empty - which happens when we are dealing with
240       the initial commit - add graftcommit as a parent). Note that this
241       assumes history with a single root (that is, no merge without common
242       ancestors happened). If this is not the case, use:
243
244           git filter-branch --parent-filter \
245                   'test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>" || cat' HEAD
246
247
248       or even simpler:
249
250           echo "$commit-id $graft-id" >> .git/info/grafts
251           git filter-branch $graft-id..HEAD
252
253
254       To remove commits authored by "Darl McBribe" from the history:
255
256           git filter-branch --commit-filter '
257                   if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
258                   then
259                           skip_commit "$@";
260                   else
261                           git commit-tree "$@";
262                   fi' HEAD
263
264
265       The function skip_commit is defined as follows:
266
267           skip_commit()
268           {
269                   shift;
270                   while [ -n "$1" ];
271                   do
272                           shift;
273                           map "$1";
274                           shift;
275                   done;
276           }
277
278
279       The shift magic first throws away the tree id and then the -p
280       parameters. Note that this handles merges properly! In case Darl
281       committed a merge between P1 and P2, it will be propagated properly and
282       all children of the merge will become merge commits with P1,P2 as their
283       parents instead of the merge commit.
284
285       NOTE the changes introduced by the commits, and which are not reverted
286       by subsequent commits, will still be in the rewritten branch. If you
287       want to throw out changes together with the commits, you should use the
288       interactive mode of git rebase.
289
290       You can rewrite the commit log messages using --msg-filter. For
291       example, git svn-id strings in a repository created by git svn can be
292       removed this way:
293
294           git filter-branch --msg-filter '
295                   sed -e "/^git-svn-id:/d"
296           '
297
298
299       If you need to add Acked-by lines to, say, the last 10 commits (none of
300       which is a merge), use this command:
301
302           git filter-branch --msg-filter '
303                   cat &&
304                   echo "Acked-by: Bugs Bunny <bunny@bugzilla.org>"
305           ' HEAD~10..HEAD
306
307
308       The --env-filter option can be used to modify committer and/or author
309       identity. For example, if you found out that your commits have the
310       wrong identity due to a misconfigured user.email, you can make a
311       correction, before publishing the project, like this:
312
313           git filter-branch --env-filter '
314                   if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
315                   then
316                           GIT_AUTHOR_EMAIL=john@example.com
317                           export GIT_AUTHOR_EMAIL
318                   fi
319                   if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
320                   then
321                           GIT_COMMITTER_EMAIL=john@example.com
322                           export GIT_COMMITTER_EMAIL
323                   fi
324           ' -- --all
325
326
327       To restrict rewriting to only part of the history, specify a revision
328       range in addition to the new branch name. The new branch name will
329       point to the top-most revision that a git rev-list of this range will
330       print.
331
332       Consider this history:
333
334                D--E--F--G--H
335               /     /
336           A--B-----C
337
338
339       To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use:
340
341           git filter-branch ... C..H
342
343
344       To rewrite commits E,F,G,H, use one of these:
345
346           git filter-branch ... C..H --not D
347           git filter-branch ... D..H --not C
348
349
350       To move the whole tree into a subdirectory, or remove it from there:
351
352           git filter-branch --index-filter \
353                   'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
354                           GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
355                                   git update-index --index-info &&
356                    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
357
358

CHECKLIST FOR SHRINKING A REPOSITORY

360       git-filter-branch is often used to get rid of a subset of files,
361       usually with some combination of --index-filter and
362       --subdirectory-filter. People expect the resulting repository to be
363       smaller than the original, but you need a few more steps to actually
364       make it smaller, because Git tries hard not to lose your objects until
365       you tell it to. First make sure that:
366
367       ·   You really removed all variants of a filename, if a blob was moved
368           over its lifetime.  git log --name-only --follow --all -- filename
369           can help you find renames.
370
371       ·   You really filtered all refs: use --tag-name-filter cat -- --all
372           when calling git-filter-branch.
373
374       Then there are two ways to get a smaller repository. A safer way is to
375       clone, that keeps your original intact.
376
377       ·   Clone it with git clone file:///path/to/repo. The clone will not
378           have the removed objects. See git-clone(1). (Note that cloning with
379           a plain path just hardlinks everything!)
380
381       If you really don’t want to clone it, for whatever reasons, check the
382       following points instead (in this order). This is a very destructive
383       approach, so make a backup or go back to cloning it. You have been
384       warned.
385
386       ·   Remove the original refs backed up by git-filter-branch: say git
387           for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git
388           update-ref -d.
389
390       ·   Expire all reflogs with git reflog expire --expire=now --all.
391
392       ·   Garbage collect all unreferenced objects with git gc --prune=now
393           (or if your git-gc is not new enough to support arguments to
394           --prune, use git repack -ad; git prune instead).
395

GIT

397       Part of the git(1) suite
398
399
400
401Git 1.8.3.1                       11/19/2018              GIT-FILTER-BRANCH(1)
Impressum