зеркало из https://github.com/microsoft/git.git
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:
Родитель
7e0f1704b8
Коммит
f95eef15f2
|
@ -112,6 +112,11 @@ OPTIONS
|
|||
As a special extension, the commit filter may emit multiple
|
||||
commit ids; in that case, ancestors of the original commit will
|
||||
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>::
|
||||
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 '
|
||||
if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
|
||||
then
|
||||
shift;
|
||||
while [ -n "$1" ];
|
||||
do
|
||||
shift;
|
||||
echo "$1";
|
||||
shift;
|
||||
done;
|
||||
skip_commit "$@";
|
||||
else
|
||||
git commit-tree "$@";
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
|
|
|
@ -23,6 +23,20 @@ map()
|
|||
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
|
||||
# the progress is still visible
|
||||
|
||||
|
|
|
@ -138,13 +138,7 @@ test_expect_success "remove a certain author's commits" '
|
|||
git-filter-branch -f --commit-filter "\
|
||||
if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\
|
||||
then\
|
||||
shift;\
|
||||
while [ -n \"\$1\" ];\
|
||||
do\
|
||||
shift;\
|
||||
echo \"\$1\";\
|
||||
shift;\
|
||||
done;\
|
||||
skip_commit \"\$@\";
|
||||
else\
|
||||
git commit-tree \"\$@\";\
|
||||
fi" removed-author &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче