All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Galan Rémi" <remi.galan-alfonso@ensimag.grenoble-inp.fr>
To: Git List <git@vger.kernel.org>
Cc: "Remi Lespinet" <remi.lespinet@ensimag.grenoble-inp.fr>,
	"Guillaume Pages" <guillaume.pages@ensimag.grenoble-inp.fr>,
	"Louis-Alexandre Stuber"
	<louis--alexandre.stuber@ensimag.grenoble-inp.fr>,
	"Antoine Delaite" <antoine.delaite@ensimag.grenoble-inp.fr>,
	"Matthieu Moy" <Matthieu.Moy@grenoble-inp.fr>,
	"Junio C Hamano" <gitster@pobox.com>,
	"Johannes Schindelin" <johannes.schindelin@gmx.de>,
	"Stefan Beller" <sbeller@google.com>,
	"Philip Oakley" <philipoakley@iee.org>,
	"Eric Sunshine" <sunshine@sunshineco.com>,
	"Stephen Kelly" <steveire@gmail.com>,
	"Galan Rémi" <remi.galan-alfonso@ensimag.grenoble-inp.fr>
Subject: [PATCH/RFCv2 2/2] git rebase -i: warn about removed commits
Date: Mon,  1 Jun 2015 11:57:23 +0200	[thread overview]
Message-ID: <1433152643-4292-3-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr> (raw)
In-Reply-To: <1433152643-4292-1-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr>

Check if commits were removed (i.e. a line was deleted) and 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 "ignore", 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.

rebase.checkLevel defaults to "ignore".

Signed-off-by: Galan Rémi <remi.galan-alfonso@ensimag.grenoble-inp.fr>
---
 Documentation/config.txt      |   9 ++++
 Documentation/git-rebase.txt  |   6 +++
 git-rebase--interactive.sh    | 105 ++++++++++++++++++++++++++++++++++++++++++
 t/t3404-rebase-interactive.sh |  10 +++-
 4 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5f76e8c..e2e5554 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2160,6 +2160,15 @@ 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. If set to "ignore", no checking is done.  Defaults to
+	"ignore".
+
 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 9cf3760..d348ca2 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -213,6 +213,12 @@ 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. If set to "ignore" no
+	checking is done. "ignore" by default.
+
 OPTIONS
 -------
 --onto <newbase>::
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 2882276..58da6ee 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -837,6 +837,109 @@ 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
+	do
+		case $command in
+		x|"exec")
+			;;
+		*)
+			printf "%s\n" "$sha1"
+			;;
+		esac
+	done <$temp_file >"$2"
+	rm $temp_file
+}
+
+# Transforms SHA-1 list in argument
+# to a list of commits (in place)
+# Doesn't check if the SHA-1 are commits.
+# $1: file with long SHA-1 list
+long_sha_to_commit_list () {
+	short_missing=""
+	git_command="git show --oneline"
+	get_line_command="head -n 1"
+	temp_file=$(mktemp)
+	while read -r sha
+	do
+		if test -n "$sha"
+		then
+			commit=$($git_command $sha | $get_line_command)
+			if test -n "$commit"
+			then
+				printf "%s\n" "$commit"
+			fi
+		fi
+	done <"$1" >$temp_file
+	mv $temp_file "$1"
+}
+
+# Use warn for each line of a file
+# $1: file to warn
+warn_file () {
+	while read -r line
+	do
+		warn " - $line"
+	done <"$1"
+}
+
+# Check if the user dropped some commits by mistake
+# Behaviour determined by .gitconfig.
+check_commits () {
+	checkLevel=$(git config --get rebase.checkLevel)
+	checkLevel=${checkLevel:-ignore}
+	# To lowercase
+	checkLevel=$(echo "$checkLevel" | tr 'A-Z' 'a-z')
+
+	case "$checkLevel" in
+	warn|error)
+		# Get the SHA-1 of the commits
+		todo_list_to_sha_list "$todo".backup "$todo".oldsha1
+		todo_list_to_sha_list "$todo" "$todo".newsha1
+
+		# Sort the SHA-1 and compare them
+		echo "$(sort -u "$todo".oldsha1)" >"$todo".oldsha1
+		echo "$(sort -u "$todo".newsha1)" >"$todo".newsha1
+		echo "$(comm -2 -3 "$todo".oldsha1 "$todo".newsha1)" >"$todo".miss
+
+		# Make the list user-friendly
+		long_sha_to_commit_list "$todo".miss
+
+		# Check missing commits
+		if test -s "$todo".miss
+		then
+			warn "Warning : some commits may have been dropped" \
+				"accidentally."
+			warn "Dropped commits (in no relevent order):"
+			warn_file "$todo".miss
+			warn ""
+			warn "To avoid this message, use \"drop\" to" \
+				"explicitly remove a commit."
+			warn "Use git --config rebase.checkLevel to change" \
+				"the level of warnings (ignore,warn,error)."
+			warn ""
+
+			if test "$checkLevel" = error
+			then
+				die_abort "Rebase aborted due to dropped commits."
+			fi
+		fi
+		;;
+	ignore)
+		;;
+	*)
+		warn "Unrecognized setting $checkLevel 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
@@ -1079,6 +1182,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"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1bad068..d3a9ed5 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1103,7 +1103,6 @@ test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '
 '
 
 test_expect_success 'drop' '
-	git checkout master &&
 	test_when_finished "git checkout master" &&
 	git checkout -b dropBranchTest master &&
 	set_fake_editor &&
@@ -1113,4 +1112,13 @@ test_expect_success 'drop' '
 	test A = $(git cat-file commit HEAD^^ | sed -ne \$p)
 '
 
+test_expect_success 'rebase -i respects rebase.checkLevel' '
+	test_config rebase.checkLevel error &&
+	test_when_finished "git checkout master" &&
+	git checkout -b tmp2 master &&
+	set_fake_editor &&
+	test_must_fail env FAKE_LINES="1 2 3 4" git rebase -i --root &&
+	test E = $(git cat-file commit HEAD | sed -ne \$p)
+'
+
 test_done
-- 
2.4.1.363.g9535a9c

  parent reply	other threads:[~2015-06-01  9:57 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-01  9:57 [PATCH/RFCv2 0/2] rebase -i : drop command and removed commits Galan Rémi
2015-06-01  9:57 ` [PATCH/RFCv2 1/2] git-rebase -i: add command "drop" to remove a commit Galan Rémi
2015-06-01 16:39   ` Junio C Hamano
2015-06-01 17:06     ` Matthieu Moy
2015-06-01 17:45     ` Remi Galan Alfonso
2015-06-01 18:36       ` Matthieu Moy
2015-06-02  7:23         ` Remi Galan Alfonso
2015-06-02  7:45           ` Matthieu Moy
2015-06-02 17:14             ` Junio C Hamano
2015-06-03  9:13               ` Remi Galan Alfonso
2015-06-03 17:52                 ` Junio C Hamano
2015-06-01  9:57 ` Galan Rémi [this message]
2015-06-01 11:52 Galan Rémi
2015-06-01 11:52 ` [PATCH/RFCv2 2/2] git rebase -i: warn about removed commits Galan Rémi
2015-06-01 23:16   ` Eric Sunshine
2015-06-01 23:17     ` Eric Sunshine
2015-06-02  7:42     ` Remi Galan Alfonso
2015-06-02 13:41       ` Eric Sunshine
2015-06-02 13:51         ` Remi Galan Alfonso
2015-06-02  6:40   ` Matthieu Moy
2015-06-02  9:23     ` Remi Galan Alfonso
2015-06-02 17:17     ` Junio C Hamano
2015-06-03 11:44 [PATCH/RFCv4 1/2] git-rebase -i: add command "drop" to remove a commit Galan Rémi
2015-06-03 11:44 ` [PATCH/RFCv4 2/2] git rebase -i: warn about removed commits Galan Rémi
2015-06-03 19:14   ` [PATCH/RFCv2 " Eric Sunshine
2015-06-03 20:09     ` Remi Galan Alfonso
2015-06-06 23:45       ` Remi Galan Alfonso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1433152643-4292-3-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr \
    --to=remi.galan-alfonso@ensimag.grenoble-inp.fr \
    --cc=Matthieu.Moy@grenoble-inp.fr \
    --cc=antoine.delaite@ensimag.grenoble-inp.fr \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=guillaume.pages@ensimag.grenoble-inp.fr \
    --cc=johannes.schindelin@gmx.de \
    --cc=louis--alexandre.stuber@ensimag.grenoble-inp.fr \
    --cc=philipoakley@iee.org \
    --cc=remi.lespinet@ensimag.grenoble-inp.fr \
    --cc=sbeller@google.com \
    --cc=steveire@gmail.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.