threads / patch / 30700

patchrebase [-i --exec | -ix] <CMD>...

Subject: [PATCH] rebase [-i --exec | -ix] <CMD>...

## tl;dr

50 messages between Jun 4, 2012 and Jun 14, 2012. Diffs are folded; open one to read it.

replies: 49people: 8as markdown or json

Kong Lucien· Jun 4, 2012, 13:47 UTC · lore

This patch provides a way to automatically add these "exec" lines between each commit applications. For instance, running 'git rebase -i --exec "make test"' lets you check that intermediate commits are compilable. At this point, you can't use --exec without the interactive mode (-i).

Tests about this new command are also added in t3404-rebase-interactive.sh.

Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
 Documentation/git-rebase.txt  |   43 ++++++++++++++++++++++-
 git-rebase--interactive.sh    |   13 +++++++
 git-rebase.sh                 |   35 +++++++++++++++++--
 t/t3404-rebase-interactive.sh |   74 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 159 insertions(+), 6 deletions(-)
Show changes to 4 files +159 −6

Documentation/git-rebase.txt, git-rebase--interactive.sh, git-rebase.sh, t/t3404-rebase-interactive.sh

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 147fa1a..96dbf26 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
 	[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 	--root [<branch>]
 'git rebase' --continue | --skip | --abort
 
@@ -210,6 +210,17 @@ rebase.autosquash::
 
 OPTIONS
 -------
+<cmd>::
+	Shell command executed between each commit applications. The
+	--exec option has to be specified.
++
+You may execute several commands between each commit applications.
+Therefore, you can use one instance of exec:
+	git rebase -i --exec "cmd1; cmd2; ...".
+You can also insert several instances of exec, if you wish to
+only have one command per line for example:
+	git rebase -i --exec "cmd1" --exec "cmd2" ...
+
 <newbase>::
 	Starting point at which to create the new commits. If the
 	--onto option is not specified, the starting point is
@@ -336,6 +347,13 @@ link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for details).
 	user edit that list before rebasing.  This mode can also be used to
 	split commits (see SPLITTING COMMITS below).
 
+-x::
+--exec::
+	Automatically add "exec" followed by <cmd> between each commit
+	applications (see INTERACTIVE MODE below).
++
+This has to be used along with the `--interactive` option explicitly.
+
 -p::
 --preserve-merges::
 	Instead of ignoring merges, try to recreate them.
@@ -521,6 +539,27 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can
 use shell features (like "cd", ">", ";" ...). The command is run from
 the root of the working tree.
 
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
+If the option '-i' is missing, The command will return the usage page
+of "git rebase". Same if there is no <cmd> specified behind --exec.
+
 SPLITTING COMMITS
 -----------------
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0c19b7c..7444160 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -876,6 +876,19 @@ cat >> "$todo" << EOF
 #
 EOF
 
+if test -n "$cmd"
+then
+	OIFS=$IFS
+	IFS=','
+	for i in $cmd
+	do
+		sed "/^pick .*/aexec $i" "$todo" >tmp
+		cat tmp >"$todo"
+	done
+	rm tmp
+	IFS=$OIFS
+fi
+
 if test -z "$keep_empty"
 then
 	echo "# Note that empty commits are commented out" >>"$todo"
diff --git a/git-rebase.sh b/git-rebase.sh
index 24a2840..a8b1793 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -30,8 +31,8 @@ Example:       git-rebase master~1 topic
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
 git-rebase [-i] --continue | --abort | --skip
 --
  Available options are
@@ -43,6 +44,7 @@ s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
 m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
+x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
@@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
+unset cmd
 strategy=
 strategy_opts=
 do_merge=
@@ -219,6 +222,24 @@ do
 		onto="$2"
 		shift
 		;;
+	-x)
+		exec_flag=true
+		test 3 -le "$#" || usage
+		if orig_head=$(git rev-parse -q --verify "$2") ||
+		   test `expr substr "$2" 1 1` = -
+		then
+			echo "You must specify a command after --exec option\n"
+			usage
+		else
+			if test -n "$cmd"
+			then
+				cmd="$2,$cmd"
+			else
+				cmd="$2"
+			fi
+		fi
+		shift
+		;;
 	-i)
 		interactive_rebase=explicit
 		;;
@@ -304,6 +325,13 @@ do
 done
 test $# -gt 2 && usage
 
+if test -n "$exec_flag" &&
+   test -z "$interactive_rebase"
+then
+	echo "--exec option must be used with --interactive option\n"
+	usage
+fi
+
 if test -n "$action"
 then
 	test -z "$in_progress" && die "No rebase in progress?"
@@ -348,7 +376,6 @@ abort)
 	exit
 	;;
 esac
-
 # Make sure no rebase is in progress
 if test -n "$in_progress"
 then
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 025c1c6..2976f07 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -755,4 +755,78 @@ test_expect_success 'rebase-i history with funny messages' '
 	test_cmp expect actual
 '
 
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+	git checkout master &&
+	git checkout -b execute &&
+	test_commit one_exec main.txt one_exec &&
+	test_commit two_exec main.txt two_exec &&
+	test_commit three_exec main.txt three_exec &&
+	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+	git rebase -ix "git show HEAD" HEAD~2 >actual &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+	git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+	git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+				exec_git_show_HEAD exec_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,11d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message and usage ' '
+	test_must_fail git rebase --exec "git show HEAD" HEAD~2 >actual &&
+	echo "--exec option must be used with --interactive option\n" >expected &&
+	test_must_fail git rebase -h >>expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD> shows error message and usage ' '
+	test_must_fail git rebase -i --exec HEAD~2>actual &&
+	echo "You must specify a command after --exec option\n" >expected &&
+	test_must_fail git rebase -h >>expected &&
+	test_cmp expected actual &&
+	git checkout master
+'
+
 test_done
-- 
1.7.8
Junio C Hamano· Jun 4, 2012, 17:42 UTC · re: Kong Lucien · lore

Re: [PATCH] rebase [-i --exec | -ix] <CMD>...

Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:
Show 19 quoted lines
> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
> index 147fa1a..96dbf26 100644
> --- a/Documentation/git-rebase.txt
> +++ b/Documentation/git-rebase.txt
> @@ -210,6 +210,17 @@ rebase.autosquash::
>  
>  OPTIONS
>  -------
> +<cmd>::
> +	Shell command executed between each commit applications. The
> +	--exec option has to be specified.
> ++
> +You may execute several commands between each commit applications.
> +Therefore, you can use one instance of exec:
> +	git rebase -i --exec "cmd1; cmd2; ...".
> +You can also insert several instances of exec, if you wish to
> +only have one command per line for example:
> +	git rebase -i --exec "cmd1" --exec "cmd2" ...
> +

The description of this and exisitng <newbase> look very odd. The usual way to describe an option that take a parameter in the OPTIONS section is to instead do:

	--onto <newbase>::
		Description of what --onto option does and how <newbase>
		is used in what it does.
	--exec <cmd>::
		Description of what --exec option does, and how	<cmd> 
                is used in what it does.
Show 11 quoted lines
> @@ -336,6 +347,13 @@ link:howto/revert-a-faulty-me
>  	user edit that list before rebasing.  This mode can also be used to
>  	split commits (see SPLITTING COMMITS below).
>  
> +-x::
> +--exec::
> +	Automatically add "exec" followed by <cmd> between each commit
> +	applications (see INTERACTIVE MODE below).
> ++
> +This has to be used along with the `--interactive` option explicitly.
> +
OK.
> @@ -521,6 +539,27 @@ in `$SHELL`, or the default shell if
> ...
> +If the option '-i' is missing, The command will return the usage page
> +of "git rebase". Same if there is no <cmd> specified behind --exec.
OK.
Show 20 quoted lines
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index 0c19b7c..7444160 100644
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -876,6 +876,19 @@ cat >> "$todo" << EOF
>  #
>  EOF
>  
> +if test -n "$cmd"
> +then
> +	OIFS=$IFS
> +	IFS=','
> +	for i in $cmd
> +	do
> +		sed "/^pick .*/aexec $i" "$todo" >tmp
> +		cat tmp >"$todo"
> +	done
> +	rm tmp
> +	IFS=$OIFS
> +fi

Where does this "we split at comma", implying "the user is forbidden to have a comma in the executed command and its arguments" come from?

A more conventional way that would be less troublesome in the real life is to use LF instead in a case like this (and git-rebase.sh already defines it for exactly a case like this).

I am not sure if that "aexec" is portable outside GNUism, though. Traditionally the a(ppend) command is spelled like this:

	[1addr]a\
        text
to write one line (cf. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html#tag_20_116_13_03).

Why is "pick" special? Don't you want to run the commands after "edit", "reword", "squash", "fixup"?

This should come immediately after autosquash rearranged the insns in the $todo file, before the help text is appended to it.

Show 12 quoted lines
> diff --git a/git-rebase.sh b/git-rebase.sh
> index 24a2840..a8b1793 100755
> --- a/git-rebase.sh
> +++ b/git-rebase.sh
> @@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
>  To check out the original branch and stop rebasing run \"git rebase --abort\".
>  "
>  unset onto
> +unset cmd
>  strategy=
>  strategy_opts=
>  do_merge=

You copied badness from the existing "unset onto"; I do not think the rest of the code (and especially the new code you add) treats a variable that is not set and set to an empty string any different, and setting it to empty is the right thing to do in such a case.

Show 6 quoted lines
> @@ -219,6 +222,24 @@ do
>  		onto="$2"
>  		shift
>  		;;
> +	-x)
> +		exec_flag=true

exec_flag is not cleared at the beginning of the script, so if the command is run without "-x" on the command line, it can have whatever garbage value that was in the environment. You know that $cmd is empty if "-x" was not given, and you can make sure $cmd becomes non-empty when "-x" is given, so remove use of this variable and replace any 'test -n "$exec_flag"' with 'test -n "$cmd"'.

> +		test 3 -le "$#" || usage

Why 3? You only care about the presense of $2 you are about to read, no?

Show 15 quoted lines
> +		if orig_head=$(git rev-parse -q --verify "$2") ||
> +		   test `expr substr "$2" 1 1` = -
> +		then
> +			echo "You must specify a command after --exec option\n"
> +			usage
> +		else
> +			if test -n "$cmd"
> +			then
> +				cmd="$2,$cmd"
> +			else
> +				cmd="$2"
> +			fi
> +		fi
> +		shift
> +		;;

Are you telling me that I cannot have a branch named "make"? Drop this nonsense, and just write it in a more straightforward way, e.g.

	-x)
		test 2 -le "$#" || usage
                cmd="${cmd:+"$cmd$LF"} $2"
                shift
                ;;
                
Show 10 quoted lines
>  	-i)
>  		interactive_rebase=explicit
>  		;;
> @@ -304,6 +325,13 @@ do
>  done
>  test $# -gt 2 && usage
>  
> +if test -n "$exec_flag" &&
> +   test -z "$interactive_rebase"
> +then
I think this should be
	if test -n "$cmd" && test "$interactive_rebase" != explicit
        then
Show 8 quoted lines
> @@ -348,7 +376,6 @@ abort)
>  	exit
>  	;;
>  esac
> -
>  # Make sure no rebase is in progress
>  if test -n "$in_progress"
>  then
Why?
Matthieu Moy· Jun 4, 2012, 20:30 UTC · re: Junio C Hamano · lore

Re: [PATCH] rebase [-i --exec | -ix] <CMD>...

Junio C Hamano <gitster@pobox.com> writes:
Show 11 quoted lines
> The description of this and exisitng <newbase> look very odd.  The
> usual way to describe an option that take a parameter in the OPTIONS
> section is to instead do:
>
> 	--onto <newbase>::
> 		Description of what --onto option does and how <newbase>
> 		is used in what it does.
>
> 	--exec <cmd>::
> 		Description of what --exec option does, and how	<cmd> 
>                 is used in what it does.

(to the authors: you can add a trivial patch to fix the --onto doc, and base your work on it)

> Why is "pick" special?  Don't you want to run the commands after
> "edit", "reword", "squash", "fixup"?
I'd actually say you want to run it after a squash/fixup serie only.
If the result of --autosquash is

pick foo fixup bar fixup boz pick foobar

I think you want to rewrite it as

pick foo fixup bar fixup boz exec make pick foobar exec make

The command is typically used to check that each new commit is OK, but we can forget about the intermediate states as we are precisely getting rid of them.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Junio C Hamano· Jun 4, 2012, 21:06 UTC · re: Matthieu Moy · lore

Re: [PATCH] rebase [-i --exec | -ix] <CMD>...

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
Show 17 quoted lines
> I'd actually say you want to run it after a squash/fixup serie only.
>
> If the result of --autosquash is
>
> pick foo
> fixup bar
> fixup boz
> pick foobar
>
> I think you want to rewrite it as
>
> pick foo
> fixup bar
> fixup boz
> exec make
> pick foobar
> exec make
That makes sense.
konglu@minatec.inpg.fr· Jun 5, 2012, 17:59 UTC · re: Junio C Hamano · lore

Re: [PATCH] rebase [-i --exec | -ix] <CMD>...

Junio C Hamano <gitster@pobox.com> a écrit :
Show 24 quoted lines
>> +		if orig_head=$(git rev-parse -q --verify "$2") ||
>> +		   test `expr substr "$2" 1 1` = -
>> +		then
>> +			echo "You must specify a command after --exec option\n"
>> +			usage
>> +		else
>> +			if test -n "$cmd"
>> +			then
>> +				cmd="$2,$cmd"
>> +			else
>> +				cmd="$2"
>> +			fi
>> +		fi
>> +		shift
>> +		;;
>
> Are you telling me that I cannot have a branch named "make"?  Drop
> this nonsense, and just write it in a more straightforward way, e.g.
>
> 	-x)
> 		test 2 -le "$#" || usage
>                 cmd="${cmd:+"$cmd$LF"} $2"
>                 shift
>                 ;;

I agree with the fact that the code must not restrain you in naming branches. But shouldn't we keep the "test `expr substr "$2" 1 1` = -" part so that options can't be right after the "--exec" ?

Junio C Hamano· Jun 5, 2012, 18:13 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCH] rebase [-i --exec | -ix] <CMD>...

konglu@minatec.inpg.fr writes:
> But shouldn't we keep the "test `expr substr "$2" 1 1` = -" part so that
> options can't be right after the "--exec" ?

No. We have no reason to forbid users from giving their commands names that begin with "-", and if it is a typo, "exec" machinery will catch it and tell the user "no such command". I do not see any good reason to be clever in the part of the command parsing loop that handles "--exec <cmd>" option.

Matthieu Moy· Jun 4, 2012, 17:48 UTC · re: Kong Lucien · lore

Re: [PATCH] rebase [-i --exec | -ix] <CMD>...

Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:
Show 21 quoted lines
> --- a/Documentation/git-rebase.txt
> +++ b/Documentation/git-rebase.txt
> @@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
>  SYNOPSIS
>  --------
>  [verse]
> -'git rebase' [-i | --interactive] [options] [--onto <newbase>]
> +'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
>  	[<upstream>] [<branch>]
> -'git rebase' [-i | --interactive] [options] --onto <newbase>
> +'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
>  	--root [<branch>]
>  'git rebase' --continue | --skip | --abort
>  
> @@ -210,6 +210,17 @@ rebase.autosquash::
>  
>  OPTIONS
>  -------
> +<cmd>::
> +	Shell command executed between each commit applications. The
> +	--exec option has to be specified.
[...]
> +-x::
> +--exec::

That seems weird to have --exec <cmd> specification split into one for --exec, and another for <cmd> ...

> +You may execute several commands between each commit applications.
> +Therefore, you can use one instance of exec:
> +	git rebase -i --exec "cmd1; cmd2; ...".
s/Therefore/For this/ ?
(Therefore = donc in French)
Show 10 quoted lines
> +if test -n "$cmd"
> +then
> +	OIFS=$IFS
> +	IFS=','
> +	for i in $cmd
> +	do
> +		sed "/^pick .*/aexec $i" "$todo" >tmp
> +		cat tmp >"$todo"
> +	done
> +	rm tmp

Isn't this executed from the top of the workdir? What if the user already has a file named tmp there?

Show 6 quoted lines
> +			if test -n "$cmd"
> +			then
> +				cmd="$2,$cmd"
> +			else
> +				cmd="$2"
> +			fi

What happens when <cmd> contains a comma (e.g. --exec "rm file,with,commas,in,name.txt") ?

If you don't allow this case, then you should error out instead of executing a weird behavior silently. Or you can escape the comma and unescape it later, but that may be overkill.

Show 6 quoted lines
> +if test -n "$exec_flag" &&
> +   test -z "$interactive_rebase"
> +then
> +	echo "--exec option must be used with --interactive option\n"
> +	usage
> +fi

I'd even skip the "usage" here, as the error message is clear enough (and is much less visible before a page of "usage" output). Just die-ing would be better I think.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Lucien Kong· Jun 6, 2012, 10:34 UTC · re: Kong Lucien · lore

[PATCHv2] rebase [-i --exec | -ix] <CMD>...

This patch provides a way to automatically add these "exec" lines between each commit applications. For instance, running 'git rebase -i --exec "make test"' lets you check that intermediate commits are compilable. It is also compatible with the option --autosquash. At this point, you can't use --exec without the interactive mode (-i).

Tests about this new command are also added in t3404-rebase-interactive.sh.

Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
The part of --onto in the documentation is changed to be consistent
with the other options. The exec line, when using the option --autosquash,
is now only added after the squash/fixup series.
 Documentation/git-rebase.txt  |   54 +++++++++++++++--
 git-rebase--interactive.sh    |   19 ++++++
 git-rebase.sh                 |   20 ++++++-
 t/t3404-rebase-interactive.sh |  124 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 207 insertions(+), 10 deletions(-)
Show changes to 4 files +207 −10

Documentation/git-rebase.txt, git-rebase--interactive.sh, git-rebase.sh, t/t3404-rebase-interactive.sh

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 147fa1a..1dd95c4 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
 	[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 	--root [<branch>]
 'git rebase' --continue | --skip | --abort
 
@@ -210,11 +210,29 @@ rebase.autosquash::
 
 OPTIONS
 -------
-<newbase>::
-	Starting point at which to create the new commits. If the
-	--onto option is not specified, the starting point is
-	<upstream>.  May be any valid commit, and not just an
-	existing branch name.
+-x <cmd>::
+--exec <cmd>::
+	Automatically add "exec" followed by <cmd> between each commit
+	applications. Using this option along with --autosquash adds
+	the exec line after the squash/fixeup series only. <cmd>
+	stands for shell commands. The --exec option has to be
+	specified. (see INTERACTIVE MODE below)
++
+This has to be used along with the `--interactive` option explicitly.
+You may execute several commands between each commit applications.
+For this, you can use one instance of exec:
+	git rebase -i --exec "cmd1; cmd2; ...".
+You can also insert several instances of exec, if you wish to
+only have one command per line for example:
+	git rebase -i --exec "cmd1" --exec "cmd2" ...
+
+--onto <newbase>::
+	With this option, git rebase takes all commits from <branch>,
+	that are not in <upstream>, and transplant them on top of
+	<newbase>. <newbase> is the starting point at which to create
+	the new commits. If the --onto option is not specified, the
+	starting point is <upstream>.  May be any valid commit, and
+	not just an existing branch name.
 +
 As a special case, you may use "A\...B" as a shortcut for the
 merge base of A and B if there is exactly one merge base. You can
@@ -521,6 +539,28 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can
 use shell features (like "cd", ">", ";" ...). The command is run from
 the root of the working tree.
 
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
+If the option '-i' is missing, The command will return a message
+error. If there is no <cmd> specified behind --exec, the command will
+return a message error and the usage page of 'git rebase'.
+
 SPLITTING COMMITS
 -----------------
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0c19b7c..3539afd 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -684,6 +684,23 @@ rearrange_squash () {
 	rm -f "$1.sq" "$1.rearranged"
 }
 
+# Add commands after a pick or after a squash/fixup serie
+# in the todo list.
+add_exec_commands () {
+	OIFS=$IFS
+	IFS=$LF
+	for i in $cmd
+	do
+		tmp=$(sed "/^pick .*/i\
+				exec $i" "$1")
+		echo "$tmp" >"$1"
+		tmp=$(sed '1d' "$1")
+		echo "$tmp" >"$1"
+		echo "exec $i" >>"$1"
+	done
+	IFS=$OIFS
+}
+
 case "$action" in
 continue)
 	# do we have anything to commit?
@@ -857,6 +874,8 @@ fi
 
 test -s "$todo" || echo noop >> "$todo"
 test -n "$autosquash" && rearrange_squash "$todo"
+test -n "$cmd" && add_exec_commands "$todo"
+
 cat >> "$todo" << EOF
 
 # Rebase $shortrevisions onto $shortonto
diff --git a/git-rebase.sh b/git-rebase.sh
index 24a2840..19ead1a 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -30,8 +31,8 @@ Example:       git-rebase master~1 topic
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
 git-rebase [-i] --continue | --abort | --skip
 --
  Available options are
@@ -43,6 +44,7 @@ s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
 m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
+x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
@@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
+cmd=
 strategy=
 strategy_opts=
 do_merge=
@@ -219,6 +222,11 @@ do
 		onto="$2"
 		shift
 		;;
+	-x)
+		test 2 -le "$#" || usage
+		cmd="${cmd:+"$cmd$LF"} $2"
+		shift
+		;;
 	-i)
 		interactive_rebase=explicit
 		;;
@@ -304,6 +312,12 @@ do
 done
 test $# -gt 2 && usage
 
+if test -n "$cmd" &&
+   test "$interactive_rebase" != explicit
+then
+	die "--exec option must be used with --interactive option\n"
+fi
+
 if test -n "$action"
 then
 	test -z "$in_progress" && die "No rebase in progress?"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 025c1c6..4fe98d5 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -755,4 +755,128 @@ test_expect_success 'rebase-i history with funny messages' '
 	test_cmp expect actual
 '
 
+
+test_expect_success 'prepare for rebase -i --exec' '
+	git checkout master &&
+	git checkout -b execute &&
+	test_commit one_exec main.txt one_exec &&
+	test_commit two_exec main.txt two_exec &&
+	test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+	git reset --hard execute &&
+	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+	git reset --hard execute &&
+	git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+				exec_git_show_HEAD exec_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,11d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+	git reset --hard execute &&
+	git checkout -b autosquash &&
+	echo second >second.txt &&
+	git add second.txt &&
+	git commit -m "fixup! two_exec" &&
+	echo bis >bis.txt &&
+	git add bis.txt &&
+	git commit -m "fixup! two_exec" &&
+	(
+		git checkout -b autosquash_actual &&
+		git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+	) &&
+	git checkout autosquash &&
+	(
+		git checkout -b autosquash_expected &&
+		FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~4 >expected
+	) &&
+	sed '1,13d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+	git reset --hard execute &&
+	test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+	echo "--exec option must be used with --interactive option\n" >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
+	git reset --hard execute &&
+	test_must_fail git rebase -i --exec 2>actual &&
+	sed '1d' actual >tmp &&
+	mv tmp actual &&
+	test_must_fail git rebase -h >expected &&
+	test_cmp expected actual &&
+	git checkout master
+'
+
 test_done
-- 
1.7.8
Matthieu Moy· Jun 6, 2012, 20:03 UTC · re: Lucien Kong · lore

Re: [PATCHv2] rebase [-i --exec | -ix] <CMD>...

Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:
Show 16 quoted lines
> @@ -210,11 +210,29 @@ rebase.autosquash::
>  
>  OPTIONS
>  -------
> -<newbase>::
> -	Starting point at which to create the new commits. If the
> -	--onto option is not specified, the starting point is
> -	<upstream>.  May be any valid commit, and not just an
> -	existing branch name.
> +-x <cmd>::
> +--exec <cmd>::
> +	Automatically add "exec" followed by <cmd> between each commit
> +	applications. Using this option along with --autosquash adds
> +	the exec line after the squash/fixeup series only. <cmd>
> +	stands for shell commands. The --exec option has to be
> +	specified. (see INTERACTIVE MODE below)

It would make sense to split that into two patches, one to fix --onto's documentation, and the next one to add --exec. I won't insist on that though (but maybe others will).

Show 8 quoted lines
> ++
> +This has to be used along with the `--interactive` option explicitly.
> +You may execute several commands between each commit applications.
> +For this, you can use one instance of exec:
> +	git rebase -i --exec "cmd1; cmd2; ...".
> +You can also insert several instances of exec, if you wish to
> +only have one command per line for example:
> +	git rebase -i --exec "cmd1" --exec "cmd2" ...

This formats badly in asciidoc (try "make doc" and see the generated HTML).

Try this:
This has to be used along with the `--interactive` option explicitly.
You may execute several commands between each commit applications.
For this, you can use one instance of exec:
+
	git rebase -i --exec "cmd1; cmd2; ...".
+
You can also insert several instances of exec, if you wish to
only have one command per line for example:
+
	git rebase -i --exec "cmd1" --exec "cmd2" ...
-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Junio C Hamano· Jun 6, 2012, 22:54 UTC · re: Lucien Kong · lore

Re: [PATCHv2] rebase [-i --exec | -ix] <CMD>...

Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:
> The part of --onto in the documentation is changed to be consistent
> with the other options. The exec line, when using the option --autosquash,
> is now only added after the squash/fixup series.
Thanks.

Inserting "exec" before each "pick" and then adjusting the result (i.e. removing the very first one and adding one at the end) is a clever idea. I wonder if that can be done without temporary variable whose value can grow to be a large string, though.

Queued, but I've tweaked the log message a bit before queuing.
Zbigniew Jędrzejewski-Szmek· Jun 7, 2012, 08:25 UTC · re: Lucien Kong · lore

Re: [PATCHv2] rebase [-i --exec | -ix] <CMD>...

On 06/06/2012 12:34 PM, Lucien Kong wrote:
Show 58 quoted lines
> This patch provides a way to automatically add these "exec" lines
> between each commit applications. For instance, running 'git rebase -i
> --exec "make test"' lets you check that intermediate commits are
> compilable. It is also compatible with the option --autosquash. At
> this point, you can't use --exec without the interactive mode (-i).
> 
> Tests about this new command are also added in
> t3404-rebase-interactive.sh.
> 
> Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
> Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
> Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
> Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
> Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
> Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
> ---
> The part of --onto in the documentation is changed to be consistent
> with the other options. The exec line, when using the option --autosquash,
> is now only added after the squash/fixup series.
> 
>  Documentation/git-rebase.txt  |   54 +++++++++++++++--
>  git-rebase--interactive.sh    |   19 ++++++
>  git-rebase.sh                 |   20 ++++++-
>  t/t3404-rebase-interactive.sh |  124 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 207 insertions(+), 10 deletions(-)
> 
> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
> index 147fa1a..1dd95c4 100644
> --- a/Documentation/git-rebase.txt
> +++ b/Documentation/git-rebase.txt
> @@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
>  SYNOPSIS
>  --------
>  [verse]
> -'git rebase' [-i | --interactive] [options] [--onto <newbase>]
> +'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
>  	[<upstream>] [<branch>]
> -'git rebase' [-i | --interactive] [options] --onto <newbase>
> +'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
>  	--root [<branch>]
>  'git rebase' --continue | --skip | --abort
>  
> @@ -210,11 +210,29 @@ rebase.autosquash::
>  
>  OPTIONS
>  -------
> -<newbase>::
> -	Starting point at which to create the new commits. If the
> -	--onto option is not specified, the starting point is
> -	<upstream>.  May be any valid commit, and not just an
> -	existing branch name.
> +-x <cmd>::
> +--exec <cmd>::
> +	Automatically add "exec" followed by <cmd> between each commit
> +	applications. Using this option along with --autosquash adds
> +	the exec line after the squash/fixeup series only. <cmd>
> +	stands for shell commands. The --exec option has to be
> +	specified. (see INTERACTIVE MODE below)
Hi,
this still doesn't seem right:
- "exec" is added *after* other lines, not *between*
- --exec is not mandatory
Maybe something along these lines:
-x <cmd>::
--exec <cmd>::
  Append "exec <cmd>" after each commit application line. <cmd> will
  be interpreted as one or more shell commands.
  +
  If --autosquash is used, the "exec" lines will not be appended for
  the intermediate commits, and will only appear at the end of each
  squash/fixup series.
> ++
> +This has to be used along with the `--interactive` option explicitly.
This sentence is very unclear. (E.g. is 'this'?)
Show 6 quoted lines
> +You may execute several commands between each commit applications.
> +For this, you can use one instance of exec:
> +	git rebase -i --exec "cmd1; cmd2; ...".
> +You can also insert several instances of exec, if you wish to
> +only have one command per line for example:
> +	git rebase -i --exec "cmd1" --exec "cmd2" ...
s/per line for example/per line. For example/ ?
Show 8 quoted lines
> +
> +--onto <newbase>::
> +	With this option, git rebase takes all commits from <branch>,
> +	that are not in <upstream>, and transplant them on top of
> +	<newbase>. <newbase> is the starting point at which to create
> +	the new commits. If the --onto option is not specified, the
> +	starting point is <upstream>.  May be any valid commit, and
> +	not just an existing branch name.
Shouldn't this chunk be a separate patch?
s/transplant/transplants/

-- Zbyszek

Johannes Sixt· Jun 7, 2012, 08:40 UTC · re: Lucien Kong · lore

Re: [PATCHv2] rebase [-i --exec | -ix] <CMD>...

Am 06.06.2012 12:34, schrieb Lucien Kong:
> This patch provides a way to automatically add these "exec" lines
> between each commit applications. For instance, running 'git rebase -i
> --exec "make test"' lets you check that intermediate commits are
> compilable.

While I won't be a heavy user of this feature, I think it has some merit as a porcelain feature, particularly because it is rather cumbersome to achieve the same effect as in the given example without plumbing commands.

> +-x <cmd>::
> +--exec <cmd>::
...
> ++
> +This has to be used along with the `--interactive` option explicitly.
...
> +
> +If the option '-i' is missing, The command will return a message
> +error. If there is no <cmd> specified behind --exec, the command will
> +return a message error and the usage page of 'git rebase'.

The important part (that -x needs -i) of this paragraph are already spelled out above, and the exact error behavior does not need a description in the manual. Drop this paragraph.

BTW, I don't think it is a good idea to dump the usage if -x was used without -i.

Show 9 quoted lines
> +# Add commands after a pick or after a squash/fixup serie
> +# in the todo list.
> +add_exec_commands () {
> +	OIFS=$IFS
> +	IFS=$LF
> +	for i in $cmd
> +	do
> +		tmp=$(sed "/^pick .*/i\
> +				exec $i" "$1")
Does this white-space before 'exec' not end up in the  todo list?

I think it is wise to use introduce sed expressions by using -e. This applies to all 'sed' invocations that this patch introduces (also in the test-suite).

> +		echo "$tmp" >"$1"

Some 'echo' implementations expand escape sequences in the supplied texts. To avoid it (this is user-supplied text!), do this:

		printf "%s\n" "$tmp" >"$1"
> +		tmp=$(sed '1d' "$1")
> +		echo "$tmp" >"$1"
> +		echo "exec $i" >>"$1"
Ditto.
> +	done
> +	IFS=$OIFS
> +}
> +	-x)
> +		test 2 -le "$#" || usage
> +		cmd="${cmd:+"$cmd$LF"} $2"

The quoting here is *very* odd. The outer dquotes do extend their effect into the replacement word after the :+ operator. I am surprised that so many shells grok it. ash does not, by the way. Also, you don't need the space anymore. Therefore:

		cmd="${cmd:+$cmd$LF}$2"
> +		shift
> +		;;
Show 8 quoted lines
> +test_expect_success 'running "git rebase -i --exec git show HEAD"' '
> +	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
> +	(
> +		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
> +		export FAKE_LINES &&
> +		git rebase -i HEAD~2 >expected
> +	) &&
> +	sed '1,9d' expected >expect &&

Here and everywhere else: Single quotes do not nest :-) use dquotes (and -e).

> +	mv expect expected &&
Why not
	( ... git rebase ... >expect ) &&
	sed -e ... expect >expected &&
without the mv?

You could even line up the commands in a pipeline, but since the first one contains a git command, it is better not to do that because breakage of the git command would not be detected if it is not the last command in the pipeline.

Show 5 quoted lines
> +test_expect_success 'rebase --exec without -i shows error message' '
> +	git reset --hard execute &&
> +	test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
> +	echo "--exec option must be used with --interactive option\n" >expected &&
> +	test_cmp expected actual
Sooner or later this text will be translated. Therefore:
	test_i18ncmp ...
-- Hannes
konglu@minatec.inpg.fr· Jun 7, 2012, 12:04 UTC · re: Johannes Sixt · lore

Re: [PATCHv2] rebase [-i --exec | -ix] <CMD>...

Johannes Sixt <j6t@kdbg.org> a écrit :
> BTW, I don't think it is a good idea to dump the usage if -x was used
> without -i.

In fact, that would be the next step, so that the "--exec" option could be used without the interactive mode.

Matthieu Moy· Jun 7, 2012, 13:43 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv2] rebase [-i --exec | -ix] <CMD>...

konglu@minatec.inpg.fr writes:
Show 7 quoted lines
> Johannes Sixt <j6t@kdbg.org> a écrit :
>
>> BTW, I don't think it is a good idea to dump the usage if -x was used
>> without -i.
>
> In fact, that would be the next step, so that the "--exec" option could
> be used without the interactive mode.

I think Jeff meant that a short error message would be better than showing the complete usage instruction, which indeed is already the case:

+if test -n "$cmd" &&
+   test "$interactive_rebase" != explicit
+then
+	die "--exec option must be used with --interactive option\n"
+fi
-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Lucien Kong· Jun 8, 2012, 14:53 UTC · re: Lucien Kong · lore

[PATCHv3 1/2] git-rebase.txt: "--onto" option updated

The description of the option "--onto" is changed to be consistent with the format of the other options.

Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
 Documentation/git-rebase.txt |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)
Show changes to Documentation/git-rebase.txt +7 −5
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 147fa1a..d2a510c 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -210,11 +210,13 @@ rebase.autosquash::
 
 OPTIONS
 -------
-<newbase>::
-	Starting point at which to create the new commits. If the
-	--onto option is not specified, the starting point is
-	<upstream>.  May be any valid commit, and not just an
-	existing branch name.
+--onto <newbase>::
+	With this option, git rebase takes all commits from <branch>,
+	that are not in <upstream>, and transplants them on top of
+	<newbase>. <newbase is the starting point at which to create
+	the new commits. If the --onto option is not specified, the
+	starting point is <upstream>.  May be any valid commit, and
+	not just an existing branch name.
 +
 As a special case, you may use "A\...B" as a shortcut for the
 merge base of A and B if there is exactly one merge base. You can
-- 
1.7.8
Lucien Kong· Jun 8, 2012, 14:53 UTC · re: Lucien Kong · lore

[PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

This patch provides a way to automatically add these "exec" lines between each commit applications. For instance, running 'git rebase -i --exec "make test"' lets you check that intermediate commits are compilable. It is also compatible with the option --autosquash. At this point, you can't use --exec without the interactive mode (-i).

Tests about this new command are also added in t3404-rebase-interactive.sh.

Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
Should now work on MacOS.
 Documentation/git-rebase.txt  |   43 ++++++++++++++-
 git-rebase--interactive.sh    |   18 ++++++
 git-rebase.sh                 |   20 ++++++-
 t/t3404-rebase-interactive.sh |  118 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 194 insertions(+), 5 deletions(-)
Show changes to 4 files +194 −5

Documentation/git-rebase.txt, git-rebase--interactive.sh, git-rebase.sh, t/t3404-rebase-interactive.sh

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index d2a510c..866b451 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
 	[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 	--root [<branch>]
 'git rebase' --continue | --skip | --abort
 
@@ -210,6 +210,27 @@ rebase.autosquash::
 
 OPTIONS
 -------
+-x <cmd>::
+--exec <cmd>::
+	Append "exec <cmd>" after each commit application line. <cmd>
+	will be interpreted as one or more shell commands (see
+	INTERACTIVE MODE below).
++
+This option has to be used along with the `--interactive` option
+explicitly.  You may execute several commands between each commit
+applications.  For this, you can use one instance of exec:
++
+	git rebase -i --exec "cmd1; cmd2; ...".
++
+You can also insert several instances of exec, if you wish to only
+have one command per line. For example:
++
+	git rebase -i --exec "cmd1" --exec "cmd2" ...
++
+If --autosquash is used, the "exec" lines will not be appended for the
+intermediate commits, and will only appear at the end of each
+squash/fixup series.
+
 --onto <newbase>::
 	With this option, git rebase takes all commits from <branch>,
 	that are not in <upstream>, and transplants them on top of
@@ -523,6 +544,24 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can
 use shell features (like "cd", ">", ";" ...). The command is run from
 the root of the working tree.
 
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
 SPLITTING COMMITS
 -----------------
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0c19b7c..7bbef4b 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -684,6 +684,22 @@ rearrange_squash () {
 	rm -f "$1.sq" "$1.rearranged"
 }
 
+# Add commands after a pick or after a squash/fixup serie
+# in the todo list.
+add_exec_commands () {
+	OIFS=$IFS
+	IFS=$LF
+	for i in $cmd
+	do
+		sed -e "/^pick .*/i\\
+exec $i" "$1" >"$1.exec"
+		sed -e '1d' "$1.exec" >"$1"
+		printf "%s\n" "exec $i" >>"$1"
+	done
+	IFS=$OIFS
+	rm -f "$1.exec"
+}
+
 case "$action" in
 continue)
 	# do we have anything to commit?
@@ -857,6 +873,8 @@ fi
 
 test -s "$todo" || echo noop >> "$todo"
 test -n "$autosquash" && rearrange_squash "$todo"
+test -n "$cmd" && add_exec_commands "$todo"
+
 cat >> "$todo" << EOF
 
 # Rebase $shortrevisions onto $shortonto
diff --git a/git-rebase.sh b/git-rebase.sh
index 24a2840..04dbf74 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -30,8 +31,8 @@ Example:       git-rebase master~1 topic
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
 git-rebase [-i] --continue | --abort | --skip
 --
  Available options are
@@ -43,6 +44,7 @@ s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
 m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
+x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
@@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
+cmd=
 strategy=
 strategy_opts=
 do_merge=
@@ -219,6 +222,11 @@ do
 		onto="$2"
 		shift
 		;;
+	-x)
+		test 2 -le "$#" || usage
+		cmd="${cmd:+$cmd$LF}$2"
+		shift
+		;;
 	-i)
 		interactive_rebase=explicit
 		;;
@@ -304,6 +312,12 @@ do
 done
 test $# -gt 2 && usage
 
+if test -n "$cmd" &&
+   test "$interactive_rebase" != explicit
+then
+	die "--exec option must be used with --interactive option\n"
+fi
+
 if test -n "$action"
 then
 	test -z "$in_progress" && die "No rebase in progress?"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 025c1c6..ba953ab 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -755,4 +755,122 @@ test_expect_success 'rebase-i history with funny messages' '
 	test_cmp expect actual
 '
 
+
+test_expect_success 'prepare for rebase -i --exec' '
+	git checkout master &&
+	git checkout -b execute &&
+	test_commit one_exec main.txt one_exec &&
+	test_commit two_exec main.txt two_exec &&
+	test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+	git reset --hard execute &&
+	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed '1,9d' expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed '1,9d' expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed '1,9d' expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+	git reset --hard execute &&
+	git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+				exec_git_show_HEAD exec_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed '1,11d' expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+	git reset --hard execute &&
+	git checkout -b autosquash &&
+	echo second >second.txt &&
+	git add second.txt &&
+	git commit -m "fixup! two_exec" &&
+	echo bis >bis.txt &&
+	git add bis.txt &&
+	git commit -m "fixup! two_exec" &&
+	(
+		git checkout -b autosquash_actual &&
+		git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+	) &&
+	git checkout autosquash &&
+	(
+		git checkout -b autosquash_expected &&
+		FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~4 >expect
+	) &&
+	sed '1,13d' expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+	git reset --hard execute &&
+	test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+	echo "--exec option must be used with --interactive option\n" >expected &&
+	test_i18ncmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
+	git reset --hard execute &&
+	test_must_fail git rebase -i --exec 2>actual &&
+	sed '1d' actual >tmp &&
+	mv tmp actual &&
+	test_must_fail git rebase -h >expected &&
+	test_cmp expected actual &&
+	git checkout master
+'
+
 test_done
-- 
1.7.8
Johannes Sixt· Jun 8, 2012, 17:02 UTC · re: Lucien Kong · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

Am 08.06.2012 16:53, schrieb Lucien Kong:
Show 5 quoted lines
> +if test -n "$cmd" &&
> +   test "$interactive_rebase" != explicit
> +then
> +	die "--exec option must be used with --interactive option\n"
> +fi
Is the \n really necessary?
> +	sed -e "1,9d" expect >expected &&

Good. But I said "Here and everywhere else". So I wonder about these lines ;)

Show 6 quoted lines
> +	sed '1,9d' expect >expected &&
> +	sed '1,9d' expect >expected &&
> +	sed '1,9d' expect >expected &&
> +	sed '1,11d' expect >expected &&
> +	sed '1,13d' expect >expected &&
> +	sed '1d' actual >tmp &&
-- Hannes
Torsten Bögershausen· Jun 8, 2012, 18:56 UTC · re: Lucien Kong · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

On 08.06.12 16:53, Lucien Kong wrote:
Show 8 quoted lines
> This patch provides a way to automatically add these "exec" lines
> between each commit applications. For instance, running 'git rebase -i
> --exec "make test"' lets you check that intermediate commits are
> compilable. It is also compatible with the option --autosquash. At
> this point, you can't use --exec without the interactive mode (-i).
> 
> Tests about this new command are also added in
> t3404-rebase-interactive.sh.
> Should now work on MacOS.

Hej, I'm not sure on which commit to apply the patch. (may be we shoud improve git format-patch to tell us the original commit ID), but if I remove the non applying part, it looks like this:

================= ok 54 - rebase-i history with funny messages

expecting success: 
	git checkout master &&
	git checkout -b execute &&
	test_commit one_exec main.txt one_exec &&
	test_commit two_exec main.txt two_exec &&
	test_commit three_exec main.txt three_exec
Switched to branch 'master'
Switched to a new branch 'execute'
[execute 925b01e] one_exec
 Author: A U Thor <author@example.com>
 1 file changed, 1 insertion(+)
 create mode 100644 main.txt
[execute 7f87cbe] two_exec
 Author: A U Thor <author@example.com>
 1 file changed, 1 insertion(+), 1 deletion(-)
[execute f0f177e] three_exec
 Author: A U Thor <author@example.com>
 1 file changed, 1 insertion(+), 1 deletion(-)
ok 55 - prepare for rebase -i --exec
expecting success: 
	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
	(
		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
		export FAKE_LINES &&
		git rebase -i HEAD~2 >expected
	) &&
	sed 1,9d expected >expect &&
	mv expect expected &&
	test_cmp expected actual
error: unknown option `exec'
usage: git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
   or: git rebase [-i] [options] --onto <newbase> --root [<branch>]
   or: git-rebase [-i] --continue | --abort | --skip
Available options are
    -v, --verbose         display a diffstat of what changed upstream
    -q, --quiet           be quiet. implies --no-stat
    --onto ...            rebase onto given branch instead of upstream
    -p, --preserve-merges
                          try to recreate merges instead of ignoring them
    -s, --strategy ...    use the given merge strategy
    --no-ff               cherry-pick all commits, even if unchanged
    -m, --merge           use merging strategies to rebase
    -i, --interactive     let the user edit the list of commits to rebase
    -k, --keep-empty	     preserve empty commits during rebase
    -f, --force-rebase    force rebase even if branch is up to date
    -X, --strategy-option ...
                          pass the argument through to the merge strategy
    --stat                display a diffstat of what changed upstream
    -n, --no-stat         do not show diffstat of what changed upstream
    --verify              allow pre-rebase hook to run
    --rerere-autoupdate   allow rerere to update index with resolved conflicts
    --root                rebase all reachable commits up to the root(s)
    --autosquash          move commits that begin with squash!/fixup! under -i
    --committer-date-is-author-date
                          passed to 'git am'
    --ignore-date         passed to 'git am'
    --whitespace ...      passed to 'git apply'
    --ignore-whitespace   passed to 'git apply'
    -C ...                passed to 'git apply'
Actions:
    --continue            continue
    --abort               abort and check out the original branch
    --skip                skip current patch and continue

not ok - 56 running "git rebase -i --exec git show HEAD" # # git rebase -i --exec "git show HEAD" HEAD~2 >actual && # ( # FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" && # export FAKE_LINES && # git rebase -i HEAD~2 >expected # ) && # sed 1,9d expected >expect && # mv expect expected && # test_cmp expected actual #

expecting success: 
	git reset --hard execute &&
	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
	(
		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
		export FAKE_LINES &&
		git rebase -i HEAD~2 >expected
	) &&
	sed 1,9d expected >expect &&
	mv expect expected &&
	test_cmp expected actual
HEAD is now at f0f177e three_exec
error: unknown option `exec'
usage: git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
   or: git rebase [-i] [options] --onto <newbase> --root [<branch>]
   or: git-rebase [-i] --continue | --abort | --skip
Available options are
    -v, --verbose         display a diffstat of what changed upstream
    -q, --quiet           be quiet. implies --no-stat
    --onto ...            rebase onto given branch instead of upstream
    -p, --preserve-merges
                          try to recreate merges instead of ignoring them
    -s, --strategy ...    use the given merge strategy
    --no-ff               cherry-pick all commits, even if unchanged
    -m, --merge           use merging strategies to rebase
    -i, --interactive     let the user edit the list of commits to rebase
    -k, --keep-empty	     preserve empty commits during rebase
    -f, --force-rebase    force rebase even if branch is up to date
    -X, --strategy-option ...
                          pass the argument through to the merge strategy
    --stat                display a diffstat of what changed upstream
    -n, --no-stat         do not show diffstat of what changed upstream
    --verify              allow pre-rebase hook to run
    --rerere-autoupdate   allow rerere to update index with resolved conflicts
    --root                rebase all reachable commits up to the root(s)
    --autosquash          move commits that begin with squash!/fixup! under -i
    --committer-date-is-author-date
                          passed to 'git am'
    --ignore-date         passed to 'git am'
    --whitespace ...      passed to 'git apply'
    --ignore-whitespace   passed to 'git apply'
    -C ...                passed to 'git apply'
Actions:
    --continue            continue
    --abort               abort and check out the original branch
    --skip                skip current patch and continue
not ok - 57 running "git rebase --exec git show HEAD -i"
konglu@minatec.inpg.fr· Jun 8, 2012, 19:15 UTC · re: Torsten Bögershausen · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

Torsten Bögershausen <tboegi@web.de> a écrit :
Show 16 quoted lines
> On 08.06.12 16:53, Lucien Kong wrote:
>> This patch provides a way to automatically add these "exec" lines
>> between each commit applications. For instance, running 'git rebase -i
>> --exec "make test"' lets you check that intermediate commits are
>> compilable. It is also compatible with the option --autosquash. At
>> this point, you can't use --exec without the interactive mode (-i).
>>
>> Tests about this new command are also added in
>> t3404-rebase-interactive.sh.
>
>> Should now work on MacOS.
>
> Hej,
> I'm not sure on which commit to apply the patch.
> (may be we shoud improve git format-patch to tell us the original commit ID),
> but if I remove the non applying part, it looks like this:

Which part does not apply ? If you skip the part that's implementing the exec option, of course Git will not recognize it.

Torsten Bögershausen· Jun 8, 2012, 19:55 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

On 08.06.12 21:15, konglu@minatec.inpg.fr wrote:
> 
> Torsten Bögershausen <tboegi@web.de> a écrit :
> Which part does not apply ? If you skip the part that's implementing the
> exec option, of course Git will not recognize it.

Hej, 2 questions: a) Where should it apply ? I tried to apply it on commit f623ca1cae600e97cb0b38131fdd33e4fb669cf8

b) Does the line from my log "error: unknown option `exec'" tell us anything?

/Torsten
konglu@minatec.inpg.fr· Jun 8, 2012, 20:07 UTC · re: Torsten Bögershausen · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

Torsten Bögershausen <tboegi@web.de> a écrit :
Show 12 quoted lines
> On 08.06.12 21:15, konglu@minatec.inpg.fr wrote:
>>
>> Torsten Bögershausen <tboegi@web.de> a écrit :
>
>> Which part does not apply ? If you skip the part that's implementing the
>> exec option, of course Git will not recognize it.
>
>
> Hej,
> 2 questions:
> a) Where should it apply ?
> I tried to apply it on commit f623ca1cae600e97cb0b38131fdd33e4fb669cf8

I just tried to apply it on that commit and it works for me. What's the error message ?

> b) Does the line from my log
> "error: unknown option `exec'"
> tell us anything?
Yes, that the patch was not applied ^^'.
Torsten Bögershausen· Jun 8, 2012, 20:51 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

On 08.06.12 22:07, konglu@minatec.inpg.fr wrote:
Show 24 quoted lines
> 
> Torsten Bögershausen <tboegi@web.de> a écrit :
> 
>> On 08.06.12 21:15, konglu@minatec.inpg.fr wrote:
>>>
>>> Torsten Bögershausen <tboegi@web.de> a écrit :
>>
>>> Which part does not apply ? If you skip the part that's implementing the
>>> exec option, of course Git will not recognize it.
>>
>>
>> Hej,
>> 2 questions:
>> a) Where should it apply ?
>> I tried to apply it on commit f623ca1cae600e97cb0b38131fdd33e4fb669cf8
> 
> I just tried to apply it on that commit and it works for me. What's the
> error message ?
> 
>> b) Does the line from my log
>> "error: unknown option `exec'"
>> tell us anything?
> 
> Yes, that the patch was not applied ^^'.
------------------------------------------------
That's the outcome, if I try to re-apply it:
Applying: Fwd: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
error: patch failed: Documentation/git-rebase.txt:210
error: Documentation/git-rebase.txt: patch does not apply
Patch failed at 0001 Fwd: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
=====================
And after my fumbling, the diff looks like this (see below).
It seems that something changed, because the error line is different- 

Sorry if I messed something up here, it looks as if the functionality implementing the "exec" is missing in my code base. For me it looks as if I only picked up the test cases, and I'm missing something.

In this case it would be helpful if you just re-send the patch to my email,
and I can try to re-do the patch based on f623ca1cae600e97cb0b38,
or whatever you specify.
Does that makes sense?
/Torsten
 
------------------------
git diff  f623ca1cae600e97cb0b38..63884a991c9d8
=================================================
Show changes to 4 files +206 −10

Documentation/git-rebase.txt, git-rebase--interactive.sh, git-rebase.sh, t/t3404-rebase-interactive.sh

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 147fa1a..1dd95c4 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
 	[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 	--root [<branch>]
 'git rebase' --continue | --skip | --abort
 
@@ -210,11 +210,29 @@ rebase.autosquash::
 
 OPTIONS
 -------
-<newbase>::
-	Starting point at which to create the new commits. If the
-	--onto option is not specified, the starting point is
-	<upstream>.  May be any valid commit, and not just an
-	existing branch name.
+-x <cmd>::
+--exec <cmd>::
+	Automatically add "exec" followed by <cmd> between each commit
+	applications. Using this option along with --autosquash adds
+	the exec line after the squash/fixeup series only. <cmd>
+	stands for shell commands. The --exec option has to be
+	specified. (see INTERACTIVE MODE below)
++
+This has to be used along with the `--interactive` option explicitly.
+You may execute several commands between each commit applications.
+For this, you can use one instance of exec:
+	git rebase -i --exec "cmd1; cmd2; ...".
+You can also insert several instances of exec, if you wish to
+only have one command per line for example:
+	git rebase -i --exec "cmd1" --exec "cmd2" ...
+
+--onto <newbase>::
+	With this option, git rebase takes all commits from <branch>,
+	that are not in <upstream>, and transplant them on top of
+	<newbase>. <newbase> is the starting point at which to create
+	the new commits. If the --onto option is not specified, the
+	starting point is <upstream>.  May be any valid commit, and
+	not just an existing branch name.
 +
 As a special case, you may use "A\...B" as a shortcut for the
 merge base of A and B if there is exactly one merge base. You can
@@ -521,6 +539,28 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can
 use shell features (like "cd", ">", ";" ...). The command is run from
 the root of the working tree.
 
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
+If the option '-i' is missing, The command will return a message
+error. If there is no <cmd> specified behind --exec, the command will
+return a message error and the usage page of 'git rebase'.
+
 SPLITTING COMMITS
 -----------------
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0c19b7c..dc9e7e9 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -684,6 +684,22 @@ rearrange_squash () {
 	rm -f "$1.sq" "$1.rearranged"
 }
 
+# Add commands after a pick or after a squash/fixup serie
+# in the todo list.
+add_exec_commands () {
+	OIFS=$IFS
+	IFS=$LF
+	for i in $cmd
+	do
+		tmp=$(sed "/^pick .*/i\exec $i" "$1")
+		echo "$tmp" >"$1"
+		tmp=$(sed '1d' "$1")
+		echo "$tmp" >"$1"
+		echo "exec $i" >>"$1"
+	done
+	IFS=$OIFS
+}
+
 case "$action" in
 continue)
 	# do we have anything to commit?
@@ -857,6 +873,8 @@ fi
 
 test -s "$todo" || echo noop >> "$todo"
 test -n "$autosquash" && rearrange_squash "$todo"
+test -n "$cmd" && add_exec_commands "$todo"
+
 cat >> "$todo" << EOF
 
 # Rebase $shortrevisions onto $shortonto
diff --git a/git-rebase.sh b/git-rebase.sh
index e616737..87b21e3 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -30,8 +31,8 @@ Example:       git-rebase master~1 topic
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
 git-rebase [-i] --continue | --abort | --skip
 --
  Available options are
@@ -43,6 +44,7 @@ s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
 m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
+x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
@@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
+cmd=
 strategy=
 strategy_opts=
 do_merge=
@@ -220,6 +223,11 @@ do
 		onto="$2"
 		shift
 		;;
+	-x)
+		test 2 -le "$#" || usage
+		cmd="${cmd:+"$cmd$LF"} $2"
+		shift
+		;;
 	-i)
 		interactive_rebase=explicit
 		;;
@@ -305,6 +313,12 @@ do
 done
 test $# -gt 2 && usage
 
+if test -n "$cmd" &&
+   test "$interactive_rebase" != explicit
+then
+	die "--exec option must be used with --interactive option\n"
+fi
+
 if test -n "$action"
 then
 	test -z "$in_progress" && die "No rebase in progress?"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 025c1c6..4fe98d5 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -755,4 +755,128 @@ test_expect_success 'rebase-i history with funny messages' '
 	test_cmp expect actual
 '
 
+
+test_expect_success 'prepare for rebase -i --exec' '
+	git checkout master &&
+	git checkout -b execute &&
+	test_commit one_exec main.txt one_exec &&
+	test_commit two_exec main.txt two_exec &&
+	test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+	git reset --hard execute &&
+	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,9d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+	git reset --hard execute &&
+	git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+				exec_git_show_HEAD exec_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expected
+	) &&
+	sed '1,11d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+	git reset --hard execute &&
+	git checkout -b autosquash &&
+	echo second >second.txt &&
+	git add second.txt &&
+	git commit -m "fixup! two_exec" &&
+	echo bis >bis.txt &&
+	git add bis.txt &&
+	git commit -m "fixup! two_exec" &&
+	(
+		git checkout -b autosquash_actual &&
+		git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+	) &&
+	git checkout autosquash &&
+	(
+		git checkout -b autosquash_expected &&
+		FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~4 >expected
+	) &&
+	sed '1,13d' expected >expect &&
+	mv expect expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+	git reset --hard execute &&
+	test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+	echo "--exec option must be used with --interactive option\n" >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
+	git reset --hard execute &&
+	test_must_fail git rebase -i --exec 2>actual &&
+	sed '1d' actual >tmp &&
+	mv tmp actual &&
+	test_must_fail git rebase -h >expected &&
+	test_cmp expected actual &&
+	git checkout master
+'
+
 test_done
konglu@minatec.inpg.fr· Jun 8, 2012, 21:03 UTC · re: Torsten Bögershausen · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

Torsten Bögershausen <tboegi@web.de> a écrit :
Show 34 quoted lines
> On 08.06.12 22:07, konglu@minatec.inpg.fr wrote:
>>
>> Torsten Bögershausen <tboegi@web.de> a écrit :
>>
>>> On 08.06.12 21:15, konglu@minatec.inpg.fr wrote:
>>>>
>>>> Torsten Bögershausen <tboegi@web.de> a écrit :
>>>
>>>> Which part does not apply ? If you skip the part that's implementing the
>>>> exec option, of course Git will not recognize it.
>>>
>>>
>>> Hej,
>>> 2 questions:
>>> a) Where should it apply ?
>>> I tried to apply it on commit f623ca1cae600e97cb0b38131fdd33e4fb669cf8
>>
>> I just tried to apply it on that commit and it works for me. What's the
>> error message ?
>>
>>> b) Does the line from my log
>>> "error: unknown option `exec'"
>>> tell us anything?
>>
>> Yes, that the patch was not applied ^^'.
> ------------------------------------------------
> That's the outcome, if I try to re-apply it:
> Applying: Fwd: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
> error: patch failed: Documentation/git-rebase.txt:210
> error: Documentation/git-rebase.txt: patch does not apply
> Patch failed at 0001 Fwd: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
> When you have resolved this problem run "git am --resolved".
> If you would prefer to skip this patch, instead run "git am --skip".
> To restore the original branch and stop patching run "git am --abort".
Did you first apply the first part [PATCHv3 1/2] of the patch ?
Lucien Kong.
Torsten Bögershausen· Jun 9, 2012, 06:14 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

On 08.06.12 23:03, konglu@minatec.inpg.fr wrote:
Show 41 quoted lines
> 
> Torsten Bögershausen <tboegi@web.de> a écrit :
> 
>> On 08.06.12 22:07, konglu@minatec.inpg.fr wrote:
>>>
>>> Torsten Bögershausen <tboegi@web.de> a écrit :
>>>
>>>> On 08.06.12 21:15, konglu@minatec.inpg.fr wrote:
>>>>>
>>>>> Torsten Bögershausen <tboegi@web.de> a écrit :
>>>>
>>>>> Which part does not apply ? If you skip the part that's implementing the
>>>>> exec option, of course Git will not recognize it.
>>>>
>>>>
>>>> Hej,
>>>> 2 questions:
>>>> a) Where should it apply ?
>>>> I tried to apply it on commit f623ca1cae600e97cb0b38131fdd33e4fb669cf8
>>>
>>> I just tried to apply it on that commit and it works for me. What's the
>>> error message ?
>>>
>>>> b) Does the line from my log
>>>> "error: unknown option `exec'"
>>>> tell us anything?
>>>
>>> Yes, that the patch was not applied ^^'.
>> ------------------------------------------------
>> That's the outcome, if I try to re-apply it:
>> Applying: Fwd: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
>> error: patch failed: Documentation/git-rebase.txt:210
>> error: Documentation/git-rebase.txt: patch does not apply
>> Patch failed at 0001 Fwd: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
>> When you have resolved this problem run "git am --resolved".
>> If you would prefer to skip this patch, instead run "git am --skip".
>> To restore the original branch and stop patching run "git am --abort".
> 
> Did you first apply the first part [PATCHv3 1/2] of the patch ?
> 
> Lucien Kong.

Hej, I have 2 patches with the headline "[PATCHv3 1/2" in my in box. None of them is dealing in any kind with upgrading a command to understand "exec".

To be able to test under Mac OS it could be helpful if you just re-send one patch to my email. Then I can try to re-do the patch based on f623ca1cae600e97cb0b38 and test it under Mac OS.

Does that makes sense?
/Torsten
konglu@minatec.inpg.fr· Jun 9, 2012, 06:47 UTC · re: Torsten Bögershausen · lore

Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...

Torsten Bögershausen <tboegi@web.de> a écrit :
> Hej,
> I have 2 patches with the headline "[PATCHv3 1/2" in my in box.
> None of them is dealing in any kind with upgrading a command to  
> understand "exec".
Here you can see the thread of the discussion:
http://thread.gmane.org/gmane.comp.version-control.git/199497
> To be able to test under Mac OS it could be helpful if you just re-send
> one patch to my email.
> Then I can try to re-do the patch based on f623ca1cae600e97cb0b38 and
> test it under Mac OS.

Alright, gonna send you the patch in one part so that it can be applied alone :).

Lucien Kong
Lucien Kong· Jun 10, 2012, 10:44 UTC · re: Lucien Kong · lore

[PATCHv4] rebase [-i --exec | -ix] <CMD>...

This patch provides a way to automatically add these "exec" lines between each commit applications. For instance, running 'git rebase -i --exec "make test"' lets you check that intermediate commits are compilable. It is also compatible with the option --autosquash. At this point, you can't use --exec without the interactive mode (-i).

Tests about this new command are also added in t3404-rebase-interactive.sh.

Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
The change in git-rebase.txt about the option --onto
was done in another patch. This patch can be applied
independently.
 Documentation/git-rebase.txt  |   43 ++++++++++++++-
 git-rebase--interactive.sh    |   23 ++++++++
 git-rebase.sh                 |   20 ++++++-
 t/t3404-rebase-interactive.sh |  118 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 199 insertions(+), 5 deletions(-)
Show changes to 4 files +199 −5

Documentation/git-rebase.txt, git-rebase--interactive.sh, git-rebase.sh, t/t3404-rebase-interactive.sh

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 147fa1a..a2f1514 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
 	[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 	--root [<branch>]
 'git rebase' --continue | --skip | --abort
 
@@ -210,6 +210,27 @@ rebase.autosquash::
 
 OPTIONS
 -------
+-x <cmd>::
+--exec <cmd>::
+	Append "exec <cmd>" after each commit application line. <cmd>
+	will be interpreted as one or more shell commands (see
+	INTERACTIVE MODE below).
++
+This option has to be used along with the `--interactive` option
+explicitly.  You may execute several commands between each commit
+applications.  For this, you can use one instance of exec:
++
+	git rebase -i --exec "cmd1; cmd2; ...".
++
+You can also insert several instances of exec, if you wish to only
+have one command per line. For example:
++
+	git rebase -i --exec "cmd1" --exec "cmd2" ...
++
+If --autosquash is used, the "exec" lines will not be appended for the
+intermediate commits, and will only appear at the end of each
+squash/fixup series.
+
 <newbase>::
 	Starting point at which to create the new commits. If the
 	--onto option is not specified, the starting point is
@@ -521,6 +542,24 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can
 use shell features (like "cd", ">", ";" ...). The command is run from
 the root of the working tree.
 
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
 SPLITTING COMMITS
 -----------------
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0c19b7c..5f56672 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -684,6 +684,27 @@ rearrange_squash () {
 	rm -f "$1.sq" "$1.rearranged"
 }
 
+# Add commands after a pick or after a squash/fixup serie
+# in the todo list.
+add_exec_commands () {
+	{
+		first=t
+		while read -r insn rest
+		do
+			case $insn in
+			pick)
+				test -n "$first" ||
+				printf "%s" "$cmd"
+				;;
+			esac
+			printf "%s %s\n" "$insn" "$rest"
+			first=
+		done
+		printf "%s" "$cmd"
+	} <"$1" >"$1.new" &&
+	mv "$1.new" "$1"
+}
+
 case "$action" in
 continue)
 	# do we have anything to commit?
@@ -857,6 +878,8 @@ fi
 
 test -s "$todo" || echo noop >> "$todo"
 test -n "$autosquash" && rearrange_squash "$todo"
+test -n "$cmd" && add_exec_commands "$todo"
+
 cat >> "$todo" << EOF
 
 # Rebase $shortrevisions onto $shortonto
diff --git a/git-rebase.sh b/git-rebase.sh
index 24a2840..2952bc0 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -30,8 +31,8 @@ Example:       git-rebase master~1 topic
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
 git-rebase [-i] --continue | --abort | --skip
 --
  Available options are
@@ -43,6 +44,7 @@ s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
 m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
+x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
@@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
+cmd=
 strategy=
 strategy_opts=
 do_merge=
@@ -219,6 +222,11 @@ do
 		onto="$2"
 		shift
 		;;
+	-x)
+		test 2 -le "$#" || usage
+		cmd="${cmd}exec $2${LF}"
+		shift
+		;;
 	-i)
 		interactive_rebase=explicit
 		;;
@@ -304,6 +312,12 @@ do
 done
 test $# -gt 2 && usage
 
+if test -n "$cmd" &&
+   test "$interactive_rebase" != explicit
+then
+	die "--exec option must be used with --interactive option"
+fi
+
 if test -n "$action"
 then
 	test -z "$in_progress" && die "No rebase in progress?"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 025c1c6..600519c 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -755,4 +755,122 @@ test_expect_success 'rebase-i history with funny messages' '
 	test_cmp expect actual
 '
 
+
+test_expect_success 'prepare for rebase -i --exec' '
+	git checkout master &&
+	git checkout -b execute &&
+	test_commit one_exec main.txt one_exec &&
+	test_commit two_exec main.txt two_exec &&
+	test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+	git reset --hard execute &&
+	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+	git reset --hard execute &&
+	git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+				exec_git_show_HEAD exec_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,11d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+	git reset --hard execute &&
+	git checkout -b autosquash &&
+	echo second >second.txt &&
+	git add second.txt &&
+	git commit -m "fixup! two_exec" &&
+	echo bis >bis.txt &&
+	git add bis.txt &&
+	git commit -m "fixup! two_exec" &&
+	(
+		git checkout -b autosquash_actual &&
+		git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+	) &&
+	git checkout autosquash &&
+	(
+		git checkout -b autosquash_expected &&
+		FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~4 >expect
+	) &&
+	sed -e "1,13d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+	git reset --hard execute &&
+	test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+	echo "--exec option must be used with --interactive option" >expected &&
+	test_i18ncmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
+	git reset --hard execute &&
+	test_must_fail git rebase -i --exec 2>actual &&
+	sed '1d' actual >tmp &&
+	mv tmp actual &&
+	test_must_fail git rebase -h >expected &&
+	test_cmp expected actual &&
+	git checkout master
+'
+
 test_done
-- 
1.7.8
Johannes Sixt· Jun 10, 2012, 11:56 UTC · re: Lucien Kong · lore

Re: [PATCHv4] rebase [-i --exec | -ix] <CMD>...

Am 10.06.2012 12:44, schrieb Lucien Kong:
Show 9 quoted lines
> +test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
> +	git reset --hard execute &&
> +	test_must_fail git rebase -i --exec 2>actual &&
> +	sed '1d' actual >tmp &&
> +	mv tmp actual &&
> +	test_must_fail git rebase -h >expected &&
> +	test_cmp expected actual &&
> +	git checkout master
> +'

IMO, it is more important to check that the error message is present rather than whether the usage blurb is correct. But since the error is generated by the option parsing machinery, it is probably sufficient to check *only* for failure, and don't verify the output at all.

Then change the headline of the text to the neutral
test_expect_success 'rebase -i --exec without <CMD>' '

And, BTW, next time I point out that sed 'xy'... should be changed to sed -e "xy"... you review *ALL* sed commands you introduce, not just those that I point out, OK?

And, BTW, when I point out that ...>expected && sed <expected >expect && mv expect expected should be ...>expect && sed <expect >expected, you extrapolate *yourself* that the same pattern applies even if the files are named "tmp" and "actual", OK?

That's expected from thoughtful contributors.
-- Hannes
Junio C Hamano· Jun 11, 2012, 15:14 UTC · re: Johannes Sixt · lore

Re: [PATCHv4] rebase [-i --exec | -ix] <CMD>...

Johannes Sixt <j6t@kdbg.org> writes:
Show 19 quoted lines
> Am 10.06.2012 12:44, schrieb Lucien Kong:
>> +test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
>> +	git reset --hard execute &&
>> +	test_must_fail git rebase -i --exec 2>actual &&
>> +	sed '1d' actual >tmp &&
>> +	mv tmp actual &&
>> +	test_must_fail git rebase -h >expected &&
>> +	test_cmp expected actual &&
>> +	git checkout master
>> +'
>
> IMO, it is more important to check that the error message is present
> rather than whether the usage blurb is correct. But since the error is
> generated by the option parsing machinery, it is probably sufficient to
> check *only* for failure, and don't verify the output at all.
>
> Then change the headline of the text to the neutral
>
> test_expect_success 'rebase -i --exec without <CMD>' '
Makes sense; thanks for a thoughtful suggestion.
Show 12 quoted lines
> And, BTW, next time I point out that sed 'xy'... should be changed to
> sed -e "xy"... you review *ALL* sed commands you introduce, not just
> those that I point out, OK?
>
> And, BTW, when I point out that ...>expected && sed <expected >expect &&
> mv expect expected should be ...>expect && sed <expect >expected, you
> extrapolate *yourself* that the same pattern applies even if the files
> are named "tmp" and "actual", OK?
>
> That's expected from thoughtful contributors.
>
> -- Hannes
Johannes Sixt· Jun 12, 2012, 18:55 UTC · re: Junio C Hamano · lore

Re: [PATCHv4] rebase [-i --exec | -ix] <CMD>...

Am 11.06.2012 17:14, schrieb Junio C Hamano:
Show 17 quoted lines
> Johannes Sixt <j6t@kdbg.org> writes:
> 
>> Am 10.06.2012 12:44, schrieb Lucien Kong:
>>> +test_expect_success 'rebase -i --exec without <CMD> shows error message and usage' '
>>> +	git reset --hard execute &&
>>> +	test_must_fail git rebase -i --exec 2>actual &&
>>> +	sed '1d' actual >tmp &&
>>> +	mv tmp actual &&
>>> +	test_must_fail git rebase -h >expected &&
>>> +	test_cmp expected actual &&
>>> +	git checkout master
>>> +'
>>
>> IMO, it is more important to check that the error message is present
>> rather than whether the usage blurb is correct. But since the error is
>> generated by the option parsing machinery, it is probably sufficient to
>> check *only* for failure, and don't verify the output at all.

I changed my mind. If option parsing regresses in such a way that --exec suddenly works without command, then the 'test_must_fail git rebase ...' could pass because there is a failure much later in the rebase process, which we would not detect if we do not check the output. It is therefore good to check whether the expected failure happens during option parsing.

Checking the usage blurb rather than the error message even has advantages: it is immune to changes of the error messages and to i18n poisoning.

In this light, the version you have queued is fine.
-- Hannes
Junio C Hamano· Jun 12, 2012, 20:29 UTC · re: Johannes Sixt · lore

Re: [PATCHv4] rebase [-i --exec | -ix] <CMD>...

Johannes Sixt <j6t@kdbg.org> writes:
> Checking the usage blurb rather than the error message even has
> advantages: it is immune to changes of the error messages and to i18n
> poisoning.

Yes, to a degree. There is no guarantee that the error message stays on a single line in a particular l10n ;-).

> In this light, the version you have queued is fine.
Lucien Kong· Jun 12, 2012, 08:05 UTC · re: Lucien Kong · lore

[PATCHv5] rebase [-i --exec | -ix] <CMD>...

This patch provides a way to automatically add these "exec" lines between each commit applications. For instance, running 'git rebase -i --exec "make test"' lets you check that intermediate commits are compilable. It is also compatible with the option --autosquash. At this point, you can't use --exec without the interactive mode (-i).

Tests about this new command are also added in t3404-rebase-interactive.sh.

Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>
Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>
Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>
Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>
Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
---
The last test is changed to be consistent with the other
(thanks Johannes for reviewing the code).
 Documentation/git-rebase.txt  |   43 ++++++++++++++-
 git-rebase--interactive.sh    |   23 ++++++++
 git-rebase.sh                 |   20 ++++++-
 t/t3404-rebase-interactive.sh |  117 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 198 insertions(+), 5 deletions(-)
Show changes to 4 files +198 −5

Documentation/git-rebase.txt, git-rebase--interactive.sh, git-rebase.sh, t/t3404-rebase-interactive.sh

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 147fa1a..a2f1514 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
 	[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 	--root [<branch>]
 'git rebase' --continue | --skip | --abort
 
@@ -210,6 +210,27 @@ rebase.autosquash::
 
 OPTIONS
 -------
+-x <cmd>::
+--exec <cmd>::
+	Append "exec <cmd>" after each commit application line. <cmd>
+	will be interpreted as one or more shell commands (see
+	INTERACTIVE MODE below).
++
+This option has to be used along with the `--interactive` option
+explicitly.  You may execute several commands between each commit
+applications.  For this, you can use one instance of exec:
++
+	git rebase -i --exec "cmd1; cmd2; ...".
++
+You can also insert several instances of exec, if you wish to only
+have one command per line. For example:
++
+	git rebase -i --exec "cmd1" --exec "cmd2" ...
++
+If --autosquash is used, the "exec" lines will not be appended for the
+intermediate commits, and will only appear at the end of each
+squash/fixup series.
+
 <newbase>::
 	Starting point at which to create the new commits. If the
 	--onto option is not specified, the starting point is
@@ -521,6 +542,24 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can
 use shell features (like "cd", ">", ";" ...). The command is run from
 the root of the working tree.
 
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
 SPLITTING COMMITS
 -----------------
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0c19b7c..5f56672 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -684,6 +684,27 @@ rearrange_squash () {
 	rm -f "$1.sq" "$1.rearranged"
 }
 
+# Add commands after a pick or after a squash/fixup serie
+# in the todo list.
+add_exec_commands () {
+	{
+		first=t
+		while read -r insn rest
+		do
+			case $insn in
+			pick)
+				test -n "$first" ||
+				printf "%s" "$cmd"
+				;;
+			esac
+			printf "%s %s\n" "$insn" "$rest"
+			first=
+		done
+		printf "%s" "$cmd"
+	} <"$1" >"$1.new" &&
+	mv "$1.new" "$1"
+}
+
 case "$action" in
 continue)
 	# do we have anything to commit?
@@ -857,6 +878,8 @@ fi
 
 test -s "$todo" || echo noop >> "$todo"
 test -n "$autosquash" && rearrange_squash "$todo"
+test -n "$cmd" && add_exec_commands "$todo"
+
 cat >> "$todo" << EOF
 
 # Rebase $shortrevisions onto $shortonto
diff --git a/git-rebase.sh b/git-rebase.sh
index 24a2840..2952bc0 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,8 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -30,8 +31,8 @@ Example:       git-rebase master~1 topic
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
 git-rebase [-i] --continue | --abort | --skip
 --
  Available options are
@@ -43,6 +44,7 @@ s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
 m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
+x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
@@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\".
 To check out the original branch and stop rebasing run \"git rebase --abort\".
 "
 unset onto
+cmd=
 strategy=
 strategy_opts=
 do_merge=
@@ -219,6 +222,11 @@ do
 		onto="$2"
 		shift
 		;;
+	-x)
+		test 2 -le "$#" || usage
+		cmd="${cmd}exec $2${LF}"
+		shift
+		;;
 	-i)
 		interactive_rebase=explicit
 		;;
@@ -304,6 +312,12 @@ do
 done
 test $# -gt 2 && usage
 
+if test -n "$cmd" &&
+   test "$interactive_rebase" != explicit
+then
+	die "--exec option must be used with --interactive option"
+fi
+
 if test -n "$action"
 then
 	test -z "$in_progress" && die "No rebase in progress?"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 025c1c6..68d6148 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -755,4 +755,121 @@ test_expect_success 'rebase-i history with funny messages' '
 	test_cmp expect actual
 '
 
+
+test_expect_success 'prepare for rebase -i --exec' '
+	git checkout master &&
+	git checkout -b execute &&
+	test_commit one_exec main.txt one_exec &&
+	test_commit two_exec main.txt two_exec &&
+	test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+	git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+	git reset --hard execute &&
+	git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+	git reset --hard execute &&
+	git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,9d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+	git reset --hard execute &&
+	git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+	(
+		FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+				exec_git_show_HEAD exec_pwd" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~2 >expect
+	) &&
+	sed -e "1,11d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+	git reset --hard execute &&
+	git checkout -b autosquash &&
+	echo second >second.txt &&
+	git add second.txt &&
+	git commit -m "fixup! two_exec" &&
+	echo bis >bis.txt &&
+	git add bis.txt &&
+	git commit -m "fixup! two_exec" &&
+	(
+		git checkout -b autosquash_actual &&
+		git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+	) &&
+	git checkout autosquash &&
+	(
+		git checkout -b autosquash_expected &&
+		FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+		export FAKE_LINES &&
+		git rebase -i HEAD~4 >expect
+	) &&
+	sed -e "1,13d" expect >expected &&
+	test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+	git reset --hard execute &&
+	test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+	echo "--exec option must be used with --interactive option" >expected &&
+	test_i18ncmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD>' '
+	git reset --hard execute &&
+	test_must_fail git rebase -i --exec 2>tmp &&
+	sed -e "1d" tmp >actual &&
+	test_must_fail git rebase -h >expected &&
+	test_cmp expected actual &&
+	git checkout master
+'
+
 test_done
-- 
1.7.8
Zbigniew Jędrzejewski-Szmek· Jun 12, 2012, 09:23 UTC · re: Lucien Kong · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

On 06/12/2012 10:05 AM, Lucien Kong wrote:
Show 9 quoted lines
> +-x <cmd>::
> +--exec <cmd>::
> +	Append "exec <cmd>" after each commit application line. <cmd>
> +	will be interpreted as one or more shell commands (see
> +	INTERACTIVE MODE below).
> ++
> +This option has to be used along with the `--interactive` option
> +explicitly.  You may execute several commands between each commit
> +applications.  For this, you can use one instance of exec:
Hi,

this is still grammatically fishy, and has "between each commit applications", which was corrected above, but not here.

> +	git rebase -i --exec "cmd1; cmd2; ...".
> ++
> +You can also insert several instances of exec, if you wish to only
> +have one command per line. For example:
s/instances of exec/instances of --exec/
Show 6 quoted lines
> +	git rebase -i --exec "cmd1" --exec "cmd2" ...
> ++
> +If --autosquash is used, the "exec" lines will not be appended for the
> +intermediate commits, and will only appear at the end of each
> +squash/fixup series.
> +
Zbyszek
Junio C Hamano· Jun 12, 2012, 14:46 UTC · re: Zbigniew Jędrzejewski-Szmek · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Zbigniew Jędrzejewski-Szmek  <zbyszek@in.waw.pl> writes:
Show 14 quoted lines
> On 06/12/2012 10:05 AM, Lucien Kong wrote:
>> +-x <cmd>::
>> +--exec <cmd>::
>> +	Append "exec <cmd>" after each commit application line. <cmd>
>> +	will be interpreted as one or more shell commands (see
>> +	INTERACTIVE MODE below).
>> ++
>> +This option has to be used along with the `--interactive` option
>> +explicitly.  You may execute several commands between each commit
>> +applications.  For this, you can use one instance of exec:
> Hi,
>
> this is still grammatically fishy, and has "between each commit
> applications", which was corrected above, but not here.

Not just grammo, but "between" is not correct, as there will be the final test after the last "pick".

Show 5 quoted lines
>> +	git rebase -i --exec "cmd1; cmd2; ...".
>> ++
>> +You can also insert several instances of exec, if you wish to only
>> +have one command per line. For example:
> s/instances of exec/instances of --exec/

Not just that, in the explanation part, we tend to spell `--exec` to make the part that needs to be literally typed stand out (also we want to see dash-dash, not em-dash, in the formatted output).

Show 6 quoted lines
>> +	git rebase -i --exec "cmd1" --exec "cmd2" ...
>> ++
>> +If --autosquash is used, the "exec" lines will not be appended for the
>> +intermediate commits, and will only appear at the end of each
>> +squash/fixup series.
>> +
Same for `--autosquash`.

I do not think it is worth another round of resend at this point, so please eyeball the version I fixed up and queued in 'pu' when it is pushed out. I also moved the '-x <cmd>::' option description to where it belongs (iow, not at the very beginning).

Zbigniew Jędrzejewski-Szmek· Jun 13, 2012, 14:04 UTC · re: Junio C Hamano · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

On 06/12/2012 04:46 PM, Junio C Hamano wrote:
> I do not think it is worth another round of resend at this point, so
> please eyeball the version I fixed up and queued in 'pu' when it is
> pushed out.  I also moved the '-x <cmd>::' option description to
> where it belongs (iow, not at the very beginning).

Hi, I think some small changes are still in order. Please consider squashing this in:

-----8<------
Subject: [PATCH] squash! rebase -i: teach "--exec <cmd>"
In the commit message: s/each runs/each run/
Fixup to the documentation part:
- Use the phrase "after each commit in the final history" from Junio's
  commit message to replace "each commit application". The latter is
  awkward and not really true.
- Reorder paragraphs and reword the one about --interactive.
  Make the part about two forms of exec less verbose.
- Replace ';' with '&&' in the example. This (a) makes the two
  examples equivalent, and (b) encourages good practice that we try
  to follow in git tests to never fail silently. People are likely
  to copy the example verbatim.
---
 Documentation/git-rebase.txt | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)
Show changes to Documentation/git-rebase.txt +12 −11
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 048da64..179ab77 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -346,22 +346,23 @@ idea unless you know what you are doing (see BUGS
below).

 -x <cmd>::
 --exec <cmd>::
-	Append "exec <cmd>" after each commit application line. <cmd>
-	will be interpreted as one or more shell commands (see
-	INTERACTIVE MODE below).
+	Append "exec <cmd>" after each line creating a commit in the
+	final history. <cmd> will be interpreted as one or more shell
+	commands.
 +
-This option has to be used along with the `--interactive` option
-explicitly.  You may execute several commands after each commit
-application.  For this, you can use one instance of `--exec`:
+This option can only be used with the `--interactive` option
+(see INTERACTIVE MODE below).
 +
-	git rebase -i --exec "cmd1; cmd2; ...".
+You may execute several commands by either using one instance of `--exec`
+with several commands:
 +
-You can also insert several instances of `--exec`, if you wish to only
-have one command per line. For example:
+	git rebase -i --exec "cmd1 && cmd2 && ..."
 +
-	git rebase -i --exec "cmd1" --exec "cmd2" ...
+or equivalently by giving more than one `--exec`:
 +
-If `--autosquash` is used, the "exec" lines will not be appended for
+	git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
++
+If `--autosquash` is used, "exec" lines will not be appended for
 the intermediate commits, and will only appear at the end of each
 squash/fixup series.
-- 
1.7.11.rc3.129.ga90bc7a.dirty
-----8<------

Zbyszek
Junio C Hamano· Jun 13, 2012, 17:32 UTC · re: Zbigniew Jędrzejewski-Szmek · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Zbigniew Jędrzejewski-Szmek  <zbyszek@in.waw.pl> writes:
Show 25 quoted lines
> On 06/12/2012 04:46 PM, Junio C Hamano wrote:
>> I do not think it is worth another round of resend at this point, so
>> please eyeball the version I fixed up and queued in 'pu' when it is
>> pushed out.  I also moved the '-x <cmd>::' option description to
>> where it belongs (iow, not at the very beginning).
>
> Hi,
> I think some small changes are still in order. Please consider
> squashing this in:
>
> -----8<------
> Subject: [PATCH] squash! rebase -i: teach "--exec <cmd>"
>
> In the commit message: s/each runs/each run/
>
> Fixup to the documentation part:
> - Use the phrase "after each commit in the final history" from Junio's
>   commit message to replace "each commit application". The latter is
>   awkward and not really true.
> - Reorder paragraphs and reword the one about --interactive.
>   Make the part about two forms of exec less verbose.
> - Replace ';' with '&&' in the example. This (a) makes the two
>   examples equivalent, and (b) encourages good practice that we try
>   to follow in git tests to never fail silently. People are likely
>   to copy the example verbatim.
Looks sensible; Lucien, opinions?
Show 42 quoted lines
>  Documentation/git-rebase.txt | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
> index 048da64..179ab77 100644
> --- a/Documentation/git-rebase.txt
> +++ b/Documentation/git-rebase.txt
> @@ -346,22 +346,23 @@ idea unless you know what you are doing (see BUGS
> below).
>
>  -x <cmd>::
>  --exec <cmd>::
> -	Append "exec <cmd>" after each commit application line. <cmd>
> -	will be interpreted as one or more shell commands (see
> -	INTERACTIVE MODE below).
> +	Append "exec <cmd>" after each line creating a commit in the
> +	final history. <cmd> will be interpreted as one or more shell
> +	commands.
>  +
> -This option has to be used along with the `--interactive` option
> -explicitly.  You may execute several commands after each commit
> -application.  For this, you can use one instance of `--exec`:
> +This option can only be used with the `--interactive` option
> +(see INTERACTIVE MODE below).
>  +
> -	git rebase -i --exec "cmd1; cmd2; ...".
> +You may execute several commands by either using one instance of `--exec`
> +with several commands:
>  +
> -You can also insert several instances of `--exec`, if you wish to only
> -have one command per line. For example:
> +	git rebase -i --exec "cmd1 && cmd2 && ..."
>  +
> -	git rebase -i --exec "cmd1" --exec "cmd2" ...
> +or equivalently by giving more than one `--exec`:
>  +
> -If `--autosquash` is used, the "exec" lines will not be appended for
> +	git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
> ++
> +If `--autosquash` is used, "exec" lines will not be appended for
>  the intermediate commits, and will only appear at the end of each
>  squash/fixup series.
konglu@minatec.inpg.fr· Jun 13, 2012, 18:05 UTC · re: Zbigniew Jędrzejewski-Szmek · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> a écrit :
Show 19 quoted lines
> On 06/12/2012 04:46 PM, Junio C Hamano wrote:
>> I do not think it is worth another round of resend at this point, so
>> please eyeball the version I fixed up and queued in 'pu' when it is
>> pushed out.  I also moved the '-x <cmd>::' option description to
>> where it belongs (iow, not at the very beginning).
>
> Hi,
> I think some small changes are still in order. Please consider
> squashing this in:
>
> -----8<------
> Subject: [PATCH] squash! rebase -i: teach "--exec <cmd>"
>
> In the commit message: s/each runs/each run/
>
> Fixup to the documentation part:
> - Use the phrase "after each commit in the final history" from Junio's
>   commit message to replace "each commit application". The latter is
>   awkward and not really true.

After reading again the sentence, I find that the new expression is more appropriate when it comes to the "--autosquash" case (here, "in the final history" is clearer than "application"). Thus, the new formulation seems good to me.

> - Reorder paragraphs and reword the one about --interactive.
>   Make the part about two forms of exec less verbose.
Less verbose and avoid some repetitions. But...
Show 9 quoted lines
> +You may execute several commands by either using one instance of `--exec`
> +with several commands:
>  +
> -You can also insert several instances of `--exec`, if you wish to only
> -have one command per line. For example:
> +	git rebase -i --exec "cmd1 && cmd2 && ..."
>  +
> -	git rebase -i --exec "cmd1" --exec "cmd2" ...
> +or equivalently by giving more than one `--exec`:

...I'm against using "equivalently" as in the first case, all the commands are on one line, and in the second case, each commands have its line, thus easier for the user to manipulate them independently.

> - Replace ';' with '&&' in the example. This (a) makes the two
>   examples equivalent, and (b) encourages good practice that we try
>   to follow in git tests to never fail silently. People are likely
>   to copy the example verbatim.
Why not.
Junio C Hamano· Jun 13, 2012, 18:22 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

konglu@minatec.inpg.fr writes:
Show 13 quoted lines
>> +You may execute several commands by either using one instance of `--exec`
>> +with several commands:
>>  +
>> -You can also insert several instances of `--exec`, if you wish to only
>> -have one command per line. For example:
>> +	git rebase -i --exec "cmd1 && cmd2 && ..."
>>  +
>> -	git rebase -i --exec "cmd1" --exec "cmd2" ...
>> +or equivalently by giving more than one `--exec`:
>
> ...I'm against using "equivalently" as in the first case, all the commands
> are on one line, and in the second case, each commands have its line, thus
> easier for the user to manipulate them independently.
It looks that editing
    pick foo            pick foo
    exec cmd1           exec cmd1 && cmd2
    exec cmd2
    pick bar            pick bar
    exec cmd1           exec cmd1 && cmd2
    exec cmd2
to
    pick foo            pick foo
                        exec         cmd2
    exec cmd2
    pick bar            pick bar
    exec cmd1           exec cmd1

would take exactly the same effort, at least to me. And more importantly, without editing don't they do *exactly* the same thing? If cmd1 fails, the sequencing stops at that step without running cmd2.

konglu@minatec.inpg.fr· Jun 13, 2012, 19:38 UTC · re: Junio C Hamano · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Junio C Hamano <gitster@pobox.com> a écrit :
Show 20 quoted lines
> It looks that editing
>
>     pick foo            pick foo
>     exec cmd1           exec cmd1 && cmd2
>     exec cmd2
>     pick bar            pick bar
>     exec cmd1           exec cmd1 && cmd2
>     exec cmd2
>
> to
>
>     pick foo            pick foo
>                         exec         cmd2
>     exec cmd2
>     pick bar            pick bar
>     exec cmd1           exec cmd1
>
> would take exactly the same effort, at least to me.  And more
> importantly, without editing don't they do *exactly* the same thing?
> If cmd1 fails, the sequencing stops at that step without running cmd2.

True. I was thinking under the fact that the user would edit the commands by himself but the purpose of the "--exec" option is to avoid that (or at least that the user won't have to type all by himself). Forget what I said then :).

Johannes Sixt· Jun 13, 2012, 20:59 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Am 13.06.2012 21:38, schrieb konglu@minatec.inpg.fr:
Show 28 quoted lines
> 
> Junio C Hamano <gitster@pobox.com> a écrit :
> 
>> It looks that editing
>>
>>     pick foo            pick foo
>>     exec cmd1           exec cmd1 && cmd2
>>     exec cmd2
>>     pick bar            pick bar
>>     exec cmd1           exec cmd1 && cmd2
>>     exec cmd2
>>
>> to
>>
>>     pick foo            pick foo
>>                         exec         cmd2
>>     exec cmd2
>>     pick bar            pick bar
>>     exec cmd1           exec cmd1
>>
>> would take exactly the same effort, at least to me.  And more
>> importantly, without editing don't they do *exactly* the same thing?
>> If cmd1 fails, the sequencing stops at that step without running cmd2.
> 
> True. I was thinking under the fact that the user would edit the commands
> by himself but the purpose of the "--exec" option is to avoid that (or at
> least that the user won't have to type all by himself). Forget what I said
> then :).
Not so fast.
	exec cmd1 && cmd2
and
	exec cmd1
	exec cmd2

are far from equivalent: If cmd1 fails, the first version never runs cmd2, but the second version runs cmd2 upon rebase --continue.

The updated documentation should not say that the two are "equivalent".
-- Hannes
Zbigniew Jędrzejewski-Szmek· Jun 13, 2012, 21:07 UTC · re: Johannes Sixt · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

On 06/13/2012 10:59 PM, Johannes Sixt wrote:
Show 41 quoted lines
> Am 13.06.2012 21:38, schrieb konglu@minatec.inpg.fr:
>>
>> Junio C Hamano <gitster@pobox.com> a écrit :
>>
>>> It looks that editing
>>>
>>>     pick foo            pick foo
>>>     exec cmd1           exec cmd1 && cmd2
>>>     exec cmd2
>>>     pick bar            pick bar
>>>     exec cmd1           exec cmd1 && cmd2
>>>     exec cmd2
>>>
>>> to
>>>
>>>     pick foo            pick foo
>>>                         exec         cmd2
>>>     exec cmd2
>>>     pick bar            pick bar
>>>     exec cmd1           exec cmd1
>>>
>>> would take exactly the same effort, at least to me.  And more
>>> importantly, without editing don't they do *exactly* the same thing?
>>> If cmd1 fails, the sequencing stops at that step without running cmd2.
>>
>> True. I was thinking under the fact that the user would edit the commands
>> by himself but the purpose of the "--exec" option is to avoid that (or at
>> least that the user won't have to type all by himself). Forget what I said
>> then :).
> 
> Not so fast.
> 
> 	exec cmd1 && cmd2
> and
> 	exec cmd1
> 	exec cmd2
> 
> are far from equivalent: If cmd1 fails, the first version never runs
> cmd2, but the second version runs cmd2 upon rebase --continue.
> 
> The updated documentation should not say that the two are "equivalent".

Good catch. Word "equivalently" is inappropriate here. I think that just removing that one word is best.

Zbyszek
Junio C Hamano· Jun 13, 2012, 22:25 UTC · re: Johannes Sixt · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Johannes Sixt <j6t@kdbg.org> writes:
Show 11 quoted lines
> Not so fast.
>
> 	exec cmd1 && cmd2
> and
> 	exec cmd1
> 	exec cmd2
>
> are far from equivalent: If cmd1 fails, the first version never runs
> cmd2, but the second version runs cmd2 upon rebase --continue.
>
> The updated documentation should not say that the two are "equivalent".
Fair'nuf.  Thansk.
Show changes to Documentation/git-rebase.txt +1 −1
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 179ab77..2d71e4b 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -358,7 +358,7 @@ with several commands:
 +
 	git rebase -i --exec "cmd1 && cmd2 && ..."
 +
-or equivalently by giving more than one `--exec`:
+or by giving more than one `--exec`:
 +
 	git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
 +
Junio C Hamano· Jun 13, 2012, 22:35 UTC · re: Johannes Sixt · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Johannes Sixt <j6t@kdbg.org> writes:
Show 9 quoted lines
> Not so fast.
>
> 	exec cmd1 && cmd2
> and
> 	exec cmd1
> 	exec cmd2
>
> are far from equivalent: If cmd1 fails, the first version never runs
> cmd2, but the second version runs cmd2 upon rebase --continue.
This reminds me of one thing.

For "exec" insns that are meant to validate each commit in the resulting history, what should happen (I am not asking what the current implementation of "rebase -i" does) after "exec cmd1" fails?

Ideally, the user will at that point fix the problem in the code, run "commit --amend" to record the fix, and then want to make sure it really fixed it by re-running "exec cmd1", no?

Shouldn't "rebase --continue" after such a "commit --amend" resume execution from "exec cmd1", which failed in the initial run?

I said in the beginning 'For "exec" insns that are meant to validate', as "exec" is not necessarily about validation, and other use cases of it may want it run only once in the sequence, whether it succeeds or fails. So perhaps we would need two kinds of "exec", one that just runs once and is not re-run even if the initial round fails, and another (perhaps spell it "test") that runs upon "--continue" until it passes. The latter of course can be skipped by the user with "rebase --skip".

Zbigniew Jędrzejewski-Szmek· Jun 13, 2012, 22:43 UTC · re: Junio C Hamano · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

On 06/14/2012 12:35 AM, Junio C Hamano wrote:
Show 33 quoted lines
> Johannes Sixt <j6t@kdbg.org> writes:
> 
>> Not so fast.
>>
>> 	exec cmd1 && cmd2
>> and
>> 	exec cmd1
>> 	exec cmd2
>>
>> are far from equivalent: If cmd1 fails, the first version never runs
>> cmd2, but the second version runs cmd2 upon rebase --continue.
> 
> This reminds me of one thing.
> 
> For "exec" insns that are meant to validate each commit in the
> resulting history, what should happen (I am not asking what the
> current implementation of "rebase -i" does) after "exec cmd1" fails?
> 
> Ideally, the user will at that point fix the problem in the code,
> run "commit --amend" to record the fix, and then want to make sure
> it really fixed it by re-running "exec cmd1", no?
> 
> Shouldn't "rebase --continue" after such a "commit --amend" resume
> execution from "exec cmd1", which failed in the initial run?
> 
> I said in the beginning 'For "exec" insns that are meant to validate',
> as "exec" is not necessarily about validation, and other use cases
> of it may want it run only once in the sequence, whether it succeeds
> or fails.  So perhaps we would need two kinds of "exec", one that
> just runs once and is not re-run even if the initial round fails,
> and another (perhaps spell it "test") that runs upon "--continue"
> until it passes.  The latter of course can be skipped by the user
> with "rebase --skip".

A different proposal would be to add a 'rebase --retry' which would inoke the last command again. And then the advice after 'exec' could say "Use --retry to rerun this command, and --continue to proceed with the next one".

--retry could make sense for 'apply' commands too: if a commit fails to
apply, one could do
  git reset --hard HEAD^
  hack hack adjusting the preimage
  git commit
  git rebase --retry

Using --retry to rerun tests would have the advantage that one normally doesn't think that the tests will fail, so could get into the habit of using 'exec', not 'test', for the verification commands.

Just thinking aloud.
Zbyszek
Matthieu Moy· Jun 14, 2012, 06:57 UTC · re: Zbigniew Jędrzejewski-Szmek · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:
>> Shouldn't "rebase --continue" after such a "commit --amend" resume
>> execution from "exec cmd1", which failed in the initial run?

There are use-cases where this would be useful, but that would also be a real pain if the command itself is broken (e.g. does "echo OK; exit 1", that the user can interpret as correct but that "git rebase" will consider as a failure). It this case, the user would have no simple way to get out of the situation (either --abort or --skip).

The current behavior is not that bad: "git rebase --continue" does not re-check the current commit, but the user did have an opportunity to check the commit manually before running it. The problem with rebase (that --exec solves), is that it creates new commits without giving the user this opportunity. I'm not sure adding one more type of command is worth the extra-complexity.

Show 7 quoted lines
> A different proposal would be to add a 'rebase --retry' which would
> inoke the last command again. And then the advice after 'exec' could say
> "Use --retry to rerun this command, and --continue to proceed with the
> next one".
>
> --retry could make sense for 'apply' commands too: if a commit fails to
> apply, one could do
[...]
That makes sense to me.
-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Marc Branchaud· Jun 14, 2012, 14:08 UTC · re: Matthieu Moy · lore

Re: [PATCHv5] rebase [-i --exec | -ix] <CMD>...

On 12-06-14 02:57 AM, Matthieu Moy wrote:
> Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:
> 
>>> Shouldn't "rebase --continue" after such a "commit --amend" resume
>>> execution from "exec cmd1", which failed in the initial run?
+1 for Junio's proposal.

Currently the only time --continue moves on to the next insn is in the "edit" case, when everything up to that point (including applying the "edit" commit) is fine. But if the rebase halted due to a problem, --continue ensures the problem is fixed before moving on to the next insn (e.g. it makes sure a merge conflict is resolved).

I think it makes the most sense for --continue after an exec-failure to try to re-run the exec. Furthermore, --skip after an exec failure should just skip the exec.

To me that makes --continue's (and --skip's) behaviour consistent with what it does when any other insn operation fails. In other words, if the rebase hits an exec failure, the user is going to want to fix it before continuing (just like any other failure during a rebase). If the user decides to not fix the failing exec, they can --skip it.

		M.
Matthieu Moy· Jun 8, 2012, 15:00 UTC · re: Lucien Kong · lore

Re: [PATCHv3 1/2] git-rebase.txt: "--onto" option updated

Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:
> +	<newbase>. <newbase is the starting point at which to create
Missing > after <newbase.
-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Junio C Hamano· Jun 8, 2012, 17:07 UTC · re: Lucien Kong · lore

Re: [PATCHv3 1/2] git-rebase.txt: "--onto" option updated

Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:
Show 20 quoted lines
> The description of the option "--onto" is changed to be consistent
> with the format of the other options.
> ...
>  OPTIONS
>  -------
> -<newbase>::
> -	Starting point at which to create the new commits. If the
> -	--onto option is not specified, the starting point is
> -	<upstream>.  May be any valid commit, and not just an
> -	existing branch name.
> +--onto <newbase>::
> +	With this option, git rebase takes all commits from <branch>,
> +	that are not in <upstream>, and transplants them on top of
> +	<newbase>. <newbase is the starting point at which to create
> +	the new commits. If the --onto option is not specified, the
> +	starting point is <upstream>.  May be any valid commit, and
> +	not just an existing branch name.
>  +
>  As a special case, you may use "A\...B" as a shortcut for the
>  merge base of A and B if there is exactly one merge base. You can
This is doing two unrelated things in a single patch, isn't it?

I would imagine that a patch that is about "to be consistent with the format" would be a one-liner

	-<newbase>::
        +--onto <newbase>::

without anything else. The change this patch makes to the explanation is much larger, but that is not justified in the proposed commit log message.

Besides, I find the new explanatory text much harder to understand than the original one.

konglu@minatec.inpg.fr· Jun 8, 2012, 19:06 UTC · re: Junio C Hamano · lore

Re: [PATCHv3 1/2] git-rebase.txt: "--onto" option updated

Junio C Hamano <gitster@pobox.com> a écrit :
Show 34 quoted lines
> Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:
>
>> The description of the option "--onto" is changed to be consistent
>> with the format of the other options.
>> ...
>>  OPTIONS
>>  -------
>> -<newbase>::
>> -	Starting point at which to create the new commits. If the
>> -	--onto option is not specified, the starting point is
>> -	<upstream>.  May be any valid commit, and not just an
>> -	existing branch name.
>> +--onto <newbase>::
>> +	With this option, git rebase takes all commits from <branch>,
>> +	that are not in <upstream>, and transplants them on top of
>> +	<newbase>. <newbase is the starting point at which to create
>> +	the new commits. If the --onto option is not specified, the
>> +	starting point is <upstream>.  May be any valid commit, and
>> +	not just an existing branch name.
>>  +
>>  As a special case, you may use "A\...B" as a shortcut for the
>>  merge base of A and B if there is exactly one merge base. You can
>
> This is doing two unrelated things in a single patch, isn't it?
>
> I would imagine that a patch that is about "to be consistent with
> the format" would be a one-liner
>
> 	-<newbase>::
>         +--onto <newbase>::
>
> without anything else.  The change this patch makes to the
> explanation is much larger, but that is not justified in the
> proposed commit log message.
That's what I thought, but it appeared to me that the description
--onto <newbase>::
         Starting point at which to create the new commits.
         If the --onto option is not specified, the starting
         point is <upstream>.  May be any valid commit, and
	not just an existing branch name.

only focus on the parameter <newbase>. It does not really explain first what the option is doing. With the second sentence, it's more like a description of "what happens when we run git rebase without --onto" than "what happens when we run git rebase with --onto".

Junio C Hamano <gitster@pobox.com> a écrit :
> 	--onto <newbase>::
> 		Description of what --onto option does and how <newbase>
> 		is used in what it does.
Junio C Hamano· Jun 8, 2012, 19:52 UTC · re: konglu@minatec.inpg.fr · lore

Re: [PATCHv3 1/2] git-rebase.txt: "--onto" option updated

konglu@minatec.inpg.fr writes:
Show 9 quoted lines
> That's what I thought, but it appeared to me that the description
>
> --onto <newbase>::
>          Starting point at which to create the new commits.
>          If the --onto option is not specified, the starting
>          point is <upstream>.  May be any valid commit, and
> 	not just an existing branch name.
>
> only focus on the parameter <newbase>.

Talking about <newbase> is equivalent to talking about --onto isn't it? What the command does is described far above upfront in the manual page; the description of options is the place to explain what details are affected by giving (or not giving) the option in the behaviour that was explained earlier.

konglu@minatec.inpg.fr· Jun 8, 2012, 20:08 UTC · re: Junio C Hamano · lore

Re: [PATCHv3 1/2] git-rebase.txt: "--onto" option updated

Junio C Hamano <gitster@pobox.com> a écrit :
Show 17 quoted lines
> konglu@minatec.inpg.fr writes:
>
>> That's what I thought, but it appeared to me that the description
>>
>> --onto <newbase>::
>>          Starting point at which to create the new commits.
>>          If the --onto option is not specified, the starting
>>          point is <upstream>.  May be any valid commit, and
>> 	not just an existing branch name.
>>
>> only focus on the parameter <newbase>.
>
> Talking about <newbase> is equivalent to talking about --onto isn't
> it?  What the command does is described far above upfront in the
> manual page; the description of options is the place to explain what
> details are affected by giving (or not giving) the option in the
> behaviour that was explained earlier.
Alright, gonna keep it unchanged then :).

← back to recent threads