rebase: add and use git_rebase__interactive__preserve_merges

At the moment it's an exact copy of git_rebase__interactive except the name has changed. Signed-off-by: Wink Saville <wink@saville.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Wink Saville committed Mar 23, 2018 at 14:25 UTC 950b487cf06672c60ab5080bf5b6a59bd394457d
2 files changed +109 -1
git-rebase--interactive.sh
+108
@@ -1058,3 +1058,111 @@ git_rebase__interactive () {
1058
1059 complete_action
1060 }
1061 +
1062 +git_rebase__interactive__preserve_merges () {
1063 + initiate_action "$action"
1064 + ret=$?
1065 + if test $ret = 0; then
1066 + return 0
1067 + fi
1068 +
1069 + setup_reflog_action
1070 + init_basic_state
1071 +
1072 + if test t = "$preserve_merges"
1073 + then
1074 + if test -z "$rebase_root"
1075 + then
1076 + mkdir "$rewritten" &&
1077 + for c in $(git merge-base --all $orig_head $upstream)
1078 + do
1079 + echo $onto > "$rewritten"/$c ||
1080 + die "$(gettext "Could not init rewritten commits")"
1081 + done
1082 + else
1083 + mkdir "$rewritten" &&
1084 + echo $onto > "$rewritten"/root ||
1085 + die "$(gettext "Could not init rewritten commits")"
1086 + fi
1087 + # No cherry-pick because our first pass is to determine
1088 + # parents to rewrite and skipping dropped commits would
1089 + # prematurely end our probe
1090 + merges_option=
1091 + else
1092 + merges_option="--no-merges --cherry-pick"
1093 + fi
1094 +
1095 + init_revisions_and_shortrevisions
1096 +
1097 + if test t != "$preserve_merges"
1098 + then
1099 + git rebase--helper --make-script ${keep_empty:+--keep-empty} \
1100 + $revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
1101 + die "$(gettext "Could not generate todo list")"
1102 + else
1103 + format=$(git config --get rebase.instructionFormat)
1104 + # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
1105 + git rev-list $merges_option --format="%m%H ${format:-%s}" \
1106 + --reverse --left-right --topo-order \
1107 + $revisions ${restrict_revision+^$restrict_revision} | \
1108 + sed -n "s/^>//p" |
1109 + while read -r sha1 rest
1110 + do
1111 +
1112 + if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
1113 + then
1114 + comment_out="$comment_char "
1115 + else
1116 + comment_out=
1117 + fi
1118 +
1119 + if test -z "$rebase_root"
1120 + then
1121 + preserve=t
1122 + for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
1123 + do
1124 + if test -f "$rewritten"/$p
1125 + then
1126 + preserve=f
1127 + fi
1128 + done
1129 + else
1130 + preserve=f
1131 + fi
1132 + if test f = "$preserve"
1133 + then
1134 + touch "$rewritten"/$sha1
1135 + printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
1136 + fi
1137 + done
1138 + fi
1139 +
1140 + # Watch for commits that been dropped by --cherry-pick
1141 + if test t = "$preserve_merges"
1142 + then
1143 + mkdir "$dropped"
1144 + # Save all non-cherry-picked changes
1145 + git rev-list $revisions --left-right --cherry-pick | \
1146 + sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
1147 + # Now all commits and note which ones are missing in
1148 + # not-cherry-picks and hence being dropped
1149 + git rev-list $revisions |
1150 + while read rev
1151 + do
1152 + if test -f "$rewritten"/$rev &&
1153 + ! sane_grep "$rev" "$state_dir"/not-cherry-picks >/dev/null
1154 + then
1155 + # Use -f2 because if rev-list is telling us this commit is
1156 + # not worthwhile, we don't want to track its multiple heads,
1157 + # just the history of its first-parent for others that will
1158 + # be rebasing on top of it
1159 + git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$dropped"/$rev
1160 + sha1=$(git rev-list -1 $rev)
1161 + sane_grep -v "^[a-z][a-z]* $sha1" <"$todo" > "${todo}2" ; mv "${todo}2" "$todo"
1162 + rm "$rewritten"/$rev
1163 + fi
1164 + done
1165 + fi
1166 +
1167 + complete_action
1168 +}
git-rebase.sh
+1 -1
@@ -197,7 +197,7 @@ run_specific_rebase () {
197 autosquash=
198 fi
199 . git-rebase--$type
200 - git_rebase__$type
200 + git_rebase__$type${preserve_merges:+__preserve_merges}
201 ret=$?
202 if test $ret -eq 0
203 then