mirror of
https://github.com/git/git.git
synced 2024-11-27 20:14:30 +08:00
filter-branch: introduce convenience function "skip_commit"
With this function, a commit filter can leave out unwanted commits (such as temporary commits). It does _not_ undo the changeset corresponding to that commit, but it _skips_ the revision. IOW no tree object is changed by this. If you like to commit early and often, but want to filter out all intermediate commits, marked by "@@@" in the commit message, you can now do this with git filter-branch --commit-filter ' if git cat-file commit $GIT_COMMIT | grep '@@@' > /dev/null; then skip_commit "$@"; else git commit-tree "$@"; fi' newbranch Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
7e0f1704b8
commit
f95eef15f2
@ -112,6 +112,11 @@ OPTIONS
|
|||||||
As a special extension, the commit filter may emit multiple
|
As a special extension, the commit filter may emit multiple
|
||||||
commit ids; in that case, ancestors of the original commit will
|
commit ids; in that case, ancestors of the original commit will
|
||||||
have all of them as parents.
|
have all of them as parents.
|
||||||
|
+
|
||||||
|
You can use the 'map' convenience function in this filter, and other
|
||||||
|
convenience functions, too. For example, calling 'skip_commit "$@"'
|
||||||
|
will leave out the current commit (but not its changes! If you want
|
||||||
|
that, use gitlink:git-rebase[1] instead).
|
||||||
|
|
||||||
--tag-name-filter <command>::
|
--tag-name-filter <command>::
|
||||||
This is the filter for rewriting tag names. When passed,
|
This is the filter for rewriting tag names. When passed,
|
||||||
@ -209,24 +214,39 @@ To remove commits authored by "Darl McBribe" from the history:
|
|||||||
git filter-branch --commit-filter '
|
git filter-branch --commit-filter '
|
||||||
if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
|
if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
|
||||||
then
|
then
|
||||||
shift;
|
skip_commit "$@";
|
||||||
while [ -n "$1" ];
|
|
||||||
do
|
|
||||||
shift;
|
|
||||||
echo "$1";
|
|
||||||
shift;
|
|
||||||
done;
|
|
||||||
else
|
else
|
||||||
git commit-tree "$@";
|
git commit-tree "$@";
|
||||||
fi' HEAD
|
fi' HEAD
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Note that the changes introduced by the commits, and 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 gitlink:git-rebase[1].
|
||||||
|
|
||||||
|
The function 'skip_commits' 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
|
The shift magic first throws away the tree id and then the -p
|
||||||
parameters. Note that this handles merges properly! In case Darl
|
parameters. Note that this handles merges properly! In case Darl
|
||||||
committed a merge between P1 and P2, it will be propagated properly
|
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
|
and all children of the merge will become merge commits with P1,P2
|
||||||
as their parents instead of the merge commit.
|
as their parents instead of the merge commit.
|
||||||
|
|
||||||
|
|
||||||
To restrict rewriting to only part of the history, specify a revision
|
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
|
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
|
point to the top-most revision that a 'git rev-list' of this range
|
||||||
|
@ -23,6 +23,20 @@ map()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if you run 'skip_commit "$@"' in a commit filter, it will print
|
||||||
|
# the (mapped) parents, effectively skipping the commit.
|
||||||
|
|
||||||
|
skip_commit()
|
||||||
|
{
|
||||||
|
shift;
|
||||||
|
while [ -n "$1" ];
|
||||||
|
do
|
||||||
|
shift;
|
||||||
|
map "$1";
|
||||||
|
shift;
|
||||||
|
done;
|
||||||
|
}
|
||||||
|
|
||||||
# override die(): this version puts in an extra line break, so that
|
# override die(): this version puts in an extra line break, so that
|
||||||
# the progress is still visible
|
# the progress is still visible
|
||||||
|
|
||||||
|
@ -138,13 +138,7 @@ test_expect_success "remove a certain author's commits" '
|
|||||||
git-filter-branch -f --commit-filter "\
|
git-filter-branch -f --commit-filter "\
|
||||||
if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\
|
if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\
|
||||||
then\
|
then\
|
||||||
shift;\
|
skip_commit \"\$@\";
|
||||||
while [ -n \"\$1\" ];\
|
|
||||||
do\
|
|
||||||
shift;\
|
|
||||||
echo \"\$1\";\
|
|
||||||
shift;\
|
|
||||||
done;\
|
|
||||||
else\
|
else\
|
||||||
git commit-tree \"\$@\";\
|
git commit-tree \"\$@\";\
|
||||||
fi" removed-author &&
|
fi" removed-author &&
|
||||||
|
Loading…
Reference in New Issue
Block a user