Re: [PATCHv3 2/2] rebase [-i --exec | -ix] <CMD>...
From: Torsten Bögershausen <hidden>
Date: 2016-06-15 22:54:01
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
On 08.06.12 22:07, konglu@minatec.inpg.fr wrote:
Torsten Bögershausen [off-list ref] a écrit :quoted
On 08.06.12 21:15, konglu@minatec.inpg.fr wrote:quoted
Torsten Bögershausen [off-list ref] a écrit :quoted
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 f623ca1cae600e97cb0b38131fdd33e4fb669cf8I just tried to apply it on that commit and it works for me. What's the error message ?quoted
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 =================================================
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