From 76e2f7ce323c7ddb3a7c29e56407da6a69a4fa53 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 7 Aug 2009 23:31:57 -0700 Subject: git stat: the beginning of "status that is not a dry-run of commit" Tentatively add "git stat" as a new command. This is not "preview of commit with the same arguments"; the path parameters are not paths to be added to the pristine index (aka "--only" option), but are taken as pathspecs to limit the output. Later in 1.7.0 release, it will take over "git status". Signed-off-by: Junio C Hamano --- builtin-commit.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 10 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 200ffdaad4..5e23ef1f0a 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -24,6 +24,7 @@ #include "string-list.h" #include "rerere.h" #include "unpack-trees.h" +#include "quote.h" static const char * const builtin_commit_usage[] = { "git commit [options] [--] ...", @@ -35,6 +36,11 @@ static const char * const builtin_status_usage[] = { NULL }; +static const char * const builtin_stat_usage[] = { + "git stat [options]", + NULL +}; + static unsigned char head_sha1[20], merge_head_sha1[20]; static char *use_message_buffer; static const char commit_editmsg[] = "COMMIT_EDITMSG"; @@ -346,6 +352,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn, struct wt_status *s) { + unsigned char sha1[20]; + if (s->relative_paths) s->prefix = prefix; @@ -357,7 +365,9 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int s->index_file = index_file; s->fp = fp; s->nowarn = nowarn; + s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0; + wt_status_collect(s); wt_status_print(s); return s->commitable; @@ -691,6 +701,21 @@ static const char *find_author_by_nickname(const char *name) die("No existing author found with '%s'", name); } + +static void handle_untracked_files_arg(struct wt_status *s) +{ + if (!untracked_files_arg) + ; /* default already initialized */ + else if (!strcmp(untracked_files_arg, "no")) + s->show_untracked_files = SHOW_NO_UNTRACKED_FILES; + else if (!strcmp(untracked_files_arg, "normal")) + s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; + else if (!strcmp(untracked_files_arg, "all")) + s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES; + else + die("Invalid untracked files mode '%s'", untracked_files_arg); +} + static int parse_and_validate_options(int argc, const char *argv[], const char * const usage[], const char *prefix, @@ -794,16 +819,7 @@ static int parse_and_validate_options(int argc, const char *argv[], else die("Invalid cleanup mode %s", cleanup_arg); - if (!untracked_files_arg) - ; /* default already initialized */ - else if (!strcmp(untracked_files_arg, "no")) - s->show_untracked_files = SHOW_NO_UNTRACKED_FILES; - else if (!strcmp(untracked_files_arg, "normal")) - s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; - else if (!strcmp(untracked_files_arg, "all")) - s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES; - else - die("Invalid untracked files mode '%s'", untracked_files_arg); + handle_untracked_files_arg(s); if (all && argc > 0) die("Paths with -a does not make sense."); @@ -886,6 +902,45 @@ static int git_status_config(const char *k, const char *v, void *cb) return git_diff_ui_config(k, v, NULL); } +int cmd_stat(int argc, const char **argv, const char *prefix) +{ + struct wt_status s; + unsigned char sha1[20]; + static struct option builtin_stat_options[] = { + OPT__VERBOSE(&verbose), + { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, + "mode", + "show untracked files, optional modes: all, normal, no. (Default: all)", + PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, + OPT_END(), + }; + + wt_status_prepare(&s); + git_config(git_status_config, &s); + argc = parse_options(argc, argv, prefix, + builtin_stat_options, + builtin_stat_usage, 0); + handle_untracked_files_arg(&s); + + if (*argv) + s.pathspec = get_pathspec(prefix, argv); + + read_cache(); + refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); + s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; + wt_status_collect(&s); + + s.verbose = verbose; + if (s.relative_paths) + s.prefix = prefix; + if (s.use_color == -1) + s.use_color = git_use_color_default; + if (diff_use_color_default == -1) + diff_use_color_default = git_use_color_default; + wt_status_print(&s); + return 0; +} + int cmd_status(int argc, const char **argv, const char *prefix) { struct wt_status s; -- cgit v1.2.1 From 173e6c8852be3c543689f8613ddf3fdafd9ca7b9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 4 Aug 2009 23:55:22 -0700 Subject: git stat -s: short status output Give -s(hort) option to "git stat" that shows the status of paths in a more concise way. XY PATH1 -> PATH2 format to be more machine readable than output from "git status", which is about previewing of "git commit" with the same arguments. PATH1 is the path in the HEAD, and " -> PATH2" part is shown only when PATH1 corresponds to a different path in the index/worktree. For unmerged entries, X shows the status of stage #2 (i.e. ours) and Y shows the status of stage #3 (i.e. theirs). For entries that do not have conflicts, X shows the status of the index, and Y shows the status of the work tree. For untracked paths, XY are "??". X Y Meaning ------------------------------------------------- [MD] not updated M [ MD] updated in index A [ MD] added to index D [ MD] deleted from index R [ MD] renamed in index C [ MD] copied in index [MARC] index and work tree matches [ MARC] M work tree changed since index [ MARC] D deleted in work tree D D unmerged, both deleted A U unmerged, added by us U D unmerged, deleted by them U A unmerged, added by them D U unmerged, deleted by us A A unmerged, both added U U unmerged, both modified ? ? untracked When given -z option, the records are terminated by NUL characters for better machine readability. Because the traditional long format is designed for human consumption, NUL termination does not make sense. For this reason, -z option implies -s (short output). Signed-off-by: Junio C Hamano --- builtin-commit.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 8 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 5e23ef1f0a..1a360cb37c 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -902,12 +902,87 @@ static int git_status_config(const char *k, const char *v, void *cb) return git_diff_ui_config(k, v, NULL); } +#define quote_path quote_path_relative + +static void short_unmerged(int null_termination, struct string_list_item *it, + struct wt_status *s) +{ + struct wt_status_change_data *d = it->util; + const char *how = "??"; + + switch (d->stagemask) { + case 1: how = "DD"; break; /* both deleted */ + case 2: how = "AU"; break; /* added by us */ + case 3: how = "UD"; break; /* deleted by them */ + case 4: how = "UA"; break; /* added by them */ + case 5: how = "DU"; break; /* deleted by us */ + case 6: how = "AA"; break; /* both added */ + case 7: how = "UU"; break; /* both modified */ + } + printf("%s ", how); + if (null_termination) { + fprintf(stdout, "%s%c", it->string, 0); + } else { + struct strbuf onebuf = STRBUF_INIT; + const char *one; + one = quote_path(it->string, -1, &onebuf, s->prefix); + printf("%s\n", one); + strbuf_release(&onebuf); + } +} + +static void short_status(int null_termination, struct string_list_item *it, + struct wt_status *s) +{ + struct wt_status_change_data *d = it->util; + + printf("%c%c ", + !d->index_status ? ' ' : d->index_status, + !d->worktree_status ? ' ' : d->worktree_status); + if (null_termination) { + fprintf(stdout, "%s%c", it->string, 0); + if (d->head_path) + fprintf(stdout, "%s%c", d->head_path, 0); + } else { + struct strbuf onebuf = STRBUF_INIT; + const char *one; + if (d->head_path) { + one = quote_path(d->head_path, -1, &onebuf, s->prefix); + printf("%s -> ", one); + strbuf_release(&onebuf); + } + one = quote_path(it->string, -1, &onebuf, s->prefix); + printf("%s\n", one); + strbuf_release(&onebuf); + } +} + +static void short_untracked(int null_termination, struct string_list_item *it, + struct wt_status *s) +{ + if (null_termination) { + fprintf(stdout, "?? %s%c", it->string, 0); + } else { + struct strbuf onebuf = STRBUF_INIT; + const char *one; + one = quote_path(it->string, -1, &onebuf, s->prefix); + printf("?? %s\n", one); + strbuf_release(&onebuf); + } +} + int cmd_stat(int argc, const char **argv, const char *prefix) { struct wt_status s; + static int null_termination, shortstatus; + int i; unsigned char sha1[20]; static struct option builtin_stat_options[] = { OPT__VERBOSE(&verbose), + OPT_BOOLEAN('s', "short", &shortstatus, + "show status concicely"), + OPT_BOOLEAN('z', "null", &null_termination, + "terminate entries with NUL"), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", @@ -915,6 +990,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix) OPT_END(), }; + if (null_termination) + shortstatus = 1; + wt_status_prepare(&s); git_config(git_status_config, &s); argc = parse_options(argc, argv, prefix, @@ -930,14 +1008,34 @@ int cmd_stat(int argc, const char **argv, const char *prefix) s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; wt_status_collect(&s); - s.verbose = verbose; - if (s.relative_paths) - s.prefix = prefix; - if (s.use_color == -1) - s.use_color = git_use_color_default; - if (diff_use_color_default == -1) - diff_use_color_default = git_use_color_default; - wt_status_print(&s); + if (shortstatus) { + for (i = 0; i < s.change.nr; i++) { + struct wt_status_change_data *d; + struct string_list_item *it; + + it = &(s.change.items[i]); + d = it->util; + if (d->stagemask) + short_unmerged(null_termination, it, &s); + else + short_status(null_termination, it, &s); + } + for (i = 0; i < s.untracked.nr; i++) { + struct string_list_item *it; + + it = &(s.untracked.items[i]); + short_untracked(null_termination, it, &s); + } + } else { + s.verbose = verbose; + if (s.relative_paths) + s.prefix = prefix; + if (s.use_color == -1) + s.use_color = git_use_color_default; + if (diff_use_color_default == -1) + diff_use_color_default = git_use_color_default; + wt_status_print(&s); + } return 0; } -- cgit v1.2.1 From 9e4b7ab652561e1807702fe5288e04b8873fc437 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Aug 2009 02:27:39 -0700 Subject: git status: not "commit --dry-run" anymore This removes tentative "git stat" and make it take over "git status". There are some tests that expect "git status" to exit with non-zero status when there is something staged. Some tests expect "git status path..." to show the status for a partial commit. For these, replace "git status" with "git commit --dry-run". For the ones that do not attempt a dry-run of a partial commit that check the output from the command, check the output from "git status" as well, as they should be identical. Signed-off-by: Junio C Hamano --- builtin-commit.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 1a360cb37c..6cb0e40484 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -36,11 +36,6 @@ static const char * const builtin_status_usage[] = { NULL }; -static const char * const builtin_stat_usage[] = { - "git stat [options]", - NULL -}; - static unsigned char head_sha1[20], merge_head_sha1[20]; static char *use_message_buffer; static const char commit_editmsg[] = "COMMIT_EDITMSG"; @@ -971,13 +966,13 @@ static void short_untracked(int null_termination, struct string_list_item *it, } } -int cmd_stat(int argc, const char **argv, const char *prefix) +int cmd_status(int argc, const char **argv, const char *prefix) { struct wt_status s; static int null_termination, shortstatus; int i; unsigned char sha1[20]; - static struct option builtin_stat_options[] = { + static struct option builtin_status_options[] = { OPT__VERBOSE(&verbose), OPT_BOOLEAN('s', "short", &shortstatus, "show status concicely"), @@ -996,8 +991,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix) wt_status_prepare(&s); git_config(git_status_config, &s); argc = parse_options(argc, argv, prefix, - builtin_stat_options, - builtin_stat_usage, 0); + builtin_status_options, + builtin_status_usage, 0); handle_untracked_files_arg(&s); if (*argv) @@ -1039,22 +1034,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix) return 0; } -int cmd_status(int argc, const char **argv, const char *prefix) -{ - struct wt_status s; - - wt_status_prepare(&s); - git_config(git_status_config, &s); - if (s.use_color == -1) - s.use_color = git_use_color_default; - if (diff_use_color_default == -1) - diff_use_color_default = git_use_color_default; - - argc = parse_and_validate_options(argc, argv, builtin_status_usage, - prefix, &s); - return dry_run_commit(argc, argv, prefix, &s); -} - static void print_summary(const char *prefix, const unsigned char *sha1) { struct rev_info rev; -- cgit v1.2.1 From 9b4fe22990dd3fab9494927935c371b072ee7c8f Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 5 Sep 2009 04:50:26 -0400 Subject: status: typo fix in usage Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 6cb0e40484..812470e63d 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -975,7 +975,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) static struct option builtin_status_options[] = { OPT__VERBOSE(&verbose), OPT_BOOLEAN('s', "short", &shortstatus, - "show status concicely"), + "show status concisely"), OPT_BOOLEAN('z', "null", &null_termination, "terminate entries with NUL"), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, -- cgit v1.2.1 From 01d8ba187d6e8a6bfa908fbef16a36d1186981dd Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 5 Sep 2009 04:53:48 -0400 Subject: status: refactor short-mode printing to its own function We want to be able to call it from multiple places. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 812470e63d..5b42179fe7 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -966,11 +966,32 @@ static void short_untracked(int null_termination, struct string_list_item *it, } } +static void short_print(struct wt_status *s, int null_termination) +{ + int i; + for (i = 0; i < s->change.nr; i++) { + struct wt_status_change_data *d; + struct string_list_item *it; + + it = &(s->change.items[i]); + d = it->util; + if (d->stagemask) + short_unmerged(null_termination, it, s); + else + short_status(null_termination, it, s); + } + for (i = 0; i < s->untracked.nr; i++) { + struct string_list_item *it; + + it = &(s->untracked.items[i]); + short_untracked(null_termination, it, s); + } +} + int cmd_status(int argc, const char **argv, const char *prefix) { struct wt_status s; static int null_termination, shortstatus; - int i; unsigned char sha1[20]; static struct option builtin_status_options[] = { OPT__VERBOSE(&verbose), @@ -1003,25 +1024,9 @@ int cmd_status(int argc, const char **argv, const char *prefix) s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; wt_status_collect(&s); - if (shortstatus) { - for (i = 0; i < s.change.nr; i++) { - struct wt_status_change_data *d; - struct string_list_item *it; - - it = &(s.change.items[i]); - d = it->util; - if (d->stagemask) - short_unmerged(null_termination, it, &s); - else - short_status(null_termination, it, &s); - } - for (i = 0; i < s.untracked.nr; i++) { - struct string_list_item *it; - - it = &(s.untracked.items[i]); - short_untracked(null_termination, it, &s); - } - } else { + if (shortstatus) + short_print(&s, null_termination); + else { s.verbose = verbose; if (s.relative_paths) s.prefix = prefix; -- cgit v1.2.1 From dd2be243d62260d4c825c22fdd2f61a7da12de22 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 5 Sep 2009 04:54:14 -0400 Subject: status: refactor format option parsing This makes it possible to have more than two formats. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 5b42179fe7..aa4a358799 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -991,12 +991,16 @@ static void short_print(struct wt_status *s, int null_termination) int cmd_status(int argc, const char **argv, const char *prefix) { struct wt_status s; - static int null_termination, shortstatus; + static int null_termination; + static enum { + STATUS_FORMAT_LONG, + STATUS_FORMAT_SHORT, + } status_format = STATUS_FORMAT_LONG; unsigned char sha1[20]; static struct option builtin_status_options[] = { OPT__VERBOSE(&verbose), - OPT_BOOLEAN('s', "short", &shortstatus, - "show status concisely"), + OPT_SET_INT('s', "short", &status_format, + "show status concisely", STATUS_FORMAT_SHORT), OPT_BOOLEAN('z', "null", &null_termination, "terminate entries with NUL"), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, @@ -1006,8 +1010,8 @@ int cmd_status(int argc, const char **argv, const char *prefix) OPT_END(), }; - if (null_termination) - shortstatus = 1; + if (null_termination && status_format == STATUS_FORMAT_LONG) + status_format = STATUS_FORMAT_SHORT; wt_status_prepare(&s); git_config(git_status_config, &s); @@ -1024,9 +1028,11 @@ int cmd_status(int argc, const char **argv, const char *prefix) s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; wt_status_collect(&s); - if (shortstatus) + switch (status_format) { + case STATUS_FORMAT_SHORT: short_print(&s, null_termination); - else { + break; + case STATUS_FORMAT_LONG: s.verbose = verbose; if (s.relative_paths) s.prefix = prefix; @@ -1035,6 +1041,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) if (diff_use_color_default == -1) diff_use_color_default = git_use_color_default; wt_status_print(&s); + break; } return 0; } -- cgit v1.2.1 From 6f15787181a163e158c6fee1d79085b97692ac2f Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 5 Sep 2009 04:55:37 -0400 Subject: status: add --porcelain output format The "short" format was added to "git status" recently to provide a less verbose way of looking at the same information. This has two practical uses: 1. Users who want a more dense display of the information. 2. Scripts which want to parse the information and need a stable, easy-to-parse interface. For now, the "--short" format covers both of those uses. However, as time goes on, users of (1) may want additional format tweaks, or for "git status" to change its behavior based on configuration variables. Those wishes will be at odds with (2), which wants to stability for scripts. This patch introduces a separate --porcelain option early to avoid problems later on. Right now the --short and --porcelain outputs are identical. However, as time goes on, we will have the freedom to customize --short for human consumption while keeping --porcelain stable. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index aa4a358799..ffdee31bbf 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -995,12 +995,16 @@ int cmd_status(int argc, const char **argv, const char *prefix) static enum { STATUS_FORMAT_LONG, STATUS_FORMAT_SHORT, + STATUS_FORMAT_PORCELAIN, } status_format = STATUS_FORMAT_LONG; unsigned char sha1[20]; static struct option builtin_status_options[] = { OPT__VERBOSE(&verbose), OPT_SET_INT('s', "short", &status_format, "show status concisely", STATUS_FORMAT_SHORT), + OPT_SET_INT(0, "porcelain", &status_format, + "show porcelain output format", + STATUS_FORMAT_PORCELAIN), OPT_BOOLEAN('z', "null", &null_termination, "terminate entries with NUL"), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, @@ -1011,7 +1015,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) }; if (null_termination && status_format == STATUS_FORMAT_LONG) - status_format = STATUS_FORMAT_SHORT; + status_format = STATUS_FORMAT_PORCELAIN; wt_status_prepare(&s); git_config(git_status_config, &s); @@ -1032,6 +1036,9 @@ int cmd_status(int argc, const char **argv, const char *prefix) case STATUS_FORMAT_SHORT: short_print(&s, null_termination); break; + case STATUS_FORMAT_PORCELAIN: + short_print(&s, null_termination); + break; case STATUS_FORMAT_LONG: s.verbose = verbose; if (s.relative_paths) -- cgit v1.2.1 From 7c9f7038e923e6eb135b27c6fca9a010b034bc27 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 5 Sep 2009 04:59:56 -0400 Subject: commit: support alternate status formats The status command recently grew "short" and "porcelain" options for alternate output formats. Since status is no longer "commit --dry-run", these formats are inaccessible to people who do want to see a dry-run in a parseable form. This patch makes those formats available to "git commit", implying the "dry-run" option when they are used. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index ffdee31bbf..f2fd0a4580 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -72,6 +72,15 @@ static int use_editor = 1, initial_commit, in_merge; static const char *only_include_assumed; static struct strbuf message; +static int null_termination; +static enum { + STATUS_FORMAT_LONG, + STATUS_FORMAT_SHORT, + STATUS_FORMAT_PORCELAIN, +} status_format = STATUS_FORMAT_LONG; + +static void short_print(struct wt_status *s, int null_termination); + static int opt_parse_m(const struct option *opt, const char *arg, int unset) { struct strbuf *buf = opt->value; @@ -105,6 +114,12 @@ static struct option builtin_commit_options[] = { OPT_BOOLEAN('o', "only", &only, "commit only specified files"), OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"), OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"), + OPT_SET_INT(0, "short", &status_format, "show status concisely", + STATUS_FORMAT_SHORT), + OPT_SET_INT(0, "porcelain", &status_format, + "show porcelain output format", STATUS_FORMAT_PORCELAIN), + OPT_BOOLEAN('z', "null", &null_termination, + "terminate entries with NUL"), OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"), @@ -363,7 +378,18 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0; wt_status_collect(s); - wt_status_print(s); + + switch (status_format) { + case STATUS_FORMAT_SHORT: + short_print(s, null_termination); + break; + case STATUS_FORMAT_PORCELAIN: + short_print(s, null_termination); + break; + case STATUS_FORMAT_LONG: + wt_status_print(s); + break; + } return s->commitable; } @@ -821,6 +847,11 @@ static int parse_and_validate_options(int argc, const char *argv[], else if (interactive && argc > 0) die("Paths with --interactive does not make sense."); + if (null_termination && status_format == STATUS_FORMAT_LONG) + status_format = STATUS_FORMAT_PORCELAIN; + if (status_format != STATUS_FORMAT_LONG) + dry_run = 1; + return argc; } @@ -991,12 +1022,6 @@ static void short_print(struct wt_status *s, int null_termination) int cmd_status(int argc, const char **argv, const char *prefix) { struct wt_status s; - static int null_termination; - static enum { - STATUS_FORMAT_LONG, - STATUS_FORMAT_SHORT, - STATUS_FORMAT_PORCELAIN, - } status_format = STATUS_FORMAT_LONG; unsigned char sha1[20]; static struct option builtin_status_options[] = { OPT__VERBOSE(&verbose), -- cgit v1.2.1 From 482a6c106132bea454bf839f458c014f84ddbd99 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Thu, 26 Nov 2009 16:24:38 +0100 Subject: status -s: respect the status.relativePaths option Otherwise, 'status' and 'status -s' in a subdir would produce different names. This change is all the more important because status.relativePaths is on by default. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin-commit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index f2fd0a4580..f49b598cbd 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -1059,6 +1059,8 @@ int cmd_status(int argc, const char **argv, const char *prefix) switch (status_format) { case STATUS_FORMAT_SHORT: + if (s.relative_paths) + s.prefix = prefix; short_print(&s, null_termination); break; case STATUS_FORMAT_PORCELAIN: -- cgit v1.2.1 From 84dbe7b867cfaaa929ed1941f930d564514ae714 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Sat, 5 Dec 2009 16:04:37 +0100 Subject: builtin-commit: refactor short-status code into wt-status.c Currently, builtin-commit.c contains most code producing the short-status output, whereas wt-status.c contains most of the code for the long format. Refactor so that most of the long and short format producing code resides in wt-status.c and is named analogously. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin-commit.c | 101 +++---------------------------------------------------- 1 file changed, 4 insertions(+), 97 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index f49b598cbd..8411236fda 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -79,8 +79,6 @@ static enum { STATUS_FORMAT_PORCELAIN, } status_format = STATUS_FORMAT_LONG; -static void short_print(struct wt_status *s, int null_termination); - static int opt_parse_m(const struct option *opt, const char *arg, int unset) { struct strbuf *buf = opt->value; @@ -381,10 +379,10 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int switch (status_format) { case STATUS_FORMAT_SHORT: - short_print(s, null_termination); + wt_shortstatus_print(s, null_termination); break; case STATUS_FORMAT_PORCELAIN: - short_print(s, null_termination); + wt_shortstatus_print(s, null_termination); break; case STATUS_FORMAT_LONG: wt_status_print(s); @@ -928,97 +926,6 @@ static int git_status_config(const char *k, const char *v, void *cb) return git_diff_ui_config(k, v, NULL); } -#define quote_path quote_path_relative - -static void short_unmerged(int null_termination, struct string_list_item *it, - struct wt_status *s) -{ - struct wt_status_change_data *d = it->util; - const char *how = "??"; - - switch (d->stagemask) { - case 1: how = "DD"; break; /* both deleted */ - case 2: how = "AU"; break; /* added by us */ - case 3: how = "UD"; break; /* deleted by them */ - case 4: how = "UA"; break; /* added by them */ - case 5: how = "DU"; break; /* deleted by us */ - case 6: how = "AA"; break; /* both added */ - case 7: how = "UU"; break; /* both modified */ - } - printf("%s ", how); - if (null_termination) { - fprintf(stdout, "%s%c", it->string, 0); - } else { - struct strbuf onebuf = STRBUF_INIT; - const char *one; - one = quote_path(it->string, -1, &onebuf, s->prefix); - printf("%s\n", one); - strbuf_release(&onebuf); - } -} - -static void short_status(int null_termination, struct string_list_item *it, - struct wt_status *s) -{ - struct wt_status_change_data *d = it->util; - - printf("%c%c ", - !d->index_status ? ' ' : d->index_status, - !d->worktree_status ? ' ' : d->worktree_status); - if (null_termination) { - fprintf(stdout, "%s%c", it->string, 0); - if (d->head_path) - fprintf(stdout, "%s%c", d->head_path, 0); - } else { - struct strbuf onebuf = STRBUF_INIT; - const char *one; - if (d->head_path) { - one = quote_path(d->head_path, -1, &onebuf, s->prefix); - printf("%s -> ", one); - strbuf_release(&onebuf); - } - one = quote_path(it->string, -1, &onebuf, s->prefix); - printf("%s\n", one); - strbuf_release(&onebuf); - } -} - -static void short_untracked(int null_termination, struct string_list_item *it, - struct wt_status *s) -{ - if (null_termination) { - fprintf(stdout, "?? %s%c", it->string, 0); - } else { - struct strbuf onebuf = STRBUF_INIT; - const char *one; - one = quote_path(it->string, -1, &onebuf, s->prefix); - printf("?? %s\n", one); - strbuf_release(&onebuf); - } -} - -static void short_print(struct wt_status *s, int null_termination) -{ - int i; - for (i = 0; i < s->change.nr; i++) { - struct wt_status_change_data *d; - struct string_list_item *it; - - it = &(s->change.items[i]); - d = it->util; - if (d->stagemask) - short_unmerged(null_termination, it, s); - else - short_status(null_termination, it, s); - } - for (i = 0; i < s->untracked.nr; i++) { - struct string_list_item *it; - - it = &(s->untracked.items[i]); - short_untracked(null_termination, it, s); - } -} - int cmd_status(int argc, const char **argv, const char *prefix) { struct wt_status s; @@ -1061,10 +968,10 @@ int cmd_status(int argc, const char **argv, const char *prefix) case STATUS_FORMAT_SHORT: if (s.relative_paths) s.prefix = prefix; - short_print(&s, null_termination); + wt_shortstatus_print(&s, null_termination); break; case STATUS_FORMAT_PORCELAIN: - short_print(&s, null_termination); + wt_shortstatus_print(&s, null_termination); break; case STATUS_FORMAT_LONG: s.verbose = verbose; -- cgit v1.2.1 From 3fe2a894e98566dd91e69982552454cfb381cf24 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Sat, 5 Dec 2009 16:04:38 +0100 Subject: status -s: obey color.status Make the short version of status obey the color.status boolean. We color the status letters only, because they carry the state information and are potentially colored differently, such as for a file with staged changes as well as changes in the worktree against the index. Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- builtin-commit.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 8411236fda..07cc76c04a 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -968,6 +968,10 @@ int cmd_status(int argc, const char **argv, const char *prefix) case STATUS_FORMAT_SHORT: if (s.relative_paths) s.prefix = prefix; + if (s.use_color == -1) + s.use_color = git_use_color_default; + if (diff_use_color_default == -1) + diff_use_color_default = git_use_color_default; wt_shortstatus_print(&s, null_termination); break; case STATUS_FORMAT_PORCELAIN: -- cgit v1.2.1 From 4a7cc2fdf39c90e6eff84d30b86490cac2c33705 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Dec 2009 00:17:15 -0500 Subject: status: disable color for porcelain format The porcelain format is identical to the shortstatus format, except that it should not respect any user configuration, including color. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 07cc76c04a..ded58984ac 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -382,7 +382,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int wt_shortstatus_print(s, null_termination); break; case STATUS_FORMAT_PORCELAIN: - wt_shortstatus_print(s, null_termination); + wt_porcelain_print(s, null_termination); break; case STATUS_FORMAT_LONG: wt_status_print(s); @@ -975,7 +975,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) wt_shortstatus_print(&s, null_termination); break; case STATUS_FORMAT_PORCELAIN: - wt_shortstatus_print(&s, null_termination); + wt_porcelain_print(&s, null_termination); break; case STATUS_FORMAT_LONG: s.verbose = verbose; -- cgit v1.2.1 From 8661768fc9cfdeeaae76693501b82940cfcbedc2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Dec 2009 00:26:25 -0500 Subject: status: reduce duplicated setup code We have three output formats: short, porcelain, and long. The short and long formats respect user-config, and the porcelain one does not. This led to us repeating config-related setup code for the short and long formats. Since the last commit, color config is explicitly cleared when showing the porcelain format. Let's do the same with relative-path configuration, which enables us to hoist the duplicated code from the switch statement in cmd_status. As a bonus, this fixes "commit --dry-run --porcelain", which was unconditionally setting up that configuration, anyway. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index ded58984ac..b39295fbf2 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -964,14 +964,15 @@ int cmd_status(int argc, const char **argv, const char *prefix) s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; wt_status_collect(&s); + if (s.relative_paths) + s.prefix = prefix; + if (s.use_color == -1) + s.use_color = git_use_color_default; + if (diff_use_color_default == -1) + diff_use_color_default = git_use_color_default; + switch (status_format) { case STATUS_FORMAT_SHORT: - if (s.relative_paths) - s.prefix = prefix; - if (s.use_color == -1) - s.use_color = git_use_color_default; - if (diff_use_color_default == -1) - diff_use_color_default = git_use_color_default; wt_shortstatus_print(&s, null_termination); break; case STATUS_FORMAT_PORCELAIN: @@ -979,12 +980,6 @@ int cmd_status(int argc, const char **argv, const char *prefix) break; case STATUS_FORMAT_LONG: s.verbose = verbose; - if (s.relative_paths) - s.prefix = prefix; - if (s.use_color == -1) - s.use_color = git_use_color_default; - if (diff_use_color_default == -1) - diff_use_color_default = git_use_color_default; wt_status_print(&s); break; } -- cgit v1.2.1 From 309883015ff3af6ce14ff9fe401e06cfce8adb13 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 11 Dec 2009 23:45:24 -0800 Subject: commit/status: check $GIT_DIR/MERGE_HEAD only once The code checked for the MERGE_HEAD file to see if we were about to commit a merge twice in the codepath; also one of them used a variable merge_head_sha1[] which was set but was never used. Just check it once, but do so also in "git status", too, as we will be using this for status generation in the next patch. Signed-off-by: Junio C Hamano --- builtin-commit.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index b39295fbf2..17dd462173 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -36,7 +36,7 @@ static const char * const builtin_status_usage[] = { NULL }; -static unsigned char head_sha1[20], merge_head_sha1[20]; +static unsigned char head_sha1[20]; static char *use_message_buffer; static const char commit_editmsg[] = "COMMIT_EDITMSG"; static struct lock_file index_lock; /* real index */ @@ -319,7 +319,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int */ commit_style = COMMIT_PARTIAL; - if (file_exists(git_path("MERGE_HEAD"))) + if (in_merge) die("cannot do a partial commit during a merge."); memset(&partial, 0, sizeof(partial)); @@ -758,9 +758,6 @@ static int parse_and_validate_options(int argc, const char *argv[], if (get_sha1("HEAD", head_sha1)) initial_commit = 1; - if (!get_sha1("MERGE_HEAD", merge_head_sha1)) - in_merge = 1; - /* Sanity check options */ if (amend && initial_commit) die("You have nothing to amend."); @@ -951,6 +948,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) wt_status_prepare(&s); git_config(git_status_config, &s); + in_merge = file_exists(git_path("MERGE_HEAD")); argc = parse_options(argc, argv, prefix, builtin_status_options, builtin_status_usage, 0); @@ -1057,10 +1055,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix) wt_status_prepare(&s); git_config(git_commit_config, &s); + in_merge = file_exists(git_path("MERGE_HEAD")); if (s.use_color == -1) s.use_color = git_use_color_default; - argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix, &s); if (dry_run) { -- cgit v1.2.1 From 3c5884536563518ce6cd4dc782b0ebb670bf3b6d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 11 Dec 2009 23:53:41 -0800 Subject: status/commit: do not suggest "reset HEAD " while merging Suggesting "'reset HEAD ' to unstage" is dead wrong if we are about to record a merge commit. For either an unmerged path (i.e. with unresolved conflicts), or an updated path, it would result in discarding what the other branch did. Note that we do not do anything special in a case where we are amending a merge. The user is making an evil merge starting from an already committed merge, and running "reset HEAD " is the right way to get rid of the local edit that has been added to the index. Once "reset --unresolve " becomes available, we might want to suggest it for a merged path that has unresolve information, but until then, just remove the incorrect advice. We might also want to suggest "checkout --conflict " to revert the file in the work tree to the state of failed automerge for an unmerged path, but we never did that, and this commit does not change that. Signed-off-by: Junio C Hamano --- builtin-commit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 17dd462173..7218454d1e 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -960,6 +960,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) read_cache(); refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; + s.in_merge = in_merge; wt_status_collect(&s); if (s.relative_paths) @@ -1056,6 +1057,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) wt_status_prepare(&s); git_config(git_commit_config, &s); in_merge = file_exists(git_path("MERGE_HEAD")); + s.in_merge = in_merge; if (s.use_color == -1) s.use_color = git_use_color_default; -- cgit v1.2.1