At the moment it's an exact copy of git_rebase__interactive except
the name has changed.

Signed-off-by: Wink Saville <w...@saville.com>
---
 git-rebase--interactive.sh | 108 +++++++++++++++++++++++++++++++++++++++++++++
 git-rebase.sh              |   2 +-
 2 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 2c10a7f1a..ab5513d80 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -1058,3 +1058,111 @@ git_rebase__interactive () {
 
        complete_action
 }
+
+git_rebase__interactive__preserve_merges () {
+       initiate_action "$action"
+       ret=$?
+       if test $ret = 0; then
+               return 0
+       fi
+
+       setup_reflog_action
+       init_basic_state
+
+       if test t = "$preserve_merges"
+       then
+               if test -z "$rebase_root"
+               then
+                       mkdir "$rewritten" &&
+                       for c in $(git merge-base --all $orig_head $upstream)
+                       do
+                               echo $onto > "$rewritten"/$c ||
+                                       die "$(gettext "Could not init 
rewritten commits")"
+                       done
+               else
+                       mkdir "$rewritten" &&
+                       echo $onto > "$rewritten"/root ||
+                               die "$(gettext "Could not init rewritten 
commits")"
+               fi
+               # No cherry-pick because our first pass is to determine
+               # parents to rewrite and skipping dropped commits would
+               # prematurely end our probe
+               merges_option=
+       else
+               merges_option="--no-merges --cherry-pick"
+       fi
+
+       init_revisions_and_shortrevisions
+
+       if test t != "$preserve_merges"
+       then
+               git rebase--helper --make-script ${keep_empty:+--keep-empty} \
+                       $revisions ${restrict_revision+^$restrict_revision} 
>"$todo" ||
+               die "$(gettext "Could not generate todo list")"
+       else
+               format=$(git config --get rebase.instructionFormat)
+               # the 'rev-list .. | sed' requires %m to parse; the instruction 
requires %H to parse
+               git rev-list $merges_option --format="%m%H ${format:-%s}" \
+                       --reverse --left-right --topo-order \
+                       $revisions ${restrict_revision+^$restrict_revision} | \
+                       sed -n "s/^>//p" |
+               while read -r sha1 rest
+               do
+
+                       if test -z "$keep_empty" && is_empty_commit $sha1 && ! 
is_merge_commit $sha1
+                       then
+                               comment_out="$comment_char "
+                       else
+                               comment_out=
+                       fi
+
+                       if test -z "$rebase_root"
+                       then
+                               preserve=t
+                               for p in $(git rev-list --parents -1 $sha1 | 
cut -d' ' -s -f2-)
+                               do
+                                       if test -f "$rewritten"/$p
+                                       then
+                                               preserve=f
+                                       fi
+                               done
+                       else
+                               preserve=f
+                       fi
+                       if test f = "$preserve"
+                       then
+                               touch "$rewritten"/$sha1
+                               printf '%s\n' "${comment_out}pick $sha1 $rest" 
>>"$todo"
+                       fi
+               done
+       fi
+
+       # Watch for commits that been dropped by --cherry-pick
+       if test t = "$preserve_merges"
+       then
+               mkdir "$dropped"
+               # Save all non-cherry-picked changes
+               git rev-list $revisions --left-right --cherry-pick | \
+                       sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
+               # Now all commits and note which ones are missing in
+               # not-cherry-picks and hence being dropped
+               git rev-list $revisions |
+               while read rev
+               do
+                       if test -f "$rewritten"/$rev &&
+                          ! sane_grep "$rev" "$state_dir"/not-cherry-picks 
>/dev/null
+                       then
+                               # Use -f2 because if rev-list is telling us 
this commit is
+                               # not worthwhile, we don't want to track its 
multiple heads,
+                               # just the history of its first-parent for 
others that will
+                               # be rebasing on top of it
+                               git rev-list --parents -1 $rev | cut -d' ' -s 
-f2 > "$dropped"/$rev
+                               sha1=$(git rev-list -1 $rev)
+                               sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > 
"${todo}2" ; mv "${todo}2" "$todo"
+                               rm "$rewritten"/$rev
+                       fi
+               done
+       fi
+
+       complete_action
+}
diff --git a/git-rebase.sh b/git-rebase.sh
index 6edf8c5b1..fb64ee1fe 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -197,7 +197,7 @@ run_specific_rebase () {
                autosquash=
        fi
        . git-rebase--$type
-       git_rebase__$type
+       git_rebase__$type${preserve_merges:+__preserve_merges}
        ret=$?
        if test $ret -eq 0
        then
-- 
2.16.2

Reply via email to