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