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

[PATCH/RFC 2/2] git rebase -i: Warn removed or dupplicated commits

From
Galan Rémi <remi.galan-alfonso@ensimag.grenoble-inp.fr>
Date
May 26, 2015, 21:38 UTC
Message-ID
<1432676318-22852-2-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr>
In-Reply-To
<1432676318-22852-1-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr>

Check if commits were removed (i.e. a line was deleted) or dupplicated (e.g. the same commit is picked twice), can print warnings or abort git rebase according to the value of the configuration variable rebase.checkLevel.

Add the configuration variable rebase.checkLevel.
    - When unset or set to "IGNORED", no checking is done.
    - When set to "WARN", the commits are checked, warnings are
      displayed but git rebase still proceeds.
    - When set to "ERROR", the commits are checked, warnings are
      displayed and the rebase is aborted.
Signed-off-by: Galan Rémi <remi.galan-alfonso@ensimag.grenoble-inp.fr>
---
 This part of the patch has no test yet, it is more for rfc.
 Documentation/config.txt     |  8 +++++
 Documentation/git-rebase.txt |  5 +++
 git-rebase--interactive.sh   | 76 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index d44bc85..2152e27 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2204,6 +2204,14 @@ rebase.autoStash::
 	successful rebase might result in non-trivial conflicts.
 	Defaults to false.
 
+rebase.checkLevel::
+	If set to "warn", git rebase -i will print a warning if some
+	commits are removed (i.e. a line was deleted) or if some
+	commits appear more than one time (e.g. the same commit is
+	picked twice), however the rebase will still proceed. If set
+	to "error", it will print the previous warnings and abort the
+	rebase.
+
 receive.advertiseAtomic::
 	By default, git-receive-pack will advertise the atomic push
 	capability to its clients. If you don't want to this capability
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 3cd2ef2..cb05cbb 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -213,6 +213,11 @@ rebase.autoSquash::
 rebase.autoStash::
 	If set to true enable '--autostash' option by default.
 
+rebase.checkLevel::
+	If set to "warn" print warnings about removed commits and
+	duplicated commits in interactive mode. If set to "error"
+	print the warnings and abort the rebase. No check by default.
+
 OPTIONS
 -------
 --onto <newbase>::
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index cb749e8..8a837ca 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -837,6 +837,80 @@ add_exec_commands () {
 	mv "$1.new" "$1"
 }
 
+# Print the list of the sha-1 of the commits
+# from a todo list in a file.
+# $1 : todo-file, $2 : outfile
+todo_list_to_sha_list () {
+	todo_list=$(git stripspace --strip-comments < "$1")
+	temp_file=$(mktemp)
+	echo "$todo_list" > "$temp_file"
+	while read -r command sha1 rest < "$temp_file"
+	do
+		case "$command" in
+		x|"exec")
+			;;
+		*)
+			echo "$sha1" >> "$2"
+			;;
+		esac
+		sed -i '1d' "$temp_file"
+	done
+	rm "$temp_file"
+}
+
+# Check if the user dropped some commits by mistake
+# or if there are two identical commits.
+# Behaviour determined by .gitconfig.
+check_commits () {
+	checkLevel=$(git config --get rebase.checkLevel)
+	checkLevel=${checkLevel:-"IGNORE"}
+	# To uppercase
+	checkLevel=$(echo "$checkLevel" | tr '[:lower:]' '[:upper:]')
+
+	case "$checkLevel" in
+	"WARN"|"ERROR")
+		todo_list_to_sha_list "$todo".backup "$todo".oldsha1
+		todo_list_to_sha_list "$todo" "$todo".newsha1
+
+		duplicates=$(sort "$todo".newsha1 | uniq -d)
+
+		echo "$(sort -u "$todo".oldsha1)" > "$todo".oldsha1
+		echo "$(sort -u "$todo".newsha1)" > "$todo".newsha1
+		missing=$(comm -2 -3 "$todo".oldsha1 "$todo".newsha1)
+
+		# check missing commits
+		if ! test -z "$missing"
+		then
+			warn "Warning : some commits may have been dropped accidentally."
+			warn "Dropped commits:"
+			warn "$missing"
+			warn "To avoid this message, use \"drop\" to explicitely remove a commit."
+			warn "Use git --config rebase.checkLevel to change"
+			warn "the level of warnings (ignore,warn,error)."
+			warn ""
+
+			if test "$checkLevel" = "ERROR"
+			then
+				die_abort "Rebase aborted due to dropped commits."
+			fi
+		fi
+
+		# check duplicate commits
+		if ! test -z "$duplicates"
+		then
+			warn "Warning : some commits have been used twice:"
+			warn "$duplicates"
+			warn ""
+		fi
+		;;
+	"IGNORE")
+		;;
+	*)
+		warn "Unrecognized setting for option rebase.checkLevel in git rebase -i"
+		;;
+	esac
+}
+
 # The whole contents of this file is run by dot-sourcing it from
 # inside a shell function.  It used to be that "return"s we see
 # below were not inside any function, and expected to return
@@ -1082,6 +1156,8 @@ has_action "$todo" ||
 
 expand_todo_ids
 
+check_commits
+
 test -d "$rewritten" || test -n "$force_rebase" || skip_unnecessary_picks
 
 GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
-- 
2.4.1.174.g28bfe8e
Previous: Galan RémiNext: Eric Sunshine
Message 2 of 24 in “git-rebase -i: Add key word "drop" to remove a commit”
  1. 1/2 git-rebase -i: Add key word "drop" to remove a commitGalan Rémi, May 26, 2015
  2. 2/2 git rebase -i: Warn removed or dupplicated commitsGalan Rémi, May 26, 2015
  3. Eric SunshineMay 26, 2015
  4. Remi Galan AlfonsoMay 27, 2015
  5. Eric SunshineMay 27, 2015
  6. Junio C HamanoMay 27, 2015
  7. Remi Galan AlfonsoMay 28, 2015
  8. Junio C HamanoMay 28, 2015
  9. Remi Galan AlfonsoMay 27, 2015
  10. Stephen KellyMay 27, 2015
  11. Matthieu MoyMay 27, 2015
  12. Junio C HamanoMay 27, 2015
  13. Eric SunshineMay 26, 2015
  14. Johannes SchindelinMay 27, 2015
  15. Remi Galan AlfonsoMay 27, 2015
  16. Matthieu MoyMay 27, 2015
  17. Junio C HamanoMay 27, 2015
  18. Matthieu MoyMay 27, 2015
  19. Junio C HamanoMay 27, 2015
  20. Stefan BellerMay 27, 2015
  21. Johannes SchindelinMay 28, 2015
  22. Stefan BellerMay 28, 2015
  23. Matthieu MoyMay 28, 2015
  24. Philip OakleyMay 27, 2015

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.