{"thread":{"id":"24501","subject":"[RFC/PATCH 0/9] commit: more focused advice in the no-changes-staged case","startedAt":"2010-07-25T00:54:43Z","lastAt":"2010-08-20T17:51:37Z","messageCount":38,"participants":["Jonathan Nieder","Ævar Arnfjörð Bjarmason","Thomas Rast","Sverre Rabbelier","Nguyen Thai Ngoc Duy","Matthieu Moy","Raja R Harinath","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"146229","messageId":"20100725005443.GA18370@burratino","threadId":"24501","inReplyTo":null,"subject":"[RFC/PATCH 0/9] commit: more focused advice in the no-changes-staged case","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:54:43Z","receivedAt":"2010-07-25T00:54:43Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nWhen last seen[1], this series was a single patch in very rough form,\nbut there have been almost no functional changes since then.\n\nThe patches suppress most output when “git commit” is run without\nstages changed.  So instead of\n\n\t$ git commit\n\t# On branch master\n\t# Changed but not updated:\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:   dir1/modified\n\t#\n\t# Untracked files:\n\t#   (use \"git add <file>...\" to include in what will be committed)\n\t#\n\t#\tactual\n\t#\tdir1/untracked\n\t#\tdir2/modified\n\t#\tdir2/untracked\n\t#\texpect\n\t#\toutput\n\t#\tuntracked\n\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\nwhich may cause a newcomer to panic, you get\n\n\t$ git commit\n\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\nwhich would just cause her to scratch her head or say “oh, right!”\ninstead.  Hopefully these patches will at least provide a reminder to\nimprove the various \"no changes\" advice messages.\n\nIdeas for future work:\n\n - add some tests\n - give the full traditional output if -a or any paths were passed on\n   the command line.\n\nMost of the patches are code clarity improvements which is not\nstrictly related to this topic.\n\nPatch 6 cleans up the most obvious script to add tests for this in,\nthough I have not added any tests to it.\n\nPatch 8 changes commit --dry-run output in a more modest way, to\nprint the same advice Jeff added to commit proper last month.  I\nsuspect this is a good change, but input from people who script\naround commit --dry-run would be welcome.\n\nPatch 9 is the advertised patch.  It should be self-explanatory.\n\nThoughts?\n\nJonathan Nieder (9):\n  wt-status: split wt_status_print into digestible pieces\n  wt-status: give submodule summary printing its own function\n  commit: split off a function to fetch the default log message\n  commit: encapsulate commit -s handling in its own function\n  commit: split off the piece that writes status\n  t7508 (status): modernize style\n  commit: give empty-commit avoidance code its own function\n  commit --dry-run: give advice on empty amend\n  commit: suppress status summary when no changes staged\n\n builtin/commit.c  |  328 ++++++++------\n t/t7508-status.sh | 1380 ++++++++++++++++++++++++++++-------------------------\n wt-status.c       |  103 +++--\n wt-status.h       |    1 +\n 4 files changed, 989 insertions(+), 823 deletions(-)\n\n[1] http://thread.gmane.org/gmane.linux.debian.devel.bugs.general/698001/focus=145541\n"},{"id":"146230","messageId":"20100725005626.GA18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 1/9] wt-status: split wt_status_print into digestible pieces","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:56:26Z","receivedAt":"2010-07-25T00:56:26Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The result does not fit on a 24-line terminal yet, but it’s\ngetting close.  No functional change intended.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n wt-status.c |   85 ++++++++++++++++++++++++++++++++---------------------------\n 1 files changed, 46 insertions(+), 39 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 2f9e33c..b0f17cf 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -604,6 +604,31 @@ static void wt_status_print_verbose(struct wt_status *s)\n \trun_diff_index(&rev, 1);\n }\n \n+static void wt_status_print_nochanges(struct wt_status *s)\n+{\n+\tif (s->amend)\n+\t\tfprintf(s->fp, \"# No changes\\n\");\n+\telse if (s->nowarn)\n+\t\t; /* nothing */\n+\telse if (s->workdir_dirty)\n+\t\tprintf(\"no changes added to commit%s\\n\",\n+\t\t\tadvice_status_hints\n+\t\t\t? \" (use \\\"git add\\\" and/or \\\"git commit -a\\\")\" : \"\");\n+\telse if (s->untracked.nr)\n+\t\tprintf(\"nothing added to commit but untracked files present%s\\n\",\n+\t\t\tadvice_status_hints\n+\t\t\t? \" (use \\\"git add\\\" to track)\" : \"\");\n+\telse if (s->is_initial)\n+\t\tprintf(\"nothing to commit%s\\n\", advice_status_hints\n+\t\t\t? \" (create/copy files and use \\\"git add\\\" to track)\" : \"\");\n+\telse if (!s->show_untracked_files)\n+\t\tprintf(\"nothing to commit%s\\n\", advice_status_hints\n+\t\t\t? \" (use -u to show untracked files)\" : \"\");\n+\telse\n+\t\tprintf(\"nothing to commit%s\\n\", advice_status_hints\n+\t\t\t? \" (working directory clean)\" : \"\");\n+}\n+\n static void wt_status_print_tracking(struct wt_status *s)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n@@ -623,25 +648,28 @@ static void wt_status_print_tracking(struct wt_status *s)\n \tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n }\n \n-void wt_status_print(struct wt_status *s)\n+static void wt_status_print_onbranch(struct wt_status *s)\n {\n \tconst char *branch_color = color(WT_STATUS_HEADER, s);\n-\n-\tif (s->branch) {\n-\t\tconst char *on_what = \"On branch \";\n-\t\tconst char *branch_name = s->branch;\n-\t\tif (!prefixcmp(branch_name, \"refs/heads/\"))\n-\t\t\tbranch_name += 11;\n-\t\telse if (!strcmp(branch_name, \"HEAD\")) {\n-\t\t\tbranch_name = \"\";\n-\t\t\tbranch_color = color(WT_STATUS_NOBRANCH, s);\n-\t\t\ton_what = \"Not currently on any branch.\";\n-\t\t}\n-\t\tcolor_fprintf(s->fp, color(WT_STATUS_HEADER, s), \"# \");\n-\t\tcolor_fprintf_ln(s->fp, branch_color, \"%s%s\", on_what, branch_name);\n-\t\tif (!s->is_initial)\n-\t\t\twt_status_print_tracking(s);\n+\tconst char *on_what = \"On branch \";\n+\tconst char *branch_name = s->branch;\n+\tif (!prefixcmp(branch_name, \"refs/heads/\"))\n+\t\tbranch_name += 11;\n+\telse if (!strcmp(branch_name, \"HEAD\")) {\n+\t\tbranch_name = \"\";\n+\t\tbranch_color = color(WT_STATUS_NOBRANCH, s);\n+\t\ton_what = \"Not currently on any branch.\";\n \t}\n+\tcolor_fprintf(s->fp, color(WT_STATUS_HEADER, s), \"# \");\n+\tcolor_fprintf_ln(s->fp, branch_color, \"%s%s\", on_what, branch_name);\n+\tif (!s->is_initial)\n+\t\twt_status_print_tracking(s);\n+}\n+\n+void wt_status_print(struct wt_status *s)\n+{\n+\tif (s->branch)\n+\t\twt_status_print_onbranch(s);\n \n \tif (s->is_initial) {\n \t\tcolor_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), \"#\");\n@@ -669,29 +697,8 @@ void wt_status_print(struct wt_status *s)\n \n \tif (s->verbose)\n \t\twt_status_print_verbose(s);\n-\tif (!s->commitable) {\n-\t\tif (s->amend)\n-\t\t\tfprintf(s->fp, \"# No changes\\n\");\n-\t\telse if (s->nowarn)\n-\t\t\t; /* nothing */\n-\t\telse if (s->workdir_dirty)\n-\t\t\tprintf(\"no changes added to commit%s\\n\",\n-\t\t\t\tadvice_status_hints\n-\t\t\t\t? \" (use \\\"git add\\\" and/or \\\"git commit -a\\\")\" : \"\");\n-\t\telse if (s->untracked.nr)\n-\t\t\tprintf(\"nothing added to commit but untracked files present%s\\n\",\n-\t\t\t\tadvice_status_hints\n-\t\t\t\t? \" (use \\\"git add\\\" to track)\" : \"\");\n-\t\telse if (s->is_initial)\n-\t\t\tprintf(\"nothing to commit%s\\n\", advice_status_hints\n-\t\t\t\t? \" (create/copy files and use \\\"git add\\\" to track)\" : \"\");\n-\t\telse if (!s->show_untracked_files)\n-\t\t\tprintf(\"nothing to commit%s\\n\", advice_status_hints\n-\t\t\t\t? \" (use -u to show untracked files)\" : \"\");\n-\t\telse\n-\t\t\tprintf(\"nothing to commit%s\\n\", advice_status_hints\n-\t\t\t\t? \" (working directory clean)\" : \"\");\n-\t}\n+\tif (!s->commitable)\n+\t\twt_status_print_nochanges(s);\n }\n \n static void wt_shortstatus_unmerged(int null_termination, struct string_list_item *it,\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146231","messageId":"20100725005747.GB18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 2/9] wt-status: split off a function for printing submodule summary","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:57:47Z","receivedAt":"2010-07-25T00:57:47Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"This only shaves a couple lines from wt_status_print().\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n wt-status.c |   18 +++++++++++-------\n 1 files changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex b0f17cf..90a0824 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -522,7 +522,7 @@ static void wt_status_print_changed(struct wt_status *s)\n \twt_status_print_trailer(s);\n }\n \n-static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted)\n+static void do_submodule_summary(struct wt_status *s, int uncommitted)\n {\n \tstruct child_process sm_summary;\n \tchar summary_limit[64];\n@@ -553,6 +553,14 @@ static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitt\n \trun_command(&sm_summary);\n }\n \n+static void wt_status_print_submodule_summary(struct wt_status *s)\n+{\n+\tif (s->ignore_submodule_arg && !strcmp(s->ignore_submodule_arg, \"all\"))\n+\t\treturn;\n+\tdo_submodule_summary(s, 0);  /* staged */\n+\tdo_submodule_summary(s, 1);  /* unstaged */\n+}\n+\n static void wt_status_print_other(struct wt_status *s,\n \t\t\t\t  struct string_list *l,\n \t\t\t\t  const char *what,\n@@ -680,12 +688,8 @@ void wt_status_print(struct wt_status *s)\n \twt_status_print_updated(s);\n \twt_status_print_unmerged(s);\n \twt_status_print_changed(s);\n-\tif (s->submodule_summary &&\n-\t    (!s->ignore_submodule_arg ||\n-\t     strcmp(s->ignore_submodule_arg, \"all\"))) {\n-\t\twt_status_print_submodule_summary(s, 0);  /* staged */\n-\t\twt_status_print_submodule_summary(s, 1);  /* unstaged */\n-\t}\n+\tif (s->submodule_summary)\n+\t\twt_status_print_submodule_summary(s);\n \tif (s->show_untracked_files) {\n \t\twt_status_print_other(s, &s->untracked, \"Untracked\", \"add\");\n \t\tif (s->show_ignored_files)\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146232","messageId":"20100725005808.GC18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 3/9] commit: split off a function to fetch the default log message","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:58:08Z","receivedAt":"2010-07-25T00:58:08Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The details of how the default message template is grabbed from\nMERGE_MSG will be irrelevant to most people reading the commit\npreparation code.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/commit.c |   94 +++++++++++++++++++++++++++++++----------------------\n 1 files changed, 55 insertions(+), 39 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex a78dbd8..6774180 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -549,62 +549,78 @@ static int ends_rfc2822_footer(struct strbuf *sb)\n \treturn 1;\n }\n \n-static int prepare_to_commit(const char *index_file, const char *prefix,\n-\t\t\t     struct wt_status *s)\n+/*\n+ * Return value is the \"source\" argument for hooks/prepare-commit-msg.\n+ */\n+static const char *get_template_message(struct strbuf *sb,\n+\t\t\t\t\tconst char **hook_arg2)\n {\n \tstruct stat statbuf;\n-\tint commitable, saved_color_setting;\n-\tstruct strbuf sb = STRBUF_INIT;\n-\tchar *buffer;\n-\tFILE *fp;\n-\tconst char *hook_arg1 = NULL;\n-\tconst char *hook_arg2 = NULL;\n-\tint ident_shown = 0;\n-\n-\tif (!no_verify && run_hook(index_file, \"pre-commit\", NULL))\n-\t\treturn 0;\n-\n \tif (message.len) {\n-\t\tstrbuf_addbuf(&sb, &message);\n-\t\thook_arg1 = \"message\";\n-\t} else if (logfile && !strcmp(logfile, \"-\")) {\n+\t\tstrbuf_addbuf(sb, &message);\n+\t\treturn \"message\";\n+\t}\n+\tif (logfile && !strcmp(logfile, \"-\")) {\n \t\tif (isatty(0))\n \t\t\tfprintf(stderr, \"(reading log message from standard input)\\n\");\n-\t\tif (strbuf_read(&sb, 0, 0) < 0)\n+\t\tif (strbuf_read(sb, 0, 0) < 0)\n \t\t\tdie_errno(\"could not read log from standard input\");\n-\t\thook_arg1 = \"message\";\n-\t} else if (logfile) {\n-\t\tif (strbuf_read_file(&sb, logfile, 0) < 0)\n-\t\t\tdie_errno(\"could not read log file '%s'\",\n-\t\t\t\t  logfile);\n-\t\thook_arg1 = \"message\";\n-\t} else if (use_message) {\n-\t\tbuffer = strstr(use_message_buffer, \"\\n\\n\");\n+\t\treturn \"message\";\n+\t}\n+\tif (logfile) {\n+\t\tif (strbuf_read_file(sb, logfile, 0) < 0)\n+\t\t\tdie_errno(\"could not read log file '%s'\", logfile);\n+\t\treturn \"message\";\n+\t}\n+\tif (use_message) {\n+\t\tchar *buffer = strstr(use_message_buffer, \"\\n\\n\");\n \t\tif (!buffer || buffer[2] == '\\0')\n \t\t\tdie(\"commit has empty message\");\n-\t\tstrbuf_add(&sb, buffer + 2, strlen(buffer + 2));\n-\t\thook_arg1 = \"commit\";\n-\t\thook_arg2 = use_message;\n-\t} else if (!stat(git_path(\"MERGE_MSG\"), &statbuf)) {\n-\t\tif (strbuf_read_file(&sb, git_path(\"MERGE_MSG\"), 0) < 0)\n+\t\tstrbuf_add(sb, buffer + 2, strlen(buffer + 2));\n+\t\t*hook_arg2 = use_message;\n+\t\treturn \"commit\";\n+\t}\n+\tif (!stat(git_path(\"MERGE_MSG\"), &statbuf)) {\n+\t\tif (strbuf_read_file(sb, git_path(\"MERGE_MSG\"), 0) < 0)\n \t\t\tdie_errno(\"could not read MERGE_MSG\");\n-\t\thook_arg1 = \"merge\";\n-\t} else if (!stat(git_path(\"SQUASH_MSG\"), &statbuf)) {\n-\t\tif (strbuf_read_file(&sb, git_path(\"SQUASH_MSG\"), 0) < 0)\n+\t\treturn \"merge\";\n+\t}\n+\tif (!stat(git_path(\"SQUASH_MSG\"), &statbuf)) {\n+\t\tif (strbuf_read_file(sb, git_path(\"SQUASH_MSG\"), 0) < 0)\n \t\t\tdie_errno(\"could not read SQUASH_MSG\");\n-\t\thook_arg1 = \"squash\";\n-\t} else if (template_file && !stat(template_file, &statbuf)) {\n-\t\tif (strbuf_read_file(&sb, template_file, 0) < 0)\n+\t\treturn \"squash\";\n+\t}\n+\tif (template_file && !stat(template_file, &statbuf)) {\n+\t\tif (strbuf_read_file(sb, template_file, 0) < 0)\n \t\t\tdie_errno(\"could not read '%s'\", template_file);\n-\t\thook_arg1 = \"template\";\n+\t\treturn \"template\";\n \t}\n \n \t/*\n \t * This final case does not modify the template message,\n \t * it just sets the argument to the prepare-commit-msg hook.\n \t */\n-\telse if (in_merge)\n-\t\thook_arg1 = \"merge\";\n+\tif (in_merge)\n+\t\treturn \"merge\";\n+\n+\treturn NULL;\n+}\n+\n+\n+static int prepare_to_commit(const char *index_file, const char *prefix,\n+\t\t\t     struct wt_status *s)\n+{\n+\tint commitable, saved_color_setting;\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tFILE *fp;\n+\tconst char *hook_arg1 = NULL;\n+\tconst char *hook_arg2 = NULL;\n+\tint ident_shown = 0;\n+\n+\tif (!no_verify && run_hook(index_file, \"pre-commit\", NULL))\n+\t\treturn 0;\n+\n+\thook_arg1 = get_template_message(&sb, &hook_arg2);\n \n \tfp = fopen(git_path(commit_editmsg), \"w\");\n \tif (fp == NULL)\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146233","messageId":"20100725005848.GD18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 4/9] commit: split commit -s handling into its own function","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:58:48Z","receivedAt":"2010-07-25T00:58:48Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"prepare_to_commit is easier to read straight through with optional\nsteps moved out-of-line.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/commit.c |   37 ++++++++++++++++++++-----------------\n 1 files changed, 20 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 6774180..b599486 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -606,6 +606,24 @@ static const char *get_template_message(struct strbuf *sb,\n \treturn NULL;\n }\n \n+static void add_committer_signoff(struct strbuf *sb)\n+{\n+\tstruct strbuf sob = STRBUF_INIT;\n+\tint i;\n+\n+\tstrbuf_addstr(&sob, sign_off_header);\n+\tstrbuf_addstr(&sob, fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n+\t\t\t\t     getenv(\"GIT_COMMITTER_EMAIL\")));\n+\tstrbuf_addch(&sob, '\\n');\n+\tfor (i = sb->len - 1; i > 0 && sb->buf[i - 1] != '\\n'; i--)\n+\t\t; /* do nothing */\n+\tif (prefixcmp(sb->buf + i, sob.buf)) {\n+\t\tif (!i || !ends_rfc2822_footer(sb))\n+\t\t\tstrbuf_addch(sb, '\\n');\n+\t\tstrbuf_addbuf(sb, &sob);\n+\t}\n+\tstrbuf_release(&sob);\n+}\n \n static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\t     struct wt_status *s)\n@@ -629,23 +647,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \tif (cleanup_mode != CLEANUP_NONE)\n \t\tstripspace(&sb, 0);\n \n-\tif (signoff) {\n-\t\tstruct strbuf sob = STRBUF_INIT;\n-\t\tint i;\n-\n-\t\tstrbuf_addstr(&sob, sign_off_header);\n-\t\tstrbuf_addstr(&sob, fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n-\t\t\t\t\t     getenv(\"GIT_COMMITTER_EMAIL\")));\n-\t\tstrbuf_addch(&sob, '\\n');\n-\t\tfor (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\\n'; i--)\n-\t\t\t; /* do nothing */\n-\t\tif (prefixcmp(sb.buf + i, sob.buf)) {\n-\t\t\tif (!i || !ends_rfc2822_footer(&sb))\n-\t\t\t\tstrbuf_addch(&sb, '\\n');\n-\t\t\tstrbuf_addbuf(&sb, &sob);\n-\t\t}\n-\t\tstrbuf_release(&sob);\n-\t}\n+\tif (signoff)\n+\t\tadd_committer_signoff(&sb);\n \n \tif (fwrite(sb.buf, 1, sb.len, fp) < sb.len)\n \t\tdie_errno(\"could not write commit template\");\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146234","messageId":"20100725005909.GE18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 5/9] commit: split off the piece that writes status","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:59:09Z","receivedAt":"2010-07-25T00:59:09Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The new write_status function takes care of writing status\ninformation about the pending commit (e.g., author name and\nwhether a merge is pending) to COMMIT_EDITMSG.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/commit.c |  158 +++++++++++++++++++++++++++++-------------------------\n 1 files changed, 85 insertions(+), 73 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex b599486..85e560e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -625,15 +625,94 @@ static void add_committer_signoff(struct strbuf *sb)\n \tstrbuf_release(&sob);\n }\n \n+static int write_status(FILE *fp, const char *index_file,\n+\t\t\t\tconst char *prefix, struct wt_status *s)\n+{\n+\tint commitable, saved_color_setting;\n+\tchar *author_ident;\n+\tconst char *committer_ident;\n+\tint ident_shown = 0;\n+\n+\tif (in_merge)\n+\t\tfprintf(fp,\n+\t\t\t\"#\\n\"\n+\t\t\t\"# It looks like you may be committing a MERGE.\\n\"\n+\t\t\t\"# If this is not correct, please remove the file\\n\"\n+\t\t\t\"#\t%s\\n\"\n+\t\t\t\"# and try again.\\n\"\n+\t\t\t\"#\\n\",\n+\t\t\tgit_path(\"MERGE_HEAD\"));\n+\n+\tfprintf(fp,\n+\t\t\"\\n\"\n+\t\t\"# Please enter the commit message for your changes.\");\n+\tif (cleanup_mode == CLEANUP_ALL)\n+\t\tfprintf(fp,\n+\t\t\t\" Lines starting\\n\"\n+\t\t\t\"# with '#' will be ignored, and an empty\"\n+\t\t\t\" message aborts the commit.\\n\");\n+\telse /* CLEANUP_SPACE, that is. */\n+\t\tfprintf(fp,\n+\t\t\t\" Lines starting\\n\"\n+\t\t\t\"# with '#' will be kept; you may remove them\"\n+\t\t\t\" yourself if you want to.\\n\"\n+\t\t\t\"# An empty message aborts the commit.\\n\");\n+\tif (only_include_assumed)\n+\t\tfprintf(fp, \"# %s\\n\", only_include_assumed);\n+\n+\tauthor_ident = xstrdup(fmt_name(author_name, author_email));\n+\tcommitter_ident = fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n+\t\t\t\t   getenv(\"GIT_COMMITTER_EMAIL\"));\n+\tif (strcmp(author_ident, committer_ident))\n+\t\tfprintf(fp,\n+\t\t\t\"%s\"\n+\t\t\t\"# Author:    %s\\n\",\n+\t\t\tident_shown++ ? \"\" : \"#\\n\",\n+\t\t\tauthor_ident);\n+\tfree(author_ident);\n+\n+\tif (!user_ident_sufficiently_given())\n+\t\tfprintf(fp,\n+\t\t\t\"%s\"\n+\t\t\t\"# Committer: %s\\n\",\n+\t\t\tident_shown++ ? \"\" : \"#\\n\",\n+\t\t\tcommitter_ident);\n+\n+\tif (ident_shown)\n+\t\tfprintf(fp, \"#\\n\");\n+\n+\tsaved_color_setting = s->use_color;\n+\ts->use_color = 0;\n+\tcommitable = run_status(fp, index_file, prefix, 1, s);\n+\ts->use_color = saved_color_setting;\n+\treturn commitable;\n+}\n+\n+static int something_is_staged(void)\n+{\n+\tunsigned char sha1[20];\n+\tconst char *parent = \"HEAD\";\n+\n+\tif (!active_nr && read_cache() < 0)\n+\t\tdie(\"Cannot read index\");\n+\n+\tif (amend)\n+\t\tparent = \"HEAD^1\";\n+\n+\tif (get_sha1(parent, sha1))\n+\t\treturn !!active_nr;\n+\telse\n+\t\treturn index_differs_from(parent, 0);\n+}\n+\n static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\t     struct wt_status *s)\n {\n-\tint commitable, saved_color_setting;\n+\tint commitable;\n \tstruct strbuf sb = STRBUF_INIT;\n \tFILE *fp;\n \tconst char *hook_arg1 = NULL;\n \tconst char *hook_arg2 = NULL;\n-\tint ident_shown = 0;\n \n \tif (!no_verify && run_hook(index_file, \"pre-commit\", NULL))\n \t\treturn 0;\n@@ -659,77 +738,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \n \t/* This checks if committer ident is explicitly given */\n \tgit_committer_info(0);\n-\tif (use_editor && include_status) {\n-\t\tchar *author_ident;\n-\t\tconst char *committer_ident;\n-\n-\t\tif (in_merge)\n-\t\t\tfprintf(fp,\n-\t\t\t\t\"#\\n\"\n-\t\t\t\t\"# It looks like you may be committing a MERGE.\\n\"\n-\t\t\t\t\"# If this is not correct, please remove the file\\n\"\n-\t\t\t\t\"#\t%s\\n\"\n-\t\t\t\t\"# and try again.\\n\"\n-\t\t\t\t\"#\\n\",\n-\t\t\t\tgit_path(\"MERGE_HEAD\"));\n-\n-\t\tfprintf(fp,\n-\t\t\t\"\\n\"\n-\t\t\t\"# Please enter the commit message for your changes.\");\n-\t\tif (cleanup_mode == CLEANUP_ALL)\n-\t\t\tfprintf(fp,\n-\t\t\t\t\" Lines starting\\n\"\n-\t\t\t\t\"# with '#' will be ignored, and an empty\"\n-\t\t\t\t\" message aborts the commit.\\n\");\n-\t\telse /* CLEANUP_SPACE, that is. */\n-\t\t\tfprintf(fp,\n-\t\t\t\t\" Lines starting\\n\"\n-\t\t\t\t\"# with '#' will be kept; you may remove them\"\n-\t\t\t\t\" yourself if you want to.\\n\"\n-\t\t\t\t\"# An empty message aborts the commit.\\n\");\n-\t\tif (only_include_assumed)\n-\t\t\tfprintf(fp, \"# %s\\n\", only_include_assumed);\n-\n-\t\tauthor_ident = xstrdup(fmt_name(author_name, author_email));\n-\t\tcommitter_ident = fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n-\t\t\t\t\t   getenv(\"GIT_COMMITTER_EMAIL\"));\n-\t\tif (strcmp(author_ident, committer_ident))\n-\t\t\tfprintf(fp,\n-\t\t\t\t\"%s\"\n-\t\t\t\t\"# Author:    %s\\n\",\n-\t\t\t\tident_shown++ ? \"\" : \"#\\n\",\n-\t\t\t\tauthor_ident);\n-\t\tfree(author_ident);\n-\n-\t\tif (!user_ident_sufficiently_given())\n-\t\t\tfprintf(fp,\n-\t\t\t\t\"%s\"\n-\t\t\t\t\"# Committer: %s\\n\",\n-\t\t\t\tident_shown++ ? \"\" : \"#\\n\",\n-\t\t\t\tcommitter_ident);\n-\n-\t\tif (ident_shown)\n-\t\t\tfprintf(fp, \"#\\n\");\n-\n-\t\tsaved_color_setting = s->use_color;\n-\t\ts->use_color = 0;\n-\t\tcommitable = run_status(fp, index_file, prefix, 1, s);\n-\t\ts->use_color = saved_color_setting;\n-\t} else {\n-\t\tunsigned char sha1[20];\n-\t\tconst char *parent = \"HEAD\";\n-\n-\t\tif (!active_nr && read_cache() < 0)\n-\t\t\tdie(\"Cannot read index\");\n-\n-\t\tif (amend)\n-\t\t\tparent = \"HEAD^1\";\n-\n-\t\tif (get_sha1(parent, sha1))\n-\t\t\tcommitable = !!active_nr;\n-\t\telse\n-\t\t\tcommitable = index_differs_from(parent, 0);\n-\t}\n+\tif (use_editor && include_status)\n+\t\tcommitable = write_status(fp, index_file, prefix, s);\n+\telse\n+\t\tcommitable = something_is_staged();\n \n \tfclose(fp);\n \n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146235","messageId":"20100725005942.GF18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 6/9] t7508 (status): modernize style","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T00:59:42Z","receivedAt":"2010-07-25T00:59:42Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Some cleanups to make this test script easier to read and use,\nsuch as:\n\n - put setup code in test_expect_success scripts to make the\n   test script easier to scan through;\n\n - avoid a pipe to test_decode_color that forgets the exit status of\n   \"git status\", by redirecting to a temporary file (named \"actual\")\n   for that function to consume instead;\n\n - remove precomputed object IDs;\n\n - reset configuration after each test, so there is less state\n   for a reader to keep in mind.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t7508-status.sh | 1373 ++++++++++++++++++++++++++++-------------------------\n 1 files changed, 734 insertions(+), 639 deletions(-)\n\ndiff --git a/t/t7508-status.sh b/t/t7508-status.sh\nindex a72fe3a..882e5d7 100755\n--- a/t/t7508-status.sh\n+++ b/t/t7508-status.sh\n@@ -8,23 +8,23 @@ test_description='git status'\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-\t: >tracked &&\n-\t: >modified &&\n+\t>tracked &&\n+\t>modified &&\n \tmkdir dir1 &&\n-\t: >dir1/tracked &&\n-\t: >dir1/modified &&\n+\t>dir1/tracked &&\n+\t>dir1/modified &&\n \tmkdir dir2 &&\n-\t: >dir1/tracked &&\n-\t: >dir1/modified &&\n+\t>dir1/tracked &&\n+\t>dir1/modified &&\n \tgit add . &&\n \n \tgit status >output &&\n \n \ttest_tick &&\n \tgit commit -m initial &&\n-\t: >untracked &&\n-\t: >dir1/untracked &&\n-\t: >dir2/untracked &&\n+\t>untracked &&\n+\t>dir1/untracked &&\n+\t>dir2/untracked &&\n \techo 1 >dir1/modified &&\n \techo 2 >dir2/modified &&\n \techo 3 >dir2/added &&\n@@ -32,564 +32,604 @@ test_expect_success 'setup' '\n '\n \n test_expect_success 'status (1)' '\n-\n \tgrep \"use \\\"git rm --cached <file>\\.\\.\\.\\\" to unstage\" output\n-\n '\n \n-cat >expect <<\\EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n-\n test_expect_success 'status (2)' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n \n \tgit status >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n-# On branch master\n-# Changes to be committed:\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n-\n-git config advice.statusHints false\n-\n test_expect_success 'status (advice.statusHints false)' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\n+\t#\tmodified:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n+\tgit config advice.statusHints false &&\n+\ttest_when_finished \"git config --unset advice.statusHints\" &&\n \n \tgit status >output &&\n \ttest_cmp expect output\n-\n '\n \n-git config --unset advice.statusHints\n-\n-cat >expect <<\\EOF\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n-\n test_expect_success 'status -s' '\n+\tcat >expect <<-\\EOF &&\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n \n \tgit status -s >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n-## master\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n-\n test_expect_success 'status -s -b' '\n+\tcat >expect <<-\\EOF &&\n+\t## master\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n \n \tgit status -s -b >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files not listed (use -u option to show untracked files)\n-EOF\n-test_expect_success 'status -uno' '\n+test_expect_success 'set up dir3 for untracked files tests' '\n \tmkdir dir3 &&\n-\t: >dir3/untracked1 &&\n-\t: >dir3/untracked2 &&\n+\t>dir3/untracked1 &&\n+\t>dir3/untracked2 &&\n+\n+\tcat >expect <<-\\EOF\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files not listed (use -u option to show untracked files)\n+\tEOF\n+'\n+\n+test_expect_success 'status -uno' '\n \tgit status -uno >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'status (status.showUntrackedFiles no)' '\n-\tgit config status.showuntrackedfiles no\n+\tgit config status.showuntrackedfiles no &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files not listed\n-EOF\n-git config advice.statusHints false\n test_expect_success 'status -uno (advice.statusHints false)' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\n+\t#\tmodified:   dir1/modified\n+\t#\n+\t# Untracked files not listed\n+\tEOF\n+\tgit config status.showuntrackedfiles no &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n+\tgit config advice.statusHints false &&\n+\ttest_when_finished \"git config --unset advice.statusHints\" &&\n \tgit status -uno >output &&\n \ttest_cmp expect output\n '\n-git config --unset advice.statusHints\n \n-cat >expect << EOF\n- M dir1/modified\n-A  dir2/added\n-EOF\n+test_expect_success 'setup: status -s -uno expected output' '\n+\tcat >expect <<-\\EOF\n+\t M dir1/modified\n+\tA  dir2/added\n+\tEOF\n+'\n+\n test_expect_success 'status -s -uno' '\n-\tgit config --unset status.showuntrackedfiles\n+\ttest_might_fail git config --unset status.showuntrackedfiles &&\n \tgit status -s -uno >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'status -s (status.showUntrackedFiles no)' '\n-\tgit config status.showuntrackedfiles no\n+\tgit config status.showuntrackedfiles no &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status -s >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\tdir3/\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n+test_expect_success 'setup: status -unormal expected output' '\n+\tcat >expect <<-\\EOF\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\tdir3/\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n+'\n+\n test_expect_success 'status -unormal' '\n+\tgit config status.showuntrackedfiles no &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status -unormal >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'status (status.showUntrackedFiles normal)' '\n-\tgit config status.showuntrackedfiles normal\n+\tgit config status.showuntrackedfiles normal &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? dir3/\n-?? expect\n-?? output\n-?? untracked\n-EOF\n+test_expect_success 'setup: status -s -unormal expected output' '\n+\tcat >expect <<-\\EOF\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? dir3/\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n+'\n+\n test_expect_success 'status -s -unormal' '\n-\tgit config --unset status.showuntrackedfiles\n+\ttest_might_fail git config --unset status.showuntrackedfiles &&\n \tgit status -s -unormal >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'status -s (status.showUntrackedFiles normal)' '\n-\tgit config status.showuntrackedfiles normal\n+\tgit config status.showuntrackedfiles normal &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status -s >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\tdir3/untracked1\n-#\tdir3/untracked2\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n+test_expect_success 'setup: status -uall expected output' '\n+\tcat >expect <<-\\EOF\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\tdir3/untracked1\n+\t#\tdir3/untracked2\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n+'\n+\n test_expect_success 'status -uall' '\n \tgit status -uall >output &&\n \ttest_cmp expect output\n '\n test_expect_success 'status (status.showUntrackedFiles all)' '\n-\tgit config status.showuntrackedfiles all\n+\tgit config status.showuntrackedfiles all &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status >output &&\n \trm -rf dir3 &&\n-\tgit config --unset status.showuntrackedfiles &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n+test_expect_success 'setup: status -s -uall expected output' '\n+\tcat >expect <<-\\EOF\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n+'\n+\n test_expect_success 'status -s -uall' '\n-\tgit config --unset status.showuntrackedfiles\n+\ttest_might_fail git config --unset status.showuntrackedfiles &&\n \tgit status -s -uall >output &&\n \ttest_cmp expect output\n '\n+\n test_expect_success 'status -s (status.showUntrackedFiles all)' '\n-\tgit config status.showuntrackedfiles all\n+\tgit config status.showuntrackedfiles all &&\n+\ttest_when_finished \"git config --unset status.showuntrackedfiles\" &&\n \tgit status -s >output &&\n-\trm -rf dir3 &&\n-\tgit config --unset status.showuntrackedfiles &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<\\EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   ../dir2/added\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tuntracked\n-#\t../dir2/modified\n-#\t../dir2/untracked\n-#\t../expect\n-#\t../output\n-#\t../untracked\n-EOF\n+test_expect_success 'setup: done with dir3' '\n+\trm -rf dir3\n+'\n \n test_expect_success 'status with relative paths' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   ../dir2/added\n+\t#\n+\t# Changed but not updated:\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:   modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tuntracked\n+\t#\t../dir2/modified\n+\t#\t../dir2/untracked\n+\t#\t../expect\n+\t#\t../output\n+\t#\t../untracked\n+\tEOF\n \n-\t(cd dir1 && git status) >output &&\n+\t(\n+\t\tcd dir1 &&\n+\t\tgit status >../output\n+\t) &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n- M modified\n-A  ../dir2/added\n-?? untracked\n-?? ../dir2/modified\n-?? ../dir2/untracked\n-?? ../expect\n-?? ../output\n-?? ../untracked\n-EOF\n test_expect_success 'status -s with relative paths' '\n+\tcat >expect <<-\\EOF &&\n+\t M modified\n+\tA  ../dir2/added\n+\t?? untracked\n+\t?? ../dir2/modified\n+\t?? ../dir2/untracked\n+\t?? ../expect\n+\t?? ../output\n+\t?? ../untracked\n+\tEOF\n \n-\t(cd dir1 && git status -s) >output &&\n+\t(\n+\t\tcd dir1 &&\n+\t\tgit status -s >../output\n+\t) &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n-\n test_expect_success 'status --porcelain ignores relative paths setting' '\n+\tcat >expect <<-\\EOF &&\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n \n-\t(cd dir1 && git status --porcelain) >output &&\n+\t(\n+\t\tcd dir1 &&\n+\t\tgit status --porcelain >../output\n+\t) &&\n \ttest_cmp expect output\n-\n '\n \n-test_expect_success 'setup unique colors' '\n-\n+test_expect_success 'setup: unique colors' '\n \tgit config status.color.untracked blue\n-\n '\n \n-cat >expect <<\\EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\t<GREEN>new file:   dir2/added<RESET>\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\t<RED>modified:   dir1/modified<RESET>\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\t<BLUE>dir1/untracked<RESET>\n-#\t<BLUE>dir2/modified<RESET>\n-#\t<BLUE>dir2/untracked<RESET>\n-#\t<BLUE>expect<RESET>\n-#\t<BLUE>output<RESET>\n-#\t<BLUE>untracked<RESET>\n-EOF\n+test_expect_success 'setup: expect colorful output' '\n+\tcat >expect <<-\\EOF\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\t<GREEN>new file:   dir2/added<RESET>\n+\t#\n+\t# Changed but not updated:\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#\t<RED>modified:   dir1/modified<RESET>\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\t<BLUE>actual<RESET>\n+\t#\t<BLUE>dir1/untracked<RESET>\n+\t#\t<BLUE>dir2/modified<RESET>\n+\t#\t<BLUE>dir2/untracked<RESET>\n+\t#\t<BLUE>expect<RESET>\n+\t#\t<BLUE>output<RESET>\n+\t#\t<BLUE>untracked<RESET>\n+\tEOF\n+'\n \n test_expect_success 'status with color.ui' '\n-\n \tgit config color.ui always &&\n-\tgit status | test_decode_color >output &&\n+\ttest_when_finished \"git config --unset color.ui\" &&\n+\tgit status >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n test_expect_success 'status with color.status' '\n-\n-\tgit config --unset color.ui &&\n+\ttest_might_fail git config --unset color.ui &&\n \tgit config color.status always &&\n-\tgit status | test_decode_color >output &&\n+\ttest_when_finished \"git config --unset color.status\" &&\n+\tgit status >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n- <RED>M<RESET> dir1/modified\n-<GREEN>A<RESET>  dir2/added\n-<BLUE>??<RESET> dir1/untracked\n-<BLUE>??<RESET> dir2/modified\n-<BLUE>??<RESET> dir2/untracked\n-<BLUE>??<RESET> expect\n-<BLUE>??<RESET> output\n-<BLUE>??<RESET> untracked\n-EOF\n+test_expect_success 'setup: expected colorful short output' '\n+\tcat >expect <<-\\EOF\n+\t <RED>M<RESET> dir1/modified\n+\t<GREEN>A<RESET>  dir2/added\n+\t<BLUE>??<RESET> actual\n+\t<BLUE>??<RESET> dir1/untracked\n+\t<BLUE>??<RESET> dir2/modified\n+\t<BLUE>??<RESET> dir2/untracked\n+\t<BLUE>??<RESET> expect\n+\t<BLUE>??<RESET> output\n+\t<BLUE>??<RESET> untracked\n+\tEOF\n+'\n \n test_expect_success 'status -s with color.ui' '\n-\n-\tgit config --unset color.status &&\n+\ttest_might_fail git config --unset color.status &&\n \tgit config color.ui always &&\n-\tgit status -s | test_decode_color >output &&\n+\ttest_when_finished \"git config --unset color.ui\" &&\n+\tgit status -s >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n test_expect_success 'status -s with color.status' '\n-\n-\tgit config --unset color.ui &&\n+\ttest_might_fail git config --unset color.ui &&\n \tgit config color.status always &&\n-\tgit status -s | test_decode_color >output &&\n+\ttest_when_finished \"git config --unset color.status\" &&\n+\tgit status -s >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n-## <GREEN>master<RESET>\n- <RED>M<RESET> dir1/modified\n-<GREEN>A<RESET>  dir2/added\n-<BLUE>??<RESET> dir1/untracked\n-<BLUE>??<RESET> dir2/modified\n-<BLUE>??<RESET> dir2/untracked\n-<BLUE>??<RESET> expect\n-<BLUE>??<RESET> output\n-<BLUE>??<RESET> untracked\n-EOF\n-\n test_expect_success 'status -s -b with color.status' '\n+\tcat >expect <<-\\EOF &&\n+\t## <GREEN>master<RESET>\n+\t <RED>M<RESET> dir1/modified\n+\t<GREEN>A<RESET>  dir2/added\n+\t<BLUE>??<RESET> actual\n+\t<BLUE>??<RESET> dir1/untracked\n+\t<BLUE>??<RESET> dir2/modified\n+\t<BLUE>??<RESET> dir2/untracked\n+\t<BLUE>??<RESET> expect\n+\t<BLUE>??<RESET> output\n+\t<BLUE>??<RESET> untracked\n+\tEOF\n \n-\tgit status -s -b | test_decode_color >output &&\n+\tgit config color.status always &&\n+\ttest_when_finished \"git config --unset color.status\" &&\n+\tgit status -s -b >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n+test_expect_success 'setup: expect uncolorful status --porcelain output' '\n+\tcat >expect <<-\\EOF\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? actual\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n+'\n \n test_expect_success 'status --porcelain ignores color.ui' '\n-\n-\tgit config --unset color.status &&\n+\ttest_might_fail git config --unset color.status &&\n \tgit config color.ui always &&\n-\tgit status --porcelain | test_decode_color >output &&\n+\ttest_when_finished \"git config --unset color.ui\" &&\n+\tgit status --porcelain >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n test_expect_success 'status --porcelain ignores color.status' '\n-\n-\tgit config --unset color.ui &&\n+\ttest_might_fail git config --unset color.ui &&\n \tgit config color.status always &&\n-\tgit status --porcelain | test_decode_color >output &&\n+\ttest_when_finished \"git config --unset color.status\" &&\n+\tgit status --porcelain >actual &&\n+\ttest_decode_color <actual >output &&\n \ttest_cmp expect output\n-\n '\n \n-# recover unconditionally from color tests\n-git config --unset color.status\n-git config --unset color.ui\n+test_expect_success 'setup: recover unconditionally from color tests' '\n+\ttest_might_fail git config --unset color.status &&\n+\ttest_might_fail git config --unset color.ui\n+'\n \n test_expect_success 'status --porcelain ignores -b' '\n-\n \tgit status --porcelain -b >output &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n-\n-\n test_expect_success 'status without relative paths' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n \n-\tgit config status.relativePaths false\n-\t(cd dir1 && git status) >output &&\n+\tgit config status.relativePaths false &&\n+\ttest_when_finished \"git config --unset status.relativePaths\" &&\n+\t(\n+\t\tcd dir1 &&\n+\t\tgit status >../output\n+\t) &&\n \ttest_cmp expect output\n-\n '\n \n-cat >expect <<\\EOF\n- M dir1/modified\n-A  dir2/added\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n-\n test_expect_success 'status -s without relative paths' '\n+\tcat >expect <<-\\EOF &&\n+\t M dir1/modified\n+\tA  dir2/added\n+\t?? actual\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n \n-\t(cd dir1 && git status -s) >output &&\n+\tgit config status.relativePaths false &&\n+\ttest_when_finished \"git config --unset status.relativePaths\" &&\n+\t(\n+\t\tcd dir1 &&\n+\t\tgit status -s >../output\n+\t) &&\n \ttest_cmp expect output\n-\n '\n \n-cat <<EOF >expect\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n test_expect_success 'dry-run of partial commit excluding new file in index' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tmodified:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n+\n \tgit commit --dry-run dir1/modified >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M\tdir1/modified\n-EOF\n test_expect_success 'status refreshes the index' '\n+\tEMPTY_BLOB=$(git hash-object -t blob --stdin </dev/null) &&\n+\tZEROES=0000000000000000000000000000000000000000 &&\n+\techo \":100644 100644 $EMPTY_BLOB $ZEROES M\tdir1/modified\" >expect &&\n+\n \ttouch dir2/added &&\n \tgit status &&\n \tgit diff-files >output &&\n@@ -597,39 +637,42 @@ test_expect_success 'status refreshes the index' '\n '\n \n test_expect_success 'setup status submodule summary' '\n-\ttest_create_repo sm && (\n+\ttest_create_repo sm &&\n+\t(\n \t\tcd sm &&\n \t\t>foo &&\n \t\tgit add foo &&\n \t\tgit commit -m \"Add foo\"\n \t) &&\n-\tgit add sm\n+\tgit add sm &&\n+\n+\tcat >expect <<-\\EOF\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\tnew file:   sm\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\tnew file:   sm\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n test_expect_success 'status submodule summary is disabled by default' '\n \tgit status >output &&\n \ttest_cmp expect output\n@@ -641,17 +684,21 @@ test_expect_success 'status --untracked-files=all does not show submodule' '\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n- M dir1/modified\n-A  dir2/added\n-A  sm\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n+test_expect_success 'setup status -s submodule summary' '\n+\tcat >expect <<-\\EOF\n+\t M dir1/modified\n+\tA  dir2/added\n+\tA  sm\n+\t?? actual\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n+'\n+\n test_expect_success 'status -s submodule summary is disabled by default' '\n \tgit status -s >output &&\n \ttest_cmp expect output\n@@ -663,275 +710,323 @@ test_expect_success 'status -s --untracked-files=all does not show submodule' '\n \ttest_cmp expect output\n '\n \n-head=$(cd sm && git rev-parse --short=7 --verify HEAD)\n+test_expect_success 'setup: save head' '\n+\thead=$(\n+\t\tcd sm &&\n+\t\tgit rev-parse --short=7 --verify HEAD\n+\t)\n+'\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\tnew file:   sm\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Submodule changes to be committed:\n-#\n-# * sm 0000000...$head (1):\n-#   > Add foo\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n test_expect_success 'status submodule summary' '\n+\tcat >expect <<-EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\tnew file:   sm\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Submodule changes to be committed:\n+\t#\n+\t# * sm 0000000...$head (1):\n+\t#   > Add foo\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n+\n \tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n \tgit status >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n- M dir1/modified\n-A  dir2/added\n-A  sm\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n test_expect_success 'status -s submodule summary' '\n+\tcat >expect <<-\\EOF &&\n+\t M dir1/modified\n+\tA  dir2/added\n+\tA  sm\n+\t?? actual\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n+\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n \tgit status -s >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-no changes added to commit (use \"git add\" and/or \"git commit -a\")\n-EOF\n test_expect_success 'status submodule summary (clean submodule)' '\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\n \tgit commit -m \"commit submodule\" &&\n \tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n \ttest_must_fail git commit --dry-run >output &&\n \ttest_cmp expect output &&\n \tgit status >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n- M dir1/modified\n-?? dir1/untracked\n-?? dir2/modified\n-?? dir2/untracked\n-?? expect\n-?? output\n-?? untracked\n-EOF\n test_expect_success 'status -s submodule summary (clean submodule)' '\n+\tcat >expect <<-\\EOF &&\n+\t M dir1/modified\n+\t?? actual\n+\t?? dir1/untracked\n+\t?? dir2/modified\n+\t?? dir2/untracked\n+\t?? expect\n+\t?? output\n+\t?? untracked\n+\tEOF\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n \tgit status -s >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-# On branch master\n-# Changes to be committed:\n-#   (use \"git reset HEAD^1 <file>...\" to unstage)\n-#\n-#\tnew file:   dir2/added\n-#\tnew file:   sm\n-#\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Submodule changes to be committed:\n-#\n-# * sm 0000000...$head (1):\n-#   > Add foo\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-EOF\n test_expect_success 'commit --dry-run submodule summary (--amend)' '\n+\tcat >expect <<-EOF &&\n+\t# On branch master\n+\t# Changes to be committed:\n+\t#   (use \"git reset HEAD^1 <file>...\" to unstage)\n+\t#\n+\t#\tnew file:   dir2/added\n+\t#\tnew file:   sm\n+\t#\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Submodule changes to be committed:\n+\t#\n+\t# * sm 0000000...$head (1):\n+\t#   > Add foo\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tEOF\n+\n \tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n \tgit commit --dry-run --amend >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success POSIXPERM 'status succeeds in a read-only repository' '\n-\t(\n-\t\tchmod a-w .git &&\n-\t\t# make dir1/tracked stat-dirty\n-\t\t>dir1/tracked1 && mv -f dir1/tracked1 dir1/tracked &&\n-\t\tgit status -s >output &&\n-\t\t! grep dir1/tracked output &&\n-\t\t# make sure \"status\" succeeded without writing index out\n-\t\tgit diff-files | grep dir1/tracked\n-\t)\n-\tstatus=$?\n-\tchmod 775 .git\n-\t(exit $status)\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\n+\tchmod a-w .git &&\n+\ttest_when_finished \"chmod 775 .git\" &&\n+\n+\t# make dir1/tracked stat-dirty\n+\t>dir1/tracked1 &&\n+\tmv -f dir1/tracked1 dir1/tracked &&\n+\n+\tgit status -s >output &&\n+\t! grep dir1/tracked output &&\n+\n+\t# make sure \"status\" succeeded without writing index out\n+\tgit diff-files >output &&\n+\tgrep dir1/tracked output\n '\n \n-cat > expect << EOF\n-# On branch master\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-no changes added to commit (use \"git add\" and/or \"git commit -a\")\n-EOF\n+test_expect_success 'setup: status --ignore-submodules' '\n+\tcat >expect <<-\\EOF\n+\t# On branch master\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+'\n \n test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' '\n-\techo modified > sm/untracked &&\n-\tgit status --ignore-submodules=untracked > output &&\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\techo modified >sm/untracked &&\n+\tgit status --ignore-submodules=untracked >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '\n-\tgit status --ignore-submodules=dirty > output &&\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\tgit status --ignore-submodules=dirty >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '\n-\techo modified > sm/foo &&\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\techo modified >sm/foo &&\n \tgit status --ignore-submodules=dirty > output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-# On branch master\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#   (commit or discard the untracked or modified content in submodules)\n-#\n-#\tmodified:   dir1/modified\n-#\tmodified:   sm (modified content)\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-no changes added to commit (use \"git add\" and/or \"git commit -a\")\n-EOF\n-\n test_expect_success \"--ignore-submodules=untracked doesn't suppress submodules with modified content\" '\n-\tgit status --ignore-submodules=untracked > output &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changed but not updated:\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#   (commit or discard the untracked or modified content in submodules)\n+\t#\n+\t#\tmodified:   dir1/modified\n+\t#\tmodified:   sm (modified content)\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\tgit status --ignore-submodules=untracked >output &&\n \ttest_cmp expect output\n '\n \n-head2=$(cd sm && git commit -q -m \"2nd commit\" foo && git rev-parse --short=7 --verify HEAD)\n-\n-cat > expect << EOF\n-# On branch master\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\tmodified:   sm (new commits)\n-#\n-# Submodules changed but not updated:\n-#\n-# * sm $head...$head2 (1):\n-#   > 2nd commit\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-no changes added to commit (use \"git add\" and/or \"git commit -a\")\n-EOF\n+test_expect_success 'setup' '\n+\thead2=$(\n+\t\tcd sm &&\n+\t\tgit commit -q -m \"2nd commit\" foo &&\n+\t\tgit rev-parse --short=7 --verify HEAD\n+\t) &&\n+\tcat >expect <<-EOF\n+\t# On branch master\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\tmodified:   sm (new commits)\n+\t#\n+\t# Submodules changed but not updated:\n+\t#\n+\t# * sm $head...$head2 (1):\n+\t#   > 2nd commit\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+'\n \n test_expect_success \"--ignore-submodules=untracked doesn't suppress submodule summary\" '\n-\tgit status --ignore-submodules=untracked > output &&\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\tgit status --ignore-submodules=untracked >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success \"--ignore-submodules=dirty doesn't suppress submodule summary\" '\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n \tgit status --ignore-submodules=dirty > output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-# On branch master\n-# Changed but not updated:\n-#   (use \"git add <file>...\" to update what will be committed)\n-#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n-#\n-#\tmodified:   dir1/modified\n-#\n-# Untracked files:\n-#   (use \"git add <file>...\" to include in what will be committed)\n-#\n-#\tdir1/untracked\n-#\tdir2/modified\n-#\tdir2/untracked\n-#\texpect\n-#\toutput\n-#\tuntracked\n-no changes added to commit (use \"git add\" and/or \"git commit -a\")\n-EOF\n-\n test_expect_success \"--ignore-submodules=all suppresses submodule summary\" '\n-\tgit status --ignore-submodules=all > output &&\n+\tcat >expect <<-\\EOF &&\n+\t# On branch master\n+\t# Changed but not updated:\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:   dir1/modified\n+\t#\n+\t# Untracked files:\n+\t#   (use \"git add <file>...\" to include in what will be committed)\n+\t#\n+\t#\tactual\n+\t#\tdir1/untracked\n+\t#\tdir2/modified\n+\t#\tdir2/untracked\n+\t#\texpect\n+\t#\toutput\n+\t#\tuntracked\n+\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n+\tEOF\n+\tgit config status.submodulesummary 10 &&\n+\ttest_when_finished \"git config --unset status.submodulesummary\" &&\n+\tgit status --ignore-submodules=all >output &&\n \ttest_cmp expect output\n '\n \n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146236","messageId":"20100725010006.GG18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 7/9] commit: give empty-commit avoidance code its own function","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T01:00:06Z","receivedAt":"2010-07-25T01:00:06Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"With v1.7.1.1~16^2 (commit: give advice on empty amend, 2010-06-06),\n\"git commit\" was taught to provide some extra advice in response to\nattempts to amend a commit into emptiness, but \"git commit --amend\n--dry-run\" was not updated to match.  Split out a function that could\nbe used to carry out such an update if it seems to be a good idea.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/commit.c |   24 ++++++++++++++++++------\n 1 files changed, 18 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 85e560e..febefee 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -705,6 +705,18 @@ static int something_is_staged(void)\n \t\treturn index_differs_from(parent, 0);\n }\n \n+static int empty_commit_ok(const char *index_file, const char *prefix,\n+\t\t\t\tstruct wt_status *s)\n+{\n+\tif (in_merge || allow_empty || (amend && is_a_merge(head_sha1)))\n+\t\treturn 1;\n+\n+\trun_status(stdout, index_file, prefix, 0, s);\n+\tif (amend)\n+\t\tfputs(empty_amend_advice, stderr);\n+\treturn 0;\n+}\n+\n static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\t     struct wt_status *s)\n {\n@@ -745,13 +757,13 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \n \tfclose(fp);\n \n-\tif (!commitable && !in_merge && !allow_empty &&\n-\t    !(amend && is_a_merge(head_sha1))) {\n-\t\trun_status(stdout, index_file, prefix, 0, s);\n-\t\tif (amend)\n-\t\t\tfputs(empty_amend_advice, stderr);\n+\t/*\n+\t * If there is nothing staged for commit, this is not a\n+\t * merge, and --allow-empty was not supplied, dump status\n+\t * followed by some hints for staging changes.\n+\t */\n+\tif (!commitable && !empty_commit_ok(index_file, prefix, s))\n \t\treturn 0;\n-\t}\n \n \t/*\n \t * Re-read the index as pre-commit hook could have updated it,\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146237","messageId":"20100725010116.GH18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 8/9] commit --dry-run: give advice on empty amend","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T01:01:16Z","receivedAt":"2010-07-25T01:01:16Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Share code from the non-dry-run case to ensure the output from\n\"commit --amend --dry-run\" matches that from \"commit --amend\"\non attempts to amend away a commit.  The output had fallen\nout of synch in v1.7.1.1~16^2 (2010-06-06).\n\nThe only change in output is some extra text to stderr.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/commit.c |    9 ++++++++-\n 1 files changed, 8 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex febefee..9a4ea34 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1016,7 +1016,14 @@ static int dry_run_commit(int argc, const char **argv, const char *prefix,\n \tconst char *index_file;\n \n \tindex_file = prepare_index(argc, argv, prefix, 1);\n-\tcommitable = run_status(stdout, index_file, prefix, 0, s);\n+\n+\t/*\n+\t * Give extra advice when faced with attempts to amend away a commit.\n+\t */\n+\tif (!something_is_staged() && !empty_commit_ok(index_file, prefix, s))\n+\t\tcommitable = 0;\n+\telse\n+\t\tcommitable = run_status(stdout, index_file, prefix, 0, s);\n \trollback_index_files();\n \n \treturn commitable ? 0 : 1;\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146238","messageId":"20100725010230.GI18420@burratino","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"[PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T01:02:30Z","receivedAt":"2010-07-25T01:02:30Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Starting out, it can be unnerving that “git commit” spews out\na list of changes instead of just making a commit when the user\nhas forgotten to stage any changes.\n\nSo give some focused advice in that case, by suppressing the\nstatus summary so the existing message about the need to stage\nchanges can be read more easily.\n\nExample: before:\n\n\t$ git commit\n\t# On branch master\n\t# Changed but not updated:\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:   dir1/modified\n\t#\n\t# Untracked files:\n\t#   (use \"git add <file>...\" to include in what will be committed)\n\t#\n\t#\tactual\n\t#\tdir1/untracked\n\t#\tdir2/modified\n\t#\tdir2/untracked\n\t#\texpect\n\t#\toutput\n\t#\tuntracked\n\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\t$\n\nAfter:\n\n\t$ git commit\n\tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\t$\n\nCc: Jakub Narebski <jnareb@gmail.com>\nCc: Jeff King <peff@peff.net>\nCc: Thomas Rast <trast@student.ethz.ch>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nThat’s the end of the series.  Thanks for reading.\n\n builtin/commit.c  |   10 +++++++++-\n t/t7508-status.sh |    7 ++++---\n wt-status.c       |    2 +-\n wt-status.h       |    1 +\n 4 files changed, 15 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 9a4ea34..a2588a9 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -96,7 +96,8 @@ static int null_termination;\n static enum {\n \tSTATUS_FORMAT_LONG,\n \tSTATUS_FORMAT_SHORT,\n-\tSTATUS_FORMAT_PORCELAIN\n+\tSTATUS_FORMAT_PORCELAIN,\n+\tSTATUS_FORMAT_NOCHANGES\n } status_format = STATUS_FORMAT_LONG;\n static int status_show_branch;\n \n@@ -443,6 +444,9 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int\n \tcase STATUS_FORMAT_LONG:\n \t\twt_status_print(s);\n \t\tbreak;\n+\tcase STATUS_FORMAT_NOCHANGES:\n+\t\twt_status_print_nochanges(s);\n+\t\tbreak;\n \t}\n \n \treturn s->commitable;\n@@ -711,6 +715,8 @@ static int empty_commit_ok(const char *index_file, const char *prefix,\n \tif (in_merge || allow_empty || (amend && is_a_merge(head_sha1)))\n \t\treturn 1;\n \n+\tif (status_format == STATUS_FORMAT_LONG)\n+\t\tstatus_format = STATUS_FORMAT_NOCHANGES;\n \trun_status(stdout, index_file, prefix, 0, s);\n \tif (amend)\n \t\tfputs(empty_amend_advice, stderr);\n@@ -1170,6 +1176,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)\n \t\ts.ignore_submodule_arg = ignore_submodule_arg;\n \t\twt_status_print(&s);\n \t\tbreak;\n+\tcase STATUS_FORMAT_NOCHANGES:\n+\t\treturn error(\"unexpected status format\");\n \t}\n \treturn 0;\n }\ndiff --git a/t/t7508-status.sh b/t/t7508-status.sh\nindex 882e5d7..c41a54c 100755\n--- a/t/t7508-status.sh\n+++ b/t/t7508-status.sh\n@@ -800,10 +800,11 @@ test_expect_success 'status submodule summary (clean submodule)' '\n \tgit commit -m \"commit submodule\" &&\n \tgit config status.submodulesummary 10 &&\n \ttest_when_finished \"git config --unset status.submodulesummary\" &&\n-\ttest_must_fail git commit --dry-run >output &&\n+\ttest_must_fail git commit --dry-run >actual &&\n+\tgit status >output &&\n \ttest_cmp expect output &&\n-\tgit status >output &&\n-\ttest_cmp expect output\n+\techo '\\''no changes added to commit (use \"git add\" and/or \"git commit -a\")'\\'' >expect &&\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'status -s submodule summary (clean submodule)' '\ndiff --git a/wt-status.c b/wt-status.c\nindex 90a0824..83d2ae2 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -612,7 +612,7 @@ static void wt_status_print_verbose(struct wt_status *s)\n \trun_diff_index(&rev, 1);\n }\n \n-static void wt_status_print_nochanges(struct wt_status *s)\n+void wt_status_print_nochanges(struct wt_status *s)\n {\n \tif (s->amend)\n \t\tfprintf(s->fp, \"# No changes\\n\");\ndiff --git a/wt-status.h b/wt-status.h\nindex 9df9c9f..1cee54b 100644\n--- a/wt-status.h\n+++ b/wt-status.h\n@@ -65,5 +65,6 @@ void wt_status_collect(struct wt_status *s);\n \n void wt_shortstatus_print(struct wt_status *s, int null_termination, int show_branch);\n void wt_porcelain_print(struct wt_status *s, int null_termination);\n+void wt_status_print_nochanges(struct wt_status *s);\n \n #endif /* STATUS_H */\n-- \n1.7.2.9.ge3789.dirty\n"},{"id":"146248","messageId":"AANLkTin_GsqW6JIUqJXkrIQFIRcZXaoCUFm83s3m_LBG@mail.gmail.com","threadId":"24501","inReplyTo":"20100725005942.GF18420@burratino","subject":"Re: [PATCH 6/9] t7508 (status): modernize style","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-07-25T08:38:03Z","receivedAt":"2010-07-25T08:38:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, Jul 25, 2010 at 00:59, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Some cleanups to make this test script easier to read and use,\n> such as:\n>\n>  - put setup code in test_expect_success scripts to make the\n>   test script easier to scan through;\n>\n>  - avoid a pipe to test_decode_color that forgets the exit status of\n>   \"git status\", by redirecting to a temporary file (named \"actual\")\n>   for that function to consume instead;\n>\n>  - remove precomputed object IDs;\n>\n>  - reset configuration after each test, so there is less state\n>   for a reader to keep in mind.\n\nThese changes are all good. Well spotted with the test_might_fail()\nadditions, adding forgotten &&, and turning the >expect code setup\ninto their own tests.\n\nAcked.\n"},{"id":"146252","messageId":"AANLkTilnQhsopnuAf0nja8Qq63VrOlt0_uCJrqYv5X-v@mail.gmail.com","threadId":"24501","inReplyTo":"20100725005443.GA18370@burratino","subject":"Re: [RFC/PATCH 0/9] commit: more focused advice in the no-changes-staged case","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-07-25T08:54:22Z","receivedAt":"2010-07-25T08:54:22Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Sun, Jul 25, 2010 at 00:54, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Hi,\n>\n> When last seen[1], this series was a single patch in very rough form,\n> but there have been almost no functional changes since then.\n>\n> The patches suppress most output when “git commit” is run without\n> stages changed.  So instead of\n>\n>        $ git commit\n>        # On branch master\n>        # Changed but not updated:\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:   dir1/modified\n>        #\n>        # Untracked files:\n>        #   (use \"git add <file>...\" to include in what will be committed)\n>        #\n>        #       actual\n>        #       dir1/untracked\n>        #       dir2/modified\n>        #       dir2/untracked\n>        #       expect\n>        #       output\n>        #       untracked\n>        no changes added to commit (use \"git add\" and/or \"git commit -a\")\n>\n> which may cause a newcomer to panic, you get\n>\n>        $ git commit\n>        no changes added to commit (use \"git add\" and/or \"git commit -a\")\n>\n> which would just cause her to scratch her head or say “oh, right!”\n> instead.  Hopefully these patches will at least provide a reminder to\n> improve the various \"no changes\" advice messages.\n>\n> Ideas for future work:\n>\n>  - add some tests\n>  - give the full traditional output if -a or any paths were passed on\n>   the command line.\n>\n> Most of the patches are code clarity improvements which is not\n> strictly related to this topic.\n>\n> Patch 6 cleans up the most obvious script to add tests for this in,\n> though I have not added any tests to it.\n>\n> Patch 8 changes commit --dry-run output in a more modest way, to\n> print the same advice Jeff added to commit proper last month.  I\n> suspect this is a good change, but input from people who script\n> around commit --dry-run would be welcome.\n>\n> Patch 9 is the advertised patch.  It should be self-explanatory.\n>\n> Thoughts?\n\nFirstly. Acked-by on patches 1-8, they're some much needed\ncleanup. Especially fixing the hairy wt-status.c code and the test\nfixes.\n\nI'm not so sure about 9/9. Every time I make this mistake with \"git\ncommit\" I find it helpful to be able to just look up to see what I\nneed to stage. But perhaps the wall of text can be confusing to\nnewbies, I don't have a strong opinion on whether it should be\nincluded or not.\n\nAs an aside, isn't this sort of thing (i.e. long notices/help\nmessages) usually hidden behind advice.* nowadays?\n\nWith the stripped down message nothing tells you how to find out what\nto add, which the old message did just by including the \"git status\"\noutput.\n\nAnyway, meh, I don't know :)\n"},{"id":"146255","messageId":"201007251122.41166.trast@student.ethz.ch","threadId":"24501","inReplyTo":"AANLkTilnQhsopnuAf0nja8Qq63VrOlt0_uCJrqYv5X-v@mail.gmail.com","subject":"Re: [RFC/PATCH 0/9] commit: more focused advice in the no-changes-staged case","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-07-25T09:22:40Z","receivedAt":"2010-07-25T09:22:40Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n> On Sun, Jul 25, 2010 at 00:54, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> > Hi,\n> >\n> > When last seen[1], this series was a single patch in very rough form,\n> > but there have been almost no functional changes since then.\n> >\n> > The patches suppress most output when “git commit” is run without\n> > stages changed.  So instead of\n> >\n> >        $ git commit\n> >        # On branch master\n> >        # Changed but not updated:\n[...]\n> >        # Untracked files:\n[...]\n> >        no changes added to commit (use \"git add\" and/or \"git commit -a\")\n> >\n> > which may cause a newcomer to panic, you get\n> >\n> >        $ git commit\n> >        no changes added to commit (use \"git add\" and/or \"git commit -a\")\n> >\n> > which would just cause her to scratch her head or say “oh, right!”\n> > instead.  Hopefully these patches will at least provide a reminder to\n> > improve the various \"no changes\" advice messages.\n[...]\n> I'm not so sure about 9/9. Every time I make this mistake with \"git\n> commit\" I find it helpful to be able to just look up to see what I\n> need to stage. But perhaps the wall of text can be confusing to\n> newbies, I don't have a strong opinion on whether it should be\n> included or not.\n\nI tend to agree with Ævar.  I was trying a different direction\nyesterday, it's still WIP but you can try it from here:\n\n  git://repo.or.cz/git/trast.git t/color-porcelain-message-output\n\nIt does not have any effect in this case because wt-status.c just\nprintf()s \"no changes added to commit\", but the idea would be that it\nshould end up in the error color (bold red by default) so that it\nstands out clearly.\n\n[I actually wrote it because for git-rebase it's even worse: if you\nhave fixed one conflict and immediately hit another, the output is\n\n  Recorded resolution for 'dir/a'.\n  [detached HEAD aa9ae6b] related change                          (1)\n   1 files changed, 1 insertions(+), 1 deletions(-)\n  Automatic cherry-pick failed.  After resolving the conflicts,\n  mark the corrected paths with 'git add <paths>', and\n  run 'git rebase --continue'\n  Recorded preimage for 'dir/a'\n  Could not apply 649420f... second                               (2)\n\n(1) is the subject of the just-applied commit, whereas (2) is the\nsubject of the now-conflicted commit.  In my case (1) caught my eye\nfor some reason and I had to look three times to figure out that (2)\nwas the interesting part.  Now it's in red!]\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"146747","messageId":"20100729235151.GB6623@burratino","threadId":"24501","inReplyTo":"201007251122.41166.trast@student.ethz.ch","subject":"Making error messages stand out (Re: [RFC/PATCH 0/9] commit: more focused advice in the no-changes-staged case)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-29T23:51:51Z","receivedAt":"2010-07-29T23:51:51Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Thomas Rast wrote:\n\n>   git://repo.or.cz/git/trast.git t/color-porcelain-message-output\n\nMy first thought was \"that’s a horrible idea; red text is so hard to\nread\".  My second thought: \"oh, maybe it’s not so bad because it’s\nbold\".  Now I am starting to worry about the sort of distraction that\ncan sometimes follow from too much formatting (e.g., with certain\nsyntax highlighting engines).\n\nA little bold text here and there (maybe to highlight the heading\nstrings like \"fatal\" and \"hint\") would be very useful, certainly.  To\ndeal with messages like\n\n  Recorded resolution for 'dir/a'.\n  [detached HEAD aa9ae6b] related change                          (1)\n   1 files changed, 1 insertions(+), 1 deletions(-)\n  Automatic cherry-pick failed.  After resolving the conflicts,\n  mark the corrected paths with 'git add <paths>', and\n  run 'git rebase --continue'\n  Recorded preimage for 'dir/a'\n  Could not apply 649420f... second                               (2)\n \nthough, I find the best solution is to use short, formulaic messages:\n\n  ...\n  Recorded resolution for 'dir/a'.\n  [detached HEAD aa9ae6b] related change\n   1 files changed, 1 insertions(+), 1 deletions(-)\n  fatal: could not apply 649420f... second\n  hint: after resolving the conflicts, mark the corrected paths\n  hint: with 'git add <paths>' and run 'git rebase --continue'\n\nI do realize this is not a very useful thing to say without attaching\na patch. ;-)\n"},{"id":"146794","messageId":"AANLkTi=ao2RY8NGm4cACqz3_5zfT2zvXB4JHOopBD9T5@mail.gmail.com","threadId":"24501","inReplyTo":"20100729235151.GB6623@burratino","subject":"Re: Making error messages stand out (Re: [RFC/PATCH 0/9] commit: more focused advice in the no-changes-staged case)","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-07-30T18:44:24Z","receivedAt":"2010-07-30T18:44:24Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Thu, Jul 29, 2010 at 18:51, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> though, I find the best solution is to use short, formulaic messages:\n>\n>  ...\n>  Recorded resolution for 'dir/a'.\n>  [detached HEAD aa9ae6b] related change\n>   1 files changed, 1 insertions(+), 1 deletions(-)\n>  fatal: could not apply 649420f... second\n>  hint: after resolving the conflicts, mark the corrected paths\n>  hint: with 'git add <paths>' and run 'git rebase --continue'\n\nYes please. This would be _extremely_ helpful!\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"147724","messageId":"201008110911.40133.trast@student.ethz.ch","threadId":"24501","inReplyTo":"20100725010230.GI18420@burratino","subject":"Re: [PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-08-11T07:11:39Z","receivedAt":"2010-08-11T07:11:39Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Jonathan Nieder wrote:\n> Example: before:\n>\n> \t$ git commit\n> \t# On branch master\n> \t# Changed but not updated:\n[...]\n> \tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n> \t$\n>\n> After:\n>\n> \t$ git commit\n> \tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n> \t$\n\nEither Junio just picked this up in the last push or I just never\nnoticed before, but this breaks t6040 which tests for the \"On branch\n...\" stuff:\n\n  ../trash directory.t6040-tracking-info$ git commit --dry-run\n  # On branch follower\n  # Your branch is ahead of 'master' by 1 commit.\n  #\n  nothing to commit (use -u to show untracked files)\n  ../trash directory.t6040-tracking-info$ ~/g/git-commit --dry-run\n  nothing to commit (use -u to show untracked files)\n\nresulting in\n\n  expecting success:\n          (\n                  cd test &&\n                  git checkout b1 >/dev/null &&\n                  # reports nothing to commit\n                  test_must_fail git commit --dry-run\n          ) >actual &&\n          grep \"have 1 and 1 different\" actual\n\n  Already on 'b1'\n  not ok - 5 status\n\n--\nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"147725","messageId":"20100811073028.GA5450@burratino","threadId":"24501","inReplyTo":"201008110911.40133.trast@student.ethz.ch","subject":"Re: [PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T07:30:28Z","receivedAt":"2010-08-11T07:30:28Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Thomas Rast wrote:\n> Jonathan Nieder wrote:\n\n>> Example: before:\n>>\n>> \t$ git commit\n>> \t# On branch master\n>> \t# Changed but not updated:\n>[...]\n>> \tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n>> \t$\n>>\n>> After:\n>>\n>> \t$ git commit\n>> \tno changes added to commit (use \"git add\" and/or \"git commit -a\")\n>> \t$\n>\n> Either Junio just picked this up in the last push or I just never\n> noticed before, but this breaks t6040 which tests for the \"On branch\n> ...\" stuff\n\nYep, Ævar noticed the same.  That test is meant to check that\nwhen git commit/status gives status information it reflects the\ncorrect tracking info.  So maybe:\n\n-- 8< --\nSubject: t6040 (branch tracking): check “status” instead of “commit”\n\nAmong the tests for correct branch tracking output is one that\nexamines “git commit” output:\n\n $ git commit\n # Your branch and 'origin/maint' have diverged,\n # and have 9 and 69 different commit(s) each, respectively.\n [...]\n no changes added to commit (use \"git add\" and/or \"git commit -a\")\n $\n\nBut we are experimenting with changing that output.  So drop\nthat test for now and replace it with a test for “git status”\n(which was not being checked yet and shares the same output\nformat and wt-status backend).\n\nReported-by: Thomas Rast <trast@student.ethz.ch>\nReported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 1785e17..3bc91b1 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -64,7 +64,7 @@ test_expect_success 'checkout with local tracked branch' '\n \tgrep \"is ahead of\" actual\n '\n \n-test_expect_success 'status' '\n+test_expect_failure 'status' '\n \t(\n \t\tcd test &&\n \t\tgit checkout b1 >/dev/null &&\n-- \n"},{"id":"147726","messageId":"20100811074909.GC5450@burratino","threadId":"24501","inReplyTo":"20100811073028.GA5450@burratino","subject":"[PATCH v2] t6040 (branch tracking): check “status” instead of “commit”","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T07:49:09Z","receivedAt":"2010-08-11T07:49:09Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Among the tests for correct branch tracking output is one that\nexamines “git commit” output:\n\n $ git commit\n # Your branch and 'origin/maint' have diverged,\n # and have 9 and 69 different commit(s) each, respectively.\n [...]\n no changes added to commit (use \"git add\" and/or \"git commit -a\")\n $\n\nBut we are experimenting with changing that output.  So drop\nthat test for now and replace it with a test for “git status”\n(which was not being checked yet and shares the same output\nformat and wt-status backend).\n\nReported-by: Thomas Rast <trast@student.ethz.ch>\nReported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Oops, wrong patch.  Here’s the one I meant.  Sane?\n\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex 1785e17..a5b4489 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -68,8 +68,7 @@ test_expect_success 'status' '\n \t(\n \t\tcd test &&\n \t\tgit checkout b1 >/dev/null &&\n-\t\t# reports nothing to commit\n-\t\ttest_must_fail git commit --dry-run\n+\t\tgit status\n \t) >actual &&\n \tgrep \"have 1 and 1 different\" actual\n '\n-- \n"},{"id":"147732","messageId":"20100811083100.GA16495@burratino","threadId":"24501","inReplyTo":"AANLkTi=ao2RY8NGm4cACqz3_5zfT2zvXB4JHOopBD9T5@mail.gmail.com","subject":"[WIP/PATCH 0/4] Re: Making error messages stand out","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T08:31:00Z","receivedAt":"2010-08-11T08:31:00Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Sverre Rabbelier wrote:\n> On Thu, Jul 29, 2010 at 18:51, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> though, I find the best solution is to use short, formulaic messages:\n>>\n>>  ...\n>>  Recorded resolution for 'dir/a'.\n>>  [detached HEAD aa9ae6b] related change\n>>   1 files changed, 1 insertions(+), 1 deletions(-)\n>>  fatal: could not apply 649420f... second\n>>  hint: after resolving the conflicts, mark the corrected paths\n>>  hint: with 'git add <paths>' and run 'git rebase --continue'\n>\n> Yes please. This would be _extremely_ helpful!\n\nOk. :)\n\nThis does not suppress the “Could not apply” message at the end yet.\n\nPatches are against cc/revert.\n\nJonathan Nieder (4):\n  Eliminate “Finished cherry-pick/revert” message\n  Introduce advise() to print hints\n  cherry-pick: Use error() for failure message\n  cherry-pick: Use advise() for hints\n\n Documentation/howto/revert-branch-rebase.txt |    6 ---\n builtin/revert.c                             |   52 ++++++++++++-------------\n contrib/examples/git-revert.sh               |    1 -\n git-rebase--interactive.sh                   |    6 +-\n t/t3507-cherry-pick-conflict.sh              |   20 ++++++++++\n t/t3508-cherry-pick-many-commits.sh          |   42 +++++++++++++++------\n 6 files changed, 78 insertions(+), 49 deletions(-)\n"},{"id":"147734","messageId":"20100811083607.GB16495@burratino","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"[PATCH 1/4] Eliminate “Finished cherry-pick/revert” message","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T08:36:07Z","receivedAt":"2010-08-11T08:36:07Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"When cherry-pick was written (v0.99.6~63, 2005-08-27), “git commit”\nwas quiet, and the output from cherry-pick provided useful information\nabout the progress of a rebase.\n\nNow next to the output from “git commit”, the cherry-pick notification\nis so much noise (except for the name of the picked commit).\n\n $ git cherry-pick ..topic\n Finished cherry-pick of 499088b.\n [detached HEAD 17e1ff2] Move glob module to libdpkg\n  Author: Guillem Jover <guillem@debian.org>\n  8 files changed, 12 insertions(+), 9 deletions(-)\n  rename {src => lib/dpkg}/glob.c (98%)\n  rename {src => lib/dpkg}/glob.h (93%)\n Finished cherry-pick of ae947e1.\n [detached HEAD 058caa3] libdpkg: Add missing symbols to Versions script\n  Author: Guillem Jover <guillem@debian.org>\n  1 files changed, 2 insertions(+), 0 deletions(-)\n $\n\nThe noise is especially troublesome when sifting through the output of\na rebase or multiple cherry-pick that eventually failed.\n\nWith the commit subject, it is already not hard to figure out where\nthe commit came from.  So drop the “Finished” message.\n\nCc: Christian Couder <chriscool@tuxfamily.org>\nCc: Thomas Rast <trast@student.ethz.ch>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/howto/revert-branch-rebase.txt |    6 ----\n builtin/revert.c                             |    2 -\n contrib/examples/git-revert.sh               |    1 -\n t/t3508-cherry-pick-many-commits.sh          |   42 ++++++++++++++++++-------\n 4 files changed, 30 insertions(+), 21 deletions(-)\n\ndiff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt\nindex 8c32da6..093c656 100644\n--- a/Documentation/howto/revert-branch-rebase.txt\n+++ b/Documentation/howto/revert-branch-rebase.txt\n@@ -112,25 +112,19 @@ $ git tag pu-anchor pu\n $ git rebase master\n * Applying: Redo \"revert\" using three-way merge machinery.\n First trying simple merge strategy to cherry-pick.\n-Finished one cherry-pick.\n * Applying: Remove git-apply-patch-script.\n First trying simple merge strategy to cherry-pick.\n Simple cherry-pick fails; trying Automatic cherry-pick.\n Removing Documentation/git-apply-patch-script.txt\n Removing git-apply-patch-script\n-Finished one cherry-pick.\n * Applying: Document \"git cherry-pick\" and \"git revert\"\n First trying simple merge strategy to cherry-pick.\n-Finished one cherry-pick.\n * Applying: mailinfo and applymbox updates\n First trying simple merge strategy to cherry-pick.\n-Finished one cherry-pick.\n * Applying: Show commits in topo order and name all commits.\n First trying simple merge strategy to cherry-pick.\n-Finished one cherry-pick.\n * Applying: More documentation updates.\n First trying simple merge strategy to cherry-pick.\n-Finished one cherry-pick.\n ------------------------------------------------\n \n The temporary tag 'pu-anchor' is me just being careful, in case 'git\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex e261fb2..c3d64af 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -521,8 +521,6 @@ static int do_pick_commit(void)\n \t} else {\n \t\tif (!no_commit)\n \t\t\tres = run_git_commit(defmsg);\n-\t\tif (!res)\n-\t\t\tfprintf(stderr, \"Finished %s.\\n\", mebuf.buf);\n \t}\n \n \tstrbuf_release(&mebuf);\ndiff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh\nindex 49f0032..60a05a8 100755\n--- a/contrib/examples/git-revert.sh\n+++ b/contrib/examples/git-revert.sh\n@@ -181,7 +181,6 @@ Conflicts:\n \tesac\n \texit 1\n }\n-echo >&2 \"Finished one $me.\"\n \n # If we are cherry-pick, and if the merge did not result in\n # hand-editing, we will hit this commit and inherit the original\ndiff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh\nindex 0f61495..8e09fd0 100755\n--- a/t/t3508-cherry-pick-many-commits.sh\n+++ b/t/t3508-cherry-pick-many-commits.sh\n@@ -35,36 +35,54 @@ test_expect_success setup '\n '\n \n test_expect_success 'cherry-pick first..fourth works' '\n-\tcat <<-EOF >expected &&\n-\tFinished cherry-pick of commit $(git rev-parse --short second).\n-\tFinished cherry-pick of commit $(git rev-parse --short third).\n-\tFinished cherry-pick of commit $(git rev-parse --short fourth).\n+\tcat <<-\\EOF >expected &&\n+\t[master OBJID] second\n+\t Author: A U Thor <author@example.com>\n+\t 1 files changed, 1 insertions(+), 0 deletions(-)\n+\t[master OBJID] third\n+\t Author: A U Thor <author@example.com>\n+\t 1 files changed, 1 insertions(+), 0 deletions(-)\n+\t[master OBJID] fourth\n+\t Author: A U Thor <author@example.com>\n+\t 1 files changed, 1 insertions(+), 0 deletions(-)\n \tEOF\n \n \tgit checkout -f master &&\n \tgit reset --hard first &&\n \ttest_tick &&\n-\tgit cherry-pick first..fourth 2>actual &&\n+\tgit cherry-pick first..fourth >actual &&\n \tgit diff --quiet other &&\n \tgit diff --quiet HEAD other &&\n-\ttest_cmp expected actual &&\n+\n+\tsed -e \"s/$_x05[0-9a-f][0-9a-f]/OBJID/\" <actual >actual.fuzzy &&\n+\ttest_cmp expected actual.fuzzy &&\n \tcheck_head_differs_from fourth\n '\n \n test_expect_success 'cherry-pick --strategy resolve first..fourth works' '\n-\tcat <<-EOF >expected &&\n-\tFinished cherry-pick of commit $(git rev-parse --short second) with strategy resolve.\n-\tFinished cherry-pick of commit $(git rev-parse --short third) with strategy resolve.\n-\tFinished cherry-pick of commit $(git rev-parse --short fourth) with strategy resolve.\n+\tcat <<-\\EOF >expected &&\n+\tTrying simple merge.\n+\t[master OBJID] second\n+\t Author: A U Thor <author@example.com>\n+\t 1 files changed, 1 insertions(+), 0 deletions(-)\n+\tTrying simple merge.\n+\t[master OBJID] third\n+\t Author: A U Thor <author@example.com>\n+\t 1 files changed, 1 insertions(+), 0 deletions(-)\n+\tTrying simple merge.\n+\t[master OBJID] fourth\n+\t Author: A U Thor <author@example.com>\n+\t 1 files changed, 1 insertions(+), 0 deletions(-)\n \tEOF\n \n \tgit checkout -f master &&\n \tgit reset --hard first &&\n \ttest_tick &&\n-\tgit cherry-pick --strategy resolve first..fourth 2>actual &&\n+\tgit cherry-pick --strategy resolve first..fourth >actual &&\n \tgit diff --quiet other &&\n \tgit diff --quiet HEAD other &&\n-\ttest_cmp expected actual &&\n+\tsed -e \"s/$_x05[0-9a-f][0-9a-f]/OBJID/\" <actual >actual.fuzzy &&\n+\ttest_cmp expected actual.fuzzy &&\n \tcheck_head_differs_from fourth\n '\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"147735","messageId":"20100811083641.GC16495@burratino","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"[PATCH 2/4] Introduce advise() to print hints","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T08:36:41Z","receivedAt":"2010-08-11T08:36:41Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Like error(), warn(), and die(), advise() prints a short message\nwith a formulaic prefix to stderr.\n\nIt is local to revert.c for now because I am not sure this is\nthe right API (we may want to take an array of advice lines or a\nboolean argument for easy suppression of unwanted advice).\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/revert.c |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex c3d64af..74c1581 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -241,6 +241,15 @@ static void set_author_ident_env(const char *message)\n \t\t\tsha1_to_hex(commit->object.sha1));\n }\n \n+static void advise(const char *advice, ...)\n+{\n+\tva_list params;\n+\n+\tva_start(params, advice);\n+\tvreportf(\"hint: \", advice, params);\n+\tva_end(params);\n+}\n+\n static char *help_msg(void)\n {\n \tstruct strbuf helpbuf = STRBUF_INIT;\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"147737","messageId":"20100811083724.GD16495@burratino","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"[PATCH 3/4] cherry-pick/revert: Use error() for failure message","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T08:37:24Z","receivedAt":"2010-08-11T08:37:24Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"When cherry-pick fails after picking a large series of commits, it can\nbe hard to pick out the error message and advice.  Clarify the error\nand prefix it with “error: ” to help.\n\nBefore:\n\n\tAutomatic cherry-pick failed.  [...advice...]\n\nAfter:\n\n\terror: could not apply 7ab78c9... Do something neat.\n\t[...advice...]\n\nNoticed-by: Thomas Rast <trast@student.ethz.ch>\nEncouraged-by: Sverre Rabbelier <srabbelier@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/revert.c |    7 +++++--\n 1 files changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 74c1581..9a7483b 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -524,8 +524,11 @@ static int do_pick_commit(void)\n \t}\n \n \tif (res) {\n-\t\tfprintf(stderr, \"Automatic %s failed.%s\\n\",\n-\t\t\tmebuf.buf, help_msg());\n+\t\terror(\"could not %s %s... %s\",\n+\t\t      action == REVERT ? \"revert\" : \"apply\",\n+\t\t      find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),\n+\t\t      msg.subject);\n+\t\tfprintf(stderr, help_msg());\n \t\trerere(allow_rerere_auto);\n \t} else {\n \t\tif (!no_commit)\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"147739","messageId":"20100811083751.GE16495@burratino","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"[PATCH 4/4] cherry-pick/revert: Use advise() for hints","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T08:37:51Z","receivedAt":"2010-08-11T08:37:51Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"When cherry-pick fails after picking a large series of commits, it can\nbe hard to pick out the error message and advice.  Prefix the advice\nwith “hint: ” to help.\n\nBefore:\n\n    error: could not apply 7ab78c9... foo\n      After resolving the conflicts,\n    mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n    and commit the result with:\n\n            git commit -c 7ab78c9a7898b87127365478431289cb98f8d98f\n\nAfter:\n\n    error: could not apply 7ab78c9... foo\n    hint: after resolving the conflicts, mark the corrected paths\n    hint: with 'git add <paths>' or 'git rm <paths>'\n    hint: and commit the result with 'git commit -c 7ab78c9'\n\nNoticed-by: Thomas Rast <trast@student.ethz.ch>\nEncouraged-by: Sverre Rabbelier <srabbelier@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nThanks for reading.\n\n builtin/revert.c                |   36 ++++++++++++------------------------\n git-rebase--interactive.sh      |    6 +++---\n t/t3507-cherry-pick-conflict.sh |   20 ++++++++++++++++++++\n 3 files changed, 35 insertions(+), 27 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 9a7483b..7f35cc6 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -250,27 +250,21 @@ static void advise(const char *advice, ...)\n \tva_end(params);\n }\n \n-static char *help_msg(void)\n+static void print_advice(void)\n {\n-\tstruct strbuf helpbuf = STRBUF_INIT;\n \tchar *msg = getenv(\"GIT_CHERRY_PICK_HELP\");\n \n-\tif (msg)\n-\t\treturn msg;\n-\n-\tstrbuf_addstr(&helpbuf, \"  After resolving the conflicts,\\n\"\n-\t\t\"mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\\n\"\n-\t\t\"and commit the result\");\n-\n-\tif (action == CHERRY_PICK) {\n-\t\tstrbuf_addf(&helpbuf, \" with: \\n\"\n-\t\t\t\"\\n\"\n-\t\t\t\"        git commit -c %s\\n\",\n-\t\t\t    sha1_to_hex(commit->object.sha1));\n+\tif (msg) {\n+\t\tfprintf(stderr, \"%s\\n\", msg);\n+\t\treturn;\n \t}\n-\telse\n-\t\tstrbuf_addch(&helpbuf, '.');\n-\treturn strbuf_detach(&helpbuf, NULL);\n+\n+\tadvise(\"after resolving the conflicts, mark the corrected paths\");\n+\tadvise(\"with 'git add <paths>' or 'git rm <paths>'\");\n+\n+\tif (action == CHERRY_PICK)\n+\t\tadvise(\"and commit the result with 'git commit -c %s'\",\n+\t\t       find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));\n }\n \n static void write_message(struct strbuf *msgbuf, const char *filename)\n@@ -404,7 +398,6 @@ static int do_pick_commit(void)\n \tstruct commit_message msg = { NULL, NULL, NULL, NULL, NULL };\n \tchar *defmsg = NULL;\n \tstruct strbuf msgbuf = STRBUF_INIT;\n-\tstruct strbuf mebuf = STRBUF_INIT;\n \tint res;\n \n \tif (no_commit) {\n@@ -501,9 +494,6 @@ static int do_pick_commit(void)\n \t\t}\n \t}\n \n-\tstrbuf_addf(&mebuf, \"%s of commit %s\", me,\n-\t\t    find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));\n-\n \tif (!strategy || !strcmp(strategy, \"recursive\") || action == REVERT) {\n \t\tres = do_recursive_merge(base, next, base_label, next_label,\n \t\t\t\t\t head, &msgbuf);\n@@ -512,7 +502,6 @@ static int do_pick_commit(void)\n \t\tstruct commit_list *common = NULL;\n \t\tstruct commit_list *remotes = NULL;\n \n-\t\tstrbuf_addf(&mebuf, \" with strategy %s\", strategy);\n \t\twrite_message(&msgbuf, defmsg);\n \n \t\tcommit_list_insert(base, &common);\n@@ -528,14 +517,13 @@ static int do_pick_commit(void)\n \t\t      action == REVERT ? \"revert\" : \"apply\",\n \t\t      find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),\n \t\t      msg.subject);\n-\t\tfprintf(stderr, help_msg());\n+\t\tprint_advice();\n \t\trerere(allow_rerere_auto);\n \t} else {\n \t\tif (!no_commit)\n \t\t\tres = run_git_commit(defmsg);\n \t}\n \n-\tstrbuf_release(&mebuf);\n \tfree_message(&msg);\n \tfree(defmsg);\n \ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 31e6860..8f6876d 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -113,9 +113,9 @@ REBASE_ROOT=\n AUTOSQUASH=\n NEVER_FF=\n \n-GIT_CHERRY_PICK_HELP=\"  After resolving the conflicts,\n-mark the corrected paths with 'git add <paths>', and\n-run 'git rebase --continue'\"\n+GIT_CHERRY_PICK_HELP=\"\\\n+hint: after resolving the conflicts, mark the corrected paths\n+hint: with 'git add <paths>' and run 'git rebase --continue'\"\n export GIT_CHERRY_PICK_HELP\n \n warn () {\ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex e25cf80..3f29594 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -38,6 +38,26 @@ test_expect_success 'failed cherry-pick does not advance HEAD' '\n \ttest \"$head\" = \"$newhead\"\n '\n \n+test_expect_success 'advice from failed cherry-pick' '\n+\tgit checkout -f initial^0 &&\n+\tgit read-tree -u --reset HEAD &&\n+\tgit clean -d -f -f -q -x &&\n+\n+\tgit update-index --refresh &&\n+\tgit diff-index --exit-code HEAD &&\n+\n+\tpicked=$(git rev-parse --short picked) &&\n+\tcat <<-EOF >expected &&\n+\terror: could not apply $picked... picked\n+\thint: after resolving the conflicts, mark the corrected paths\n+\thint: with 'git add <paths>' or 'git rm <paths>'\n+\thint: and commit the result with 'git commit -c $picked'\n+\tEOF\n+\ttest_must_fail git cherry-pick picked 2>actual &&\n+\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'failed cherry-pick produces dirty index' '\n \n \tgit checkout -f initial^0 &&\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"147747","messageId":"AANLkTi=cNUTG-DGZNpwrag9Wz2-JoQQamiayKVNA5wbn@mail.gmail.com","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"Re: [WIP/PATCH 0/4] Re: Making error messages stand out","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-08-11T09:21:52Z","receivedAt":"2010-08-11T09:21:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Aug 11, 2010 at 6:31 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Sverre Rabbelier wrote:\n>> On Thu, Jul 29, 2010 at 18:51, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>\n>>> though, I find the best solution is to use short, formulaic messages:\n>>>\n>>>  ...\n>>>  Recorded resolution for 'dir/a'.\n>>>  [detached HEAD aa9ae6b] related change\n>>>   1 files changed, 1 insertions(+), 1 deletions(-)\n>>>  fatal: could not apply 649420f... second\n>>>  hint: after resolving the conflicts, mark the corrected paths\n>>>  hint: with 'git add <paths>' and run 'git rebase --continue'\n>>\n>> Yes please. This would be _extremely_ helpful!\n>\n> Ok. :)\n>\n> This does not suppress the “Could not apply” message at the end yet.\n\nEven better, make it available for some time with, say \"git hints\".\nAfter doing lots of things to resolve conflicts, I simply forget what\nit hinted me.\n-- \nDuy\n"},{"id":"147749","messageId":"vpqhbj11o9d.fsf@bauges.imag.fr","threadId":"24501","inReplyTo":"AANLkTi=cNUTG-DGZNpwrag9Wz2-JoQQamiayKVNA5wbn@mail.gmail.com","subject":"Re: [WIP/PATCH 0/4] Re: Making error messages stand out","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2010-08-11T09:39:58Z","receivedAt":"2010-08-11T09:39:58Z","isPatch":true,"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> Even better, make it available for some time with, say \"git hints\".\n> After doing lots of things to resolve conflicts, I simply forget what\n> it hinted me.\n\nActually, I don't think we should add a new command for that, but add\nsomething to \"git status\", like\n\n$ git status\n# On branch master\n# rebase in progress (use \"git rebase --continue\" to proceed)\n# ...\n\nSame would apply to conflicting merges. It's very common for beginners\n(especially when they come from SVN) to start a merge, mis-read the\nmessage telling you to commit once you fixed the conflicts, fix\nconflicts, and continue hacking. A message in \"git status\" when\n.git/MERGE_HEAD exists would help a bit, like (depending on whether\nthe index still has conflicts):\n\n# merge in progress (fix conflicts below and commit)\n\n# merge in progress (use \"git commit\" to proceed)\n\n\nIf one adds an option to make it all-caps, red, and blinking, then\nI'll activate it for my students ;-).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"147751","messageId":"AANLkTinxm9Fzwewh2BS0kMxDGG=QKhz3wfVwNikTVZSr@mail.gmail.com","threadId":"24501","inReplyTo":"vpqhbj11o9d.fsf@bauges.imag.fr","subject":"Re: [WIP/PATCH 0/4] Re: Making error messages stand out","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-08-11T09:58:56Z","receivedAt":"2010-08-11T09:58:56Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Aug 11, 2010 at 7:39 PM, Matthieu Moy\n<Matthieu.Moy@grenoble-inp.fr> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> Even better, make it available for some time with, say \"git hints\".\n>> After doing lots of things to resolve conflicts, I simply forget what\n>> it hinted me.\n>\n> Actually, I don't think we should add a new command for that, but add\n> something to \"git status\", like\n>\n> $ git status\n> # On branch master\n> # rebase in progress (use \"git rebase --continue\" to proceed)\n> # ...\n>\n> Same would apply to conflicting merges. It's very common for beginners\n> (especially when they come from SVN) to start a merge, mis-read the\n> message telling you to commit once you fixed the conflicts, fix\n> conflicts, and continue hacking. A message in \"git status\" when\n> .git/MERGE_HEAD exists would help a bit, like (depending on whether\n> the index still has conflicts):\n>\n> # merge in progress (fix conflicts below and commit)\n>\n> # merge in progress (use \"git commit\" to proceed)\n\nYes. Looks good. Except that I rarely use git-status these days. Maybe\nthat will motivate me to use that command more.\n\n> If one adds an option to make it all-caps, red, and blinking, then\n> I'll activate it for my students ;-).\n\nI'd suggest you patch git-status with figlet to get some more attention :-)\n-- \nDuy\n"},{"id":"147757","messageId":"AANLkTi=DPu+roNsuWZARkK=cmKhcqMx=CDyiv6cf7tof@mail.gmail.com","threadId":"24501","inReplyTo":"20100811073028.GA5450@burratino","subject":"Re: [PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-11T12:15:23Z","receivedAt":"2010-08-11T12:15:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 11, 2010 at 07:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n> -test_expect_success 'status' '\n> +test_expect_failure 'status' '\n>        (\n>                cd test &&\n>                git checkout b1 >/dev/null &&\n\nBetter to test_expect_success like my patch does and explicitly check\nthe output, otherwise that test will pass if any part of it fails,\ne.g. if the checkout fails.\n\nNot likely, but it's more likely that the output will change again, in\nwhich case the grep tests I did would start failing again.\n\nIt's good to have test canaries like that for important parts of our\noutput.\n"},{"id":"147798","messageId":"AANLkTimBY=WxAr8fv=W2AMcdQ6Jmcj0kvN=SDmrn5KYN@mail.gmail.com","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"Re: [WIP/PATCH 0/4] Re: Making error messages stand out","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-08-11T17:34:41Z","receivedAt":"2010-08-11T17:34:41Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Wed, Aug 11, 2010 at 03:31, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Jonathan Nieder (4):\n>  Eliminate “Finished cherry-pick/revert” message\n>  Introduce advise() to print hints\n>  cherry-pick: Use error() for failure message\n>  cherry-pick: Use advise() for hints\n\nNice :).\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"147847","messageId":"20100811235742.GA18499@burratino","threadId":"24501","inReplyTo":"AANLkTi=DPu+roNsuWZARkK=cmKhcqMx=CDyiv6cf7tof@mail.gmail.com","subject":"Re: [PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-11T23:57:42Z","receivedAt":"2010-08-11T23:57:42Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n> On Wed, Aug 11, 2010 at 07:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> -test_expect_success 'status' '\n>> +test_expect_failure 'status' '\n\nOops.  Did you see the follow-up patch?\n\n> Better to test_expect_success like my patch does and explicitly check\n> the output, otherwise that test will pass if any part of it fails,\n> e.g. if the checkout fails.\n>\n> Not likely, but it's more likely that the output will change again, in\n> which case the grep tests I did would start failing again.\n\nThe wt-status output series ought have included a separate test for\nthe new “git commit --dry-run” output.  But this is not what that test\nscript is about, and I think including it there would have been\nconfusing.\n\nSorry for the breakage, and thanks for reporting it.\n"},{"id":"147845","messageId":"AANLkTikVyWjTmRssQyBfRVY=PLguTgHHA+_YdsmsMwP3@mail.gmail.com","threadId":"24501","inReplyTo":"20100811235742.GA18499@burratino","subject":"Re: [PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-12T00:05:25Z","receivedAt":"2010-08-12T00:05:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 11, 2010 at 23:57, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Ævar Arnfjörð Bjarmason wrote:\n>> On Wed, Aug 11, 2010 at 07:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>\n>>> -test_expect_success 'status' '\n>>> +test_expect_failure 'status' '\n>\n> Oops.  Did you see the follow-up patch?\n\nNo, I'm probably missing something. Move along now, nothing to see\nhere :)\n\n>> Better to test_expect_success like my patch does and explicitly check\n>> the output, otherwise that test will pass if any part of it fails,\n>> e.g. if the checkout fails.\n>>\n>> Not likely, but it's more likely that the output will change again, in\n>> which case the grep tests I did would start failing again.\n>\n> The wt-status output series ought have included a separate test for\n> the new “git commit --dry-run” output.  But this is not what that test\n> script is about, and I think including it there would have been\n> confusing.\n\nSounds like you got this covered, that's good enough for me.\n\n> Sorry for the breakage, and thanks for reporting it.\n\nNo problem.\n"},{"id":"147846","messageId":"20100812001013.GB18499@burratino","threadId":"24501","inReplyTo":"AANLkTikVyWjTmRssQyBfRVY=PLguTgHHA+_YdsmsMwP3@mail.gmail.com","subject":"Re: [PATCH 9/9] commit: suppress status summary when no changes staged","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-12T00:10:13Z","receivedAt":"2010-08-12T00:10:13Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n> On Wed, Aug 11, 2010 at 23:57, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> Did you see the follow-up patch?\n>\n> No, I'm probably missing something. Move along now, nothing to see\n> here :)\n\nI figured it out.  Gmail’s implementation of threading is (deliberately)\nbroken.\n\nThe follow-up has subject\n\n  [PATCH v2] t6040 (branch tracking): check “status” instead of “commit”\n\n> Sounds like you got this covered\n\nThanks again for a quick report and patch --- they were helpful\nindeed.\n"},{"id":"147849","messageId":"AANLkTi=zQW=QjmBtDwwn51VCDPfJae6CQwSbx+9ATxNs@mail.gmail.com","threadId":"24501","inReplyTo":"20100811074909.GC5450@burratino","subject":"Re: [PATCH v2] t6040 (branch tracking): check “status” instead of “commit”","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-12T00:45:31Z","receivedAt":"2010-08-12T00:45:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 11, 2010 at 07:49, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Among the tests for correct branch tracking output is one that\n> examines “git commit” output:\n>\n>  $ git commit\n>  # Your branch and 'origin/maint' have diverged,\n>  # and have 9 and 69 different commit(s) each, respectively.\n>  [...]\n>  no changes added to commit (use \"git add\" and/or \"git commit -a\")\n>  $\n>\n> But we are experimenting with changing that output.  So drop\n> that test for now and replace it with a test for “git status”\n> (which was not being checked yet and shares the same output\n> format and wt-status backend).\n>\n> Reported-by: Thomas Rast <trast@student.ethz.ch>\n> Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> ---\n>  Oops, wrong patch.  Here’s the one I meant.  Sane?\n>\n> diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\n> index 1785e17..a5b4489 100755\n> --- a/t/t6040-tracking-info.sh\n> +++ b/t/t6040-tracking-info.sh\n> @@ -68,8 +68,7 @@ test_expect_success 'status' '\n>        (\n>                cd test &&\n>                git checkout b1 >/dev/null &&\n> -               # reports nothing to commit\n> -               test_must_fail git commit --dry-run\n> +               git status\n>        ) >actual &&\n>        grep \"have 1 and 1 different\" actual\n>  '\n\nThis looks good. My patch should be dropped in favor of this. It looks\nlike the extra testing I did is covered by the \"git commit --dry-run\"\ntest in t7508-status.sh in your original patch.\n"},{"id":"148386","messageId":"1282142204-14720-1-git-send-email-avarab@gmail.com","threadId":"24501","inReplyTo":"20100811083100.GA16495@burratino","subject":"[PATCH] tests: fix syntax error in \"Use advise() for hints\" test","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-18T14:36:44Z","receivedAt":"2010-08-18T14:36:44Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the test introduced in the \"Use advise() for hints\" patch by\nJonathan Nieder not to use '' for quotes inside '' delimited code. It\nended up introducing a file called <paths> to the main git repository.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t3507-cherry-pick-conflict.sh |   10 +++++-----\n 1 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex 3f29594..607bf25 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -38,7 +38,7 @@ test_expect_success 'failed cherry-pick does not advance HEAD' '\n \ttest \"$head\" = \"$newhead\"\n '\n \n-test_expect_success 'advice from failed cherry-pick' '\n+test_expect_success 'advice from failed cherry-pick' \"\n \tgit checkout -f initial^0 &&\n \tgit read-tree -u --reset HEAD &&\n \tgit clean -d -f -f -q -x &&\n@@ -46,17 +46,17 @@ test_expect_success 'advice from failed cherry-pick' '\n \tgit update-index --refresh &&\n \tgit diff-index --exit-code HEAD &&\n \n-\tpicked=$(git rev-parse --short picked) &&\n+\tpicked=\\$(git rev-parse --short picked) &&\n \tcat <<-EOF >expected &&\n-\terror: could not apply $picked... picked\n+\terror: could not apply \\$picked... picked\n \thint: after resolving the conflicts, mark the corrected paths\n \thint: with 'git add <paths>' or 'git rm <paths>'\n-\thint: and commit the result with 'git commit -c $picked'\n+\thint: and commit the result with 'git commit -c \\$picked'\n \tEOF\n \ttest_must_fail git cherry-pick picked 2>actual &&\n \n \ttest_cmp expected actual\n-'\n+\"\n \n test_expect_success 'failed cherry-pick produces dirty index' '\n \n-- \n1.7.2.1.414.g9bf49\n"},{"id":"148436","messageId":"20100819043036.GD25649@burratino","threadId":"24501","inReplyTo":"1282142204-14720-1-git-send-email-avarab@gmail.com","subject":"Re: [PATCH] tests: fix syntax error in \"Use advise() for hints\" test","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-19T04:30:36Z","receivedAt":"2010-08-19T04:30:36Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n\n> Change the test introduced in the \"Use advise() for hints\" patch by\n> Jonathan Nieder not to use '' for quotes inside '' delimited code.\n\nYikes.  Thanks for catching this.\n\n> -test_expect_success 'advice from failed cherry-pick' '\n> +test_expect_success 'advice from failed cherry-pick' \"\n[...]\n>  \tcat <<-EOF >expected &&\n> -\terror: could not apply $picked... picked\n> +\terror: could not apply \\$picked... picked\n\nAlthough the style you chose is arguably the least ugly, nested shell\ninterpolation can be hard to follow.  How about this?\n\n-- 8< --\nSubject: t3507 (cherry-pick): escape quotes in \"Use advise()\" test\n\nDo not use unescaped '' quotes inside ''-delimited code.  Otherwise,\nthis test tries to read a file named \"paths\" in the test repository,\nresulting in the error:\n\n t3507-cherry-pick-conflict.sh: 59: cannot open paths: No such file\n\nBased-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t3507-cherry-pick-conflict.sh |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex 3f29594..6026e7e 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -50,8 +50,8 @@ test_expect_success 'advice from failed cherry-pick' '\n \tcat <<-EOF >expected &&\n \terror: could not apply $picked... picked\n \thint: after resolving the conflicts, mark the corrected paths\n-\thint: with 'git add <paths>' or 'git rm <paths>'\n-\thint: and commit the result with 'git commit -c $picked'\n+\thint: with '\\''git add <paths>'\\'' or '\\''git rm <paths>'\\''\n+\thint: and commit the result with '\\''git commit -c $picked'\\''\n \tEOF\n \ttest_must_fail git cherry-pick picked 2>actual &&\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148446","messageId":"AANLkTikDq4eJfm2RnbGDuJMHCR8_4cn6NfJpoYWHbWWN@mail.gmail.com","threadId":"24501","inReplyTo":"20100819043036.GD25649@burratino","subject":"Re: [PATCH] tests: fix syntax error in \"Use advise() for hints\" test","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-19T12:22:31Z","receivedAt":"2010-08-19T12:22:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Thu, Aug 19, 2010 at 04:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Ævar Arnfjörð Bjarmason wrote:\n>\n>> Change the test introduced in the \"Use advise() for hints\" patch by\n>> Jonathan Nieder not to use '' for quotes inside '' delimited code.\n>\n> Yikes.  Thanks for catching this.\n\nFWIW prove flagged it:\n\n    $ prove ./t35*.sh\n    ./t3500-cherry.sh .................... ok\n    ./t3501-revert-cherry-pick.sh ........ ok\n    ./t3502-cherry-pick-merge.sh ......... ok\n    ./t3503-cherry-pick-root.sh .......... ok\n    ./t3504-cherry-pick-rerere.sh ........ ok\n    ./t3505-cherry-pick-empty.sh ......... ok\n    ./t3506-cherry-pick-ff.sh ............ ok\n    ./t3507-cherry-pick-conflict.sh ...... 1/?\n./t3507-cherry-pick-conflict.sh: 59: cannot open paths: No such file\n    ./t3507-cherry-pick-conflict.sh ...... ok\n    ./t3508-cherry-pick-many-commits.sh .. ok\n    ./t3509-cherry-pick-merge-df.sh ...... ok\n    All tests successful.\n    Files=10, Tests=62,  4 wallclock secs ( 0.08 usr  0.06 sys +  0.65\ncusr  2.91 csys =  3.70 CPU)\n    Result: PASS\n\n> Although the style you chose is arguably the least ugly, nested shell\n> interpolation can be hard to follow.  How about this?\n\nI think '\\'' is harder to follow than \\\" and \\$, but each to his own\n:)\n"},{"id":"148542","messageId":"87aaohwq0r.fsf@hariville.hurrynot.org","threadId":"24501","inReplyTo":"AANLkTikDq4eJfm2RnbGDuJMHCR8_4cn6NfJpoYWHbWWN@mail.gmail.com","subject":"Re: [PATCH] tests: fix syntax error in \"Use advise() for hints\" test","fromName":"Raja R Harinath","fromEmail":"harinath@hurrynot.org","sentAt":"2010-08-20T10:13:24Z","receivedAt":"2010-08-20T10:13:24Z","isPatch":true,"sender":{"key":"harinath@hurrynot.org","avatar":"https://avatars.githubusercontent.com/u/4610?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> On Thu, Aug 19, 2010 at 04:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n[snip]\n>> Although the style you chose is arguably the least ugly, nested shell\n>> interpolation can be hard to follow.  How about this?\n>\n> I think '\\'' is harder to follow than \\\" and \\$, but each to his own\n> :)\n\nThere's also the slightly longer but somewhat prettier '\"'\"'.\n\n- Hari\n"},{"id":"148570","messageId":"AANLkTi=WoMFYU6rDggyB+-s6F_LasUnc-N+gk9v+=C_r@mail.gmail.com","threadId":"24501","inReplyTo":"87aaohwq0r.fsf@hariville.hurrynot.org","subject":"Re: [PATCH] tests: fix syntax error in \"Use advise() for hints\" test","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-20T14:22:02Z","receivedAt":"2010-08-20T14:22:02Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Fri, Aug 20, 2010 at 10:13, Raja R Harinath <harinath@hurrynot.org> wrote:\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>> On Thu, Aug 19, 2010 at 04:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> [snip]\n>>> Although the style you chose is arguably the least ugly, nested shell\n>>> interpolation can be hard to follow.  How about this?\n>>\n>> I think '\\'' is harder to follow than \\\" and \\$, but each to his own\n>> :)\n>\n> There's also the slightly longer but somewhat prettier '\"'\"'.\n\nI must say, you guys have an odd sense of aesthetics :)\n"},{"id":"148589","messageId":"7v8w41cguu.fsf@alter.siamese.dyndns.org","threadId":"24501","inReplyTo":"AANLkTi=WoMFYU6rDggyB+-s6F_LasUnc-N+gk9v+=C_r@mail.gmail.com","subject":"Re: [PATCH] tests: fix syntax error in \"Use advise() for hints\" test","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-08-20T17:51:37Z","receivedAt":"2010-08-20T17:51:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> On Fri, Aug 20, 2010 at 10:13, Raja R Harinath <harinath@hurrynot.org> wrote:\n>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>>\n>>> On Thu, Aug 19, 2010 at 04:30, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>> [snip]\n>>>> Although the style you chose is arguably the least ugly, nested shell\n>>>> interpolation can be hard to follow.  How about this?\n>>>\n>>> I think '\\'' is harder to follow than \\\" and \\$, but each to his own\n>>> :)\n>>\n>> There's also the slightly longer but somewhat prettier '\"'\"'.\n>\n> I must say, you guys have an odd sense of aesthetics :)\n\nI'd have to agree.  If I were writing this I would probably use '\\''\nmyself but that is not because it looks good (it does not) but in my\nexperience it tends to be the least error prone.\n\nBut your original is just fine.\n"}]}