git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC PATCH v5 5/8] Add and use git_rebase__interactive__preserve_merges

From
Wink Saville <wink@saville.com>
Date
Mar 23, 2018, 21:25 UTC
Message-ID
<784c1d59b7d4831c57e923be3515ddf68a3a8f14.1521839546.git.wink@saville.com>
In-Reply-To
<cover.1521839546.git.wink@saville.com>

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>
---
 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
Previous: Eric SunshineNext: Wink Saville
Message 23 of 42 in “rebase-interactive”
  1. rebase-interactiveWink Saville, Mar 23, 2018
  2. rebase-interactive: Simplify pick_on_preserving_mergesWink Saville, Mar 23, 2018
  3. Johannes SchindelinMar 23, 2018
  4. rebase: Update invocation of rebase dot-sourced scriptsWink Saville, Mar 23, 2018
  5. Eric SunshineMar 23, 2018
  6. Junio C HamanoMar 23, 2018
  7. Eric SunshineMar 23, 2018
  8. Johannes SchindelinMar 23, 2018
  9. Wink SavilleMar 23, 2018
  10. Junio C HamanoMar 23, 2018
  11. Wink SavilleMar 23, 2018
  12. 0/8 rebase-interactiveWink Saville, Mar 23, 2018
  13. 1/8 rebase-interactive: simplify pick_on_preserving_mergesWink Saville, Mar 23, 2018
  14. 2/8 rebase: update invocation of rebase dot-sourced scriptsWink Saville, Mar 23, 2018
  15. 3/8 Indent function git_rebase__interactiveWink Saville, Mar 23, 2018
  16. Junio C HamanoMar 23, 2018
  17. Wink SavilleMar 23, 2018
  18. Junio C HamanoMar 23, 2018
  19. Wink SavilleMar 24, 2018
  20. 4/8 Extract functions out of git_rebase__interactiveWink Saville, Mar 23, 2018
  21. Junio C HamanoMar 23, 2018
  22. Eric SunshineMar 24, 2018
  23. 5/8 Add and use git_rebase__interactive__preserve_mergesWink Saville, Mar 23, 2018
  24. 6/8 Remove unused code paths from git_rebase__interactiveWink Saville, Mar 23, 2018
  25. 7/8 Remove unused code paths from git_rebase__interactive__preserve_mergesWink Saville, Mar 23, 2018
  26. 8/8 Remove merges_option and a blank lineWink Saville, Mar 23, 2018
  27. Wink SavilleMar 23, 2018
  28. Junio C HamanoMar 23, 2018
  29. Wink SavilleMar 23, 2018
  30. Wink SavilleMar 24, 2018
  31. Junio C HamanoMar 26, 2018
  32. Jeff HostetlerMar 26, 2018
  33. Junio C HamanoMar 26, 2018
  34. Jeff HostetlerMar 26, 2018
  35. Junio C HamanoMar 27, 2018
  36. Jeff HostetlerMar 27, 2018
  37. Junio C HamanoMar 26, 2018
  38. Jeff HostetlerMar 26, 2018
  39. Wink SavilleMar 26, 2018
  40. Junio C HamanoMar 26, 2018
  41. Johannes SchindelinMar 26, 2018
  42. Junio C HamanoMar 23, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.