filter-branch: add git_commit_non_empty_tree and --prune-empty.
git_commit_non_empty_tree is added to the functions that can be run from commit filters. Its effect is to commit only commits actually touching the tree and that are not merge points either. The option --prune-empty is added. It defaults the commit-filter to 'git_commit_non_empty_tree "$@"', and can be used with any other combination of filters, except --commit-hook that must used 'git_commit_non_empty_tree "$@"' where one puts 'git commit-tree "$@"' usually to achieve the same result. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pierre Habouzit committed
Oct 31, 2008 at 10:12 UTC
d3240d935c4b844db71e4570eeedfac4cff73f78
3 files changed
+50
-1
Documentation/git-filter-branch.txt
+14
@@ -122,6 +122,10 @@ You can use the 'map' convenience function in this filter, and other
122
convenience functions, too. For example, calling 'skip_commit "$@"'
123
will leave out the current commit (but not its changes! If you want
124
that, use 'git-rebase' instead).
125
++
126
+You can also use the 'git_commit_non_empty_tree "$@"' instead of
127
+'git commit-tree "$@"' if you don't wish to keep commits with a single parent
128
+and that makes no change to the tree.
129
130
--tag-name-filter <command>::
131
This is the filter for rewriting tag names. When passed,
@@ -151,6 +155,16 @@ to other tags will be rewritten to point to the underlying commit.
155
The result will contain that directory (and only that) as its
156
project root.
157
158
+--prune-empty::
159
+ Some kind of filters will generate empty commits, that left the tree
160
+ untouched. This switch allow git-filter-branch to ignore such
161
+ commits. Though, this switch only applies for commits that have one
162
+ and only one parent, it will hence keep merges points. Also, this
163
+ option is not compatible with the use of '--commit-filter'. Though you
164
+ just need to use the function 'git_commit_non_empty_tree "$@"' instead
165
+ of the 'git commit-tree "$@"' idiom in your commit filter to make that
166
+ happen.
167
+
168
--original <namespace>::
169
Use this option to set the namespace where the original commits
170
will be stored. The default value is 'refs/original'.
git-filter-branch.sh
+28
-1
@@ -40,6 +40,16 @@ skip_commit()
40
done;
41
}
42
43
+# if you run 'git_commit_non_empty_tree "$@"' in a commit filter,
44
+# it will skip commits that leave the tree untouched, commit the other.
45
+git_commit_non_empty_tree()
46
+{
47
+ if test $# = 3 && test "$1" = $(git rev-parse "$3^{tree}"); then
48
+ map "$3"
49
+ else
50
+ git commit-tree "$@"
51
+ fi
52
+}
53
# override die(): this version puts in an extra line break, so that
54
# the progress is still visible
55
@@ -109,11 +119,12 @@ filter_tree=
119
filter_index=
120
filter_parent=
121
filter_msg=cat
112
-filter_commit='git commit-tree "$@"'
122
+filter_commit=
123
filter_tag_name=
124
filter_subdir=
125
orig_namespace=refs/original/
126
force=
127
+prune_empty=
128
while :
129
do
130
case "$1" in
@@ -126,6 +137,11 @@ do
137
force=t
138
continue
139
;;
140
+ --prune-empty)
141
+ shift
142
+ prune_empty=t
143
+ continue
144
+ ;;
145
-*)
146
;;
147
*)
@@ -176,6 +192,17 @@ do
192
esac
193
done
194
195
+case "$prune_empty,$filter_commit" in
196
+,)
197
+ filter_commit='git commit-tree "$@"';;
198
+t,)
199
+ filter_commit="$functions;"' git_commit_non_empty_tree "$@"';;
200
+,*)
201
+ ;;
202
+*)
203
+ die "Cannot set --prune-empty and --filter-commit at the same time"
204
+esac
205
+
206
case "$force" in
207
t)
208
rm -rf "$tempdir"
t/t7003-filter-branch.sh
+8
@@ -262,4 +262,12 @@ test_expect_success 'Tag name filtering allows slashes in tag names' '
262
test_cmp expect actual
263
'
264
265
+test_expect_success 'Prune empty commits' '
266
+ git rev-list HEAD > expect &&
267
+ make_commit to_remove &&
268
+ git filter-branch -f --index-filter "git update-index --remove to_remove" --prune-empty HEAD &&
269
+ git rev-list HEAD > actual &&
270
+ test_cmp expect actual
271
+'
272
+
273
test_done