[PATCH 4/6] rebase: --rewrite-{refs,heads,tags} to pull refs along with branch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The new option --rewrite-refs causes the TODO file to contain a "ref"
command for each appropriate ref pointing to a selected commit, other
than the one we are already rebasing.  The argument to --rewrite-refs
is a ref pattern of the same type accepted by for-each-ref: a pattern
matches a ref name if it matches exactly, matches exactly up to a
slash, or matches according to fnmatch(3).  The options
--rewrite-heads and --rewrite-tags are supplied as shortcuts.

The effect of this is that when a branch contains intermediate
branches, like so:

      part1 part2 topic
        |     |     |
        v     v     v
  A--*--*--*--*--*--*
   \
    B <--master

a single command like "git rebase --rewrite-heads master topic"
suffices to rewrite all the heads that are part of the topic, like so:

        part1 part2 topic
  A       |     |     |
   \      v     v     v
    B--*--*--*--*--*--*
    ^
    |
    master

Signed-off-by: Greg Price <price@xxxxxxx>
---
 Documentation/git-rebase.txt |   13 ++++++++++++-
 git-rebase--interactive.sh   |   25 ++++++++++++++++++++++++-
 git-rebase.sh                |   17 +++++++++++++++++
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 74fda58..e4f32fc 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -347,6 +347,15 @@ idea unless you know what you are doing (see BUGS below).
 	root commits will be rewritten to have <newbase> as parent
 	instead.
 
+--rewrite-refs=<pattern>::
+--rewrite-heads::
+--rewrite-tags::
+	Rewrite refs matching <pattern> which point to the rebased
+	commits.  The options --rewrite-heads and --rewrite-tags are
+	shortcuts for --rewrite-refs=refs/heads and
+	--rewrite-refs=refs/tags respectively.  Ref patterns are
+	interpreted as in linkgit:git-for-each-ref[1].
+
 --autosquash::
 --no-autosquash::
 	When the commit log message begins with "squash! ..." (or
@@ -457,7 +466,9 @@ but omits the commit messages of commits with the "fixup" command.
 
 If you want to update a ref to point to a rewritten commit, add a
 command "ref <refname>" after the "pick", "edit", or other command
-that produces the commit.
+that produces the commit.  You can use the --rewrite-refs option to
+have the file start out with these commands for refs inside the branch
+you are rebasing.
 
 'git rebase' will stop when "pick" has been replaced with "edit" or
 when a command fails due to merge errors. When you are done editing
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index cec9cab..42ea3e7 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -741,12 +741,23 @@ else
 	revisions=$onto...$orig_head
 	shortrevisions=$shorthead
 fi
-git rev-list $merges_option --pretty=oneline --abbrev-commit \
+if test -z "rewrite_refs"
+then
+	pretty=oneline
+else
+	pretty=format:"%m%h %s%n%m%D"
+fi
+git rev-list $merges_option --pretty="$pretty" --abbrev-commit \
 	--abbrev=7 --reverse --left-right --topo-order \
 	$revisions | \
 	sed -n "s/^>//p" |
 while read -r shortsha1 rest
 do
+	if test -n "$rewrite_refs"
+	then
+		read refs
+	fi
+
 	if test t != "$preserve_merges"
 	then
 		printf '%s\n' "pick $shortsha1 $rest" >> "$todo"
@@ -771,6 +782,18 @@ do
 			printf '%s\n' "pick $shortsha1 $rest" >> "$todo"
 		fi
 	fi
+
+	if test -n "$rewrite_refs"
+	then
+		for ref in $refs; do echo "$ref"; done | \
+		git for-each-ref --stdin $rewrite_refs \
+			--format '%(refname)' | \
+		while read ref
+		do
+			test "$ref" != "$head_name" &&
+			echo "ref $ref" >> "$todo"
+		done
+	fi
 done
 
 # Watch for commits that been dropped by --cherry-pick
diff --git a/git-rebase.sh b/git-rebase.sh
index 1bfe6a8..7c365ab 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -38,6 +38,9 @@ git-rebase [-i] --continue | --abort | --skip
 v,verbose!         display a diffstat of what changed upstream
 q,quiet!           be quiet. implies --no-stat
 onto=!             rebase onto given branch instead of upstream
+rewrite-heads!     rewrite intermediate heads on branch
+rewrite-tags!      rewrite intermediate tags on branch
+rewrite-refs=!     rewrite intermediate refs matching pattern
 p,preserve-merges! try to recreate merges instead of ignoring them
 s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
@@ -96,6 +99,7 @@ state_dir=
 # One of {'', continue, skip, abort}, as parsed from command line
 action=
 preserve_merges=
+rebase_refs=
 autosquash=
 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 
@@ -246,6 +250,19 @@ do
 		strategy="$1"
 		do_merge=t
 		;;
+	--rewrite-refs)
+		shift
+		rewrite_refs="$rewrite_refs $1"
+		test -z "$interactive_rebase" && interactive_rebase=implied
+		;;
+	--rewrite-heads)
+		rewrite_refs="$rewrite_refs refs/heads"
+		test -z "$interactive_rebase" && interactive_rebase=implied
+		;;
+	--rewrite-tags)
+		rewrite_refs="$rewrite_refs refs/tags"
+		test -z "$interactive_rebase" && interactive_rebase=implied
+		;;
 	-n)
 		diffstat=
 		;;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]