From d36f8679e94c2a0d4d15d6adcea434634af6d627 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 28 Aug 2008 20:54:59 -0400 Subject: pretty=format: respect date format options When running a command like: git log --pretty=format:%ad --date=short the date option was ignored. This patch causes it to use whatever format was specified by --date (or by --relative-date, etc), just as the non-user formats would do. 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 649c8beb3e..c870037b07 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -882,7 +882,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1) if (!log_tree_commit(&rev, commit)) { struct strbuf buf = STRBUF_INIT; - format_commit_message(commit, "%h: %s", &buf); + format_commit_message(commit, "%h: %s", &buf, DATE_NORMAL); printf("%s\n", buf.buf); strbuf_release(&buf); } -- cgit v1.3 From 146ea068a0434a7423d8b0d77f27ccff0a584ac4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 26 Aug 2008 23:13:13 -0700 Subject: git commit --author=$name: look $name up in existing commits This allows "git commit --author=$name" to accept a name that is not in the required "A U Thor " format, and use that to look up an author name that matches from existing commits. When using this feature, it is the user's responsibility to give a name that uniquely matches the name s/he wants, as the logic returns the name from the first matching commit. Signed-off-by: Junio C Hamano --- Documentation/git-commit.txt | 6 ++++-- builtin-commit.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'builtin-commit.c') diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 0e25bb8627..eb05b0f49b 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -75,8 +75,10 @@ OPTIONS read the message from the standard input. --author=:: - Override the author name used in the commit. Use - `A U Thor ` format. + Override the author name used in the commit. You can use the + standard `A U Thor ` format. Otherwise, + an existing commit that matches the given string and its author + name is used. -m :: --message=:: diff --git a/builtin-commit.c b/builtin-commit.c index c870037b07..4182686b90 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -710,6 +710,31 @@ static int message_is_empty(struct strbuf *sb, int start) return 1; } +static const char *find_author_by_nickname(const char *name) +{ + struct rev_info revs; + struct commit *commit; + struct strbuf buf = STRBUF_INIT; + const char *av[20]; + int ac = 0; + + init_revisions(&revs, NULL); + strbuf_addf(&buf, "--author=%s", name); + av[++ac] = "--all"; + av[++ac] = "-i"; + av[++ac] = buf.buf; + av[++ac] = NULL; + setup_revisions(ac, av, &revs, NULL); + prepare_revision_walk(&revs); + commit = get_revision(&revs); + if (commit) { + strbuf_release(&buf); + format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL); + return strbuf_detach(&buf, NULL); + } + die("No existing author found with '%s'", name); +} + static int parse_and_validate_options(int argc, const char *argv[], const char * const usage[], const char *prefix) @@ -720,6 +745,9 @@ static int parse_and_validate_options(int argc, const char *argv[], logfile = parse_options_fix_filename(prefix, logfile); template_file = parse_options_fix_filename(prefix, template_file); + if (force_author && !strchr(force_author, '>')) + force_author = find_author_by_nickname(force_author); + if (logfile || message.len || use_message) use_editor = 0; if (edit_flag) -- cgit v1.3 From 85e72830697a23dd6b1af8b6bfb3c1a7be60dfae Mon Sep 17 00:00:00 2001 From: David Soria Parra Date: Sun, 31 Aug 2008 14:09:39 +0200 Subject: cast pid_t's to uintmax_t to improve portability Some systems (like e.g. OpenSolaris) define pid_t as long, therefore all our sprintf that use %i/%d cause a compiler warning beacuse of the implicit long->int cast. To make sure that we fit the limits, we display pids as PRIuMAX and cast them explicitly to uintmax_t. Signed-off-by: David Soria Parra Signed-off-by: Junio C Hamano --- builtin-commit.c | 2 +- builtin-fetch-pack.c | 2 +- daemon.c | 6 +++--- fast-import.c | 6 +++--- receive-pack.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index c870037b07..b75d5e931d 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -320,7 +320,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix) die("unable to write new_index file"); fd = hold_lock_file_for_update(&false_lock, - git_path("next-index-%d", getpid()), 1); + git_path("next-index-%"PRIuMAX, (uintmax_t) getpid()), 1); create_base_index(); add_remove_files(&partial); diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 273239af3b..17a5a422c2 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -540,7 +540,7 @@ static int get_pack(int xd[2], char **pack_lockfile) *av++ = "--fix-thin"; if (args.lock_pack || unpack_limit) { int s = sprintf(keep_arg, - "--keep=fetch-pack %d on ", getpid()); + "--keep=fetch-pack %"PRIuMAX " on ", (uintmax_t) getpid()); if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) strcpy(keep_arg + s, "localhost"); *av++ = keep_arg; diff --git a/daemon.c b/daemon.c index 23278e28dc..c315932ced 100644 --- a/daemon.c +++ b/daemon.c @@ -86,7 +86,7 @@ static void logreport(int priority, const char *err, va_list params) * Since stderr is set to linebuffered mode, the * logging of different processes will not overlap */ - fprintf(stderr, "[%d] ", (int)getpid()); + fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid()); vfprintf(stderr, err, params); fputc('\n', stderr); } @@ -658,7 +658,7 @@ static void check_dead_children(void) remove_child(pid); if (!WIFEXITED(status) || (WEXITSTATUS(status) > 0)) dead = " (with error)"; - loginfo("[%d] Disconnected%s", (int)pid, dead); + loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead); } } @@ -923,7 +923,7 @@ static void store_pid(const char *path) FILE *f = fopen(path, "w"); if (!f) die("cannot open pid file %s: %s", path, strerror(errno)); - if (fprintf(f, "%d\n", getpid()) < 0 || fclose(f) != 0) + if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0) die("failed to write pid file %s: %s", path, strerror(errno)); } diff --git a/fast-import.c b/fast-import.c index 7089e6f9e6..acb8e2e360 100644 --- a/fast-import.c +++ b/fast-import.c @@ -376,7 +376,7 @@ static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *); static void write_crash_report(const char *err) { - char *loc = git_path("fast_import_crash_%d", getpid()); + char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid()); FILE *rpt = fopen(loc, "w"); struct branch *b; unsigned long lu; @@ -390,8 +390,8 @@ static void write_crash_report(const char *err) fprintf(stderr, "fast-import: dumping crash report to %s\n", loc); fprintf(rpt, "fast-import crash report:\n"); - fprintf(rpt, " fast-import process: %d\n", getpid()); - fprintf(rpt, " parent process : %d\n", getppid()); + fprintf(rpt, " fast-import process: %"PRIuMAX"\n", (uintmax_t) getpid()); + fprintf(rpt, " parent process : %"PRIuMAX"\n", (uintmax_t) getppid()); fprintf(rpt, " at %s\n", show_date(time(NULL), 0, DATE_LOCAL)); fputc('\n', rpt); diff --git a/receive-pack.c b/receive-pack.c index d44c19e6b5..b81678a970 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -407,7 +407,7 @@ static const char *unpack(void) char keep_arg[256]; struct child_process ip; - s = sprintf(keep_arg, "--keep=receive-pack %i on ", getpid()); + s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid()); if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) strcpy(keep_arg + s, "localhost"); -- cgit v1.3 From e502f9e7e6ceb8dfbdb94e2675355847740fc28f Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 8 Sep 2008 01:05:41 +0200 Subject: builtin-commit.c: show on which branch a commit was added This outputs the current branch on which a commit was created, just for reference. For example: Created commit 6d42875 on master: Fix submodule invalid command error This also reminds the committer when he is on a detached HEAD: Created commit 02a7172 on detached HEAD: Also do this for 'git commit --amend' Signed-off-by: Pieter de Bie Signed-off-by: Junio C Hamano --- builtin-commit.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 8165bb3d31..f7b90604aa 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -878,10 +878,37 @@ int cmd_status(int argc, const char **argv, const char *prefix) return commitable ? 0 : 1; } +static char *get_commit_format_string(void) +{ + unsigned char sha[20]; + const char *head = resolve_ref("HEAD", sha, 0, NULL); + struct strbuf buf = STRBUF_INIT; + + strbuf_addstr(&buf, "format:%h"); + + /* Are we on a detached HEAD? */ + if (!strcmp("HEAD", head)) + strbuf_addstr(&buf, " on detached HEAD"); + else if (!prefixcmp(head, "refs/heads/")) { + const char *cp; + strbuf_addstr(&buf, " on "); + for (cp = head + 11; *cp; cp++) { + if (*cp == '%') + strbuf_addstr(&buf, "%x25"); + else + strbuf_addch(&buf, *cp); + } + } + strbuf_addstr(&buf, ": %s"); + + return strbuf_detach(&buf, NULL); +} + static void print_summary(const char *prefix, const unsigned char *sha1) { struct rev_info rev; struct commit *commit; + char *format = get_commit_format_string(); commit = lookup_commit(sha1); if (!commit) @@ -899,7 +926,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1) rev.verbose_header = 1; rev.show_root_diff = 1; - get_commit_format("format:%h: %s", &rev); + get_commit_format(format, &rev); rev.always_show_header = 0; rev.diffopt.detect_rename = 1; rev.diffopt.rename_limit = 100; @@ -910,10 +937,11 @@ static void print_summary(const char *prefix, const unsigned char *sha1) if (!log_tree_commit(&rev, commit)) { struct strbuf buf = STRBUF_INIT; - format_commit_message(commit, "%h: %s", &buf, DATE_NORMAL); + format_commit_message(commit, format + 7, &buf, DATE_NORMAL); printf("%s\n", buf.buf); strbuf_release(&buf); } + free(format); } static int git_commit_config(const char *k, const char *v, void *cb) -- cgit v1.3 From 6bb6b0341af26739ba305b20c62a433f15029049 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 10 Sep 2008 22:10:32 +0200 Subject: builtin-commit: use commit_tree() First, it adds less code than removes, second this allows us to use recuce_heads() for parents, so that the parents of a merge will be always the same with or without a conflict. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- builtin-commit.c | 67 ++++++++++++++------------------------------------------ 1 file changed, 16 insertions(+), 51 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 8165bb3d31..55e1087d27 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -667,14 +667,14 @@ static int prepare_to_commit(const char *index_file, const char *prefix) } /* - * Find out if the message starting at position 'start' in the strbuf - * contains only whitespace and Signed-off-by lines. + * Find out if the message in the strbuf contains only whitespace and + * Signed-off-by lines. */ -static int message_is_empty(struct strbuf *sb, int start) +static int message_is_empty(struct strbuf *sb) { struct strbuf tmpl; const char *nl; - int eol, i; + int eol, i, start = 0; if (cleanup_mode == CLEANUP_NONE && sb->len) return 0; @@ -929,34 +929,14 @@ static const char commit_utf8_warn[] = "You may want to amend it after fixing the message, or set the config\n" "variable i18n.commitencoding to the encoding your project uses.\n"; -static void add_parent(struct strbuf *sb, const unsigned char *sha1) -{ - struct object *obj = parse_object(sha1); - const char *parent = sha1_to_hex(sha1); - const char *cp; - - if (!obj) - die("Unable to find commit parent %s", parent); - if (obj->type != OBJ_COMMIT) - die("Parent %s isn't a proper commit", parent); - - for (cp = sb->buf; cp && (cp = strstr(cp, "\nparent ")); cp += 8) { - if (!memcmp(cp + 8, parent, 40) && cp[48] == '\n') { - error("duplicate parent %s ignored", parent); - return; - } - } - strbuf_addf(sb, "parent %s\n", parent); -} - int cmd_commit(int argc, const char **argv, const char *prefix) { - int header_len; struct strbuf sb; const char *index_file, *reflog_msg; char *nl, *p; unsigned char commit_sha1[20]; struct ref_lock *ref_lock; + struct commit_list *parents = NULL, **pptr = &parents; git_config(git_commit_config, NULL); @@ -971,13 +951,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix) return 1; } - /* - * The commit object - */ - strbuf_init(&sb, 0); - strbuf_addf(&sb, "tree %s\n", - sha1_to_hex(active_cache_tree->sha1)); - /* Determine parents */ if (initial_commit) { reflog_msg = "commit (initial)"; @@ -991,13 +964,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix) die("could not parse HEAD commit"); for (c = commit->parents; c; c = c->next) - add_parent(&sb, c->item->object.sha1); + pptr = &commit_list_insert(c->item, pptr)->next; } else if (in_merge) { struct strbuf m; FILE *fp; reflog_msg = "commit (merge)"; - add_parent(&sb, head_sha1); + pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; strbuf_init(&m, 0); fp = fopen(git_path("MERGE_HEAD"), "r"); if (fp == NULL) @@ -1007,24 +980,18 @@ int cmd_commit(int argc, const char **argv, const char *prefix) unsigned char sha1[20]; if (get_sha1_hex(m.buf, sha1) < 0) die("Corrupt MERGE_HEAD file (%s)", m.buf); - add_parent(&sb, sha1); + pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next; } fclose(fp); strbuf_release(&m); } else { reflog_msg = "commit"; - strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1)); + pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; } - - strbuf_addf(&sb, "author %s\n", - fmt_ident(author_name, author_email, author_date, IDENT_ERROR_ON_NO_NAME)); - strbuf_addf(&sb, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); - if (!is_encoding_utf8(git_commit_encoding)) - strbuf_addf(&sb, "encoding %s\n", git_commit_encoding); - strbuf_addch(&sb, '\n'); + parents = reduce_heads(parents); /* Finally, get the commit message */ - header_len = sb.len; + strbuf_init(&sb, 0); if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) { rollback_index_files(); die("could not read commit message"); @@ -1037,16 +1004,15 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (cleanup_mode != CLEANUP_NONE) stripspace(&sb, cleanup_mode == CLEANUP_ALL); - if (sb.len < header_len || message_is_empty(&sb, header_len)) { + if (message_is_empty(&sb)) { rollback_index_files(); fprintf(stderr, "Aborting commit due to empty commit message.\n"); exit(1); } - strbuf_addch(&sb, '\0'); - if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf)) - fprintf(stderr, commit_utf8_warn); - if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1)) { + if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1, + fmt_ident(author_name, author_email, author_date, + IDENT_ERROR_ON_NO_NAME))) { rollback_index_files(); die("failed to write commit object"); } @@ -1055,12 +1021,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) initial_commit ? NULL : head_sha1, 0); - nl = strchr(sb.buf + header_len, '\n'); + nl = strchr(sb.buf, '\n'); if (nl) strbuf_setlen(&sb, nl + 1 - sb.buf); else strbuf_addch(&sb, '\n'); - strbuf_remove(&sb, 0, header_len); strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg)); strbuf_insert(&sb, strlen(reflog_msg), ": ", 2); -- cgit v1.3 From cbce6c0be30cbaf8c39051f85006d679338a8ddc Mon Sep 17 00:00:00 2001 From: Rafael Garcia-Suarez Date: Mon, 29 Sep 2008 18:04:41 +0200 Subject: Clarify commit error message for unmerged files Currently, trying to use git-commit with unmerged files in the index will show the message "Error building trees", which can be a bit obscure to the end user. This patch makes the error message clearer, and consistent with what git-write-tree reports in a similar situation. Signed-off-by: Rafael Garcia-Suarez Signed-off-by: Shawn O. Pearce --- 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 c870037b07..e2a7e48b1c 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix) active_cache_tree = cache_tree(); if (cache_tree_update(active_cache_tree, active_cache, active_nr, 0, 0) < 0) { - error("Error building trees"); + error("Error building trees; the index is unmerged?"); return 0; } -- cgit v1.3 From 72c69ebc035efe08aef03866184aa9b344814d93 Mon Sep 17 00:00:00 2001 From: Andreas Ericsson Date: Tue, 30 Sep 2008 11:52:50 +0200 Subject: git commit: Reformat output somewhat Previously, we used to print something along the lines of Created commit abc9056 on master: Snib the sprock but that output was sometimes confusing, as many projects use the "subsystem: message" style of commit subjects (just like this commit message does). When such improvements are done on topic-branches, it's not uncommon to name the topic-branch the same as the subsystem, leading to output like this: Created commit abc9056 on i386: i386: Snib the sprock which doesn't look very nice and can be highly confusing. This patch alters the format so that the noise-word "commit" is dropped except when it makes the output read better and the commit subject is put inside parentheses. We also emphasize the detached case so that users do not overlook it in case the commit subject is long enough to extend to the next line. The end result looks thusly: normal case Created abc9056 (i386: Snib the sprock) on i386 detached head Created DETACHED commit abc9056 (i386: Snib the sprock) While we're at it, we rename "initial commit" to "root-commit" to align it with the argument to 'git log', producing this: initial commit Created root-commit abc9056 (i386: Snib the sprock) on i386 Documentation/gittutorial-2.txt is updated accordingly so that new users recognize what they're looking at. Signed-off-by: Andreas Ericsson Signed-off-by: Shawn O. Pearce --- Documentation/gittutorial-2.txt | 13 ++++++++----- builtin-commit.c | 12 +++++------- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'builtin-commit.c') diff --git a/Documentation/gittutorial-2.txt b/Documentation/gittutorial-2.txt index 660904686c..8484e7a026 100644 --- a/Documentation/gittutorial-2.txt +++ b/Documentation/gittutorial-2.txt @@ -32,22 +32,25 @@ Initialized empty Git repository in .git/ $ echo 'hello world' > file.txt $ git add . $ git commit -a -m "initial commit" -Created initial commit 54196cc2703dc165cbd373a65a4dcf22d50ae7f7 +Created root-commit 54196cc (initial commit) on master create mode 100644 file.txt $ echo 'hello world!' >file.txt $ git commit -a -m "add emphasis" -Created commit c4d59f390b9cfd4318117afde11d601c1085f241 +Created c4d59f3 (add emphasis) on master ------------------------------------------------ -What are the 40 digits of hex that git responded to the commit with? +What are the 7 digits of hex that git responded to the commit with? We saw in part one of the tutorial that commits have names like this. It turns out that every object in the git history is stored under -such a 40-digit hex name. That name is the SHA1 hash of the object's +a 40-digit hex name. That name is the SHA1 hash of the object's contents; among other things, this ensures that git will never store the same data twice (since identical data is given an identical SHA1 name), and that the contents of a git object will never change (since -that would change the object's name as well). +that would change the object's name as well). The 7 char hex strings +here are simply the abbreviation of such 40 character long strings. +Abbreviations can be used everywhere where the 40 character strings +can be used, so long as they are unambiguous. It is expected that the content of the commit object you created while following the example above generates a different SHA1 hash than diff --git a/builtin-commit.c b/builtin-commit.c index f7b90604aa..4f0745fa0e 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -884,12 +884,11 @@ static char *get_commit_format_string(void) const char *head = resolve_ref("HEAD", sha, 0, NULL); struct strbuf buf = STRBUF_INIT; - strbuf_addstr(&buf, "format:%h"); + /* use shouty-caps if we're on detached HEAD */ + strbuf_addf(&buf, "format:%s", strcmp("HEAD", head) ? "" : "DETACHED commit"); + strbuf_addstr(&buf, "%h (%s)"); - /* Are we on a detached HEAD? */ - if (!strcmp("HEAD", head)) - strbuf_addstr(&buf, " on detached HEAD"); - else if (!prefixcmp(head, "refs/heads/")) { + if (!prefixcmp(head, "refs/heads/")) { const char *cp; strbuf_addstr(&buf, " on "); for (cp = head + 11; *cp; cp++) { @@ -899,7 +898,6 @@ static char *get_commit_format_string(void) strbuf_addch(&buf, *cp); } } - strbuf_addstr(&buf, ": %s"); return strbuf_detach(&buf, NULL); } @@ -933,7 +931,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1) rev.diffopt.break_opt = 0; diff_setup_done(&rev.diffopt); - printf("Created %scommit ", initial_commit ? "initial " : ""); + printf("Created %s", initial_commit ? "root-commit " : ""); if (!log_tree_commit(&rev, commit)) { struct strbuf buf = STRBUF_INIT; -- cgit v1.3 From c85db254d9d3309bb330444385dbb3b7be5100d3 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 1 Oct 2008 18:31:25 -0400 Subject: reformat informational commit message When committing, we print a message like: Created [DETACHED commit] () on The most useful bit of information there (besides the detached status, if it is present) is which branch you made the commit on. However, it is sometimes hard to see because the subject dominates the line. Instead, let's put the most useful information (detached status and commit branch) on the far left, with the subject (which is least likely to be interesting) on the far right. We'll use brackets to offset the branch name so the line is not mistaken for an error line of the form "program: some sort of error". E.g.,: [jk/bikeshed] created bd8098f: "reformat informational commit message" Signed-off-by: Jeff King Signed-off-by: Shawn O. Pearce --- builtin-commit.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 4f0745fa0e..f2e32a830e 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -878,35 +878,13 @@ int cmd_status(int argc, const char **argv, const char *prefix) return commitable ? 0 : 1; } -static char *get_commit_format_string(void) -{ - unsigned char sha[20]; - const char *head = resolve_ref("HEAD", sha, 0, NULL); - struct strbuf buf = STRBUF_INIT; - - /* use shouty-caps if we're on detached HEAD */ - strbuf_addf(&buf, "format:%s", strcmp("HEAD", head) ? "" : "DETACHED commit"); - strbuf_addstr(&buf, "%h (%s)"); - - if (!prefixcmp(head, "refs/heads/")) { - const char *cp; - strbuf_addstr(&buf, " on "); - for (cp = head + 11; *cp; cp++) { - if (*cp == '%') - strbuf_addstr(&buf, "%x25"); - else - strbuf_addch(&buf, *cp); - } - } - - return strbuf_detach(&buf, NULL); -} - static void print_summary(const char *prefix, const unsigned char *sha1) { struct rev_info rev; struct commit *commit; - char *format = get_commit_format_string(); + static const char *format = "format:%h: \"%s\""; + unsigned char junk_sha1[20]; + const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL); commit = lookup_commit(sha1); if (!commit) @@ -931,7 +909,13 @@ static void print_summary(const char *prefix, const unsigned char *sha1) rev.diffopt.break_opt = 0; diff_setup_done(&rev.diffopt); - printf("Created %s", initial_commit ? "root-commit " : ""); + printf("[%s%s]: created ", + !prefixcmp(head, "refs/heads/") ? + head + 11 : + !strcmp(head, "HEAD") ? + "detached HEAD" : + head, + initial_commit ? " (root-commit)" : ""); if (!log_tree_commit(&rev, commit)) { struct strbuf buf = STRBUF_INIT; @@ -939,7 +923,6 @@ static void print_summary(const char *prefix, const unsigned char *sha1) printf("%s\n", buf.buf); strbuf_release(&buf); } - free(format); } static int git_commit_config(const char *k, const char *v, void *cb) -- cgit v1.3 From cf10f9fdd5e673a163847f0e931ce9731507e03b Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 3 Oct 2008 14:04:47 +0200 Subject: builtin-commit: use reduce_heads() only when appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 6bb6b034 (builtin-commit: use commit_tree(), 2008-09-10), builtin-commit performs a reduce_heads() unconditionally. However, it's not always needed, and in some cases even harmful. reduce_heads() is not needed for the initial commit or for an "ordinary" commit, because they don't have any or have only one parent, respectively. reduce_heads() must be avoided when 'git commit' is run after a 'git merge --no-ff --no-commit', otherwise it will turn the non-fast-forward merge into fast-forward. For the same reason, reduce_heads() must be avoided when amending such a merge commit. To resolve this issue, 'git merge' will write info about whether fast-forward is allowed or not to $GIT_DIR/MERGE_MODE. Based on this info, 'git commit' will only perform reduce_heads() when it's committing a merge and fast-forward is enabled. Also add test cases to ensure that non-fast-forward merges are committed and amended properly. Signed-off-by: Miklos Vajna Signed-off-by: SZEDER Gábor Signed-off-by: Shawn O. Pearce --- branch.c | 1 + builtin-commit.c | 16 ++++++++++++++-- builtin-merge.c | 10 ++++++++++ t/t7600-merge.sh | 16 ++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) (limited to 'builtin-commit.c') diff --git a/branch.c b/branch.c index b1e59f2196..205b89dc69 100644 --- a/branch.c +++ b/branch.c @@ -168,5 +168,6 @@ void remove_branch_state(void) unlink(git_path("MERGE_HEAD")); unlink(git_path("MERGE_RR")); unlink(git_path("MERGE_MSG")); + unlink(git_path("MERGE_MODE")); unlink(git_path("SQUASH_MSG")); } diff --git a/builtin-commit.c b/builtin-commit.c index b920257524..93f360f768 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -937,6 +937,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) unsigned char commit_sha1[20]; struct ref_lock *ref_lock; struct commit_list *parents = NULL, **pptr = &parents; + struct stat statbuf; + int allow_fast_forward = 1; git_config(git_commit_config, NULL); @@ -951,6 +953,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) return 1; } + strbuf_init(&sb, 0); /* Determine parents */ if (initial_commit) { reflog_msg = "commit (initial)"; @@ -984,14 +987,22 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } fclose(fp); strbuf_release(&m); + if (!stat(git_path("MERGE_MODE"), &statbuf)) { + if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0) + die("could not read MERGE_MODE: %s", + strerror(errno)); + if (!strcmp(sb.buf, "no-ff")) + allow_fast_forward = 0; + } + if (allow_fast_forward) + parents = reduce_heads(parents); } else { reflog_msg = "commit"; pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; } - parents = reduce_heads(parents); /* Finally, get the commit message */ - strbuf_init(&sb, 0); + strbuf_reset(&sb); if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) { rollback_index_files(); die("could not read commit message"); @@ -1040,6 +1051,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) unlink(git_path("MERGE_HEAD")); unlink(git_path("MERGE_MSG")); + unlink(git_path("MERGE_MODE")); unlink(git_path("SQUASH_MSG")); if (commit_index_files()) diff --git a/builtin-merge.c b/builtin-merge.c index 5c65a58699..4c9ed5da09 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -180,6 +180,7 @@ static void drop_save(void) { unlink(git_path("MERGE_HEAD")); unlink(git_path("MERGE_MSG")); + unlink(git_path("MERGE_MODE")); } static void save_state(void) @@ -1210,6 +1211,15 @@ int cmd_merge(int argc, const char **argv, const char *prefix) merge_msg.len) die("Could not write to %s", git_path("MERGE_MSG")); close(fd); + fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) + die("Could open %s for writing", git_path("MERGE_MODE")); + strbuf_reset(&buf); + if (!allow_fast_forward) + strbuf_addf(&buf, "no-ff"); + if (write_in_full(fd, buf.buf, buf.len) != buf.len) + die("Could not write to %s", git_path("MERGE_MODE")); + close(fd); } if (merge_was_ok) { diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 9516f541e9..209d7cd4b8 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -511,4 +511,20 @@ test_expect_success 'in-index merge' ' test_debug 'gitk --all' +test_expect_success 'merge --no-ff --no-commit && commit' ' + git reset --hard c0 && + git merge --no-ff --no-commit c1 && + EDITOR=: git commit && + verify_parents $c0 $c1 +' + +test_debug 'gitk --all' + +test_expect_success 'amending no-ff merge commit' ' + EDITOR=: git commit --amend && + verify_parents $c0 $c1 +' + +test_debug 'gitk --all' + test_done -- cgit v1.3 From f285a2d7ed6548666989406de8f0e7233eb84368 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Thu, 9 Oct 2008 14:12:12 -0500 Subject: Replace calls to strbuf_init(&foo, 0) with STRBUF_INIT initializer Many call sites use strbuf_init(&foo, 0) to initialize local strbuf variable "foo" which has not been accessed since its declaration. These can be replaced with a static initialization using the STRBUF_INIT macro which is just as readable, saves a function call, and takes up fewer lines. Signed-off-by: Brandon Casey Signed-off-by: Shawn O. Pearce --- archive-tar.c | 6 ++---- archive.c | 6 ++---- builtin-apply.c | 26 ++++++++------------------ builtin-blame.c | 3 +-- builtin-branch.c | 3 +-- builtin-cat-file.c | 3 +-- builtin-checkout-index.c | 4 +--- builtin-checkout.c | 12 ++++-------- builtin-clean.c | 6 ++---- builtin-clone.c | 9 +++------ builtin-commit.c | 15 +++++---------- builtin-fetch--tool.c | 3 +-- builtin-fmt-merge-msg.c | 4 +--- builtin-help.c | 4 +--- builtin-log.c | 13 ++++--------- builtin-merge.c | 27 +++++++++------------------ builtin-remote.c | 8 ++------ builtin-rev-list.c | 3 +-- builtin-rev-parse.c | 4 +--- builtin-show-branch.c | 3 +-- builtin-stripspace.c | 3 +-- builtin-tag.c | 3 +-- builtin-update-index.c | 10 +++------- combine-diff.c | 3 +-- config.c | 6 ++---- convert.c | 3 +-- diff.c | 15 +++++---------- editor.c | 3 +-- exec_cmd.c | 4 +--- fsck.c | 3 +-- git.c | 3 +-- graph.c | 13 ++++--------- hash-object.c | 4 +--- imap-send.c | 3 +-- log-tree.c | 3 +-- merge-recursive.c | 3 +-- mktag.c | 3 +-- mktree.c | 6 ++---- pretty.c | 3 +-- read-cache.c | 3 +-- remote.c | 3 +-- rerere.c | 4 +--- sha1_file.c | 6 ++---- walker.c | 3 +-- ws.c | 3 +-- wt-status.c | 10 +++------- 46 files changed, 91 insertions(+), 197 deletions(-) (limited to 'builtin-commit.c') diff --git a/archive-tar.c b/archive-tar.c index 13029619e5..ba890ebdec 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -124,11 +124,10 @@ static int write_tar_entry(struct archiver_args *args, unsigned int mode, void *buffer, unsigned long size) { struct ustar_header header; - struct strbuf ext_header; + struct strbuf ext_header = STRBUF_INIT; int err = 0; memset(&header, 0, sizeof(header)); - strbuf_init(&ext_header, 0); if (!sha1) { *header.typeflag = TYPEFLAG_GLOBAL_HEADER; @@ -211,10 +210,9 @@ static int write_tar_entry(struct archiver_args *args, static int write_global_extended_header(struct archiver_args *args) { const unsigned char *sha1 = args->commit_sha1; - struct strbuf ext_header; + struct strbuf ext_header = STRBUF_INIT; int err; - strbuf_init(&ext_header, 0); strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40); err = write_tar_entry(args, NULL, NULL, 0, 0, ext_header.buf, ext_header.len); diff --git a/archive.c b/archive.c index 44ab008039..849eed553e 100644 --- a/archive.c +++ b/archive.c @@ -29,11 +29,10 @@ static void format_subst(const struct commit *commit, struct strbuf *buf) { char *to_free = NULL; - struct strbuf fmt; + struct strbuf fmt = STRBUF_INIT; if (src == buf->buf) to_free = strbuf_detach(buf, NULL); - strbuf_init(&fmt, 0); for (;;) { const char *b, *c; @@ -65,10 +64,9 @@ static void *sha1_file_to_archive(const char *path, const unsigned char *sha1, buffer = read_sha1_file(sha1, type, sizep); if (buffer && S_ISREG(mode)) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; size_t size = 0; - strbuf_init(&buf, 0); strbuf_attach(&buf, buffer, *sizep, *sizep + 1); convert_to_working_tree(path, buf.buf, buf.len, &buf); if (commit) diff --git a/builtin-apply.c b/builtin-apply.c index bf80610506..f1f675819f 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -321,13 +321,12 @@ static char *find_name(const char *line, char *def, int p_value, int terminate) const char *start = line; if (*line == '"') { - struct strbuf name; + struct strbuf name = STRBUF_INIT; /* * Proposed "new-style" GNU patch/diff format; see * http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 */ - strbuf_init(&name, 0); if (!unquote_c_style(&name, line, NULL)) { char *cp; @@ -675,11 +674,8 @@ static char *git_header_name(char *line, int llen) if (*line == '"') { const char *cp; - struct strbuf first; - struct strbuf sp; - - strbuf_init(&first, 0); - strbuf_init(&sp, 0); + struct strbuf first = STRBUF_INIT; + struct strbuf sp = STRBUF_INIT; if (unquote_c_style(&first, line, &second)) goto free_and_fail1; @@ -741,10 +737,9 @@ static char *git_header_name(char *line, int llen) */ for (second = name; second < line + llen; second++) { if (*second == '"') { - struct strbuf sp; + struct strbuf sp = STRBUF_INIT; const char *np; - strbuf_init(&sp, 0); if (unquote_c_style(&sp, second, NULL)) goto free_and_fail2; @@ -1508,11 +1503,10 @@ static const char minuses[]= static void show_stats(struct patch *patch) { - struct strbuf qname; + struct strbuf qname = STRBUF_INIT; char *cp = patch->new_name ? patch->new_name : patch->old_name; int max, add, del; - strbuf_init(&qname, 0); quote_c_style(cp, &qname, NULL, 0); /* @@ -2292,14 +2286,12 @@ static void add_to_fn_table(struct patch *patch) static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; struct image image; size_t len; char *img; struct patch *tpatch; - strbuf_init(&buf, 0); - if (!(patch->is_copy || patch->is_rename) && ((tpatch = in_fn_table(patch->old_name)) != NULL)) { if (tpatch == (struct patch *) -1) { @@ -2779,7 +2771,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size) { int fd; - struct strbuf nbuf; + struct strbuf nbuf = STRBUF_INIT; if (S_ISGITLINK(mode)) { struct stat st; @@ -2798,7 +2790,6 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf, if (fd < 0) return -1; - strbuf_init(&nbuf, 0); if (convert_to_working_tree(path, buf, size, &nbuf)) { size = nbuf.len; buf = nbuf.buf; @@ -3060,13 +3051,12 @@ static void prefix_patches(struct patch *p) static int apply_patch(int fd, const char *filename, int options) { size_t offset; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; struct patch *list = NULL, **listp = &list; int skipped_patch = 0; /* FIXME - memory leak when using multiple patch files as inputs */ memset(&fn_table, 0, sizeof(struct string_list)); - strbuf_init(&buf, 0); patch_input_file = filename; read_patch_file(&buf, fd); offset = 0; diff --git a/builtin-blame.c b/builtin-blame.c index df537593d0..48cc0c175d 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -2062,7 +2062,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con struct commit *commit; struct origin *origin; unsigned char head_sha1[20]; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; const char *ident; time_t now; int size, len; @@ -2082,7 +2082,6 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con origin = make_origin(commit, path); - strbuf_init(&buf, 0); if (!contents_from || strcmp("-", contents_from)) { struct stat st; const char *read_from; diff --git a/builtin-branch.c b/builtin-branch.c index b1a2ad7a6b..8d634ff571 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -334,11 +334,10 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, } if (verbose) { - struct strbuf subject; + struct strbuf subject = STRBUF_INIT; const char *sub = " **** invalid ref ****"; char stat[128]; - strbuf_init(&subject, 0); stat[0] = '\0'; commit = item->commit; diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 3fba6b9e74..30d00a6664 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -189,9 +189,8 @@ static int batch_one_object(const char *obj_name, int print_contents) static int batch_objects(int print_contents) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; - strbuf_init(&buf, 0); while (strbuf_getline(&buf, stdin, '\n') != EOF) { int error = batch_one_object(buf.buf, print_contents); if (error) diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c index 55b7aafe06..4ba27024c5 100644 --- a/builtin-checkout-index.c +++ b/builtin-checkout-index.c @@ -268,13 +268,11 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) } if (read_from_stdin) { - struct strbuf buf, nbuf; + struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; if (all) die("git checkout-index: don't mix '--all' and '--stdin'"); - strbuf_init(&buf, 0); - strbuf_init(&nbuf, 0); while (strbuf_getline(&buf, stdin, line_termination) != EOF) { const char *p; if (line_termination && buf.buf[0] == '"') { diff --git a/builtin-checkout.c b/builtin-checkout.c index 3762f71aae..ad04a184a2 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -310,8 +310,7 @@ static void show_local_changes(struct object *head) static void describe_detached_head(char *msg, struct commit *commit) { - struct strbuf sb; - strbuf_init(&sb, 0); + struct strbuf sb = STRBUF_INIT; parse_commit(commit); pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0); fprintf(stderr, "%s %s... %s\n", msg, @@ -360,8 +359,7 @@ struct branch_info { static void setup_branch_path(struct branch_info *branch) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; strbuf_addstr(&buf, "refs/heads/"); strbuf_addstr(&buf, branch->name); branch->path = strbuf_detach(&buf, NULL); @@ -484,7 +482,7 @@ static void update_refs_for_switch(struct checkout_opts *opts, struct branch_info *old, struct branch_info *new) { - struct strbuf msg; + struct strbuf msg = STRBUF_INIT; const char *old_desc; if (opts->new_branch) { create_branch(old->name, opts->new_branch, new->name, 0, @@ -493,7 +491,6 @@ static void update_refs_for_switch(struct checkout_opts *opts, setup_branch_path(new); } - strbuf_init(&msg, 0); old_desc = old->name; if (!old_desc) old_desc = sha1_to_hex(old->commit->object.sha1); @@ -738,8 +735,7 @@ no_reference: } if (opts.new_branch) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; strbuf_addstr(&buf, "refs/heads/"); strbuf_addstr(&buf, opts.new_branch); if (!get_sha1(buf.buf, rev)) diff --git a/builtin-clean.c b/builtin-clean.c index 48bf29f40a..f78c2fb108 100644 --- a/builtin-clean.c +++ b/builtin-clean.c @@ -31,11 +31,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix) int i; int show_only = 0, remove_directories = 0, quiet = 0, ignored = 0; int ignored_only = 0, baselen = 0, config_set = 0, errors = 0; - struct strbuf directory; + struct strbuf directory = STRBUF_INIT; struct dir_struct dir; const char *path, *base; static const char **pathspec; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; const char *qname; char *seen = NULL; struct option options[] = { @@ -58,7 +58,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, options, builtin_clean_usage, 0); - strbuf_init(&buf, 0); memset(&dir, 0, sizeof(dir)); if (ignored_only) dir.show_ignored = 1; @@ -88,7 +87,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (baselen) path = base = xmemdupz(*pathspec, baselen); read_directory(&dir, path, base, baselen, pathspec); - strbuf_init(&directory, 0); if (pathspec) seen = xmalloc(argc > 0 ? argc : 1); diff --git a/builtin-clone.c b/builtin-clone.c index 49d2eb9c2b..1ddc14b9c7 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -264,10 +264,9 @@ pid_t junk_pid; static void remove_junk(void) { - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; if (getpid() != junk_pid) return; - strbuf_init(&sb, 0); if (junk_git_dir) { strbuf_addstr(&sb, junk_git_dir); remove_dir_recursively(&sb, 0); @@ -354,7 +353,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) char *path, *dir; const struct ref *refs, *head_points_at, *remote_head, *mapped_refs; char branch_top[256], key[256], value[256]; - struct strbuf reflog_msg; + struct strbuf reflog_msg = STRBUF_INIT; struct transport *transport = NULL; char *src_ref_prefix = "refs/heads/"; @@ -404,7 +403,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (!stat(dir, &buf)) die("destination directory '%s' already exists.", dir); - strbuf_init(&reflog_msg, 0); strbuf_addf(&reflog_msg, "clone: from %s", repo); if (option_bare) @@ -526,7 +524,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) create_symref("HEAD", head_points_at->name, NULL); if (!option_bare) { - struct strbuf head_ref; + struct strbuf head_ref = STRBUF_INIT; const char *head = head_points_at->name; if (!prefixcmp(head, "refs/heads/")) @@ -539,7 +537,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) head_points_at->old_sha1, NULL, 0, DIE_ON_ERR); - strbuf_init(&head_ref, 0); strbuf_addstr(&head_ref, branch_top); strbuf_addstr(&head_ref, "HEAD"); diff --git a/builtin-commit.c b/builtin-commit.c index b920257524..a2755dc3be 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -448,7 +448,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix) { struct stat statbuf; int commitable, saved_color_setting; - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; char *buffer; FILE *fp; const char *hook_arg1 = NULL; @@ -458,7 +458,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix) if (!no_verify && run_hook(index_file, "pre-commit", NULL)) return 0; - strbuf_init(&sb, 0); if (message.len) { strbuf_addbuf(&sb, &message); hook_arg1 = "message"; @@ -511,10 +510,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix) stripspace(&sb, 0); if (signoff) { - struct strbuf sob; + struct strbuf sob = STRBUF_INIT; int i; - strbuf_init(&sob, 0); strbuf_addstr(&sob, sign_off_header); strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"))); @@ -672,7 +670,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix) */ static int message_is_empty(struct strbuf *sb) { - struct strbuf tmpl; + struct strbuf tmpl = STRBUF_INIT; const char *nl; int eol, i, start = 0; @@ -680,7 +678,6 @@ static int message_is_empty(struct strbuf *sb) return 0; /* See if the template is just a prefix of the message. */ - strbuf_init(&tmpl, 0); if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) { stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); if (start + tmpl.len <= sb->len && @@ -931,7 +928,7 @@ static const char commit_utf8_warn[] = int cmd_commit(int argc, const char **argv, const char *prefix) { - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; const char *index_file, *reflog_msg; char *nl, *p; unsigned char commit_sha1[20]; @@ -966,12 +963,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) for (c = commit->parents; c; c = c->next) pptr = &commit_list_insert(c->item, pptr)->next; } else if (in_merge) { - struct strbuf m; + struct strbuf m = STRBUF_INIT; FILE *fp; reflog_msg = "commit (merge)"; pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; - strbuf_init(&m, 0); fp = fopen(git_path("MERGE_HEAD"), "r"); if (fp == NULL) die("could not open %s for reading: %s", @@ -991,7 +987,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix) parents = reduce_heads(parents); /* Finally, get the commit message */ - strbuf_init(&sb, 0); if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) { rollback_index_files(); die("could not read commit message"); diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index 7460ab7fce..469b07e240 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -5,8 +5,7 @@ static char *get_stdin(void) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; if (strbuf_read(&buf, 0, 1024) < 0) { die("error reading standard input: %s", strerror(errno)); } diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index c6324dc795..df18f4070f 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -358,7 +358,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) }; FILE *in = stdin; - struct strbuf input, output; + struct strbuf input = STRBUF_INIT, output = STRBUF_INIT; int ret; git_config(fmt_merge_msg_config, NULL); @@ -372,10 +372,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) die("cannot open %s", inpath); } - strbuf_init(&input, 0); if (strbuf_read(&input, fileno(in), 0) < 0) die("could not read input file %s", strerror(errno)); - strbuf_init(&output, 0); ret = fmt_merge_msg(merge_summary, &input, &output); if (ret) diff --git a/builtin-help.c b/builtin-help.c index 64207cbfe9..f076efa921 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -322,11 +322,9 @@ static const char *cmd_to_page(const char *git_cmd) static void setup_man_path(void) { - struct strbuf new_path; + struct strbuf new_path = STRBUF_INIT; const char *old_path = getenv("MANPATH"); - strbuf_init(&new_path, 0); - /* We should always put ':' after our path. If there is no * old_path, the ':' at the end will let 'man' to try * system-wide paths after ours to find the manual page. If diff --git a/builtin-log.c b/builtin-log.c index fc5e4da822..794821f6bc 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -628,10 +628,9 @@ static void gen_message_id(struct rev_info *info, char *base) const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME); const char *email_start = strrchr(committer, '<'); const char *email_end = strrchr(committer, '>'); - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; if (!email_start || !email_end || email_start > email_end - 1) die("Could not extract email from committer identity."); - strbuf_init(&buf, 0); strbuf_addf(&buf, "%s.%lu.git.%.*s", base, (unsigned long) time(NULL), (int)(email_end - email_start - 1), email_start + 1); @@ -650,7 +649,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, const char *msg; const char *extra_headers = rev->extra_headers; struct shortlog log; - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; int i; const char *encoding = "utf-8"; struct diff_options opts; @@ -671,7 +670,6 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, committer = git_committer_info(0); msg = body; - strbuf_init(&sb, 0); pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822, encoding); pp_title_line(CMIT_FMT_EMAIL, &msg, &sb, subject_start, extra_headers, @@ -753,7 +751,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) const char *in_reply_to = NULL; struct patch_ids ids; char *add_signoff = NULL; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; git_config(git_format_config, NULL); init_revisions(&rev, prefix); @@ -861,8 +859,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) } argc = j; - strbuf_init(&buf, 0); - for (i = 0; i < extra_hdr_nr; i++) { strbuf_addstr(&buf, extra_hdr[i]); strbuf_addch(&buf, '\n'); @@ -1139,8 +1135,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) sign = '-'; if (verbose) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; pretty_print_commit(CMIT_FMT_ONELINE, commit, &buf, 0, NULL, NULL, 0, 0); printf("%c %s %s\n", sign, diff --git a/builtin-merge.c b/builtin-merge.c index 38266baf5f..5e2b7f12c3 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -226,7 +226,7 @@ static void reset_hard(unsigned const char *sha1, int verbose) static void restore_state(void) { - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; const char *args[] = { "stash", "apply", NULL, NULL }; if (is_null_sha1(stash)) @@ -234,7 +234,6 @@ static void restore_state(void) reset_hard(head, 1); - strbuf_init(&sb, 0); args[2] = sha1_to_hex(stash); /* @@ -258,7 +257,7 @@ static void squash_message(void) { struct rev_info rev; struct commit *commit; - struct strbuf out; + struct strbuf out = STRBUF_INIT; struct commit_list *j; int fd; @@ -282,7 +281,6 @@ static void squash_message(void) if (prepare_revision_walk(&rev)) die("revision walk setup failed"); - strbuf_init(&out, 0); strbuf_addstr(&out, "Squashed commit of the following:\n"); while ((commit = get_revision(&rev)) != NULL) { strbuf_addch(&out, '\n'); @@ -327,9 +325,8 @@ static int run_hook(const char *name) static void finish(const unsigned char *new_head, const char *msg) { - struct strbuf reflog_message; + struct strbuf reflog_message = STRBUF_INIT; - strbuf_init(&reflog_message, 0); if (!msg) strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION")); else { @@ -380,7 +377,7 @@ static void merge_name(const char *remote, struct strbuf *msg) { struct object *remote_head; unsigned char branch_head[20], buf_sha[20]; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; const char *ptr; int len, early; @@ -389,7 +386,6 @@ static void merge_name(const char *remote, struct strbuf *msg) if (!remote_head) die("'%s' does not point to a commit", remote); - strbuf_init(&buf, 0); strbuf_addstr(&buf, "refs/heads/"); strbuf_addstr(&buf, remote); resolve_ref(buf.buf, branch_head, 0, 0); @@ -444,10 +440,9 @@ static void merge_name(const char *remote, struct strbuf *msg) if (!strcmp(remote, "FETCH_HEAD") && !access(git_path("FETCH_HEAD"), R_OK)) { FILE *fp; - struct strbuf line; + struct strbuf line = STRBUF_INIT; char *ptr; - strbuf_init(&line, 0); fp = fopen(git_path("FETCH_HEAD"), "r"); if (!fp) die("could not open %s for reading: %s", @@ -545,7 +540,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, const char **args; int i = 0, ret; struct commit_list *j; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; int index_fd; struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); @@ -592,7 +587,6 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, } else { args = xmalloc((4 + commit_list_count(common) + commit_list_count(remoteheads)) * sizeof(char *)); - strbuf_init(&buf, 0); strbuf_addf(&buf, "merge-%s", strategy); args[i++] = buf.buf; for (j = common; j; j = j->next) @@ -847,7 +841,7 @@ static int evaluate_result(void) int cmd_merge(int argc, const char **argv, const char *prefix) { unsigned char result_tree[20]; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; const char *head_arg; int flag, head_invalid = 0, i; int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0; @@ -896,7 +890,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * Traditional format never would have "-m" so it is an * additional safety measure to check for it. */ - strbuf_init(&buf, 0); if (!have_message && is_old_style_invocation(argc, argv)) { strbuf_addstr(&merge_msg, argv[0]); @@ -926,7 +919,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) reset_hard(remote_head->sha1, 0); return 0; } else { - struct strbuf msg; + struct strbuf msg = STRBUF_INIT; /* We are invoked directly as the first-class UI. */ head_arg = "HEAD"; @@ -939,7 +932,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * codepath so we discard the error in this * loop. */ - strbuf_init(&msg, 0); for (i = 0; i < argc; i++) merge_name(argv[i], &msg); fmt_merge_msg(option_log, &msg, &merge_msg); @@ -1014,7 +1006,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) !common->next && !hashcmp(common->item->object.sha1, head)) { /* Again the most common case of merging one remote. */ - struct strbuf msg; + struct strbuf msg = STRBUF_INIT; struct object *o; char hex[41]; @@ -1024,7 +1016,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix) hex, find_unique_abbrev(remoteheads->item->object.sha1, DEFAULT_ABBREV)); - strbuf_init(&msg, 0); strbuf_addstr(&msg, "Fast forward"); if (have_message) strbuf_addstr(&msg, diff --git a/builtin-remote.c b/builtin-remote.c index 90a4e35828..6b3325dfa9 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -54,7 +54,7 @@ static int add(int argc, const char **argv) struct string_list track = { NULL, 0, 0 }; const char *master = NULL; struct remote *remote; - struct strbuf buf, buf2; + struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT; const char *name, *url; int i; @@ -81,9 +81,6 @@ static int add(int argc, const char **argv) remote->fetch_refspec_nr)) die("remote %s already exists.", name); - strbuf_init(&buf, 0); - strbuf_init(&buf2, 0); - strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name); if (!valid_fetch_refspec(buf2.buf)) die("'%s' is not a valid remote name", name); @@ -352,7 +349,7 @@ static int rm(int argc, const char **argv) OPT_END() }; struct remote *remote; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; struct known_remotes known_remotes = { NULL, NULL }; struct string_list branches = { NULL, 0, 0, 1 }; struct branches_for_remote cb_data = { NULL, &branches, &known_remotes }; @@ -368,7 +365,6 @@ static int rm(int argc, const char **argv) known_remotes.to_delete = remote; for_each_remote(add_known_remote, &known_remotes); - strbuf_init(&buf, 0); strbuf_addf(&buf, "remote.%s", remote->name); if (git_config_rename_section(buf.buf, NULL) < 1) return error("Could not remove config section '%s'", buf.buf); diff --git a/builtin-rev-list.c b/builtin-rev-list.c index facaff288d..06cdeb7ebe 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -107,8 +107,7 @@ static void show_commit(struct commit *commit) putchar('\n'); if (revs.verbose_header && commit->buffer) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; pretty_print_commit(revs.commit_format, commit, &buf, revs.abbrev, NULL, NULL, revs.date_mode, 0); diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index 9aa049ec17..81d5a6ffc9 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -307,19 +307,17 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) OPT_END(), }; - struct strbuf sb, parsed; + struct strbuf sb = STRBUF_INIT, parsed = STRBUF_INIT; const char **usage = NULL; struct option *opts = NULL; int onb = 0, osz = 0, unb = 0, usz = 0; - strbuf_init(&parsed, 0); strbuf_addstr(&parsed, "set --"); argc = parse_options(argc, argv, parseopt_opts, parseopt_usage, PARSE_OPT_KEEP_DASHDASH); if (argc < 1 || strcmp(argv[0], "--")) usage_with_options(parseopt_usage, parseopt_opts); - strbuf_init(&sb, 0); /* get the usage up to the first line with a -- on it */ for (;;) { if (strbuf_getline(&sb, stdin, '\n') == EOF) diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 233eed499d..306b850c72 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -259,11 +259,10 @@ static void join_revs(struct commit_list **list_p, static void show_one_commit(struct commit *commit, int no_name) { - struct strbuf pretty; + struct strbuf pretty = STRBUF_INIT; const char *pretty_str = "(unavailable)"; struct commit_name *name = commit->util; - strbuf_init(&pretty, 0); if (commit->object.parsed) { pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, 0, NULL, NULL, 0, 0); diff --git a/builtin-stripspace.c b/builtin-stripspace.c index c0b21301ba..d6e3896c00 100644 --- a/builtin-stripspace.c +++ b/builtin-stripspace.c @@ -70,14 +70,13 @@ void stripspace(struct strbuf *sb, int skip_comments) int cmd_stripspace(int argc, const char **argv, const char *prefix) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; int strip_comments = 0; if (argc > 1 && (!strcmp(argv[1], "-s") || !strcmp(argv[1], "--strip-comments"))) strip_comments = 1; - strbuf_init(&buf, 0); if (strbuf_read(&buf, 0, 1024) < 0) die("could not read the input"); diff --git a/builtin-tag.c b/builtin-tag.c index f2853d08c7..b13fa34d8c 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -338,7 +338,7 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) int cmd_tag(int argc, const char **argv, const char *prefix) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; unsigned char object[20], prev[20]; char ref[PATH_MAX]; const char *object_ref, *tag; @@ -388,7 +388,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix) if (verify) return for_each_tag_name(argv, verify_tag); - strbuf_init(&buf, 0); if (msg.given || msgfile) { if (msg.given && msgfile) die("only one -F or -m option is allowed."); diff --git a/builtin-update-index.c b/builtin-update-index.c index 3a2291b03e..65d5775107 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -297,11 +297,9 @@ static void update_one(const char *path, const char *prefix, int prefix_length) static void read_index_info(int line_termination) { - struct strbuf buf; - struct strbuf uq; + struct strbuf buf = STRBUF_INIT; + struct strbuf uq = STRBUF_INIT; - strbuf_init(&buf, 0); - strbuf_init(&uq, 0); while (strbuf_getline(&buf, stdin, line_termination) != EOF) { char *ptr, *tab; char *path_name; @@ -717,10 +715,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) free((char*)p); } if (read_from_stdin) { - struct strbuf buf, nbuf; + struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; - strbuf_init(&buf, 0); - strbuf_init(&nbuf, 0); setup_work_tree(); while (strbuf_getline(&buf, stdin, line_termination) != EOF) { const char *p; diff --git a/combine-diff.c b/combine-diff.c index de83c6972e..5aa1104d34 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -742,9 +742,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, /* If not a fake symlink, apply filters, e.g. autocrlf */ if (is_file) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; - strbuf_init(&buf, 0); if (convert_to_git(elem->path, result, len, &buf, safe_crlf)) { free(result); result = strbuf_detach(&buf, &len); diff --git a/config.c b/config.c index 18d305c890..b8d289d217 100644 --- a/config.c +++ b/config.c @@ -753,9 +753,8 @@ static int store_write_section(int fd, const char* key) { const char *dot; int i, success; - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; - strbuf_init(&sb, 0); dot = memchr(key, '.', store.baselen); if (dot) { strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key); @@ -780,7 +779,7 @@ static int store_write_pair(int fd, const char* key, const char* value) int i, success; int length = strlen(key + store.baselen + 1); const char *quote = ""; - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; /* * Check to see if the value needs to be surrounded with a dq pair. @@ -797,7 +796,6 @@ static int store_write_pair(int fd, const char* key, const char* value) if (i && value[i - 1] == ' ') quote = "\""; - strbuf_init(&sb, 0); strbuf_addf(&sb, "\t%.*s = %s", length, key + store.baselen + 1, quote); diff --git a/convert.c b/convert.c index 78efed800d..1816e977b7 100644 --- a/convert.c +++ b/convert.c @@ -281,7 +281,7 @@ static int apply_filter(const char *path, const char *src, size_t len, * (child --> cmd) --> us */ int ret = 1; - struct strbuf nbuf; + struct strbuf nbuf = STRBUF_INIT; struct async async; struct filter_params params; @@ -299,7 +299,6 @@ static int apply_filter(const char *path, const char *src, size_t len, if (start_async(&async)) return 0; /* error was already reported */ - strbuf_init(&nbuf, 0); if (strbuf_read(&nbuf, async.out, len) < 0) { error("read from external filter %s failed", cmd); ret = 0; diff --git a/diff.c b/diff.c index 2af3a97487..1c6be897b2 100644 --- a/diff.c +++ b/diff.c @@ -217,9 +217,8 @@ static char *quote_two(const char *one, const char *two) { int need_one = quote_c_style(one, NULL, NULL, 1); int need_two = quote_c_style(two, NULL, NULL, 1); - struct strbuf res; + struct strbuf res = STRBUF_INIT; - strbuf_init(&res, 0); if (need_one + need_two) { strbuf_addch(&res, '"'); quote_c_style(one, &res, NULL, 1); @@ -683,7 +682,7 @@ static char *pprint_rename(const char *a, const char *b) { const char *old = a; const char *new = b; - struct strbuf name; + struct strbuf name = STRBUF_INIT; int pfx_length, sfx_length; int len_a = strlen(a); int len_b = strlen(b); @@ -691,7 +690,6 @@ static char *pprint_rename(const char *a, const char *b) int qlen_a = quote_c_style(a, NULL, NULL, 0); int qlen_b = quote_c_style(b, NULL, NULL, 0); - strbuf_init(&name, 0); if (qlen_a || qlen_b) { quote_c_style(a, &name, NULL, 0); strbuf_addstr(&name, " => "); @@ -834,8 +832,7 @@ static void fill_print_name(struct diffstat_file *file) return; if (!file->is_renamed) { - struct strbuf buf; - strbuf_init(&buf, 0); + struct strbuf buf = STRBUF_INIT; if (quote_c_style(file->name, &buf, NULL, 0)) { pname = strbuf_detach(&buf, NULL); } else { @@ -1820,10 +1817,9 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int static int populate_from_stdin(struct diff_filespec *s) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; size_t size = 0; - strbuf_init(&buf, 0); if (strbuf_read(&buf, 0, 0) < 0) return error("error while reading from stdin %s", strerror(errno)); @@ -1875,7 +1871,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) if (!s->sha1_valid || reuse_worktree_file(s->path, s->sha1, 0)) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; struct stat st; int fd; @@ -1918,7 +1914,6 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) /* * Convert from working tree format to canonical git format */ - strbuf_init(&buf, 0); if (convert_to_git(s->path, s->data, s->size, &buf, safe_crlf)) { size_t size = 0; munmap(s->data, s->size); diff --git a/editor.c b/editor.c index eebc3e95fe..4d469d076b 100644 --- a/editor.c +++ b/editor.c @@ -26,9 +26,8 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en int i = 0; int failed; const char *args[6]; - struct strbuf arg0; + struct strbuf arg0 = STRBUF_INIT; - strbuf_init(&arg0, 0); if (strcspn(editor, "$ \t'") != len) { /* there are specials */ strbuf_addf(&arg0, "%s \"$@\"", editor); diff --git a/exec_cmd.c b/exec_cmd.c index ce6741eb68..cdd35f9195 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -59,9 +59,7 @@ static void add_path(struct strbuf *out, const char *path) void setup_path(void) { const char *old_path = getenv("PATH"); - struct strbuf new_path; - - strbuf_init(&new_path, 0); + struct strbuf new_path = STRBUF_INIT; add_path(&new_path, argv_exec_path); add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT)); diff --git a/fsck.c b/fsck.c index 797e3178ae..0cf5f012bd 100644 --- a/fsck.c +++ b/fsck.c @@ -307,9 +307,8 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...) { va_list ap; int len; - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; - strbuf_init(&sb, 0); strbuf_addf(&sb, "object %s:", obj->sha1?sha1_to_hex(obj->sha1):"(null)"); va_start(ap, fmt); diff --git a/git.c b/git.c index f4b0cf611b..89feb0b6dc 100644 --- a/git.c +++ b/git.c @@ -389,10 +389,9 @@ static void handle_internal_command(int argc, const char **argv) static void execv_dashed_external(const char **argv) { - struct strbuf cmd; + struct strbuf cmd = STRBUF_INIT; const char *tmp; - strbuf_init(&cmd, 0); strbuf_addf(&cmd, "git-%s", argv[0]); /* diff --git a/graph.c b/graph.c index 5f821706c6..162a516ee1 100644 --- a/graph.c +++ b/graph.c @@ -1010,14 +1010,12 @@ int graph_is_commit_finished(struct git_graph const *graph) void graph_show_commit(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; int shown_commit_line = 0; if (!graph) return; - strbuf_init(&msgbuf, 0); - while (!shown_commit_line) { shown_commit_line = graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); @@ -1031,12 +1029,11 @@ void graph_show_commit(struct git_graph *graph) void graph_show_oneline(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; if (!graph) return; - strbuf_init(&msgbuf, 0); graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); strbuf_release(&msgbuf); @@ -1044,12 +1041,11 @@ void graph_show_oneline(struct git_graph *graph) void graph_show_padding(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; if (!graph) return; - strbuf_init(&msgbuf, 0); graph_padding_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); strbuf_release(&msgbuf); @@ -1057,7 +1053,7 @@ void graph_show_padding(struct git_graph *graph) int graph_show_remainder(struct git_graph *graph) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; int shown = 0; if (!graph) @@ -1066,7 +1062,6 @@ int graph_show_remainder(struct git_graph *graph) if (graph_is_commit_finished(graph)) return 0; - strbuf_init(&msgbuf, 0); for (;;) { graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); diff --git a/hash-object.c b/hash-object.c index a4d127cf78..20937ff94c 100644 --- a/hash-object.c +++ b/hash-object.c @@ -34,10 +34,8 @@ static void hash_object(const char *path, const char *type, int write_object, static void hash_stdin_paths(const char *type, int write_objects) { - struct strbuf buf, nbuf; + struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; - strbuf_init(&buf, 0); - strbuf_init(&nbuf, 0); while (strbuf_getline(&buf, stdin, '\n') != EOF) { if (buf.buf[0] == '"') { strbuf_reset(&nbuf); diff --git a/imap-send.c b/imap-send.c index af7e08c094..3703dbd1af 100644 --- a/imap-send.c +++ b/imap-send.c @@ -1266,10 +1266,9 @@ static int imap_store_msg(struct store *gctx, struct msg_data *data, int *uid) static int read_message(FILE *f, struct msg_data *msg) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; memset(msg, 0, sizeof(*msg)); - strbuf_init(&buf, 0); do { if (strbuf_fread(&buf, CHUNKSIZE, f) <= 0) diff --git a/log-tree.c b/log-tree.c index 2c1f3e673a..cec3c06136 100644 --- a/log-tree.c +++ b/log-tree.c @@ -252,7 +252,7 @@ void log_write_email_headers(struct rev_info *opt, const char *name, void show_log(struct rev_info *opt) { - struct strbuf msgbuf; + struct strbuf msgbuf = STRBUF_INIT; struct log_info *log = opt->loginfo; struct commit *commit = log->commit, *parent = log->parent; int abbrev = opt->diffopt.abbrev; @@ -381,7 +381,6 @@ void show_log(struct rev_info *opt) /* * And then the pretty-printed message itself */ - strbuf_init(&msgbuf, 0); if (need_8bit_cte >= 0) need_8bit_cte = has_non_ascii(opt->add_signoff); pretty_print_commit(opt->commit_format, commit, &msgbuf, diff --git a/merge-recursive.c b/merge-recursive.c index 6bc3eac85c..245232a408 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -498,8 +498,7 @@ static void update_file_flags(struct merge_options *o, if (type != OBJ_BLOB) die("blob expected for %s '%s'", sha1_to_hex(sha), path); if (S_ISREG(mode)) { - struct strbuf strbuf; - strbuf_init(&strbuf, 0); + struct strbuf strbuf = STRBUF_INIT; if (convert_to_working_tree(path, buf, size, &strbuf)) { free(buf); size = strbuf.len; diff --git a/mktag.c b/mktag.c index 0b34341f71..ba3d495e07 100644 --- a/mktag.c +++ b/mktag.c @@ -153,7 +153,7 @@ static int verify_tag(char *buffer, unsigned long size) int main(int argc, char **argv) { - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; unsigned char result_sha1[20]; if (argc != 1) @@ -161,7 +161,6 @@ int main(int argc, char **argv) setup_git_directory(); - strbuf_init(&buf, 0); if (strbuf_read(&buf, 0, 4096) < 0) { die("could not read from stdin"); } diff --git a/mktree.c b/mktree.c index e0da110a98..514fd9b15a 100644 --- a/mktree.c +++ b/mktree.c @@ -65,8 +65,8 @@ static const char mktree_usage[] = "git-mktree [-z]"; int main(int ac, char **av) { - struct strbuf sb; - struct strbuf p_uq; + struct strbuf sb = STRBUF_INIT; + struct strbuf p_uq = STRBUF_INIT; unsigned char sha1[20]; int line_termination = '\n'; @@ -82,8 +82,6 @@ int main(int ac, char **av) av++; } - strbuf_init(&sb, 0); - strbuf_init(&p_uq, 0); while (strbuf_getline(&sb, stdin, line_termination) != EOF) { char *ptr, *ntr; unsigned mode; diff --git a/pretty.c b/pretty.c index 8beafa08d3..1e79943339 100644 --- a/pretty.c +++ b/pretty.c @@ -234,7 +234,7 @@ static char *get_header(const struct commit *commit, const char *key) static char *replace_encoding_header(char *buf, const char *encoding) { - struct strbuf tmp; + struct strbuf tmp = STRBUF_INIT; size_t start, len; char *cp = buf; @@ -250,7 +250,6 @@ static char *replace_encoding_header(char *buf, const char *encoding) return buf; /* should not happen but be defensive */ len = cp + 1 - (buf + start); - strbuf_init(&tmp, 0); strbuf_attach(&tmp, buf, strlen(buf), strlen(buf) + 1); if (is_encoding_utf8(encoding)) { /* we have re-coded to UTF-8; drop the header */ diff --git a/read-cache.c b/read-cache.c index 6f344f345d..c229fd4d0d 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1467,9 +1467,8 @@ int write_index(const struct index_state *istate, int newfd) /* Write extension data here */ if (istate->cache_tree) { - struct strbuf sb; + struct strbuf sb = STRBUF_INIT; - strbuf_init(&sb, 0); cache_tree_write(&sb, istate->cache_tree); err = write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sb.len) < 0 || ce_write(&c, newfd, sb.buf, sb.len) < 0; diff --git a/remote.c b/remote.c index a2d7ab146e..d5efadd93d 100644 --- a/remote.c +++ b/remote.c @@ -245,7 +245,7 @@ static void read_branches_file(struct remote *remote) { const char *slash = strchr(remote->name, '/'); char *frag; - struct strbuf branch; + struct strbuf branch = STRBUF_INIT; int n = slash ? slash - remote->name : 1000; FILE *f = fopen(git_path("branches/%.*s", n, remote->name), "r"); char *s, *p; @@ -283,7 +283,6 @@ static void read_branches_file(struct remote *remote) * #branch specified. The "master" (or specified) branch is * fetched and stored in the local branch of the same name. */ - strbuf_init(&branch, 0); frag = strchr(p, '#'); if (frag) { *(frag++) = '\0'; diff --git a/rerere.c b/rerere.c index 121f911414..5bb5316cda 100644 --- a/rerere.c +++ b/rerere.c @@ -79,7 +79,7 @@ static int handle_file(const char *path, enum { RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL, } hunk = RR_CONTEXT; - struct strbuf one, two; + struct strbuf one = STRBUF_INIT, two = STRBUF_INIT; FILE *f = fopen(path, "r"); FILE *out = NULL; @@ -97,8 +97,6 @@ static int handle_file(const char *path, if (sha1) git_SHA1_Init(&ctx); - strbuf_init(&one, 0); - strbuf_init(&two, 0); while (fgets(buf, sizeof(buf), f)) { if (!prefixcmp(buf, "<<<<<<< ")) { if (hunk != RR_CONTEXT) diff --git a/sha1_file.c b/sha1_file.c index ea6bd996b2..3fbb0820a0 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -2386,8 +2386,7 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size, * Convert blobs to git internal format */ if ((type == OBJ_BLOB) && path) { - struct strbuf nbuf; - strbuf_init(&nbuf, 0); + struct strbuf nbuf = STRBUF_INIT; if (convert_to_git(path, buf, size, &nbuf, write_object ? safe_crlf : 0)) { buf = strbuf_detach(&nbuf, &size); @@ -2411,8 +2410,7 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, size_t size = xsize_t(st->st_size); if (!S_ISREG(st->st_mode)) { - struct strbuf sbuf; - strbuf_init(&sbuf, 0); + struct strbuf sbuf = STRBUF_INIT; if (strbuf_read(&sbuf, fd, 4096) >= 0) ret = index_mem(sha1, sbuf.buf, sbuf.len, write_object, type, path); diff --git a/walker.c b/walker.c index 0e68ee6d2e..6b4cf70c6a 100644 --- a/walker.c +++ b/walker.c @@ -215,9 +215,8 @@ static int mark_complete(const char *path, const unsigned char *sha1, int flag, int walker_targets_stdin(char ***target, const char ***write_ref) { int targets = 0, targets_alloc = 0; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; *target = NULL; *write_ref = NULL; - strbuf_init(&buf, 0); while (1) { char *rf_one = NULL; char *tg_one; diff --git a/ws.c b/ws.c index 7a7ff130a3..b1efcd9d75 100644 --- a/ws.c +++ b/ws.c @@ -99,8 +99,7 @@ unsigned whitespace_rule(const char *pathname) /* The returned string should be freed by the caller. */ char *whitespace_error_string(unsigned ws) { - struct strbuf err; - strbuf_init(&err, 0); + struct strbuf err = STRBUF_INIT; if (ws & WS_TRAILING_SPACE) strbuf_addstr(&err, "trailing whitespace"); if (ws & WS_SPACE_BEFORE_TAB) { diff --git a/wt-status.c b/wt-status.c index 7cf890f243..d2eac36aea 100644 --- a/wt-status.c +++ b/wt-status.c @@ -103,10 +103,8 @@ static void wt_status_print_filepair(struct wt_status *s, { const char *c = color(t); const char *one, *two; - struct strbuf onebuf, twobuf; + struct strbuf onebuf = STRBUF_INIT, twobuf = STRBUF_INIT; - strbuf_init(&onebuf, 0); - strbuf_init(&twobuf, 0); one = quote_path(p->one->path, -1, &onebuf, s->prefix); two = quote_path(p->two->path, -1, &twobuf, s->prefix); @@ -190,9 +188,8 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q, static void wt_status_print_initial(struct wt_status *s) { int i; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; - strbuf_init(&buf, 0); if (active_nr) { s->commitable = 1; wt_status_print_cached_header(s); @@ -268,9 +265,8 @@ static void wt_status_print_untracked(struct wt_status *s) struct dir_struct dir; int i; int shown_header = 0; - struct strbuf buf; + struct strbuf buf = STRBUF_INIT; - strbuf_init(&buf, 0); memset(&dir, 0, sizeof(dir)); if (!s->untracked) { -- cgit v1.3 From acd3b9eca82e38950f94e4708b528b7dae09a7c8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 17 Oct 2008 15:44:39 -0700 Subject: Enhance hold_lock_file_for_{update,append}() API This changes the "die_on_error" boolean parameter to a mere "flags", and changes the existing callers of hold_lock_file_for_update/append() functions to pass LOCK_DIE_ON_ERROR. Signed-off-by: Junio C Hamano --- builtin-commit.c | 3 ++- builtin-fetch-pack.c | 3 ++- builtin-revert.c | 3 ++- bundle.c | 3 ++- cache.h | 2 ++ lockfile.c | 29 +++++++++++++++++------------ pack-refs.c | 3 ++- refs.c | 9 ++++++--- rerere.c | 3 ++- sha1_file.c | 2 +- t/t7201-co.sh | 2 +- 11 files changed, 39 insertions(+), 23 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index e2a7e48b1c..b563a0d67c 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -320,7 +320,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix) die("unable to write new_index file"); fd = hold_lock_file_for_update(&false_lock, - git_path("next-index-%d", getpid()), 1); + git_path("next-index-%d", getpid()), + LOCK_DIE_ON_ERROR); create_base_index(); add_remove_files(&partial); diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 85509f5ee5..21ce3e0163 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -813,7 +813,8 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args, ) die("shallow file was changed during fetch"); - fd = hold_lock_file_for_update(&lock, shallow, 1); + fd = hold_lock_file_for_update(&lock, shallow, + LOCK_DIE_ON_ERROR); if (!write_shallow_commits(fd, 0)) { unlink(shallow); rollback_lock_file(&lock); diff --git a/builtin-revert.c b/builtin-revert.c index 27881e9493..e839387629 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -338,7 +338,8 @@ static int revert_or_cherry_pick(int argc, const char **argv) * reverse of it if we are revert. */ - msg_fd = hold_lock_file_for_update(&msg_file, defmsg, 1); + msg_fd = hold_lock_file_for_update(&msg_file, defmsg, + LOCK_DIE_ON_ERROR); encoding = get_encoding(message); if (!encoding) diff --git a/bundle.c b/bundle.c index 00b2aabefc..7d17a1fde1 100644 --- a/bundle.c +++ b/bundle.c @@ -186,7 +186,8 @@ int create_bundle(struct bundle_header *header, const char *path, if (bundle_to_stdout) bundle_fd = 1; else - bundle_fd = hold_lock_file_for_update(&lock, path, 1); + bundle_fd = hold_lock_file_for_update(&lock, path, + LOCK_DIE_ON_ERROR); /* write signature */ write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature)); diff --git a/cache.h b/cache.h index 884fae826c..8ab2fd8fd0 100644 --- a/cache.h +++ b/cache.h @@ -411,6 +411,8 @@ struct lock_file { char on_list; char filename[PATH_MAX]; }; +#define LOCK_DIE_ON_ERROR 1 +#define LOCK_NODEREF 2 extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int hold_lock_file_for_append(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); diff --git a/lockfile.c b/lockfile.c index 4023797b00..6d75608693 100644 --- a/lockfile.c +++ b/lockfile.c @@ -121,15 +121,17 @@ static char *resolve_symlink(char *p, size_t s) } -static int lock_file(struct lock_file *lk, const char *path) +static int lock_file(struct lock_file *lk, const char *path, int flags) { - if (strlen(path) >= sizeof(lk->filename)) return -1; + if (strlen(path) >= sizeof(lk->filename)) + return -1; strcpy(lk->filename, path); /* * subtract 5 from size to make sure there's room for adding * ".lock" for the lock file name */ - resolve_symlink(lk->filename, sizeof(lk->filename)-5); + if (!(flags & LOCK_NODEREF)) + resolve_symlink(lk->filename, sizeof(lk->filename)-5); strcat(lk->filename, ".lock"); lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666); if (0 <= lk->fd) { @@ -155,21 +157,21 @@ static int lock_file(struct lock_file *lk, const char *path) return lk->fd; } -int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on_error) +int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags) { - int fd = lock_file(lk, path); - if (fd < 0 && die_on_error) + int fd = lock_file(lk, path, flags); + if (fd < 0 && (flags & LOCK_DIE_ON_ERROR)) die("unable to create '%s.lock': %s", path, strerror(errno)); return fd; } -int hold_lock_file_for_append(struct lock_file *lk, const char *path, int die_on_error) +int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags) { int fd, orig_fd; - fd = lock_file(lk, path); + fd = lock_file(lk, path, flags); if (fd < 0) { - if (die_on_error) + if (flags & LOCK_DIE_ON_ERROR) die("unable to create '%s.lock': %s", path, strerror(errno)); return fd; } @@ -177,13 +179,13 @@ int hold_lock_file_for_append(struct lock_file *lk, const char *path, int die_on orig_fd = open(path, O_RDONLY); if (orig_fd < 0) { if (errno != ENOENT) { - if (die_on_error) + if (flags & LOCK_DIE_ON_ERROR) die("cannot open '%s' for copying", path); close(fd); return error("cannot open '%s' for copying", path); } } else if (copy_fd(orig_fd, fd)) { - if (die_on_error) + if (flags & LOCK_DIE_ON_ERROR) exit(128); close(fd); return -1; @@ -215,7 +217,10 @@ int commit_lock_file(struct lock_file *lk) int hold_locked_index(struct lock_file *lk, int die_on_error) { - return hold_lock_file_for_update(lk, get_index_file(), die_on_error); + return hold_lock_file_for_update(lk, get_index_file(), + die_on_error + ? LOCK_DIE_ON_ERROR + : 0); } void set_alternate_index_output(const char *name) diff --git a/pack-refs.c b/pack-refs.c index 848d311c2b..2c76fb181f 100644 --- a/pack-refs.c +++ b/pack-refs.c @@ -89,7 +89,8 @@ int pack_refs(unsigned int flags) memset(&cbdata, 0, sizeof(cbdata)); cbdata.flags = flags; - fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1); + fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), + LOCK_DIE_ON_ERROR); cbdata.refs_file = fdopen(fd, "w"); if (!cbdata.refs_file) die("unable to create ref-pack file structure (%s)", diff --git a/refs.c b/refs.c index 39a3b23804..9e422dcccb 100644 --- a/refs.c +++ b/refs.c @@ -790,7 +790,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char struct ref_lock *lock; struct stat st; int last_errno = 0; - int type; + int type, lflags; int mustexist = (old_sha1 && !is_null_sha1(old_sha1)); lock = xcalloc(1, sizeof(struct ref_lock)); @@ -830,8 +830,11 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char lock->lk = xcalloc(1, sizeof(struct lock_file)); - if (flags & REF_NODEREF) + lflags = LOCK_DIE_ON_ERROR; + if (flags & REF_NODEREF) { ref = orig_ref; + lflags |= LOCK_NODEREF; + } lock->ref_name = xstrdup(ref); lock->orig_ref_name = xstrdup(orig_ref); ref_file = git_path("%s", ref); @@ -845,8 +848,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char error("unable to create directory for %s", ref_file); goto error_return; } - lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, 1); + lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags); return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock; error_return: diff --git a/rerere.c b/rerere.c index 323e493daf..2b7a99d729 100644 --- a/rerere.c +++ b/rerere.c @@ -346,7 +346,8 @@ int setup_rerere(struct string_list *merge_rr) return -1; merge_rr_path = xstrdup(git_path("MERGE_RR")); - fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 1); + fd = hold_lock_file_for_update(&write_lock, merge_rr_path, + LOCK_DIE_ON_ERROR); read_rr(merge_rr); return fd; } diff --git a/sha1_file.c b/sha1_file.c index e2cb342a32..5cfae5d1ad 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -385,7 +385,7 @@ static void read_info_alternates(const char * relative_base, int depth) void add_to_alternates_file(const char *reference) { struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); - int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), 1); + int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR); char *alt = mkpath("%s/objects\n", reference); write_or_die(fd, alt, strlen(alt)); if (commit_lock_file(lock)) diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 3f70adaf5a..f93478f97f 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -339,7 +339,7 @@ test_expect_success 'checkout w/--track from non-branch HEAD fails' ' test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)" ' -test_expect_failure 'detach a symbolic link HEAD' ' +test_expect_success 'detach a symbolic link HEAD' ' git checkout master && git config --bool core.prefersymlinkrefs yes && git checkout side && -- cgit v1.3 From 0b38227f283e208866d3e2ac85bcd947a71f1b17 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 12 Nov 2008 03:25:52 -0500 Subject: commit: Fix stripping of patch in verbose mode. When the "-v" option is given, we put diff of what is to be committed into the commit template, and then strip it back out again after the user has edited it. We used to look for the diff by searching for the "diff --git a/" header. With diff.mnemonicprefix set in the configuration, however, this pattern does not match. The pattern is loosened to cover this case. Also, if the user puts their own diff in the message (e.g., as a sample output), then we will accidentally trigger the pattern, removing part of their output. We can avoid doing this stripping altogether if the user didn't use "-v" in the first place, so we know that any match we find will be a false positive. [jc: this fix was split out of a series originally meant for master.] Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 8 ++++-- t/t7507-commit-verbose.sh | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100755 t/t7507-commit-verbose.sh (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index b563a0d67c..1e08399919 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -1004,9 +1004,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } /* Truncate the message just before the diff, if any. */ - p = strstr(sb.buf, "\ndiff --git a/"); - if (p != NULL) - strbuf_setlen(&sb, p - sb.buf + 1); + if (verbose) { + p = strstr(sb.buf, "\ndiff --git "); + if (p != NULL) + strbuf_setlen(&sb, p - sb.buf + 1); + } if (cleanup_mode != CLEANUP_NONE) stripspace(&sb, cleanup_mode == CLEANUP_ALL); diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh new file mode 100755 index 0000000000..519adba80b --- /dev/null +++ b/t/t7507-commit-verbose.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +test_description='verbose commit template' +. ./test-lib.sh + +cat >check-for-diff <message <<'EOF' +subject + +body +EOF + +test_expect_success 'setup' ' + echo content >file && + git add file && + git commit -F message +' + +test_expect_failure 'initial commit shows verbose diff' ' + git commit --amend -v +' + +test_expect_success 'second commit' ' + echo content modified >file && + git add file && + git commit -F message +' + +check_message() { + git log -1 --pretty=format:%s%n%n%b >actual && + test_cmp "$1" actual +} + +test_expect_success 'verbose diff is stripped out' ' + git commit --amend -v && + check_message message +' + +test_expect_success 'verbose diff is stripped out (mnemonicprefix)' ' + git config diff.mnemonicprefix true && + git commit --amend -v && + check_message message +' + +cat >diff <<'EOF' +This is an example commit message that contains a diff. + +diff --git c/file i/file +new file mode 100644 +index 0000000..f95c11d +--- /dev/null ++++ i/file +@@ -0,0 +1 @@ ++this is some content +EOF + +test_expect_success 'diff in message is retained without -v' ' + git commit --amend -F diff && + check_message diff +' + +test_expect_failure 'diff in message is retained with -v' ' + git commit --amend -F diff -v && + check_message diff +' + +test_done -- cgit v1.3 From 671c9b7e315db89081cc69f83a8f405e4aca37bc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 13 Nov 2008 16:36:30 -0800 Subject: Add cache preload facility This can do the lstat() storm in parallel, giving potentially much improved performance for cold-cache cases or things like NFS that have weak metadata caching. Just use "read_cache_preload()" instead of "read_cache()" to force an optimistic preload of the index stat data. The function takes a pathspec as its argument, allowing us to preload only the relevant portion of the index. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- Documentation/config.txt | 9 +++++ Makefile | 1 + builtin-commit.c | 8 ++--- builtin-diff-files.c | 4 +-- builtin-diff.c | 8 ++--- cache.h | 3 ++ config.c | 5 +++ environment.c | 3 ++ preload-index.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 preload-index.c (limited to 'builtin-commit.c') diff --git a/Documentation/config.txt b/Documentation/config.txt index 32dcd643d2..0d96e763ac 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -413,6 +413,15 @@ data writes properly, but can be useful for filesystems that do not use journalling (traditional UNIX filesystems) or that only journal metadata and not file contents (OS X's HFS+, or Linux ext3 with "data=writeback"). +core.preloadindex:: + Enable parallel index preload for operations like 'git diff' ++ +This can speed up operations like 'git diff' and 'git status' especially +on filesystems like NFS that have weak caching semantics and thus +relatively high IO latencies. With this set to 'true', git will do the +index comparison to the filesystem data in parallel, allowing +overlapping IO's. + alias.*:: Command aliases for the linkgit:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation diff --git a/Makefile b/Makefile index 35adafa011..acac0ae5d9 100644 --- a/Makefile +++ b/Makefile @@ -496,6 +496,7 @@ LIB_OBJS += write_or_die.o LIB_OBJS += ws.o LIB_OBJS += wt-status.o LIB_OBJS += xdiff-interface.o +LIB_OBJS += preload-index.o BUILTIN_OBJS += builtin-add.o BUILTIN_OBJS += builtin-annotate.o diff --git a/builtin-commit.c b/builtin-commit.c index 591d16b91e..1677e6b45f 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -225,18 +225,18 @@ static char *prepare_index(int argc, const char **argv, const char *prefix) if (interactive) { interactive_add(argc, argv, prefix); - if (read_cache() < 0) + if (read_cache_preload(NULL) < 0) die("index file corrupt"); commit_style = COMMIT_AS_IS; return get_index_file(); } - if (read_cache() < 0) - die("index file corrupt"); - if (*argv) pathspec = get_pathspec(prefix, argv); + if (read_cache_preload(pathspec) < 0) + die("index file corrupt"); + /* * Non partial, non as-is commit. * diff --git a/builtin-diff-files.c b/builtin-diff-files.c index 2b578c714d..5b64011de8 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -59,8 +59,8 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) (rev.diffopt.output_format & DIFF_FORMAT_PATCH)) rev.combine_merges = rev.dense_combined_merges = 1; - if (read_cache() < 0) { - perror("read_cache"); + if (read_cache_preload(rev.diffopt.paths) < 0) { + perror("read_cache_preload"); return -1; } result = run_diff_files(&rev, options); diff --git a/builtin-diff.c b/builtin-diff.c index 7ceceeb6ff..1447c1d6ba 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -134,8 +134,8 @@ static int builtin_diff_index(struct rev_info *revs, revs->max_count != -1 || revs->min_age != -1 || revs->max_age != -1) usage(builtin_diff_usage); - if (read_cache() < 0) { - perror("read_cache"); + if (read_cache_preload(revs->diffopt.paths) < 0) { + perror("read_cache_preload"); return -1; } return run_diff_index(revs, cached); @@ -234,8 +234,8 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv revs->combine_merges = revs->dense_combined_merges = 1; setup_work_tree(); - if (read_cache() < 0) { - perror("read_cache"); + if (read_cache_preload(revs->diffopt.paths) < 0) { + perror("read_cache_preload"); return -1; } result = run_diff_files(revs, options); diff --git a/cache.h b/cache.h index 3b5f0c4c00..685a8666b6 100644 --- a/cache.h +++ b/cache.h @@ -262,6 +262,7 @@ static inline void remove_name_hash(struct cache_entry *ce) #define read_cache() read_index(&the_index) #define read_cache_from(path) read_index_from(&the_index, (path)) +#define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec)) #define is_cache_unborn() is_index_unborn(&the_index) #define read_cache_unmerged() read_index_unmerged(&the_index) #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd)) @@ -368,6 +369,7 @@ extern int init_db(const char *template_dir, unsigned int flags); /* Initialize and use the cache information */ extern int read_index(struct index_state *); +extern int read_index_preload(struct index_state *, const char **pathspec); extern int read_index_from(struct index_state *, const char *path); extern int is_index_unborn(struct index_state *); extern int read_index_unmerged(struct index_state *); @@ -458,6 +460,7 @@ extern size_t packed_git_limit; extern size_t delta_base_cache_limit; extern int auto_crlf; extern int fsync_object_files; +extern int core_preload_index; enum safe_crlf { SAFE_CRLF_FALSE = 0, diff --git a/config.c b/config.c index 67cc1dcad0..d2fc8f5f22 100644 --- a/config.c +++ b/config.c @@ -490,6 +490,11 @@ static int git_default_core_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.preloadindex")) { + core_preload_index = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/environment.c b/environment.c index bb96ac0a71..e278bce0ea 100644 --- a/environment.c +++ b/environment.c @@ -43,6 +43,9 @@ unsigned whitespace_rule_cfg = WS_DEFAULT_RULE; enum branch_track git_branch_track = BRANCH_TRACK_REMOTE; enum rebase_setup_type autorebase = AUTOREBASE_NEVER; +/* Parallel index stat data preload? */ +int core_preload_index = 0; + /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; static char *work_tree; diff --git a/preload-index.c b/preload-index.c new file mode 100644 index 0000000000..6253578c96 --- /dev/null +++ b/preload-index.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008 Linus Torvalds + */ +#include "cache.h" +#include + +/* + * Mostly randomly chosen maximum thread counts: we + * cap the parallelism to 20 threads, and we want + * to have at least 500 lstat's per thread for it to + * be worth starting a thread. + */ +#define MAX_PARALLEL (20) +#define THREAD_COST (500) + +struct thread_data { + pthread_t pthread; + struct index_state *index; + const char **pathspec; + int offset, nr; +}; + +static void *preload_thread(void *_data) +{ + int nr; + struct thread_data *p = _data; + struct index_state *index = p->index; + struct cache_entry **cep = index->cache + p->offset; + + nr = p->nr; + if (nr + p->offset > index->cache_nr) + nr = index->cache_nr - p->offset; + + do { + struct cache_entry *ce = *cep++; + struct stat st; + + if (ce_stage(ce)) + continue; + if (ce_uptodate(ce)) + continue; + if (!ce_path_match(ce, p->pathspec)) + continue; + if (lstat(ce->name, &st)) + continue; + if (ie_match_stat(index, ce, &st, 0)) + continue; + ce_mark_uptodate(ce); + } while (--nr > 0); + return NULL; +} + +static void preload_index(struct index_state *index, const char **pathspec) +{ + int threads, i, work, offset; + struct thread_data data[MAX_PARALLEL]; + + if (!core_preload_index) + return; + + threads = index->cache_nr / THREAD_COST; + if (threads < 2) + return; + if (threads > MAX_PARALLEL) + threads = MAX_PARALLEL; + offset = 0; + work = (index->cache_nr + threads - 1) / threads; + for (i = 0; i < threads; i++) { + struct thread_data *p = data+i; + p->index = index; + p->pathspec = pathspec; + p->offset = offset; + p->nr = work; + offset += work; + if (pthread_create(&p->pthread, NULL, preload_thread, p)) + die("unable to create threaded lstat"); + } + for (i = 0; i < threads; i++) { + struct thread_data *p = data+i; + if (pthread_join(p->pthread, NULL)) + die("unable to join threaded lstat"); + } +} + +int read_index_preload(struct index_state *index, const char **pathspec) +{ + int retval = read_index(index); + + preload_index(index, pathspec); + return retval; +} -- cgit v1.3 From 331fcb598ec0127fd89c992361bc573dcd3a4a63 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 28 Nov 2008 19:56:34 -0800 Subject: git add --intent-to-add: do not let an empty blob be committed by accident Writing a tree out of an index with an "intent to add" entry is blocked. This implies that you cannot "git commit" from such a state; however you can still do "git commit -a" or "git commit $that_path". Signed-off-by: Junio C Hamano --- builtin-commit.c | 2 +- builtin-write-tree.c | 2 +- cache-tree.c | 10 +++++++--- read-cache.c | 8 ++++++++ t/t2203-add-intent.sh | 28 ++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 1677e6b45f..2b499fa543 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix) active_cache_tree = cache_tree(); if (cache_tree_update(active_cache_tree, active_cache, active_nr, 0, 0) < 0) { - error("Error building trees; the index is unmerged?"); + error("Error building trees"); return 0; } diff --git a/builtin-write-tree.c b/builtin-write-tree.c index 52a3c015ff..9d640508dd 100644 --- a/builtin-write-tree.c +++ b/builtin-write-tree.c @@ -42,7 +42,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) die("%s: error reading the index", me); break; case WRITE_TREE_UNMERGED_INDEX: - die("%s: error building trees; the index is unmerged?", me); + die("%s: error building trees", me); break; case WRITE_TREE_PREFIX_ERROR: die("%s: prefix %s not found", me, prefix); diff --git a/cache-tree.c b/cache-tree.c index 5f8ee87bb1..3d8f218a5f 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -155,13 +155,17 @@ static int verify_cache(struct cache_entry **cache, funny = 0; for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; - if (ce_stage(ce)) { + if (ce_stage(ce) || (ce->ce_flags & CE_INTENT_TO_ADD)) { if (10 < ++funny) { fprintf(stderr, "...\n"); break; } - fprintf(stderr, "%s: unmerged (%s)\n", - ce->name, sha1_to_hex(ce->sha1)); + if (ce_stage(ce)) + fprintf(stderr, "%s: unmerged (%s)\n", + ce->name, sha1_to_hex(ce->sha1)); + else + fprintf(stderr, "%s: not added yet\n", + ce->name); } } if (funny) diff --git a/read-cache.c b/read-cache.c index fa30a0f885..8579663ee0 100644 --- a/read-cache.c +++ b/read-cache.c @@ -257,6 +257,14 @@ int ie_match_stat(const struct index_state *istate, if (!ignore_valid && (ce->ce_flags & CE_VALID)) return 0; + /* + * Intent-to-add entries have not been added, so the index entry + * by definition never matches what is in the work tree until it + * actually gets added. + */ + if (ce->ce_flags & CE_INTENT_TO_ADD) + return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED; + changed = ce_match_stat_basic(ce, st); /* diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index d4de35ea06..58a329961e 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -32,5 +32,33 @@ test_expect_success 'intent to add does not clobber existing paths' ' ! grep "$empty" actual ' +test_expect_success 'cannot commit with i-t-a entry' ' + test_tick && + git commit -a -m initial && + git reset --hard && + + echo xyzzy >rezrov && + echo frotz >nitfol && + git add rezrov && + git add -N nitfol && + test_must_fail git commit +' + +test_expect_success 'can commit with an unrelated i-t-a entry in index' ' + git reset --hard && + echo xyzzy >rezrov && + echo frotz >nitfol && + git add rezrov && + git add -N nitfol && + git commit -m partial rezrov +' + +test_expect_success 'can "commit -a" with an i-t-a entry' ' + git reset --hard && + : >nitfol && + git add -N nitfol && + git commit -a -m all +' + test_done -- cgit v1.3 From 7e76aba317b690932c8236311219b0faf97f1571 Mon Sep 17 00:00:00 2001 From: Markus Heidelberg Date: Sat, 13 Dec 2008 20:05:34 +0100 Subject: builtin-commit: remove unused message variable builtin-commit uses commit_tree() from builtin-commit-tree since 6bb6b03 (builtin-commit: use commit_tree(), 2008-09-10), where the same message is used. Signed-off-by: Markus Heidelberg Signed-off-by: Junio C Hamano --- builtin-commit.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 2b499fa543..e88b78f811 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -932,11 +932,6 @@ static int git_commit_config(const char *k, const char *v, void *cb) return git_status_config(k, v, cb); } -static const char commit_utf8_warn[] = -"Warning: commit message does not conform to UTF-8.\n" -"You may want to amend it after fixing the message, or set the config\n" -"variable i18n.commitencoding to the encoding your project uses.\n"; - int cmd_commit(int argc, const char **argv, const char *prefix) { struct strbuf sb = STRBUF_INIT; -- cgit v1.3 From 3f4b609f5f3146a34eb72e82ab55714328e0bd1a Mon Sep 17 00:00:00 2001 From: Markus Heidelberg Date: Thu, 8 Jan 2009 19:53:01 +0100 Subject: git-commit: color status output when color.ui is set When using "git commit" and there was nothing to commit (the editor wasn't launched), the status output wasn't colored, even though color.ui was set. Only when setting color.status it worked. Signed-off-by: Markus Heidelberg Signed-off-by: Junio C Hamano --- builtin-commit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index e88b78f811..2d90f7430d 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -945,6 +945,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix) git_config(git_commit_config, NULL); + if (wt_status_use_color == -1) + wt_status_use_color = git_use_color_default; + argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix); index_file = prepare_index(argc, argv, prefix); -- cgit v1.3 From 38920dd6d377a82f4c8c51c3451271d6a93c92a8 Mon Sep 17 00:00:00 2001 From: Markus Heidelberg Date: Thu, 8 Jan 2009 19:53:05 +0100 Subject: git-status -v: color diff output when color.ui is set When using "git status -v", the diff output wasn't colored, even though color.ui was set. Only when setting color.diff it worked. Signed-off-by: Markus Heidelberg Signed-off-by: Junio C Hamano --- builtin-commit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 2d90f7430d..7cf227a1b1 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -866,6 +866,9 @@ int cmd_status(int argc, const char **argv, const char *prefix) if (wt_status_use_color == -1) wt_status_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); index_file = prepare_index(argc, argv, prefix); -- cgit v1.3 From 0b50922abffb82c473182b03eb5bb47a978cceac Mon Sep 17 00:00:00 2001 From: Clemens Buchacher Date: Wed, 14 Jan 2009 15:54:35 +0100 Subject: remove pathspec_match, use match_pathspec instead Both versions have the same functionality. This removes any redundancy. This also adds makes two extensions to match_pathspec: - If pathspec is NULL, return 1. This reflects the behavior of git commands, for which no paths usually means "match all paths". - If seen is NULL, do not use it. Signed-off-by: Clemens Buchacher Signed-off-by: Junio C Hamano --- builtin-checkout.c | 6 +++--- builtin-commit.c | 2 +- builtin-ls-files.c | 40 ++-------------------------------------- cache.h | 1 - dir.c | 19 +++++++++++-------- 5 files changed, 17 insertions(+), 51 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-checkout.c b/builtin-checkout.c index b5dd9c07b4..84a28257b6 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -240,7 +240,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; - pathspec_match(pathspec, ps_matched, ce->name, 0); + match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, ps_matched); } if (report_path_error(ps_matched, pathspec, 0)) @@ -249,7 +249,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, /* Any unmerged paths? */ for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; - if (pathspec_match(pathspec, NULL, ce->name, 0)) { + if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) { if (!ce_stage(ce)) continue; if (opts->force) { @@ -274,7 +274,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, state.refresh_cache = 1; for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; - if (pathspec_match(pathspec, NULL, ce->name, 0)) { + if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) { if (!ce_stage(ce)) { errs |= checkout_entry(ce, &state, NULL); continue; diff --git a/builtin-commit.c b/builtin-commit.c index e88b78f811..3d1867ac17 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -166,7 +166,7 @@ static int list_paths(struct string_list *list, const char *with_tree, struct cache_entry *ce = active_cache[i]; if (ce->ce_flags & CE_UPDATE) continue; - if (!pathspec_match(pattern, m, ce->name, 0)) + if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m)) continue; string_list_insert(ce->name, list); } diff --git a/builtin-ls-files.c b/builtin-ls-files.c index f72eb85475..3434031295 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -36,42 +36,6 @@ static const char *tag_other = ""; static const char *tag_killed = ""; static const char *tag_modified = ""; - -/* - * Match a pathspec against a filename. The first "skiplen" characters - * are the common prefix - */ -int pathspec_match(const char **spec, char *ps_matched, - const char *filename, int skiplen) -{ - const char *m; - - while ((m = *spec++) != NULL) { - int matchlen = strlen(m + skiplen); - - if (!matchlen) - goto matched; - if (!strncmp(m + skiplen, filename + skiplen, matchlen)) { - if (m[skiplen + matchlen - 1] == '/') - goto matched; - switch (filename[skiplen + matchlen]) { - case '/': case '\0': - goto matched; - } - } - if (!fnmatch(m + skiplen, filename + skiplen, 0)) - goto matched; - if (ps_matched) - ps_matched++; - continue; - matched: - if (ps_matched) - *ps_matched = 1; - return 1; - } - return 0; -} - static void show_dir_entry(const char *tag, struct dir_entry *ent) { int len = prefix_len; @@ -80,7 +44,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) if (len >= ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); - if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len)) + if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched)) return; fputs(tag, stdout); @@ -156,7 +120,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) if (len >= ce_namelen(ce)) die("git ls-files: internal error - cache entry not superset of prefix"); - if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len)) + if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched)) return; if (tag && *tag && show_valid_bit && diff --git a/cache.h b/cache.h index 231c06d772..c60259d492 100644 --- a/cache.h +++ b/cache.h @@ -936,7 +936,6 @@ extern int ws_fix_copy(char *, const char *, int, unsigned, int *); extern int ws_blank_line(const char *line, int len, unsigned ws_rule); /* ls-files */ -int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen); int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset); void overlay_tree_on_cache(const char *tree_name, const char *prefix); diff --git a/dir.c b/dir.c index 8b0e0fbaf7..c50ecc8d69 100644 --- a/dir.c +++ b/dir.c @@ -108,25 +108,28 @@ static int match_one(const char *match, const char *name, int namelen) * and a mark is left in seen[] array for pathspec element that * actually matched anything. */ -int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen) +int match_pathspec(const char **pathspec, const char *name, int namelen, + int prefix, char *seen) { - int retval; - const char *match; + int i, retval = 0; + + if (!pathspec) + return 1; name += prefix; namelen -= prefix; - for (retval = 0; (match = *pathspec++) != NULL; seen++) { + for (i = 0; pathspec[i] != NULL; i++) { int how; - if (*seen == MATCHED_EXACTLY) + const char *match = pathspec[i] + prefix; + if (seen && seen[i] == MATCHED_EXACTLY) continue; - match += prefix; how = match_one(match, name, namelen); if (how) { if (retval < how) retval = how; - if (*seen < how) - *seen = how; + if (seen && seen[i] < how) + seen[i] = how; } } return retval; -- cgit v1.3 From ae98a0089ff7f7641ed15ddd595797de56eb49f1 Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Fri, 16 Jan 2009 20:09:59 +0100 Subject: Move run_hook() from builtin-commit.c into run-command.c (libgit) A function that runs a hook is used in several Git commands. builtin-commit.c has the one that is most general for cases without piping. The one in builtin-gc.c prints some useful warnings. This patch moves a merged version of these variants into libgit and lets the other builtins use this libified run_hook(). The run_hook() function used in receive-pack.c feeds the standard input of the pre-receive or post-receive hooks. This function is renamed to run_receive_hook() because the libified run_hook() cannot handle this. Mentored-by: Daniel Barkalow Mentored-by: Christian Couder Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- builtin-checkout.c | 22 +++++----------------- builtin-commit.c | 34 ---------------------------------- builtin-gc.c | 30 +----------------------------- builtin-merge.c | 31 +------------------------------ builtin-receive-pack.c | 6 +++--- run-command.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ run-command.h | 2 ++ 7 files changed, 57 insertions(+), 113 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-checkout.c b/builtin-checkout.c index 149343e3a9..275176d15d 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -38,25 +38,13 @@ struct checkout_opts { static int post_checkout_hook(struct commit *old, struct commit *new, int changed) { - struct child_process proc; - const char *name = git_path("hooks/post-checkout"); - const char *argv[5]; - - if (access(name, X_OK) < 0) - return 0; - - memset(&proc, 0, sizeof(proc)); - argv[0] = name; - argv[1] = sha1_to_hex(old ? old->object.sha1 : null_sha1); - argv[2] = sha1_to_hex(new ? new->object.sha1 : null_sha1); + return run_hook(NULL, "post-checkout", + sha1_to_hex(old ? old->object.sha1 : null_sha1), + sha1_to_hex(new ? new->object.sha1 : null_sha1), + changed ? "1" : "0", NULL); /* "new" can be NULL when checking out from the index before a commit exists. */ - argv[3] = changed ? "1" : "0"; - argv[4] = NULL; - proc.argv = argv; - proc.no_stdin = 1; - proc.stdout_to_stderr = 1; - return run_command(&proc); + } static int update_some(const unsigned char *sha1, const char *base, int baselen, diff --git a/builtin-commit.c b/builtin-commit.c index e88b78f811..6f8d9fbfe6 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -361,40 +361,6 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int return s.commitable; } -static int run_hook(const char *index_file, const char *name, ...) -{ - struct child_process hook; - const char *argv[10], *env[2]; - char index[PATH_MAX]; - va_list args; - int i; - - va_start(args, name); - argv[0] = git_path("hooks/%s", name); - i = 0; - do { - if (++i >= ARRAY_SIZE(argv)) - die ("run_hook(): too many arguments"); - argv[i] = va_arg(args, const char *); - } while (argv[i]); - va_end(args); - - snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); - env[0] = index; - env[1] = NULL; - - if (access(argv[0], X_OK) < 0) - return 0; - - memset(&hook, 0, sizeof(hook)); - hook.argv = argv; - hook.no_stdin = 1; - hook.stdout_to_stderr = 1; - hook.env = env; - - return run_command(&hook); -} - static int is_a_merge(const unsigned char *sha1) { struct commit *commit = lookup_commit(sha1); diff --git a/builtin-gc.c b/builtin-gc.c index f8eae4adb4..a2014388da 100644 --- a/builtin-gc.c +++ b/builtin-gc.c @@ -144,34 +144,6 @@ static int too_many_packs(void) return gc_auto_pack_limit <= cnt; } -static int run_hook(void) -{ - const char *argv[2]; - struct child_process hook; - int ret; - - argv[0] = git_path("hooks/pre-auto-gc"); - argv[1] = NULL; - - if (access(argv[0], X_OK) < 0) - return 0; - - memset(&hook, 0, sizeof(hook)); - hook.argv = argv; - hook.no_stdin = 1; - hook.stdout_to_stderr = 1; - - ret = start_command(&hook); - if (ret) { - warning("Could not spawn %s", argv[0]); - return ret; - } - ret = finish_command(&hook); - if (ret == -ERR_RUN_COMMAND_WAITPID_SIGNAL) - warning("%s exited due to uncaught signal", argv[0]); - return ret; -} - static int need_to_gc(void) { /* @@ -194,7 +166,7 @@ static int need_to_gc(void) else if (!too_many_loose_objects()) return 0; - if (run_hook()) + if (run_hook(NULL, "pre-auto-gc", NULL)) return 0; return 1; } diff --git a/builtin-merge.c b/builtin-merge.c index cf869751b4..e4555b0199 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -300,35 +300,6 @@ static void squash_message(void) strbuf_release(&out); } -static int run_hook(const char *name) -{ - struct child_process hook; - const char *argv[3], *env[2]; - char index[PATH_MAX]; - - argv[0] = git_path("hooks/%s", name); - if (access(argv[0], X_OK) < 0) - return 0; - - snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", get_index_file()); - env[0] = index; - env[1] = NULL; - - if (squash) - argv[1] = "1"; - else - argv[1] = "0"; - argv[2] = NULL; - - memset(&hook, 0, sizeof(hook)); - hook.argv = argv; - hook.no_stdin = 1; - hook.stdout_to_stderr = 1; - hook.env = env; - - return run_command(&hook); -} - static void finish(const unsigned char *new_head, const char *msg) { struct strbuf reflog_message = STRBUF_INIT; @@ -374,7 +345,7 @@ static void finish(const unsigned char *new_head, const char *msg) } /* Run a post-merge hook */ - run_hook("post-merge"); + run_hook(NULL, "post-merge", squash ? "1" : "0", NULL); strbuf_release(&reflog_message); } diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c index db67c3162c..6564a97cef 100644 --- a/builtin-receive-pack.c +++ b/builtin-receive-pack.c @@ -136,7 +136,7 @@ static int hook_status(int code, const char *hook_name) } } -static int run_hook(const char *hook_name) +static int run_receive_hook(const char *hook_name) { static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4]; struct command *cmd; @@ -358,7 +358,7 @@ static void execute_commands(const char *unpacker_error) return; } - if (run_hook(pre_receive_hook)) { + if (run_receive_hook(pre_receive_hook)) { while (cmd) { cmd->error_string = "pre-receive hook declined"; cmd = cmd->next; @@ -627,7 +627,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) unlink(pack_lockfile); if (report_status) report(unpack_status); - run_hook(post_receive_hook); + run_receive_hook(post_receive_hook); run_update_post_hook(commands); } return 0; diff --git a/run-command.c b/run-command.c index c90cdc50e3..49810a835e 100644 --- a/run-command.c +++ b/run-command.c @@ -342,3 +342,48 @@ int finish_async(struct async *async) #endif return ret; } + +int run_hook(const char *index_file, const char *name, ...) +{ + struct child_process hook; + const char *argv[10], *env[2]; + char index[PATH_MAX]; + va_list args; + int ret; + int i; + + va_start(args, name); + argv[0] = git_path("hooks/%s", name); + i = 0; + do { + if (++i >= ARRAY_SIZE(argv)) + die("run_hook(): too many arguments"); + argv[i] = va_arg(args, const char *); + } while (argv[i]); + va_end(args); + + if (access(argv[0], X_OK) < 0) + return 0; + + memset(&hook, 0, sizeof(hook)); + hook.argv = argv; + hook.no_stdin = 1; + hook.stdout_to_stderr = 1; + if (index_file) { + snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); + env[0] = index; + env[1] = NULL; + hook.env = env; + } + + ret = start_command(&hook); + if (ret) { + warning("Could not spawn %s", argv[0]); + return ret; + } + ret = finish_command(&hook); + if (ret == -ERR_RUN_COMMAND_WAITPID_SIGNAL) + warning("%s exited due to uncaught signal", argv[0]); + + return ret; +} diff --git a/run-command.h b/run-command.h index a8b0c209e9..0211e1d471 100644 --- a/run-command.h +++ b/run-command.h @@ -49,6 +49,8 @@ int start_command(struct child_process *); int finish_command(struct child_process *); int run_command(struct child_process *); +extern int run_hook(const char *index_file, const char *name, ...); + #define RUN_COMMAND_NO_STDIN 1 #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ #define RUN_COMMAND_STDOUT_TO_STDERR 4 -- cgit v1.3 From 2454ac7b9fbc12db5cca8cd388422360528d7d6f Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Fri, 16 Jan 2009 20:40:05 +0100 Subject: builtin-commit.c: do not remove COMMIT_EDITMSG git-commit tries to remove the file ./COMMIT_EDITMSG instead of $GIT_DIR/COMMIT_EDITMSG after commit preparation (e.g. running hooks, launching editor). This behavior exists since f5bbc3225c4b07 "Port git commit to C". Some test cases (e.g. t/t7502-commit.sh) rely on the existence of $GIT_DIR/COMMIT_EDITMSG after committing and, I guess, many people are used to it. So it is best not to remove it. This patch just removes the removal of COMMIT_EDITMSG. Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- builtin-commit.c | 1 - 1 file changed, 1 deletion(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 1e08399919..6cbdd55f16 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -625,7 +625,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix) if (!commitable && !in_merge && !allow_empty && !(amend && is_a_merge(head_sha1))) { run_status(stdout, index_file, prefix, 0); - unlink(commit_editmsg); return 0; } -- cgit v1.3 From c5ee71fdeda21aef8a65366a3f66aa7cbe58cba0 Mon Sep 17 00:00:00 2001 From: Santi Béjar Date: Mon, 19 Jan 2009 23:45:16 +0100 Subject: commit: more compact summary and without extra quotes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the report format again to save the screen real estates, while avoiding from enclosing the one-line summary of the commit log inside double quotes pair, which looks awkward when the message begins or ends with a double quote. The old format looked like this: [master]: created d9a5491: "foo:bar" Simply removing the double quotes were found to be confusing as a message often begins with a short-word (area of the system) and a colon. The new format looks like this: [master d9a5491] foo:bar As discussed in the git mailing list: http://thread.gmane.org/gmane.comp.version-control.git/101687/focus=101735 Signed-off-by: Santi Béjar 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 2f0b00a174..b159af2e54 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -883,7 +883,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1) { struct rev_info rev; struct commit *commit; - static const char *format = "format:%h: \"%s\""; + static const char *format = "format:%h] %s"; unsigned char junk_sha1[20]; const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL); @@ -910,7 +910,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1) rev.diffopt.break_opt = 0; diff_setup_done(&rev.diffopt); - printf("[%s%s]: created ", + printf("[%s%s ", !prefixcmp(head, "refs/heads/") ? head + 11 : !strcmp(head, "HEAD") ? -- cgit v1.3 From 75f3ff2eeaba820b37016f464b6d1078cb6260e2 Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Tue, 10 Feb 2009 15:30:35 +0100 Subject: Generalize and libify index_is_dirty() to index_differs_from(...) index_is_dirty() in builtin-revert.c checks if the index is dirty. This patch generalizes this function to check if the index differs from a revision, i.e. the former index_is_dirty() behavior can now be achieved by index_differs_from("HEAD", 0). The second argument "diff_flags" allows to set further diff option flags like DIFF_OPT_IGNORE_SUBMODULES. See DIFF_OPT_* macros in diff.h for a list. index_differs_from() seems to be useful for more than builtin-revert.c, so it is moved into diff-lib.c and also used in builtin-commit.c. Yet to mention: - "rev.abbrev = 0;" can be safely removed. This has no impact on performance or functioning of neither setup_revisions() nor run_diff_index(). - rev.pending.objects is free()d because this fixes a leak. (Also see 295dd2ad "Fix memory leak in traverse_commit_list") Mentored-by: Daniel Barkalow Mentored-by: Christian Couder Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- builtin-commit.c | 13 ++----------- builtin-revert.c | 13 +------------ diff-lib.c | 15 +++++++++++++++ diff.h | 2 ++ 4 files changed, 20 insertions(+), 23 deletions(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index d6a3a6203a..46e649cd7c 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -561,7 +561,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix) commitable = run_status(fp, index_file, prefix, 1); wt_status_use_color = saved_color_setting; } else { - struct rev_info rev; unsigned char sha1[20]; const char *parent = "HEAD"; @@ -573,16 +572,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix) if (get_sha1(parent, sha1)) commitable = !!active_nr; - else { - init_revisions(&rev, ""); - rev.abbrev = 0; - setup_revisions(0, NULL, &rev, parent); - DIFF_OPT_SET(&rev.diffopt, QUIET); - DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); - run_diff_index(&rev, 1 /* cached */); - - commitable = !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES); - } + else + commitable = index_differs_from(parent, 0); } fclose(fp); diff --git a/builtin-revert.c b/builtin-revert.c index d48313c745..d210150671 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -223,17 +223,6 @@ static char *help_msg(const unsigned char *sha1) return helpbuf; } -static int index_is_dirty(void) -{ - struct rev_info rev; - init_revisions(&rev, NULL); - setup_revisions(0, NULL, &rev, "HEAD"); - DIFF_OPT_SET(&rev.diffopt, QUIET); - DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); - run_diff_index(&rev, 1); - return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES); -} - static struct tree *empty_tree(void) { struct tree *tree = xcalloc(1, sizeof(struct tree)); @@ -279,7 +268,7 @@ static int revert_or_cherry_pick(int argc, const char **argv) } else { if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); - if (index_is_dirty()) + if (index_differs_from("HEAD", 0)) die ("Dirty index: cannot %s", me); } discard_cache(); diff --git a/diff-lib.c b/diff-lib.c index a41e1ec07c..79d0606834 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -513,3 +513,18 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) exit(128); return 0; } + +int index_differs_from(const char *def, int diff_flags) +{ + struct rev_info rev; + + init_revisions(&rev, NULL); + setup_revisions(0, NULL, &rev, def); + DIFF_OPT_SET(&rev.diffopt, QUIET); + DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); + rev.diffopt.flags |= diff_flags; + run_diff_index(&rev, 1); + if (rev.pending.alloc) + free(rev.pending.objects); + return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0); +} diff --git a/diff.h b/diff.h index 23cd90c2e6..6703a4fb4f 100644 --- a/diff.h +++ b/diff.h @@ -265,4 +265,6 @@ extern int diff_result_code(struct diff_options *, int); extern void diff_no_index(struct rev_info *, int, const char **, int, const char *); +extern int index_differs_from(const char *def, int diff_flags); + #endif /* DIFF_H */ -- cgit v1.3 From 4f6a32f8af9cceaf0c8ccf6d00d2f100dab5a6db Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 3 Apr 2009 15:28:56 -0400 Subject: commit: abort commit if interactive add failed Previously we ignored the result of calling add_interactive, which meant that if an error occurred we simply committed whatever happened to be in the index. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-commit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 6cbdd55f16..fde7b891d9 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -224,7 +224,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix) const char **pathspec = NULL; if (interactive) { - interactive_add(argc, argv, prefix); + if (interactive_add(argc, argv, prefix) != 0) + die("interactive add failed"); if (read_cache() < 0) die("index file corrupt"); commit_style = COMMIT_AS_IS; -- cgit v1.3 From aae94ffbc138181777a942ef18daf52606df833d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 23 May 2009 11:53:10 -0700 Subject: commit: -F overrides -t Commit dbd0f5c7 (Files given on the command line are relative to $cwd, 2008-08-06) introduced parse_options_fix_filename() as a quick fix for filename arguments used in the parse options API. git-commit was still broken. This means git commit -F log -t temp in a subdirectory would make git think the log message should be taken from temp instead of log. This is because parse_options_fix_filename() calls prefix_filename() which uses a single static char buffer to do its work. Making two calls with two char pointers causes the pointers to alias. To prevent aliasing, we duplicate the string returned by parse_options_fix_filename(). Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- builtin-commit.c | 4 ++++ t/t7500-commit.sh | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'builtin-commit.c') diff --git a/builtin-commit.c b/builtin-commit.c index 81371b1d26..baaa75cf90 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -699,7 +699,11 @@ static int parse_and_validate_options(int argc, const char *argv[], argc = parse_options(argc, argv, builtin_commit_options, usage, 0); logfile = parse_options_fix_filename(prefix, logfile); + if (logfile) + logfile = xstrdup(logfile); template_file = parse_options_fix_filename(prefix, template_file); + if (template_file) + template_file = xstrdup(template_file); if (force_author && !strchr(force_author, '>')) force_author = find_author_by_nickname(force_author); diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 5998baf27b..8eec0fa9bc 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -183,4 +183,14 @@ test_expect_success 'commit message from stdin' ' commit_msg_is "Log with foo word" ' +test_expect_success 'commit -F overrides -t' ' + ( + cd subdir && + echo "-F log" > f.log && + echo "-t template" > t.template && + git commit --allow-empty -F f.log -t t.template + ) && + commit_msg_is "-F log" +' + test_done -- cgit v1.3 From 377829201783b8a648e07af6ce7d747e0f45dc19 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 23 May 2009 11:53:12 -0700 Subject: parse-opts: prepare for OPT_FILENAME To give OPT_FILENAME the prefix, we pass the prefix to parse_options() which passes the prefix to parse_options_start() which sets the prefix member of parse_opts_ctx accordingly. If there isn't a prefix in the calling context, passing NULL will suffice. Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- Documentation/technical/api-parse-options.txt | 4 ++-- archive.c | 2 +- builtin-add.c | 2 +- builtin-apply.c | 2 +- builtin-archive.c | 3 ++- builtin-bisect--helper.c | 3 ++- builtin-blame.c | 2 +- builtin-branch.c | 3 ++- builtin-cat-file.c | 2 +- builtin-check-attr.c | 4 ++-- builtin-checkout-index.c | 2 +- builtin-checkout.c | 2 +- builtin-clean.c | 3 ++- builtin-clone.c | 2 +- builtin-commit.c | 3 ++- builtin-config.c | 3 ++- builtin-count-objects.c | 2 +- builtin-describe.c | 2 +- builtin-fast-export.c | 2 +- builtin-fetch.c | 2 +- builtin-fmt-merge-msg.c | 3 ++- builtin-for-each-ref.c | 2 +- builtin-fsck.c | 2 +- builtin-gc.c | 3 ++- builtin-grep.c | 2 +- builtin-help.c | 2 +- builtin-log.c | 2 +- builtin-ls-files.c | 2 +- builtin-merge-base.c | 2 +- builtin-merge-file.c | 2 +- builtin-merge.c | 4 ++-- builtin-mktree.c | 2 +- builtin-mv.c | 3 ++- builtin-name-rev.c | 2 +- builtin-pack-refs.c | 2 +- builtin-prune.c | 2 +- builtin-push.c | 2 +- builtin-remote.c | 16 ++++++++++------ builtin-reset.c | 2 +- builtin-rev-parse.c | 4 ++-- builtin-revert.c | 2 +- builtin-rm.c | 3 ++- builtin-shortlog.c | 2 +- builtin-show-branch.c | 2 +- builtin-symbolic-ref.c | 3 ++- builtin-tag.c | 2 +- builtin-update-ref.c | 3 ++- hash-object.c | 3 ++- parse-options.c | 11 +++++++---- parse-options.h | 6 ++++-- test-parse-options.c | 2 +- 51 files changed, 86 insertions(+), 64 deletions(-) (limited to 'builtin-commit.c') diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index b43458eae6..aace5801ca 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -60,13 +60,13 @@ Steps to parse options . in `cmd_foo(int argc, const char **argv, const char *prefix)` call - argc = parse_options(argc, argv, builtin_foo_options, builtin_foo_usage, flags); + argc = parse_options(argc, argv, prefix, builtin_foo_options, builtin_foo_usage, flags); + `parse_options()` will filter out the processed options of `argv[]` and leave the non-option arguments in `argv[]`. `argc` is updated appropriately because of the assignment. + -You can also pass NULL instead of a usage array as fourth parameter of +You can also pass NULL instead of a usage array as the fifth parameter of parse_options(), to avoid displaying a help screen with usage info and option list. This should only be done if necessary, e.g. to implement a limited parser for only a subset of the options that needs to be run diff --git a/archive.c b/archive.c index b2b90d3170..0bca9ca403 100644 --- a/archive.c +++ b/archive.c @@ -309,7 +309,7 @@ static int parse_archive_args(int argc, const char **argv, OPT_END() }; - argc = parse_options(argc, argv, opts, archive_usage, 0); + argc = parse_options(argc, argv, NULL, opts, archive_usage, 0); if (remote) die("Unexpected option --remote"); diff --git a/builtin-add.c b/builtin-add.c index bee45f00de..c1b229a9d8 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -298,7 +298,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) int add_new_files; int require_pathspec; - argc = parse_options(argc, argv, builtin_add_options, + argc = parse_options(argc, argv, prefix, builtin_add_options, builtin_add_usage, PARSE_OPT_KEEP_ARGV0); if (patch_interactive) add_interactive = 1; diff --git a/builtin-apply.c b/builtin-apply.c index a40b982242..bac03d7902 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -3313,7 +3313,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) if (apply_default_whitespace) parse_whitespace_option(apply_default_whitespace); - argc = parse_options(argc, argv, builtin_apply_options, + argc = parse_options(argc, argv, prefix, builtin_apply_options, apply_usage, 0); fake_ancestor = parse_options_fix_filename(prefix, fake_ancestor); if (fake_ancestor) diff --git a/builtin-archive.c b/builtin-archive.c index ab50cebba0..3c5a5a7822 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -80,7 +80,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix) OPT_END() }; - argc = parse_options(argc, argv, local_opts, NULL, PARSE_OPT_KEEP_ALL); + argc = parse_options(argc, argv, prefix, local_opts, NULL, + PARSE_OPT_KEEP_ALL); if (output) create_output_file(output); diff --git a/builtin-bisect--helper.c b/builtin-bisect--helper.c index cb3e155116..5b226399e1 100644 --- a/builtin-bisect--helper.c +++ b/builtin-bisect--helper.c @@ -17,7 +17,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) OPT_END() }; - argc = parse_options(argc, argv, options, git_bisect_helper_usage, 0); + argc = parse_options(argc, argv, prefix, options, + git_bisect_helper_usage, 0); if (!next_all) usage_with_options(git_bisect_helper_usage, options); diff --git a/builtin-blame.c b/builtin-blame.c index cf74a92614..9dc3335910 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -2229,7 +2229,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) save_commit_buffer = 0; dashdash_pos = 0; - parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH | + parse_options_start(&ctx, argc, argv, prefix, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); for (;;) { switch (parse_options_step(&ctx, options, blame_opt_usage)) { diff --git a/builtin-branch.c b/builtin-branch.c index 6aaa708473..5687d6042c 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -610,7 +610,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) } hashcpy(merge_filter_ref, head_sha1); - argc = parse_options(argc, argv, options, builtin_branch_usage, 0); + argc = parse_options(argc, argv, prefix, options, builtin_branch_usage, + 0); if (!!delete + !!rename + !!force_create > 1) usage_with_options(builtin_branch_usage, options); diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 8fad19daed..991e40fb2e 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -231,7 +231,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) if (argc != 3 && argc != 2) usage_with_options(cat_file_usage, options); - argc = parse_options(argc, argv, options, cat_file_usage, 0); + argc = parse_options(argc, argv, prefix, options, cat_file_usage, 0); if (opt) { if (argc == 1) diff --git a/builtin-check-attr.c b/builtin-check-attr.c index 15a04b7179..8bd0430098 100644 --- a/builtin-check-attr.c +++ b/builtin-check-attr.c @@ -69,8 +69,8 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) int cnt, i, doubledash; const char *errstr = NULL; - argc = parse_options(argc, argv, check_attr_options, check_attr_usage, - PARSE_OPT_KEEP_DASHDASH); + argc = parse_options(argc, argv, prefix, check_attr_options, + check_attr_usage, PARSE_OPT_KEEP_DASHDASH); if (!argc) usage_with_options(check_attr_usage, check_attr_options); diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c index afe35e246c..a7a5ee10f3 100644 --- a/builtin-checkout-index.c +++ b/builtin-checkout-index.c @@ -249,7 +249,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) die("invalid cache"); } - argc = parse_options(argc, argv, builtin_checkout_index_options, + argc = parse_options(argc, argv, prefix, builtin_checkout_index_options, builtin_checkout_index_usage, 0); state.force = force; state.quiet = quiet; diff --git a/builtin-checkout.c b/builtin-checkout.c index b8a4b0139b..8a9a474218 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -605,7 +605,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) opts.track = BRANCH_TRACK_UNSPECIFIED; - argc = parse_options(argc, argv, options, checkout_usage, + argc = parse_options(argc, argv, prefix, options, checkout_usage, PARSE_OPT_KEEP_DASHDASH); /* --track without -b should DWIM */ diff --git a/builtin-clean.c b/builtin-clean.c index c5ad33d3e6..1c1b6d26e9 100644 --- a/builtin-clean.c +++ b/builtin-clean.c @@ -56,7 +56,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix) else config_set = 1; - argc = parse_options(argc, argv, options, builtin_clean_usage, 0); + argc = parse_options(argc, argv, prefix, options, builtin_clean_usage, + 0); memset(&dir, 0, sizeof(dir)); if (ignored_only) diff --git a/builtin-clone.c b/builtin-clone.c index c935833c6c..5c46496a43 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -360,7 +360,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) junk_pid = getpid(); - argc = parse_options(argc, argv, builtin_clone_options, + argc = parse_options(argc, argv, prefix, builtin_clone_options, builtin_clone_usage, 0); if (argc == 0) diff --git a/builtin-commit.c b/builtin-commit.c index baaa75cf90..b9a1528c9d 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -697,7 +697,8 @@ static int parse_and_validate_options(int argc, const char *argv[], { int f = 0; - argc = parse_options(argc, argv, builtin_commit_options, usage, 0); + argc = parse_options(argc, argv, prefix, builtin_commit_options, usage, + 0); logfile = parse_options_fix_filename(prefix, logfile); if (logfile) logfile = xstrdup(logfile); diff --git a/builtin-config.c b/builtin-config.c index a81bc8bbf0..60915f91ca 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -316,7 +316,8 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix) config_exclusive_filename = getenv(CONFIG_ENVIRONMENT); - argc = parse_options(argc, argv, builtin_config_options, builtin_config_usage, + argc = parse_options(argc, argv, prefix, builtin_config_options, + builtin_config_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (use_global_config + use_system_config + !!given_config_file > 1) { diff --git a/builtin-count-objects.c b/builtin-count-objects.c index b814fe5070..1b0b6c84ea 100644 --- a/builtin-count-objects.c +++ b/builtin-count-objects.c @@ -83,7 +83,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) OPT_END(), }; - argc = parse_options(argc, argv, opts, count_objects_usage, 0); + argc = parse_options(argc, argv, prefix, opts, count_objects_usage, 0); /* we do not take arguments other than flags for now */ if (argc) usage_with_options(count_objects_usage, opts); diff --git a/builtin-describe.c b/builtin-describe.c index 63c6a19da5..7a662980d1 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -322,7 +322,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) OPT_END(), }; - argc = parse_options(argc, argv, options, describe_usage, 0); + argc = parse_options(argc, argv, prefix, options, describe_usage, 0); if (max_candidates < 0) max_candidates = 0; else if (max_candidates > MAX_TAGS) diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 6731713223..6cef810312 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -515,7 +515,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) init_revisions(&revs, prefix); argc = setup_revisions(argc, argv, &revs, NULL); - argc = parse_options(argc, argv, options, fast_export_usage, 0); + argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0); if (argc > 1) usage_with_options (fast_export_usage, options); diff --git a/builtin-fetch.c b/builtin-fetch.c index 77acabfcc7..0ed6016da1 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -634,7 +634,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) for (i = 1; i < argc; i++) strbuf_addf(&default_rla, " %s", argv[i]); - argc = parse_options(argc, argv, + argc = parse_options(argc, argv, prefix, builtin_fetch_options, builtin_fetch_usage, 0); if (argc == 0) diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index fae1482ba9..d4c7206142 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -360,7 +360,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) int ret; git_config(fmt_merge_msg_config, NULL); - argc = parse_options(argc, argv, options, fmt_merge_msg_usage, 0); + argc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage, + 0); if (argc > 0) usage_with_options(fmt_merge_msg_usage, options); inpath = parse_options_fix_filename(prefix, inpath); diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index d091e04af9..784733b25d 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -905,7 +905,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) OPT_END(), }; - parse_options(argc, argv, opts, for_each_ref_usage, 0); + parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); if (maxcount < 0) { error("invalid --count argument: `%d'", maxcount); usage_with_options(for_each_ref_usage, opts); diff --git a/builtin-fsck.c b/builtin-fsck.c index 6436bc2248..7da706cac3 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -590,7 +590,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) errors_found = 0; - argc = parse_options(argc, argv, fsck_opts, fsck_usage, 0); + argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0); if (write_lost_and_found) { check_full = 1; include_reflogs = 0; diff --git a/builtin-gc.c b/builtin-gc.c index fc556ed7f3..7d3e9cc7a0 100644 --- a/builtin-gc.c +++ b/builtin-gc.c @@ -194,7 +194,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix) if (pack_refs < 0) pack_refs = !is_bare_repository(); - argc = parse_options(argc, argv, builtin_gc_options, builtin_gc_usage, 0); + argc = parse_options(argc, argv, prefix, builtin_gc_options, + builtin_gc_usage, 0); if (argc > 0) usage_with_options(builtin_gc_usage, builtin_gc_options); diff --git a/builtin-grep.c b/builtin-grep.c index 5308b346e6..73fc922c49 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -765,7 +765,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) * unrecognized non option is the beginning of the refs list * that continues up to the -- (if exists), and then paths. */ - argc = parse_options(argc, argv, options, grep_usage, + argc = parse_options(argc, argv, prefix, options, grep_usage, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_STOP_AT_NON_OPTION | PARSE_OPT_NO_INTERNAL_HELP); diff --git a/builtin-help.c b/builtin-help.c index 67dda3e6e6..af565fb658 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -423,7 +423,7 @@ int cmd_help(int argc, const char **argv, const char *prefix) setup_git_directory_gently(&nongit); git_config(git_help_config, NULL); - argc = parse_options(argc, argv, builtin_help_options, + argc = parse_options(argc, argv, prefix, builtin_help_options, builtin_help_usage, 0); if (show_all) { diff --git a/builtin-log.c b/builtin-log.c index 5d39565e94..ea8dbc8698 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -936,7 +936,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) * like "git format-patch -o a123 HEAD^.." may fail; a123 is * possibly a valid SHA1. */ - argc = parse_options(argc, argv, builtin_format_patch_options, + argc = parse_options(argc, argv, prefix, builtin_format_patch_options, builtin_format_patch_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 3d59b0e140..2312866605 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -486,7 +486,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) prefix_offset = strlen(prefix); git_config(git_default_config, NULL); - argc = parse_options(argc, argv, builtin_ls_files_options, + argc = parse_options(argc, argv, prefix, builtin_ls_files_options, ls_files_usage, 0); if (show_tag || show_valid_bit) { tag_cached = "H "; diff --git a/builtin-merge-base.c b/builtin-merge-base.c index 03fc1c2114..a6ec2f7ab7 100644 --- a/builtin-merge-base.c +++ b/builtin-merge-base.c @@ -53,7 +53,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix) }; git_config(git_default_config, NULL); - argc = parse_options(argc, argv, options, merge_base_usage, 0); + argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); if (argc < 2) usage_with_options(merge_base_usage, options); rev = xmalloc(argc * sizeof(*rev)); diff --git a/builtin-merge-file.c b/builtin-merge-file.c index 96edb97a83..afd2ea7a73 100644 --- a/builtin-merge-file.c +++ b/builtin-merge-file.c @@ -48,7 +48,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) merge_style = git_xmerge_style; } - argc = parse_options(argc, argv, options, merge_file_usage, 0); + argc = parse_options(argc, argv, prefix, options, merge_file_usage, 0); if (argc != 3) usage_with_options(merge_file_usage, options); if (quiet) { diff --git a/builtin-merge.c b/builtin-merge.c index 0b58e5eda1..8d101eff0b 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -462,7 +462,7 @@ static int git_merge_config(const char *k, const char *v, void *cb) argv = xrealloc(argv, sizeof(*argv) * (argc + 2)); memmove(argv + 1, argv, sizeof(*argv) * (argc + 1)); argc++; - parse_options(argc, argv, builtin_merge_options, + parse_options(argc, argv, NULL, builtin_merge_options, builtin_merge_usage, 0); free(buf); } @@ -855,7 +855,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (diff_use_color_default == -1) diff_use_color_default = git_use_color_default; - argc = parse_options(argc, argv, builtin_merge_options, + argc = parse_options(argc, argv, prefix, builtin_merge_options, builtin_merge_usage, 0); if (verbosity < 0) show_diffstat = 0; diff --git a/builtin-mktree.c b/builtin-mktree.c index dc4f1a711d..098395fda1 100644 --- a/builtin-mktree.c +++ b/builtin-mktree.c @@ -155,7 +155,7 @@ int cmd_mktree(int ac, const char **av, const char *prefix) OPT_END() }; - ac = parse_options(ac, av, option, mktree_usage, 0); + ac = parse_options(ac, av, prefix, option, mktree_usage, 0); while (!got_eof) { while (1) { diff --git a/builtin-mv.c b/builtin-mv.c index 01270fefdf..8b81d4b51d 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -72,7 +72,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die("index file corrupt"); - argc = parse_options(argc, argv, builtin_mv_options, builtin_mv_usage, 0); + argc = parse_options(argc, argv, prefix, builtin_mv_options, + builtin_mv_usage, 0); if (--argc < 1) usage_with_options(builtin_mv_usage, builtin_mv_options); diff --git a/builtin-name-rev.c b/builtin-name-rev.c index 08c8aabf94..06a38ac8c1 100644 --- a/builtin-name-rev.c +++ b/builtin-name-rev.c @@ -238,7 +238,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) }; git_config(git_default_config, NULL); - argc = parse_options(argc, argv, opts, name_rev_usage, 0); + argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0); if (!!all + !!transform_stdin + !!argc > 1) { error("Specify either a list, or --all, not both!"); usage_with_options(name_rev_usage, opts); diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c index 34246df4ec..091860b2e3 100644 --- a/builtin-pack-refs.c +++ b/builtin-pack-refs.c @@ -15,7 +15,7 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix) OPT_BIT(0, "prune", &flags, "prune loose refs (default)", PACK_REFS_PRUNE), OPT_END(), }; - if (parse_options(argc, argv, opts, pack_refs_usage, 0)) + if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0)) usage_with_options(pack_refs_usage, opts); return pack_refs(flags); } diff --git a/builtin-prune.c b/builtin-prune.c index 145ba83651..0ed9cce4a2 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -142,7 +142,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix) save_commit_buffer = 0; init_revisions(&revs, prefix); - argc = parse_options(argc, argv, options, prune_usage, 0); + argc = parse_options(argc, argv, prefix, options, prune_usage, 0); while (argc--) { unsigned char sha1[20]; const char *name = *argv++; diff --git a/builtin-push.c b/builtin-push.c index 2eabcd3bdf..c869974013 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -198,7 +198,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_END() }; - argc = parse_options(argc, argv, options, push_usage, 0); + argc = parse_options(argc, argv, prefix, options, push_usage, 0); if (tags) add_refspec("refs/tags/*"); diff --git a/builtin-remote.c b/builtin-remote.c index 71abf68404..13d5db168a 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -79,7 +79,8 @@ static int add(int argc, const char **argv) OPT_END() }; - argc = parse_options(argc, argv, options, builtin_remote_usage, 0); + argc = parse_options(argc, argv, NULL, options, builtin_remote_usage, + 0); if (argc < 2) usage_with_options(builtin_remote_usage, options); @@ -986,7 +987,8 @@ static int show(int argc, const char **argv) struct string_list info_list = { NULL, 0, 0, 0 }; struct show_info info; - argc = parse_options(argc, argv, options, builtin_remote_usage, 0); + argc = parse_options(argc, argv, NULL, options, builtin_remote_usage, + 0); if (argc < 1) return show_all(); @@ -1076,7 +1078,8 @@ static int set_head(int argc, const char **argv) "delete refs/remotes//HEAD"), OPT_END() }; - argc = parse_options(argc, argv, options, builtin_remote_usage, 0); + argc = parse_options(argc, argv, NULL, options, builtin_remote_usage, + 0); if (argc) strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]); @@ -1130,7 +1133,8 @@ static int prune(int argc, const char **argv) OPT_END() }; - argc = parse_options(argc, argv, options, builtin_remote_usage, 0); + argc = parse_options(argc, argv, NULL, options, builtin_remote_usage, + 0); if (argc < 1) usage_with_options(builtin_remote_usage, options); @@ -1220,7 +1224,7 @@ static int update(int argc, const char **argv) OPT_END() }; - argc = parse_options(argc, argv, options, builtin_remote_usage, + argc = parse_options(argc, argv, NULL, options, builtin_remote_usage, PARSE_OPT_KEEP_ARGV0); if (argc < 2) { argc = 2; @@ -1306,7 +1310,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix) }; int result; - argc = parse_options(argc, argv, options, builtin_remote_usage, + argc = parse_options(argc, argv, prefix, options, builtin_remote_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (argc < 1) diff --git a/builtin-reset.c b/builtin-reset.c index 7e7ebabaa8..5fa1789d0c 100644 --- a/builtin-reset.c +++ b/builtin-reset.c @@ -203,7 +203,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); - argc = parse_options(argc, argv, options, git_reset_usage, + argc = parse_options(argc, argv, prefix, options, git_reset_usage, PARSE_OPT_KEEP_DASHDASH); reflog_action = args_to_str(argv); setenv("GIT_REFLOG_ACTION", reflog_action, 0); diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index c5b3d6e31b..112d622cda 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -318,7 +318,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) int onb = 0, osz = 0, unb = 0, usz = 0; strbuf_addstr(&parsed, "set --"); - argc = parse_options(argc, argv, parseopt_opts, parseopt_usage, + argc = parse_options(argc, argv, prefix, parseopt_opts, parseopt_usage, PARSE_OPT_KEEP_DASHDASH); if (argc < 1 || strcmp(argv[0], "--")) usage_with_options(parseopt_usage, parseopt_opts); @@ -393,7 +393,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) /* put an OPT_END() */ ALLOC_GROW(opts, onb + 1, osz); memset(opts + onb, 0, sizeof(opts[onb])); - argc = parse_options(argc, argv, opts, usage, + argc = parse_options(argc, argv, prefix, opts, usage, keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0); strbuf_addf(&parsed, " --"); diff --git a/builtin-revert.c b/builtin-revert.c index 3f2614e1bb..fa4752fd20 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -60,7 +60,7 @@ static void parse_args(int argc, const char **argv) OPT_END(), }; - if (parse_options(argc, argv, options, usage_str, 0) != 1) + if (parse_options(argc, argv, NULL, options, usage_str, 0) != 1) usage_with_options(usage_str, options); arg = argv[0]; diff --git a/builtin-rm.c b/builtin-rm.c index 269d60890a..0cc4912718 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -157,7 +157,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); - argc = parse_options(argc, argv, builtin_rm_options, builtin_rm_usage, 0); + argc = parse_options(argc, argv, prefix, builtin_rm_options, + builtin_rm_usage, 0); if (!argc) usage_with_options(builtin_rm_usage, builtin_rm_options); diff --git a/builtin-shortlog.c b/builtin-shortlog.c index b28091b445..6a3812ee18 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -263,7 +263,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); shortlog_init(&log); init_revisions(&rev, prefix); - parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH | + parse_options_start(&ctx, argc, argv, prefix, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); for (;;) { diff --git a/builtin-show-branch.c b/builtin-show-branch.c index b1affd2ffb..9433811956 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -697,7 +697,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) av = default_arg - 1; /* ick; we would not address av[0] */ } - ac = parse_options(ac, av, builtin_show_branch_options, + ac = parse_options(ac, av, prefix, builtin_show_branch_options, show_branch_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (all_heads) all_remotes = 1; diff --git a/builtin-symbolic-ref.c b/builtin-symbolic-ref.c index 6ae6bcc0e8..ca855a5eb2 100644 --- a/builtin-symbolic-ref.c +++ b/builtin-symbolic-ref.c @@ -36,7 +36,8 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) }; git_config(git_default_config, NULL); - argc = parse_options(argc, argv, options, git_symbolic_ref_usage, 0); + argc = parse_options(argc, argv, prefix, options, + git_symbolic_ref_usage, 0); if (msg &&!*msg) die("Refusing to perform update with empty message"); switch (argc) { diff --git a/builtin-tag.c b/builtin-tag.c index e544430094..6e8b464109 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -405,7 +405,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) git_config(git_tag_config, NULL); - argc = parse_options(argc, argv, options, git_tag_usage, 0); + argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0); msgfile = parse_options_fix_filename(prefix, msgfile); if (keyid) { diff --git a/builtin-update-ref.c b/builtin-update-ref.c index 378dc1b7a6..76ba1d5881 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -23,7 +23,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) }; git_config(git_default_config, NULL); - argc = parse_options(argc, argv, options, git_update_ref_usage, 0); + argc = parse_options(argc, argv, prefix, options, git_update_ref_usage, + 0); if (msg && !*msg) die("Refusing to perform update with empty message."); diff --git a/hash-object.c b/hash-object.c index ebb3bedb07..47cf43c3cd 100644 --- a/hash-object.c +++ b/hash-object.c @@ -84,7 +84,8 @@ int main(int argc, const char **argv) git_extract_argv0_path(argv[0]); - argc = parse_options(argc, argv, hash_object_options, hash_object_usage, 0); + argc = parse_options(argc, argv, NULL, hash_object_options, + hash_object_usage, 0); if (write_object) { prefix = setup_git_directory(); diff --git a/parse-options.c b/parse-options.c index 1d25b94c72..be1800d7b4 100644 --- a/parse-options.c +++ b/parse-options.c @@ -285,12 +285,14 @@ static void check_typos(const char *arg, const struct option *options) } void parse_options_start(struct parse_opt_ctx_t *ctx, - int argc, const char **argv, int flags) + int argc, const char **argv, const char *prefix, + int flags) { memset(ctx, 0, sizeof(*ctx)); ctx->argc = argc - 1; ctx->argv = argv + 1; ctx->out = argv; + ctx->prefix = prefix; ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0); ctx->flags = flags; if ((flags & PARSE_OPT_KEEP_UNKNOWN) && @@ -389,12 +391,13 @@ int parse_options_end(struct parse_opt_ctx_t *ctx) return ctx->cpidx + ctx->argc; } -int parse_options(int argc, const char **argv, const struct option *options, - const char * const usagestr[], int flags) +int parse_options(int argc, const char **argv, const char *prefix, + const struct option *options, const char * const usagestr[], + int flags) { struct parse_opt_ctx_t ctx; - parse_options_start(&ctx, argc, argv, flags); + parse_options_start(&ctx, argc, argv, prefix, flags); switch (parse_options_step(&ctx, options, usagestr)) { case PARSE_OPT_HELP: exit(129); diff --git a/parse-options.h b/parse-options.h index fe41ab2c67..f652c0f3c7 100644 --- a/parse-options.h +++ b/parse-options.h @@ -122,7 +122,7 @@ struct option { * non-option arguments in argv[]. * Returns the number of arguments left in argv[]. */ -extern int parse_options(int argc, const char **argv, +extern int parse_options(int argc, const char **argv, const char *prefix, const struct option *options, const char * const usagestr[], int flags); @@ -148,13 +148,15 @@ struct parse_opt_ctx_t { int argc, cpidx; const char *opt; int flags; + const char *prefix; }; extern int parse_options_usage(const char * const *usagestr, const struct option *opts); extern void parse_options_start(struct parse_opt_ctx_t *ctx, - int argc, const char **argv, int flags); + int argc, const char **argv, const char *prefix, + int flags); extern int parse_options_step(struct parse_opt_ctx_t *ctx, const struct option *options, diff --git a/test-parse-options.c b/test-parse-options.c index e0669dcb41..da3d6581d3 100644 --- a/test-parse-options.c +++ b/test-parse-options.c @@ -65,7 +65,7 @@ int main(int argc, const char **argv) }; int i; - argc = parse_options(argc, argv, options, usage, 0); + argc = parse_options(argc, argv, NULL, options, usage, 0); printf("boolean: %d\n", boolean); printf("integer: %u\n", integer); -- cgit v1.3 From df217ed6430efe444a09fffdafd39720ae3f9864 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 23 May 2009 11:53:13 -0700 Subject: parse-opts: add OPT_FILENAME and transition builtins Commit dbd0f5c (Files given on the command line are relative to $cwd, 2008-08-06) introduced parse_options_fix_filename() as a minimal fix. OPT_FILENAME is intended to be a more robust fix for the same issue. OPT_FILENAME and its associated enum OPTION_FILENAME are used to represent filename options within the parse options API. This option is similar to OPTION_STRING. If --no is prefixed to the option the filename is unset. If no argument is given and the default value is set, the filename is set to the default value. The difference is that the filename is prefixed with the prefix passed to parse_options() (or parse_options_start()). Update git-apply, git-commit, git-fmt-merge-msg, and git-tag to use OPT_FILENAME with their filename options. Also, rename parse_options_fix_filename() to fix_filename() as it is no longer extern. Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- Documentation/technical/api-parse-options.txt | 5 ++++ builtin-apply.c | 5 +--- builtin-commit.c | 10 ++------ builtin-fmt-merge-msg.c | 3 +-- builtin-tag.c | 3 +-- parse-options.c | 36 ++++++++++++++++++--------- parse-options.h | 5 ++-- t/t0040-parse-options.sh | 19 ++++++++++++-- test-parse-options.c | 6 ++++- 9 files changed, 59 insertions(+), 33 deletions(-) (limited to 'builtin-commit.c') diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index aace5801ca..50f9e9ac17 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -167,6 +167,11 @@ There are some macros to easily define options: and the result will be put into `var`. See 'Option Callbacks' below for a more elaborate description. +`OPT_FILENAME(short, long, &var, description)`:: + Introduce an option with a filename argument. + The filename will be prefixed by passing the filename along with + the prefix argument of `parse_options()` to `prefix_filename()`. + `OPT_ARGUMENT(long, description)`:: Introduce a long-option argument that will be kept in `argv[]`. diff --git a/builtin-apply.c b/builtin-apply.c index bac03d7902..5329186266 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -3278,7 +3278,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) "apply a patch without touching the working tree"), OPT_BOOLEAN(0, "apply", &force_apply, "also apply the patch (use with --stat/--summary/--check)"), - OPT_STRING(0, "build-fake-ancestor", &fake_ancestor, "file", + OPT_FILENAME(0, "build-fake-ancestor", &fake_ancestor, "build a temporary index based on embedded index information"), { OPTION_CALLBACK, 'z', NULL, NULL, NULL, "paths are separated with NUL character", @@ -3315,9 +3315,6 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) argc = parse_options(argc, argv, prefix, builtin_apply_options, apply_usage, 0); - fake_ancestor = parse_options_fix_filename(prefix, fake_ancestor); - if (fake_ancestor) - fake_ancestor = xstrdup(fake_ancestor); if (apply_with_reject) apply = apply_verbosely = 1; diff --git a/builtin-commit.c b/builtin-commit.c index b9a1528c9d..41e222d267 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -88,13 +88,13 @@ static struct option builtin_commit_options[] = { OPT__VERBOSE(&verbose), OPT_GROUP("Commit message options"), - OPT_STRING('F', "file", &logfile, "FILE", "read log from file"), + OPT_FILENAME('F', "file", &logfile, "read log from file"), OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"), OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m), OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit "), OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"), OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), - OPT_STRING('t', "template", &template_file, "FILE", "use specified template file"), + OPT_FILENAME('t', "template", &template_file, "use specified template file"), OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"), OPT_GROUP("Commit contents options"), @@ -699,12 +699,6 @@ static int parse_and_validate_options(int argc, const char *argv[], argc = parse_options(argc, argv, prefix, builtin_commit_options, usage, 0); - logfile = parse_options_fix_filename(prefix, logfile); - if (logfile) - logfile = xstrdup(logfile); - template_file = parse_options_fix_filename(prefix, template_file); - if (template_file) - template_file = xstrdup(template_file); if (force_author && !strchr(force_author, '>')) force_author = find_author_by_nickname(force_author); diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index d4c7206142..fbf9582e66 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -351,7 +351,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) struct option options[] = { OPT_BOOLEAN(0, "log", &merge_summary, "populate log with the shortlog"), OPT_BOOLEAN(0, "summary", &merge_summary, "alias for --log"), - OPT_STRING('F', "file", &inpath, "file", "file to read from"), + OPT_FILENAME('F', "file", &inpath, "file to read from"), OPT_END() }; @@ -364,7 +364,6 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) 0); if (argc > 0) usage_with_options(fmt_merge_msg_usage, options); - inpath = parse_options_fix_filename(prefix, inpath); if (inpath && strcmp(inpath, "-")) { in = fopen(inpath, "r"); diff --git a/builtin-tag.c b/builtin-tag.c index 6e8b464109..dc3db62811 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -387,7 +387,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) "annotated tag, needs a message"), OPT_CALLBACK('m', NULL, &msg, "msg", "message for the tag", parse_msg_arg), - OPT_STRING('F', NULL, &msgfile, "file", "message in a file"), + OPT_FILENAME('F', NULL, &msgfile, "message in a file"), OPT_BOOLEAN('s', NULL, &sign, "annotated and GPG-signed tag"), OPT_STRING('u', NULL, &keyid, "key-id", "use another key to sign the tag"), @@ -406,7 +406,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix) git_config(git_tag_config, NULL); argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0); - msgfile = parse_options_fix_filename(prefix, msgfile); if (keyid) { sign = 1; diff --git a/parse-options.c b/parse-options.c index be1800d7b4..b85cab2466 100644 --- a/parse-options.c +++ b/parse-options.c @@ -31,11 +31,20 @@ static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, return 0; } +static void fix_filename(const char *prefix, const char **file) +{ + if (!file || !*file || !prefix || is_absolute_path(*file) + || !strcmp("-", *file)) + return; + *file = xstrdup(prefix_filename(prefix, strlen(prefix), *file)); +} + static int get_value(struct parse_opt_ctx_t *p, const struct option *opt, int flags) { const char *s, *arg; const int unset = flags & OPT_UNSET; + int err; if (unset && p->opt) return opterror(opt, "takes no value", flags); @@ -95,6 +104,19 @@ static int get_value(struct parse_opt_ctx_t *p, return get_arg(p, opt, flags, (const char **)opt->value); return 0; + case OPTION_FILENAME: + err = 0; + if (unset) + *(const char **)opt->value = NULL; + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) + *(const char **)opt->value = (const char *)opt->defval; + else + err = get_arg(p, opt, flags, (const char **)opt->value); + + if (!err) + fix_filename(p->prefix, (const char **)opt->value); + return err; + case OPTION_CALLBACK: if (unset) return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; @@ -494,6 +516,8 @@ int usage_with_options_internal(const char * const *usagestr, if (opts->flags & PARSE_OPT_NOARG) break; /* FALLTHROUGH */ + case OPTION_FILENAME: + /* FALLTHROUGH */ case OPTION_STRING: if (opts->argh) pos += usage_argh(opts); @@ -604,15 +628,3 @@ int parse_opt_with_commit(const struct option *opt, const char *arg, int unset) commit_list_insert(commit, opt->value); return 0; } - -/* - * This should really be OPTION_FILENAME type as a part of - * parse_options that take prefix to do this while parsing. - */ -extern const char *parse_options_fix_filename(const char *prefix, const char *file) -{ - if (!file || !prefix || is_absolute_path(file) || !strcmp("-", file)) - return file; - return prefix_filename(prefix, strlen(prefix), file); -} - diff --git a/parse-options.h b/parse-options.h index f652c0f3c7..b374ade95c 100644 --- a/parse-options.h +++ b/parse-options.h @@ -17,6 +17,7 @@ enum parse_opt_type { OPTION_STRING, OPTION_INTEGER, OPTION_CALLBACK, + OPTION_FILENAME }; enum parse_opt_flags { @@ -117,6 +118,8 @@ struct option { #define OPT_NUMBER_CALLBACK(v, h, f) \ { OPTION_NUMBER, 0, NULL, (v), NULL, (h), \ PARSE_OPT_NOARG | PARSE_OPT_NONEG, (f) } +#define OPT_FILENAME(s, l, v, h) { OPTION_FILENAME, (s), (l), (v), \ + "FILE", (h) } /* parse_options() will filter out the processed options and leave the * non-option arguments in argv[]. @@ -184,6 +187,4 @@ extern int parse_opt_with_commit(const struct option *, const char *, int); "use digits to display SHA-1s", \ PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 } -extern const char *parse_options_fix_filename(const char *prefix, const char *file); - #endif diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index a40c1236c0..bbc821ef97 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -19,6 +19,7 @@ usage: test-parse-options --set23 set integer to 23 -t