Home Explore Blog CI



git

6th chunk of `Documentation/git-filter-branch.adoc`
42170bf5604048b0641dcef2340df5525c32e18c022163700000000100000fa1
 filter-branch --msg-filter '
	cat &&
	echo "Acked-by: Bugs Bunny <bunny@bugzilla.org>"
' HEAD~10..HEAD
--------------------------------------------------------

The `--env-filter` option can be used to modify committer and/or author
identity.  For example, if you found out that your commits have the wrong
identity due to a misconfigured user.email, you can make a correction,
before publishing the project, like this:

--------------------------------------------------------
git filter-branch --env-filter '
	if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
	then
		GIT_AUTHOR_EMAIL=john@example.com
	fi
	if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
	then
		GIT_COMMITTER_EMAIL=john@example.com
	fi
' -- --all
--------------------------------------------------------

To restrict rewriting to only part of the history, specify a revision
range in addition to the new branch name.  The new branch name will
point to the top-most revision that a 'git rev-list' of this range
will print.

Consider this history:

------------------
     D--E--F--G--H
    /     /
A--B-----C
------------------

To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use:

--------------------------------
git filter-branch ... C..H
--------------------------------

To rewrite commits E,F,G,H, use one of these:

----------------------------------------
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:

---------------------------------------------------------------
git filter-branch --index-filter \
	'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
		GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
			git update-index --index-info &&
	 mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
---------------------------------------------------------------



CHECKLIST FOR SHRINKING A REPOSITORY
------------------------------------

git-filter-branch can be used to get rid of a subset of files,
usually with some combination of `--index-filter` and
`--subdirectory-filter`.  People expect the resulting repository to
be smaller than the original, but you need a few more steps to
actually make it smaller, because Git tries hard not to lose your
objects until you tell it to.  First make sure that:

* You really removed all variants of a filename, if a blob was moved
  over its lifetime.  `git log --name-only --follow --all -- filename`
  can help you find renames.

* You really filtered all refs: use `--tag-name-filter cat -- --all`
  when calling git-filter-branch.

Then there are two ways to get a smaller repository.  A safer way is
to clone, that keeps your original intact.

* Clone it with `git clone file:///path/to/repo`.  The clone
  will not have the removed objects.  See linkgit:git-clone[1].  (Note
  that cloning with a plain path just hardlinks everything!)

If you really don't want to clone it, for whatever reasons, check the
following points instead (in this order).  This is a very destructive
approach, so *make a backup* or go back to cloning it.  You have been
warned.

* Remove the original refs backed up by git-filter-branch: say `git
  for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git
  update-ref -d`.

* Expire all reflogs with `git reflog expire --expire=now --all`.

* Garbage collect all unreferenced objects with `git gc --prune=now`
  (or if your git-gc is not new enough to support arguments to
  `--prune`, use `git repack -ad; git prune` instead).

[[PERFORMANCE]]
PERFORMANCE
-----------

The performance of git-filter-branch is glacially slow; its design makes it
impossible for a backward-compatible implementation to ever be fast:

* In editing files, git-filter-branch by design checks out each and
  every commit as it existed in the original repo.  If your repo has
  `10^5` files and `10^5` commits, but each commit only modifies five
  files, then git-filter-branch will make you do `10^10` modifications,
  despite

Title: Git Filter Branch Advanced Usage and Optimization
Summary
The text explains advanced techniques for using git filter-branch, including restricting rewriting to specific revision ranges, modifying commit identities, and moving the whole tree into a subdirectory, as well as provides a checklist for shrinking a repository and discusses the performance limitations of git filter-branch, along with suggestions for optimization.