{"thread":{"id":"30608","subject":"[PATCH/RFC] t7512-status-warnings.sh : better advices for git status","startedAt":"2012-05-24T09:37:43Z","lastAt":"2012-06-12T07:14:12Z","messageCount":97,"participants":["Kong Lucien","Matthieu Moy","Nguyen Thai Ngoc Duy","NGUY Thomas","Junio C Hamano","konglu@minatec.inpg.fr","Andrew Ardill","Phil Hord","Lucien Kong"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"192057","messageId":"1337852264-32619-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":null,"subject":"[PATCH/RFC] t7512-status-warnings.sh : better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-24T09:37:43Z","receivedAt":"2012-05-24T09:37:43Z","isPatch":true,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"Tests for the display of 'git status' before and after a conflict\nresolved, and after a conflict warning during a rebase.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n---\nThe three following tests are supposed to be successful\nbut are not currently as we are not sure about the implementation.\nFor example, should the warning messages be in the top header of 'git status' or after that ?\nIf the warning messages are put as in the following tests,\nwe will have to code the messages in remote.c, and not in wt-status.c.\n\nWe are also working on the same kind of messages for git am and bisect.\n\n git/t/t7512-status-warnings.sh |   96 ++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 96 insertions(+), 0 deletions(-)\n create mode 100755 git/t/t7512-status-warnings.sh\n\ndiff --git a/git/t/t7512-status-warnings.sh b/git/t/t7512-status-warnings.sh\nnew file mode 100755\nindex 0000000..0214348\n--- /dev/null\n+++ b/git/t/t7512-status-warnings.sh\n@@ -0,0 +1,96 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\tgit init --shared --bare conflict_test.git &&\n+\tgit clone conflict_test.git test1 &&\n+\tgit clone conflict_test.git test2 &&\n+\tcd ./test1 &&\n+\ttest_commit A main.txt toto &&\n+\tcd ../test2 &&\n+\ttest_commit B main.txt tata &&\n+\tgit push --all &&\n+\tcd ../test1 &&\n+\ttest_must_fail git pull &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Your branch and '\\''origin/master'\\'' have diverged,\n+\t# and have 1 and 1 different commit each, respectively.\n+\t# You have unmerged paths : fix conflicts and then commit the result.\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\techo toto > main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Your branch and '\\''origin/master'\\'' have diverged,\n+\t# and have 1 and 1 different commit each, respectively.\n+\t# You are still merging, commit to end merge.\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+\n+test_expect_success 'status when rebase in progress' '\n+\tgit commit -m \"one\" &&\n+\ttest_commit two main.txt tata &&\n+\ttest_commit three main.txt titi &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing : fix conflicts and then run \"git rebase -- continue\".\n+\t# If you would prefer to skip this patch, instead run \"git rebase --skip\".\n+\t# To check out  the original branch and stop rebasing run \"git rebase --abort\".\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192087","messageId":"vpqpq9t32q2.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1337852264-32619-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCH/RFC] t7512-status-warnings.sh : better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-24T17:31:33Z","receivedAt":"2012-05-24T17:31:33Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"(We met off-list and already did a few fixes, but here are a few more)\n\nKong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +test_expect_success 'status when conflicts unresolved' '\n> +\tgit init --shared --bare conflict_test.git &&\n> +\tgit clone conflict_test.git test1 &&\n> +\tgit clone conflict_test.git test2 &&\n\nYou don't need to clone to get conflicts. Just create local branches and\nuse \"git merge\".\n\n> +test_expect_success 'status when conflicts resolved before commit' '\n> +\techo toto > main.txt &&\n\n\"toto\" would usually be \"foo\" in english ;-).\n\nWe usually write >main, not > main.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192240","messageId":"1338035905-24166-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1337852264-32619-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv2 1/2] wt-status: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-26T12:38:24Z","receivedAt":"2012-05-26T12:38:24Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides more information about your current state after a git status command (in the cases of conflicts, before and after they are resolved, a rebase or a bisect process).\nThis would help users to know what they are currently doing, in a more accurate way.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\n wt-status.c |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h |    1 +\n 2 files changed, 90 insertions(+), 0 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..9839280 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -15,6 +15,7 @@\n \n static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n \tGIT_COLOR_GREEN,  /* WT_STATUS_UPDATED */\n \tGIT_COLOR_RED,    /* WT_STATUS_CHANGED */\n \tGIT_COLOR_RED,    /* WT_STATUS_UNTRACKED */\n@@ -728,6 +729,92 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static void wt_status_print_in_progress(struct wt_status *s)\n+{\n+\tint i;\n+\tconst char *c = color(WT_STATUS_IN_PROGRESS, s);\n+\tconst char *git_dir = getenv(GIT_DIR_ENVIRONMENT);\n+\tconst char* path;\n+\tint unmerged_state = 0;\n+\tint rebase_state = 0;\n+\tint rebase_interactive_state = 0;\n+\tint am_state = 0;\n+\tint bisect_state = 0;\n+\tint conflict = 0;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\tstruct string_list_item *it;\n+\t\tit = &(s->change.items[i]);\n+\t\td = it->util;\n+\t\tif (d->stagemask) {\n+\t\t\tconflict = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t}\n+\n+\tpath = mkpath(\"%s/MERGE_HEAD\", git_dir);\n+\tif (!access(path, R_OK))\n+\t\tunmerged_state = 1;\n+\n+\tpath = mkpath(\"%s/rebase-apply\", git_dir);\n+\tif (!access(path, R_OK)) {\n+\t\tpath = mkpath(\"%s/rebase-apply/applying\", git_dir);\n+\t\tif (!access(path, R_OK))\n+\t\t\tam_state = 1;\n+\t\telse\n+\t\t\trebase_state = 1;\n+\t}\n+\telse {\n+\t\tpath = mkpath(\"%s/rebase-merge\", git_dir);\n+\t\tif (!access(path, R_OK)) {\n+\t\t\tpath = mkpath(\"%s/rebase-merge/interactive\", git_dir);\n+\t\t\tif (!access(path, R_OK))\n+\t\t\t\trebase_interactive_state = 1;\n+\t\t\telse\n+\t\t\t\trebase_state = 1;\n+\t\t}\n+\t}\n+\n+\tpath = mkpath(\"%s/BISECT_LOG\", git_dir);\n+\tif (!access(path, R_OK))\n+\t\tbisect_state = 1;\n+\n+\tif(bisect_state) {\n+\t\tstatus_printf_ln(s, c, _(\"You are currently bisecting.\"));\n+\t\tstatus_printf_ln(s, c, _(\"To get back to the original branch run \\\"git bisect reset\\\"\"));\n+\t\twt_status_print_trailer(s);\n+\t}\n+\n+\tif(unmerged_state) {\n+\t\tif (conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"You have unmerged paths: fix conflicts and then commit the result.\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n+\t\twt_status_print_trailer(s);\n+\t}\n+\n+\tif(rebase_state || rebase_interactive_state) {\n+\t\tif (conflict) {\n+\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: fix conflicts and then run \\\"git rebase -- continue\\\".\"));\n+\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n+\t\t\tstatus_printf_ln(s, c, _(\"To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n+\t\t}\n+\t\telse {\n+\t\t\tif (rebase_state)\n+\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: all conflicts fixed; run \\\"git rebase --continue\\\".\"));\n+\t\t\telse {\n+\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently editing in a rebase progress.\"));\n+\t\t\t\tstatus_printf_ln(s, c, _(\"You can amend the commit with\"));\n+\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit commit --amend\"));\n+\t\t\t\tstatus_printf_ln(s, c, _(\"Once you are satisfied with your changes, run\"));\n+\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit rebase --continue\"));\n+\t\t\t}\n+\t\t}\n+\t\twt_status_print_trailer(s);\n+\t}\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +837,8 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_in_progress(s);\n+\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..3d86801 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -7,6 +7,7 @@\n \n enum color_wt_status {\n \tWT_STATUS_HEADER = 0,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_UPDATED,\n \tWT_STATUS_CHANGED,\n \tWT_STATUS_UNTRACKED,\n-- \n1.7.8\n"},{"id":"192239","messageId":"1338035905-24166-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338035905-24166-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv2 2/2] t7512-status-warnings.sh: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-26T12:38:25Z","receivedAt":"2012-05-26T12:38:25Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user\nneeds to run 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am progress.\n\nAlso, the test t7060-wtstatus.sh is now compatible with the new warning messages.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\nThe 3 tests about 'am' are currently not successful because it's still\nnot implemented.\n\n t/t7060-wtstatus.sh        |    2 +\n t/t7512-status-warnings.sh |  280 ++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 282 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-warnings.sh\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..d9a1e18 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths: fix conflicts and then commit the result.\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\ndiff --git a/t/t7512-status-warnings.sh b/t/t7512-status-warnings.sh\nnew file mode 100755\nindex 0000000..ef3531f\n--- /dev/null\n+++ b/t/t7512-status-warnings.sh\n@@ -0,0 +1,280 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\tgit init --shared --bare conflict_test.git &&\n+\tgit clone conflict_test.git test1 &&\n+\tgit clone conflict_test.git test2 &&\n+\tcd ./test1 &&\n+\ttest_commit A main.txt one &&\n+\tcd ../test2 &&\n+\ttest_commit B main.txt two &&\n+\tgit push --all &&\n+\tcd ../test1 &&\n+\ttest_must_fail git pull &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Your branch and '\\''origin/master'\\'' have diverged,\n+\t# and have 1 and 1 different commit each, respectively.\n+\t#\n+\t# You have unmerged paths: fix conflicts and then commit the result.\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\techo one > main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Your branch and '\\''origin/master'\\'' have diverged,\n+\t# and have 1 and 1 different commit each, respectively.\n+\t#\n+\t# You are still merging, run \"git commit\" to conclude merge.\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\tgit commit -m \"one\" &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: fix conflicts and then run \"git rebase -- continue\".\n+\t# If you would prefer to skip this patch, instead run \"git rebase --skip\".\n+\t# To check out  the original branch and stop rebasing run \"git rebase --abort\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\ttest_when_finished \"cd ../ && rm -rf test1 test2 conflict_test.git\" &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: all conflicts fixed; run \"git rebase --continue\".\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git fake-editor.sh\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing in a rebase progress.\n+\t# You can amend the commit with\n+\t#\tgit commit --amend\n+\t# Once you are satisfied with your changes, run\n+\t#\tgit rebase --continue\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output &&\n+\tgit rebase --abort\n+'\n+\n+\n+\n+test_expect_success 'status in am progress : file already exists' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one  \" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress :\n+\t# One of the files added by the patch already exists in index !\n+\t# When you have resolved this problem run \"git am --resolved\".\n+\t# If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t# To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status in am progress : file does not exist' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one\" &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"delete main.txt\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress :\n+\t# One of the files deleted by the patch does not exist in index !\n+\t# When you have resolved this problem run \"git am --resolved\".\n+\t# If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t# To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status in am progress : patch corrupted/wrong format' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one one.txt \"one\" &&\n+\ttest_commit two two.txt \"two\" &&\n+\ttest_commit three three.txt \"three\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all\" &&\n+\techo error >Maildir/0002-two.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress :\n+\t# One of the patches is empty or corrupted !\n+\t# When you have resolved this problem run \"git am --resolved\".\n+\t# If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t# To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t# To get back to the original branch run \"git bisect reset\"\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192242","messageId":"CACsJy8Dx=HWKJ8H3LQhVAAJGtZKmMe0d5e3Q7eHER6Xo4yTAZw@mail.gmail.com","threadId":"30608","inReplyTo":"1338035905-24166-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-05-26T13:01:08Z","receivedAt":"2012-05-26T13:01:08Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, May 26, 2012 at 7:38 PM, Kong Lucien\n<Lucien.Kong@ensimag.imag.fr> wrote:\n> +       path = mkpath(\"%s/MERGE_HEAD\", git_dir);\n\nYou can use git_path(\"MERGE_HEAD\") for this, just don't save it. The\nsame for other call sites\n\n> +       if(bisect_state) {\n> +               status_printf_ln(s, c, _(\"You are currently bisecting.\"));\n> +               status_printf_ln(s, c, _(\"To get back to the original branch run \\\"git bisect reset\\\"\"));\n> +               wt_status_print_trailer(s);\n> +       }\n> +\n> +       if(unmerged_state) {\n> +               if (conflict)\n> +                       status_printf_ln(s, c, _(\"You have unmerged paths: fix conflicts and then commit the result.\"));\n> +               else\n> +                       status_printf_ln(s, c, _(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n> +               wt_status_print_trailer(s);\n> +       }\n\nNice. Although git-status is sometimes too heavy I avoid it. But I\nlike this. I don't know, it might help if this info could be printed\nalone, maybe with an option, without the actual status stuff (changed,\ncached, others...).\n\n> +       if(rebase_state || rebase_interactive_state) {\n> +               if (conflict) {\n> +                       status_printf_ln(s, c, _(\"You are currently rebasing: fix conflicts and then run \\\"git rebase -- continue\\\".\"));\n> +                       status_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n> +                       status_printf_ln(s, c, _(\"To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n> +               }\n> +               else {\n> +                       if (rebase_state)\n> +                               status_printf_ln(s, c, _(\"You are currently rebasing: all conflicts fixed; run \\\"git rebase --continue\\\".\"));\n> +                       else {\n> +                               status_printf_ln(s, c, _(\"You are currently editing in a rebase progress.\"));\n> +                               status_printf_ln(s, c, _(\"You can amend the commit with\"));\n> +                               status_printf_ln(s, c, _(\"      git commit --amend\"));\n> +                               status_printf_ln(s, c, _(\"Once you are satisfied with your changes, run\"));\n> +                               status_printf_ln(s, c, _(\"      git rebase --continue\"));\n> +                       }\n> +               }\n> +               wt_status_print_trailer(s);\n> +       }\n\nShould this verbose advice be controlled by advice.* config keys?\nExperienced users know by heart what to do and will appreciate screen\nestate being used more helpful (to them) info\n-- \nDuy\n"},{"id":"192248","messageId":"4FC1100E.2080909@gmail.com","threadId":"30608","inReplyTo":"CACsJy8Dx=HWKJ8H3LQhVAAJGtZKmMe0d5e3Q7eHER6Xo4yTAZw@mail.gmail.com","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"NGUY Thomas","fromEmail":"thomasxnguy@gmail.com","sentAt":"2012-05-26T17:17:02Z","receivedAt":"2012-05-26T17:17:02Z","isPatch":false,"sender":{"key":"thomasxnguy@gmail.com","avatar":null},"body":"Le 26/05/2012 15:01, Nguyen Thai Ngoc Duy a écrit :\n\n>> +       if(rebase_state || rebase_interactive_state) {\n>> +               if (conflict) {\n>> +                       status_printf_ln(s, c, _(\"You are currently rebasing: fix conflicts and then run \\\"git rebase -- continue\\\".\"));\n>> +                       status_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n>> +                       status_printf_ln(s, c, _(\"To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n>> +               }\n>> +               else {\n>> +                       if (rebase_state)\n>> +                               status_printf_ln(s, c, _(\"You are currently rebasing: all conflicts fixed; run \\\"git rebase --continue\\\".\"));\n>> +                       else {\n>> +                               status_printf_ln(s, c, _(\"You are currently editing in a rebase progress.\"));\n>> +                               status_printf_ln(s, c, _(\"You can amend the commit with\"));\n>> +                               status_printf_ln(s, c, _(\"      git commit --amend\"));\n>> +                               status_printf_ln(s, c, _(\"Once you are satisfied with your changes, run\"));\n>> +                               status_printf_ln(s, c, _(\"      git rebase --continue\"));\n>> +                       }\n>> +               }\n>> +               wt_status_print_trailer(s);\n>> +       }\n> Should this verbose advice be controlled by advice.* config keys?\n> Experienced users know by heart what to do and will appreciate screen\n> estate being used more helpful (to them) info\nIndeed, the advices are a bit long and could be restricted to the \ninformation about the\ncurrent state but the idea is also to give the user a way to know what \nto do next.\nFor long messages, such as the rebase case, we could actually use the \nadvice_status_hints\nvariable to display what to do next or not.\n\nKong Lucien <Lucien.Kong@ensimag.imag.fr>\nNguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nDuperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nJonas Franck <Franck.Jonas@ensimag.imag.fr>\nNguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n"},{"id":"192268","messageId":"vpqlikdlr1z.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338035905-24166-2-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv2 2/2] t7512-status-warnings.sh: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-27T12:57:44Z","receivedAt":"2012-05-27T12:57:44Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n>  t/t7060-wtstatus.sh        |    2 +\n>  t/t7512-status-warnings.sh |  280 ++++++++++++++++++++++++++++++++++++++++++++\n>  2 files changed, 282 insertions(+), 0 deletions(-)\n\n> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\n> index b8cb490..d9a1e18 100755\n> --- a/t/t7060-wtstatus.sh\n> +++ b/t/t7060-wtstatus.sh\n> @@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n>  \n>  cat >expect <<EOF\n>  # On branch side\n> +# You have unmerged paths: fix conflicts and then commit the result.\n> +#\n>  # Unmerged paths:\n>  #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n>  #\n\nDoesn't the test fail after this if you don't modify the code at the\nsame time? Git's codebase should pass all tests at each commit (if only\nto allow \"git bisect\" to run smoothly), so don't modify tests and code\nin different commits. What you can do on the other hand is to introduce\nnew failing tests (test_expect_failure), and then mark them as success\nwhen you update the code. Or introduce tests that show the current\nbehavior, and then patch the expected output when you update the code \n(the above patch hunk is a nice way to demonstrate the change introduced\nby the code for example).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192269","messageId":"vpqfwallr03.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"CACsJy8Dx=HWKJ8H3LQhVAAJGtZKmMe0d5e3Q7eHER6Xo4yTAZw@mail.gmail.com","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-27T12:58:52Z","receivedAt":"2012-05-27T12:58:52Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> Nice. Although git-status is sometimes too heavy I avoid it. But I\n> like this. I don't know, it might help if this info could be printed\n> alone, maybe with an option, without the actual status stuff (changed,\n> cached, others...).\n\nOnce this is implemented as a \"git status\" addition, we may want to add\na \"git status --very-short\" (or find a better naming) to show only the\nheader of the status.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192270","messageId":"vpq8vgdlqg8.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338035905-24166-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-27T13:10:47Z","receivedAt":"2012-05-27T13:10:47Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +\tconst char *git_dir = getenv(GIT_DIR_ENVIRONMENT);\n\nget_git_dir() would do the same more cleanly I think. And you don't\nactually need it because git_path(\"...\") does what you're doing with\nmkpath already.\n\n> +\t\tit = &(s->change.items[i]);\n> +\t\td = it->util;\n\nIsn't it a complex way to say\n\n                d = s->change.items[i].util\n\n?\n\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently editing in a rebase progress.\"));\n\nI find the wording strange.\n\n\"You are currently editing a commit during a rebase\"\n\n?\n\n> +\twt_status_print_in_progress(s);\n> +\n\nI think this deserves several functions (e.g. one for rebase in\nprogress, one for bisect, ...). The one you have is already rather long,\nand may get longer when you start using the advice mechanism.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192303","messageId":"7v1um47vik.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338035905-24166-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-28T04:57:23Z","receivedAt":"2012-05-28T04:57:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\nKong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> This patch provides more information about your current state after a git status command (in the cases of conflicts, before and after they are resolved, a rebase or a bisect process).\n> This would help users to know what they are currently doing, in a more accurate way.\n\nPlease fix these overlong lines.\n\nThe description is unclear what problem it tries to solve and how,\nand invites many questions.  Does it add more lines at the top?  At\nthe bottom?  How verbosely?  By pushing down existing information by\nadding extra lines somewhere, the existing output lines may be made\nharder to read, but how badly?  How does this affect \"status\n-s/status --porcelain\" output?  What does the new code do to figure\nout the \"current state\"?  By heuristics?  How often does the\nheuristics get it wrong and in what circumstances?\n\n\n> diff --git a/wt-status.c b/wt-status.c\n> index dd6d8c4..9839280 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -15,6 +15,7 @@\n>  \n>  static char default_wt_status_colors[][COLOR_MAXLEN] = {\n>  \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n> +\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n>  \tGIT_COLOR_GREEN,  /* WT_STATUS_UPDATED */\n>  \tGIT_COLOR_RED,    /* WT_STATUS_CHANGED */\n>  \tGIT_COLOR_RED,    /* WT_STATUS_UNTRACKED */\n\nWhy add new stuff in the middle, not at the end?\n\n> @@ -728,6 +729,92 @@ static void wt_status_print_tracking(struct wt_status *s)\n>  \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n>  }\n>  \n> +static void wt_status_print_in_progress(struct wt_status *s)\n> +{\n> +\tint i;\n> +\tconst char *c = color(WT_STATUS_IN_PROGRESS, s);\n> +\tconst char *git_dir = getenv(GIT_DIR_ENVIRONMENT);\n> +\tconst char* path;\n\n> +\tint unmerged_state = 0;\n> +\tint rebase_state = 0;\n> +\tint rebase_interactive_state = 0;\n> +\tint am_state = 0;\n> +\tint bisect_state = 0;\n\nThese are not independent (you cannot be in bisect and am at the\nsame time).  Why five independent variables?\n\n> +\tint conflict = 0;\n\nHow is this different from \"unmerged\"?\n\n> +\tfor (i = 0; i < s->change.nr; i++) {\n> +\t\tstruct wt_status_change_data *d;\n> +\t\tstruct string_list_item *it;\n> +\t\tit = &(s->change.items[i]);\n> +\t\td = it->util;\n> +\t\tif (d->stagemask) {\n> +\t\t\tconflict = 1;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t}\n\nThat \"continue\" looks like a no-op.  Mental note: conflict seems to\nremember if there was any path that was unmerged.\n\n> +\tpath = mkpath(\"%s/MERGE_HEAD\", git_dir);\n> +\tif (!access(path, R_OK))\n> +\t\tunmerged_state = 1;\n\nAhh, so \"unmerged\" is \"conflicted during merge\" (as opposed to\nrebase_state is \"conflicted during rebase\")?  Doesn't the naming\nsound odd?  If it were \"merge_state\", it might have made a bit more\nsense (but again, these are not independent conditions, so multiple\nvariables do not make sense).\n\n> +\tpath = mkpath(\"%s/rebase-apply\", git_dir);\n> +\tif (!access(path, R_OK)) {\n> +\t\tpath = mkpath(\"%s/rebase-apply/applying\", git_dir);\n> +\t\tif (!access(path, R_OK))\n> +\t\t\tam_state = 1;\n> +\t\telse\n> +\t\t\trebase_state = 1;\n> +\t}\n> +\telse {\n> +\t\tpath = mkpath(\"%s/rebase-merge\", git_dir);\n> +\t\tif (!access(path, R_OK)) {\n> +\t\t\tpath = mkpath(\"%s/rebase-merge/interactive\", git_dir);\n> +\t\t\tif (!access(path, R_OK))\n> +\t\t\t\trebase_interactive_state = 1;\n> +\t\t\telse\n> +\t\t\t\trebase_state = 1;\n> +\t\t}\n> +\t}\n\nThe above if/else makes it clear that if you are in \"am\" you can\nnever be in \"rebase -i\", but doesn't it strike you odd that the\ncheck for MERGE_HEAD is not cascaded the same way?  I.e. if you know\nyou are in \"merge\", you cannot be \"am\" nor \"rebase\", but you check\nthe latter anyway even after you know you are in \"merge\".\n\n> +\tpath = mkpath(\"%s/BISECT_LOG\", git_dir);\n> +\tif (!access(path, R_OK))\n> +\t\tbisect_state = 1;\n\nLikewise.\n\n> +\tif(bisect_state) {\n\ns/if/if /;\n\n> +\t\tstatus_printf_ln(s, c, _(\"You are currently bisecting.\"));\n> +\t\tstatus_printf_ln(s, c, _(\"To get back to the original branch run \\\"git bisect reset\\\"\"));\n> +\t\twt_status_print_trailer(s);\n> +\t}\n> +\n> +\tif(unmerged_state) {\n\nLikewise.\n\n> +\t\tif (conflict)\n> +\t\t\tstatus_printf_ln(s, c, _(\"You have unmerged paths: fix conflicts and then commit the result.\"));\n> +\t\telse\n> +\t\t\tstatus_printf_ln(s, c, _(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n> +\t\twt_status_print_trailer(s);\n> +\t}\n\nIt is annoying that the above does things in random order, i.e.\n\n\tif (are we in X)\n        \tset state to X\n\tif (are we in Y)\n        \tset state to Y\n\telse if (are we in Z)\n\t\tset state to Z\n\tif (are we in W)\n\t\tset state to W\n\n\tif (Z)\n        \tsay things about Z\n\tif (X)\n\t\tsay things about X\n\tif (Y)\n\t\tsay things about Y\n\n\nSuch a code structure invites bugs and missed cases (e.g. you do not\nseem to say anything after you detect that you are in \"am\").\n\n\n> +\tif(rebase_state || rebase_interactive_state) {\n> +\t\tif (conflict) {\n> +\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: fix conflicts and then run \\\"git rebase -- continue\\\".\"));\n> +\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n> +\t\t\tstatus_printf_ln(s, c, _(\"To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n> +\t\t}\n> +\t\telse {\n\n\tif (...) {\n\t\t...\n\t} else {\n\t\t...\n\t}\n\n> +\t\t\tif (rebase_state)\n\nWhy extra level of nesting?\n\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: all conflicts fixed; run \\\"git rebase --continue\\\".\"));\n> +\t\t\telse {\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently editing in a rebase progress.\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"You can amend the commit with\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit commit --amend\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"Once you are satisfied with your changes, run\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit rebase --continue\"));\n> +\t\t\t}\n\nI am not sure if this level of verbosity is a good thing, given that\nyou are adding this near the very beginning of the output.  When you\nhave many conflicted or modified paths, these advice messages will\nscroll off the top.\n\nOh, another thing.  Perhaps these (both detection logic and output)\nshould be protected with a new advise.* configuration variable, no?\n"},{"id":"192311","messageId":"vpqwr3whjkp.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"7v1um47vik.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-28T07:05:10Z","receivedAt":"2012-05-28T07:05:10Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> These are not independent (you cannot be in bisect and am at the\n> same time).\n\nYou should not, but it seems you can. At least, I just successfully\nstarted a \"git am\" during a \"git bisect\".\n\nEven if some checks may be added to actually prevent the situation, it\nseems better to keep \"git status\" robust to this kind of situation. If\nthe user did something really wrong, nice advices in \"git status\" will\nbe particularly helpful.\n\n>> +\tint conflict = 0;\n>\n> How is this different from \"unmerged\"?\n[...]\n>> +\tpath = mkpath(\"%s/MERGE_HEAD\", git_dir);\n>> +\tif (!access(path, R_OK))\n>> +\t\tunmerged_state = 1;\n>\n> Ahh, so \"unmerged\" is \"conflicted during merge\" (as opposed to\n> rebase_state is \"conflicted during rebase\")?  Doesn't the naming\n> sound odd?  If it were \"merge_state\", it might have made a bit more\n> sense (but again, these are not independent conditions, so multiple\n> variables do not make sense).\n\nThe variable naming is wrong (it could be s/conflicts/unmerged_present/\nand s/unmerged_state/merge_in_progress/ for example). But these two\nvariables are indeed independant. You can have unmerged path without an\nactual merge in progress (conflicts during \"git am\"), an you can have a\nmerge in progress without conflicts (if you've just \"git add\"-ed them).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192315","messageId":"vpqaa0shf0s.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338035905-24166-2-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv2 2/2] t7512-status-warnings.sh: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-28T08:43:31Z","receivedAt":"2012-05-28T08:43:31Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +test_expect_success 'status when conflicts unresolved' '\n> +\tgit init --shared --bare conflict_test.git &&\n> +\tgit clone conflict_test.git test1 &&\n> +\tgit clone conflict_test.git test2 &&\n\nI already asked off-list, but why do you need 3 repositories here.\nWouldn't it be simpler to have 2 branches and test conflicts with\n\"git merge\"?\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192378","messageId":"20120528125432.Horde.KyJxSnwdC4BPw1lo0-ZkrQA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7v1um47vik.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-05-28T10:54:32Z","receivedAt":"2012-05-28T10:54:32Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n>> +\tint unmerged_state = 0;\n>> +\tint rebase_state = 0;\n>> +\tint rebase_interactive_state = 0;\n>> +\tint am_state = 0;\n>> +\tint bisect_state = 0;\n>\n> These are not independent (you cannot be in bisect and am at the\n> same time).  Why five independent variables?\n\nSome of these variables are independant. We can be in rebase and\nbisect at the same time and, as Matthieu said, we can do an am during\na bisect. However, there are dependant cases such as you cannot do a\nrebase during an am.\n\n\n>> +\tfor (i = 0; i < s->change.nr; i++) {\n>> +\t\tstruct wt_status_change_data *d;\n>> +\t\tstruct string_list_item *it;\n>> +\t\tit = &(s->change.items[i]);\n>> +\t\td = it->util;\n>> +\t\tif (d->stagemask) {\n>> +\t\t\tconflict = 1;\n>> +\t\t\tcontinue;\n>> +\t\t}\n>> +\t}\n>\n> That \"continue\" looks like a no-op.  Mental note: conflict seems to\n> remember if there was any path that was unmerged.\n\nYou're right. It should be a \"break\" instead of \"continue\".\n\n\n> Such a code structure invites bugs and missed cases (e.g. you do not\n> seem to say anything after you detect that you are in \"am\").\n\nIn fact, the case of 'am' is not implemented in this patch. It's supposed\nto be added in the next patch.\n\n>\n>> +\tif(rebase_state || rebase_interactive_state) {\n>> +\t\tif (conflict) {\n>> +\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: fix  \n>> conflicts and then run \\\"git rebase -- continue\\\".\"));\n>> +\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this  \n>> patch, instead run \\\"git rebase --skip\\\".\"));\n>> +\t\t\tstatus_printf_ln(s, c, _(\"To check out  the original branch and  \n>> stop rebasing run \\\"git rebase --abort\\\".\"));\n>> +\t\t}\n>> +\t\telse {\n>\n> \tif (...) {\n> \t\t...\n> \t} else {\n> \t\t...\n> \t}\n>\n>> +\t\t\tif (rebase_state)\n>\n> Why extra level of nesting?\n\nThe 'conflict' variable stands for the case when we're in a conflict  \nbefore resolving\nit (with 'git add'), as we distinguish the warning messages for when  \nwe're before\nresolving a conflict and after resolving it. So, the case with  \n\"conflict\" can happen in\nboth cases rebase_state and rebase_interactive_state but the warning  \nmessages are still specifical\nfor the rebase cases. However, There are still specifical messages for  \nwhen you are\nin rebase_state or in rebase_interactive_state.\n\n>\n> Oh, another thing.  Perhaps these (both detection logic and output)\n> should be protected with a new advise.* configuration variable, no?\n\nYes, We think that it would be wise to add a new advice.* config variable\nto control the display of the new warning messages.\n"},{"id":"192388","messageId":"1338226598-16056-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338035905-24166-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv3 1/2] wt-status.*: better advices for git status added","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-28T17:36:37Z","receivedAt":"2012-05-28T17:36:37Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new warning messages in the display of\n'git status' (at the top) during conflicts, rebase, am\nand bisect process. These messages can be shortened by setting\nthe new advice.* config key called advice.statushelp to false.\n\nThus, information about the new advice.* key are added in\nDocumentation/config.txt\n\nAlso, the test t7060-wt-status.sh is now working with the\nnew warning messages.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\nThe new messages are not shown when using options such as\n-s or --porcelain.It figures the current state by finding \nthe files generated in .git in each case (during an am, \na rebase, a bisect etc.). The messages about the current\nsituation of the user are always displayed but the advices \non what the user needs to do in order to resume a rebase/bisect\n/am/ commit after resolving conflicts can be hidden by setting advice.statushelp to 'false' in the config file.\n\n Documentation/config.txt |    4 ++\n advice.c                 |    2 +\n advice.h                 |    1 +\n t/t7060-wtstatus.sh      |    2 +\n wt-status.c              |  106 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |    1 +\n 6 files changed, 116 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..6504371 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -176,6 +176,10 @@ advice.*::\n \t\tAdvice shown when you used linkgit:git-checkout[1] to\n \t\tmove to the detach HEAD state, to instruct how to create\n \t\ta local branch after the fact.\n+\tstatusHelp::\n+\t\tDirections on how to end the current process shown\n+\t\tin the output of linkgit:git-status[1].\n+\n --\n \n core.fileMode::\ndiff --git a/advice.c b/advice.c\nindex a492eea..31deb31 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -9,6 +9,7 @@ int advice_commit_before_merge = 1;\n int advice_resolve_conflict = 1;\n int advice_implicit_identity = 1;\n int advice_detached_head = 1;\n+int advice_status_help = 1;\n \n static struct {\n \tconst char *name;\n@@ -23,6 +24,7 @@ static struct {\n \t{ \"resolveconflict\", &advice_resolve_conflict },\n \t{ \"implicitidentity\", &advice_implicit_identity },\n \t{ \"detachedhead\", &advice_detached_head },\n+\t{ \"statushelp\", &advice_status_help },\n };\n \n void advise(const char *advice, ...)\ndiff --git a/advice.h b/advice.h\nindex f3cdbbf..5fd3cce 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -12,6 +12,7 @@ extern int advice_commit_before_merge;\n extern int advice_resolve_conflict;\n extern int advice_implicit_identity;\n extern int advice_detached_head;\n+extern int advice_status_help;\n \n int git_default_advice_config(const char *var, const char *value);\n void advise(const char *advice, ...);\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..d9a1e18 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths: fix conflicts and then commit the result.\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..093a352 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,109 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static void wt_status_print_in_progress(struct wt_status *s)\n+{\n+\tint i;\n+\tconst char *c = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct stat st;\n+\tint merge_in_progress = 0;\n+\tint rebase_state = 0;\n+\tint rebase_interactive_state = 0;\n+\tint am_state = 0;\n+\tint am_wrong_format_state = 0;\n+\tint bisect_state = 0;\n+\tint unmerged_present = 0;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask) {\n+\t\t\tunmerged_present = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st))\n+\t\tmerge_in_progress = 1;\n+\telse {\n+\t\tif (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st))\n+\t\t\t\tam_state = 1;\n+\t\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !(st.st_size))\n+\t\t\t\t\tam_wrong_format_state = 1;\n+\t\t\telse\n+\t\t\t\trebase_state = 1;\n+\t\t}\n+\t\telse {\n+\t\t\tif (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\t\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\t\t\trebase_interactive_state = 1;\n+\t\t\t\telse\n+\t\t\t\t\trebase_state = 1;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tbisect_state = 1;\n+\n+\tif(merge_in_progress) {\n+\t\tif (unmerged_present)\n+\t\t\tstatus_printf_ln(s, c, _(\"You have unmerged paths: fix conflicts and then commit the result.\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n+\t\twt_status_print_trailer(s);\n+\t}\n+\telse {\n+\t\tif(am_state) {\n+\t\t\tstatus_printf_ln(s, c, _(\"You are currently in am progress:\"));\n+\t\t\tif(am_wrong_format_state)\n+\t\t\t\tstatus_printf_ln(s, c, _(\"One of the patches is empty or corrupted !\"));\n+\t\t\tif (advice_status_help) {\n+\t\t\t\tstatus_printf_ln(s, c, _(\"When you have resolved this problem run \\\"git am --resolved\\\".\"));\n+\t\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n+\t\t\t\tstatus_printf_ln(s, c, _(\"To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n+\t\t\t}\n+\t\t\twt_status_print_trailer(s);\n+\t\t}\n+\n+\t\telse if (rebase_state || rebase_interactive_state) {\n+\t\t\tif (unmerged_present) {\n+\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing%s\"),\n+\t\t\t\tadvice_status_help\n+\t\t\t\t? _(\": fix conflicts and then run \\\"git rebase -- continue\\\".\") : \".\");\n+\t\t\t\tif (advice_status_help) {\n+\t\t\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n+\t\t\t\t\tstatus_printf_ln(s, c, _(\"To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\tif (rebase_state)\n+\t\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: all conflicts fixed%s\"),\n+\t\t\t\t\tadvice_status_help\n+\t\t\t\t\t? _(\": run \\\"git rebase --continue\\\".\") : \".\");\n+\t\t\t\telse {\n+\t\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently editing a commit during a rebase.\"));\n+\t\t\t\t\tif (advice_status_help) {\n+\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"You can amend the commit with\"));\n+\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit commit --amend\"));\n+\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"Once you are satisfied with your changes, run\"));\n+\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit rebase --continue\"));\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\twt_status_print_trailer(s);\n+\t\t}\n+\t}\n+\n+\tif(bisect_state) {\n+\t\tstatus_printf_ln(s, c, _(\"You are currently bisecting.\"));\n+\t\tif (advice_status_help)\n+\t\tstatus_printf_ln(s, c, _(\"To get back to the original branch run \\\"git bisect reset\\\"\"));\n+\t\twt_status_print_trailer(s);\n+\t}\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +854,8 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_in_progress(s);\n+\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..0556669 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n-- \n1.7.8\n"},{"id":"192387","messageId":"1338226598-16056-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338226598-16056-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv3 2/2] t7512-status-warnings.sh: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-28T17:36:38Z","receivedAt":"2012-05-28T17:36:38Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user\nneeds to run 'git status' to know his current situation,\nwhether there're conflicts or he's in rebase/bisect/am progress.\n\nThe last test is about the set of the advice.statushelp config key\non false in .git/config.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\n t/t7512-status-warnings.sh |  303 ++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 303 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-warnings.sh\n\ndiff --git a/t/t7512-status-warnings.sh b/t/t7512-status-warnings.sh\nnew file mode 100755\nindex 0000000..7824626\n--- /dev/null\n+++ b/t/t7512-status-warnings.sh\n@@ -0,0 +1,303 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second_branch main.txt on_second_branch &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths: fix conflicts and then commit the result.\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You are still merging, run \"git commit\" to conclude merge.\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\tgit commit -m \"one\" &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: fix conflicts and then run \"git rebase -- continue\".\n+\t# If you would prefer to skip this patch, instead run \"git rebase --skip\".\n+\t# To check out  the original branch and stop rebasing run \"git rebase --abort\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: all conflicts fixed: run \"git rebase --continue\".\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git fake-editor.sh\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t# You can amend the commit with\n+\t#\tgit commit --amend\n+\t# Once you are satisfied with your changes, run\n+\t#\tgit rebase --continue\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output &&\n+\tgit rebase --abort\n+'\n+\n+\n+\n+test_expect_success 'status in am progress: file already exists' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one  \" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress:\n+\t# When you have resolved this problem run \"git am --resolved\".\n+\t# If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t# To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status in am progress: file does not exist' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one\" &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"delete main.txt\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress:\n+\t# When you have resolved this problem run \"git am --resolved\".\n+\t# If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t# To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status in am progress : patch corrupted/wrong format' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one one.txt \"one\" &&\n+\ttest_commit two two.txt \"two\" &&\n+\ttest_commit three three.txt \"three\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all\" &&\n+\techo error >Maildir/0002-two.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress:\n+\t# One of the patches is empty or corrupted !\n+\t# When you have resolved this problem run \"git am --resolved\".\n+\t# If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t# To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t# To get back to the original branch run \"git bisect reset\"\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'status when rebase conflicts with statushelp disabled' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\tgit config --local advice.statushelp false &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192397","messageId":"vpqobp89hrw.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338226598-16056-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv3 1/2] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-28T20:23:31Z","receivedAt":"2012-05-28T20:23:31Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> These messages can be shortened by setting\n> the new advice.* config key called advice.statushelp to false.\n\nIt may make sense to use the existing advice.statusHint here.\n\n> +\telse {\n> +\t\tif (!stat(git_path(\"rebase-apply\"), &st)) {\n\n\"else { if\" is usually spelt \"else if\", without an additional level of\nindentation.\n\n> +\t\t\tstatus_printf_ln(s, c, _(\"You have unmerged paths: fix conflicts and then commit the result.\"));\n\nI'd even say\n\nYou have unmerged paths; fix conflicts and run \"git commit\"\n\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"One of the patches is empty or corrupted !\"));\n\nNo space before !\n\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"When you have resolved this problem run \\\"git am --resolved\\\".\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n\nYou have overly long lines. I already suggested splitting the function\ninto smaller functions, and the presence of long lines is usually an\nindication that the splitting should be done.\n\nDocumentation/CodingGuidelines says:\n\n,----\n| For C programs:\n| \n|  - We use tabs to indent, and interpret tabs as taking up to\n|    8 spaces.\n| \n|  - We try to keep to at most 80 characters per line.\n`----\n\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing%s\"),\n> +\t\t\t\tadvice_status_help\n> +\t\t\t\t? _(\": fix conflicts and then run \\\"git rebase -- continue\\\".\") : \".\");\n\nWeird indentation, it feels like 3 different statements.\n\n> +\tif(bisect_state) {\n\nSpace between if and (.\n\n> +\t\tif (advice_status_help)\n> +\t\tstatus_printf_ln(s, c, _(\"To get back to the original branch run \\\"git bisect reset\\\"\"));\n\nBroken indentation.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192398","messageId":"vpqzk8s82mc.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338226598-16056-2-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv3 2/2] t7512-status-warnings.sh: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-28T20:36:11Z","receivedAt":"2012-05-28T20:36:11Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +\t# You are currently rebasing: fix conflicts and then run \"git rebase -- continue\".\n> +\t# If you would prefer to skip this patch, instead run \"git rebase --skip\".\n> +\t# To check out  the original branch and stop rebasing run \"git rebase --abort\".\n\nYou can use a small indentation to mark the fact that the next lines are\nrelated to the first, like done in the other messages of status:\n\n> +\t# Unmerged paths:\n> +\t#   (use \"git reset HEAD <file>...\" to unstage)\n> +\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n\nI'd have written it like this:\n\n+\t# You are currently rebasing: fix conflicts and then run \"git rebase -- continue\".\n+\t#   If you would prefer to skip this patch, instead run \"git rebase --skip\".\n+\t#   To check out  the original branch and stop rebasing run \"git rebase --abort\".\n\nSame for other messages.\n\n> +\t# You are currently rebasing: fix conflicts and then run \"git rebase -- continue\".\n\nExtra space between -- and continue.\n\nYou could refine the advice depending on whether conflicts are (still)\npresent or not (like you did for merge).\n\n> +test_expect_success 'status in am progress : patch corrupted/wrong format' '\n\nNo space before :.\n\n> +\t# One of the patches is empty or corrupted !\n\nNo space before ! (I think I mentionned it for the C code, not sure).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192430","messageId":"7v4nqy4wrz.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338226598-16056-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv3 1/2] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-29T19:22:56Z","receivedAt":"2012-05-29T19:22:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> This patch provides new warning messages in the display of\n> 'git status' (at the top) during conflicts, rebase, am\n> and bisect process. These messages can be shortened by setting\n> the new advice.* config key called advice.statushelp to false.\n>\n> Thus, information about the new advice.* key are added in\n> Documentation/config.txt\n>\n> Also, the test t7060-wt-status.sh is now working with the\n> new warning messages.\n>\n> Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n> Signed-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\n> Signed-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\n> Signed-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\n> Signed-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n> ---\n> The new messages are not shown when using options such as\n> -s or --porcelain.It figures the current state by finding \n> the files generated in .git in each case (during an am, \n> a rebase, a bisect etc.). The messages about the current\n> situation of the user are always displayed but the advices \n> on what the user needs to do in order to resume a rebase/bisect\n> /am/ commit after resolving conflicts can be hidden by setting advice.statushelp to 'false' in the config file.\n\nDon't some of the above explanatory sentences deserve to be in the\ncommit log message proper, not hidden behind the three-dash lines?\n\n\n>  Documentation/config.txt |    4 ++\n>  advice.c                 |    2 +\n>  advice.h                 |    1 +\n>  t/t7060-wtstatus.sh      |    2 +\n>  wt-status.c              |  106 ++++++++++++++++++++++++++++++++++++++++++++++\n>  wt-status.h              |    1 +\n>  6 files changed, 116 insertions(+), 0 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 915cb5a..6504371 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -176,6 +176,10 @@ advice.*::\n>  \t\tAdvice shown when you used linkgit:git-checkout[1] to\n>  \t\tmove to the detach HEAD state, to instruct how to create\n>  \t\ta local branch after the fact.\n> +\tstatusHelp::\n> +\t\tDirections on how to end the current process shown\n> +\t\tin the output of linkgit:git-status[1].\n> +\n>  --\n\nHave you read the existing entries in the same section you are\ntouching to see if the patch result as a whole makes sense and the\nnew entry fits well in the context?\n\nIt strikes me odd that this is not listed next to statusHints, and\nit also makes me wonder if we even need to invent a new one, or it\nis better to just make the output more verbose when statusHints is\nnot being declined.\n\n> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\n> index b8cb490..d9a1e18 100755\n> --- a/t/t7060-wtstatus.sh\n> +++ b/t/t7060-wtstatus.sh\n> @@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n>  \n>  cat >expect <<EOF\n>  # On branch side\n> +# You have unmerged paths: fix conflicts and then commit the result.\n> +#\n>  # Unmerged paths:\n>  #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n>  #\n> diff --git a/wt-status.c b/wt-status.c\n> index dd6d8c4..093a352 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n>  \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n>  \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n>  \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n> +\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n>  };\n>  \n>  static const char *color(int slot, struct wt_status *s)\n> @@ -728,6 +729,109 @@ static void wt_status_print_tracking(struct wt_status *s)\n>  \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n>  }\n>  \n> +static void wt_status_print_in_progress(struct wt_status *s)\n> +{\n> +\tint i;\n> +\tconst char *c = color(WT_STATUS_IN_PROGRESS, s);\n> +\tstruct stat st;\n\n> +\tint merge_in_progress = 0;\n> +\tint rebase_state = 0;\n> +\tint rebase_interactive_state = 0;\n> +\tint am_state = 0;\n> +\tint am_wrong_format_state = 0;\n> +\tint bisect_state = 0;\n\nmerge_in_progress is very descriptive, but compared to that, none of\nthe foo_state is.\n\n> +\tint unmerged_present = 0;\n\n\n\n> +\n> +\tfor (i = 0; i < s->change.nr; i++) {\n> +\t\tstruct wt_status_change_data *d;\n> +\t\td = s->change.items[i].util;\n> +\t\tif (d->stagemask) {\n> +\t\t\tunmerged_present = 1;\n> +\t\t\tbreak;\n> +\t\t}\n> +\t}\n> +\n> +\tif (!stat(git_path(\"MERGE_HEAD\"), &st))\n> +\t\tmerge_in_progress = 1;\n> +\telse {\n> +\t\tif (!stat(git_path(\"rebase-apply\"), &st)) {\n> +\t\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st))\n> +\t\t\t\tam_state = 1;\n> +\t\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !(st.st_size))\n> +\t\t\t\t\tam_wrong_format_state = 1;\n\nIsn't nesting screwed-up around here?  Your indentation suggests you\nneed opening \"{\" after \"if (applying)\" and closing \"}\" before \"else\"\non the next line.\n\n> +\t\t\telse\n> +\t\t\t\trebase_state = 1;\n> +\t\t}\n> +\t\telse {\n> +\t\t\tif (!stat(git_path(\"rebase-merge\"), &st)) {\n> +\t\t\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n> +\t\t\t\t\trebase_interactive_state = 1;\n> +\t\t\t\telse\n> +\t\t\t\t\trebase_state = 1;\n> +\t\t\t}\n> +\t\t}\n> +\t}\n\nWhenever you write \"else {\" that is immediately followed by \"if\",\nre-read what you wrote and think if you can make it \"else if () {\"\nto reduce the indentation level.  If you still need five levels of\nindentation, the function you are writing is too complex and is a\nsign that you can use a helper function.\n\nIn this case, I think you could structure it like this:\n\n\tif (merge_head) {\n        \tmerge_in_progress++;\n\t} else if (rebase-apply) {\n\t\tif (applying) {\n\t\t\tam_in_progress++;\n                        if (patch is empty)\n                                ...\n\t\t} else {\t\t\t\n\t\t\trebase_in_progress++;\n\t\t}\n\t} else if (rebase-merge) {\n\t\tif (interactive)\n\t\t\trebase_i_in_progress++;\n\t\telse\n\t\t\trebase_in_progress++;\n\t}\n\n\n> +\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n> +\t\tbisect_state = 1;\n> +\n> +\tif(merge_in_progress) {\n\ns/if/if /;  Didn't I say this already in my previous message?\n\n> +\t\tif (unmerged_present)\n> +\t\t\tstatus_printf_ln(s, c, _(\"You have unmerged paths: fix conflicts and then commit the result.\"));\n> +\t\telse\n> +\t\t\tstatus_printf_ln(s, c, _(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n> +\t\twt_status_print_trailer(s);\n> +\t}\n> +\telse {\n> +\t\tif(am_state) {\n\nThe same comments on the \"else if\" cascading and on the missing SP\nafter keyword apply here.\n\n> +\t\t\tstatus_printf_ln(s, c, _(\"You are currently in am progress:\"));\n\n-ECANTPARSE.\n\n> +\t\t\tif(am_wrong_format_state)\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"One of the patches is empty or corrupted !\"));\n\nYou never checked corrupted; you only detected an empty file.\n\n> +\t\t\tif (advice_status_help) {\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"When you have resolved this problem run \\\"git am --resolved\\\".\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n> +\t\t\t}\n> +\t\t\twt_status_print_trailer(s);\n> +\t\t}\n> +\n> +\t\telse if (rebase_state || rebase_interactive_state) {\n> +\t\t\tif (unmerged_present) {\n> +\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing%s\"),\n> +\t\t\t\tadvice_status_help\n> +\t\t\t\t? _(\": fix conflicts and then run \\\"git rebase -- continue\\\".\") : \".\");\n\ns/-- /--/;\n\n> +\t\t\t\tif (advice_status_help) {\n> +\t\t\t\t\tstatus_printf_ln(s, c, _(\"If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n> +\t\t\t\t\tstatus_printf_ln(s, c, _(\"To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n> +\t\t\t\t}\n> +\t\t\t}\n> +\t\t\telse {\n> +\t\t\t\tif (rebase_state)\n> +\t\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently rebasing: all conflicts fixed%s\"),\n> +\t\t\t\t\tadvice_status_help\n> +\t\t\t\t\t? _(\": run \\\"git rebase --continue\\\".\") : \".\");\n> +\t\t\t\telse {\n> +\t\t\t\t\tstatus_printf_ln(s, c, _(\"You are currently editing a commit during a rebase.\"));\n> +\t\t\t\t\tif (advice_status_help) {\n> +\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"You can amend the commit with\"));\n> +\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit commit --amend\"));\n> +\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"Once you are satisfied with your changes, run\"));\n> +\t\t\t\t\t\tstatus_printf_ln(s, c, _(\"\tgit rebase --continue\"));\n> +\t\t\t\t\t}\n> +\t\t\t\t}\n> +\t\t\t}\n> +\t\t\twt_status_print_trailer(s);\n> +\t\t}\n> +\t}\n> +\n> +\tif(bisect_state) {\n> +\t\tstatus_printf_ln(s, c, _(\"You are currently bisecting.\"));\n> +\t\tif (advice_status_help)\n> +\t\tstatus_printf_ln(s, c, _(\"To get back to the original branch run \\\"git bisect reset\\\"\"));\n> +\t\twt_status_print_trailer(s);\n> +\t}\n> +}\n> +\n>  void wt_status_print(struct wt_status *s)\n>  {\n>  \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n> @@ -750,6 +854,8 @@ void wt_status_print(struct wt_status *s)\n>  \t\t\twt_status_print_tracking(s);\n>  \t}\n>  \n> +\twt_status_print_in_progress(s);\n> +\n>  \tif (s->is_initial) {\n>  \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n>  \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\n> diff --git a/wt-status.h b/wt-status.h\n> index 14aa9f7..0556669 100644\n> --- a/wt-status.h\n> +++ b/wt-status.h\n> @@ -15,6 +15,7 @@ enum color_wt_status {\n>  \tWT_STATUS_LOCAL_BRANCH,\n>  \tWT_STATUS_REMOTE_BRANCH,\n>  \tWT_STATUS_ONBRANCH,\n> +\tWT_STATUS_IN_PROGRESS,\n>  \tWT_STATUS_MAXSLOT\n>  };\n"},{"id":"192454","messageId":"7vbol61efv.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"vpqwr3whjkp.fsf@bauges.imag.fr","subject":"Re: [PATCHv2 1/2] wt-status: better advices for git status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-30T04:27:16Z","receivedAt":"2012-05-30T04:27:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> These are not independent (you cannot be in bisect and am at the\n>> same time).\n>\n> You should not, but it seems you can. At least, I just successfully\n> started a \"git am\" during a \"git bisect\".\n\nYeah, that actually is a sensible thing to support (and I am happy\nto hear it still works).\n\n> The variable naming is wrong (it could be s/conflicts/unmerged_present/\n> and s/unmerged_state/merge_in_progress/ for example). But these two\n> variables are indeed independant. You can have unmerged path without an\n> actual merge in progress (conflicts during \"git am\"), an you can have a\n> merge in progress without conflicts (if you've just \"git add\"-ed them).\n"},{"id":"192475","messageId":"20120530130914.Horde.CK7IZHwdC4BPxf-ak9fkbPA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7v4nqy4wrz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv3 1/2] wt-status.*: better advices for git status added","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-05-30T11:09:14Z","receivedAt":"2012-05-30T11:09:14Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n>>  \t\tAdvice shown when you used linkgit:git-checkout[1] to\n>>  \t\tmove to the detach HEAD state, to instruct how to create\n>>  \t\ta local branch after the fact.\n>> +\tstatusHelp::\n>> +\t\tDirections on how to end the current process shown\n>> +\t\tin the output of linkgit:git-status[1].\n>> +\n>>  --\n>\n> Have you read the existing entries in the same section you are\n> touching to see if the patch result as a whole makes sense and the\n> new entry fits well in the context?\n>\n> It strikes me odd that this is not listed next to statusHints, and\n> it also makes me wonder if we even need to invent a new one, or it\n> is better to just make the output more verbose when statusHints is\n> not being declined.\n\nYes, we first thought that we could use statusHints to protect the\nnew messages warnings. But users that disabled statusHints and still\nwished to know what to do during am/rebase/bisect etc. won't be\nable to. On the other hand, if they want to hide the new advices, they\ncan see in the doc the presence of the advice.statusHelp and disable it.\n"},{"id":"192488","messageId":"1338384216-18782-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338226598-16056-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-30T13:23:34Z","receivedAt":"2012-05-30T13:23:34Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new warning messages in the display of\n'git status' (at the top) during conflicts, rebase, am,\nbisect or cherry-pick process.\n\nThe new messages are not shown when using options such as\n-s or --porcelain.The messages about the current\nsituation of the user are always displayed but the advices\non what the user needs to do in order to resume a rebase/bisect\n/am/ commit after resolving conflicts can be hidden by setting\nadvice.statushelp to 'false' in the config file.\n\nThus, information about the new advice.* key are added in\nDocumentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the\nnew warning messages.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\nThe code figures the current state by finding the files generated\nin .git in each cases (during an am, a rebase, a bisect, etc.).\n\nThe function wt_status_print_in_progress is now splitted into\nseveral smaller functions in order to avoid too many indentations.\n\n Documentation/config.txt |    4 +\n advice.c                 |    2 +\n advice.h                 |    1 +\n t/t7060-wtstatus.sh      |    2 +\n wt-status.c              |  161 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 6 files changed, 181 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..ab1c455 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -162,6 +162,9 @@ advice.*::\n \t\tDirections on how to stage/unstage/add shown in the\n \t\toutput of linkgit:git-status[1] and the template shown\n \t\twhen writing commit messages.\n+\tstatusHelp::\n+\t\tDirections on how to end the current process shown\n+\t\tin the output of linkgit:git-status[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\n@@ -176,6 +179,7 @@ advice.*::\n \t\tAdvice shown when you used linkgit:git-checkout[1] to\n \t\tmove to the detach HEAD state, to instruct how to create\n \t\ta local branch after the fact.\n+\n --\n \n core.fileMode::\ndiff --git a/advice.c b/advice.c\nindex a492eea..31deb31 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -9,6 +9,7 @@ int advice_commit_before_merge = 1;\n int advice_resolve_conflict = 1;\n int advice_implicit_identity = 1;\n int advice_detached_head = 1;\n+int advice_status_help = 1;\n \n static struct {\n \tconst char *name;\n@@ -23,6 +24,7 @@ static struct {\n \t{ \"resolveconflict\", &advice_resolve_conflict },\n \t{ \"implicitidentity\", &advice_implicit_identity },\n \t{ \"detachedhead\", &advice_detached_head },\n+\t{ \"statushelp\", &advice_status_help },\n };\n \n void advise(const char *advice, ...)\ndiff --git a/advice.h b/advice.h\nindex f3cdbbf..5fd3cce 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -12,6 +12,7 @@ extern int advice_commit_before_merge;\n extern int advice_resolve_conflict;\n extern int advice_implicit_identity;\n extern int advice_detached_head;\n+extern int advice_status_help;\n \n int git_default_advice_config(const char *var, const char *value);\n void advise(const char *advice, ...);\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..d0fbcc7 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths; fix conflicts and run \"git commit\".\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..4dd294f 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,10 +729,149 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int wt_status_unmerged_present (struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask) {\n+\t\t\treturn 1;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static void wt_status_evaluate_state (struct wt_status_state *state)\n+{\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st))\n+\t\tstate->merge_in_progress = 1;\n+\telse if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !(st.st_size))\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t}\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t}\n+\telse if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t}\n+\telse if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st))\n+\t\tstate->cherry_pick_in_progress = 1;\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+}\n+\n+static void wt_status_merge_in_progress (struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (wt_status_unmerged_present(s))\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"You have unmerged paths; fix conflicts and run \\\"git commit\\\".\"));\n+\telse\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_am_in_progress (struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are currently in am progress:\"));\n+\tif (state->am_empty_patch)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"One of the patches is empty!\"));\n+\tif (advice_status_help) {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  When you have resolved this problem run \\\"git am --resolved\\\".\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_rebase_in_progress (struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (wt_status_unmerged_present(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n+\t\t\tadvice_status_help\n+\t\t\t? _(\": fix conflicts and then run \\\"git rebase --continue\\\".\") : \".\");\n+\t\tif (advice_status_help) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n+\t\t}\n+\t}\n+\telse if (state->rebase_in_progress)\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing: all conflicts fixed%s\"),\n+\t\t\tadvice_status_help\n+\t\t\t? _(\": run \\\"git rebase --continue\\\".\") : \".\");\n+\telse {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_help) {\n+\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n+\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n+\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with your changes, run\"));\n+\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_cherry_pick_in_progress (struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (wt_status_unmerged_present(s))\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"You are currently cherry-picking: fix conflicts and run \\\"git commit\\\".\"));\n+\telse\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"You are currently cherry-picking: all conflicts fixed: run \\\"git commit\\\".\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_bisect_in_progress (struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_help)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  To get back to the original branch run \\\"git bisect reset\\\"\"));\n+\twt_status_print_trailer(s);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n \tconst char *branch_status_color = color(WT_STATUS_HEADER, s);\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n \n \tif (s->branch) {\n \t\tconst char *on_what = _(\"On branch \");\n@@ -750,6 +890,27 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_evaluate_state(state);\n+\n+\tif (state->merge_in_progress) {\n+\t\twt_status_merge_in_progress(s, state, state_color);\n+\t}\n+\telse if (state->am_in_progress) {\n+\t\twt_status_am_in_progress(s, state, state_color);\n+\t}\n+\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress) {\n+\t\twt_status_rebase_in_progress(s, state, state_color);\n+\t}\n+\n+\telse if (state->cherry_pick_in_progress) {\n+\t\twt_status_cherry_pick_in_progress(s, state, state_color);\n+\t}\n+\n+\tif (state->bisect_in_progress) {\n+\t\twt_status_bisect_in_progress(s, state, state_color);\n+\t}\n+\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"192485","messageId":"1338384216-18782-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338384216-18782-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv4 2/3] t7512-status-warnings.sh: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-30T13:23:35Z","receivedAt":"2012-05-30T13:23:35Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user\nneeds to run 'git status' to know his current situation,\nwhether there're conflicts or he's in rebase/bisect/am/\ncherry-pick progress.\n\nOne of the test is about the set of the advice.statushelp config key\non false in .git/config.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\n t/t7512-status-warnings.sh |  352 ++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 352 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-warnings.sh\n\ndiff --git a/t/t7512-status-warnings.sh b/t/t7512-status-warnings.sh\nnew file mode 100755\nindex 0000000..2806fe8\n--- /dev/null\n+++ b/t/t7512-status-warnings.sh\n@@ -0,0 +1,352 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second_branch main.txt on_second_branch &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You are still merging, run \"git commit\" to conclude merge.\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\tgit commit -m \"one\" &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: fix conflicts and then run \"git rebase --continue\".\n+\t#   If you would prefer to skip this patch, instead run \"git rebase --skip\".\n+\t#   To check out  the original branch and stop rebasing run \"git rebase --abort\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: all conflicts fixed: run \"git rebase --continue\".\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git fake-editor.sh\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   You can amend the commit with\n+\t#\tgit commit --amend\n+\t#   Once you are satisfied with your changes, run\n+\t#\tgit rebase --continue\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output &&\n+\tgit rebase --abort\n+'\n+\n+\n+test_expect_success 'status in am progress: file already exists' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one  \" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress:\n+\t#   When you have resolved this problem run \"git am --resolved\".\n+\t#   If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t#   To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status in am progress: file does not exist' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one\" &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"delete main.txt\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress:\n+\t#   When you have resolved this problem run \"git am --resolved\".\n+\t#   If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t#   To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status in am progress: patch corrupted/wrong format' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one one.txt \"one\" &&\n+\ttest_commit two two.txt \"two\" &&\n+\ttest_commit three three.txt \"three\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all\" &&\n+\techo error >Maildir/0002-two.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently in am progress:\n+\t# One of the patches is empty!\n+\t#   When you have resolved this problem run \"git am --resolved\".\n+\t#   If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t#   To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t#   To get back to the original branch run \"git bisect reset\"\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushelp disabled' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\tgit config --local advice.statushelp false &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit checkout master &&\n+\ttest_must_fail git cherry-pick two &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking: fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\ttest_when_finished \"cd ../ && rm -rf git\"\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking: all conflicts fixed: run \"git commit\".\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192484","messageId":"1338384216-18782-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338384216-18782-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv4 3/3] Advices about 'git rm' during conflicts (unmerged paths) more relevant","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-30T13:23:36Z","receivedAt":"2012-05-30T13:23:36Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when\nthere are unmerged files) after running 'git status' is\nnow depending of the mark, whether it's 'both deleted',\n'deleted by us/them' or others. For instance, when there is\njust one file that's marked as 'both deleted', 'git status'\nshows '(use git rm [...])' and if there are two files, one\nas 'both deleted' and the other as 'added by them', the advice\nis '(use git add/rm [...])'.\n\nThe previous tests in t7512-status-warnings.sh are updated and\n5 tests are added about the different cases of unmerged paths.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\n t/t7512-status-warnings.sh |  165 ++++++++++++++++++++++++++++++++++++++++++-\n wt-status.c                |   29 ++++++++-\n 2 files changed, 189 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t7512-status-warnings.sh b/t/t7512-status-warnings.sh\nindex 2806fe8..01d614c 100755\n--- a/t/t7512-status-warnings.sh\n+++ b/t/t7512-status-warnings.sh\n@@ -27,7 +27,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t# You have unmerged paths; fix conflicts and run \"git commit\".\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" as appropriate to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -78,7 +78,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" as appropriate to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -280,7 +280,7 @@ test_expect_success 'status when rebase conflicts with statushelp disabled' '\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" as appropriate to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -311,7 +311,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t# You are currently cherry-picking: fix conflicts and run \"git commit\".\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" as appropriate to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -349,4 +349,161 @@ test_expect_success 'status when cherry-picking after resolving conflicts' '\n '\n \n \n+test_expect_success 'status when conflicts without rm advice (both modified)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second_branch main.txt on_second_branch &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by us)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tdeleted by us:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on master\" &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second main.txt on_second &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tdeleted by them:    main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout second_branch &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex 4dd294f..9d79f2b 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,27 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint simple_deleted_flag = 0;\n+\tint both_deleted_flag = 0;\n+\tint not_deleted_flag = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tif (d->stagemask == 1 && !both_deleted_flag)\n+\t\t\tboth_deleted_flag = 1;\n+\t\telse if ((d->stagemask == 3 || d->stagemask == 5) && !simple_deleted_flag)\n+\t\t\tsimple_deleted_flag = 1;\n+\t\telse if ((d->stagemask == 2 || d->stagemask == 4 || d->stagemask == 6 ||\n+\t\t\t\td->stagemask == 7) && !not_deleted_flag)\n+\t\t\tnot_deleted_flag = 1;\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +160,16 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted_flag)\n+\t\tif (!simple_deleted_flag)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" as appropriate to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\telse if (!simple_deleted_flag && !not_deleted_flag)\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" as appropriate to mark resolution)\"));\n+\telse\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"192499","messageId":"7vvcjdzini.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120530130914.Horde.CK7IZHwdC4BPxf-ak9fkbPA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv3 1/2] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-30T17:24:33Z","receivedAt":"2012-05-30T17:24:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n>> It strikes me odd that this is not listed next to statusHints, and\n>> it also makes me wonder if we even need to invent a new one, or it\n>> is better to just make the output more verbose when statusHints is\n>> not being declined.\n>\n> Yes, we first thought that we could use statusHints to protect the\n> new messages warnings. But users that disabled statusHints and still\n> wished to know what to do during am/rebase/bisect etc. won't be\n> able to. On the other hand, if they want to hide the new advices, they\n> can see in the doc the presence of the advice.statusHelp and disable it.\n\n\"When we have more more knobs, we can differentiate more cases\" is\nnot a valid argument, unless you can successfully argue that it is\nworth differentiating these subcases.  Otherwise it is just another\nuseless knob the user needs to tweak without real gain.\n\nIn this particular case, I think the new text is merely an extension\nof existing help text.  Those who have already declined statusHints\nshould not be bothered by it, and those who are being helped by them\nwould benefit from the help text being more complete.\n"},{"id":"192504","messageId":"7vmx4pzfse.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338384216-18782-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-30T18:26:25Z","receivedAt":"2012-05-30T18:26:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> This patch provides new warning messages in the display of\n> 'git status' (at the top) during conflicts, rebase, am,\n> bisect or cherry-pick process.\n\nI hate to see these called \"warnings\", as there is nothing for the\nend user to be alarmed about.  The user wanted to know what status\nthe working tree is in, and we are reporting what the user wanted to\nknow.  They are informative help messages.\n\n> The new messages are not shown when using options such as\n> -s or --porcelain.The messages about the current\n> situation of the user are always displayed but the advices\n> on what the user needs to do in order to resume a rebase/bisect\n> /am/ commit after resolving conflicts can be hidden by setting\n> advice.statushelp to 'false' in the config file.\n\nNotice the spaces are sprinkled in the above paragraph in a funny\nway?  You might want to get in the habit of proofreading what you\nwrote before sending.\n\n> Thus, information about the new advice.* key are added in\n> Documentation/config.txt.\n>\n> Also, the test t7060-wt-status.sh is now working with the\n> new warning messages.\n>\n> Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n> Signed-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\n> Signed-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\n> Signed-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\n> Signed-off-by: Nguyen Huynh Khoi Nguyen Lucien <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n> ---\n> The code figures the current state by finding the files generated\n> in .git in each cases (during an am, a rebase, a bisect, etc.).\n>\n> The function wt_status_print_in_progress is now splitted into\n> several smaller functions in order to avoid too many indentations.\n>\n>  Documentation/config.txt |    4 +\n>  advice.c                 |    2 +\n>  advice.h                 |    1 +\n>  t/t7060-wtstatus.sh      |    2 +\n>  wt-status.c              |  161 ++++++++++++++++++++++++++++++++++++++++++++++\n>  wt-status.h              |   11 +++\n>  6 files changed, 181 insertions(+), 0 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 915cb5a..ab1c455 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -162,6 +162,9 @@ advice.*::\n>  \t\tDirections on how to stage/unstage/add shown in the\n>  \t\toutput of linkgit:git-status[1] and the template shown\n>  \t\twhen writing commit messages.\n> +\tstatusHelp::\n> +\t\tDirections on how to end the current process shown\n> +\t\tin the output of linkgit:git-status[1].\n>  \tcommitBeforeMerge::\n>  \t\tAdvice shown when linkgit:git-merge[1] refuses to\n>  \t\tmerge to avoid overwriting local changes.\n> @@ -176,6 +179,7 @@ advice.*::\n>  \t\tAdvice shown when you used linkgit:git-checkout[1] to\n>  \t\tmove to the detach HEAD state, to instruct how to create\n>  \t\ta local branch after the fact.\n> +\n>  --\n>  \n>  core.fileMode::\n> diff --git a/advice.c b/advice.c\n> index a492eea..31deb31 100644\n> --- a/advice.c\n> +++ b/advice.c\n> @@ -9,6 +9,7 @@ int advice_commit_before_merge = 1;\n>  int advice_resolve_conflict = 1;\n>  int advice_implicit_identity = 1;\n>  int advice_detached_head = 1;\n> +int advice_status_help = 1;\n>  \n>  static struct {\n>  \tconst char *name;\n> @@ -23,6 +24,7 @@ static struct {\n>  \t{ \"resolveconflict\", &advice_resolve_conflict },\n>  \t{ \"implicitidentity\", &advice_implicit_identity },\n>  \t{ \"detachedhead\", &advice_detached_head },\n> +\t{ \"statushelp\", &advice_status_help },\n>  };\n>  \n>  void advise(const char *advice, ...)\n> diff --git a/advice.h b/advice.h\n> index f3cdbbf..5fd3cce 100644\n> --- a/advice.h\n> +++ b/advice.h\n> @@ -12,6 +12,7 @@ extern int advice_commit_before_merge;\n>  extern int advice_resolve_conflict;\n>  extern int advice_implicit_identity;\n>  extern int advice_detached_head;\n> +extern int advice_status_help;\n>  \n>  int git_default_advice_config(const char *var, const char *value);\n>  void advise(const char *advice, ...);\n> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\n> index b8cb490..d0fbcc7 100755\n> --- a/t/t7060-wtstatus.sh\n> +++ b/t/t7060-wtstatus.sh\n> @@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n>  \n>  cat >expect <<EOF\n>  # On branch side\n> +# You have unmerged paths; fix conflicts and run \"git commit\".\n> +#\n>  # Unmerged paths:\n>  #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n>  #\n> diff --git a/wt-status.c b/wt-status.c\n> index dd6d8c4..4dd294f 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n>  \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n>  \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n>  \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n> +\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n>  };\n>  \n>  static const char *color(int slot, struct wt_status *s)\n> @@ -728,10 +729,149 @@ static void wt_status_print_tracking(struct wt_status *s)\n>  \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n>  }\n>  \n> +static int wt_status_unmerged_present (struct wt_status *s)\n\nPlease drop needless extra SP between function name and its\nparameter list (I won't repeat this but the same breakage is\neverywhere in this patch).\n\nIs it worth giving this file-local helper function a long name like\nthat?  A short-and-sweet has_unmerged() would work just as well and\nprobably easier to read.\n\n> +{\n> +\tint i;\n> +\n> +\tfor (i = 0; i < s->change.nr; i++) {\n> +\t\tstruct wt_status_change_data *d;\n> +\t\td = s->change.items[i].util;\n> +\t\tif (d->stagemask) {\n> +\t\t\treturn 1;\n> +\t\t}\n\nPlease drop needless {} around a single statement block (I won't\nrepeat this but the same breakage is everywhere in this patch).\n\n> +\t}\n> +\treturn 0;\n> +}\n> +\n> +static void wt_status_evaluate_state (struct wt_status_state *state)\n> +{\n> +\tstruct stat st;\n> +\n> +\tstate->merge_in_progress = 0;\n> +\tstate->am_in_progress = 0;\n> +\tstate->am_empty_patch = 0;\n> +\tstate->rebase_in_progress = 0;\n> +\tstate->rebase_interactive_in_progress = 0;\n> +\tstate->cherry_pick_in_progress = 0;\n> +\tstate->bisect_in_progress = 0;\n> +\n> +\tif (!stat(git_path(\"MERGE_HEAD\"), &st))\n> +\t\tstate->merge_in_progress = 1;\n> +\telse if (!stat(git_path(\"rebase-apply\"), &st)) {\n> +\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n> +\t\t\tstate->am_in_progress = 1;\n> +\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !(st.st_size))\n\nPlease drop needless () around st.st_size.\n\n> +\t\t\t\tstate->am_empty_patch = 1;\n> +\t\t}\n> +\t\telse\n> +\t\t\tstate->rebase_in_progress = 1;\n\nTwo points on style (also appear elsewhere in this patch):\n\n\tif (!\"applying\") {\n \t\t...\n\t} else {\n\t\tstate->rebase_in_progress = 1;\n\t}\n\n - \"else\" comes on the same line as closing \"}\" of its \"if\" block;\n\n - if one of if/else if/else chain has multiple statement block, use {}\n   even for a single statement block in the chain.\n\n> +\t}\n> +\telse if (!stat(git_path(\"rebase-merge\"), &st)) {\n> +\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n> +\t\t\tstate->rebase_interactive_in_progress = 1;\n> +\t\telse\n> +\t\t\tstate->rebase_in_progress = 1;\n> +\t}\n> +\telse if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st))\n> +\t\tstate->cherry_pick_in_progress = 1;\n> +\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n> +\t\tstate->bisect_in_progress = 1;\n> +}\n> +\n> +static void wt_status_merge_in_progress (struct wt_status *s,\n> +\t\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\t\tconst char *color)\n\nThe earlier \"evaluate-state\" was a well-named function, but this is\nnot. \"merge_in_progress\" what? It is not about asking \"is a merge in\nprogress?\", but is about showing message when it is the case.\nPlease have \"print\" or \"show\" or something that tells what it _does_\nsomewhere in its name (same applies to other functions in this patch).\n\n> +{\n> +\tif (wt_status_unmerged_present(s))\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"You have unmerged paths; fix conflicts and run \\\"git commit\\\".\"));\n> +\telse\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"You are still merging, run \\\"git commit\\\" to conclude merge.\"));\n> +\twt_status_print_trailer(s);\n> +}\n> +\n> +static void wt_status_am_in_progress (struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tstatus_printf_ln(s, color,\n> +\t\t_(\"You are currently in am progress:\"));\n\nIs it just me, or is the above -ECANTPARSE?  \"You are currently in\ncommit/merge/meal/commute progress?\"\n\nPerhaps\t\"You are in the middle of an am session\" or something?\n\n> +\tif (state->am_empty_patch)\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"One of the patches is empty!\"));\n\nCan we state this better?  It is not like you have 4 patches, you\nare processing its third one, and you found that the first patch you\nhave already skipped was empty and keep nagging the user about \"one\nof them\" being empty.  As far as I can tell, you observed that\n\"current one\" that is being processed is empty in evaluate-state, so\nI think it makes more sense to tell the user the current one is\nempty instead of being vague like the above.\n\n> +\tif (advice_status_help) {\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  When you have resolved this problem run \\\"git am --resolved\\\".\"));\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n> +\t}\n\nI doubt it makes much sense to hide only these messages behind \"if\n(advice_status_help)\".  Look at how you give your \"what to do\"\nadvices in wt-status-merge-in-progress function.\n\nProbably it is a good idea to show this unconditionally *if* the\ncaller decides to call this function, and other \"print/show\" kind of\nfunctions, this patch adds.\n\n\n> +\twt_status_print_trailer(s);\n> +}\n> +\n> +static void wt_status_rebase_in_progress (struct wt_status *s,\n> +\t\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\t\tconst char *color)\n> +{\n> +\tif (wt_status_unmerged_present(s)) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n> +\t\t\tadvice_status_help\n> +\t\t\t? _(\": fix conflicts and then run \\\"git rebase --continue\\\".\") : \".\");\n\nLikewise.\n\n> +\t\tif (advice_status_help) {\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n> +\t\t}\n> +\t}\n> +\telse if (state->rebase_in_progress)\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing: all conflicts fixed%s\"),\n> +\t\t\tadvice_status_help\n> +\t\t\t? _(\": run \\\"git rebase --continue\\\".\") : \".\");\n> +\telse {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n> +\t\tif (advice_status_help) {\n> +\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with your changes, run\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n> +\t\t}\n> +\t}\n> +\twt_status_print_trailer(s);\n> +}\n> +\n> +static void wt_status_cherry_pick_in_progress (struct wt_status *s,\n> +\t\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\t\tconst char *color)\n> +{\n> +\tif (wt_status_unmerged_present(s))\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"You are currently cherry-picking: fix conflicts and run \\\"git commit\\\".\"));\n> +\telse\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"You are currently cherry-picking: all conflicts fixed: run \\\"git commit\\\".\"));\n> +\twt_status_print_trailer(s);\n> +}\n> +\n> +static void wt_status_bisect_in_progress (struct wt_status *s,\n> +\t\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\t\tconst char *color)\n> +{\n> +\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n> +\tif (advice_status_help)\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  To get back to the original branch run \\\"git bisect reset\\\"\"));\n> +\twt_status_print_trailer(s);\n> +}\n> +\n>  void wt_status_print(struct wt_status *s)\n>  {\n>  \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n>  \tconst char *branch_status_color = color(WT_STATUS_HEADER, s);\n> +\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n> +\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n>  \n>  \tif (s->branch) {\n>  \t\tconst char *on_what = _(\"On branch \");\n> @@ -750,6 +890,27 @@ void wt_status_print(struct wt_status *s)\n>  \t\t\twt_status_print_tracking(s);\n>  \t}\n>  \n> +\twt_status_evaluate_state(state);\n> +\n> +\tif (state->merge_in_progress) {\n> +\t\twt_status_merge_in_progress(s, state, state_color);\n> +\t}\n> +\telse if (state->am_in_progress) {\n> +\t\twt_status_am_in_progress(s, state, state_color);\n> +\t}\n> +\n> +\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress) {\n> +\t\twt_status_rebase_in_progress(s, state, state_color);\n> +\t}\n> +\n> +\telse if (state->cherry_pick_in_progress) {\n> +\t\twt_status_cherry_pick_in_progress(s, state, state_color);\n> +\t}\n> +\n> +\tif (state->bisect_in_progress) {\n> +\t\twt_status_bisect_in_progress(s, state, state_color);\n> +\t}\n> +\n\nAnd instead, hide the above new lines behind advice.statusHints,\nwithout introducing advice.statusHelp.  As to the global code\nstructure, it probably would make more sense to:\n\n  - rename wt_status_evaluate_state() to wt_status_print_state();\n\n  - rename the various \"print help information for this state\" functions\n    that are called in the above if/else/... cascade to merge_in_progress_show()\n    etc.\n\n  - move the above if/else/... cascade to the end of\n    wt_status_print_state(), which would make the above part more\n    like:\n\n\t wt_status_print()\n         {\n\t\tif (s->branch) {\n                \t...\n\t\t}\n\t+\twt_status_print_state(s);\n\t\tif (s->is_initial) {\n\t\t\t...\n\n  - at the beginning of wt_status_print_state(), check advice.statusHints\n    and return without doing anything if the user does not want hints.\n\nOtherwise, overall the patch is getting better looking.\n\nThanks for a pleasant read.\n\n>  \tif (s->is_initial) {\n>  \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n>  \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\n> diff --git a/wt-status.h b/wt-status.h\n> index 14aa9f7..c1066a0 100644\n> --- a/wt-status.h\n> +++ b/wt-status.h\n> @@ -15,6 +15,7 @@ enum color_wt_status {\n>  \tWT_STATUS_LOCAL_BRANCH,\n>  \tWT_STATUS_REMOTE_BRANCH,\n>  \tWT_STATUS_ONBRANCH,\n> +\tWT_STATUS_IN_PROGRESS,\n>  \tWT_STATUS_MAXSLOT\n>  };\n>  \n> @@ -71,6 +72,16 @@ struct wt_status {\n>  \tstruct string_list ignored;\n>  };\n>  \n> +struct wt_status_state {\n> +\tint merge_in_progress;\n> +\tint am_in_progress;\n> +\tint am_empty_patch;\n> +\tint rebase_in_progress;\n> +\tint rebase_interactive_in_progress;\n> +\tint cherry_pick_in_progress;\n> +\tint bisect_in_progress;\n> +};\n> +\n>  void wt_status_prepare(struct wt_status *s);\n>  void wt_status_print(struct wt_status *s);\n>  void wt_status_collect(struct wt_status *s);\n"},{"id":"192505","messageId":"7vipfdzeyu.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338384216-18782-3-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv4 3/3] Advices about 'git rm' during conflicts (unmerged paths) more relevant","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-30T18:44:09Z","receivedAt":"2012-05-30T18:44:09Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n>  static void wt_status_print_unmerged_header(struct wt_status *s)\n>  {\n> +\tint i;\n> +\tint simple_deleted_flag = 0;\n> +\tint both_deleted_flag = 0;\n> +\tint not_deleted_flag = 0;\n>  \tconst char *c = color(WT_STATUS_HEADER, s);\n>  \n>  \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n> +\n> +\tfor (i = 0; i < s->change.nr; i++) {\n> +\t\tstruct string_list_item *it = &(s->change.items[i]);\n> +\t\tstruct wt_status_change_data *d = it->util;\n> +\n> +\t\tif (d->stagemask == 1 && !both_deleted_flag)\n> +\t\t\tboth_deleted_flag = 1;\n> +\t\telse if ((d->stagemask == 3 || d->stagemask == 5) && !simple_deleted_flag)\n> +\t\t\tsimple_deleted_flag = 1;\n> +\t\telse if ((d->stagemask == 2 || d->stagemask == 4 || d->stagemask == 6 ||\n> +\t\t\t\td->stagemask == 7) && !not_deleted_flag)\n> +\t\t\tnot_deleted_flag = 1;\n> +\t}\n\nYuck.  Do you need to \"&& !flag\" in any of these?\n\n\tswitch (d->stagemask) {\n        case 1:\n        \tboth_deleted = 1;\n                break;\n        case 3:\n        case 5:\n        \tsimple_deleted = 1;\n                break;\n        default:\n        \tnot_deleted = 1;\n                break;\n\t}\n\nAlso, I think \"simple deleted\" is grossly misnamed.  It is \"one side\ndeleted, other side possibly modified\", isn't it?  Because it is\nalmost always safe to resolve \"both sides deleted\" to a deletion,\nbut \"one deleted, the other modified\" needs a lot more thought to\nresolve correctly, it is a much more complex case.  I'd call it\ndel_mod_conflict or something if I were writing this code.\n\nIn any case, drop \"_flag\" from the names.  They are annoying and do\nnot add much value.\n\n>  \tif (!advice_status_hints)\n>  \t\treturn;\n>  \tif (s->whence != FROM_COMMIT)\n> @@ -142,7 +160,16 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n>  \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n>  \telse\n>  \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n> -\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n> +\n> +\tif (!both_deleted_flag)\n\nIf you meant the control flow to follow your indentation, I think\nyou are missing opening \"{\" at the end of the above line.\n\n> +\t\tif (!simple_deleted_flag)\n> +\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" as appropriate to mark resolution)\"));\n\nNobody deleted, so we do not suggest \"rm\" as resolution, which makes\nsense.\n\nAs far as I know, in the current message we say \"as appropriate\"\nbecause we leave the choice of add/rm to the end user.  Do you still\nneed \"as appropriate\" after deciding that \"add\" is the only choice\nfor the user?\n\n> +\t\telse\n> +\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n\nThere is del/mod conflict and nothing else; the user needs to choose\nbetween add/rm.  OK.\n\n> +\telse if (!simple_deleted_flag && !not_deleted_flag)\n> +\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" as appropriate to mark resolution)\"));\n\nAssuming that a closing \"}\" for the \"if (!both_deleted)\" above is\nmissing at the beginning of this line, there is no del/mod conflict,\nsome del/del and no addition, so \"rm\" is the only choice, which\nmakes sense.  The same comment on \"as appropriate\" applies here.\n\n> +\telse\n> +\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n>  \tstatus_printf_ln(s, c, \"\");\n>  }\n\nI like the way it tries to be helpful, but I doubt this patch would\nmake much difference in the real life.  As you follow the logic like\nI demonstrated above, you show specific help only in a very narrow\ncase (i.e. there is no possible removal or there are nothing but\n\"both sides removed\").\n"},{"id":"192506","messageId":"7vehq1zdxz.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"7vmx4pzfse.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-30T19:06:16Z","receivedAt":"2012-05-30T19:06:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> And instead, hide the above new lines behind advice.statusHints,\n> without introducing advice.statusHelp.  As to the global code\n> structure, it probably would make more sense to:\n>\n>   - rename wt_status_evaluate_state() to wt_status_print_state();\n>\n>   - rename the various \"print help information for this state\" functions\n>     that are called in the above if/else/... cascade to merge_in_progress_show()\n>     etc.\n>\n>   - move the above if/else/... cascade to the end of\n>     wt_status_print_state(), which would make the above part more\n>     like:\n>\n> \t wt_status_print()\n>          {\n> \t\tif (s->branch) {\n>                 \t...\n> \t\t}\n> \t+\twt_status_print_state(s);\n> \t\tif (s->is_initial) {\n> \t\t\t...\n>\n>   - at the beginning of wt_status_print_state(), check advice.statusHints\n>     and return without doing anything if the user does not want hints.\n>\n> Otherwise, overall the patch is getting better looking.\n>\n> Thanks for a pleasant read.\n\nAfter reading the current code, I changed my mind slightly.\n\nThe way the new code tries to separate the state information\n(i.e. statement of the fact it found) and the advice messages\n(i.e. what could be done next) is indeed in line with what the\nadvice.statusHints configuration is used in the existing code.  We\nunconditionally show what we find to the user, and we give help by\ndefault but let the user decline.\n\nSo an updated suggestion would be to still move the whole thing to\nwt_status_print_state(), but not check advice.statusHints at the\nbeginning of the function (as we will show what we find even when\nthe user declines help text) and do the discovery, and hide the help\nmessages (i.e. \"do this to proceed\") behind advice.statusHints,\nwithout introducing advice.statusHelp.\n\nAs I pointed out in my review, there were some places in the patch\nthat gave help text unconditionally, which needs to be corrected.\n"},{"id":"192514","messageId":"20120530235048.Horde.jSNYW3wdC4BPxpY4izr11PA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7vipfdzeyu.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv4 3/3] Advices about 'git rm' during conflicts (unmerged paths) more relevant","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-05-30T21:50:48Z","receivedAt":"2012-05-30T21:50:48Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n>> +\t\tif (d->stagemask == 1 && !both_deleted_flag)\n>> +\t\t\tboth_deleted_flag = 1;\n>> +\t\telse if ((d->stagemask == 3 || d->stagemask == 5) &&  \n>> !simple_deleted_flag)\n>> +\t\t\tsimple_deleted_flag = 1;\n>> +\t\telse if ((d->stagemask == 2 || d->stagemask == 4 || d->stagemask == 6 ||\n>> +\t\t\t\td->stagemask == 7) && !not_deleted_flag)\n>> +\t\t\tnot_deleted_flag = 1;\n>> +\t}\n>\n> \tswitch (d->stagemask) {\n>         case 1:\n>         \tboth_deleted = 1;\n>                 break;\n>         case 3:\n>         case 5:\n>         \tsimple_deleted = 1;\n>                 break;\n>         default:\n>         \tnot_deleted = 1;\n>                 break;\n> \t}\n\nYes, using switch makes the code easier to read. In fact, I put explicitly the\ncondition when there are no delete (cases 2, 4, 6 and 7) because there  \nare cases\nwhen d->stagemask can take other number than 1..7. For example:\n\ngit init git &&\ncd git &&\ntest_commit foo main.txt foo &&\ngit branch second_branch &&\ngit mv main.txt sub_master.txt &&\ngit commit -m \"main.txt renamed in sub_master.txt\" &&\ngit checkout second_branch &&\ngit mv main.txt sub_second.txt &&\ngit commit -m \"main.txt renamed in sub_second.txt\" &&\ngit merge master &&\ngit add sub_master.txt &&\ngit add sub_second.txt\n\nAt this point, the output of git status shows in unmerged paths the  \nfile main.txt\nthat is marked as 'both deleted' so the number of elements in  \ns->change.items should\nbe 1. However, in this case, there are 2 elements. One is about the  \nfile main.txt and\nits stagemask is '1' (as expected) but the stagemask of the other  \nelement (I don't\nknow its origin) is '0'.\nAnyway, the new code becomes something like:\n\nswitch (d->stagemask) {\ncase 0:\n\tbreak;\ncase 1:\n\tboth_deleted = 1;\n\tbreak;\ncase 3:\ncase 5:\n\tdel_mod_conflict = 1;\n\tbreak;\ndefault:\n\tnot_deleted = 1;\n\tbreak;\n}\n\nThough I don't know if d->stagemask can take values such as 8, 9, etc.\n"},{"id":"192536","messageId":"vpqipfcsw1x.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338384216-18782-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T06:29:14Z","receivedAt":"2012-05-31T06:29:14Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> The new messages are not shown when using options such as\n> -s or --porcelain.The messages about the current\n\nspace between . and The (normally, 2 spaces in english).\n\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -176,6 +179,7 @@ advice.*::\n>  \t\tAdvice shown when you used linkgit:git-checkout[1] to\n>  \t\tmove to the detach HEAD state, to instruct how to create\n>  \t\ta local branch after the fact.\n> +\n>  --\n\nWhy add a blank line here?\n\n> +\tif (state->merge_in_progress) {\n> +\t\twt_status_merge_in_progress(s, state, state_color);\n> +\t}\n> +\telse if (state->am_in_progress) {\n> +\t\twt_status_am_in_progress(s, state, state_color);\n> +\t}\n> +\n> +\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress) {\n> +\t\twt_status_rebase_in_progress(s, state, state_color);\n> +\t}\n> +\n> +\telse if (state->cherry_pick_in_progress) {\n> +\t\twt_status_cherry_pick_in_progress(s, state, state_color);\n> +\t}\n> +\n> +\tif (state->bisect_in_progress) {\n> +\t\twt_status_bisect_in_progress(s, state, state_color);\n> +\t}\n\nDo these have to be if/else if/... ?\n\nIn most cases, the user will have only one of these at the same time,\nbut in the few cases where there's, e.g. a rebase during a bisect or so,\nI think it makes more sense to show both advices to the user (probably\nas a sign that something's wrong).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192538","messageId":"CAH5451kTS+LhVoSz_jiz4UTK_AwocMzn9HctOLyAUDN9j492Aw@mail.gmail.com","threadId":"30608","inReplyTo":"vpqipfcsw1x.fsf@bauges.imag.fr","subject":"Re: [PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Andrew Ardill","fromEmail":"andrew.ardill@gmail.com","sentAt":"2012-05-31T06:34:29Z","receivedAt":"2012-05-31T06:34:29Z","isPatch":false,"sender":{"key":"andrew.ardill@gmail.com","avatar":"https://gravatar.com/avatar/da14cb7c091dd44dc6c63a4d3361b149acaf25226dc78eb4131a17b93d9b0993?d=mp&s=160"},"body":"On 31 May 2012 16:29, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote:\n> Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n>\n>> The new messages are not shown when using options such as\n>> -s or --porcelain.The messages about the current\n>\n> space between . and The (normally, 2 spaces in english).\n\nIt is not common practice to use 2 spaces after a period any more,\nespecially on the web. A good summary of information around using 1 or\n2 spaces after a period can be found at [1]\n\nRegards,\n\nAndrew Ardill\n\n[1] http://www.webword.com/reports/period.html\n"},{"id":"192539","messageId":"vpq1um0svgn.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"7vmx4pzfse.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T06:42:00Z","receivedAt":"2012-05-31T06:42:00Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> +\tstatus_printf_ln(s, color,\n>> +\t\t_(\"You are currently in am progress:\"));\n>\n> Is it just me, or is the above -ECANTPARSE?  \"You are currently in\n> commit/merge/meal/commute progress?\"\n\nIt's not just you ;-).\n\n> Perhaps\t\"You are in the middle of an am session\" or something?\n\nI'd just say \"rebase in progress\".\n\n>> +\tstatus_printf_ln(s, color,\n>> +\t\t_(\"You are currently in am progress:\"));\n[...]\n>> +\tif (advice_status_help) {\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  When you have resolved this problem run \\\"git am --resolved\\\".\"));\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n>> +\t}\n>\n> I doubt it makes much sense to hide only these messages behind \"if\n> (advice_status_help)\".  Look at how you give your \"what to do\"\n> advices in wt-status-merge-in-progress function.\n\nI disagree.\n\n\"rebase in progress\" adds information for advanced Git users as well as\nfor newbies. I think it makes sense to display it unconditionnally, like\nwe currently display \"Not currently on any branch.\" or \"Your branch is\nahead of ...\".\n\nThe state in which the user is is important for anyone, but the set of\ncommands to get out of this state is not relevant for advanced users,\nand simply eats a few terminal lines for them.\n\nI think the situation is no different from other messages like \"Changes\nnot staged for commit:\", where the list matters for everyone, but the\nsuggested commands don't, and that's why I still think\nadvice.statusHints should be used here too.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192540","messageId":"vpqr4u0rgs3.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"vpq1um0svgn.fsf@bauges.imag.fr","subject":"Re: [PATCHv4 1/3] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T06:44:28Z","receivedAt":"2012-05-31T06:44:28Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n>> I doubt it makes much sense to hide only these messages behind \"if\n>> (advice_status_help)\".  Look at how you give your \"what to do\"\n>> advices in wt-status-merge-in-progress function.\n>\n> I disagree.\n\nBut I do agree with your updated suggestion (which I read too late):\n\nJunio C Hamano <gitster@pobox.com> writes:\n\n> So an updated suggestion would be to still move the whole thing to\n> wt_status_print_state(), but not check advice.statusHints at the\n> beginning of the function (as we will show what we find even when\n> the user declines help text) and do the discovery, and hide the help\n> messages (i.e. \"do this to proceed\") behind advice.statusHints,\n> without introducing advice.statusHelp.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192541","messageId":"vpqmx4orgnm.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"20120530130914.Horde.CK7IZHwdC4BPxf-ak9fkbPA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv3 1/2] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T06:47:09Z","receivedAt":"2012-05-31T06:47:09Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"konglu@minatec.inpg.fr writes:\n\n> Yes, we first thought that we could use statusHints to protect the\n> new messages warnings. But users that disabled statusHints and still\n> wished to know what to do during am/rebase/bisect etc.\n\nI don't think you should worry too much about people who already set\nstatusHints. By definition, they are people who read the documentation,\nwhich already disqualifies them as \"newbies\". If you show the state\nunconditionally, and just hide the commands, then at worse, they will\nhave to read the doc again.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192542","messageId":"vpq7gvsrfr0.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338384216-18782-3-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv4 3/3] Advices about 'git rm' during conflicts (unmerged paths) more relevant","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T07:06:43Z","receivedAt":"2012-05-31T07:06:43Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> Subject: Re: [PATCHv4 3/3] Advices about 'git rm' during conflicts (unmerged paths) more relevant\n\n\"more relevant\" doesn't say much, and your subject line doesn't say it's\nabout \"status\". What about\n\nstatus: don't suggest \"git rm\" if not appropriate\n\n?\n\n> +test_expect_success 'status when conflicts without rm advice (both modified)' '\n\nHow is this different from the other existing tests? Avoid adding\nredundant tests, they slow down the test suite without added value.\n\n> +test_expect_success 'status when conflicts with add and rm advice (deleted by us)' '\n> +test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n\nYou can probably save a few line (and test execution time) by reusing\nthe same repository in the second test, like\n\ngit reset --hard\ngit checkout master\ngit merge second_branch\n\n(i.e. reply the merge, but symmetrically, from the other branch)\n\nPerhaps this sould be added to t7060-wtstatus.sh (basic work tree status\nreporting) instead, which already tests \"deleted by us:\". Ideally, you\ncould add tests for \"deleted by them\" and \"both deleted\" in a first\npatch, and turn the add/rm into add in the implementation patch.\n\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tdeleted by us:      main.txt\n+\t#\n\nTo really test the logic, you need to have more than one file in the\nlist (the logic should say \"suggest rm if _at least one_ file may need\nit\", but currently, a patch implementing \"if _all_ files\" would pass the\ntest).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192546","messageId":"20120531095914.Horde.McdhLnwdC4BPxyTSG9v3ctA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"vpq7gvsrfr0.fsf@bauges.imag.fr","subject":"Re: [PATCHv4 3/3] Advices about 'git rm' during conflicts (unmerged paths) more relevant","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-05-31T07:59:14Z","receivedAt":"2012-05-31T07:59:14Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nMatthieu Moy <Matthieu.Moy@grenoble-inp.fr> a écrit :\n\n>> Subject: Re: [PATCHv4 3/3] Advices about 'git rm' during conflicts  \n>> (unmerged paths) more relevant\n>\n> \"more relevant\" doesn't say much, and your subject line doesn't say it's\n> about \"status\". What about\n>\n> status: don't suggest \"git rm\" if not appropriate\n>\n> ?\nIn the case of only 'both deleted', what we don't want 'git status' to suggest\nis \"git add\". Maybe something like\n\nstatus: advices appropriated during conflicts\nor\nstatus: don't suggest \"git rm\" or \"git add\" if not appropriate\n\nwould fit.\n"},{"id":"192593","messageId":"1338477344-15940-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338384216-18782-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-31T15:15:42Z","receivedAt":"2012-05-31T15:15:42Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new informative help messages in the display of\n'git status' (at the top) during conflicts, rebase, am, bisect or\ncherry-pick process.\n\nThe new messages are not shown when using options such as -s or\n--porcelain. The messages about the current situation of the user are\nalways displayed but the advices on what the user needs to do in order\nto resume a rebase/bisect /am/ commit after resolving conflicts can be\nhidden by setting advice.statushints to 'false' in the config file.\n\nThus, information about the updated advice.statushints key are added\nin Documentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the new help\nmessages. Tests about suggestions of \"git rm\" are also added.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\nThe key advice.statushelp introduced in the previous patches is\ndeleted. The messages are now controlled by advice.statushints.\n\n Documentation/config.txt |    2 +\n t/t7060-wtstatus.sh      |   71 +++++++++++++++++++++\n wt-status.c              |  154 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 4 files changed, 238 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..52f5009 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -162,6 +162,8 @@ advice.*::\n \t\tDirections on how to stage/unstage/add shown in the\n \t\toutput of linkgit:git-status[1] and the template shown\n \t\twhen writing commit messages.\n+\t\tDirections on how to end the current process shown\n+\t\tin the output of linkgit:git-status[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..8a6d68a 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths; fix conflicts and run \"git commit\".\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\n@@ -118,4 +120,73 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n \ttest_cmp expected actual\n '\n \n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\ttest_commit second conflict.txt second &&\n+\tgit checkout master &&\n+\ttest_commit on_second main.txt on_second &&\n+\ttest_commit master conflict.txt master &&\n+\ttest_must_fail git merge second_branch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         conflict.txt\n+\t#\tdeleted by them:    main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout second_branch &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..f4ba021 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,158 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int has_unmerged(struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+static void merge_in_progress_show(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s))\n+\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths%s\"),\n+\t\t\tadvice_status_hints\n+\t\t\t? _(\"; fix conflicts and run \\\"git commit\\\".\") : \".\");\n+\telse\n+\t\tstatus_printf_ln(s, color, _(\"You are still merging%s\"),\n+\t\t\tadvice_status_hints\n+\t\t\t? _(\", run \\\"git commit\\\" to conclude merge.\") : \".\");\n+\twt_status_print_trailer(s);\n+}\n+\n+static void am_in_progress_show(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are in the middle of an am session:\"));\n+\tif (state->am_empty_patch)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"The current patch is empty!\"));\n+\tif (advice_status_hints) {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  When you have resolved this problem run \\\"git am --resolved\\\".\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git am --skip\\\".\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  To restore the original branch and stop patching run \\\"git am --abort\\\".\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void rebase_in_progress_show(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n+\t\t\tadvice_status_hints\n+\t\t\t? _(\": fix conflicts and then run \\\"git rebase --continue\\\".\") : \".\");\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n+\t\t}\n+\t} else if (state->rebase_in_progress) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n+\t\t\tadvice_status_hints\n+\t\t\t? _(\": all conflicts fixed: run \\\"git rebase --continue\\\".\") : \".\");\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n+\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n+\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with your changes, run\"));\n+\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void cherry_pick_in_progress_show(struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s))\n+\t\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking%s\"),\n+\t\t\tadvice_status_hints\n+\t\t\t? _(\": fix conflicts and run \\\"git commit\\\".\") : \".\");\n+\telse\n+\t\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking%s\"),\n+\t\t\tadvice_status_hints\n+\t\t\t? _(\": all conflicts fixed: run \\\"git commit\\\".\") : \".\");\n+\twt_status_print_trailer(s);\n+}\n+\n+static void bisect_in_progress_show(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_hints)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  To get back to the original branch run \\\"git bisect reset\\\"\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_print_state(struct wt_status *s)\n+{\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st)) {\n+\t\tstate->merge_in_progress = 1;\n+\t} else if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !st.st_size)\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t} else {\n+\t\t\tstate->rebase_in_progress = 1;\n+\t\t}\n+\t} else if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t} else if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st)) {\n+\t\tstate->cherry_pick_in_progress = 1;\n+\t}\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+\n+\tif (state->merge_in_progress)\n+\t\tmerge_in_progress_show(s, state, state_color);\n+\telse if (state->am_in_progress)\n+\t\tam_in_progress_show(s, state, state_color);\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n+\t\trebase_in_progress_show(s, state, state_color);\n+\telse if (state->cherry_pick_in_progress)\n+\t\tcherry_pick_in_progress_show(s, state, state_color);\n+\tif (state->bisect_in_progress)\n+\t\tbisect_in_progress_show(s, state, state_color);\n+\tfree(state);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +903,7 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_state(s);\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"192595","messageId":"1338477344-15940-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338477344-15940-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv5 2/3] t7512-status-help.sh: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-31T15:15:43Z","receivedAt":"2012-05-31T15:15:43Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user needs to\nrun 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am/ cherry-pick progress.\n\nOne of the test is about the set of the advice.statushints config key\nto 'false' in .git/config.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\n t/t7512-status-help.sh |  347 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 347 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-help.sh\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nnew file mode 100755\nindex 0000000..af1d130\n--- /dev/null\n+++ b/t/t7512-status-help.sh\n@@ -0,0 +1,347 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second_branch main.txt on_second_branch &&\n+\ttest_must_fail git merge master &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You are still merging, run \"git commit\" to conclude merge.\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\tgit commit -m \"one\" &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: fix conflicts and then run \"git rebase --continue\".\n+\t#   If you would prefer to skip this patch, instead run \"git rebase --skip\".\n+\t#   To check out  the original branch and stop rebasing run \"git rebase --abort\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing: all conflicts fixed: run \"git rebase --continue\".\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git fake-editor.sh\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   You can amend the commit with\n+\t#\tgit commit --amend\n+\t#   Once you are satisfied with your changes, run\n+\t#\tgit rebase --continue\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output &&\n+\tgit rebase --abort\n+'\n+\n+\n+test_expect_success 'status in an am session: file already exists' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one  \" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are in the middle of an am session:\n+\t#   When you have resolved this problem run \"git am --resolved\".\n+\t#   If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t#   To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status in an am session: file does not exist' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt \"one\" &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"delete main.txt\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are in the middle of an am session:\n+\t#   When you have resolved this problem run \"git am --resolved\".\n+\t#   If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t#   To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status in an am session: wrong format' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one one.txt \"one\" &&\n+\ttest_commit two two.txt \"two\" &&\n+\ttest_commit three three.txt \"three\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all\" &&\n+\techo error >Maildir/0002-two.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are in the middle of an am session:\n+\t# The current patch is empty!\n+\t#   When you have resolved this problem run \"git am --resolved\".\n+\t#   If you would prefer to skip this patch, instead run \"git am --skip\".\n+\t#   To restore the original branch and stop patching run \"git am --abort\".\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tMaildir/\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t#   To get back to the original branch run \"git bisect reset\"\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tnothing added to commit but untracked files present (use \"git add\" to track)\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushints disabled' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\tgit config --local advice.statushints false &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expect <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit checkout master &&\n+\ttest_must_fail git cherry-pick two &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking: fix conflicts and run \"git commit\".\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\ttest_when_finished \"cd ../ && rm -rf git\"\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking: all conflicts fixed: run \"git commit\".\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192594","messageId":"1338477344-15940-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338477344-15940-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv5 3/3] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-05-31T15:15:44Z","receivedAt":"2012-05-31T15:15:44Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when there are\nunmerged files) after running 'git status' is now depending of the\nmark, whether it's 'both deleted', 'deleted by us/them' or others. For\ninstance, when there is just one file that's marked as 'both deleted',\n'git status' shows '(use git rm [...])' and if there are two files,\none as 'both deleted' and the other as 'added by them', the advice is\n'(use git add/rm [...])'.\n\nThe previous tests in t7512-status-help.sh are updated.\n\nTest about the case of only 'both deleted' is added in\nt7060-wtstatus.sh\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n---\n t/t7060-wtstatus.sh    |   28 ++++++++++++++++++++++++++++\n t/t7512-status-help.sh |    6 +++---\n wt-status.c            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 67 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex 8a6d68a..60a1b99 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -189,4 +189,32 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n \ttest_cmp expect output\n '\n \n+\n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths; fix conflicts and run \"git commit\".\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\texpect\n+\t#\toutput\n+\tEOF\n+\tgit status >output &&\n+\ttest_cmp expect output\n+'\n+\n test_done\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex af1d130..83c42df 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -27,7 +27,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t# You have unmerged paths; fix conflicts and run \"git commit\".\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -78,7 +78,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -306,7 +306,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t# You are currently cherry-picking: fix conflicts and run \"git commit\".\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\ndiff --git a/wt-status.c b/wt-status.c\nindex f4ba021..ee503b8 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,34 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint del_mod_conflict = 0;\n+\tint both_deleted = 0;\n+\tint not_deleted = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tswitch (d->stagemask) {\n+\t\tcase 0:\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tboth_deleted = 1;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\tcase 5:\n+\t\t\tdel_mod_conflict = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tnot_deleted = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted) {\n+\t\tif (!del_mod_conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t} else if (!del_mod_conflict && !not_deleted) {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t}\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"192623","messageId":"7vmx4o58zc.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338477344-15940-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-31T21:36:07Z","receivedAt":"2012-05-31T21:36:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> This patch provides new informative help messages in the display of\n> 'git status' (at the top) during conflicts, rebase, am, bisect or\n> cherry-pick process.\n>\n> The new messages are not shown when using options such as -s or\n> --porcelain. The messages about the current situation of the user are\n> always displayed but the advices on what the user needs to do in order\n> to resume a rebase/bisect /am/ commit after resolving conflicts can be\n\nIs there a reason why there is a SP after bisect here?\n\n> hidden by setting advice.statushints to 'false' in the config file.\n>\n> Thus, information about the updated advice.statushints key are added\n> in Documentation/config.txt.\n>\n> Also, the test t7060-wt-status.sh is now working with the new help\n> messages. Tests about suggestions of \"git rm\" are also added.\n\nLooks much better and getting ready for being at least on 'pu' if\nnot 'next', it seems.\n\n> Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n> Signed-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\n> Signed-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\n> Signed-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\n> Signed-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n\nHow is your development process work, by the way?  Does everybody on\nthis list have code in this patch?  Or are you just listing people\nwho are in the same class taught by Matthieu who reviewed and\ncommented on this patch?\n\n>  Documentation/config.txt |    2 +\n>  t/t7060-wtstatus.sh      |   71 +++++++++++++++++++++\n>  wt-status.c              |  154 ++++++++++++++++++++++++++++++++++++++++++++++\n>  wt-status.h              |   11 +++\n>  4 files changed, 238 insertions(+), 0 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 915cb5a..52f5009 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -162,6 +162,8 @@ advice.*::\n>  \t\tDirections on how to stage/unstage/add shown in the\n>  \t\toutput of linkgit:git-status[1] and the template shown\n>  \t\twhen writing commit messages.\n> +\t\tDirections on how to end the current process shown\n> +\t\tin the output of linkgit:git-status[1].\n\nI kind of find this hard to read.  Perhaps it shouldn't be a\nseparate sentence, but instead should just enhance the existing\nlimited \"stage/unstage/add\" set?  The list of updated, modified and\nuntracked paths with instructions given by the current code is an\nincomplete description of the current state, and I view this patch\nas filling the missing bits to it to make the output more complete.\n\nSo from that point of view, perhaps more like this?\n\n-\tDirections on how to stage/unstage/add shown in the\n-\toutput of linkgit:git-status[1] and the template shown\n-\twhen writing commit messages.\n+\tShow directions on how to proceed from the current state\n+\tin the output of linkgit:git-status[1] and in the template\n+\tshown when writing commit messages in linkgit:git-commit[1].\n\n> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\n> index b8cb490..8a6d68a 100755\n> --- a/t/t7060-wtstatus.sh\n> +++ b/t/t7060-wtstatus.sh\n> @@ -30,6 +30,8 @@ test_expect_success 'Report new path with conflict' '\n>  \n>  cat >expect <<EOF\n>  # On branch side\n> +# You have unmerged paths; fix conflicts and run \"git commit\".\n> +#\n>  # Unmerged paths:\n>  #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n>  #\n> @@ -118,4 +120,73 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n>  \ttest_cmp expected actual\n>  '\n\nNote what filenames are used to store the expected output and grab\nthe actual output out of the command.\n\n> +\n> +test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n> +\tgit init git &&\n> +\tcd git &&\n> +\ttest_when_finished \"cd ../ && rm -rf git\" &&\n\nThis is a tangent, but this sequence is wrong.  If \"git init\"\nsucceeds but \"cd git\" fails for some reason, you wouldn't clean the\nnew test repository, and worse, you go up and try to remove a random\n\"git\" that is different from what you created here.\n\nPerhaps I am being a bit superstitous, but I would feel a lot safer\nto see if this were written like this:\n\n        git init git &&\n        (\n\t\tcd git &&\n                ... the rest of this test ...\n\t) &&\n        rm -fr git\n\nto avoid mistakes.  For example, if you add any \"cd somewhere-else\"\nin the remainder of the test, your test_when_finished to go to a\nrelative \"cd ../\" wouldn't do you any good.\n\n> +\ttest_commit init main.txt init &&\n> +\tgit checkout -b second_branch &&\n> +\tgit rm main.txt &&\n> +\tgit commit -m \"main.txt deleted on second_branch\" &&\n> +\ttest_commit second conflict.txt second &&\n> +\tgit checkout master &&\n> +\ttest_commit on_second main.txt on_second &&\n> +\ttest_commit master conflict.txt master &&\n> +\ttest_must_fail git merge second_branch &&\n> +\tcat >expect <<-\\EOF &&\n> +\t# On branch master\n> +\t# You have unmerged paths; fix conflicts and run \"git commit\".\n> +\t#\n> +\t# Unmerged paths:\n> +\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n> +\t#\n> +\t#\tboth added:         conflict.txt\n> +\t#\tdeleted by them:    main.txt\n> +\t#\n> +\t# Untracked files:\n> +\t#   (use \"git add <file>...\" to include in what will be committed)\n> +\t#\n> +\t#\texpect\n> +\t#\toutput\n> +\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n> +\tEOF\n> +\tgit status >output &&\n> +\ttest_cmp expect output\n> +'\n\nAnd rename \"output\" to \"actual\" to match the existing practice\n(unless there is a compelling reason not to).\n\n> diff --git a/wt-status.c b/wt-status.c\n> index dd6d8c4..f4ba021 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n>  \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n>  \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n>  \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n> +\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n>  };\n>  \n>  static const char *color(int slot, struct wt_status *s)\n> @@ -728,6 +729,158 @@ static void wt_status_print_tracking(struct wt_status *s)\n>  \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n>  }\n>  \n> +static int has_unmerged(struct wt_status *s)\n> +{\n> +\tint i;\n> +\n> +\tfor (i = 0; i < s->change.nr; i++) {\n> +\t\tstruct wt_status_change_data *d;\n> +\t\td = s->change.items[i].util;\n> +\t\tif (d->stagemask)\n> +\t\t\treturn 1;\n> +\t}\n> +\treturn 0;\n> +}\n> +\n> +static void merge_in_progress_show(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n\nMinor nit: perhaps \"show-merge-in-progress\" would read more\nnaturally (same for all other helpers).\n\n> +{\n> +\tif (has_unmerged(s))\n> +\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths%s\"),\n> +\t\t\tadvice_status_hints\n> +\t\t\t? _(\"; fix conflicts and run \\\"git commit\\\".\") : \".\");\n> +\telse\n> +\t\tstatus_printf_ln(s, color, _(\"You are still merging%s\"),\n> +\t\t\tadvice_status_hints\n> +\t\t\t? _(\", run \\\"git commit\\\" to conclude merge.\") : \".\");\n\nThe former uses ';' while the latter uses ','.  There is a use of\n':' in the rebase-in-progress helper.  Be consistent (if I were\nwriting this code, I would pick ';').\n\nWould this qualify as a \"language lego\" i18n/l10n people loathe?\nIOW would it be better to have four independent messages?\n\n        \"You have unmerged paths.\"\n        \"You are still merging.\"\n        \"You have unmerged paths; fix conflicts and...\"\n\t\"You are still merging; fun \\\"git commit\\\" to conclude...\"\n\nThis is not a rhetorical question.  There is the same issue in the\nrebase-in-progress helper.\n\n> +static void am_in_progress_show(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tstatus_printf_ln(s, color,\n> +\t\t_(\"You are in the middle of an am session:\"));\n> +\tif (state->am_empty_patch)\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"The current patch is empty!\"));\n\nThis situation may deserve a \"; run 'am --skip' to skip it.\" advice.\n\n> +static void rebase_in_progress_show(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tif (has_unmerged(s)) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n> +\t\t\tadvice_status_hints\n> +\t\t\t? _(\": fix conflicts and then run \\\"git rebase --continue\\\".\") : \".\");\n> +\t\tif (advice_status_hints) {\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  If you would prefer to skip this patch, instead run \\\"git rebase --skip\\\".\"));\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  To check out  the original branch and stop rebasing run \\\"git rebase --abort\\\".\"));\n\nDouble-space in the middle intended?\n\nThis line looks overly long.  Does it fit (with the # prefix) on\ntypical 80-column terminals?\n\n> +\t\t}\n> +\t} else if (state->rebase_in_progress) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n> +\t\t\tadvice_status_hints\n> +\t\t\t? _(\": all conflicts fixed: run \\\"git rebase --continue\\\".\") : \".\");\n\nThe above will show this:\n\n# You are currently rebasing: all conflicts fixed: run \"git rebase --continue.\n\nThat's 78 cols, which is pushing the right edge too closely,\nespecially considering that translations tend to make messages\nlonger.\n\nAside from questionable use of ':' (I think ';' is better for the\nfirst one, and '.' is better for the latter; and s/run/Run/ to begin\na new sentence), I think this is nicer than the merge-in-progress\nmessage after the user has already marked all paths resolved, which\nsays \"You are still merging\" without saying \"you have resolved\neverything\".  Perhaps you meant to hint that by saying \"still\" (as\nopposed to \"currently\"), but the distinction feels a bit too subtle.\n\n\n> +\t} else {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n> +\t\tif (advice_status_hints) {\n> +\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with your changes, run\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n\nFor an advice in \"git status\" output, the above may be appropriate,\nbut would the user see this in \"git commit\" template, and if so,\nisn't it because the user typed \"git commit --amend\"?  Does it make\nsense to suggest to run \"git commit --amend\" in that context?\n\nThe same comment applies to all new advice messages added by this\npatch.\n\nThanks.\n"},{"id":"192632","messageId":"vpq8vg7jue4.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338477344-15940-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-01T08:42:11Z","receivedAt":"2012-06-01T08:42:11Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +\tcat >expect <<-\\EOF &&\n[...]\n> +\t# Untracked files:\n> +\t#   (use \"git add <file>...\" to include in what will be committed)\n> +\t#\n> +\t#\texpect\n> +\t#\toutput\n> +\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n> +\tEOF\n> +\tgit status >output &&\n\nYou can run\n\n  git status --untracked-files=no\n\ninstead, to get rid of these \"expect\" and \"output\". as Junio mentionned\non another topic, these make the test scripts a bit harder to maintain,\nfor example you should rename \"output\" to \"actual\", and you don't want\nthat to interfere with the content of \"expect\".\n\n> +\t} else if (state->rebase_in_progress) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing%s\"),\n> +\t\t\tadvice_status_hints\n> +\t\t\t? _(\": all conflicts fixed: run \\\"git rebase --continue\\\".\") : \".\");\n\nAvoid having two \":\" in the same sentense.\n\n> +\t\tif (advice_status_hints) {\n> +\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with your changes, run\"));\n> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n> +\t\t}\n\nCan this be more consistant with other status hints? When a hint follows\na statement on the next line, it's usually\n\n# Say something\n#   (use \"git whatever\" to change the current state)\n\ne.g.\n\n# Changes not staged for commit:\n#   (use \"git add <file>...\" to update what will be committed)\n\nSo this may be turned into\n\n# Rebase in progress\n#   (use \"git commit --amend\" to amend the current commit)\n#   (use \"git rebase --continue\" once you are satisfied with your changes)\n\n> +\tif (state->merge_in_progress)\n> +\t\tmerge_in_progress_show(s, state, state_color);\n> +\telse if (state->am_in_progress)\n> +\t\tam_in_progress_show(s, state, state_color);\n> +\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n> +\t\trebase_in_progress_show(s, state, state_color);\n> +\telse if (state->cherry_pick_in_progress)\n> +\t\tcherry_pick_in_progress_show(s, state, state_color);\n> +\tif (state->bisect_in_progress)\n> +\t\tbisect_in_progress_show(s, state, state_color);\n\nI still disagree with the \"else if\" logic here. If the user started two\noperations, I think we should show both messages.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192635","messageId":"vpqzk8nif81.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338477344-15940-3-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv5 3/3] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-01T08:55:10Z","receivedAt":"2012-06-01T08:55:10Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n>  \t# Unmerged paths:\n> -\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n> +\t#   (use \"git add <file>...\" to mark resolution)\n>  \t#\n>  \t#\tboth modified:      main.txt\n>  \t#\n\nThis makes me think of another possible improvement (unrelated from this\none). When merging a binary file, one gets\n\n# On branch branch\n# Unmerged paths:\n#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n#\n#       both modified:      binary.bin\n#\n\nBut no conflict markers, as they would make no sense in the file. Then,\nit's a real pain to fix if you're not a Git expert. It would help, in\nthe presence of binary files, to turn that into :\n\n# Unmerged paths:\n#   (use \"git checkout --ours [-- path]\" to checkout your version)\n#   (use \"git checkout --theirs [-- path]\" to checkout the version being merged)\n#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n#\n#       both modified:      binary.bin\n#\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192639","messageId":"20120601111651.Horde.R0mdSHwdC4BPyIiDyUHhUVA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7vmx4o58zc.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-01T09:16:51Z","receivedAt":"2012-06-01T09:16:51Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n> How is your development process work, by the way?  Does everybody on\n> this list have code in this patch?  Or are you just listing people\n> who are in the same class taught by Matthieu who reviewed and\n> commented on this patch?\n\nBasically, we 5 people are in the same group and work together on\nthe same project. Some are more involved into improving the advices\nin git status, and some are more involved into the XDG configuration\nbut we are all in the same room thus there're a lot of communication so\neveryone knows what's happening in each topics. Matthieu is helping us\nwhen we have technical questions but he doesn't review our code beforehand\n(he is very busy :p).\n\nBtw, we're also working on other small improvements such as the implementation\nof \"git rebase -i --exec <cmd>\".\n\n> And rename \"output\" to \"actual\" to match the existing practice\n> (unless there is a compelling reason not to).\n\nWe based our coding-style on the t7508-status.sh script which\nseem to use out-of-date style (some instructions are not in\ntest_expect_success for example). We will use the modern coding\nstyle from now on.\n\n>> +\t} else {\n>> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit  \n>> during a rebase.\"));\n>> +\t\tif (advice_status_hints) {\n>> +\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n>> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n>> +\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with  \n>> your changes, run\"));\n>> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n>\n> For an advice in \"git status\" output, the above may be appropriate,\n> but would the user see this in \"git commit\" template, and if so,\n> isn't it because the user typed \"git commit --amend\"?  Does it make\n> sense to suggest to run \"git commit --amend\" in that context?\n\nTrue, the user will see the messages in the \"git commit\" template. We\ndidn't take this case into account because we thought that not many people\nread the status in the \"git commit\" template. Anyway, just adding a condition\n\nif (advice_status_hints && !s->amend)\n\ndoes the job.\n"},{"id":"192641","messageId":"vpqzk8ngz6k.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"20120601111651.Horde.R0mdSHwdC4BPyIiDyUHhUVA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-01T09:26:59Z","receivedAt":"2012-06-01T09:26:59Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"konglu@minatec.inpg.fr writes:\n\n> Junio C Hamano <gitster@pobox.com> a écrit :\n>\n>> How is your development process work, by the way?  Does everybody on\n>> this list have code in this patch?  Or are you just listing people\n>> who are in the same class taught by Matthieu who reviewed and\n>> commented on this patch?\n>\n> Basically, we 5 people are in the same group and work together on\n> the same project. Some are more involved into improving the advices\n> in git status, and some are more involved into the XDG configuration\n> but we are all in the same room thus there're a lot of communication so\n> everyone knows what's happening in each topics. Matthieu is helping us\n> when we have technical questions but he doesn't review our code beforehand\n> (he is very busy :p).\n\nJust an addition: I'm not really a co-author of the work, but I'm the\none who authorize the students to contribute their code to Git (they are\nnormally not allowed to distribute the code they develop for school\nprojects).\n\nI think this implies that I should appear in the Signed-off-by: of the\npatches.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192651","messageId":"20120601132710.Horde.j1U5UHwdC4BPyKcOgc8zbbA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"vpq8vg7jue4.fsf@bauges.imag.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-01T11:27:10Z","receivedAt":"2012-06-01T11:27:10Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nMatthieu Moy <Matthieu.Moy@grenoble-inp.fr> a écrit :\n\n>> +\tif (state->merge_in_progress)\n>> +\t\tmerge_in_progress_show(s, state, state_color);\n>> +\telse if (state->am_in_progress)\n>> +\t\tam_in_progress_show(s, state, state_color);\n>> +\telse if (state->rebase_in_progress ||  \n>> state->rebase_interactive_in_progress)\n>> +\t\trebase_in_progress_show(s, state, state_color);\n>> +\telse if (state->cherry_pick_in_progress)\n>> +\t\tcherry_pick_in_progress_show(s, state, state_color);\n>> +\tif (state->bisect_in_progress)\n>> +\t\tbisect_in_progress_show(s, state, state_color);\n>\n> I still disagree with the \"else if\" logic here. If the user started two\n> operations, I think we should show both messages.\n\nWe show both messages in the case of bisect. However, we decided to\nimplement a priority for the other cases because of how the code figures\nout the current state.\nThe cases in which you're in 'am' AND 'rebase' or only in 'am' is hard to\nhandle. Thus The priority is given to the 'am' because running 'am' during\na 'rebase' is possible (and the other way is not).\nOn top of that, I think that the user only needs to know his \"most recent\"\ncurrent state. Given that he's running 'am' during a 'rebase', knowing that\nhe's in am progress is enough. If he finishes the 'am', then he will still\nknow that he's in a 'rebase' with 'git status'.\n"},{"id":"192656","messageId":"CABURp0qS-bDYTTgz75mQOOZsXzM1TkF_CNjaRNcXa4MYXAg0kA@mail.gmail.com","threadId":"30608","inReplyTo":"1338477344-15940-3-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv5 3/3] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-01T12:15:58Z","receivedAt":"2012-06-01T12:15:58Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Thu, May 31, 2012 at 11:15 AM, Kong Lucien\n<Lucien.Kong@ensimag.imag.fr> wrote:\n> The display of the advice '(use git add/rm [...])' (when there are\n> unmerged files) after running 'git status' is now depending of the\n> mark, whether it's 'both deleted', 'deleted by us/them' or others. For\n> instance, when there is just one file that's marked as 'both deleted',\n> 'git status' shows '(use git rm [...])' and if there are two files,\n> one as 'both deleted' and the other as 'added by them', the advice is\n> '(use git add/rm [...])'.\n>\n...\ndiff --git a/wt-status.c b/wt-status.c\n...\n> @@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n>                status_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n>        else\n>                status_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n> -       status_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n> +\n> +       if (!both_deleted) {\n> +               if (!del_mod_conflict)\n> +                       status_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n> +               else\n> +                       status_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n> +       } else if (!del_mod_conflict && !not_deleted) {\n> +               status_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n> +       } else {\n> +               status_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n> +       }\n>        status_printf_ln(s, c, \"\");\n>  }\n\n\nThis brings a frequent frustration to the front.  It is not the fault\nof this commit, so please don't think I am blaming you, Lucien.  Thank\nyou for highlighting it.\n\n> +       } else if (!del_mod_conflict && !not_deleted) {\n> +               status_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n\nWhy should I be bothered when both sides delete the same file?  Does\nthis case only occur when each side has made different changes to the\nfile prior to deleting it, or does it occur any time each commit has\ndeleted the same exact file?\n\nAs this patch highlights, the only expected resolution is to 'git rm'\nthe file; why can't git figure this out for me and continue on?\n\nIs there a config option to alter this behavior?\n\nPhil\n"},{"id":"192658","messageId":"CABURp0rm2JKBmrm62uAVj1WSc3BE_LoKoHbjmxvkQhPNgnozpA@mail.gmail.com","threadId":"30608","inReplyTo":"20120601132710.Horde.j1U5UHwdC4BPyKcOgc8zbbA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-01T12:40:39Z","receivedAt":"2012-06-01T12:40:39Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Fri, Jun 1, 2012 at 7:27 AM,  <konglu@minatec.inpg.fr> wrote:\n>\n> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> a écrit :\n>\n>>> +    if (state->merge_in_progress)\n>>> +            merge_in_progress_show(s, state, state_color);\n>>> +    else if (state->am_in_progress)\n>>> +            am_in_progress_show(s, state, state_color);\n>>> +    else if (state->rebase_in_progress ||\n>>> state->rebase_interactive_in_progress)\n>>> +            rebase_in_progress_show(s, state, state_color);\n>>> +    else if (state->cherry_pick_in_progress)\n>>> +            cherry_pick_in_progress_show(s, state, state_color);\n>>> +    if (state->bisect_in_progress)\n>>> +            bisect_in_progress_show(s, state, state_color);\n>>\n>> I still disagree with the \"else if\" logic here. If the user started two\n>> operations, I think we should show both messages.\n>\n> We show both messages in the case of bisect. However, we decided to\n> implement a priority for the other cases because of how the code figures\n> out the current state.\n> The cases in which you're in 'am' AND 'rebase' or only in 'am' is hard to\n> handle. Thus The priority is given to the 'am' because running 'am' during\n> a 'rebase' is possible (and the other way is not).\n> On top of that, I think that the user only needs to know his \"most recent\"\n> current state. Given that he's running 'am' during a 'rebase', knowing that\n> he's in am progress is enough. If he finishes the 'am', then he will still\n> know that he's in a 'rebase' with 'git status'.\n\n\nRelated to this, I think this is all useful information which is being\ngathered and analyzed here.  It would be useful if all of the git code\ncould use these status functions in common instead of implementing\nsimilar functionality individually.  But that is a topic for another\ncommit.\n\nMore appropriate for now is that I think there should be a\nporcelain(?) version of this information.  First, imagine we can get\njust this new session status information with a switch named\n'--sequencer'[*]::\n\n  $ git status --sequencer\n  You have unmerged paths.\n  You are in an am session.\n  You are in the middle of an interactive rebase.\n\n  $ git status --porcelain --sequencer\n  airu\n\nThe \"--porcelain --sequencer\" combination I am imagining here would\nshow the status as a script-parseable sequence of single-letter\nindicators telling the status of these same various conditions:\n  u - unmerged paths\n  a - git-am session\n  i - interactive rebase\n  r - rebase\n  c - cherry-pick\n  m - merge\netc.\n\nBy giving a value to --porcelain, we could limit the test to certain\nconditions and return a meaningful result code if any are true.\n\n  $ if git status --porcelain --sequencer=u ; then echo \"Unmerged\npaths exist\" ; fi\n\nI don't know if it makes sense to spell the --porcelain version with\nor without spaces/newlines.  Any opinions?\n\nWhat about the idea overall?\n\nPhil\n\n[*] Though I hate the choice of 'sequencer' as an option name for the\nuser, it makes sense to me in this context. Please suggest any\nalternatives that spring to mind.\n"},{"id":"192663","messageId":"20120601160808.Horde.ij8nYXwdC4BPyMzILrtjxYA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"CABURp0qS-bDYTTgz75mQOOZsXzM1TkF_CNjaRNcXa4MYXAg0kA@mail.gmail.com","subject":"Re: [PATCHv5 3/3] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-01T14:08:08Z","receivedAt":"2012-06-01T14:08:08Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nPhil Hord <phil.hord@gmail.com> a écrit :\n\n>> +       } else if (!del_mod_conflict && !not_deleted) {\n>> +               status_printf_ln(s, c, _(\"  (use \\\"git rm  \n>> <file>...\\\" to mark resolution)\"));\n>\n> Why should I be bothered when both sides delete the same file?  Does\n> this case only occur when each side has made different changes to the\n> file prior to deleting it, or does it occur any time each commit has\n> deleted the same exact file?\n\nIf both sides delete the same file with \"git rm\", this case does not occur\nbecause there is no conflict when merging. However, it can occur when\nboth sides rename the file and then merge.\n\n> As this patch highlights, the only expected resolution is to 'git rm'\n> the file; why can't git figure this out for me and continue on?\n\nI agree. The only option for the user is to run \"git rm\". You also have\nto type the whole name of the deleted file as you can't tab for completion\nand you can't avoid it as it's part of \"unmerged path\" (so you have to\nresolve the current index). It would be great if git could figure it by\nitself so we don't have to go through this process. Nevertheless, the\ncurrent display of the advice shows \"git add\" which can infer that you\ncan still recover the deleted file, which is not the case. At least, with\nthis code, the user will avoid this confusion.\n"},{"id":"192667","messageId":"7vvcjb3x3e.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"vpqzk8ngz6k.fsf@bauges.imag.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-01T14:50:29Z","receivedAt":"2012-06-01T14:50:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> Just an addition: I'm not really a co-author of the work, but I'm the\n> one who authorize the students to contribute their code to Git (they are\n> normally not allowed to distribute the code they develop for school\n> projects).\n>\n> I think this implies that I should appear in the Signed-off-by: of the\n> patches.\n\nGlad I asked.  Yes, it would very much help if you sign off these\npatches if that is the case.\n"},{"id":"192673","messageId":"7vbol33s31.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120601160808.Horde.ij8nYXwdC4BPyMzILrtjxYA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv5 3/3] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-01T16:38:42Z","receivedAt":"2012-06-01T16:38:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n> If both sides delete the same file with \"git rm\", this case does not occur\n> because there is no conflict when merging. However, it can occur when\n> both sides rename the file and then merge.\n>\n>> As this patch highlights, the only expected resolution is to 'git rm'\n>> the file; why can't git figure this out for me and continue on?\n>\n> I agree. The only option for the user is to run \"git rm\".\n\nIf both sides remove the path A and one side creates a similar\nlooking B but the other side does so for C, it is clear that neither\nside wants A in the result, so the only option FOR THE PATH A is to\nrun \"git rm\".\n\nBut when looking at B and C to decide, it would help knowing that\nthe corresponding source of these renames is potentially A.  If we\nauto-resolved A, we would lose that information, no?\n\nYou need to look at a larger picture.\n"},{"id":"192675","messageId":"7v396f3rhg.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120601111651.Horde.R0mdSHwdC4BPyIiDyUHhUVA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-01T16:51:39Z","receivedAt":"2012-06-01T16:51:39Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n>>> +\t} else {\n>>> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit  \n>>> during a rebase.\"));\n>>> +\t\tif (advice_status_hints) {\n>>> +\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n>>> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n>>> +\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with  \n>>> your changes, run\"));\n>>> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n>>\n>> For an advice in \"git status\" output, the above may be appropriate,\n>> but would the user see this in \"git commit\" template, and if so,\n>> isn't it because the user typed \"git commit --amend\"?  Does it make\n>> sense to suggest to run \"git commit --amend\" in that context?\n>\n> True, the user will see the messages in the \"git commit\" template. We\n> didn't take this case into account because we thought that not many people\n> read the status in the \"git commit\" template. Anyway, just adding a condition\n>\n> if (advice_status_hints && !s->amend)\n>\n> does the job.\n\nHrm, what would happen if the user ran \"git commit\" without --amend?\n\nIt could be done by mistake, which will be greatly helped by the\ninformation you already gathered during the inspection phase.  \n\nThis also can be done deliberately to split a commit in \"rebase -i\",\nso \"You are in 'rebase -i', do not commit without --amend!\" is a\nwrong message, but it may be sensible to give \"are you sure you\nmeant to commit without --amend?\"\n"},{"id":"192676","messageId":"7vy5o72cnm.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"CABURp0rm2JKBmrm62uAVj1WSc3BE_LoKoHbjmxvkQhPNgnozpA@mail.gmail.com","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-01T16:57:17Z","receivedAt":"2012-06-01T16:57:17Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phil Hord <phil.hord@gmail.com> writes:\n\n>   $ git status --sequencer\n>   You have unmerged paths.\n>   You are in an am session.\n>   You are in the middle of an interactive rebase.\n>\n>   $ git status --porcelain --sequencer\n>   airu\n>\n> The \"--porcelain --sequencer\" combination I am imagining here would\n> show the status as a script-parseable sequence of single-letter\n> indicators telling the status of these same various conditions:\n>   u - unmerged paths\n>   a - git-am session\n>   i - interactive rebase\n>   r - rebase\n>   c - cherry-pick\n>   m - merge\n> etc.\n\nSome people seem to think that machine-readable has to mean\nunreadable cryptic line noises.  It's a disease.\n\nIf you have to write \"etc.\", you clearly do not know what the\nrange of possible values of these things will eventually be.\n\nAnd I do not think it is your fault not to know what we would want\nto add in the future.  But it is your fault to choose unreadable\ncryptic line noises as an output format.\n\nJust spell them out, and do not mark them for translation.\n"},{"id":"192688","messageId":"20120601213911.Horde.UIs0dHwdC4BPyRpflFgUaLA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7v396f3rhg.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-01T19:39:11Z","receivedAt":"2012-06-01T19:39:11Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n> konglu@minatec.inpg.fr writes:\n>\n>>>> +\t} else {\n>>>> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit\n>>>> during a rebase.\"));\n>>>> +\t\tif (advice_status_hints) {\n>>>> +\t\t\tstatus_printf_ln(s, color, _(\"  You can amend the commit with\"));\n>>>> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit commit --amend\"));\n>>>> +\t\t\tstatus_printf_ln(s, color, _(\"  Once you are satisfied with\n>>>> your changes, run\"));\n>>>> +\t\t\tstatus_printf_ln(s, color, _(\"\tgit rebase --continue\"));\n>>>\n>>> For an advice in \"git status\" output, the above may be appropriate,\n>>> but would the user see this in \"git commit\" template, and if so,\n>>> isn't it because the user typed \"git commit --amend\"?  Does it make\n>>> sense to suggest to run \"git commit --amend\" in that context?\n>>\n>> True, the user will see the messages in the \"git commit\" template. We\n>> didn't take this case into account because we thought that not many people\n>> read the status in the \"git commit\" template. Anyway, just adding a  \n>> condition\n>>\n>> if (advice_status_hints && !s->amend)\n>>\n>> does the job.\n>\n> Hrm, what would happen if the user ran \"git commit\" without --amend?\n\nThe new advices will still be displayed (of course only if advice.statushints\nis enabled).\n\n> It could be done by mistake, which will be greatly helped by the\n> information you already gathered during the inspection phase.\n\nThus, if done by mistake, the user will know that he needs to do\n\"git commit --amend\" to edit the commit.\n\n> This also can be done deliberately to split a commit in \"rebase -i\",\n> so \"You are in 'rebase -i', do not commit without --amend!\" is a\n> wrong message, but it may be sensible to give \"are you sure you\n> meant to commit without --amend?\"\n\nAn interesting case. In fact, more than warning the user about running\ngit commit without --amend, wouldn't it be better if there were specific\nhelp messages about splitting a commit ? Like\n\n# Not currently on any branch.\n# You are currently splitting a commit.\n#   (Once your working directory is clean, run \"git rebase --continue\")\n#\n# Changes not staged for commit:\n#   (use \"git add <file>...\" to update what will be committed)\n#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n#\n#       modified:   t/t7060-wtstatus.sh\n#       modified:   t/t7512-status-help.sh\n#       modified:   wt-status.c\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\nthat will be the output of git status after a \"git reset HEAD^\" during\na rebase -i. There's already the advice \"(use git add <file>...)\" so\nputting it twice is not really relevant.\n\nWhat do you think about it ?\n"},{"id":"192760","messageId":"1338748217-16440-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338477344-15940-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv6 1/4] wt-status.*: better advices for git status added","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-03T18:30:14Z","receivedAt":"2012-06-03T18:30:14Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new informative help messages in the display of\n'git status' (at the top) during conflicts, rebase, am, bisect or\ncherry-pick process.\n\nThe new messages are not shown when using options such as -s or\n--porcelain. The messages about the current situation of the user are\nalways displayed but the advices on what the user needs to do in order\nto resume a rebase/bisect/am/commit after resolving conflicts can be\nhidden by setting advice.statushints to 'false' in the config file.\n\nThus, information about the updated advice.statushints key are added\nin Documentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the new help\nmessages. Tests about suggestions of \"git rm\" are also added.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n---\nThe new advices that are protected by the key advice.statushints are\nnow stated the same way the other messages protected by the same config\nkey are.\n\n Documentation/config.txt |    4 +\n t/t7060-wtstatus.sh      |   67 +++++++++++++++++++\n wt-status.c              |  165 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 4 files changed, 247 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..670945d 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -162,6 +162,10 @@ advice.*::\n \t\tDirections on how to stage/unstage/add shown in the\n \t\toutput of linkgit:git-status[1] and the template shown\n \t\twhen writing commit messages.\n+\t\tShow directions on how to proceed from the current\n+\t\tstate in the output of linkgit:git-status[1] and in\n+\t\tthe template shown when writing commit messages in\n+\t\tlinkgit:git-commit[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..61d1f38 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths.\n+#   (fix conflicts and run \"git commit\")\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\n@@ -118,4 +121,68 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n \ttest_cmp expected actual\n '\n \n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit init git &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit init main.txt init &&\n+\t\tgit checkout -b second_branch &&\n+\t\tgit rm main.txt &&\n+\t\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\t\ttest_commit second conflict.txt second &&\n+\t\tgit checkout master &&\n+\t\ttest_commit on_second main.txt on_second &&\n+\t\ttest_commit master conflict.txt master &&\n+\t\ttest_must_fail git merge second_branch &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# On branch master\n+\t\t# You have unmerged paths.\n+\t\t#   (fix conflicts and run \"git commit\")\n+\t\t#\n+\t\t# Unmerged paths:\n+\t\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t\t#\n+\t\t#\tboth added:         conflict.txt\n+\t\t#\tdeleted by them:    main.txt\n+\t\t#\n+\t\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual\n+\t) &&\n+\trm -rf git\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout second_branch &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge master &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..2460e20 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,169 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int has_unmerged(struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+static void show_merge_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"All conflicts fixed but you are still merging.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit\\\" to conclude merge)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_am_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are in the middle of an am session.\"));\n+\tif (state->am_empty_patch) {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"The current patch is empty; run \\\"git am --skip\\\" to skip it.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n+\t} else if (advice_status_hints) {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (when you have fixed this problem run \\\"git am --resolved\\\")\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_rebase_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n+\t\t}\n+\t} else if (state->rebase_in_progress) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_hints && !s->amend) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied with your changes)\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_cherry_pick_in_progress(struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git commit\\\")\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_bisect_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_hints)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git bisect reset\\\" to get back to the original branch)\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_print_state(struct wt_status *s)\n+{\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st)) {\n+\t\tstate->merge_in_progress = 1;\n+\t} else if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !st.st_size)\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t} else {\n+\t\t\tstate->rebase_in_progress = 1;\n+\t\t}\n+\t} else if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t} else if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st)) {\n+\t\tstate->cherry_pick_in_progress = 1;\n+\t}\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+\n+\tif (state->merge_in_progress)\n+\t\tshow_merge_in_progress(s, state, state_color);\n+\telse if (state->am_in_progress)\n+\t\tshow_am_in_progress(s, state, state_color);\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n+\t\tshow_rebase_in_progress(s, state, state_color);\n+\telse if (state->cherry_pick_in_progress)\n+\t\tshow_cherry_pick_in_progress(s, state, state_color);\n+\tif (state->bisect_in_progress)\n+\t\tshow_bisect_in_progress(s, state, state_color);\n+\tfree(state);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +914,7 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_state(s);\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"192761","messageId":"1338748217-16440-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338748217-16440-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv6 2/4] t7512-status-help.sh: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-03T18:30:15Z","receivedAt":"2012-06-03T18:30:15Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user needs to\nrun 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am/ cherry-pick progress.\n\nOne of the test is about the set of the advice.statushints config key\nto 'false' in .git/config.\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n---\n t/t7512-status-help.sh |  303 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 303 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-help.sh\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nnew file mode 100755\nindex 0000000..5f62262\n--- /dev/null\n+++ b/t/t7512-status-help.sh\n@@ -0,0 +1,303 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second_branch main.txt on_second_branch &&\n+\ttest_must_fail git merge master &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch second_branch\n+\t# All conflicts fixed but you are still merging.\n+\t#   (use \"git commit\" to conclude merge)\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\tgit commit -m \"one\" &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git fake-editor.sh\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one main.txt one &&\n+\t\ttest_commit two main.txt two &&\n+\t\ttest_commit three main.txt three &&\n+\t\tFAKE_LINES=\"1 edit 2\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~2 &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# Not currently on any branch.\n+\t\t# You are currently editing a commit during a rebase.\n+\t\t#   (use \"git commit --amend\" to amend the current commit)\n+\t\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t\t#\n+\t\tnothing to commit (use -u to show untracked files)\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual &&\n+\t\tgit rebase --abort\n+\t)\n+'\n+\n+\n+test_expect_success 'status in an am session: file already exists' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one main.txt \"one  \" &&\n+\t\tgit format-patch -1 -oMaildir &&\n+\t\ttest_must_fail git am Maildir/*.patch &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# On branch master\n+\t\t# You are in the middle of an am session.\n+\t\t#   (when you have fixed this problem run \"git am --resolved\")\n+\t\t#   (use \"git am --skip\" to skip this patch)\n+\t\t#   (use \"git am --abort\" to restore the original branch)\n+\t\t#\n+\t\tnothing to commit (use -u to show untracked files)\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+\n+test_expect_success 'status in an am session: file does not exist' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one main.txt \"one\" &&\n+\t\tgit rm main.txt &&\n+\t\tgit commit -m \"delete main.txt\" &&\n+\t\tgit format-patch -1 -oMaildir &&\n+\t\ttest_must_fail git am Maildir/*.patch &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# On branch master\n+\t\t# You are in the middle of an am session.\n+\t\t#   (when you have fixed this problem run \"git am --resolved\")\n+\t\t#   (use \"git am --skip\" to skip this patch)\n+\t\t#   (use \"git am --abort\" to restore the original branch)\n+\t\t#\n+\t\tnothing to commit (use -u to show untracked files)\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+\n+test_expect_success 'status in an am session: empty patch' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one one.txt \"one\" &&\n+\t\ttest_commit two two.txt \"two\" &&\n+\t\ttest_commit three three.txt \"three\" &&\n+\t\tgit format-patch -3 -oMaildir &&\n+\t\tgit rm one.txt two.txt three.txt &&\n+\t\tgit commit -m \"delete all\" &&\n+\t\techo error >Maildir/0002-two.patch &&\n+\t\ttest_must_fail git am Maildir/*.patch &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# On branch master\n+\t\t# You are in the middle of an am session.\n+\t\t# The current patch is empty; run \"git am --skip\" to skip it.\n+\t\t#   (use \"git am --abort\" to restore the original branch)\n+\t\t#\n+\t\tnothing to commit (use -u to show untracked files)\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one main.txt one &&\n+\t\ttest_commit two main.txt two &&\n+\t\ttest_commit three main.txt three &&\n+\t\tgit bisect start &&\n+\t\tgit bisect bad &&\n+\t\tgit bisect good one &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# Not currently on any branch.\n+\t\t# You are currently bisecting.\n+\t\t#   (use \"git bisect reset\" to get back to the original branch)\n+\t\t#\n+\t\tnothing to commit (use -u to show untracked files)\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushints disabled' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git\" &&\n+\t(\n+\t\tcd git &&\n+\t\tgit config --local advice.statushints false &&\n+\t\ttest_commit one main.txt one &&\n+\t\ttest_commit two main.txt two &&\n+\t\ttest_commit three main.txt three &&\n+\t\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# Not currently on any branch.\n+\t\t# You are currently rebasing.\n+\t\t#\n+\t\t# Unmerged paths:\n+\t\t#\tboth modified:      main.txt\n+\t\t#\n+\t\tno changes added to commit\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual\n+\t)\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\tgit init git &&\n+\tcd git &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\ttest_commit one main.txt one &&\n+\ttest_commit two main.txt two &&\n+\ttest_commit three main.txt three &&\n+\tgit checkout master &&\n+\ttest_must_fail git cherry-pick two &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\ttest_when_finished \"cd ../ && rm -rf git\"\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking.\n+\t#   (all conflicts fixed: run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192762","messageId":"1338748217-16440-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338748217-16440-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv6 3/4] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-03T18:30:16Z","receivedAt":"2012-06-03T18:30:16Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when there are\nunmerged files) after running 'git status' is now depending of the\nmark, whether it's 'both deleted', 'deleted by us/them' or others. For\ninstance, when there is just one file that's marked as 'both deleted',\n'git status' shows '(use git rm [...])' and if there are two files,\none as 'both deleted' and the other as 'added by them', the advice is\n'(use git add/rm [...])'.\n\nThe previous tests in t7512-status-help.sh are updated.\n\nTest about the case of only 'both deleted' is added in\nt7060-wtstatus.sh\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n---\n t/t7060-wtstatus.sh    |   25 +++++++++++++++++++++++++\n t/t7512-status-help.sh |    6 +++---\n wt-status.c            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 64 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex 61d1f38..442d340 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -185,4 +185,29 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n '\n \n \n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\ttest_when_finished \"cd ../ && rm -rf git\" &&\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n test_done\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex 5f62262..2bb43f3 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -28,7 +28,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -72,7 +72,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -270,7 +270,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\ndiff --git a/wt-status.c b/wt-status.c\nindex 2460e20..5034eee 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,34 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint del_mod_conflict = 0;\n+\tint both_deleted = 0;\n+\tint not_deleted = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tswitch (d->stagemask) {\n+\t\tcase 0:\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tboth_deleted = 1;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\tcase 5:\n+\t\t\tdel_mod_conflict = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tnot_deleted = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted) {\n+\t\tif (!del_mod_conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t} else if (!del_mod_conflict && !not_deleted) {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t}\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"192763","messageId":"1338748217-16440-4-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338748217-16440-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv6 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-03T18:30:17Z","receivedAt":"2012-06-03T18:30:17Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"Add new informative help messages at the output of 'git status' when\nthe user is splitting a commit. The code figures this state by\ncomparing the contents of the following files in the .git/ directory:\n\t  - HEAD\n\t  - ORIG_HEAD\n\t  - rebase-merge/amend\n\t  - rebase-merge/orig-head\n\nSigned-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n---\nThe second test added by this patch fails because the case in which\nthe user amend the last commit through rebase -i is not taken care of.\nWe infer that the user would directly run \"git commit --amend\" instead\nof amending it with a rebase -i.\n\n t/t7512-status-help.sh |   63 +++++++++++++++++++++++++++++++++++++++++++-\n wt-status.c            |   69 ++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 131 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex 2bb43f3..0b7f231 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -106,7 +106,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' '\n \n test_expect_success 'status when rebasing -i in edit mode' '\n \tgit init git &&\n-\ttest_when_finished \"rm -rf git fake-editor.sh\" &&\n+\ttest_when_finished \"rm -rf git\" &&\n \t(\n \t\tcd git &&\n \t\ttest_commit one main.txt one &&\n@@ -130,6 +130,67 @@ test_expect_success 'status when rebasing -i in edit mode' '\n '\n \n \n+test_expect_success 'status when splitting a commit' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one main.txt one &&\n+\t\ttest_commit two main.txt two &&\n+\t\ttest_commit three main.txt three &&\n+\t\ttest_commit four main.txt four &&\n+\t\tFAKE_LINES=\"1 edit 2 3\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~3 &&\n+\t\tgit reset HEAD^ &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# Not currently on any branch.\n+\t\t# You are currently splitting a commit.\n+\t\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t\t#\n+\t\t# Changes not staged for commit:\n+\t\t#   (use \"git add <file>...\" to update what will be committed)\n+\t\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t\t#\n+\t\t#\tmodified:   main.txt\n+\t\t#\n+\t\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual &&\n+\t\tgit rebase --abort\n+\t)\n+'\n+\n+\n+test_expect_failure 'status after editing the last commit with --amend during a rebase -i' '\n+\tgit init git &&\n+\ttest_when_finished \"rm -rf git fake-editor.sh\" &&\n+\t(\n+\t\tcd git &&\n+\t\ttest_commit one main.txt one &&\n+\t\ttest_commit two main.txt two &&\n+\t\ttest_commit three main.txt three &&\n+\t\ttest_commit four main.txt four &&\n+\t\tFAKE_LINES=\"1 2 edit 3\" &&\n+\t\texport FAKE_LINES &&\n+\t\tgit rebase -i HEAD~3 &&\n+\t\tgit commit --amend -m \"foo\" &&\n+\t\tcat >expected <<-\\EOF &&\n+\t\t# Not currently on any branch.\n+\t\t# You are currently editing a commit during a rebase.\n+\t\t#   (use \"git commit --amend\" to amend the current commit)\n+\t\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t\t#\n+\t\tnothing to commit (working directory clean)\n+\t\tEOF\n+\t\tgit status --untracked-files=no >actual &&\n+\t\ttest_cmp expected actual &&\n+\t\tgit rebase --abort\n+\t)\n+'\n+\n+\n test_expect_success 'status in an am session: file already exists' '\n \tgit init git &&\n \ttest_when_finished \"rm -rf git\" &&\ndiff --git a/wt-status.c b/wt-status.c\nindex 5034eee..bbb3370 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -12,6 +12,7 @@\n #include \"refs.h\"\n #include \"submodule.h\"\n #include \"column.h\"\n+#include \"strbuf.h\"\n \n static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n@@ -819,6 +820,69 @@ static void show_am_in_progress(struct wt_status *s,\n \twt_status_print_trailer(s);\n }\n \n+static int split_commit_in_progress()\n+{\n+\tint split_in_progress = 0;\n+\n+\tFILE *head = fopen(git_path(\"HEAD\"), \"r\");\n+\tif (!head)\n+\t\treturn 0;\n+\n+\tFILE *orig_head = fopen(git_path(\"ORIG_HEAD\"), \"r\");\n+\tif (!orig_head) {\n+\t\tfclose(head);\n+\t\treturn 0;\n+\t}\n+\n+\tFILE *rebase_amend = fopen(git_path(\"rebase-merge/amend\"), \"r\");\n+\tif (!rebase_amend) {\n+\t\tfclose(head);\n+\t\tfclose(orig_head);\n+\t\treturn 0;\n+\t}\n+\n+\tFILE *rebase_orig_head = fopen(git_path(\"rebase-merge/orig-head\"), \"r\");\n+\tif (!rebase_orig_head) {\n+\t\tfclose(head);\n+\t\tfclose(orig_head);\n+\t\tfclose(rebase_amend);\n+\t\treturn 0;\n+\t}\n+\n+\tstruct strbuf buf_head = STRBUF_INIT;\n+\tstruct strbuf buf_orig_head = STRBUF_INIT;\n+\tstruct strbuf buf_rebase_amend = STRBUF_INIT;\n+\tstruct strbuf buf_rebase_orig_head = STRBUF_INIT;\n+\n+\tstrbuf_getline(&buf_head, head, '\\n');\n+\tstrbuf_getline(&buf_orig_head, orig_head, '\\n');\n+\tstrbuf_getline(&buf_rebase_amend, rebase_amend, '\\n');\n+\tstrbuf_getline(&buf_rebase_orig_head, rebase_orig_head, '\\n');\n+\n+\tfclose(head);\n+\tfclose(orig_head);\n+\tfclose(rebase_amend);\n+\tfclose(rebase_orig_head);\n+\n+\tif (!strbuf_cmp(&buf_rebase_amend, &buf_rebase_orig_head)) {\n+\t\tif (strbuf_cmp(&buf_head, &buf_rebase_amend))\n+\t\t\tsplit_in_progress = 1;\n+\t} else if (!strbuf_cmp(&buf_orig_head, &buf_rebase_amend)) {\n+\t\tsplit_in_progress = 1;\n+\t} else if (strbuf_cmp(&buf_orig_head, &buf_rebase_orig_head)) {\n+\t\tsplit_in_progress = 1;\n+\t}\n+\n+\tif (!strbuf_cmp(&buf_head, &buf_rebase_amend))\n+\t\tsplit_in_progress = 0;\n+\n+\tstrbuf_release(&buf_head);\n+\tstrbuf_release(&buf_orig_head);\n+\tstrbuf_release(&buf_rebase_amend);\n+\tstrbuf_release(&buf_rebase_orig_head);\n+\treturn split_in_progress;\n+}\n+\n static void show_rebase_in_progress(struct wt_status *s,\n \t\t\t\tstruct wt_status_state *state,\n \t\t\t\tconst char *color)\n@@ -838,6 +902,11 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\tif (advice_status_hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else if (split_commit_in_progress()) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently splitting a commit.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (Once your working directory is clean, run \\\"git rebase --continue\\\")\"));\n \t} else {\n \t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n \t\tif (advice_status_hints && !s->amend) {\n-- \n1.7.8\n"},{"id":"192764","messageId":"vpq396cxk89.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338748217-16440-3-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv6 3/4] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-03T19:34:46Z","receivedAt":"2012-06-03T19:34:46Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n> +\ttest_when_finished \"cd ../ && rm -rf git\" &&\n\nIs it intentional that you kept this potentially dangerous \"cd ../ && rm\n-rf git\"? I saw you rewrote some instances in other patches, but not all\nof them.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192769","messageId":"7v7gvoyuk4.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338748217-16440-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv6 1/4] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-03T21:06:19Z","receivedAt":"2012-06-03T21:06:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index 915cb5a..670945d 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -162,6 +162,10 @@ advice.*::\n>  \t\tDirections on how to stage/unstage/add shown in the\n>  \t\toutput of linkgit:git-status[1] and the template shown\n>  \t\twhen writing commit messages.\n> +\t\tShow directions on how to proceed from the current\n> +\t\tstate in the output of linkgit:git-status[1] and in\n> +\t\tthe template shown when writing commit messages in\n> +\t\tlinkgit:git-commit[1].\n\nI meant these four lines to _replace_, not _add_.\n\nReading the three lines we can see in the context before this hunk,\ndon't you agree that they are now unnecessary because what they say\nis merely a subset of the four lines you added say?\n\n> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\n> index b8cb490..61d1f38 100755\n> --- a/t/t7060-wtstatus.sh\n> +++ b/t/t7060-wtstatus.sh\n> @@ -118,4 +121,68 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n> ...\n> +test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n> +\tgit init git &&\n> +\tcd git &&\n> +\ttest_commit init main.txt init &&\n\nPlease do not chdir around outside a subshell.\n\n\"This is the last test in this script\" is not an excuse, as that\nwill forbid others from improving the script by adding new ones\nlater.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index dd6d8c4..2460e20 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -728,6 +729,169 @@ static void wt_status_print_tracking(struct wt_status *s)\n> ...\n> +static void show_merge_in_progress(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tif (has_unmerged(s)) {\n> +\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n> +\t\tif (advice_status_hints)\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n> +\t} else {\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"All conflicts fixed but you are still merging.\"));\n\nThanks for rephrasing; this reads much easier.\n\n> +static void show_am_in_progress(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tstatus_printf_ln(s, color,\n> +\t\t_(\"You are in the middle of an am session.\"));\n> +\tif (state->am_empty_patch) {\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"The current patch is empty; run \\\"git am --skip\\\" to skip it.\"));\n\nIsn't everything after \"; \" an advice?\n\n> +\t\tif (advice_status_hints)\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n> +\t} else if (advice_status_hints) {\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  (when you have fixed this problem run \\\"git am --resolved\\\")\"));\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n> +\t}\n\nI think the structure can simply be:\n\n\tif (am_empty_patch)\n\t\t\"The current patch is empty.\";\n\tif (advice_status_hints) {\n\t\t\"  (use --abort to restore)\";\n\t\t\"  (use --skip to skip)\";\n                if (!am_empty_patch)\n\t\t\t\"  (use --resolved after you are done)\";\n\t}\n\nNote that I am not suggesting to change the wording of the message\nin the above; just showing the flow-structure.\n\nAlso when you are in the middle of \"git am -3\", there may be\nunmerged entries in the index; do we want to suggest \"add/rm\" to\nresolve to fill in the missing detail of \"fix\" in your \"when you\nhave fixed this problem\" message?\n\nWe may want to decide how detailed we want to make the help texts;\nthe same fuzziness exists in \"fix conflicts and then\" at the\nbeginning of show_rebase_in_progress().\n\n> +static void show_rebase_in_progress(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tif (has_unmerged(s)) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n> +\t\tif (advice_status_hints) {\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n> +\t\t}\n> +\t} else if (state->rebase_in_progress) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n> +\t\tif (advice_status_hints)\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n> +\t} else {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n> +\t\tif (advice_status_hints && !s->amend) {\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied with your changes)\"));\n> +\t\t}\n\nThis last \"else\" block is taken when running \"rebase -i\" and there\nis no longer any unmerged index entry.  I wonder if the message from\nthe first printf_ln needs to be clarified further depending on the\ncontext.\n\nSpecifically, in this sequence:\n\n\t- the user marked a commit as \"pick\";\n        - replaying of that commit resulted in conflicts;\n        - the user edited files and used add/rm to resolve conflicts;\n        - the user did one of these:\n\t  1. \"git status\"\n          2. \"git commit\" without \"--amend\"\n          3. \"git commit --amend\"\n\ncan this message come up?\n\nIn such a case, \"You are currently editing a commit\" is actively\nwrong.  The user has finished resolving the conflict and are about\nto record the result.  Also, \"git status\" and \"git commit\" without\n\"--amend\" are both sensible commands in this situation, but running\n\"git commit --amend\" is likely to be a mistake, no?\n\n\tSide note: I am not absolutely sure if \"--amend\" is always a\n\tmistake in this situation; I'd very much appreciate users\n\twho creatively use \"rebase -i\" in real life to offer valid\n\tuses of \"commit --amend\" in this scenario.\n\n> +static void show_cherry_pick_in_progress(struct wt_status *s,\n> +\t\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\t\tconst char *color)\n> +{\n> +\tif (has_unmerged(s)) {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n> +\t\tif (advice_status_hints)\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n> +\t} else {\n> +\t\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n> +\t\tif (advice_status_hints)\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (all conflicts fixed: run \\\"git commit\\\")\"));\n> +\t}\n\nThe current status is the same in either arm of if/else; shouldn't\nthey be lifted outside, i.e.\n\n\t\"You are currently cherry-picking\";\n        if (advice_status_hints) {\n        \tif (has_unmerged(s))\n\t\t\t\"  (fix conflicts ...)\";\n\t\telse\n                \t\"  (all fixed, run ...)\";\n\t}\n\nThe rest of this patch I did not quote looked all very much\nsensible.\n\nThanks.\n"},{"id":"192770","messageId":"7vvcj8xffp.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338748217-16440-2-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv6 2/4] t7512-status-help.sh: better advices for git status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-03T21:18:18Z","receivedAt":"2012-06-03T21:18:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> The following tests include several cases in which the user needs to\n> run 'git status' to know his current situation, whether there're\n> conflicts or he's in rebase/bisect/am/ cherry-pick progress.\n>\n> One of the test is about the set of the advice.statushints config key\n> to 'false' in .git/config.\n>\n> Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n> Signed-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\n> Signed-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\n> Signed-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\n> Signed-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n> Signed-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n\nAre these spelling of names correct?\n\nI thought Matthieu always called himself \"Matthieu Moy\", not the\nother way around.  I also inferred the convention used for naming\nthe mailboxes at your institution to be \"$First.$Last@$Domain\",\nwhich tells me that perhaps these names are all spelled backwards,\ni.e. \"$Last $First\", which probably goes against the convention used\naround you and Matthieu?\n\n> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\n> new file mode 100755\n> index 0000000..5f62262\n> --- /dev/null\n> +++ b/t/t7512-status-help.sh\n> @@ -0,0 +1,303 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n> +#\t\t     Thomas Nguy, Khoi Nguyen\n> +#\t\t     Grenoble INP Ensimag\n> +#\n> +\n> +test_description='git status advices'\n> +\n> +. ./test-lib.sh\n> +\n> +. \"$TEST_DIRECTORY\"/lib-rebase.sh\n> +\n> +set_fake_editor\n> +\n> +test_expect_success 'status when conflicts unresolved' '\n> +\tgit init git &&\n> +\tcd git &&\n\nEek.\n\nLater tests seem to use\n\n\tgit init git &&\n\t(\n\t\tcd git &&\n                ... everything is done inside git subdirectory ...\n\t)\n\nwith either \"test_when_finished 'rm -fr git'\" clean-up before the\nfirst \"git init git\" or \"&& rm -fr git\" at the end of the && chain.\n\nPlease be consistent.  If you want _me_ to pick one, I'd say\n\n\ttest_when_finished 'rm -fr git' &&\n        git init git &&\n        (\n        \tcd git &&\n                ... do everything in git subdirectory ...\n\t)\n\nwould be my choice.\n\n> +test_expect_success 'status when rebase in progress before rebase --continue' '\n> +\ttest_when_finished \"cd ../ && rm -rf git\" &&\n\nI've said why this is wrong; I won't repeat it.\n"},{"id":"192775","messageId":"7v7gvoxdi2.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338748217-16440-4-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv6 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-03T22:00:05Z","receivedAt":"2012-06-03T22:00:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\n> index 2bb43f3..0b7f231 100755\n> --- a/t/t7512-status-help.sh\n> +++ b/t/t7512-status-help.sh\n> @@ -106,7 +106,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' '\n>  \n>  test_expect_success 'status when rebasing -i in edit mode' '\n>  \tgit init git &&\n> -\ttest_when_finished \"rm -rf git fake-editor.sh\" &&\n> +\ttest_when_finished \"rm -rf git\" &&\n\nHrph.  Is this an \"oops\" fixup of an earlier patch?\n\n> @@ -130,6 +130,67 @@ test_expect_success 'status when rebasing -i in edit mode' '\n> ...\n> +test_expect_failure 'status after editing the last commit with --amend during a rebase -i' '\n> +\tgit init git &&\n> +\ttest_when_finished \"rm -rf git fake-editor.sh\" &&\n\nYou do not seem to remove fake-editor.sh in this test.  Why do you\nremove it here?\n\n> diff --git a/wt-status.c b/wt-status.c\n> index 5034eee..bbb3370 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -819,6 +820,69 @@ static void show_am_in_progress(struct wt_status *s,\n>  \twt_status_print_trailer(s);\n>  }\n>  \n> +static int split_commit_in_progress()\n> +{\n> +\tint split_in_progress = 0;\n> +\n> +\tFILE *head = fopen(git_path(\"HEAD\"), \"r\");\n> +\tif (!head)\n> +\t\treturn 0;\n> +\n> ...\n> +\tstruct strbuf buf_head = STRBUF_INIT;\n> +\tstruct strbuf buf_orig_head = STRBUF_INIT;\n> +\tstruct strbuf buf_rebase_amend = STRBUF_INIT;\n> +\tstruct strbuf buf_rebase_orig_head = STRBUF_INIT;\n\n\nPlease avoid decl-after-statement by declaring all variables at the\nbeginning of the function before the first statement.\n"},{"id":"192790","messageId":"20120604115110.Horde.CoZeVXwdC4BPzIUOb8j18yA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7v7gvoyuk4.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv6 1/4] wt-status.*: better advices for git status added","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-04T09:51:10Z","receivedAt":"2012-06-04T09:51:10Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n>> +\t\tif (advice_status_hints)\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n>> +\t} else if (advice_status_hints) {\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  (when you have fixed this problem run \\\"git am --resolved\\\")\"));\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n>> +\t}\n>\n> I think the structure can simply be:\n>\n> \tif (am_empty_patch)\n> \t\t\"The current patch is empty.\";\n> \tif (advice_status_hints) {\n> \t\t\"  (use --abort to restore)\";\n> \t\t\"  (use --skip to skip)\";\n>                 if (!am_empty_patch)\n> \t\t\t\"  (use --resolved after you are done)\";\n> \t}\n>\n> Note that I am not suggesting to change the wording of the message\n> in the above; just showing the flow-structure.\n>\n> Also when you are in the middle of \"git am -3\", there may be\n> unmerged entries in the index; do we want to suggest \"add/rm\" to\n> resolve to fill in the missing detail of \"fix\" in your \"when you\n> have fixed this problem\" message?\n>\n> We may want to decide how detailed we want to make the help texts;\n> the same fuzziness exists in \"fix conflicts and then\" at the\n> beginning of show_rebase_in_progress().\n\nIn fact, to detail more \"fix\" in this case by suggesting \"add/rm\"\nwould be repetitive, as this advice is already given under the block\n\"unmerged paths\":\n\n# Not currently on any branch.\n# You are currently rebasing.\n#   (fix conflicts and then run \"git rebase --continue\")\n#   (use \"git rebase --skip\" to skip this patch)\n#   (use \"git rebase --abort\" to check out the original branch)\n#\n# Unmerged paths:\n#   (use \"git reset HEAD <file>...\" to unstage)\n#   (use \"git add <file>...\" to mark resolution)\n#\n#\tboth modified:      main.txt\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\n>> +static void show_rebase_in_progress(struct wt_status *s,\n>> +\t\t\t\tstruct wt_status_state *state,\n>> +\t\t\t\tconst char *color)\n>> +{\n>> +\tif (has_unmerged(s)) {\n>> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n>> +\t\tif (advice_status_hints) {\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n>\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n>> +\t\t}\n>> +\t} else if (state->rebase_in_progress) {\n>> +\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n>> +\t\tif (advice_status_hints)\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n>> +\t} else {\n>> +\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit  \n>> during a rebase.\"));\n>> +\t\tif (advice_status_hints && !s->amend) {\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied  \n>> with your changes)\"));\n>> +\t\t}\n>\n> This last \"else\" block is taken when running \"rebase -i\" and there\n> is no longer any unmerged index entry.  I wonder if the message from\n> the first printf_ln needs to be clarified further depending on the\n> context.\n>\n> Specifically, in this sequence:\n>\n> \t- the user marked a commit as \"pick\";\n>         - replaying of that commit resulted in conflicts;\n>         - the user edited files and used add/rm to resolve conflicts;\n>         - the user did one of these:\n> \t  1. \"git status\"\n>           2. \"git commit\" without \"--amend\"\n>           3. \"git commit --amend\"\n>\n> can this message come up?\n>\n> In such a case, \"You are currently editing a commit\" is actively\n> wrong.  The user has finished resolving the conflict and are about\n> to record the result.  Also, \"git status\" and \"git commit\" without\n> \"--amend\" are both sensible commands in this situation, but running\n> \"git commit --amend\" is likely to be a mistake, no?\n\nTrue, the last \"else\" block is not supposed to be taken. The correct\nmessage that should be displayed is the first \"else if\" block, saying\njust that all conflicts are fixed and to run rebase --continue.\n"},{"id":"192791","messageId":"20120604120406.Horde.ge3VMHwdC4BPzIgWN72l8oA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7vvcj8xffp.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv6 2/4] t7512-status-help.sh: better advices for git status","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-04T10:04:06Z","receivedAt":"2012-06-04T10:04:06Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n> I thought Matthieu always called himself \"Matthieu Moy\", not the\n> other way around.  I also inferred the convention used for naming\n> the mailboxes at your institution to be \"$First.$Last@$Domain\",\n> which tells me that perhaps these names are all spelled backwards,\n> i.e. \"$Last $First\", which probably goes against the convention used\n> around you and Matthieu?\n\nHm, yeah it's spelled backwards, I didn't take notice of that.\n\n>> +. ./test-lib.sh\n>> +\n>> +. \"$TEST_DIRECTORY\"/lib-rebase.sh\n>> +\n>> +set_fake_editor\n>> +\n>> +test_expect_success 'status when conflicts unresolved' '\n>> +\tgit init git &&\n>> +\tcd git &&\n>\n> Eek.\n>\n> Later tests seem to use\n>\n> \tgit init git &&\n> \t(\n> \t\tcd git &&\n>                 ... everything is done inside git subdirectory ...\n> \t)\n>\n> with either \"test_when_finished 'rm -fr git'\" clean-up before the\n> first \"git init git\" or \"&& rm -fr git\" at the end of the && chain.\n>\n> Please be consistent.  If you want _me_ to pick one, I'd say\n>\n> \ttest_when_finished 'rm -fr git' &&\n>         git init git &&\n>         (\n>         \tcd git &&\n>                 ... do everything in git subdirectory ...\n> \t)\n>\n> would be my choice.\n\nBtw, should each test be independant with the others ? We saw that there\nare already a lot of tests that are dependant. In this case, can we apply\nthis method with the parenthesis ?\n\nWouldn't it be better if we remove the \"git init git\" part?\n"},{"id":"192806","messageId":"7vfwabunzq.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120604115110.Horde.CoZeVXwdC4BPzIUOb8j18yA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv6 1/4] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-04T14:54:01Z","receivedAt":"2012-06-04T14:54:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n> Junio C Hamano <gitster@pobox.com> a écrit:\n> ...\n>>\n>> Also when you are in the middle of \"git am -3\", there may be\n>> unmerged entries in the index; do we want to suggest \"add/rm\" to\n>> resolve to fill in the missing detail of \"fix\" in your \"when you\n>> have fixed this problem\" message?\n>>\n>> We may want to decide how detailed we want to make the help texts;\n>> the same fuzziness exists in \"fix conflicts and then\" at the\n>> beginning of show_rebase_in_progress().\n>\n> In fact, to detail more \"fix\" in this case by suggesting \"add/rm\"\n> would be repetitive, as this advice is already given under the block\n> \"unmerged paths\":\n\nOK, then I agree that \"resolve and do X\" is a sufficient level of\ndetail for these messages.\n\n>> This last \"else\" block is taken when running \"rebase -i\" and there\n>> is no longer any unmerged index entry.  I wonder if the message from\n>> the first printf_ln needs to be clarified further depending on the\n>> context.\n>>\n>> Specifically, in this sequence:\n>>\n>> \t- the user marked a commit as \"pick\";\n>>         - replaying of that commit resulted in conflicts;\n>>         - the user edited files and used add/rm to resolve conflicts;\n>>         - the user did one of these:\n>> \t  1. \"git status\"\n>>           2. \"git commit\" without \"--amend\"\n>>           3. \"git commit --amend\"\n>>\n>> can this message come up?\n>>\n>> In such a case, \"You are currently editing a commit\" is actively\n>> wrong.  The user has finished resolving the conflict and are about\n>> to record the result.  Also, \"git status\" and \"git commit\" without\n>> \"--amend\" are both sensible commands in this situation, but running\n>> \"git commit --amend\" is likely to be a mistake, no?\n>\n> True, the last \"else\" block is not supposed to be taken. The correct\n> message that should be displayed is the first \"else if\" block, saying\n> just that all conflicts are fixed and to run rebase --continue.\n\nOK, so this part still needs a bit more work, then.\n\nThanks.\n"},{"id":"192807","messageId":"7vbokzunid.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120604120406.Horde.ge3VMHwdC4BPzIgWN72l8oA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv6 2/4] t7512-status-help.sh: better advices for git status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-04T15:04:26Z","receivedAt":"2012-06-04T15:04:26Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n> Junio C Hamano <gitster@pobox.com>:\n> ...\n>> Please be consistent.  If you want _me_ to pick one, I'd say\n>>\n>> \ttest_when_finished 'rm -fr git' &&\n>>         git init git &&\n>>         (\n>>         \tcd git &&\n>>                 ... do everything in git subdirectory ...\n>> \t)\n>>\n>> would be my choice.\n>\n> Btw, should each test be independant with the others?\n\nIt would be ideal if you can make them independent with each other,\nso that after one fails, later ones do not have to.\n\n> Wouldn't it be better if we remove the \"git init git\" part?\n\nIf you do not need to keep your tests from using the test repository\nin $TRASH_DIRECTORY (e.g. \"t/trash directory.t7512-status-help\"),\nyou do not have to create a new one with \"git init\".\n"},{"id":"192808","messageId":"CABURp0pD-QuAsDAJXnQXn3sTLb__maw0Mc30PHhduTZ9YOB1FQ@mail.gmail.com","threadId":"30608","inReplyTo":"1338748217-16440-4-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv6 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-04T15:35:50Z","receivedAt":"2012-06-04T15:35:50Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Sun, Jun 3, 2012 at 2:30 PM, Kong Lucien <Lucien.Kong@ensimag.imag.fr> wrote:\n> Add new informative help messages at the output of 'git status' when\n> the user is splitting a commit. The code figures this state by\n> comparing the contents of the following files in the .git/ directory:\n>          - HEAD\n>          - ORIG_HEAD\n>          - rebase-merge/amend\n>          - rebase-merge/orig-head\n>\n> Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n> Signed-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\n> Signed-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\n> Signed-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\n> Signed-off-by: Nguyen Huynh Khoi Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n> Signed-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n> ---\n> The second test added by this patch fails because the case in which\n> the user amend the last commit through rebase -i is not taken care of.\n> We infer that the user would directly run \"git commit --amend\" instead\n> of amending it with a rebase -i.\n\n\nMaybe this is safe and logical for most workflows, or maybe this is a\nconvenience that makes this patch possible (I did not read the patch\nyet).  But I know that I sometimes use rebase-i instead of\ncommit--amend because I did not realize the patch I am fixing is the\nmost recent one until after continuing, or because the patch I am\namending was moved into the most-recent position during the rebase-i\nitself.\n\nJust a note to consider, in case this decision was made arbitrarily.\n\nThanks for looking after these kinds of corner cases.\n\nPhil\n"},{"id":"192820","messageId":"1338830399-31504-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338748217-16440-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv7 1/4] wt-status.*: better advices for git status added","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-04T17:19:56Z","receivedAt":"2012-06-04T17:19:56Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new informative help messages in the display of\n'git status' (at the top) during conflicts, rebase, am, bisect or\ncherry-pick process.\n\nThe new messages are not shown when using options such as -s or\n--porcelain. The messages about the current situation of the user are\nalways displayed but the advices on what the user needs to do in order\nto resume a rebase/bisect/am/commit after resolving conflicts can be\nhidden by setting advice.statushints to 'false' in the config file.\n\nThus, information about the updated advice.statushints key are added\nin Documentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the new help\nmessages. Tests about suggestions of \"git rm\" are also added.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThe case of conflicts during a rebase -i is now taken care of. The form\nof the tests has also been modified.\n\n Documentation/config.txt |    7 +-\n t/t7060-wtstatus.sh      |   64 ++++++++++++++++++\n wt-status.c              |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 4 files changed, 242 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..ccce4f6 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -159,9 +159,10 @@ advice.*::\n \t\tspecified a refspec that isn't your current branch) and\n \t\tit resulted in a non-fast-forward error.\n \tstatusHints::\n-\t\tDirections on how to stage/unstage/add shown in the\n-\t\toutput of linkgit:git-status[1] and the template shown\n-\t\twhen writing commit messages.\n+\t\tShow directions on how to proceed from the current\n+\t\tstate in the output of linkgit:git-status[1] and in\n+\t\tthe template shown when writing commit messages in\n+\t\tlinkgit:git-commit[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..4326df7 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths.\n+#   (fix conflicts and run \"git commit\")\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\n@@ -118,4 +121,65 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n \ttest_cmp expected actual\n '\n \n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit reset --hard &&\n+\tgit checkout master &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\ttest_commit second conflict.txt second &&\n+\tgit checkout master &&\n+\ttest_commit on_second main.txt on_second &&\n+\ttest_commit master conflict.txt master &&\n+\ttest_must_fail git merge second_branch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         conflict.txt\n+\t#\tdeleted by them:    main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit reset --hard &&\n+\tgit checkout -b conflict &&\n+\ttest_commit one main.txt one &&\n+\tgit branch conflict_second &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout conflict_second &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge conflict &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..2b19fe3 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,167 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int has_unmerged(struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+static void show_merge_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"All conflicts fixed but you are still merging.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit\\\" to conclude merge)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_am_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are in the middle of an am session.\"));\n+\tif (state->am_empty_patch)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"The current patch is empty.\"));\n+\tif (advice_status_hints) {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n+\t\tif (!state->am_empty_patch)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (when you have fixed this problem run \\\"git am --resolved\\\")\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_rebase_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstruct stat st;\n+\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n+\t\t}\n+\t} else if (state->rebase_in_progress || !stat(git_path(\"MERGE_MSG\"), &st)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_hints && !s->amend) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied with your changes)\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_cherry_pick_in_progress(struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n+\tif (advice_status_hints) {\n+\t\tif (has_unmerged(s))\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git commit\\\")\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_bisect_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_hints)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git bisect reset\\\" to get back to the original branch)\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_print_state(struct wt_status *s)\n+{\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st)) {\n+\t\tstate->merge_in_progress = 1;\n+\t} else if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !st.st_size)\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t} else {\n+\t\t\tstate->rebase_in_progress = 1;\n+\t\t}\n+\t} else if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t} else if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st)) {\n+\t\tstate->cherry_pick_in_progress = 1;\n+\t}\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+\n+\tif (state->merge_in_progress)\n+\t\tshow_merge_in_progress(s, state, state_color);\n+\telse if (state->am_in_progress)\n+\t\tshow_am_in_progress(s, state, state_color);\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n+\t\tshow_rebase_in_progress(s, state, state_color);\n+\telse if (state->cherry_pick_in_progress)\n+\t\tshow_cherry_pick_in_progress(s, state, state_color);\n+\tif (state->bisect_in_progress)\n+\t\tshow_bisect_in_progress(s, state, state_color);\n+\tfree(state);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +912,7 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_state(s);\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"192819","messageId":"1338830399-31504-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338830399-31504-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv7 2/4] t7512-status-help.sh: better advices for git status","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-04T17:19:57Z","receivedAt":"2012-06-04T17:19:57Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user needs to\nrun 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am/cherry-pick progress.\n\nOne of the test is about the set of the advice.statushints config key\nto 'false' in .git/config.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThe form of the tests has been modified.\n\n t/t7512-status-help.sh |  346 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 346 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-help.sh\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nnew file mode 100755\nindex 0000000..53d0e05\n--- /dev/null\n+++ b/t/t7512-status-help.sh\n@@ -0,0 +1,346 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\ttest_commit init main.txt init &&\n+\tgit branch second_branch &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit on_second_branch main.txt on_second_branch &&\n+\ttest_must_fail git merge master &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch second_branch\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\ttest_when_finished \"\n+\t\tgit commit -m \"end_merge\" &&\n+\t\tgit checkout master &&\n+\t\tgit branch -D second_branch &&\n+\t\techo >main.txt\n+\t\" &&\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch second_branch\n+\t# All conflicts fixed but you are still merging.\n+\t#   (use \"git commit\" to conclude merge)\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\ttest_commit one_rebase main.txt one &&\n+\ttest_commit two_rebase main.txt two &&\n+\ttest_commit three_rebase main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status during rebase -i when conflicts unresolved' '\n+\ttest_commit one_unmerge main.txt one_unmerge &&\n+\tgit branch second_branch &&\n+\ttest_commit one_master main.txt one_master &&\n+\tgit checkout second_branch &&\n+\ttest_commit one_second main.txt one_second &&\n+\ttest_must_fail git rebase -i master &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status during rebase -i after resolving conflicts' '\n+\ttest_when_finished \"\n+\t\tgit rebase --abort &&\n+\t\tgit checkout master &&\n+\t\tgit branch -D second_branch\n+\t\" &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_commit one_rebase_i main.txt one &&\n+\ttest_commit two_rebase_i main.txt two &&\n+\ttest_commit three_rebase_i main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: file already exists' '\n+\ttest_when_finished \"\n+\t\tgit am --abort &&\n+\t\trm -r Maildir/\n+\t\" &&\n+\ttest_commit one_am main.txt \"one  \" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are in the middle of an am session.\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (when you have fixed this problem run \"git am --resolved\")\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: file does not exist' '\n+\ttest_when_finished \"\n+\t\tgit am --abort &&\n+\t\trm -r Maildir/\n+\t\" &&\n+\ttest_commit two_am main.txt \"two\" &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"delete main.txt\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are in the middle of an am session.\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (when you have fixed this problem run \"git am --resolved\")\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: empty patch' '\n+\ttest_when_finished \"\n+\t\tgit am --abort &&\n+\t\trm -r Maildir/\n+\t\" &&\n+\ttest_commit one_am_empty one.txt \"one\" &&\n+\ttest_commit two_am_empty two.txt \"two\" &&\n+\ttest_commit three_am_empty three.txt \"three\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all am_empty\" &&\n+\techo error >Maildir/0002-two_am_empty.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are in the middle of an am session.\n+\t# The current patch is empty.\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\ttest_when_finished \"git bisect reset\" &&\n+\ttest_commit one_bisect main.txt one &&\n+\ttest_commit two_bisect main.txt two &&\n+\ttest_commit three_bisect main.txt three &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one_bisect &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t#   (use \"git bisect reset\" to get back to the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushints disabled' '\n+\ttest_when_finished \"\n+\t\tgit rebase --abort &&\n+\t\tgit config --local advice.statushints true\n+\t\" &&\n+\tgit config --local advice.statushints false &&\n+\ttest_commit one_statushints main.txt one &&\n+\ttest_commit two_statushints main.txt two &&\n+\ttest_commit three_statushints main.txt three &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\tgit checkout -b cherry_branch &&\n+\ttest_commit one_cherry main.txt one &&\n+\ttest_commit two_cherries main.txt two &&\n+\ttest_commit three_cherries main.txt three &&\n+\tgit checkout master &&\n+\ttest_must_fail git cherry-pick two_cherries &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\ttest_when_finished \"\n+\t\tgit cherry-pick --abort\n+\t\tgit branch -D cherry_branch\n+\t\" &&\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You are currently cherry-picking.\n+\t#   (all conflicts fixed: run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192817","messageId":"1338830399-31504-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338830399-31504-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv7 3/4] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-04T17:19:58Z","receivedAt":"2012-06-04T17:19:58Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when there are\nunmerged files) after running 'git status' is now depending of the\nmark, whether it's 'both deleted', 'deleted by us/them' or others. For\ninstance, when there is just one file that's marked as 'both deleted',\n'git status' shows '(use git rm [...])' and if there are two files,\none as 'both deleted' and the other as 'added by them', the advice is\n'(use git add/rm [...])'.\n\nThe previous tests in t7512-status-help.sh are updated.\n\nTest about the case of only 'both deleted' is added in\nt7060-wtstatus.sh\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n t/t7060-wtstatus.sh    |   26 ++++++++++++++++++++++++++\n t/t7512-status-help.sh |    8 ++++----\n wt-status.c            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 66 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex 4326df7..1e6ec37 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -182,4 +182,30 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n '\n \n \n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual &&\n+\tgit reset --hard &&\n+\tgit checkout master\n+'\n+\n+\n test_done\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex 53d0e05..e52a05a 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -26,7 +26,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -124,7 +124,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -310,7 +310,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\ndiff --git a/wt-status.c b/wt-status.c\nindex 2b19fe3..3a2b787 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,34 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint del_mod_conflict = 0;\n+\tint both_deleted = 0;\n+\tint not_deleted = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tswitch (d->stagemask) {\n+\t\tcase 0:\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tboth_deleted = 1;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\tcase 5:\n+\t\t\tdel_mod_conflict = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tnot_deleted = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted) {\n+\t\tif (!del_mod_conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t} else if (!del_mod_conflict && !not_deleted) {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t}\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"192818","messageId":"1338830399-31504-4-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338830399-31504-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv7 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Kong Lucien","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-04T17:19:59Z","receivedAt":"2012-06-04T17:19:59Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"Add new informative help messages at the output of 'git status' when\nthe user is splitting a commit. The code figures this state by\ncomparing the contents of the following files in the .git/ directory:\n\t  - HEAD\n\t  - ORIG_HEAD\n\t  - rebase-merge/amend\n\t  - rebase-merge/orig-head\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThis part of the patch is the same as the one in the v6. The code has not\nbeen modified.\n\n t/t7512-status-help.sh |   51 +++++++++++++++++++++++++++++++\n wt-status.c            |   77 ++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 128 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex e52a05a..413808e 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -180,6 +180,57 @@ test_expect_success 'status when rebasing -i in edit mode' '\n '\n \n \n+test_expect_success 'status when splitting a commit' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_commit one_split main.txt one &&\n+\ttest_commit two_split main.txt two &&\n+\ttest_commit three_split main.txt three &&\n+\ttest_commit four_split main.txt four &&\n+\tFAKE_LINES=\"1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n+test_expect_failure 'status after editing the last commit with --amend during a rebase -i' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_commit one_amend main.txt one &&\n+\ttest_commit two_amend main.txt two &&\n+\ttest_commit three_amend main.txt three &&\n+\ttest_commit four_amend main.txt four &&\n+\tFAKE_LINES=\"1 2 edit 3\" &&\n+\texport FAKE_LINES &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"foo\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (working directory clean)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+\n test_expect_success 'status in an am session: file already exists' '\n \ttest_when_finished \"\n \t\tgit am --abort &&\ndiff --git a/wt-status.c b/wt-status.c\nindex 3a2b787..2016b12 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -12,6 +12,7 @@\n #include \"refs.h\"\n #include \"submodule.h\"\n #include \"column.h\"\n+#include \"strbuf.h\"\n \n static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n@@ -817,6 +818,77 @@ static void show_am_in_progress(struct wt_status *s,\n \twt_status_print_trailer(s);\n }\n \n+static int split_commit_in_progress()\n+{\n+\tFILE *head;\n+\tstruct strbuf buf_head;\n+\tFILE *orig_head;\n+\tstruct strbuf buf_orig_head;\n+\tFILE *rebase_amend;\n+\tstruct strbuf buf_rebase_amend;\n+\tFILE *rebase_orig_head;\n+\tstruct strbuf buf_rebase_orig_head;\n+\tint split_in_progress = 0;\n+\n+\thead = fopen(git_path(\"HEAD\"), \"r\");\n+\tif (!head)\n+\t\treturn 0;\n+\n+\torig_head = fopen(git_path(\"ORIG_HEAD\"), \"r\");\n+\tif (!orig_head) {\n+\t\tfclose(head);\n+\t\treturn 0;\n+\t}\n+\n+\trebase_amend = fopen(git_path(\"rebase-merge/amend\"), \"r\");\n+\tif (!rebase_amend) {\n+\t\tfclose(head);\n+\t\tfclose(orig_head);\n+\t\treturn 0;\n+\t}\n+\n+\trebase_orig_head = fopen(git_path(\"rebase-merge/orig-head\"), \"r\");\n+\tif (!rebase_orig_head) {\n+\t\tfclose(head);\n+\t\tfclose(orig_head);\n+\t\tfclose(rebase_amend);\n+\t\treturn 0;\n+\t}\n+\n+\tstrbuf_init(&buf_head, 0);\n+\tstrbuf_init(&buf_orig_head, 0);\n+\tstrbuf_init(&buf_rebase_amend, 0);\n+\tstrbuf_init(&buf_rebase_orig_head, 0);\n+\n+\tstrbuf_getline(&buf_head, head, '\\n');\n+\tstrbuf_getline(&buf_orig_head, orig_head, '\\n');\n+\tstrbuf_getline(&buf_rebase_amend, rebase_amend, '\\n');\n+\tstrbuf_getline(&buf_rebase_orig_head, rebase_orig_head, '\\n');\n+\n+\tfclose(head);\n+\tfclose(orig_head);\n+\tfclose(rebase_amend);\n+\tfclose(rebase_orig_head);\n+\n+\tif (!strbuf_cmp(&buf_rebase_amend, &buf_rebase_orig_head)) {\n+\t\tif (strbuf_cmp(&buf_head, &buf_rebase_amend))\n+\t\t\tsplit_in_progress = 1;\n+\t} else if (!strbuf_cmp(&buf_orig_head, &buf_rebase_amend)) {\n+\t\tsplit_in_progress = 1;\n+\t} else if (strbuf_cmp(&buf_orig_head, &buf_rebase_orig_head)) {\n+\t\tsplit_in_progress = 1;\n+\t}\n+\n+\tif (!strbuf_cmp(&buf_head, &buf_rebase_amend))\n+\t\tsplit_in_progress = 0;\n+\n+\tstrbuf_release(&buf_head);\n+\tstrbuf_release(&buf_orig_head);\n+\tstrbuf_release(&buf_rebase_amend);\n+\tstrbuf_release(&buf_rebase_orig_head);\n+\treturn split_in_progress;\n+}\n+\n static void show_rebase_in_progress(struct wt_status *s,\n \t\t\t\tstruct wt_status_state *state,\n \t\t\t\tconst char *color)\n@@ -838,6 +910,11 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\tif (advice_status_hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else if (split_commit_in_progress()) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently splitting a commit.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (Once your working directory is clean, run \\\"git rebase --continue\\\")\"));\n \t} else {\n \t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n \t\tif (advice_status_hints && !s->amend) {\n-- \n1.7.8\n"},{"id":"192832","messageId":"CABURp0r0R0fDFEYqUbv9OLJ8eOsVuFRi3yO_Xjdmo638JZ4uGg@mail.gmail.com","threadId":"30608","inReplyTo":"7vy5o72cnm.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv5 1/3] wt-status.*: better advices for git status added","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2012-06-04T18:00:26Z","receivedAt":"2012-06-04T18:00:26Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Fri, Jun 1, 2012 at 12:57 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Phil Hord <phil.hord@gmail.com> writes:\n>\n>>   $ git status --sequencer\n>>   You have unmerged paths.\n>>   You are in an am session.\n>>   You are in the middle of an interactive rebase.\n>>\n>>   $ git status --porcelain --sequencer\n>>   airu\n>>\n>> The \"--porcelain --sequencer\" combination I am imagining here would\n>> show the status as a script-parseable sequence of single-letter\n>> indicators telling the status of these same various conditions:\n>>   u - unmerged paths\n>>   a - git-am session\n>>   i - interactive rebase\n>>   r - rebase\n>>   c - cherry-pick\n>>   m - merge\n>> etc.\n>\n> Some people seem to think that machine-readable has to mean\n> unreadable cryptic line noises.  It's a disease.\n>\n> If you have to write \"etc.\", you clearly do not know what the\n> range of possible values of these things will eventually be.\n>\n> And I do not think it is your fault not to know what we would want\n> to add in the future.  But it is your fault to choose unreadable\n> cryptic line noises as an output format.\n>\n> Just spell them out, and do not mark them for translation.\n\nI agree.  And I waffled a bit between single-letter indicators,\nabbreviated token-words, and fully spelled out words as you suggested.\n But I do think about future spelling or wording corrections (see\n--indexed and http-referer), and I opted for letters in this example.\n\nThanks for the suggestion.  If I push this along, I'll use words and\nlet the list sort out the spellings.\n\nPhil\n"},{"id":"192854","messageId":"vpq8vg2n643.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"1338830399-31504-2-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv7 2/4] t7512-status-help.sh: better advices for git status","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-04T21:02:04Z","receivedAt":"2012-06-04T21:02:04Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +test_expect_success 'status when conflicts resolved before commit' '\n> +\ttest_when_finished \"\n> +\t\tgit commit -m \"end_merge\" &&\n\nThe \" are respectively closing quote for the one on the line before, and\nopening quote. Avoid nesting quotes, avoid quotes ;-).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192858","messageId":"7v396aspcq.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120604120406.Horde.ge3VMHwdC4BPzIgWN72l8oA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv6 2/4] t7512-status-help.sh: better advices for git status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-04T22:07:33Z","receivedAt":"2012-06-04T22:07:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n> Junio C Hamano <gitster@pobox.com>:\n>\n>> I thought Matthieu always called himself \"Matthieu Moy\", not the\n>> other way around.  I also inferred the convention used for naming\n>> the mailboxes at your institution to be \"$First.$Last@$Domain\",\n>> which tells me that perhaps these names are all spelled backwards,\n>> i.e. \"$Last $First\", which probably goes against the convention used\n>> around you and Matthieu?\n>\n> Hm, yeah it's spelled backwards, I didn't take notice of that.\n\nOh, another thing.  In your v7 series, your author name (appears on\nthe From: header of the email) is spelled in K-L order, but your\nSign-off is the other way around, i.e. L-K.\n\nNames of some people are spelled in Family-Given order even in\nEnglish context [*1*], and I do not have any objection if you are\nfollowing that cultural practice for _your own_ name.\n\nI however want to see it done consistently between Author: and\nSigned-off-by: lines.\n\n\n[Footnote]\n\n*1* Prime minister Lee Myung-bak, chairman Mao Zedong are some\nexamples.  Somewhat strangely, not prime minister Yoshihiko Noda,\neven though some Japanese insist on spelling their names like\n\"FAMILY Given\", with family name in all caps.\n"},{"id":"192860","messageId":"7vtxyqr89y.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338830399-31504-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv7 1/4] wt-status.*: better advices for git status added","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-04T23:01:45Z","receivedAt":"2012-06-04T23:01:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> The case of conflicts during a rebase -i is now taken care of. The form\n> of the tests has also been modified.\n\n> diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\n> index b8cb490..4326df7 100755\n> --- a/t/t7060-wtstatus.sh\n> +++ b/t/t7060-wtstatus.sh\n> @@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '\n>  \n>  cat >expect <<EOF\n>  # On branch side\n> +# You have unmerged paths.\n> +#   (fix conflicts and run \"git commit\")\n> +#\n>  # Unmerged paths:\n>  #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n>  #\n> @@ -118,4 +121,65 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n>  \ttest_cmp expected actual\n>  '\n\nThese probably would want to become test_i18ncmp.\n\nOther than that, modulo message details, the code structure is very\npleasant to follow and this patch looks ready to be tested.\n\nGood job.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index dd6d8c4..2b19fe3 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -728,6 +729,167 @@ static void wt_status_print_tracking(struct wt_status *s)\n> ...\n> +static void show_am_in_progress(struct wt_status *s,\n> +\t\t\t\tstruct wt_status_state *state,\n> +\t\t\t\tconst char *color)\n> +{\n> +\tstatus_printf_ln(s, color,\n> +\t\t_(\"You are in the middle of an am session.\"));\n> +\tif (state->am_empty_patch)\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"The current patch is empty.\"));\n> +\tif (advice_status_hints) {\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n> +\t\tstatus_printf_ln(s, color,\n> +\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n> +\t\tif (!state->am_empty_patch)\n> +\t\t\tstatus_printf_ln(s, color,\n> +\t\t\t\t_(\"  (when you have fixed this problem run \\\"git am --resolved\\\")\"));\n> +\t}\n> +\twt_status_print_trailer(s);\n> +}\n\nPerhaps s/fixed this problem/resolved conflicts/ or a similar\nrephrasing is a good idea.\n\nConflicts from mergy operations are perfectly normal parts of a\nregular workday, and it is not a \"problem\" that needs to be \"fixed\".\nBoth words scare the user by implying something is broken (or worse,\n\"git broke something\") in the contents of user's repository.\n\nThere are existing messages that use the verb \"fix\" on \"conflicts\",\nonly because it is shorter than \"resolve\", but this one that calls a\nconflict a \"problem\" goes too far in the wrong direction.\n"},{"id":"192861","messageId":"7vpq9er7so.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338830399-31504-2-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv7 2/4] t7512-status-help.sh: better advices for git status","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-04T23:12:07Z","receivedAt":"2012-06-04T23:12:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kong Lucien <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +test_description='git status advices'\n> +\n> +. ./test-lib.sh\n> +\n> +. \"$TEST_DIRECTORY\"/lib-rebase.sh\n> +\n> +set_fake_editor\n> +\n> +test_expect_success 'status when conflicts unresolved' '\n> +\ttest_commit init main.txt init &&\n> +\tgit branch second_branch &&\n> +\ttest_commit on_master main.txt on_master &&\n> +\tgit checkout second_branch &&\n> +\ttest_commit on_second_branch main.txt on_second_branch &&\n> +\ttest_must_fail git merge master &&\n> +\tcat >expected <<-\\EOF &&\n> +\t# On branch second_branch\n> +\t# You have unmerged paths.\n> +\t#   (fix conflicts and run \"git commit\")\n> +\t#\n> +\t# Unmerged paths:\n> +\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n> +\t#\n> +\t#\tboth modified:      main.txt\n> +\t#\n> +\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n> +\tEOF\n> +\tgit status --untracked-files=no >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nOK.\n\n> +test_expect_success 'status when conflicts resolved before commit' '\n> +\ttest_when_finished \"\n> +\t\tgit commit -m \"end_merge\" &&\n> +\t\tgit checkout master &&\n> +\t\tgit branch -D second_branch &&\n> +\t\techo >main.txt\n> +\t\" &&\n\nI do not think this is a good idea.  The previous one may have\nfailed before even reaching \"git merge\" that was supposed to fail,\nor \"git merge\" may have succeeded by mistake.\n\nIf you are assuming that all tests succeed when we didn't introduce\nany bug to Git, and when breakages happen the developer should only\nlook at the first breakage, then it is better not to pretend as if\nyou are prepared for some tests in the sequence to fail by giving a\nclean slate to later tests.\n\nFor these two tests, I think it is much simpler and cleaner to\norganize them by\n\n (1) have code to prepare two branches in the first test, tag the\n     tip of second one, and assume this test won't break;\n\n (2) move the remainder of the first test, starting with the merge\n     of master that is expected to fail, into a separate one; and\n\n (3) begin the third test (the second one in your patch) with:\n\n \tgit reset --hard $that_tag_you_added_to_the_tip_of_second &&\n\ttest_must_fail git merge master &&\n\n     so that it begins from the state the test expects it to begin\n     in, even if the previous test somehow merged master cleanly by\n     mistake.\n\n> +test_expect_success 'status when rebase in progress before resolving conflicts' '\n> +\ttest_commit one_rebase main.txt one &&\n> +\ttest_commit two_rebase main.txt two &&\n> +\ttest_commit three_rebase main.txt three &&\n> +\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n> +\tcat >expected <<-\\EOF &&\n> +\t# Not currently on any branch.\n> +\t# You are currently rebasing.\n> +\t#   (fix conflicts and then run \"git rebase --continue\")\n> +\t#   (use \"git rebase --skip\" to skip this patch)\n> +\t#   (use \"git rebase --abort\" to check out the original branch)\n> +\t#\n> +\t# Unmerged paths:\n> +\t#   (use \"git reset HEAD <file>...\" to unstage)\n> +\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n> +\t#\n> +\t#\tboth modified:      main.txt\n> +\t#\n> +\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n> +\tEOF\n> +\tgit status --untracked-files=no >actual &&\n> +\ttest_cmp expected actual\n> +'\n> +\n> +\n> +test_expect_success 'status when rebase in progress before rebase --continue' '\n> +\ttest_when_finished \"git rebase --abort\" &&\n\nLikewise.  If anything, \"git rebase --abort\" belongs to the previous\ntest that tried to run \"git rebase\".\n"},{"id":"192887","messageId":"20120605111307.Horde.-xsEEHwdC4BPzc2jJ-GgdjA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"CABURp0pD-QuAsDAJXnQXn3sTLb__maw0Mc30PHhduTZ9YOB1FQ@mail.gmail.com","subject":"Re: [PATCHv6 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-05T09:13:07Z","receivedAt":"2012-06-05T09:13:07Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nPhil Hord <phil.hord@gmail.com> a écrit :\n\n> On Sun, Jun 3, 2012 at 2:30 PM, Kong Lucien  \n> <Lucien.Kong@ensimag.imag.fr> wrote:\n>> Add new informative help messages at the output of 'git status' when\n>> the user is splitting a commit. The code figures this state by\n>> comparing the contents of the following files in the .git/ directory:\n>>          - HEAD\n>>          - ORIG_HEAD\n>>          - rebase-merge/amend\n>>          - rebase-merge/orig-head\n>>\n>> Signed-off-by: Kong Lucien <Lucien.Kong@ensimag.imag.fr>\n>> Signed-off-by: Duperray Valentin <Valentin.Duperray@ensimag.imag.fr>\n>> Signed-off-by: Jonas Franck <Franck.Jonas@ensimag.imag.fr>\n>> Signed-off-by: Nguy Thomas <Thomas.Nguy@ensimag.imag.fr>\n>> Signed-off-by: Nguyen Huynh Khoi Nguyen  \n>> <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\n>> Signed-off-by: Moy Matthieu <Matthieu.Moy@grenoble-inp.fr>\n>> ---\n>> The second test added by this patch fails because the case in which\n>> the user amend the last commit through rebase -i is not taken care of.\n>> We infer that the user would directly run \"git commit --amend\" instead\n>> of amending it with a rebase -i.\n>\n>\n> Maybe this is safe and logical for most workflows, or maybe this is a\n> convenience that makes this patch possible (I did not read the patch\n> yet).  But I know that I sometimes use rebase-i instead of\n> commit--amend because I did not realize the patch I am fixing is the\n> most recent one until after continuing, or because the patch I am\n> amending was moved into the most-recent position during the rebase-i\n> itself.\n\nRight, This case has to be taken care of. It will need some work as\nit's quite difficult to distinguish the current state after doing\na reset HEAD^ or doing a commit --amend when the rebase-merge/amend\nis set on the last commit.\n"},{"id":"192890","messageId":"20120605123219.Horde.4685bnwdC4BPzeAz2LLCYAA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7vtxyqr89y.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv7 1/4] wt-status.*: better advices for git status added","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-05T10:32:19Z","receivedAt":"2012-06-05T10:32:19Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n>> @@ -728,6 +729,167 @@ static void wt_status_print_tracking(struct  \n>> wt_status *s)\n>> ...\n>> +static void show_am_in_progress(struct wt_status *s,\n>> +\t\t\t\tstruct wt_status_state *state,\n>> +\t\t\t\tconst char *color)\n>> +{\n>> +\tstatus_printf_ln(s, color,\n>> +\t\t_(\"You are in the middle of an am session.\"));\n>> +\tif (state->am_empty_patch)\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"The current patch is empty.\"));\n>> +\tif (advice_status_hints) {\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n>> +\t\tstatus_printf_ln(s, color,\n>> +\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n>> +\t\tif (!state->am_empty_patch)\n>> +\t\t\tstatus_printf_ln(s, color,\n>> +\t\t\t\t_(\"  (when you have fixed this problem run \\\"git am --resolved\\\")\"));\n>> +\t}\n>> +\twt_status_print_trailer(s);\n>> +}\n>\n> Perhaps s/fixed this problem/resolved conflicts/ or a similar\n> rephrasing is a good idea.\n>\n> Conflicts from mergy operations are perfectly normal parts of a\n> regular workday, and it is not a \"problem\" that needs to be \"fixed\".\n> Both words scare the user by implying something is broken (or worse,\n> \"git broke something\") in the contents of user's repository.\n>\n> There are existing messages that use the verb \"fix\" on \"conflicts\",\n> only because it is shorter than \"resolve\", but this one that calls a\n> conflict a \"problem\" goes too far in the wrong direction.\n\nI agree. Still, experienced users probably have their advice.statushints\ndisabled and won't have any problems resolving a conflict. However, for\n\"beginners\" that need the advices, resolving a conflict may not seem\nas trivial as it is. And even though the word \"problem\" may scare them,\nit will attract their attention.\n"},{"id":"192894","messageId":"vpqy5o2hu2l.fsf@bauges.imag.fr","threadId":"30608","inReplyTo":"20120605123219.Horde.4685bnwdC4BPzeAz2LLCYAA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv7 1/4] wt-status.*: better advices for git status added","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-06-05T11:33:22Z","receivedAt":"2012-06-05T11:33:22Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"konglu@minatec.inpg.fr writes:\n\n> > Perhaps s/fixed this problem/resolved conflicts/ [...]\n>\n> I agree. Still, experienced users probably have their advice.statushints\n> disabled and won't have any problems resolving a conflict. However, for\n> \"beginners\" that need the advices, resolving a conflict may not seem\n> as trivial as it is. And even though the word \"problem\" may scare them,\n> it will attract their attention.\n\nBut beginners are scared by conflicts. Indeed, \"there are conflicts\" is\nautomatically translated into \"sir, it doesn't work\" by many beginners I\nknow ;-). I prefer Junio's wording as a subliminal message that\nconflicts are not \"a problem\", but just \"something you should avoid when\npossible, and fix otherwise\".\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192951","messageId":"1338927687-29822-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338830399-31504-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv8 1/4] wt-status.*: better advices for git status added","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-05T20:21:24Z","receivedAt":"2012-06-05T20:21:24Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new informative help messages in the display of\n'git status' (at the top) during conflicts, rebase, am, bisect or\ncherry-pick process.\n\nThe new messages are not shown when using options such as -s or\n--porcelain. The messages about the current situation of the user are\nalways displayed but the advices on what the user needs to do in order\nto resume a rebase/bisect/am/commit after resolving conflicts can be\nhidden by setting advice.statushints to 'false' in the config file.\n\nThus, information about the updated advice.statushints key are added\nin Documentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the new help\nmessages. Tests about suggestions of \"git rm\" are also added.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThe help messages in the case of an am session are changed to be\nconsistent with the other messages.\n\n Documentation/config.txt |    7 +-\n t/t7060-wtstatus.sh      |   64 ++++++++++++++++++\n wt-status.c              |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 4 files changed, 242 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..ccce4f6 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -159,9 +159,10 @@ advice.*::\n \t\tspecified a refspec that isn't your current branch) and\n \t\tit resulted in a non-fast-forward error.\n \tstatusHints::\n-\t\tDirections on how to stage/unstage/add shown in the\n-\t\toutput of linkgit:git-status[1] and the template shown\n-\t\twhen writing commit messages.\n+\t\tShow directions on how to proceed from the current\n+\t\tstate in the output of linkgit:git-status[1] and in\n+\t\tthe template shown when writing commit messages in\n+\t\tlinkgit:git-commit[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..e8c3690 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths.\n+#   (fix conflicts and run \"git commit\")\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\n@@ -118,4 +121,65 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n \ttest_cmp expected actual\n '\n \n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit reset --hard &&\n+\tgit checkout master &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\ttest_commit second conflict.txt second &&\n+\tgit checkout master &&\n+\ttest_commit on_second main.txt on_second &&\n+\ttest_commit master conflict.txt master &&\n+\ttest_must_fail git merge second_branch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         conflict.txt\n+\t#\tdeleted by them:    main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit reset --hard &&\n+\tgit checkout -b conflict &&\n+\ttest_commit one main.txt one &&\n+\tgit branch conflict_second &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout conflict_second &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge conflict &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..7548509 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,167 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int has_unmerged(struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+static void show_merge_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"All conflicts fixed but you are still merging.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit\\\" to conclude merge)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_am_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are in the middle of an am session.\"));\n+\tif (state->am_empty_patch)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"The current patch is empty.\"));\n+\tif (advice_status_hints) {\n+\t\tif (!state->am_empty_patch)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git am --resolved\\\")\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_rebase_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstruct stat st;\n+\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n+\t\t}\n+\t} else if (state->rebase_in_progress || !stat(git_path(\"MERGE_MSG\"), &st)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_hints && !s->amend) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied with your changes)\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_cherry_pick_in_progress(struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n+\tif (advice_status_hints) {\n+\t\tif (has_unmerged(s))\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git commit\\\")\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_bisect_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_hints)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git bisect reset\\\" to get back to the original branch)\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_print_state(struct wt_status *s)\n+{\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st)) {\n+\t\tstate->merge_in_progress = 1;\n+\t} else if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !st.st_size)\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t} else {\n+\t\t\tstate->rebase_in_progress = 1;\n+\t\t}\n+\t} else if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t} else if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st)) {\n+\t\tstate->cherry_pick_in_progress = 1;\n+\t}\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+\n+\tif (state->merge_in_progress)\n+\t\tshow_merge_in_progress(s, state, state_color);\n+\telse if (state->am_in_progress)\n+\t\tshow_am_in_progress(s, state, state_color);\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n+\t\tshow_rebase_in_progress(s, state, state_color);\n+\telse if (state->cherry_pick_in_progress)\n+\t\tshow_cherry_pick_in_progress(s, state, state_color);\n+\tif (state->bisect_in_progress)\n+\t\tshow_bisect_in_progress(s, state, state_color);\n+\tfree(state);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +912,7 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_state(s);\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"192949","messageId":"1338927687-29822-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338927687-29822-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv8 2/4] t7512-status-help.sh: better advices for git status","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-05T20:21:25Z","receivedAt":"2012-06-05T20:21:25Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user needs to\nrun 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am/cherry-pick progress.\n\nOne of the test is about the set of the advice.statushints config key\nto 'false' in .git/config.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThe structure of the tests are changed so that they are now independant\nwith each other.\n\n t/t7512-status-help.sh |  372 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 372 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-help.sh\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nnew file mode 100755\nindex 0000000..3714e8e\n--- /dev/null\n+++ b/t/t7512-status-help.sh\n@@ -0,0 +1,372 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'prepare for conflicts' '\n+\ttest_commit init main.txt init &&\n+\tgit branch conflicts &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout conflicts &&\n+\ttest_commit on_conflicts main.txt on_conflicts\n+'\n+\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\ttest_must_fail git merge master &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflicts\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\tgit reset --hard conflicts &&\n+\ttest_must_fail git merge master &&\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflicts\n+\t# All conflicts fixed but you are still merging.\n+\t#   (use \"git commit\" to conclude merge)\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for rebase conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_conflicts &&\n+\ttest_commit one_rebase main.txt one &&\n+\ttest_commit two_rebase main.txt two &&\n+\ttest_commit three_rebase main.txt three\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\tgit reset --hard rebase_conflicts &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for rebase_i_conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_i_conflicts &&\n+\ttest_commit one_unmerge main.txt one_unmerge &&\n+\tgit branch rebase_i_conflicts_second &&\n+\ttest_commit one_master main.txt one_master &&\n+\tgit checkout rebase_i_conflicts_second &&\n+\ttest_commit one_second main.txt one_second\n+'\n+\n+\n+test_expect_success 'status during rebase -i when conflicts unresolved' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase -i rebase_i_conflicts &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status during rebase -i after resolving conflicts' '\n+\tgit reset --hard rebase_i_conflicts_second &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase -i rebase_i_conflicts &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_i_edit &&\n+\ttest_commit one_rebase_i main.txt one &&\n+\ttest_commit two_rebase_i main.txt two &&\n+\ttest_commit three_rebase_i main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare am_session' '\n+\tgit reset --hard master &&\n+\tgit checkout -b am_session &&\n+\ttest_commit one_am one.txt \"one\" &&\n+\ttest_commit two_am two.txt \"two\" &&\n+\ttest_commit three_am three.txt \"three\"\n+'\n+\n+\n+test_expect_success 'status in an am session: file already exists' '\n+\tgit checkout -b am_already_exists &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_already_exists\n+\t# You are in the middle of an am session.\n+\t#   (fix conflicts and then run \"git am --resolved\")\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: file does not exist' '\n+\tgit reset --hard am_session &&\n+\tgit checkout -b am_not_exists &&\n+\tgit rm three.txt &&\n+\tgit commit -m \"delete three.txt\" &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_not_exists\n+\t# You are in the middle of an am session.\n+\t#   (fix conflicts and then run \"git am --resolved\")\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: empty patch' '\n+\tgit reset --hard am_session &&\n+\tgit checkout -b am_empty &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all am_empty\" &&\n+\techo error >Maildir/0002-two_am.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_empty\n+\t# You are in the middle of an am session.\n+\t# The current patch is empty.\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit reset --hard master &&\n+\tgit checkout -b bisect &&\n+\ttest_commit one_bisect main.txt one &&\n+\ttest_commit two_bisect main.txt two &&\n+\ttest_commit three_bisect main.txt three &&\n+\ttest_when_finished \"git bisect reset\" &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one_bisect &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t#   (use \"git bisect reset\" to get back to the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushints disabled' '\n+\tgit reset --hard master &&\n+\tgit checkout -b statushints_disabled &&\n+\ttest_when_finished \"git config --local advice.statushints true\" &&\n+\tgit config --local advice.statushints false &&\n+\ttest_commit one_statushints main.txt one &&\n+\ttest_commit two_statushints main.txt two &&\n+\ttest_commit three_statushints main.txt three &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for cherry-pick conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b cherry_branch &&\n+\ttest_commit one_cherry main.txt one &&\n+\ttest_commit two_cherries main.txt two &&\n+\tgit checkout -b cherry_branch_second &&\n+\ttest_commit second_cherry main.txt second &&\n+\tgit checkout cherry_branch &&\n+\ttest_commit three_cherries main.txt three\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\ttest_when_finished \"git cherry-pick --abort\" &&\n+\ttest_must_fail git cherry-pick cherry_branch_second &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch cherry_branch\n+\t# You are currently cherry-picking.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\tgit reset --hard cherry_branch &&\n+\ttest_when_finished \"git cherry-pick --abort\" &&\n+\ttest_must_fail git cherry-pick cherry_branch_second &&\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch cherry_branch\n+\t# You are currently cherry-picking.\n+\t#   (all conflicts fixed: run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"192950","messageId":"1338927687-29822-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338927687-29822-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv8 3/4] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-05T20:21:26Z","receivedAt":"2012-06-05T20:21:26Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when there are\nunmerged files) after running 'git status' is now depending of the\nmark, whether it's 'both deleted', 'deleted by us/them' or others. For\ninstance, when there is just one file that's marked as 'both deleted',\n'git status' shows '(use git rm [...])' and if there are two files,\none as 'both deleted' and the other as 'added by them', the advice is\n'(use git add/rm [...])'.\n\nThe previous tests in t7512-status-help.sh are updated.\n\nTest about the case of only 'both deleted' is added in\nt7060-wtstatus.sh\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n t/t7060-wtstatus.sh    |   36 ++++++++++++++++++++++++++++++++++--\n t/t7512-status-help.sh |    8 ++++----\n wt-status.c            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 74 insertions(+), 7 deletions(-)\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex e8c3690..f4f38a5 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -152,7 +152,7 @@ test_expect_success 'status when conflicts with add and rm advice (deleted by th\n '\n \n \n-test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+test_expect_success 'prepare for conflicts' '\n \tgit reset --hard &&\n \tgit checkout -b conflict &&\n \ttest_commit one main.txt one &&\n@@ -161,7 +161,11 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n \tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n \tgit checkout conflict_second &&\n \tgit mv main.txt sub_second.txt &&\n-\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\"\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n \ttest_must_fail git merge conflict &&\n \tcat >expected <<-\\EOF &&\n \t# On branch conflict_second\n@@ -182,4 +186,32 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n '\n \n \n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\tgit reset --hard conflict_second &&\n+\ttest_must_fail git merge conflict &&\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual &&\n+\tgit reset --hard &&\n+\tgit checkout master\n+'\n+\n+\n test_done\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex 3714e8e..bdce192 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -30,7 +30,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -83,7 +83,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -140,7 +140,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -336,7 +336,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\ndiff --git a/wt-status.c b/wt-status.c\nindex 7548509..fcde045 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,34 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint del_mod_conflict = 0;\n+\tint both_deleted = 0;\n+\tint not_deleted = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tswitch (d->stagemask) {\n+\t\tcase 0:\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tboth_deleted = 1;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\tcase 5:\n+\t\t\tdel_mod_conflict = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tnot_deleted = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted) {\n+\t\tif (!del_mod_conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t} else if (!del_mod_conflict && !not_deleted) {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t}\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"192948","messageId":"1338927687-29822-4-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338927687-29822-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv8 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-05T20:21:27Z","receivedAt":"2012-06-05T20:21:27Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"Add new informative help messages at the output of 'git status' when\nthe user is splitting a commit. The code figures this state by\ncomparing the contents of the following files in the .git/ directory:\n\t  - HEAD\n\t  - ORIG_HEAD\n\t  - rebase-merge/amend\n\t  - rebase-merge/orig-head\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n t/t7512-status-help.sh |   55 ++++++++++++++++++++++++++++++++++\n wt-status.c            |   77 ++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 132 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex bdce192..a77574f 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -196,6 +196,61 @@ test_expect_success 'status when rebasing -i in edit mode' '\n '\n \n \n+test_expect_success 'status when splitting a commit' '\n+\tgit reset --hard master &&\n+\tgit checkout -b split_commit &&\n+\ttest_commit one_split main.txt one &&\n+\ttest_commit two_split main.txt two &&\n+\ttest_commit three_split main.txt three &&\n+\ttest_commit four_split main.txt four &&\n+\tFAKE_LINES=\"1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_failure 'status after editing the last commit with --amend during a rebase -i' '\n+\tgit reset --hard master &&\n+\tgit checkout -b amend_last &&\n+\ttest_commit one_amend main.txt one &&\n+\ttest_commit two_amend main.txt two &&\n+\ttest_commit three_amend main.txt three &&\n+\ttest_commit four_amend main.txt four &&\n+\tFAKE_LINES=\"1 2 edit 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"foo\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (working directory clean)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n test_expect_success 'prepare am_session' '\n \tgit reset --hard master &&\n \tgit checkout -b am_session &&\ndiff --git a/wt-status.c b/wt-status.c\nindex fcde045..5445dbf 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -12,6 +12,7 @@\n #include \"refs.h\"\n #include \"submodule.h\"\n #include \"column.h\"\n+#include \"strbuf.h\"\n \n static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n@@ -817,6 +818,77 @@ static void show_am_in_progress(struct wt_status *s,\n \twt_status_print_trailer(s);\n }\n \n+static int split_commit_in_progress()\n+{\n+\tFILE *head;\n+\tstruct strbuf buf_head;\n+\tFILE *orig_head;\n+\tstruct strbuf buf_orig_head;\n+\tFILE *rebase_amend;\n+\tstruct strbuf buf_rebase_amend;\n+\tFILE *rebase_orig_head;\n+\tstruct strbuf buf_rebase_orig_head;\n+\tint split_in_progress = 0;\n+\n+\thead = fopen(git_path(\"HEAD\"), \"r\");\n+\tif (!head)\n+\t\treturn 0;\n+\n+\torig_head = fopen(git_path(\"ORIG_HEAD\"), \"r\");\n+\tif (!orig_head) {\n+\t\tfclose(head);\n+\t\treturn 0;\n+\t}\n+\n+\trebase_amend = fopen(git_path(\"rebase-merge/amend\"), \"r\");\n+\tif (!rebase_amend) {\n+\t\tfclose(head);\n+\t\tfclose(orig_head);\n+\t\treturn 0;\n+\t}\n+\n+\trebase_orig_head = fopen(git_path(\"rebase-merge/orig-head\"), \"r\");\n+\tif (!rebase_orig_head) {\n+\t\tfclose(head);\n+\t\tfclose(orig_head);\n+\t\tfclose(rebase_amend);\n+\t\treturn 0;\n+\t}\n+\n+\tstrbuf_init(&buf_head, 0);\n+\tstrbuf_init(&buf_orig_head, 0);\n+\tstrbuf_init(&buf_rebase_amend, 0);\n+\tstrbuf_init(&buf_rebase_orig_head, 0);\n+\n+\tstrbuf_getline(&buf_head, head, '\\n');\n+\tstrbuf_getline(&buf_orig_head, orig_head, '\\n');\n+\tstrbuf_getline(&buf_rebase_amend, rebase_amend, '\\n');\n+\tstrbuf_getline(&buf_rebase_orig_head, rebase_orig_head, '\\n');\n+\n+\tfclose(head);\n+\tfclose(orig_head);\n+\tfclose(rebase_amend);\n+\tfclose(rebase_orig_head);\n+\n+\tif (!strbuf_cmp(&buf_rebase_amend, &buf_rebase_orig_head)) {\n+\t\tif (strbuf_cmp(&buf_head, &buf_rebase_amend))\n+\t\t\tsplit_in_progress = 1;\n+\t} else if (!strbuf_cmp(&buf_orig_head, &buf_rebase_amend)) {\n+\t\tsplit_in_progress = 1;\n+\t} else if (strbuf_cmp(&buf_orig_head, &buf_rebase_orig_head)) {\n+\t\tsplit_in_progress = 1;\n+\t}\n+\n+\tif (!strbuf_cmp(&buf_head, &buf_rebase_amend))\n+\t\tsplit_in_progress = 0;\n+\n+\tstrbuf_release(&buf_head);\n+\tstrbuf_release(&buf_orig_head);\n+\tstrbuf_release(&buf_rebase_amend);\n+\tstrbuf_release(&buf_rebase_orig_head);\n+\treturn split_in_progress;\n+}\n+\n static void show_rebase_in_progress(struct wt_status *s,\n \t\t\t\tstruct wt_status_state *state,\n \t\t\t\tconst char *color)\n@@ -838,6 +910,11 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\tif (advice_status_hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else if (split_commit_in_progress()) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently splitting a commit.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (Once your working directory is clean, run \\\"git rebase --continue\\\")\"));\n \t} else {\n \t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n \t\tif (advice_status_hints && !s->amend) {\n-- \n1.7.8\n"},{"id":"192954","messageId":"7vfwa9o3xo.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1338927687-29822-4-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv8 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-05T21:16:03Z","receivedAt":"2012-06-05T21:16:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +static int split_commit_in_progress()\n\nstatic int split_commit_in_progress(void)\n\n> +{\n> +\tFILE *head;\n> +\tstruct strbuf buf_head;\n> +\tFILE *orig_head;\n> +\tstruct strbuf buf_orig_head;\n> +\tFILE *rebase_amend;\n> +\tstruct strbuf buf_rebase_amend;\n> +\tFILE *rebase_orig_head;\n> +\tstruct strbuf buf_rebase_orig_head;\n> +\tint split_in_progress = 0;\n> +\n> +\thead = fopen(git_path(\"HEAD\"), \"r\");\n> +\tif (!head)\n> +\t\treturn 0;\n> +\n> +\torig_head = fopen(git_path(\"ORIG_HEAD\"), \"r\");\n> +\tif (!orig_head) {\n> +\t\tfclose(head);\n> +\t\treturn 0;\n> +\t}\n> +\n> +\trebase_amend = fopen(git_path(\"rebase-merge/amend\"), \"r\");\n> +\tif (!rebase_amend) {\n> +\t\tfclose(head);\n> +\t\tfclose(orig_head);\n> +\t\treturn 0;\n> +\t}\n> +\n> +\trebase_orig_head = fopen(git_path(\"rebase-merge/orig-head\"), \"r\");\n> +\tif (!rebase_orig_head) {\n> +\t\tfclose(head);\n> +\t\tfclose(orig_head);\n> +\t\tfclose(rebase_amend);\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tstrbuf_init(&buf_head, 0);\n> +\tstrbuf_init(&buf_orig_head, 0);\n> +\tstrbuf_init(&buf_rebase_amend, 0);\n> +\tstrbuf_init(&buf_rebase_orig_head, 0);\n> +\n> +\tstrbuf_getline(&buf_head, head, '\\n');\n> +\tstrbuf_getline(&buf_orig_head, orig_head, '\\n');\n> +\tstrbuf_getline(&buf_rebase_amend, rebase_amend, '\\n');\n> +\tstrbuf_getline(&buf_rebase_orig_head, rebase_orig_head, '\\n');\n> +\n> +\tfclose(head);\n> +\tfclose(orig_head);\n> +\tfclose(rebase_amend);\n> +\tfclose(rebase_orig_head);\n\n\nThat is somewhat an ugly sequence; wouldn't it make sense to have a\nsmall helper that takes a path in git_path() and returns a pointer\nto an allocated string, i.e. something like...\n\n\tstatic char *read_line_from_git_path(const char *filename)\n        {\n        \tstruct struct buf = STRBUF_INIT;\n                FILE *fp = fopen(git_path(filename), \"r\");\n                if (!fp)\n                \treturn NULL;\n\t\tstrbuf_getline(&buf, fp, '\\n');\n\t\tfclose(fp);\n                return strbuf_detach(&buf, NULL);\n\t}\n\nnb. return value from fclose() may need to be be checked as well,\nbut this is just an illustration.\n\nReading from git_path(\"HEAD\") looked funny, as you may end up\nreading the \"ref: refs/heads/master\".  Of course that would not\ncompare equal to what you would read from \"rebase-merge/amend\", and\nthat may be fine for the purpose of your test, but it still looks\nsomewhat funny.  As modern rebase is done on a detached HEAD,\nperhaps it is a good idea to check if the HEAD is detached and\nreturn false from this function if that is not the case.  I dunno.\n\nOther than that, all four patches in the series looked good.  Will\nreplace what I queued on 'pu' last night.\n\nThanks.\n"},{"id":"193064","messageId":"1339075029-27109-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1338927687-29822-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv9 1/4] wt-status.*: better advices for git status added","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-07T13:17:06Z","receivedAt":"2012-06-07T13:17:06Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new informative help messages in the display of\n'git status' (at the top) during conflicts, rebase, am, bisect or\ncherry-pick process.\n\nThe new messages are not shown when using options such as -s or\n--porcelain. The messages about the current situation of the user are\nalways displayed but the advices on what the user needs to do in order\nto resume a rebase/bisect/am/commit after resolving conflicts can be\nhidden by setting advice.statushints to 'false' in the config file.\n\nThus, information about the updated advice.statushints key are added\nin Documentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the new help\nmessages. Tests about suggestions of \"git rm\" are also added.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\npart 1/4 unchanged since v8. Only the part 4/4 is changed.\n\n Documentation/config.txt |    7 +-\n t/t7060-wtstatus.sh      |   64 ++++++++++++++++++\n wt-status.c              |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 4 files changed, 242 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..ccce4f6 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -159,9 +159,10 @@ advice.*::\n \t\tspecified a refspec that isn't your current branch) and\n \t\tit resulted in a non-fast-forward error.\n \tstatusHints::\n-\t\tDirections on how to stage/unstage/add shown in the\n-\t\toutput of linkgit:git-status[1] and the template shown\n-\t\twhen writing commit messages.\n+\t\tShow directions on how to proceed from the current\n+\t\tstate in the output of linkgit:git-status[1] and in\n+\t\tthe template shown when writing commit messages in\n+\t\tlinkgit:git-commit[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..e8c3690 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths.\n+#   (fix conflicts and run \"git commit\")\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\n@@ -118,4 +121,65 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n \ttest_cmp expected actual\n '\n \n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit reset --hard &&\n+\tgit checkout master &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\ttest_commit second conflict.txt second &&\n+\tgit checkout master &&\n+\ttest_commit on_second main.txt on_second &&\n+\ttest_commit master conflict.txt master &&\n+\ttest_must_fail git merge second_branch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         conflict.txt\n+\t#\tdeleted by them:    main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit reset --hard &&\n+\tgit checkout -b conflict &&\n+\ttest_commit one main.txt one &&\n+\tgit branch conflict_second &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout conflict_second &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge conflict &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..7548509 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,167 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int has_unmerged(struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+static void show_merge_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"All conflicts fixed but you are still merging.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit\\\" to conclude merge)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_am_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are in the middle of an am session.\"));\n+\tif (state->am_empty_patch)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"The current patch is empty.\"));\n+\tif (advice_status_hints) {\n+\t\tif (!state->am_empty_patch)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git am --resolved\\\")\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_rebase_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstruct stat st;\n+\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n+\t\t}\n+\t} else if (state->rebase_in_progress || !stat(git_path(\"MERGE_MSG\"), &st)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_hints && !s->amend) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied with your changes)\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_cherry_pick_in_progress(struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n+\tif (advice_status_hints) {\n+\t\tif (has_unmerged(s))\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git commit\\\")\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_bisect_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_hints)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git bisect reset\\\" to get back to the original branch)\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_print_state(struct wt_status *s)\n+{\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st)) {\n+\t\tstate->merge_in_progress = 1;\n+\t} else if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !st.st_size)\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t} else {\n+\t\t\tstate->rebase_in_progress = 1;\n+\t\t}\n+\t} else if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t} else if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st)) {\n+\t\tstate->cherry_pick_in_progress = 1;\n+\t}\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+\n+\tif (state->merge_in_progress)\n+\t\tshow_merge_in_progress(s, state, state_color);\n+\telse if (state->am_in_progress)\n+\t\tshow_am_in_progress(s, state, state_color);\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n+\t\tshow_rebase_in_progress(s, state, state_color);\n+\telse if (state->cherry_pick_in_progress)\n+\t\tshow_cherry_pick_in_progress(s, state, state_color);\n+\tif (state->bisect_in_progress)\n+\t\tshow_bisect_in_progress(s, state, state_color);\n+\tfree(state);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +912,7 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_state(s);\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"193066","messageId":"1339075029-27109-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339075029-27109-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv9 2/4] t7512-status-help.sh: better advices for git status","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-07T13:17:07Z","receivedAt":"2012-06-07T13:17:07Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user needs to\nrun 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am/cherry-pick progress.\n\nOne of the test is about the set of the advice.statushints config key\nto 'false' in .git/config.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\npart 2/4 unchanged since v8.\n\n t/t7512-status-help.sh |  372 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 372 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-help.sh\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nnew file mode 100755\nindex 0000000..3714e8e\n--- /dev/null\n+++ b/t/t7512-status-help.sh\n@@ -0,0 +1,372 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'prepare for conflicts' '\n+\ttest_commit init main.txt init &&\n+\tgit branch conflicts &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout conflicts &&\n+\ttest_commit on_conflicts main.txt on_conflicts\n+'\n+\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\ttest_must_fail git merge master &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflicts\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\tgit reset --hard conflicts &&\n+\ttest_must_fail git merge master &&\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflicts\n+\t# All conflicts fixed but you are still merging.\n+\t#   (use \"git commit\" to conclude merge)\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for rebase conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_conflicts &&\n+\ttest_commit one_rebase main.txt one &&\n+\ttest_commit two_rebase main.txt two &&\n+\ttest_commit three_rebase main.txt three\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\tgit reset --hard rebase_conflicts &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for rebase_i_conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_i_conflicts &&\n+\ttest_commit one_unmerge main.txt one_unmerge &&\n+\tgit branch rebase_i_conflicts_second &&\n+\ttest_commit one_master main.txt one_master &&\n+\tgit checkout rebase_i_conflicts_second &&\n+\ttest_commit one_second main.txt one_second\n+'\n+\n+\n+test_expect_success 'status during rebase -i when conflicts unresolved' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase -i rebase_i_conflicts &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status during rebase -i after resolving conflicts' '\n+\tgit reset --hard rebase_i_conflicts_second &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase -i rebase_i_conflicts &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_i_edit &&\n+\ttest_commit one_rebase_i main.txt one &&\n+\ttest_commit two_rebase_i main.txt two &&\n+\ttest_commit three_rebase_i main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare am_session' '\n+\tgit reset --hard master &&\n+\tgit checkout -b am_session &&\n+\ttest_commit one_am one.txt \"one\" &&\n+\ttest_commit two_am two.txt \"two\" &&\n+\ttest_commit three_am three.txt \"three\"\n+'\n+\n+\n+test_expect_success 'status in an am session: file already exists' '\n+\tgit checkout -b am_already_exists &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_already_exists\n+\t# You are in the middle of an am session.\n+\t#   (fix conflicts and then run \"git am --resolved\")\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: file does not exist' '\n+\tgit reset --hard am_session &&\n+\tgit checkout -b am_not_exists &&\n+\tgit rm three.txt &&\n+\tgit commit -m \"delete three.txt\" &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_not_exists\n+\t# You are in the middle of an am session.\n+\t#   (fix conflicts and then run \"git am --resolved\")\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: empty patch' '\n+\tgit reset --hard am_session &&\n+\tgit checkout -b am_empty &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all am_empty\" &&\n+\techo error >Maildir/0002-two_am.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_empty\n+\t# You are in the middle of an am session.\n+\t# The current patch is empty.\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit reset --hard master &&\n+\tgit checkout -b bisect &&\n+\ttest_commit one_bisect main.txt one &&\n+\ttest_commit two_bisect main.txt two &&\n+\ttest_commit three_bisect main.txt three &&\n+\ttest_when_finished \"git bisect reset\" &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one_bisect &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t#   (use \"git bisect reset\" to get back to the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushints disabled' '\n+\tgit reset --hard master &&\n+\tgit checkout -b statushints_disabled &&\n+\ttest_when_finished \"git config --local advice.statushints true\" &&\n+\tgit config --local advice.statushints false &&\n+\ttest_commit one_statushints main.txt one &&\n+\ttest_commit two_statushints main.txt two &&\n+\ttest_commit three_statushints main.txt three &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for cherry-pick conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b cherry_branch &&\n+\ttest_commit one_cherry main.txt one &&\n+\ttest_commit two_cherries main.txt two &&\n+\tgit checkout -b cherry_branch_second &&\n+\ttest_commit second_cherry main.txt second &&\n+\tgit checkout cherry_branch &&\n+\ttest_commit three_cherries main.txt three\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\ttest_when_finished \"git cherry-pick --abort\" &&\n+\ttest_must_fail git cherry-pick cherry_branch_second &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch cherry_branch\n+\t# You are currently cherry-picking.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\tgit reset --hard cherry_branch &&\n+\ttest_when_finished \"git cherry-pick --abort\" &&\n+\ttest_must_fail git cherry-pick cherry_branch_second &&\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch cherry_branch\n+\t# You are currently cherry-picking.\n+\t#   (all conflicts fixed: run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"193065","messageId":"1339075029-27109-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339075029-27109-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv9 3/4] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-07T13:17:08Z","receivedAt":"2012-06-07T13:17:08Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when there are\nunmerged files) after running 'git status' is now depending of the\nmark, whether it's 'both deleted', 'deleted by us/them' or others. For\ninstance, when there is just one file that's marked as 'both deleted',\n'git status' shows '(use git rm [...])' and if there are two files,\none as 'both deleted' and the other as 'added by them', the advice is\n'(use git add/rm [...])'.\n\nThe previous tests in t7512-status-help.sh are updated.\n\nTest about the case of only 'both deleted' is added in\nt7060-wtstatus.sh\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\npart 3/4 unchanged since v8.\n\n t/t7060-wtstatus.sh    |   36 ++++++++++++++++++++++++++++++++++--\n t/t7512-status-help.sh |    8 ++++----\n wt-status.c            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 74 insertions(+), 7 deletions(-)\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex e8c3690..f4f38a5 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -152,7 +152,7 @@ test_expect_success 'status when conflicts with add and rm advice (deleted by th\n '\n \n \n-test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+test_expect_success 'prepare for conflicts' '\n \tgit reset --hard &&\n \tgit checkout -b conflict &&\n \ttest_commit one main.txt one &&\n@@ -161,7 +161,11 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n \tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n \tgit checkout conflict_second &&\n \tgit mv main.txt sub_second.txt &&\n-\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\"\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n \ttest_must_fail git merge conflict &&\n \tcat >expected <<-\\EOF &&\n \t# On branch conflict_second\n@@ -182,4 +186,32 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n '\n \n \n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\tgit reset --hard conflict_second &&\n+\ttest_must_fail git merge conflict &&\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual &&\n+\tgit reset --hard &&\n+\tgit checkout master\n+'\n+\n+\n test_done\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex 3714e8e..bdce192 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -30,7 +30,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -83,7 +83,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -140,7 +140,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -336,7 +336,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\ndiff --git a/wt-status.c b/wt-status.c\nindex 7548509..fcde045 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,34 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint del_mod_conflict = 0;\n+\tint both_deleted = 0;\n+\tint not_deleted = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tswitch (d->stagemask) {\n+\t\tcase 0:\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tboth_deleted = 1;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\tcase 5:\n+\t\t\tdel_mod_conflict = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tnot_deleted = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted) {\n+\t\tif (!del_mod_conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t} else if (!del_mod_conflict && !not_deleted) {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t}\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"193067","messageId":"1339075029-27109-4-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339075029-27109-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv9 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-07T13:17:09Z","receivedAt":"2012-06-07T13:17:09Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"Add new informative help messages at the output of 'git status' when\nthe user is splitting a commit. The code figures this state by\ncomparing the contents of the following files in the .git/ directory:\n\t  - HEAD\n\t  - ORIG_HEAD\n\t  - rebase-merge/amend\n\t  - rebase-merge/orig-head\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThe code is now restructured. The right help message is now displayed when\nyou amend the last commit through rebase interactive, and when you're\nediting several edits whether you're amending or splitting them.\n\n t/t7512-status-help.sh |  277 ++++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.c            |   52 +++++++++\n 2 files changed, 329 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex bdce192..3ce384a 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -196,6 +196,283 @@ test_expect_success 'status when rebasing -i in edit mode' '\n '\n \n \n+test_expect_success 'status when splitting a commit' '\n+\tgit reset --hard master &&\n+\tgit checkout -b split_commit &&\n+\ttest_commit one_split main.txt one &&\n+\ttest_commit two_split main.txt two &&\n+\ttest_commit three_split main.txt three &&\n+\ttest_commit four_split main.txt four &&\n+\tFAKE_LINES=\"1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status after editing the last commit with --amend during a rebase -i' '\n+\tgit reset --hard master &&\n+\tgit checkout -b amend_last &&\n+\ttest_commit one_amend main.txt one &&\n+\ttest_commit two_amend main.txt two &&\n+\ttest_commit three_amend main.txt three &&\n+\ttest_commit four_amend main.txt four &&\n+\tFAKE_LINES=\"1 2 edit 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"foo\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for several edits' '\n+\tgit reset --hard master &&\n+\tgit checkout -b several_edits &&\n+\ttest_commit one_edits main.txt one &&\n+\ttest_commit two_edits main.txt two &&\n+\ttest_commit three_edits main.txt three &&\n+\ttest_commit four_edits main.txt four\n+'\n+\n+\n+test_expect_success 'status: (continue first edit) second edit' '\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit rebase --continue &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (continue first edit) second edit and split' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit rebase --continue &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (continue first edit) second edit and amend' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit rebase --continue &&\n+\tgit commit --amend -m \"foo\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (amend first edit) second edit' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"a\" &&\n+\tgit rebase --continue &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (amend first edit) second edit and split' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"b\" &&\n+\tgit rebase --continue &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (amend first edit) second edit and amend' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"c\" &&\n+\tgit rebase --continue &&\n+\tgit commit --amend -m \"d\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (split first edit) second edit' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tgit add main.txt &&\n+\tgit commit -m \"e\" &&\n+\tgit rebase --continue &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (split first edit) second edit and split' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tgit add main.txt &&\n+\tgit commit --amend -m \"f\" &&\n+\tgit rebase --continue &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (split first edit) second edit and amend' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tgit add main.txt &&\n+\tgit commit --amend -m \"g\" &&\n+\tgit rebase --continue &&\n+\tgit commit --amend -m \"h\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n test_expect_success 'prepare am_session' '\n \tgit reset --hard master &&\n \tgit checkout -b am_session &&\ndiff --git a/wt-status.c b/wt-status.c\nindex fcde045..5c0706b 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -12,6 +12,7 @@\n #include \"refs.h\"\n #include \"submodule.h\"\n #include \"column.h\"\n+#include \"strbuf.h\"\n \n static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n@@ -817,6 +818,52 @@ static void show_am_in_progress(struct wt_status *s,\n \twt_status_print_trailer(s);\n }\n \n+static char *read_line_from_git_path(const char *filename)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tFILE *fp = fopen(git_path(filename), \"r\");\n+\tif (!fp) {\n+\t\tstrbuf_release(&buf);\n+\t\treturn NULL;\n+\t}\n+\tstrbuf_getline(&buf, fp, '\\n');\n+\tif (!fclose(fp)) {\n+\t\treturn strbuf_detach(&buf, NULL);\n+\t} else {\n+\t\tstrbuf_release(&buf);\n+\t\treturn NULL;\n+\t}\n+}\n+\n+static int split_commit_in_progress(struct wt_status *s)\n+{\n+\tint split_in_progress = 0;\n+\tconst char *head = read_line_from_git_path(\"HEAD\");\n+\tconst char *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n+\tconst char *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n+\tconst char *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n+\n+\tif (!head || !orig_head || !rebase_amend ||\n+\t\t\t!rebase_orig_head || !prefixcmp(head, \"refs/heads/\"))\n+\t\treturn split_in_progress;\n+\n+\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n+\t\tif (strcmp(head, rebase_amend))\n+\t\t\tsplit_in_progress = 1;\n+\t} else if (strcmp(orig_head, rebase_orig_head)) {\n+\t\tsplit_in_progress = 1;\n+\t}\n+\n+\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n+\t\tsplit_in_progress = 0;\n+\n+\tfree((char*)head);\n+\tfree((char*)orig_head);\n+\tfree((char*)rebase_amend);\n+\tfree((char*)rebase_orig_head);\n+\treturn split_in_progress;\n+}\n+\n static void show_rebase_in_progress(struct wt_status *s,\n \t\t\t\tstruct wt_status_state *state,\n \t\t\t\tconst char *color)\n@@ -838,6 +885,11 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\tif (advice_status_hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else if (split_commit_in_progress(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently splitting a commit.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (Once your working directory is clean, run \\\"git rebase --continue\\\")\"));\n \t} else {\n \t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n \t\tif (advice_status_hints && !s->amend) {\n-- \n1.7.8\n"},{"id":"193092","messageId":"7vpq9bgfne.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1339075029-27109-4-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv9 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-07T18:07:01Z","receivedAt":"2012-06-07T18:07:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +static int split_commit_in_progress(struct wt_status *s)\n> +{\n> +\tint split_in_progress = 0;\n> +\tconst char *head = read_line_from_git_path(\"HEAD\");\n> +\tconst char *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n> +\tconst char *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n> +\tconst char *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n\nBy declaring these newly allocated memory you own in this function\nand free() yourself as \"const char *\", the only thing you are\ngaining is the need to cast constness away when you call free().\n\nWhy are these necessary?\n\n> +\tif (!head || !orig_head || !rebase_amend ||\n> +\t\t\t!rebase_orig_head || !prefixcmp(head, \"refs/heads/\"))\n> +\t\treturn split_in_progress;\n\nCan't .git/HEAD be a symlinked symref?\n"},{"id":"193108","messageId":"7v8vfyg8ga.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1339075029-27109-4-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv9 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-07T20:42:29Z","receivedAt":"2012-06-07T20:42:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:\n\n> +static char *read_line_from_git_path(const char *filename)\n> +{\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tFILE *fp = fopen(git_path(filename), \"r\");\n\nWe currently do not pass any filename with per-cent in it, but that\ncall should be git_path(\"%s\", filename) for sanity.\n"},{"id":"193113","messageId":"20120607230527.Horde.vsZkPXwdC4BP0ReXmNcTX0A@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7v8vfyg8ga.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv9 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-07T21:05:27Z","receivedAt":"2012-06-07T21:05:27Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n> Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:\n>\n>> +static char *read_line_from_git_path(const char *filename)\n>> +{\n>> +\tstruct strbuf buf = STRBUF_INIT;\n>> +\tFILE *fp = fopen(git_path(filename), \"r\");\n>\n> We currently do not pass any filename with per-cent in it, but that\n> call should be git_path(\"%s\", filename) for sanity.\n\nThanks, that should fix our problem (sometimes, a warning message appears\nduring compilation about this line and we didn't know what to change).\n"},{"id":"193137","messageId":"20120608112945.Horde.I4abIHwdC4BP0cYJzywVAeA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7vfwa9o3xo.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv8 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-08T09:29:45Z","receivedAt":"2012-06-08T09:29:45Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n> Reading from git_path(\"HEAD\") looked funny, as you may end up\n> reading the \"ref: refs/heads/master\".  Of course that would not\n> compare equal to what you would read from \"rebase-merge/amend\", and\n> that may be fine for the purpose of your test, but it still looks\n> somewhat funny.  As modern rebase is done on a detached HEAD,\n> perhaps it is a good idea to check if the HEAD is detached and\n> return false from this function if that is not the case.  I dunno.\n\nOn second thoughts, I do not think that checking if HEAD is detached\nor not is needed, as the part of the code that includes reading can\nonly be called during a rebase interactive, in which case the HEAD\ncan only be detached.\n"},{"id":"193160","messageId":"7vzk8ddeua.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"20120608112945.Horde.I4abIHwdC4BP0cYJzywVAeA@webmail.minatec.grenoble-inp.fr","subject":"Re: [PATCHv8 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-08T15:05:01Z","receivedAt":"2012-06-08T15:05:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"konglu@minatec.inpg.fr writes:\n\n>> Reading from git_path(\"HEAD\") looked funny, as you may end up\n>> reading the \"ref: refs/heads/master\".  Of course that would not\n>> compare equal to what you would read from \"rebase-merge/amend\", and\n>> that may be fine for the purpose of your test, but it still looks\n>> somewhat funny.  As modern rebase is done on a detached HEAD,\n>> perhaps it is a good idea to check if the HEAD is detached and\n>> return false from this function if that is not the case.  I dunno.\n>\n> On second thoughts, I do not think that checking if HEAD is detached\n> or not is needed, as the part of the code that includes reading can\n> only be called during a rebase interactive, in which case the HEAD\n> can only be detached.\n\n\"can only be detached\" is making a huge assumption.\n\nI'd rather see a code that verifies that the assumption still holds\nafter changes are made to other parts of the system and gracefully\ndegrade its behaviour when the assumption it makes no longer holds.\n\nBesides, making sure that the HEAD is detached when you _think_ you\nare in the middle of a rebase is a necessary part of catching and\nreporting a potential mistake like this, no?\n\n\t$ git checkout -b throwaway\n        $ git rebase --onto HEAD~5 HEAD~2\n        ... conflicts ...\n        $ git checkout throwaway\n"},{"id":"193248","messageId":"1339327058-29371-1-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339075029-27109-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv10 1/4] wt-status.*: better advices for git status added","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-10T11:17:35Z","receivedAt":"2012-06-10T11:17:35Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"This patch provides new informative help messages in the display of\n'git status' (at the top) during conflicts, rebase, am, bisect or\ncherry-pick process.\n\nThe new messages are not shown when using options such as -s or\n--porcelain. The messages about the current situation of the user are\nalways displayed but the advices on what the user needs to do in order\nto resume a rebase/bisect/am/commit after resolving conflicts can be\nhidden by setting advice.statushints to 'false' in the config file.\n\nThus, information about the updated advice.statushints key are added\nin Documentation/config.txt.\n\nAlso, the test t7060-wt-status.sh is now working with the new help\nmessages. Tests about suggestions of \"git rm\" are also added.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\npart 1/4 unchanged since v9.\n\n Documentation/config.txt |    7 +-\n t/t7060-wtstatus.sh      |   64 ++++++++++++++++++\n wt-status.c              |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.h              |   11 +++\n 4 files changed, 242 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 915cb5a..ccce4f6 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -159,9 +159,10 @@ advice.*::\n \t\tspecified a refspec that isn't your current branch) and\n \t\tit resulted in a non-fast-forward error.\n \tstatusHints::\n-\t\tDirections on how to stage/unstage/add shown in the\n-\t\toutput of linkgit:git-status[1] and the template shown\n-\t\twhen writing commit messages.\n+\t\tShow directions on how to proceed from the current\n+\t\tstate in the output of linkgit:git-status[1] and in\n+\t\tthe template shown when writing commit messages in\n+\t\tlinkgit:git-commit[1].\n \tcommitBeforeMerge::\n \t\tAdvice shown when linkgit:git-merge[1] refuses to\n \t\tmerge to avoid overwriting local changes.\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex b8cb490..e8c3690 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' '\n \n cat >expect <<EOF\n # On branch side\n+# You have unmerged paths.\n+#   (fix conflicts and run \"git commit\")\n+#\n # Unmerged paths:\n #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n #\n@@ -118,4 +121,65 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '\n \ttest_cmp expected actual\n '\n \n+\n+test_expect_success 'status when conflicts with add and rm advice (deleted by them)' '\n+\tgit reset --hard &&\n+\tgit checkout master &&\n+\ttest_commit init main.txt init &&\n+\tgit checkout -b second_branch &&\n+\tgit rm main.txt &&\n+\tgit commit -m \"main.txt deleted on second_branch\" &&\n+\ttest_commit second conflict.txt second &&\n+\tgit checkout master &&\n+\ttest_commit on_second main.txt on_second &&\n+\ttest_commit master conflict.txt master &&\n+\ttest_must_fail git merge second_branch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch master\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth added:         conflict.txt\n+\t#\tdeleted by them:    main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+\tgit reset --hard &&\n+\tgit checkout -b conflict &&\n+\ttest_commit one main.txt one &&\n+\tgit branch conflict_second &&\n+\tgit mv main.txt sub_master.txt &&\n+\tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n+\tgit checkout conflict_second &&\n+\tgit mv main.txt sub_second.txt &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\ttest_must_fail git merge conflict &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\tadded by them:      sub_master.txt\n+\t#\tadded by us:        sub_second.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n test_done\ndiff --git a/wt-status.c b/wt-status.c\nindex dd6d8c4..7548509 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -23,6 +23,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_GREEN,  /* WT_STATUS_LOCAL_BRANCH */\n \tGIT_COLOR_RED,    /* WT_STATUS_REMOTE_BRANCH */\n \tGIT_COLOR_NIL,    /* WT_STATUS_ONBRANCH */\n+\tGIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */\n };\n \n static const char *color(int slot, struct wt_status *s)\n@@ -728,6 +729,167 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n+static int has_unmerged(struct wt_status *s)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct wt_status_change_data *d;\n+\t\td = s->change.items[i].util;\n+\t\tif (d->stagemask)\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+static void show_merge_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You have unmerged paths.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"All conflicts fixed but you are still merging.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit\\\" to conclude merge)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_am_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color,\n+\t\t_(\"You are in the middle of an am session.\"));\n+\tif (state->am_empty_patch)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"The current patch is empty.\"));\n+\tif (advice_status_hints) {\n+\t\tif (!state->am_empty_patch)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git am --resolved\\\")\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --skip\\\" to skip this patch)\"));\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git am --abort\\\" to restore the original branch)\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_rebase_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstruct stat st;\n+\n+\tif (has_unmerged(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and then run \\\"git rebase --continue\\\")\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --skip\\\" to skip this patch)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --abort\\\" to check out the original branch)\"));\n+\t\t}\n+\t} else if (state->rebase_in_progress || !stat(git_path(\"MERGE_MSG\"), &st)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently rebasing.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n+\t\tif (advice_status_hints && !s->amend) {\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git commit --amend\\\" to amend the current commit)\"));\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (use \\\"git rebase --continue\\\" once you are satisfied with your changes)\"));\n+\t\t}\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_cherry_pick_in_progress(struct wt_status *s,\n+\t\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently cherry-picking.\"));\n+\tif (advice_status_hints) {\n+\t\tif (has_unmerged(s))\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (fix conflicts and run \\\"git commit\\\")\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (all conflicts fixed: run \\\"git commit\\\")\"));\n+\t}\n+\twt_status_print_trailer(s);\n+}\n+\n+static void show_bisect_in_progress(struct wt_status *s,\n+\t\t\t\tstruct wt_status_state *state,\n+\t\t\t\tconst char *color)\n+{\n+\tstatus_printf_ln(s, color, _(\"You are currently bisecting.\"));\n+\tif (advice_status_hints)\n+\t\tstatus_printf_ln(s, color,\n+\t\t\t_(\"  (use \\\"git bisect reset\\\" to get back to the original branch)\"));\n+\twt_status_print_trailer(s);\n+}\n+\n+static void wt_status_print_state(struct wt_status *s)\n+{\n+\tconst char *state_color = color(WT_STATUS_IN_PROGRESS, s);\n+\tstruct wt_status_state *state = calloc(1, sizeof(*state));\n+\tstruct stat st;\n+\n+\tstate->merge_in_progress = 0;\n+\tstate->am_in_progress = 0;\n+\tstate->am_empty_patch = 0;\n+\tstate->rebase_in_progress = 0;\n+\tstate->rebase_interactive_in_progress = 0;\n+\tstate->cherry_pick_in_progress = 0;\n+\tstate->bisect_in_progress = 0;\n+\n+\tif (!stat(git_path(\"MERGE_HEAD\"), &st)) {\n+\t\tstate->merge_in_progress = 1;\n+\t} else if (!stat(git_path(\"rebase-apply\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-apply/applying\"), &st)) {\n+\t\t\tstate->am_in_progress = 1;\n+\t\t\tif (!stat(git_path(\"rebase-apply/patch\"), &st) && !st.st_size)\n+\t\t\t\tstate->am_empty_patch = 1;\n+\t\t} else {\n+\t\t\tstate->rebase_in_progress = 1;\n+\t\t}\n+\t} else if (!stat(git_path(\"rebase-merge\"), &st)) {\n+\t\tif (!stat(git_path(\"rebase-merge/interactive\"), &st))\n+\t\t\tstate->rebase_interactive_in_progress = 1;\n+\t\telse\n+\t\t\tstate->rebase_in_progress = 1;\n+\t} else if (!stat(git_path(\"CHERRY_PICK_HEAD\"), &st)) {\n+\t\tstate->cherry_pick_in_progress = 1;\n+\t}\n+\tif (!stat(git_path(\"BISECT_LOG\"), &st))\n+\t\tstate->bisect_in_progress = 1;\n+\n+\tif (state->merge_in_progress)\n+\t\tshow_merge_in_progress(s, state, state_color);\n+\telse if (state->am_in_progress)\n+\t\tshow_am_in_progress(s, state, state_color);\n+\telse if (state->rebase_in_progress || state->rebase_interactive_in_progress)\n+\t\tshow_rebase_in_progress(s, state, state_color);\n+\telse if (state->cherry_pick_in_progress)\n+\t\tshow_cherry_pick_in_progress(s, state, state_color);\n+\tif (state->bisect_in_progress)\n+\t\tshow_bisect_in_progress(s, state, state_color);\n+\tfree(state);\n+}\n+\n void wt_status_print(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_ONBRANCH, s);\n@@ -750,6 +912,7 @@ void wt_status_print(struct wt_status *s)\n \t\t\twt_status_print_tracking(s);\n \t}\n \n+\twt_status_print_state(s);\n \tif (s->is_initial) {\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), \"\");\n \t\tstatus_printf_ln(s, color(WT_STATUS_HEADER, s), _(\"Initial commit\"));\ndiff --git a/wt-status.h b/wt-status.h\nindex 14aa9f7..c1066a0 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -15,6 +15,7 @@ enum color_wt_status {\n \tWT_STATUS_LOCAL_BRANCH,\n \tWT_STATUS_REMOTE_BRANCH,\n \tWT_STATUS_ONBRANCH,\n+\tWT_STATUS_IN_PROGRESS,\n \tWT_STATUS_MAXSLOT\n };\n \n@@ -71,6 +72,16 @@ struct wt_status {\n \tstruct string_list ignored;\n };\n \n+struct wt_status_state {\n+\tint merge_in_progress;\n+\tint am_in_progress;\n+\tint am_empty_patch;\n+\tint rebase_in_progress;\n+\tint rebase_interactive_in_progress;\n+\tint cherry_pick_in_progress;\n+\tint bisect_in_progress;\n+};\n+\n void wt_status_prepare(struct wt_status *s);\n void wt_status_print(struct wt_status *s);\n void wt_status_collect(struct wt_status *s);\n-- \n1.7.8\n"},{"id":"193246","messageId":"1339327058-29371-2-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339327058-29371-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv10 2/4] t7512-status-help.sh: better advices for git status","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-10T11:17:36Z","receivedAt":"2012-06-10T11:17:36Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The following tests include several cases in which the user needs to\nrun 'git status' to know his current situation, whether there're\nconflicts or he's in rebase/bisect/am/cherry-pick progress.\n\nOne of the test is about the set of the advice.statushints config key\nto 'false' in .git/config.\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\npart 2/4 unchanged since v9.\n\n t/t7512-status-help.sh |  372 ++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 372 insertions(+), 0 deletions(-)\n create mode 100755 t/t7512-status-help.sh\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nnew file mode 100755\nindex 0000000..3714e8e\n--- /dev/null\n+++ b/t/t7512-status-help.sh\n@@ -0,0 +1,372 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,\n+#\t\t     Thomas Nguy, Khoi Nguyen\n+#\t\t     Grenoble INP Ensimag\n+#\n+\n+test_description='git status advices'\n+\n+. ./test-lib.sh\n+\n+. \"$TEST_DIRECTORY\"/lib-rebase.sh\n+\n+set_fake_editor\n+\n+test_expect_success 'prepare for conflicts' '\n+\ttest_commit init main.txt init &&\n+\tgit branch conflicts &&\n+\ttest_commit on_master main.txt on_master &&\n+\tgit checkout conflicts &&\n+\ttest_commit on_conflicts main.txt on_conflicts\n+'\n+\n+\n+test_expect_success 'status when conflicts unresolved' '\n+\ttest_must_fail git merge master &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflicts\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when conflicts resolved before commit' '\n+\tgit reset --hard conflicts &&\n+\ttest_must_fail git merge master &&\n+\techo one >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflicts\n+\t# All conflicts fixed but you are still merging.\n+\t#   (use \"git commit\" to conclude merge)\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for rebase conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_conflicts &&\n+\ttest_commit one_rebase main.txt one &&\n+\ttest_commit two_rebase main.txt two &&\n+\ttest_commit three_rebase main.txt three\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before resolving conflicts' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase in progress before rebase --continue' '\n+\tgit reset --hard rebase_conflicts &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\techo three >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for rebase_i_conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_i_conflicts &&\n+\ttest_commit one_unmerge main.txt one_unmerge &&\n+\tgit branch rebase_i_conflicts_second &&\n+\ttest_commit one_master main.txt one_master &&\n+\tgit checkout rebase_i_conflicts_second &&\n+\ttest_commit one_second main.txt one_second\n+'\n+\n+\n+test_expect_success 'status during rebase -i when conflicts unresolved' '\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase -i rebase_i_conflicts &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (fix conflicts and then run \"git rebase --continue\")\n+\t#   (use \"git rebase --skip\" to skip this patch)\n+\t#   (use \"git rebase --abort\" to check out the original branch)\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status during rebase -i after resolving conflicts' '\n+\tgit reset --hard rebase_i_conflicts_second &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase -i rebase_i_conflicts &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#   (all conflicts fixed: run \"git rebase --continue\")\n+\t#\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebasing -i in edit mode' '\n+\tgit reset --hard master &&\n+\tgit checkout -b rebase_i_edit &&\n+\ttest_commit one_rebase_i main.txt one &&\n+\ttest_commit two_rebase_i main.txt two &&\n+\ttest_commit three_rebase_i main.txt three &&\n+\tFAKE_LINES=\"1 edit 2\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~2 &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare am_session' '\n+\tgit reset --hard master &&\n+\tgit checkout -b am_session &&\n+\ttest_commit one_am one.txt \"one\" &&\n+\ttest_commit two_am two.txt \"two\" &&\n+\ttest_commit three_am three.txt \"three\"\n+'\n+\n+\n+test_expect_success 'status in an am session: file already exists' '\n+\tgit checkout -b am_already_exists &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_already_exists\n+\t# You are in the middle of an am session.\n+\t#   (fix conflicts and then run \"git am --resolved\")\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: file does not exist' '\n+\tgit reset --hard am_session &&\n+\tgit checkout -b am_not_exists &&\n+\tgit rm three.txt &&\n+\tgit commit -m \"delete three.txt\" &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -1 -oMaildir &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_not_exists\n+\t# You are in the middle of an am session.\n+\t#   (fix conflicts and then run \"git am --resolved\")\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status in an am session: empty patch' '\n+\tgit reset --hard am_session &&\n+\tgit checkout -b am_empty &&\n+\ttest_when_finished \"rm Maildir/* && git am --abort\" &&\n+\tgit format-patch -3 -oMaildir &&\n+\tgit rm one.txt two.txt three.txt &&\n+\tgit commit -m \"delete all am_empty\" &&\n+\techo error >Maildir/0002-two_am.patch &&\n+\ttest_must_fail git am Maildir/*.patch &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch am_empty\n+\t# You are in the middle of an am session.\n+\t# The current patch is empty.\n+\t#   (use \"git am --skip\" to skip this patch)\n+\t#   (use \"git am --abort\" to restore the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when bisecting' '\n+\tgit reset --hard master &&\n+\tgit checkout -b bisect &&\n+\ttest_commit one_bisect main.txt one &&\n+\ttest_commit two_bisect main.txt two &&\n+\ttest_commit three_bisect main.txt three &&\n+\ttest_when_finished \"git bisect reset\" &&\n+\tgit bisect start &&\n+\tgit bisect bad &&\n+\tgit bisect good one_bisect &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently bisecting.\n+\t#   (use \"git bisect reset\" to get back to the original branch)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when rebase conflicts with statushints disabled' '\n+\tgit reset --hard master &&\n+\tgit checkout -b statushints_disabled &&\n+\ttest_when_finished \"git config --local advice.statushints true\" &&\n+\tgit config --local advice.statushints false &&\n+\ttest_commit one_statushints main.txt one &&\n+\ttest_commit two_statushints main.txt two &&\n+\ttest_commit three_statushints main.txt three &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\ttest_must_fail git rebase HEAD^ --onto HEAD^^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently rebasing.\n+\t#\n+\t# Unmerged paths:\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for cherry-pick conflicts' '\n+\tgit reset --hard master &&\n+\tgit checkout -b cherry_branch &&\n+\ttest_commit one_cherry main.txt one &&\n+\ttest_commit two_cherries main.txt two &&\n+\tgit checkout -b cherry_branch_second &&\n+\ttest_commit second_cherry main.txt second &&\n+\tgit checkout cherry_branch &&\n+\ttest_commit three_cherries main.txt three\n+'\n+\n+\n+test_expect_success 'status when cherry-picking before resolving conflicts' '\n+\ttest_when_finished \"git cherry-pick --abort\" &&\n+\ttest_must_fail git cherry-pick cherry_branch_second &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch cherry_branch\n+\t# You are currently cherry-picking.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#\n+\t#\tboth modified:      main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status when cherry-picking after resolving conflicts' '\n+\tgit reset --hard cherry_branch &&\n+\ttest_when_finished \"git cherry-pick --abort\" &&\n+\ttest_must_fail git cherry-pick cherry_branch_second &&\n+\techo end >main.txt &&\n+\tgit add main.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch cherry_branch\n+\t# You are currently cherry-picking.\n+\t#   (all conflicts fixed: run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_done\n-- \n1.7.8\n"},{"id":"193247","messageId":"1339327058-29371-3-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339327058-29371-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv10 3/4] status: don't suggest \"git rm\" or \"git add\" if not appropriate","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-10T11:17:37Z","receivedAt":"2012-06-10T11:17:37Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"The display of the advice '(use git add/rm [...])' (when there are\nunmerged files) after running 'git status' is now depending of the\nmark, whether it's 'both deleted', 'deleted by us/them' or others. For\ninstance, when there is just one file that's marked as 'both deleted',\n'git status' shows '(use git rm [...])' and if there are two files,\none as 'both deleted' and the other as 'added by them', the advice is\n'(use git add/rm [...])'.\n\nThe previous tests in t7512-status-help.sh are updated.\n\nTest about the case of only 'both deleted' is added in\nt7060-wtstatus.sh\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\npart 3/4 unchanged since v9.\n\n t/t7060-wtstatus.sh    |   36 ++++++++++++++++++++++++++++++++++--\n t/t7512-status-help.sh |    8 ++++----\n wt-status.c            |   37 ++++++++++++++++++++++++++++++++++++-\n 3 files changed, 74 insertions(+), 7 deletions(-)\n\ndiff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh\nindex e8c3690..f4f38a5 100755\n--- a/t/t7060-wtstatus.sh\n+++ b/t/t7060-wtstatus.sh\n@@ -152,7 +152,7 @@ test_expect_success 'status when conflicts with add and rm advice (deleted by th\n '\n \n \n-test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n+test_expect_success 'prepare for conflicts' '\n \tgit reset --hard &&\n \tgit checkout -b conflict &&\n \ttest_commit one main.txt one &&\n@@ -161,7 +161,11 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n \tgit commit -m \"main.txt renamed in sub_master.txt\" &&\n \tgit checkout conflict_second &&\n \tgit mv main.txt sub_second.txt &&\n-\tgit commit -m \"main.txt renamed in sub_second.txt\" &&\n+\tgit commit -m \"main.txt renamed in sub_second.txt\"\n+'\n+\n+\n+test_expect_success 'status when conflicts with add and rm advice (both deleted)' '\n \ttest_must_fail git merge conflict &&\n \tcat >expected <<-\\EOF &&\n \t# On branch conflict_second\n@@ -182,4 +186,32 @@ test_expect_success 'status when conflicts with add and rm advice (both deleted)\n '\n \n \n+test_expect_success 'status when conflicts with only rm advice (both deleted)' '\n+\tgit reset --hard conflict_second &&\n+\ttest_must_fail git merge conflict &&\n+\tgit add sub_master.txt &&\n+\tgit add sub_second.txt &&\n+\tcat >expected <<-\\EOF &&\n+\t# On branch conflict_second\n+\t# You have unmerged paths.\n+\t#   (fix conflicts and run \"git commit\")\n+\t#\n+\t# Changes to be committed:\n+\t#\n+\t#\tnew file:   sub_master.txt\n+\t#\n+\t# Unmerged paths:\n+\t#   (use \"git rm <file>...\" to mark resolution)\n+\t#\n+\t#\tboth deleted:       main.txt\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual &&\n+\tgit reset --hard &&\n+\tgit checkout master\n+'\n+\n+\n test_done\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex 3714e8e..bdce192 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -30,7 +30,7 @@ test_expect_success 'status when conflicts unresolved' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -83,7 +83,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -140,7 +140,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '\n \t#\n \t# Unmerged paths:\n \t#   (use \"git reset HEAD <file>...\" to unstage)\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\n@@ -336,7 +336,7 @@ test_expect_success 'status when cherry-picking before resolving conflicts' '\n \t#   (fix conflicts and run \"git commit\")\n \t#\n \t# Unmerged paths:\n-\t#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n+\t#   (use \"git add <file>...\" to mark resolution)\n \t#\n \t#\tboth modified:      main.txt\n \t#\ndiff --git a/wt-status.c b/wt-status.c\nindex 7548509..fcde045 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -131,9 +131,34 @@ void wt_status_prepare(struct wt_status *s)\n \n static void wt_status_print_unmerged_header(struct wt_status *s)\n {\n+\tint i;\n+\tint del_mod_conflict = 0;\n+\tint both_deleted = 0;\n+\tint not_deleted = 0;\n \tconst char *c = color(WT_STATUS_HEADER, s);\n \n \tstatus_printf_ln(s, c, _(\"Unmerged paths:\"));\n+\n+\tfor (i = 0; i < s->change.nr; i++) {\n+\t\tstruct string_list_item *it = &(s->change.items[i]);\n+\t\tstruct wt_status_change_data *d = it->util;\n+\n+\t\tswitch (d->stagemask) {\n+\t\tcase 0:\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tboth_deleted = 1;\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\tcase 5:\n+\t\t\tdel_mod_conflict = 1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tnot_deleted = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (!advice_status_hints)\n \t\treturn;\n \tif (s->whence != FROM_COMMIT)\n@@ -142,7 +167,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s)\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git reset %s <file>...\\\" to unstage)\"), s->reference);\n \telse\n \t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm --cached <file>...\\\" to unstage)\"));\n-\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\n+\tif (!both_deleted) {\n+\t\tif (!del_mod_conflict)\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add <file>...\\\" to mark resolution)\"));\n+\t\telse\n+\t\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t} else if (!del_mod_conflict && !not_deleted) {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git rm <file>...\\\" to mark resolution)\"));\n+\t} else {\n+\t\tstatus_printf_ln(s, c, _(\"  (use \\\"git add/rm <file>...\\\" as appropriate to mark resolution)\"));\n+\t}\n \tstatus_printf_ln(s, c, \"\");\n }\n \n-- \n1.7.8\n"},{"id":"193245","messageId":"1339327058-29371-4-git-send-email-Lucien.Kong@ensimag.imag.fr","threadId":"30608","inReplyTo":"1339327058-29371-1-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"[PATCHv10 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Lucien Kong","fromEmail":"lucien.kong@ensimag.imag.fr","sentAt":"2012-06-10T11:17:38Z","receivedAt":"2012-06-10T11:17:38Z","isPatch":false,"sender":{"key":"lucien.kong@ensimag.imag.fr","avatar":null},"body":"Add new informative help messages at the output of 'git status' when\nthe user is splitting a commit. The code figures this state by\ncomparing the contents of the following files in the .git/ directory:\n\t  - HEAD\n\t  - ORIG_HEAD\n\t  - rebase-merge/amend\n\t  - rebase-merge/orig-head\n\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\nThe \"const\" have been dropped and the check about \"HEAD\" been\ndetached or not is fixed.\n\n t/t7512-status-help.sh |  277 ++++++++++++++++++++++++++++++++++++++++++++++++\n wt-status.c            |   51 +++++++++\n 2 files changed, 328 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh\nindex bdce192..3ce384a 100755\n--- a/t/t7512-status-help.sh\n+++ b/t/t7512-status-help.sh\n@@ -196,6 +196,283 @@ test_expect_success 'status when rebasing -i in edit mode' '\n '\n \n \n+test_expect_success 'status when splitting a commit' '\n+\tgit reset --hard master &&\n+\tgit checkout -b split_commit &&\n+\ttest_commit one_split main.txt one &&\n+\ttest_commit two_split main.txt two &&\n+\ttest_commit three_split main.txt three &&\n+\ttest_commit four_split main.txt four &&\n+\tFAKE_LINES=\"1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status after editing the last commit with --amend during a rebase -i' '\n+\tgit reset --hard master &&\n+\tgit checkout -b amend_last &&\n+\ttest_commit one_amend main.txt one &&\n+\ttest_commit two_amend main.txt two &&\n+\ttest_commit three_amend main.txt three &&\n+\ttest_commit four_amend main.txt four &&\n+\tFAKE_LINES=\"1 2 edit 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"foo\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'prepare for several edits' '\n+\tgit reset --hard master &&\n+\tgit checkout -b several_edits &&\n+\ttest_commit one_edits main.txt one &&\n+\ttest_commit two_edits main.txt two &&\n+\ttest_commit three_edits main.txt three &&\n+\ttest_commit four_edits main.txt four\n+'\n+\n+\n+test_expect_success 'status: (continue first edit) second edit' '\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit rebase --continue &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (continue first edit) second edit and split' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit rebase --continue &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (continue first edit) second edit and amend' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit rebase --continue &&\n+\tgit commit --amend -m \"foo\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (amend first edit) second edit' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"a\" &&\n+\tgit rebase --continue &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (amend first edit) second edit and split' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"b\" &&\n+\tgit rebase --continue &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (amend first edit) second edit and amend' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit commit --amend -m \"c\" &&\n+\tgit rebase --continue &&\n+\tgit commit --amend -m \"d\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (split first edit) second edit' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tgit add main.txt &&\n+\tgit commit -m \"e\" &&\n+\tgit rebase --continue &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (split first edit) second edit and split' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tgit add main.txt &&\n+\tgit commit --amend -m \"f\" &&\n+\tgit rebase --continue &&\n+\tgit reset HEAD^ &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently splitting a commit.\n+\t#   (Once your working directory is clean, run \"git rebase --continue\")\n+\t#\n+\t# Changes not staged for commit:\n+\t#   (use \"git add <file>...\" to update what will be committed)\n+\t#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\t#\n+\t#\tmodified:   main.txt\n+\t#\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n+test_expect_success 'status: (split first edit) second edit and amend' '\n+\tgit reset --hard several_edits &&\n+\tFAKE_LINES=\"edit 1 edit 2 3\" &&\n+\texport FAKE_LINES &&\n+\ttest_when_finished \"git rebase --abort\" &&\n+\tgit rebase -i HEAD~3 &&\n+\tgit reset HEAD^ &&\n+\tgit add main.txt &&\n+\tgit commit --amend -m \"g\" &&\n+\tgit rebase --continue &&\n+\tgit commit --amend -m \"h\" &&\n+\tcat >expected <<-\\EOF &&\n+\t# Not currently on any branch.\n+\t# You are currently editing a commit during a rebase.\n+\t#   (use \"git commit --amend\" to amend the current commit)\n+\t#   (use \"git rebase --continue\" once you are satisfied with your changes)\n+\t#\n+\tnothing to commit (use -u to show untracked files)\n+\tEOF\n+\tgit status --untracked-files=no >actual &&\n+\ttest_i18ncmp expected actual\n+'\n+\n+\n test_expect_success 'prepare am_session' '\n \tgit reset --hard master &&\n \tgit checkout -b am_session &&\ndiff --git a/wt-status.c b/wt-status.c\nindex fcde045..5496a1f 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -12,6 +12,7 @@\n #include \"refs.h\"\n #include \"submodule.h\"\n #include \"column.h\"\n+#include \"strbuf.h\"\n \n static char default_wt_status_colors[][COLOR_MAXLEN] = {\n \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n@@ -817,6 +818,51 @@ static void show_am_in_progress(struct wt_status *s,\n \twt_status_print_trailer(s);\n }\n \n+static char *read_line_from_git_path(const char *filename)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tFILE *fp = fopen(git_path(\"%s\", filename), \"r\");\n+\tif (!fp) {\n+\t\tstrbuf_release(&buf);\n+\t\treturn NULL;\n+\t}\n+\tstrbuf_getline(&buf, fp, '\\n');\n+\tif (!fclose(fp)) {\n+\t\treturn strbuf_detach(&buf, NULL);\n+\t} else {\n+\t\tstrbuf_release(&buf);\n+\t\treturn NULL;\n+\t}\n+}\n+\n+static int split_commit_in_progress(struct wt_status *s)\n+{\n+\tint split_in_progress = 0;\n+\tchar *head = read_line_from_git_path(\"HEAD\");\n+\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n+\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n+\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n+\n+\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head || !prefixcmp(head, \"ref: \"))\n+\t\treturn split_in_progress;\n+\n+\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n+\t\tif (strcmp(head, rebase_amend))\n+\t\t\tsplit_in_progress = 1;\n+\t} else if (strcmp(orig_head, rebase_orig_head)) {\n+\t\tsplit_in_progress = 1;\n+\t}\n+\n+\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n+\t\tsplit_in_progress = 0;\n+\n+\tfree(head);\n+\tfree(orig_head);\n+\tfree(rebase_amend);\n+\tfree(rebase_orig_head);\n+\treturn split_in_progress;\n+}\n+\n static void show_rebase_in_progress(struct wt_status *s,\n \t\t\t\tstruct wt_status_state *state,\n \t\t\t\tconst char *color)\n@@ -838,6 +884,11 @@ static void show_rebase_in_progress(struct wt_status *s,\n \t\tif (advice_status_hints)\n \t\t\tstatus_printf_ln(s, color,\n \t\t\t\t_(\"  (all conflicts fixed: run \\\"git rebase --continue\\\")\"));\n+\t} else if (split_commit_in_progress(s)) {\n+\t\tstatus_printf_ln(s, color, _(\"You are currently splitting a commit.\"));\n+\t\tif (advice_status_hints)\n+\t\t\tstatus_printf_ln(s, color,\n+\t\t\t\t_(\"  (Once your working directory is clean, run \\\"git rebase --continue\\\")\"));\n \t} else {\n \t\tstatus_printf_ln(s, color, _(\"You are currently editing a commit during a rebase.\"));\n \t\tif (advice_status_hints && !s->amend) {\n-- \n1.7.8\n"},{"id":"193369","messageId":"7vsje161lx.fsf@alter.siamese.dyndns.org","threadId":"30608","inReplyTo":"1339327058-29371-4-git-send-email-Lucien.Kong@ensimag.imag.fr","subject":"Re: [PATCHv10 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-11T20:21:46Z","receivedAt":"2012-06-11T20:21:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lucien Kong <Lucien.Kong@ensimag.imag.fr> writes:\n\n> Add new informative help messages at the output of 'git status' when\n> the user is splitting a commit. The code figures this state by\n> comparing the contents of the following files in the .git/ directory:\n> \t  - HEAD\n> \t  - ORIG_HEAD\n> \t  - rebase-merge/amend\n> \t  - rebase-merge/orig-head\n\nIt may be just me but I would find it easier to read if you had a\nblank line before this four-item enumerated list.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index fcde045..5496a1f 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -12,6 +12,7 @@\n>  #include \"refs.h\"\n>  #include \"submodule.h\"\n>  #include \"column.h\"\n> +#include \"strbuf.h\"\n>  \n>  static char default_wt_status_colors[][COLOR_MAXLEN] = {\n>  \tGIT_COLOR_NORMAL, /* WT_STATUS_HEADER */\n> @@ -817,6 +818,51 @@ static void show_am_in_progress(struct wt_status *s,\n>  \twt_status_print_trailer(s);\n>  }\n>  \n> +static char *read_line_from_git_path(const char *filename)\n> +{\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tFILE *fp = fopen(git_path(\"%s\", filename), \"r\");\n> +\tif (!fp) {\n> +\t\tstrbuf_release(&buf);\n> +\t\treturn NULL;\n> +\t}\n> +\tstrbuf_getline(&buf, fp, '\\n');\n> +\tif (!fclose(fp)) {\n> +\t\treturn strbuf_detach(&buf, NULL);\n> +\t} else {\n> +\t\tstrbuf_release(&buf);\n> +\t\treturn NULL;\n> +\t}\n> +}\n\nWith this code, read_line_from_git_path(\"HEAD\") will read:\n\n\t[0-9a-f]{40} when the HEAD is detached;\n\n        ref: refs/heads/<current-branch-name> when textual symref is\n        in use (and you are on the branch); or\n\n\t[0-9a-f]{40} stored in refs/heads/<current-branch-name> when\n\tsymlink symref is in use (and you are on the branch).\n\n> +static int split_commit_in_progress(struct wt_status *s)\n> +{\n> +\tint split_in_progress = 0;\n> +\tchar *head = read_line_from_git_path(\"HEAD\");\n> +\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n> +\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n> +\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n> +\n> +\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head || !prefixcmp(head, \"ref: \"))\n> +\t\treturn split_in_progress;\n\nI think the above\n\n\t!prefixcmp(head, \"ref: \")\n\nis probably a mistake; shouldn't it be\n\n\tstrcmp(s->branch, \"HEAD\")\n\nwhich is used in wt_status_print() to diagnose that you are on a\ndetached HEAD (which is the normal case)?  Otherwise head may point\nat the commit object name read from \"refs/heads/current\" through a\nsymbolic link .git/HEAD that points at \"refs/heads/current\".\n"},{"id":"193417","messageId":"20120612091412.Horde.lcugXXwdC4BP1uxEDLrRNgA@webmail.minatec.grenoble-inp.fr","threadId":"30608","inReplyTo":"7vsje161lx.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv10 4/4] status: better advices when splitting a commit (during rebase -i)","fromName":"","fromEmail":"konglu@minatec.inpg.fr","sentAt":"2012-06-12T07:14:12Z","receivedAt":"2012-06-12T07:14:12Z","isPatch":false,"sender":{"key":"konglu@minatec.inpg.fr","avatar":null},"body":"\nJunio C Hamano <gitster@pobox.com> a écrit :\n\n>> +static int split_commit_in_progress(struct wt_status *s)\n>> +{\n>> +\tint split_in_progress = 0;\n>> +\tchar *head = read_line_from_git_path(\"HEAD\");\n>> +\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n>> +\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n>> +\tchar *rebase_orig_head =  \n>> read_line_from_git_path(\"rebase-merge/orig-head\");\n>> +\n>> +\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||  \n>> !prefixcmp(head, \"ref: \"))\n>> +\t\treturn split_in_progress;\n>\n> I think the above\n>\n> \t!prefixcmp(head, \"ref: \")\n>\n> is probably a mistake; shouldn't it be\n>\n> \tstrcmp(s->branch, \"HEAD\")\n>\n> which is used in wt_status_print() to diagnose that you are on a\n> detached HEAD (which is the normal case)?  Otherwise head may point\n> at the commit object name read from \"refs/heads/current\" through a\n> symbolic link .git/HEAD that points at \"refs/heads/current\".\n\nAah, that's the variable I was looking for.\nThanks for fixing it up :).\n\nLucien Kong\n"}]}