{"thread":{"id":"46472","subject":"[RFC PATCH 1/5] rebase --continue: add --autostage to stage unstaged changes","startedAt":"2017-07-26T10:27:45Z","lastAt":"2017-08-25T11:54:51Z","messageCount":19,"participants":["Phillip Wood","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"325116","messageId":"20170726102720.15274-2-phillip.wood@talktalk.net","threadId":"46472","inReplyTo":"20170726102720.15274-1-phillip.wood@talktalk.net","subject":"[RFC PATCH 1/5] rebase --continue: add --autostage to stage unstaged changes","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-26T10:27:16Z","receivedAt":"2017-07-26T10:27:45Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nAfter resolving conflicts during a rebase it is a pain to have to run\n'git add' before 'git rebase --continue'. Passing --autostage to 'git\nrebase --continue' will stage them automatically so long as 'git diff\n--check' says they are ok. This is a safety measure to avoid\naccidentally staging files containing unresolved conflicts.\n\nContinuing an interactive rebase after a failed exec or if HEAD has\nchanged since rebase stopped with --autostage will stage changes that\nwont be committed as rebase --continue will bail out. This will be\nfixed in the next commit.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n\nUsing diff check is not ideal as it will error out on whitespace\nchanges (which should be check in a commit hook if the user is worried\nabout them) as well as merge markers. Looking through diff.c it should\nbe possible to add a --check=merge-markers optional argument as the\ntwo checks are enabled independently in the code. As Junio pointed out\nin a previous message [1] the absence of conflict markers does not\nindicate that a file is fully resolved but checking for them does at\nleast avoid the case of the user blindly continuing when they have\nforgotten to look at a conflicted file.\n\nThe autostaging behaviour is opt-in so users who like the additional\nsafety of having to do git add before git rebase --continue can\ncontinue using their current workflow.\n\nI wonder if check_unstaged() should give different error messages\ndepending on the presence of unmerged paths rather than saying\n'unstaged changes' all the time. Also it should probably have some\nmessage after the check for merge markers fails rather than just the\nraw output from diff --check.\n\n[1] https://public-inbox.org/git/xmqqmv7td0a5.fsf@gitster.mtv.corp.google.com/\n\n\n git-rebase--am.sh          |  1 +\n git-rebase--interactive.sh |  1 +\n git-rebase--merge.sh       |  1 +\n git-rebase.sh              | 76 +++++++++++++++++++++++++++++++++++++++++-----\n 4 files changed, 71 insertions(+), 8 deletions(-)\n\ndiff --git a/git-rebase--am.sh b/git-rebase--am.sh\nindex 375239341fbfe885e51a25e9e0dc2d4fee791345..30faa8c24cce2149a883c0055e3f6e93dabd2dd0 100644\n--- a/git-rebase--am.sh\n+++ b/git-rebase--am.sh\n@@ -17,6 +17,7 @@ git_rebase__am () {\n \n case \"$action\" in\n continue)\n+\tcheck_unstaged\n \tgit am --resolved --resolvemsg=\"$resolvemsg\" \\\n \t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} &&\n \tmove_to_original_branch\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 90b1fbe9cf6e8dfb2f4331916809fa40bf9050d2..4c037a3f7a9e01406c4205bf8786a3da5060381f 100644\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -1069,6 +1069,7 @@ git_rebase__interactive () {\n \n case \"$action\" in\n continue)\n+\tcheck_unstaged\n \tif test ! -d \"$rewritten\"\n \tthen\n \t\texec git rebase--helper ${force_rebase:+--no-ff} --continue\ndiff --git a/git-rebase--merge.sh b/git-rebase--merge.sh\nindex 06a4723d4db3db74ea17ace60d824e83cdee25e9..81723fc485882750c3ed7214b880d49cf55c6d68 100644\n--- a/git-rebase--merge.sh\n+++ b/git-rebase--merge.sh\n@@ -16,6 +16,7 @@ read_state () {\n continue_merge () {\n \ttest -d \"$state_dir\" || die \"$state_dir directory does not exist\"\n \n+\tcheck_unstaged\n \tunmerged=$(git ls-files -u)\n \tif test -n \"$unmerged\"\n \tthen\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex 2cf73b88e8e83ca34b9eb319dbc2b0a220139b0f..9ca387349b1cde440c4244de9125446fd35a7b67 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -9,7 +9,7 @@ OPTIONS_STUCKLONG=t\n OPTIONS_SPEC=\"\\\n git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]\n git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]\n-git-rebase --continue | --abort | --skip | --edit-todo\n+git-rebase --continue [--autostage] | --abort | --skip | --edit-todo\n --\n  Available options are\n v,verbose!         display a diffstat of what changed upstream\n@@ -32,6 +32,7 @@ verify             allow pre-rebase hook to run\n rerere-autoupdate  allow rerere to update index with resolved conflicts\n root!              rebase all reachable commits up to the root(s)\n autosquash         move commits that begin with squash!/fixup! under -i\n+a,autostage        add unstaged changes to the index when continuing\n committer-date-is-author-date! passed to 'git am'\n ignore-date!       passed to 'git am'\n signoff            passed to 'git am'\n@@ -69,6 +70,7 @@ merge_dir=\"$GIT_DIR\"/rebase-merge\n apply_dir=\"$GIT_DIR\"/rebase-apply\n verbose=\n diffstat=\n+autostage=false\n test \"$(git config --bool rebase.stat)\" = true && diffstat=t\n autostash=\"$(git config --bool rebase.autostash || echo false)\"\n fork_point=auto\n@@ -213,6 +215,67 @@ run_pre_rebase_hook () {\n \tfi\n }\n \n+check_autostage () {\n+\t# If the user has already staged files that contain whitespace\n+\t# errors or merge markers then we want ignore them so rebase\n+\t# --continue behaves consistency with and without --autostage\n+\tgit diff-index --diff-filter=U --cached --name-only -z HEAD |\n+\t\txargs -0 git diff-index --check HEAD -- &&\n+\tgit diff-files --diff-filter=MA --check &&\n+\tgit add -u ||\n+\t\texit $?\n+}\n+\n+autostage_advice () {\n+\tgettext \"\\\n+Unable to continue rebasing as there are unstaged changes.\n+Please stage or reset the changes before continuing with:\n+\n+  git rebase --continue\n+\n+or run:\n+\n+  git rebase --continue --autostage\n+\n+to stage them automatically.\n+\"\n+}\n+\n+check_unstaged () {\n+\tgit update-index --ignore-submodules --refresh >/dev/null\n+\tif ! git diff-files --quiet --ignore-submodules\n+\tthen\n+\t\tif test $autostage = true\n+\t\tthen\n+\t\t\tcheck_autostage\n+\t\telse\n+\t\t\tdie \"$(autostage_advice)\"\n+\t\tfi\n+\tfi\n+}\n+\n+parse_continue () {\n+\taction=continue\n+\tshift\n+\twhile test $# != 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t--autostage)\n+\t\t\tautostage=true\n+\t\t\t;;\n+\t\t--no-autostage)\n+\t\t\tautostage=false\n+\t\t\t;;\n+\t\t--)\n+\t\t\t;;\n+\t\t*)\n+\t\t\tusage\n+\t\t\t;;\n+\t\tesac\n+\tshift\n+\tdone\n+}\n+\n test -f \"$apply_dir\"/applying &&\n \tdie \"$(gettext \"It looks like git-am is in progress. Cannot rebase.\")\"\n \n@@ -243,7 +306,10 @@ do\n \t--verify)\n \t\tok_to_skip_pre_rebase=\n \t\t;;\n-\t--continue|--skip|--abort|--quit|--edit-todo)\n+\t--continue)\n+\t\tparse_continue \"$@\"\n+\t\t;;\n+\t--skip|--abort|--quit|--edit-todo)\n \t\ttest $total_argc -eq 2 || usage\n \t\taction=${1##--}\n \t\t;;\n@@ -374,12 +440,6 @@ continue)\n \t# Sanity check\n \tgit rev-parse --verify HEAD >/dev/null ||\n \t\tdie \"$(gettext \"Cannot read HEAD\")\"\n-\tgit update-index --ignore-submodules --refresh &&\n-\tgit diff-files --quiet --ignore-submodules || {\n-\t\techo \"$(gettext \"You must edit all merge conflicts and then\n-mark them as resolved using git add\")\"\n-\t\texit 1\n-\t}\n \tread_basic_state\n \trun_specific_rebase\n \t;;\n-- \n2.13.3\n\n"},{"id":"325117","messageId":"20170726102720.15274-4-phillip.wood@talktalk.net","threadId":"46472","inReplyTo":"20170726102720.15274-1-phillip.wood@talktalk.net","subject":"[RFC PATCH 3/5] Unify rebase amend message when HEAD has changed","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-26T10:27:18Z","receivedAt":"2017-07-26T10:27:46Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nIf rebase --interactive is unable to commit staged changes because\nHEAD has changed since rebase stopped the user gets different messages\ndepending on whether they specified --autostage or not. Update the\nmessages in the other code paths to match the --autostage one.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n\nThe change from error() to fprintf() is to keep the messages consistent,\nmaybe the messages in the shell script should be prefixed with\n'error:' instead.\n\n git-rebase--interactive.sh | 10 ++++++----\n sequencer.c                | 22 +++++++++++++++++-----\n 2 files changed, 23 insertions(+), 9 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 8140c88839b4f3a86f53faaaa2ba4433ecc7f58b..e1845e940b8de05b10b011d8167917a60a7c00b9 100644\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -1164,10 +1164,12 @@ $(unstaged_advice)\"\n \t\t\tdie \"$(gettext \"Error trying to find the author identity to amend commit\")\"\n \t\tif test -n \"$amend_head\"\n \t\tthen\n-\t\t\ttest -n \"$amend_ok\" ||\n-\t\t\tdie \"$(gettext \"\\\n-You have uncommitted changes in your working tree. Please commit them\n-first and then run 'git rebase --continue' again.\")\"\n+\t\t\ttest -n \"$amend_ok\" || {\n+\t\t\t\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n+\t\t\t\tdie \"$(gettext \"\\\n+Unable to commit changes as HEAD has changed since git rebase stopped.\")\n+$(staged_advice)\"\n+\t\t\t}\n \t\t\tdo_with_author git commit --amend --no-verify -F \"$msg\" -e \\\n \t\t\t\t${gpg_sign_opt:+\"$gpg_sign_opt\"} ||\n \t\t\t\tdie \"$(gettext \"Could not commit staged changes.\")\"\ndiff --git a/sequencer.c b/sequencer.c\nindex 3010faf86398697469e903318a35421d911acb23..2722d36781e5c47ee81eb3359aa6178042430e68 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -2214,12 +2214,24 @@ static int commit_staged_changes(struct replay_opts *opts)\n \t\tif (get_sha1_hex(rev.buf, to_amend))\n \t\t\treturn error(_(\"invalid contents: '%s'\"),\n \t\t\t\trebase_path_amend());\n-\t\tif (hashcmp(head, to_amend))\n-\t\t\treturn error(_(\"\\nYou have uncommitted changes in your \"\n-\t\t\t\t       \"working tree. Please, commit them\\n\"\n-\t\t\t\t       \"first and then run 'git rebase \"\n-\t\t\t\t       \"--continue' again.\"));\n+\t\tif (hashcmp(head, to_amend)) {\n+\t\t\tconst char *gpg_opt = gpg_sign_opt_quoted(opts);\n \n+\t\t\tfprintf(stderr, _(\n+\"Unable to commit changes as HEAD has changed since git rebase stopped.\\n\"\n+\"If you wish to squash the changes into the last commit, run:\\n\"\n+\"\\n\"\n+\"  git commit --amend %s\\n\"\n+\"\\n\"\n+\"If they are meant to go into a new commit, run:\\n\"\n+\"\\n\"\n+\"  git commit %s\\n\"\n+\"\\n\"\n+\"In both cases, once you're done, continue with:\\n\"\n+\"\\n\"\n+\"  git rebase --continue\\n\"), gpg_opt, gpg_opt);\n+\t\t\treturn -1;\n+\t\t}\n \t\tstrbuf_release(&rev);\n \t\tflags |= AMEND_MSG;\n \t}\n-- \n2.13.3\n\n"},{"id":"325118","messageId":"20170726102720.15274-5-phillip.wood@talktalk.net","threadId":"46472","inReplyTo":"20170726102720.15274-1-phillip.wood@talktalk.net","subject":"[RFC PATCH 4/5] Add tests for rebase --continue --autostage","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-26T10:27:19Z","receivedAt":"2017-07-26T10:27:48Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nMake sure that --autostage stages any changes and fails if there are\nmerge markers in the file to be staged.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t3418-rebase-continue.sh | 35 ++++++++++++++++++++++++++++++++++-\n 1 file changed, 34 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex 4428b9086e8bcb383df801834d0de323f316f4fa..4e71e5d5c2f26866cd5d32bfea445f899398d6c9 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -14,7 +14,6 @@ test_expect_success 'setup' '\n \n \tgit checkout -b topic HEAD^ &&\n \ttest_commit \"commit-new-file-F2-on-topic-branch\" F2 22 &&\n-\n \tgit checkout master\n '\n \n@@ -40,6 +39,40 @@ test_expect_success 'non-interactive rebase --continue works with touched file'\n \tgit rebase --continue\n '\n \n+reset () {\n+\trm -fr .git/rebase-* &&\n+\tgit reset --hard commit-new-file-F2-on-topic-branch &&\n+\tgit checkout master\n+}\n+\n+test_autostage () {\n+\taction=$1\n+\n+\ttest_expect_success \"rebase $action --continue --autostage stages changes\" '\n+\t\treset &&\n+\t\ttest_must_fail git rebase $action --onto master master topic &&\n+\t\techo \"Resolved\" >F2 &&\n+\t\tgit rebase --continue --autostage\n+'\n+\n+\ttest_expect_success \"rebase $action --continue --autostage fails when there are merge markers (1)\" '\n+\t\treset &&\n+\t\ttest_must_fail git rebase $action --onto master master topic &&\n+\t\ttest_must_fail git rebase --continue --autostage\n+'\n+\n+\ttest_expect_success \"rebase $action --continue --autostage  fails when there are merge markers (2)\" '\n+\t\treset &&\n+\t\ttest_must_fail git rebase $action --onto master master topic &&\n+\t\tgit reset -- F2 &&\n+\t\ttest_must_fail git rebase --continue --autostage\n+\t'\n+}\n+\n+test_autostage\n+test_autostage -i\n+test_autostage -m\n+\n test_expect_success 'non-interactive rebase --continue with rerere enabled' '\n \ttest_config rerere.enabled true &&\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n-- \n2.13.3\n\n"},{"id":"325119","messageId":"20170726102720.15274-6-phillip.wood@talktalk.net","threadId":"46472","inReplyTo":"20170726102720.15274-1-phillip.wood@talktalk.net","subject":"[RFC PATCH 5/5] Add rebase.continue.autostage config setting","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-26T10:27:20Z","receivedAt":"2017-07-26T10:27:50Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThis enables the user to always specify --autostage with --continue\n\nThe tests check that setting rebase.continue.autostage=true results in\n'git rebase --continue' autostaging unstaged changes and that\n'--no-autostage' overrides it.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n git-rebase.sh              |  2 +-\n t/t3418-rebase-continue.sh | 15 +++++++++++++++\n 2 files changed, 16 insertions(+), 1 deletion(-)\n\ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex 9ca387349b1cde440c4244de9125446fd35a7b67..632a19079ba1d88092f47121c7a0797af079aaf5 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -70,7 +70,7 @@ merge_dir=\"$GIT_DIR\"/rebase-merge\n apply_dir=\"$GIT_DIR\"/rebase-apply\n verbose=\n diffstat=\n-autostage=false\n+autostage=$(git config --bool --get rebase.continue.autostage || echo false)\n test \"$(git config --bool rebase.stat)\" = true && diffstat=t\n autostash=\"$(git config --bool rebase.autostash || echo false)\"\n fork_point=auto\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex 4e71e5d5c2f26866cd5d32bfea445f899398d6c9..7c2a30a3cd8ba7e33519bd68a3f89e90409169da 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -67,6 +67,21 @@ test_autostage () {\n \t\tgit reset -- F2 &&\n \t\ttest_must_fail git rebase --continue --autostage\n \t'\n+\n+\ttest_expect_success \"rebase.continue.autostage rebase $action works\" '\n+\t\treset &&\n+\t\ttest_must_fail git rebase $action --onto master master topic &&\n+\t\techo \"Resolved\" >F2 &&\n+\t\tgit -c rebase.continue.autostage=true rebase --continue\n+'\n+\n+\ttest_expect_success \"rebase $action --continue --no-autostage works\" '\n+\t\treset &&\n+\t\ttest_must_fail git rebase $action --onto master master topic &&\n+\t\techo \"Resolved\" >F2 &&\n+\t\ttest_must_fail git -c rebase.continue.autostage=true rebase --continue --no-autostage\n+'\n+\n }\n \n test_autostage\n-- \n2.13.3\n\n"},{"id":"325120","messageId":"20170726102720.15274-1-phillip.wood@talktalk.net","threadId":"46472","inReplyTo":null,"subject":"[RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-26T10:27:15Z","receivedAt":"2017-07-26T10:27:55Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThese patches add an '--autostage' option (and corresponding config\nvariable) to 'rebase --continue' that will stage any unstaged changes\nbefore continuing. This saves the user having to type 'git add' before\nrunning 'git rebase --continue'.\n\nPhillip Wood (5):\n  rebase --continue: add --autostage to stage unstaged changes\n  rebase -i: improve --continue --autostage\n  Unify rebase amend message when HEAD has changed\n  Add tests for rebase --continue --autostage\n  Add rebase.continue.autostage config setting\n\n git-rebase--am.sh             |   1 +\n git-rebase--interactive.sh    | 111 ++++++++++++++++++++++++++++++++----------\n git-rebase--merge.sh          |   1 +\n git-rebase.sh                 |  76 ++++++++++++++++++++++++++---\n sequencer.c                   |  22 +++++++--\n t/t3404-rebase-interactive.sh |   2 +-\n t/t3418-rebase-continue.sh    |  50 ++++++++++++++++++-\n 7 files changed, 222 insertions(+), 41 deletions(-)\n\n-- \n2.13.3\n\n"},{"id":"325121","messageId":"20170726102720.15274-3-phillip.wood@talktalk.net","threadId":"46472","inReplyTo":"20170726102720.15274-1-phillip.wood@talktalk.net","subject":"[RFC PATCH 2/5] rebase -i: improve --continue --autostage","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-26T10:27:17Z","receivedAt":"2017-07-26T10:27:57Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nIf HEAD has changed since the rebase stopped or rebase stopped due to\na failed exec then 'git rebase --continue --autostage' will autostage\nchanges that cannot be commited. Fix this by reordering some of the\nchecks so that 'git rebase --continue --autostage' never stages\nchanges unless they can be committed. Also reword some error\nmessages to account of --autostage and try and make them clearer.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n\nThis could do with some tests the check the correct error message is\ngiven in each failure case. However I'm expecting to change the error\nmessages based on the feedback I get to this patch so I'll add the\ntests once the messages are finalized. I've tried to give a bit more\nexplanation in the error messages as I found some of the previous\nmessages didn't explain why rebase couldn't continue. Splitting the\nadvice out means it is consistent between different code paths and\nshould make it easier to optionally disable it in future if anyone\nwanted to add that. As for the formatting of the messages I wonder if\nthey would be better without so many empty lines (I find the current\nmessages a bit intimating as they seem so long). e.g.\n\nIf you wish to squash the unstaged changes into the last commit, run:\n    git add -u\n    git commit --amend \\$gpg_sign_opt_quoted\nIf they are meant to go into a new commit, run:\n    git add -u\n    git commit \\$gpg_sign_opt_quoted\nIn both cases, once you're done, continue with:\n    git rebase --continue\n\nInstead of\n\nIf you wish to squash the unstaged changes into the last commit, run:\n\n  git add -u\n  git commit --amend \\$gpg_sign_opt_quoted\n\nIf they are meant to go into a new commit, run:\n\n  git add -u\n  git commit \\$gpg_sign_opt_quoted\n\nIn both cases, once you're done, continue with:\n\n  git rebase --continue\n\n\n git-rebase--interactive.sh    | 104 ++++++++++++++++++++++++++++++++----------\n t/t3404-rebase-interactive.sh |   2 +-\n 2 files changed, 81 insertions(+), 25 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 4c037a3f7a9e01406c4205bf8786a3da5060381f..8140c88839b4f3a86f53faaaa2ba4433ecc7f58b 100644\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -1056,6 +1056,42 @@ The possible behaviours are: ignore, warn, error.\")\"\n \tfi\n }\n \n+unstaged_advice () {\n+\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n+\teval_gettext \"\\\n+If you wish to squash the unstaged changes into the last commit, run:\n+\n+  git add -u\n+  git commit --amend \\$gpg_sign_opt_quoted\n+\n+If they are meant to go into a new commit, run:\n+\n+  git add -u\n+  git commit \\$gpg_sign_opt_quoted\n+\n+In both cases, once you're done, continue with:\n+\n+  git rebase --continue\n+\"\n+}\n+\n+staged_advice () {\n+\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n+\teval_gettext \"\\\n+If you wish to squash the staged changes into the last commit, run:\n+\n+  git commit --amend \\$gpg_sign_opt_quoted\n+\n+If they are meant to go into a new commit, run:\n+\n+  git commit \\$gpg_sign_opt_quoted\n+\n+In both cases, once you're done, continue with:\n+\n+  git rebase --continue\n+\"\n+}\n+\n # The whole contents of this file is run by dot-sourcing it from\n # inside a shell function.  It used to be that \"return\"s we see\n # below were not inside any function, and expected to return\n@@ -1067,9 +1103,50 @@ The possible behaviours are: ignore, warn, error.\")\"\n # here, and immediately call it after defining it.\n git_rebase__interactive () {\n \n+amend_head='' amend_ok=''\n case \"$action\" in\n continue)\n-\tcheck_unstaged\n+\ttest -f \"$amend\" &&\n+\t\tamend_head=$(cat \"$amend\") &&\n+\t\ttest $amend_head = $(git rev-parse HEAD) &&\n+\t\tamend_ok=1\n+\tgit update-index --refresh --ignore-submodules >/dev/null\n+\tgit diff-files --quiet --ignore-submodules\n+\tunstaged=$?\n+\tif ! test -f \"$author_script\"\n+\tthen\n+\t\tif test $unstaged = 1\n+\t\tthen\n+\t\t\tdie \"$(gettext \"Not expecting unstaged changes.\")\n+$(unstaged_advice)\"\n+\t\telif ! git diff-index --cached --quiet --ignore-submodules HEAD --\n+\t\tthen\n+\t\t\tdie \"$(gettext \"Not expecting staged changes.\")\n+$(staged_advice)\"\n+\t\tfi\n+\tfi\n+\tif test $unstaged = 1 && test $autostage = true\n+\tthen\n+\t\tif test -n \"$amend_head\" && test -z \"$amend_ok\"\n+\t\tthen\n+\t\t\tdie \"$(gettext \"\\\n+Unable to commit changes as HEAD has changed since git rebase stopped.\")\n+$(unstaged_advice)\"\n+\t\telse\n+\t\t\tcheck_autostage\n+\t\tfi\n+\telif test $unstaged = 1\n+\tthen\n+\t\tif test -n \"$amend_head\" && test -z \"$amend_ok\"\n+\t\tthen\n+\t\t\tdie \"$(gettext \"\\\n+Unable to continue rebasing as there are unstaged changes and\n+HEAD has changed since git rebase stopped.\")\n+$(unstaged_advice)\"\n+\t\telse\n+\t\t\tdie \"$(autostage_advice)\"\n+\t\tfi\n+\tfi\n \tif test ! -d \"$rewritten\"\n \tthen\n \t\texec git rebase--helper ${force_rebase:+--no-ff} --continue\n@@ -1083,31 +1160,11 @@ continue)\n \t\trm \"$GIT_DIR\"/CHERRY_PICK_HEAD ||\n \t\tdie \"$(gettext \"Could not remove CHERRY_PICK_HEAD\")\"\n \telse\n-\t\tif ! test -f \"$author_script\"\n-\t\tthen\n-\t\t\tgpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote \"$gpg_sign_opt\")}\n-\t\t\tdie \"$(eval_gettext \"\\\n-You have staged changes in your working tree.\n-If these changes are meant to be\n-squashed into the previous commit, run:\n-\n-  git commit --amend \\$gpg_sign_opt_quoted\n-\n-If they are meant to go into a new commit, run:\n-\n-  git commit \\$gpg_sign_opt_quoted\n-\n-In both cases, once you're done, continue with:\n-\n-  git rebase --continue\n-\")\"\n-\t\tfi\n \t\t. \"$author_script\" ||\n \t\t\tdie \"$(gettext \"Error trying to find the author identity to amend commit\")\"\n-\t\tif test -f \"$amend\"\n+\t\tif test -n \"$amend_head\"\n \t\tthen\n-\t\t\tcurrent_head=$(git rev-parse --verify HEAD)\n-\t\t\ttest \"$current_head\" = $(cat \"$amend\") ||\n+\t\t\ttest -n \"$amend_ok\" ||\n \t\t\tdie \"$(gettext \"\\\n You have uncommitted changes in your working tree. Please commit them\n first and then run 'git rebase --continue' again.\")\"\n@@ -1126,7 +1183,6 @@ first and then run 'git rebase --continue' again.\")\"\n \t\trecord_in_rewritten \"$(cat \"$state_dir\"/stopped-sha)\"\n \tfi\n \n-\trequire_clean_work_tree \"rebase\"\n \tdo_rest\n \treturn 0\n \t;;\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 37821d245433f757fa13f0a3e27da0312bebb7db..3eed8a3bc5a8e9c3bae32e181d367d9a9c0aff80 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -563,7 +563,7 @@ test_expect_success 'clean error after failed \"exec\"' '\n \techo \"edited again\" > file7 &&\n \tgit add file7 &&\n \ttest_must_fail git rebase --continue 2>error &&\n-\ttest_i18ngrep \"you have staged changes in your working tree\" error\n+\ttest_i18ngrep \"Not expecting staged changes\" error\n '\n \n test_expect_success 'rebase a detached HEAD' '\n-- \n2.13.3\n\n"},{"id":"325139","messageId":"xmqqa83rrrdu.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"20170726102720.15274-1-phillip.wood@talktalk.net","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-07-26T18:21:17Z","receivedAt":"2017-07-26T18:21:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> These patches add an '--autostage' option (and corresponding config\n> variable) to 'rebase --continue' that will stage any unstaged changes\n> before continuing. This saves the user having to type 'git add' before\n> running 'git rebase --continue'.\n\nI wonder if this interacts with existing rerere.autoupdate\nconfiguration variable and if so how (i.e. would they conflict and\nfight with each other?  would they work well together?  would one of\nthem make the other unnecessary?).  In any case, they look closely\nrelated and perhaps should be named similarly.\n\nI even have a suspicion that they may be essentially doing the same\nthing.\n\nFor a previous discussion, you start from here:\n\n  https://public-inbox.org/git/7vej6xb4lr.fsf@gitster.siamese.dyndns.org/#t\n\nand for the context, look at the original post by Ingo, to which the\nabove message is a response to.\n\nThanks.\n\n>\n> Phillip Wood (5):\n>   rebase --continue: add --autostage to stage unstaged changes\n>   rebase -i: improve --continue --autostage\n>   Unify rebase amend message when HEAD has changed\n>   Add tests for rebase --continue --autostage\n>   Add rebase.continue.autostage config setting\n>\n>  git-rebase--am.sh             |   1 +\n>  git-rebase--interactive.sh    | 111 ++++++++++++++++++++++++++++++++----------\n>  git-rebase--merge.sh          |   1 +\n>  git-rebase.sh                 |  76 ++++++++++++++++++++++++++---\n>  sequencer.c                   |  22 +++++++--\n>  t/t3404-rebase-interactive.sh |   2 +-\n>  t/t3418-rebase-continue.sh    |  50 ++++++++++++++++++-\n>  7 files changed, 222 insertions(+), 41 deletions(-)\n"},{"id":"325157","messageId":"xmqqa83qq2uf.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"xmqqa83rrrdu.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-07-26T21:56:40Z","receivedAt":"2017-07-26T21:56:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Phillip Wood <phillip.wood@talktalk.net> writes:\n>\n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>> These patches add an '--autostage' option (and corresponding config\n>> variable) to 'rebase --continue' that will stage any unstaged changes\n>> before continuing. This saves the user having to type 'git add' before\n>> running 'git rebase --continue'.\n>\n> I wonder if this interacts with existing rerere.autoupdate\n> configuration variable and if so how (i.e. would they conflict and\n> fight with each other?  would they work well together?  would one of\n> them make the other unnecessary?).  In any case, they look closely\n> related and perhaps should be named similarly.\n>\n> I even have a suspicion that they may be essentially doing the same\n> thing.\n>\n> For a previous discussion, you start from here:\n>\n>   https://public-inbox.org/git/7vej6xb4lr.fsf@gitster.siamese.dyndns.org/#t\n>\n> and for the context, look at the original post by Ingo, to which the\n> above message is a response to.\n>\n> Thanks.\n\nHmph, this is interesting.\n\n\"git rebase\" does take \"--rerere-autoupdate\" option from the command\nline, and propagates it to a later invocation of \"rebase --continue\"\nby storing the value to $state_dir/allow_rerere_autoupdate file and\nreading the value from it.  $allow_rerere_autoupdate shell variable\nis used to hold the setting.  \n\nI'd expect that this variable to be used in invocations of \"git am\"\nin git-rebase--am.sh; but that does not seem to be the case.  I\nwonder if this was once working but over time we broke the feature\nwithout anybody noticing it, or if the support was added but not\ncompleted and the feature was a no-op from the beginning?\n\n\n\n\n\n\n\n\n\n"},{"id":"325158","messageId":"xmqq60eeq24l.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"xmqqa83qq2uf.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-07-26T22:12:10Z","receivedAt":"2017-07-26T22:12:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Hmph, this is interesting.\n>\n> \"git rebase\" does take \"--rerere-autoupdate\" option from the command\n> line, and propagates it to a later invocation of \"rebase --continue\"\n> by storing the value to $state_dir/allow_rerere_autoupdate file and\n> reading the value from it.  $allow_rerere_autoupdate shell variable\n> is used to hold the setting.  \n>\n> I'd expect that this variable to be used in invocations of \"git am\"\n> in git-rebase--am.sh; but that does not seem to be the case.  I\n> wonder if this was once working but over time we broke the feature\n> without anybody noticing it, or if the support was added but not\n> completed and the feature was a no-op from the beginning?\n\nAt least in v1.7.0 when doing \"rebase -m\", the rerere-autoupdate was\nplumbed correctly through to the invocation of \"git merge\" that is\ndone inside git-rebase.sh.  I do not see the same option passed down\nto the invocation of \"git am\", so perhaps nobody cared back then\nabout rerere during \"git rebase\" that does not use \"git am\" backend,\neven though \"git am\" itself were capable of talking the option.\n\nIn any case, if you corrected the existing \"git rebase\" and its\nbackend so that \"--rerere-autoupdate\" works as advertised, I think\nyou are already 80% there without adding a yet another option, as I\nsuspect that the most of the need for avoiding \"git add\" during a\n\"git rebase\" session is during a conflict resolution, and allowing\n\"rerere\" to automatically update the index with auto-resolution will\nleave _only_ changes to the paths the end user actually needs to\ntake a look and manually fix still not in the index.  And from the\nworkflow point of view, encouraging them to \"git add\" their manual\nresolution after they are satisified with their changes by not doing\n\"git add\" blindly for all changes, like your --autostage\" does, is\nprobably a good thing.\n\n\n\n"},{"id":"325180","messageId":"8cdda835-0b4f-6ffb-31bf-6192999818be@talktalk.net","threadId":"46472","inReplyTo":"xmqq60eeq24l.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-27T10:36:05Z","receivedAt":"2017-07-27T10:36:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 26/07/17 23:12, Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> Hmph, this is interesting.\n>>\n>> \"git rebase\" does take \"--rerere-autoupdate\" option from the command\n>> line, and propagates it to a later invocation of \"rebase --continue\"\n>> by storing the value to $state_dir/allow_rerere_autoupdate file and\n>> reading the value from it.  $allow_rerere_autoupdate shell variable\n>> is used to hold the setting.  \n>>\n>> I'd expect that this variable to be used in invocations of \"git am\"\n>> in git-rebase--am.sh; but that does not seem to be the case.  I\n>> wonder if this was once working but over time we broke the feature\n>> without anybody noticing it, or if the support was added but not\n>> completed and the feature was a no-op from the beginning?\n> \n> At least in v1.7.0 when doing \"rebase -m\", the rerere-autoupdate was\n> plumbed correctly through to the invocation of \"git merge\" that is\n> done inside git-rebase.sh.  I do not see the same option passed down\n> to the invocation of \"git am\", so perhaps nobody cared back then\n> about rerere during \"git rebase\" that does not use \"git am\" backend,\n> even though \"git am\" itself were capable of talking the option.\n> \n> In any case, if you corrected the existing \"git rebase\" and its\n> backend so that \"--rerere-autoupdate\" works as advertised\n\nI've had a quick look and I think it's just a case of adding\n'$allow_rerere_autoupdate' to the invocation of 'git am'. 'git am' calls\nrerere_clear() when skipping so that doesn't need to go into the shell\nscript. I'll come up with a test to check it works as I think it does.\n\n> I think\n> you are already 80% there without adding a yet another option, as I\n> suspect that the most of the need for avoiding \"git add\" during a\n> \"git rebase\" session is during a conflict resolution, and allowing\n> \"rerere\" to automatically update the index with auto-resolution will\n> leave _only_ changes to the paths the end user actually needs to\n> take a look and manually fix still not in the index. \n\nI'm interested in the 20% as it's about 100% of my rebase conflicts.\nI've got rerere enabled but I cannot recall it helping me with a rebase\nconflict in the five or six years I've been using git [1]. A lot of my\nrebase conflicts come from fixup! commits or reordering things with\nrebase -i and generally they're only going to happen once as I don't\napply the same fixup! more than once and if I've rearranged commits the\nconflicts are likely to be different in the (possibly unlikely) event I\nrearrange them again in the future.\n\nOnce I've resolved a conflict I will look at the diff and maybe compile\nand run some tests. Then, if I'm happy I'll run 'git rebase --continue',\nto me the 'git add' stage doesn't really add anything useful, it's just\nan inconvenience.\n\nThe other use I have for --autostage is when editing commits with rebase\n-i, once I'm happy with the edit I just want to continue and have rebase\namend the commit. I don't feel having to run 'git add' is helpful in\nthis case.\n\n> And from the\n> workflow point of view, encouraging them to \"git add\" their manual\n> resolution after they are satisified with their changes by not doing\n> \"git add\" blindly for all changes, like your --autostage\" does, is\n> probably a good thing.\n\nIn my mind running 'git rebase --continue' is the signal to git that the\nconflicts are resolved.\n\nBest Wishes\n\nPhillip\n\n[1] Maybe I've not noticed it helping when rebasing onto an updated\nupstream, although if I'm actively changing the rebased commits between\nupstream updates the conflicts may well change between updates. Also I\ndon't tend to get many upstream conflicts with the projects I'm working on.\n\n"},{"id":"325183","messageId":"6a71f802-b20c-f6bc-7bb5-8d81db3353d8@talktalk.net","threadId":"46472","inReplyTo":"8cdda835-0b4f-6ffb-31bf-6192999818be@talktalk.net","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-07-27T13:25:40Z","receivedAt":"2017-07-27T13:25:53Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 27/07/17 11:36, Phillip Wood wrote:\n> On 26/07/17 23:12, Junio C Hamano wrote:\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> Hmph, this is interesting.\n>>>\n>>> \"git rebase\" does take \"--rerere-autoupdate\" option from the command\n>>> line, and propagates it to a later invocation of \"rebase --continue\"\n>>> by storing the value to $state_dir/allow_rerere_autoupdate file and\n>>> reading the value from it.  $allow_rerere_autoupdate shell variable\n>>> is used to hold the setting.\n>>>\n>>> I'd expect that this variable to be used in invocations of \"git am\"\n>>> in git-rebase--am.sh; but that does not seem to be the case.  I\n>>> wonder if this was once working but over time we broke the feature\n>>> without anybody noticing it, or if the support was added but not\n>>> completed and the feature was a no-op from the beginning?\n>>\n>> At least in v1.7.0 when doing \"rebase -m\", the rerere-autoupdate was\n>> plumbed correctly through to the invocation of \"git merge\" that is\n>> done inside git-rebase.sh.  I do not see the same option passed down\n>> to the invocation of \"git am\", so perhaps nobody cared back then\n>> about rerere during \"git rebase\" that does not use \"git am\" backend,\n>> even though \"git am\" itself were capable of talking the option.\n>>\n>> In any case, if you corrected the existing \"git rebase\" and its\n>> backend so that \"--rerere-autoupdate\" works as advertised\n> \n> I've had a quick look and I think it's just a case of adding\n> '$allow_rerere_autoupdate' to the invocation of 'git am'. 'git am' calls\n> rerere_clear() when skipping so that doesn't need to go into the shell\n> script. I'll come up with a test to check it works as I think it does.\n> \n>> I think\n>> you are already 80% there without adding a yet another option, as I\n>> suspect that the most of the need for avoiding \"git add\" during a\n>> \"git rebase\" session is during a conflict resolution, and allowing\n>> \"rerere\" to automatically update the index with auto-resolution will\n>> leave _only_ changes to the paths the end user actually needs to\n>> take a look and manually fix still not in the index.\n> \n> I'm interested in the 20% as it's about 100% of my rebase conflicts.\n> I've got rerere enabled but I cannot recall it helping me with a rebase\n> conflict in the five or six years I've been using git [1]. A lot of my\n> rebase conflicts come from fixup! commits or reordering things with\n> rebase -i and generally they're only going to happen once as I don't\n> apply the same fixup! more than once and if I've rearranged commits the\n> conflicts are likely to be different in the (possibly unlikely) event I\n> rearrange them again in the future.\n> \n> Once I've resolved a conflict I will look at the diff and maybe compile\n> and run some tests. Then, if I'm happy I'll run 'git rebase --continue',\n> to me the 'git add' stage doesn't really add anything useful, it's just\n> an inconvenience.\n> \n> The other use I have for --autostage is when editing commits with rebase\n> -i, once I'm happy with the edit I just want to continue and have rebase\n> amend the commit. I don't feel having to run 'git add' is helpful in\n> this case.\n> \n>> And from the\n>> workflow point of view, encouraging them to \"git add\" their manual\n>> resolution after they are satisified with their changes by not doing\n>> \"git add\" blindly for all changes, like your --autostage\" does, is\n>> probably a good thing.\n\nGit allows 'git commit -a' to complete a conflicted merge which I think \nis much the same thing as I'm proposing. Also there's nothing to stop a \nuser accidentally running 'git add' on a path that isn't resolved or \njust blindly running 'add -u' before continuing the rebase because they \nthink they've resolved everything. I guess it is a kind of \nconvenience/safety trade-off.\n\n> In my mind running 'git rebase --continue' is the signal to git that the\n> conflicts are resolved.\n> Best Wishes\n> \n> Phillip\n> \n> [1] Maybe I've not noticed it helping when rebasing onto an updated\n> upstream, although if I'm actively changing the rebased commits between\n> upstream updates the conflicts may well change between updates. Also I\n> don't tend to get many upstream conflicts with the projects I'm working on.\n\nThinking about it some more, once a conflict is resolved, the next time \nthat rewritten commit is rebased onto an updated upstream the same \nconflict will not occur as the rewritten commit that's being replayed \ndoes not conflict with the previous upstream - the resolution is baked \ninto the commit that's being replayed.\n\n"},{"id":"325189","messageId":"xmqqpocloqcp.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"6a71f802-b20c-f6bc-7bb5-8d81db3353d8@talktalk.net","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-07-27T15:24:06Z","receivedAt":"2017-07-27T15:24:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n>> On 26/07/17 23:12, Junio C Hamano wrote:\n>>> I think\n>>> you are already 80% there without adding a yet another option,...\n>> ...\n>> I'm interested in the 20% as it's about 100% of my rebase conflicts.\n\nOK, then at least a fixed --rerere-autoupdate would hopefully limit\nthe scope of the additional 20%; I'd suspect that a new option would\nalso internally turn on --rerere-autoupdate, so that the remaining\nchanges you would see upon --continue would be limited to what the\nuser had to manually resolve (and edit without having textual conflict,\naka evil merge to resolve semantic conflicts).\n\nI am *not* opposed to an option to tell the command to blindly take\nsuch remaining changes, as long as it stays optional---the use of\nthe option can then be taken as a strong signal that the user is OK\nwith the local changes in the working tree, even if the user may not\nhave marked them as resolved with \"git add\".\n\n>>> And from the\n>>> workflow point of view, encouraging them to \"git add\" their manual\n>>> resolution after they are satisified with their changes by not doing\n>>> \"git add\" blindly for all changes, like your --autostage\" does, is\n>>> probably a good thing.\n>\n> Git allows 'git commit -a' to complete a conflicted merge which I\n> think is much the same thing as I'm proposing....\n\n\"-a\" is a strong enough sign that the user is OK with all the paths;\n\"git commit\" without an option does not.  So it is OK for a new\noption (perhaps \"--all-autoupdate\", which does more than the\nexisting \"--rerere-autoupdate\") to become the signal that the user\nis OK with all the local changes.\n\nThis is a tangent, but concluding a merge with \"commit -a\" (or \"add\n-u && commit -a\") has always been discouraged among Git expert\nusers, and it will stay to be so.  If you search the list archive,\nyou would find a good explanation by Linus on this, but a short\nversion is that this is because it is normal to start a merge in a\ndirty working tree where the user has local changes that the user\nknows will not interfere with the merge.  \n\nBecause \"rebase\" refuses to work in a dirty working tree, the\nanalogy with \"merge\" does not quite hold.  Doing \"add -u\" before\ntelling it to \"--continue\" would be much safer.\n\nThanks.\n\n\n\n"},{"id":"326861","messageId":"a3b7af29-8b3a-5253-21da-957920212a6e@talktalk.net","threadId":"46472","inReplyTo":"xmqqpocloqcp.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-08-21T10:32:48Z","receivedAt":"2017-08-21T10:32:56Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 27/07/17 16:24, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood@talktalk.net> writes:\n> \n>>> On 26/07/17 23:12, Junio C Hamano wrote:\n>>>> I think\n>>>> you are already 80% there without adding a yet another option,...\n>>> ...\n>>> I'm interested in the 20% as it's about 100% of my rebase conflicts.\n> \n> OK, then at least a fixed --rerere-autoupdate would hopefully limit\n> the scope of the additional 20%; I'd suspect that a new option would\n> also internally turn on --rerere-autoupdate, so that the remaining\n> changes you would see upon --continue would be limited to what the\n> user had to manually resolve (and edit without having textual conflict,\n> aka evil merge to resolve semantic conflicts).\n\nI can see the logic in that but I was imagining (and the patches\nimplement) that the --autostage option would be passed to 'rebase\n--continue' not when the rebase was started by which time it is too late\nto turn on --rerere-autoupdate for the current conflicts. I prefer\nhaving to pass --autostage with --continue so that it is a concious\ndecision by the user to stage unstaged changes when they continue rather\nthan rebase just doing it each time it continues.\n\n> I am *not* opposed to an option to tell the command to blindly take\n> such remaining changes, as long as it stays optional---the use of\n> the option can then be taken as a strong signal that the user is OK\n> with the local changes in the working tree, even if the user may not\n> have marked them as resolved with \"git add\".\n\nI agree it definitely needs to be optional (possibly with a config\noption to have it on by default but I'm not wedded to that as it is easy\nto set up a git or shell alias)\n\nWhat is the best way forward on this? The patches I posted add a\n'--autostage' option to be passed with '--continue' which means that\nstaging all the unstaged changes remains optional but does not allow\n--rerere-autoupdate to be automatically enabled. I'm not sure about the\ncheck for merge markers, as it is implemented it also checks for\nwhitespace errors which is really the domain of the pre-commit hook. If\nwe go for an explicit --autostage without the config key to make it on\nby default then maybe it is OK to drop the check, but it keeping it\ncould be a useful safety measure. I don't think it would be too much\nwork the change diff to allow '--check=merge-markers' as internally the\nwhitespace and marker checks are implemented separately.\n\nBest Wishes\n\nPhillip\n\n>>>> And from the\n>>>> workflow point of view, encouraging them to \"git add\" their manual\n>>>> resolution after they are satisified with their changes by not doing\n>>>> \"git add\" blindly for all changes, like your --autostage\" does, is\n>>>> probably a good thing.\n>>\n>> Git allows 'git commit -a' to complete a conflicted merge which I\n>> think is much the same thing as I'm proposing....\n> \n> \"-a\" is a strong enough sign that the user is OK with all the paths;\n> \"git commit\" without an option does not.  So it is OK for a new\n> option (perhaps \"--all-autoupdate\", which does more than the\n> existing \"--rerere-autoupdate\") to become the signal that the user\n> is OK with all the local changes.\n> \n> This is a tangent, but concluding a merge with \"commit -a\" (or \"add\n> -u && commit -a\") has always been discouraged among Git expert\n> users, and it will stay to be so.  If you search the list archive,\n> you would find a good explanation by Linus on this, but a short\n> version is that this is because it is normal to start a merge in a\n> dirty working tree where the user has local changes that the user\n> knows will not interfere with the merge.  \n> \n> Because \"rebase\" refuses to work in a dirty working tree, the\n> analogy with \"merge\" does not quite hold.  Doing \"add -u\" before\n> telling it to \"--continue\" would be much safer.\n> \n> Thanks.\n> \n> \n> \n\n"},{"id":"326910","messageId":"xmqqinhg5ysf.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"a3b7af29-8b3a-5253-21da-957920212a6e@talktalk.net","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-08-21T22:41:36Z","receivedAt":"2017-08-21T22:41:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n> ... I prefer\n> having to pass --autostage with --continue so that it is a concious\n> decision by the user to stage unstaged changes when they continue rather\n> than rebase just doing it each time it continues.\n\nIn other words, instead of\n\n\tgit add -u && git rebase --continue\n\nyou would want a quicker way to say\n\n\tgit rebase --continue $something_here \n\nIf that is the case, that is understandable to me.  Is the \"-u\" (I\nthink \"git add -u\" is short for \"--update\" but I didn't check) taken\nas a valid option to \"git rebase\"?  If not, that $something_here could\nbe \"-u\".\n\nThanks for pinging the thread; otherwise I would have forgotten,\nespecially because not many other people were involved in the\ndiscussion to begin with.\n\n"},{"id":"326927","messageId":"d1eaed1c-5e62-0a93-f65d-06be43812617@talktalk.net","threadId":"46472","inReplyTo":"xmqqinhg5ysf.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-08-22T10:54:44Z","receivedAt":"2017-08-22T10:54:53Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 21/08/17 23:41, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood@talktalk.net> writes:\n> \n>> ... I prefer\n>> having to pass --autostage with --continue so that it is a concious\n>> decision by the user to stage unstaged changes when they continue rather\n>> than rebase just doing it each time it continues.\n> \n> In other words, instead of\n> \n> \tgit add -u && git rebase --continue\n> \n> you would want a quicker way to say\n> \n> \tgit rebase --continue $something_here \n\nExactly\n\n> If that is the case, that is understandable to me.  Is the \"-u\" (I\n> think \"git add -u\" is short for \"--update\" but I didn't check) taken\n> as a valid option to \"git rebase\"?  If not, that $something_here could\n> be \"-u\".\n\nAt the moment $something_else is -a/--autostage but -u/--update (I've\nchecked the add man page and you're right) could be good as well.\n\nrebase --continue -a\n\nbehaves like commit -a in that it commits all updated tracked files and\ndoes not take pathspecs, if we go for -u then there is a difference with\n'git add -u' as that can take an optional pathspec.\n\n\nDid you have any further thoughts on what checks if any this new option\nshould make to avoid staging obviously unresolved files?\n\n> Thanks for pinging the thread; otherwise I would have forgotten,\n> especially because not many other people were involved in the\n> discussion to begin with.\n\nYes it would be interesting to hear if this would be useful for others too.\n\nBest Wishes\n\nPhillip\n\n\n\n"},{"id":"326935","messageId":"xmqqefs34mz4.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"d1eaed1c-5e62-0a93-f65d-06be43812617@talktalk.net","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-08-22T15:54:23Z","receivedAt":"2017-08-22T15:54:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n>> In other words, instead of\n>> \n>> \tgit add -u && git rebase --continue\n>> \n>> you would want a quicker way to say\n>> \n>> \tgit rebase --continue $something_here \n>\n> Exactly\n> ...\n> rebase --continue -a\n>\n> behaves like commit -a in that it commits all updated tracked files and\n> does not take pathspecs.\n\nHmph, but what 'a' in \"commit -a\" wants to convey is \"all\", and in\nthe context of \"rebase\" we want to avoid saying \"all\".  A user can\nbe confused into thinking \"all\" refers to \"all subsequent commits\" \nnot \"all paths conflicted\".\n\nBesides, with the $something_here option, the user is explicitly\ntelling us that the user finisished the resolution of conflicts left\nin the working tree.  There is nothing \"auto\" about it.\n\n> Did you have any further thoughts on what checks if any this new option\n> should make to avoid staging obviously unresolved files?\n\nThe more I think about this, the more I am convinced that it is a\nvery bad idea to give such a $something_here option only to \"rebase\".\n\nThe standard flow for any operation that could stop in the middle\nbecause the command needs help from the user with conflicts that\ncannot be mechanically resolved is\n\n (1) write out conflicted state in the working tree, and mark these\n     paths in the index by leaving them in higher stages\n     (i.e. \"ls-files -u\" would list them);\n\n (2) the user edits them and marks the ones that are now resolved;\n\n (3) the user tells us to \"continue\".\n\nand this is not limited to \"rebase\".  \"cherry-pick\", \"am\", and\n\"revert\" all share the above, and even \"merge\" (which is a single\ncommit operation to which \"continue\" in its original meaning---to\ntell us the user is done with this step and wants us to go on\nprocessing further commits or patches---does not quite apply) does.\n\nAnd \"rebase\" is an oddball in that it is the only command that we\ncould deduce which files in the working tree should be \"add\"ed, i.e.\n\"all the files that are different from HEAD\".  All others allow\nusers to begin in a dirty working tree (they only require the index\nto be clean), so your \n\n\tgit [cherry-pick|am|revert] --continue $something_here\n\ncannot be \"git add -u && git [that command] --continue\".  Blindly\ntaking any and all files that have modifications from HEAD will\nproduce a wrong result.\n\nYou cannot even sanely solve that by first recording the paths that\nare conflicted before giving control back to the user and limit the\n\"add\" to them, i.e. doing \"git add\" only for paths that appear in\n\"git ls-files -u\" output would not catch additional changes the was\nneeded in files that did not initially conflict (i.e. \"evil merge\"\nwill have to modify a file that was not involved in the mechanical\npart of the conflict), because out of the files that are dirty in\nthe working tree, some are evil merge resolutions and others are\nones that were dirty from the beginning.\n\nThe only reason \"git rebase\" can get away without having to worry\nabout all of the above is because it insists that the working tree\nis clean before it begins.  In the ideal world, however, we would\nwant to lift that and allow it to start in a working tree that has\nan unfinished local modification that does not interfere with the\nrebase, just like all other operations that could stop upon a\nconflict.  And when that happens, your $something_here option to\n\"git rebase --continue\" will have to worry about it, too.\n\nSo...\n"},{"id":"327124","messageId":"5dcd588d-b6ce-713d-dc28-25853d5bb4b3@talktalk.net","threadId":"46472","inReplyTo":"xmqqefs34mz4.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-08-24T13:25:05Z","receivedAt":"2017-08-24T13:25:16Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 22/08/17 16:54, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood@talktalk.net> writes:\n> \n>>> In other words, instead of\n>>>\n>>> \tgit add -u && git rebase --continue\n>>>\n>>> you would want a quicker way to say\n>>>\n>>> \tgit rebase --continue $something_here \n>>\n>> Exactly\n>> ...\n>> rebase --continue -a\n>>\n>> behaves like commit -a in that it commits all updated tracked files and\n>> does not take pathspecs.\n> \n> Hmph, but what 'a' in \"commit -a\" wants to convey is \"all\", and in\n> the context of \"rebase\" we want to avoid saying \"all\".  A user can\n> be confused into thinking \"all\" refers to \"all subsequent commits\" \n> not \"all paths conflicted\".\n> \n> Besides, with the $something_here option, the user is explicitly\n> telling us that the user finisished the resolution of conflicts left\n> in the working tree.  There is nothing \"auto\" about it.\n> \n>> Did you have any further thoughts on what checks if any this new option\n>> should make to avoid staging obviously unresolved files?\n> \n> The more I think about this, the more I am convinced that it is a\n> very bad idea to give such a $something_here option only to \"rebase\".\n> \n> The standard flow for any operation that could stop in the middle\n> because the command needs help from the user with conflicts that\n> cannot be mechanically resolved is\n> \n>  (1) write out conflicted state in the working tree, and mark these\n>      paths in the index by leaving them in higher stages\n>      (i.e. \"ls-files -u\" would list them);\n> \n>  (2) the user edits them and marks the ones that are now resolved;\n> \n>  (3) the user tells us to \"continue\".\n> \n> and this is not limited to \"rebase\".  \"cherry-pick\", \"am\", and\n> \"revert\" all share the above, and even \"merge\" (which is a single\n> commit operation to which \"continue\" in its original meaning---to\n> tell us the user is done with this step and wants us to go on\n> processing further commits or patches---does not quite apply) does.\n> \n> And \"rebase\" is an oddball in that it is the only command that we\n> could deduce which files in the working tree should be \"add\"ed, i.e.\n> \"all the files that are different from HEAD\".  All others allow\n> users to begin in a dirty working tree (they only require the index\n> to be clean), \n\nAre you sure about that, the second sentence of the cherry-pick man page\nis \"This requires your working tree to be clean (no modifications from\nthe HEAD commit).\". If you pass '--no-commit' then this is relaxed so\nthat the index can differ from HEAD but it is not clear from the man\npage if the working tree can differ from the index (potentially that\ncould give different conflicts in the index and working tree). I'm not\nsure what a rebase that does not commit changes would look like.\n\n> so your \n> \n> \tgit [cherry-pick|am|revert] --continue $something_here\n> \n> cannot be \"git add -u && git [that command] --continue\".  Blindly\n> taking any and all files that have modifications from HEAD will\n> produce a wrong result.\n> \n> You cannot even sanely solve that by first recording the paths that\n> are conflicted before giving control back to the user and limit the\n> \"add\" to them, i.e. doing \"git add\" only for paths that appear in\n> \"git ls-files -u\" output would not catch additional changes the was\n> needed in files that did not initially conflict (i.e. \"evil merge\"\n> will have to modify a file that was not involved in the mechanical\n> part of the conflict), because out of the files that are dirty in\n> the working tree, some are evil merge resolutions and others are\n> ones that were dirty from the beginning.\n\nI wonder if git could record the state of the working tree in a\ntemporary index just before it exits with conflicts. Then when the user\nhas resolved the conflicts\n\ngit [cherry-pick|am|revert] --continue $something_here\n\ncould do something like\n\n{ GIT_INDEX_FILE=$TMP_INDEX git diff-files --name-only &&\n    git ls-files -u } | git update-index --remove --stdin\n\nto stage the files that the user has edited. This would not catch the\ncase where a new untracked file has been created that should be added to\nthe conflict resolution, but I think it is reasonable to expect the user\nto manually add new files in this case. It would also not add an\nunchanged file whose changes should be part of the conflict resolution\nbut I can't think of a sensible case where the user might want that at\nthe moment.\n\n> \n> The only reason \"git rebase\" can get away without having to worry\n> about all of the above is because it insists that the working tree\n> is clean before it begins.  In the ideal world, however, we would\n> want to lift that and allow it to start in a working tree that has\n> an unfinished local modification that does not interfere with the\n> rebase, just like all other operations that could stop upon a\n> conflict. \n\nIt could be expensive to check that the local modifications will not\ninterfere with the rebase - wouldn't it have to look at all the files\ntouched by each commit before starting? What do cherry-pick and am do\nhere when picking several commits?\n\n And when that happens, your $something_here option to\n> \"git rebase --continue\" will have to worry about it, too.\n> So...\n> \n\n"},{"id":"327138","messageId":"xmqqtw0wx6b1.fsf@gitster.mtv.corp.google.com","threadId":"46472","inReplyTo":"5dcd588d-b6ce-713d-dc28-25853d5bb4b3@talktalk.net","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-08-24T16:46:10Z","receivedAt":"2017-08-24T16:46:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n> It could be expensive to check that the local modifications will not\n> interfere with the rebase - wouldn't it have to look at all the files\n> touched by each commit before starting? What do cherry-pick and am do\n> here when picking several commits?\n\nYes, so?\n\n\"I do not think of a way to implement it cheaply, so we forbid\nanybody from finding a clever optimization to implement it cheaply\nby adding a feature that will not work well with it when it\nhappens?\"\n\n"},{"id":"327183","messageId":"81909475-5801-c32b-efb5-a2a90c959a21@talktalk.net","threadId":"46472","inReplyTo":"xmqqtw0wx6b1.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC PATCH 0/5] Add option to autostage changes when continuing a rebase","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-08-25T11:54:43Z","receivedAt":"2017-08-25T11:54:51Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 24/08/17 17:46, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood@talktalk.net> writes:\n> \n>> It could be expensive to check that the local modifications will not\n>> interfere with the rebase - wouldn't it have to look at all the files\n>> touched by each commit before starting? What do cherry-pick and am do\n>> here when picking several commits?\n> \n> Yes, so?\n> \n> \"I do not think of a way to implement it cheaply, so we forbid\n> anybody from finding a clever optimization to implement it cheaply\n> by adding a feature that will not work well with it when it\n> happens?\"\n> \nOuch, I think that is a rather unfair characterization of what I said\nand certainly does not reflect what I was trying to say. I was asking\nsince cherry-pick and am can pick/apply multiple commits/patches and\napparently allow the user to start with a dirty tree what do they do\nabout checking that the applied commits/patches do not interfere with\nany local changes. As for \"adding a feature that will not work well with\nit when it happens?\" I suggested a possible solution in the message.\n\nAnyway you're not convinced this feature is a good idea and no one else\nhas commented so I'll drop it.\n\nPhil\n"}]}