Home Explore Blog CI



git

5th chunk of `Documentation/git-filter-branch.adoc`
4d2b7c31e6f74baf5ad58269eaaa1c26207dbd3ae672c1670000000100000fa4
 foodir -- --all
-------------------------------------------------------

Thus you can, e.g., turn a library subdirectory into a repository of
its own.  Note the `--` that separates 'filter-branch' options from
revision options, and the `--all` to rewrite all branches and tags.

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>/"' HEAD
-------------------------------------------------------------------

(if the parent string is empty - which happens when 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 \
	'test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>" || cat' HEAD
--------------------------------------------------------------------------

or even simpler:

-----------------------------------------------
git replace --graft $commit-id $graft-id
git filter-branch $graft-id..HEAD
-----------------------------------------------

To remove commits authored by "Darl McBribe" from the history:

------------------------------------------------------------------------------
git filter-branch --commit-filter '
	if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
	then
		skip_commit "$@";
	else
		git commit-tree "$@";
	fi' HEAD
------------------------------------------------------------------------------

The function 'skip_commit' is defined as follows:

--------------------------
skip_commit()
{
	shift;
	while [ -n "$1" ];
	do
		shift;
		map "$1";
		shift;
	done;
}
--------------------------

The shift magic first throws away the tree id and then the -p
parameters.  Note that this handles merges properly! In case Darl
committed a merge between P1 and P2, it will be propagated properly
and all children of the merge will become merge commits with P1,P2
as their parents instead of the merge commit.

*NOTE* the changes introduced by the commits, and which are not reverted
by subsequent commits, will still be in the rewritten branch. If you want
to throw out _changes_ together with the commits, you should use the
interactive mode of 'git rebase'.

You can rewrite the commit log messages using `--msg-filter`.  For
example, 'git svn-id' strings in a repository created by 'git svn' can
be removed this way:

-------------------------------------------------------
git filter-branch --msg-filter '
	sed -e "/^git-svn-id:/d"
'
-------------------------------------------------------

If you need to add 'Acked-by' lines to, say, the last 10 commits (none
of which is a merge), use this command:

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

Title: Advanced Git Filter Branch Usage and Examples
Summary
The text provides advanced examples of using the git filter-branch command to rewrite Git history, including removing commits by specific authors, changing commit log messages, modifying committer and author identities, and restricting rewriting to specific revision ranges, along with explanations of the options and scripts used.