filter-branch: Use rev-list arguments to specify revision ranges.

A subset of commits in a branch used to be specified by options (-k, -r)
as well as the branch tip itself (-s). It is more natural (for git users)
to specify revision ranges like 'master..next' instead. This makes it so.
If no range is specified it defaults to 'HEAD'.

As a consequence, the new name of the filtered branch must be the first
non-option argument. All remaining arguments are passed to 'git rev-list'
unmodified.

The tip of the branch that gets filtered is implied: It is the first
commit that git rev-list would print for the specified range.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Johannes Sixt 2007-06-06 09:43:41 +02:00 committed by Junio C Hamano
parent 9840906026
commit 2766ce2815
2 changed files with 13 additions and 28 deletions

View File

@ -42,15 +42,6 @@
# does this in the '.git-rewrite/' directory but you can override # does this in the '.git-rewrite/' directory but you can override
# that choice by this parameter. # that choice by this parameter.
# #
# -r STARTREV:: The commit id to start the rewrite at
# Normally, the command will rewrite the entire history. If you
# pass this argument, though, this will be the first commit it
# will rewrite and keep the previous commits intact.
#
# -k KEEPREV:: A commit id until which _not_ to rewrite history
# If you pass this argument, this commit and all of its
# predecessors are kept intact.
#
# Filters # Filters
# ~~~~~~~ # ~~~~~~~
# The filters are applied in the order as listed below. The COMMAND # The filters are applied in the order as listed below. The COMMAND
@ -164,27 +155,31 @@
# 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, use -r or -k or both. # 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: # Consider this history:
# #
# D--E--F--G--H # D--E--F--G--H
# / / # / /
# A--B-----C # A--B-----C
# #
# To rewrite only commits F,G,H, use: # To rewrite commits D,E,F,G,H, use:
# #
# git-filter-branch -r F ... # git-filter-branch ... new-H C..H
# #
# To rewrite commits E,F,G,H, use one of these: # To rewrite commits E,F,G,H, use one of these:
# #
# git-filter-branch -r E -k C ... # git-filter-branch ... new-H C..H --not D
# git-filter-branch -k D -k C ... # git-filter-branch ... new-H D..H --not C
# Testsuite: TODO # Testsuite: TODO
set -e set -e
USAGE="git-filter-branch [-d TEMPDIR] [-r STARTREV]... [-k KEEPREV]... [-s SRCBRANCH] [FILTERS] DESTBRANCH" USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]"
. git-sh-setup . git-sh-setup
map() map()
@ -232,7 +227,6 @@ get_parents () {
} }
tempdir=.git-rewrite tempdir=.git-rewrite
unchanged=" "
filter_env= filter_env=
filter_tree= filter_tree=
filter_index= filter_index=
@ -240,7 +234,6 @@ filter_parent=
filter_msg=cat filter_msg=cat
filter_commit='git-commit-tree "$@"' filter_commit='git-commit-tree "$@"'
filter_tag_name= filter_tag_name=
srcbranch=HEAD
while case "$#" in 0) usage;; esac while case "$#" in 0) usage;; esac
do do
case "$1" in case "$1" in
@ -265,12 +258,6 @@ do
-d) -d)
tempdir="$OPTARG" tempdir="$OPTARG"
;; ;;
-r)
unchanged="$(get_parents "$OPTARG") $unchanged"
;;
-k)
unchanged="$(git-rev-parse "$OPTARG"^{commit}) $unchanged"
;;
--env-filter) --env-filter)
filter_env="$OPTARG" filter_env="$OPTARG"
;; ;;
@ -292,9 +279,6 @@ do
--tag-name-filter) --tag-name-filter)
filter_tag_name="$OPTARG" filter_tag_name="$OPTARG"
;; ;;
-s)
srcbranch="$OPTARG"
;;
*) *)
usage usage
;; ;;
@ -302,6 +286,7 @@ do
done done
dstbranch="$1" dstbranch="$1"
shift
test -n "$dstbranch" || die "missing branch name" test -n "$dstbranch" || die "missing branch name"
git-show-ref "refs/heads/$dstbranch" 2> /dev/null && git-show-ref "refs/heads/$dstbranch" 2> /dev/null &&
die "branch $dstbranch already exists" die "branch $dstbranch already exists"
@ -327,7 +312,7 @@ ret=0
mkdir ../map # map old->new commit ids for rewriting parents mkdir ../map # map old->new commit ids for rewriting parents
git-rev-list --reverse --topo-order $srcbranch --not $unchanged >../revs git-rev-list --reverse --topo-order --default HEAD "$@" >../revs
commits=$(cat ../revs | wc -l | tr -d " ") commits=$(cat ../revs | wc -l | tr -d " ")
test $commits -eq 0 && die "Found nothing to rewrite" test $commits -eq 0 && die "Found nothing to rewrite"

View File

@ -47,7 +47,7 @@ test_expect_success 'test that the file was renamed' '
git tag oldD H3~4 git tag oldD H3~4
test_expect_success 'rewrite one branch, keeping a side branch' ' test_expect_success 'rewrite one branch, keeping a side branch' '
git-filter-branch --tree-filter "mv b boh || :" -k D -s oldD modD git-filter-branch --tree-filter "mv b boh || :" modD D..oldD
' '
test_expect_success 'common ancestor is still common (unchanged)' ' test_expect_success 'common ancestor is still common (unchanged)' '