diff options
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/add.c | 5 | ||||
-rw-r--r-- | builtin/apply.c | 23 | ||||
-rw-r--r-- | builtin/blame.c | 3 | ||||
-rw-r--r-- | builtin/branch.c | 50 | ||||
-rw-r--r-- | builtin/checkout.c | 25 | ||||
-rw-r--r-- | builtin/clone.c | 8 | ||||
-rw-r--r-- | builtin/commit.c | 33 | ||||
-rw-r--r-- | builtin/config.c | 29 | ||||
-rw-r--r-- | builtin/describe.c | 10 | ||||
-rw-r--r-- | builtin/diff.c | 14 | ||||
-rw-r--r-- | builtin/fast-export.c | 4 | ||||
-rw-r--r-- | builtin/fetch.c | 6 | ||||
-rw-r--r-- | builtin/fsck.c | 31 | ||||
-rw-r--r-- | builtin/grep.c | 5 | ||||
-rw-r--r-- | builtin/index-pack.c | 6 | ||||
-rw-r--r-- | builtin/init-db.c | 14 | ||||
-rw-r--r-- | builtin/log.c | 42 | ||||
-rw-r--r-- | builtin/merge.c | 39 | ||||
-rw-r--r-- | builtin/notes.c | 16 | ||||
-rw-r--r-- | builtin/patch-id.c | 2 | ||||
-rw-r--r-- | builtin/push.c | 10 | ||||
-rw-r--r-- | builtin/read-tree.c | 4 | ||||
-rw-r--r-- | builtin/tag.c | 6 |
23 files changed, 229 insertions, 156 deletions
diff --git a/builtin/add.c b/builtin/add.c index 12b964e642..1d74763f58 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -21,8 +21,7 @@ static const char * const builtin_add_usage[] = { static int patch_interactive, add_interactive, edit_interactive; static int take_worktree_changes; -struct update_callback_data -{ +struct update_callback_data { int flags; int add_errors; }; @@ -317,7 +316,7 @@ static struct option builtin_add_options[] = { OPT__VERBOSE(&verbose, "be verbose"), OPT_GROUP(""), OPT_BOOLEAN('i', "interactive", &add_interactive, "interactive picking"), - OPT_BOOLEAN('p', "patch", &patch_interactive, "interactive patching"), + OPT_BOOLEAN('p', "patch", &patch_interactive, "select hunks interactively"), OPT_BOOLEAN('e', "edit", &edit_interactive, "edit current diff and apply"), OPT__FORCE(&ignored_too, "allow adding otherwise ignored files"), OPT_BOOLEAN('u', "update", &take_worktree_changes, "update tracked files"), diff --git a/builtin/apply.c b/builtin/apply.c index 14951daedf..36e150768b 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -204,6 +204,7 @@ struct line { unsigned hash : 24; unsigned flag : 8; #define LINE_COMMON 1 +#define LINE_PATCHED 2 }; /* @@ -2085,7 +2086,8 @@ static int match_fragment(struct image *img, /* Quick hash check */ for (i = 0; i < preimage_limit; i++) - if (preimage->line[i].hash != img->line[try_lno + i].hash) + if ((img->line[try_lno + i].flag & LINE_PATCHED) || + (preimage->line[i].hash != img->line[try_lno + i].hash)) return 0; if (preimage_limit == preimage->nr) { @@ -2428,11 +2430,15 @@ static void update_image(struct image *img, memcpy(img->line + applied_pos, postimage->line, postimage->nr * sizeof(*img->line)); + for (i = 0; i < postimage->nr; i++) + img->line[applied_pos + i].flag |= LINE_PATCHED; + img->nr = nr; } static int apply_one_fragment(struct image *img, struct fragment *frag, - int inaccurate_eof, unsigned ws_rule) + int inaccurate_eof, unsigned ws_rule, + int nth_fragment) { int match_beginning, match_end; const char *patch = frag->patch; @@ -2638,6 +2644,15 @@ static int apply_one_fragment(struct image *img, struct fragment *frag, apply = 0; } + if (apply_verbosely && applied_pos != pos) { + int offset = applied_pos - pos; + if (apply_in_reverse) + offset = 0 - offset; + fprintf(stderr, + "Hunk #%d succeeded at %d (offset %d lines).\n", + nth_fragment, applied_pos + 1, offset); + } + /* * Warn if it was necessary to reduce the number * of context lines. @@ -2785,12 +2800,14 @@ static int apply_fragments(struct image *img, struct patch *patch) const char *name = patch->old_name ? patch->old_name : patch->new_name; unsigned ws_rule = patch->ws_rule; unsigned inaccurate_eof = patch->inaccurate_eof; + int nth = 0; if (patch->is_binary) return apply_binary(img, patch); while (frag) { - if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule)) { + nth++; + if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) { error("patch failed: %s:%ld", name, frag->oldpos); if (!apply_with_reject) return -1; diff --git a/builtin/blame.c b/builtin/blame.c index aa30ec5269..f6b03f750a 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1312,8 +1312,7 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt) /* * Information on commits, used for output. */ -struct commit_info -{ +struct commit_info { const char *author; const char *author_mail; unsigned long author_time; diff --git a/builtin/branch.c b/builtin/branch.c index 9e546e4a83..b9ba011f7b 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -134,7 +134,7 @@ static int branch_merged(int kind, const char *name, in_merge_bases(rev, &head_rev, 1) != merged) { if (merged) warning("deleting branch '%s' that has been merged to\n" - " '%s', but it is not yet merged to HEAD.", + " '%s', but not yet been merged to HEAD.", name, reference_name); else warning("not deleting branch '%s' that is not yet merged to\n" @@ -390,6 +390,30 @@ static int matches_merge_filter(struct commit *commit) return (is_merged == (merge_filter == SHOW_MERGED)); } +static void add_verbose_info(struct strbuf *out, struct ref_item *item, + int verbose, int abbrev) +{ + struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT; + const char *sub = " **** invalid ref ****"; + struct commit *commit = item->commit; + + if (commit && !parse_commit(commit)) { + struct pretty_print_context ctx = {0}; + pretty_print_commit(CMIT_FMT_ONELINE, commit, + &subject, &ctx); + sub = subject.buf; + } + + if (item->kind == REF_LOCAL_BRANCH) + fill_tracking_info(&stat, item->name, verbose > 1); + + strbuf_addf(out, " %s %s%s", + find_unique_abbrev(item->commit->object.sha1, abbrev), + stat.buf, sub); + strbuf_release(&stat); + strbuf_release(&subject); +} + static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, int abbrev, int current, char *prefix) { @@ -430,27 +454,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, if (item->dest) strbuf_addf(&out, " -> %s", item->dest); - else if (verbose) { - struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT; - const char *sub = " **** invalid ref ****"; - - commit = item->commit; - if (commit && !parse_commit(commit)) { - struct pretty_print_context ctx = {0}; - pretty_print_commit(CMIT_FMT_ONELINE, commit, - &subject, &ctx); - sub = subject.buf; - } - - if (item->kind == REF_LOCAL_BRANCH) - fill_tracking_info(&stat, item->name, verbose > 1); - - strbuf_addf(&out, " %s %s%s", - find_unique_abbrev(item->commit->object.sha1, abbrev), - stat.buf, sub); - strbuf_release(&stat); - strbuf_release(&subject); - } + else if (verbose) + /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */ + add_verbose_info(&out, item, verbose, abbrev); printf("%s\n", out.buf); strbuf_release(&name); strbuf_release(&out); diff --git a/builtin/checkout.c b/builtin/checkout.c index 757f9a08dd..e98576f22e 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -404,7 +404,7 @@ static int merge_working_tree(struct checkout_opts *opts, topts.dir->exclude_per_dir = ".gitignore"; tree = parse_tree_indirect(old->commit ? old->commit->object.sha1 : - (unsigned char *)EMPTY_TREE_SHA1_BIN); + EMPTY_TREE_SHA1_BIN); init_tree_desc(&trees[0], tree->buffer, tree->size); tree = parse_tree_indirect(new->commit->object.sha1); init_tree_desc(&trees[1], tree->buffer, tree->size); @@ -678,7 +678,7 @@ static const char *unique_tracking_name(const char *name) int cmd_checkout(int argc, const char **argv, const char *prefix) { struct checkout_opts opts; - unsigned char rev[20]; + unsigned char rev[20], branch_rev[20]; const char *arg; struct branch_info new; struct tree *source_tree = NULL; @@ -832,18 +832,21 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) argc--; new.name = arg; - if ((new.commit = lookup_commit_reference_gently(rev, 1))) { - setup_branch_path(&new); + setup_branch_path(&new); - if ((check_ref_format(new.path) == CHECK_REF_FORMAT_OK) && - resolve_ref(new.path, rev, 1, NULL)) - ; - else - new.path = NULL; + if (check_ref_format(new.path) == CHECK_REF_FORMAT_OK && + resolve_ref(new.path, branch_rev, 1, NULL)) + hashcpy(rev, branch_rev); + else + new.path = NULL; /* not an existing branch */ + + if (!(new.commit = lookup_commit_reference_gently(rev, 1))) { + /* not a commit */ + source_tree = parse_tree_indirect(rev); + } else { parse_commit(new.commit); source_tree = new.commit->tree; - } else - source_tree = parse_tree_indirect(rev); + } if (!source_tree) /* case (1): want a tree */ die("reference is not a tree: %s", arg); diff --git a/builtin/clone.c b/builtin/clone.c index 61e0989b5a..2ee1fa9846 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -66,10 +66,10 @@ static struct option builtin_clone_options[] = { "setup as shared repository"), OPT_BOOLEAN(0, "recursive", &option_recursive, "initialize submodules in the clone"), - OPT_BOOLEAN(0, "recurse_submodules", &option_recursive, + OPT_BOOLEAN(0, "recurse-submodules", &option_recursive, "initialize submodules in the clone"), - OPT_STRING(0, "template", &option_template, "path", - "path the template repository"), + OPT_STRING(0, "template", &option_template, "template-directory", + "directory from which templates will be used"), OPT_STRING(0, "reference", &option_reference, "repo", "reference repository"), OPT_STRING('o', "origin", &option_origin, "branch", @@ -413,7 +413,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (path) repo = xstrdup(make_nonrelative_path(repo_name)); else if (!strchr(repo_name, ':')) - repo = xstrdup(make_absolute_path(repo_name)); + die("repository '%s' does not exist", repo_name); else repo = repo_name; is_local = path && !is_bundle; diff --git a/builtin/commit.c b/builtin/commit.c index 03cff5af63..6e32166a29 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -118,14 +118,14 @@ static struct option builtin_commit_options[] = { OPT__VERBOSE(&verbose, "show diff in commit message template"), OPT_GROUP("Commit message options"), - OPT_FILENAME('F', "file", &logfile, "read log from file"), - OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"), - OPT_STRING(0, "date", &force_date, "DATE", "override date 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_STRING(0, "fixup", &fixup_message, "COMMIT", "use autosquash formatted message to fixup specified commit"), - OPT_STRING(0, "squash", &squash_message, "COMMIT", "use autosquash formatted message to squash specified commit"), + OPT_FILENAME('F', "file", &logfile, "read message from file"), + OPT_STRING(0, "author", &force_author, "author", "override author for commit"), + OPT_STRING(0, "date", &force_date, "date", "override date for commit"), + OPT_CALLBACK('m', "message", &message, "message", "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_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"), + OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"), OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"), OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_FILENAME('t', "template", &template_file, "use specified template file"), @@ -145,12 +145,12 @@ static struct option builtin_commit_options[] = { STATUS_FORMAT_SHORT), OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"), OPT_SET_INT(0, "porcelain", &status_format, - "show porcelain output format", STATUS_FORMAT_PORCELAIN), + "machine-readable output", STATUS_FORMAT_PORCELAIN), OPT_BOOLEAN('z', "null", &null_termination, "terminate entries with NUL"), OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"), - { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, + { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, /* end commit contents options */ { OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL, @@ -634,7 +634,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0) die_errno("could not read SQUASH_MSG"); hook_arg1 = "squash"; - } else if (template_file && !stat(template_file, &statbuf)) { + } else if (template_file) { if (strbuf_read_file(&sb, template_file, 0) < 0) die_errno("could not read '%s'", template_file); hook_arg1 = "template"; @@ -1092,7 +1092,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) OPT_BOOLEAN('b', "branch", &status_show_branch, "show branch information"), OPT_SET_INT(0, "porcelain", &status_format, - "show porcelain output format", + "machine-readable output", STATUS_FORMAT_PORCELAIN), OPT_BOOLEAN('z', "null", &null_termination, "terminate entries with NUL"), @@ -1131,13 +1131,8 @@ int cmd_status(int argc, const char **argv, const char *prefix) refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL); fd = hold_locked_index(&index_lock, 0); - if (0 <= fd) { - if (active_cache_changed && - !write_cache(fd, active_cache, active_nr)) - commit_locked_index(&index_lock); - else - rollback_lock_file(&index_lock); - } + if (0 <= fd) + update_index_if_able(&the_index, &index_lock); s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0; s.in_merge = in_merge; diff --git a/builtin/config.c b/builtin/config.c index ca4a0db4a7..f87443698a 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -52,7 +52,7 @@ static struct option builtin_config_options[] = { OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"), OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"), OPT_BOOLEAN(0, "local", &use_local_config, "use repository config file"), - OPT_STRING('f', "file", &given_config_file, "FILE", "use given config file"), + OPT_STRING('f', "file", &given_config_file, "file", "use given config file"), OPT_GROUP("Action"), OPT_BIT(0, "get", &actions, "get value: name [value-regex]", ACTION_GET), OPT_BIT(0, "get-all", &actions, "get all values: key [value-regex]", ACTION_GET_ALL), @@ -153,7 +153,6 @@ static int show_config(const char *key_, const char *value_, void *cb) static int get_value(const char *key_, const char *regex_) { int ret = -1; - char *tl; char *global = NULL, *repo_config = NULL; const char *system_wide = NULL, *local; @@ -167,18 +166,32 @@ static int get_value(const char *key_, const char *regex_) system_wide = git_etc_gitconfig(); } - key = xstrdup(key_); - for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl) - *tl = tolower(*tl); - for (tl=key; *tl && *tl != '.'; ++tl) - *tl = tolower(*tl); - if (use_key_regexp) { + char *tl; + + /* + * NEEDSWORK: this naive pattern lowercasing obviously does not + * work for more complex patterns like "^[^.]*Foo.*bar". + * Perhaps we should deprecate this altogether someday. + */ + + key = xstrdup(key_); + for (tl = key + strlen(key) - 1; + tl >= key && *tl != '.'; + tl--) + *tl = tolower(*tl); + for (tl = key; *tl && *tl != '.'; tl++) + *tl = tolower(*tl); + key_regexp = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(key_regexp, key, REG_EXTENDED)) { fprintf(stderr, "Invalid key pattern: %s\n", key_); + free(key); goto free_strings; } + } else { + if (git_config_parse_key(key_, &key, NULL)) + goto free_strings; } if (regex_) { diff --git a/builtin/describe.c b/builtin/describe.c index 342129fdbd..4afd1504a6 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -21,7 +21,7 @@ static int debug; /* Display lots of verbose info */ static int all; /* Any valid ref can be used */ static int tags; /* Allow lightweight tags */ static int longformat; -static int abbrev = DEFAULT_ABBREV; +static int abbrev = -1; /* unspecified */ static int max_candidates = 10; static struct hash_table names; static int have_util; @@ -63,7 +63,7 @@ static inline struct commit_name *find_commit_name(const unsigned char *peeled) return n; } -static int set_util(void *chain) +static int set_util(void *chain, void *data) { struct commit_name *n; for (n = chain; n; n = n->next) { @@ -289,7 +289,7 @@ static void describe(const char *arg, int last_one) fprintf(stderr, "searching to describe %s\n", arg); if (!have_util) { - for_each_hash(&names, set_util); + for_each_hash(&names, set_util, NULL); have_util = 1; } @@ -420,7 +420,11 @@ int cmd_describe(int argc, const char **argv, const char *prefix) OPT_END(), }; + git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, describe_usage, 0); + if (abbrev < 0) + abbrev = DEFAULT_ABBREV; + if (max_candidates < 0) max_candidates = 0; else if (max_candidates > MAX_TAGS) diff --git a/builtin/diff.c b/builtin/diff.c index 945e7583a8..d4d80c982e 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -197,12 +197,7 @@ static void refresh_index_quietly(void) discard_cache(); read_cache(); refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); - - if (active_cache_changed && - !write_cache(fd, active_cache, active_nr)) - commit_locked_index(lock_file); - - rollback_lock_file(lock_file); + update_index_if_able(&the_index, lock_file); } static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv) @@ -330,8 +325,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix) else if (!strcmp(arg, "--cached") || !strcmp(arg, "--staged")) { add_head_to_pending(&rev); - if (!rev.pending.nr) - die("No HEAD commit to compare with (yet)"); + if (!rev.pending.nr) { + struct tree *tree; + tree = lookup_tree((const unsigned char*)EMPTY_TREE_SHA1_BIN); + add_pending_object(&rev, &tree->object, "HEAD"); + } break; } } diff --git a/builtin/fast-export.c b/builtin/fast-export.c index c8fd46b872..b18fc85c4c 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -619,9 +619,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) OPT_CALLBACK(0, "tag-of-filtered-object", &tag_of_filtered_mode, "mode", "select handling of tags that tag filtered objects", parse_opt_tag_of_filtered_mode), - OPT_STRING(0, "export-marks", &export_filename, "FILE", + OPT_STRING(0, "export-marks", &export_filename, "file", "Dump marks to this file"), - OPT_STRING(0, "import-marks", &import_filename, "FILE", + OPT_STRING(0, "import-marks", &import_filename, "file", "Import marks from this file"), OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger, "Fake a tagger when tags lack one"), diff --git a/builtin/fetch.c b/builtin/fetch.c index 357f3cdbbf..7efecfe1cf 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -49,7 +49,7 @@ static struct option builtin_fetch_options[] = { "fetch from all remotes"), OPT_BOOLEAN('a', "append", &append, "append to .git/FETCH_HEAD instead of overwriting"), - OPT_STRING(0, "upload-pack", &upload_pack, "PATH", + OPT_STRING(0, "upload-pack", &upload_pack, "path", "path to upload pack on remote end"), OPT__FORCE(&force, "force overwrite of local branch"), OPT_BOOLEAN('m', "multiple", &multiple, @@ -69,9 +69,9 @@ static struct option builtin_fetch_options[] = { OPT_BOOLEAN('u', "update-head-ok", &update_head_ok, "allow updating of HEAD ref"), OPT_BOOLEAN(0, "progress", &progress, "force progress reporting"), - OPT_STRING(0, "depth", &depth, "DEPTH", + OPT_STRING(0, "depth", &depth, "depth", "deepen history of shallow clone"), - { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, "DIR", + { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, "dir", "prepend this to submodule path output", PARSE_OPT_HIDDEN }, OPT_END() }; diff --git a/builtin/fsck.c b/builtin/fsck.c index 6d5ebca7a9..795aba087f 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -74,7 +74,13 @@ static int mark_object(struct object *obj, int type, void *data) { struct object *parent = data; + /* + * The only case data is NULL or type is OBJ_ANY is when + * mark_object_reachable() calls us. All the callers of + * that function has non-NULL obj hence ... + */ if (!obj) { + /* ... these references to parent->fld are safe here */ printf("broken link from %7s %s\n", typename(parent->type), sha1_to_hex(parent->sha1)); printf("broken link from %7s %s\n", @@ -84,6 +90,7 @@ static int mark_object(struct object *obj, int type, void *data) } if (type != OBJ_ANY && obj->type != type) + /* ... and the reference to parent is safe here */ objerror(parent, "wrong object type in link"); if (obj->flags & REACHABLE) @@ -109,7 +116,7 @@ static void mark_object_reachable(struct object *obj) mark_object(obj, OBJ_ANY, NULL); } -static int traverse_one_object(struct object *obj, struct object *parent) +static int traverse_one_object(struct object *obj) { int result; struct tree *tree = NULL; @@ -138,7 +145,7 @@ static int traverse_reachable(void) entry = pending.objects + --pending.nr; obj = entry->item; parent = (struct object *) entry->name; - result |= traverse_one_object(obj, parent); + result |= traverse_one_object(obj); } return !!result; } @@ -385,10 +392,20 @@ static void add_sha1_list(unsigned char *sha1, unsigned long ino) sha1_list.nr = ++nr; } +static inline int is_loose_object_file(struct dirent *de, + char *name, unsigned char *sha1) +{ + if (strlen(de->d_name) != 38) + return 0; + memcpy(name + 2, de->d_name, 39); + return !get_sha1_hex(name, sha1); +} + static void fsck_dir(int i, char *path) { DIR *dir = opendir(path); struct dirent *de; + char name[100]; if (!dir) return; @@ -396,17 +413,13 @@ static void fsck_dir(int i, char *path) if (verbose) fprintf(stderr, "Checking directory %s\n", path); + sprintf(name, "%02x", i); while ((de = readdir(dir)) != NULL) { - char name[100]; unsigned char sha1[20]; if (is_dot_or_dotdot(de->d_name)) continue; - if (strlen(de->d_name) == 38) { - sprintf(name, "%02x", i); - memcpy(name+2, de->d_name, 39); - if (get_sha1_hex(name, sha1) < 0) - break; + if (is_loose_object_file(de, name, sha1)) { add_sha1_list(sha1, DIRENT_SORT_HINT(de)); continue; } @@ -556,8 +569,8 @@ static int fsck_cache_tree(struct cache_tree *it) sha1_to_hex(it->sha1)); return 1; } - mark_object_reachable(obj); obj->used = 1; + mark_object_reachable(obj); if (obj->type != OBJ_TREE) err |= objerror(obj, "non-tree in cache-tree"); } diff --git a/builtin/grep.c b/builtin/grep.c index fdf7131efd..bb0f93208f 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -40,8 +40,7 @@ enum work_type {WORK_SHA1, WORK_FILE}; * threads. The producer adds struct work_items to 'todo' and the * consumers pick work items from the same array. */ -struct work_item -{ +struct work_item { enum work_type type; char *name; @@ -865,7 +864,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) OPT_BOOLEAN('F', "fixed-strings", &opt.fixed, "interpret patterns as fixed strings"), OPT_GROUP(""), - OPT_BOOLEAN('n', NULL, &opt.linenum, "show line numbers"), + OPT_BOOLEAN('n', "line-number", &opt.linenum, "show line numbers"), OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1), OPT_BIT('H', NULL, &opt.pathname, "show filenames", 1), OPT_NEGBIT(0, "full-name", &opt.relative, diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 8dc5c0b541..c7e600db47 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -13,8 +13,7 @@ static const char index_pack_usage[] = "git index-pack [-v] [-o <index-file>] [ --keep | --keep=<msg> ] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])"; -struct object_entry -{ +struct object_entry { struct pack_idx_entry idx; unsigned long size; unsigned int hdr_size; @@ -44,8 +43,7 @@ struct base_data { #define FLAG_LINK (1u<<20) #define FLAG_CHECKED (1u<<21) -struct delta_entry -{ +struct delta_entry { union delta_base base; int obj_no; }; diff --git a/builtin/init-db.c b/builtin/init-db.c index e3af9eaa87..fbeb380ee2 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -419,7 +419,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) unsigned int flags = 0; const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, "template-directory", - "provide the directory from which templates will be used"), + "directory from which templates will be used"), OPT_SET_INT(0, "bare", &is_bare_repository_cfg, "create a bare repository", 1), { OPTION_CALLBACK, 0, "shared", &init_shared_repository, @@ -498,13 +498,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) is_bare_repository_cfg = guess_repository_type(git_dir); if (!is_bare_repository_cfg) { - if (git_dir) { - const char *git_dir_parent = strrchr(git_dir, '/'); - if (git_dir_parent) { - char *rel = xstrndup(git_dir, git_dir_parent - git_dir); - git_work_tree_cfg = xstrdup(make_absolute_path(rel)); - free(rel); - } + const char *git_dir_parent = strrchr(git_dir, '/'); + if (git_dir_parent) { + char *rel = xstrndup(git_dir, git_dir_parent - git_dir); + git_work_tree_cfg = xstrdup(make_absolute_path(rel)); + free(rel); } if (!git_work_tree_cfg) { git_work_tree_cfg = xcalloc(PATH_MAX, 1); diff --git a/builtin/log.c b/builtin/log.c index d8c6c28d2f..9a15d69617 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -263,7 +263,13 @@ static int cmd_log_walk(struct rev_info *rev) * retain that state information if replacing rev->diffopt in this loop */ while ((commit = get_revision(rev)) != NULL) { - log_tree_commit(rev, commit); + if (!log_tree_commit(rev, commit) && + rev->max_count >= 0) + /* + * We decremented max_count in get_revision, + * but we didn't actually show the commit. + */ + rev->max_count++; if (!rev->reflog_info) { /* we allow cycles in reflog ancestry */ free(commit->buffer); @@ -1352,6 +1358,23 @@ static const char * const cherry_usage[] = { NULL }; +static void print_commit(char sign, struct commit *commit, int verbose, + int abbrev) +{ + if (!verbose) { + printf("%c %s\n", sign, + find_unique_abbrev(commit->object.sha1, abbrev)); + } else { + struct strbuf buf = STRBUF_INIT; + struct pretty_print_context ctx = {0}; + pretty_print_commit(CMIT_FMT_ONELINE, commit, &buf, &ctx); + printf("%c %s %s\n", sign, + find_unique_abbrev(commit->object.sha1, abbrev), + buf.buf); + strbuf_release(&buf); + } +} + int cmd_cherry(int argc, const char **argv, const char *prefix) { struct rev_info revs; @@ -1436,22 +1459,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) commit = list->item; if (has_commit_patch_id(commit, &ids)) sign = '-'; - - if (verbose) { - struct strbuf buf = STRBUF_INIT; - struct pretty_print_context ctx = {0}; - pretty_print_commit(CMIT_FMT_ONELINE, commit, - &buf, &ctx); - printf("%c %s %s\n", sign, - find_unique_abbrev(commit->object.sha1, abbrev), - buf.buf); - strbuf_release(&buf); - } - else { - printf("%c %s\n", sign, - find_unique_abbrev(commit->object.sha1, abbrev)); - } - + print_commit(sign, commit, verbose, abbrev); list = list->next; } diff --git a/builtin/merge.c b/builtin/merge.c index 42fff387e6..f9fb26dc33 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -195,7 +195,7 @@ static struct option builtin_merge_options[] = { OPT_CALLBACK('X', "strategy-option", &xopts, "option=value", "option for selected merge strategy", option_parse_x), OPT_CALLBACK('m', "message", &merge_msg, "message", - "message to be used for the merge commit (if any)", + "merge commit message (for a non-fast-forward merge)", option_parse_message), OPT__VERBOSITY(&verbosity), OPT_BOOLEAN(0, "abort", &abort_current_merge, @@ -795,6 +795,32 @@ static void add_strategies(const char *string, unsigned attr) } +static void write_merge_msg(void) +{ + int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666); + if (fd < 0) + die_errno("Could not open '%s' for writing", + git_path("MERGE_MSG")); + if (write_in_full(fd, merge_msg.buf, merge_msg.len) != merge_msg.len) + die_errno("Could not write to '%s'", git_path("MERGE_MSG")); + close(fd); +} + +static void read_merge_msg(void) +{ + strbuf_reset(&merge_msg); + if (strbuf_read_file(&merge_msg, git_path("MERGE_MSG"), 0) < 0) + die_errno("Could not read from '%s'", git_path("MERGE_MSG")); +} + +static void run_prepare_commit_msg(void) +{ + write_merge_msg(); + run_hook(get_index_file(), "prepare-commit-msg", + git_path("MERGE_MSG"), "merge", NULL, NULL); + read_merge_msg(); +} + static int merge_trivial(void) { unsigned char result_tree[20], result_commit[20]; @@ -806,6 +832,7 @@ static int merge_trivial(void) parent->next = xmalloc(sizeof(*parent->next)); parent->next->item = remoteheads->item; parent->next->next = NULL; + run_prepare_commit_msg(); commit_tree(merge_msg.buf, result_tree, parent, result_commit, NULL); finish(result_commit, "In-index merge"); drop_save(); @@ -835,6 +862,7 @@ static int finish_automerge(struct commit_list *common, } free_commit_list(remoteheads); strbuf_addch(&merge_msg, '\n'); + run_prepare_commit_msg(); commit_tree(merge_msg.buf, result_tree, parents, result_commit, NULL); strbuf_addf(&buf, "Merge made by %s.", wt_strategy); finish(result_commit, buf.buf); @@ -1316,14 +1344,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die_errno("Could not write to '%s'", git_path("MERGE_HEAD")); close(fd); strbuf_addch(&merge_msg, '\n'); - fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666); - if (fd < 0) - die_errno("Could not open '%s' for writing", - git_path("MERGE_MSG")); - if (write_in_full(fd, merge_msg.buf, merge_msg.len) != - merge_msg.len) - die_errno("Could not write to '%s'", git_path("MERGE_MSG")); - close(fd); + write_merge_msg(); fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) die_errno("Could not open '%s' for writing", diff --git a/builtin/notes.c b/builtin/notes.c index 4d5556e2cb..0aab150c52 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -537,16 +537,16 @@ static int add(int argc, const char **argv, const char *prefix) const unsigned char *note; struct msg_arg msg = { 0, 0, STRBUF_INIT }; struct option options[] = { - { OPTION_CALLBACK, 'm', "message", &msg, "MSG", + { OPTION_CALLBACK, 'm', "message", &msg, "msg", "note contents as a string", PARSE_OPT_NONEG, parse_msg_arg}, - { OPTION_CALLBACK, 'F', "file", &msg, "FILE", + { OPTION_CALLBACK, 'F', "file", &msg, "file", "note contents in a file", PARSE_OPT_NONEG, parse_file_arg}, - { OPTION_CALLBACK, 'c', "reedit-message", &msg, "OBJECT", + { OPTION_CALLBACK, 'c', "reedit-message", &msg, "object", "reuse and edit specified note object", PARSE_OPT_NONEG, parse_reedit_arg}, - { OPTION_CALLBACK, 'C', "reuse-message", &msg, "OBJECT", + { OPTION_CALLBACK, 'C', "reuse-message", &msg, "object", "reuse specified note object", PARSE_OPT_NONEG, parse_reuse_arg}, OPT__FORCE(&force, "replace existing notes"), @@ -682,16 +682,16 @@ static int append_edit(int argc, const char **argv, const char *prefix) const char * const *usage; struct msg_arg msg = { 0, 0, STRBUF_INIT }; struct option options[] = { - { OPTION_CALLBACK, 'm', "message", &msg, "MSG", + { OPTION_CALLBACK, 'm', "message", &msg, "msg", "note contents as a string", PARSE_OPT_NONEG, parse_msg_arg}, - { OPTION_CALLBACK, 'F', "file", &msg, "FILE", + { OPTION_CALLBACK, 'F', "file", &msg, "file", "note contents in a file", PARSE_OPT_NONEG, parse_file_arg}, - { OPTION_CALLBACK, 'c', "reedit-message", &msg, "OBJECT", + { OPTION_CALLBACK, 'c', "reedit-message", &msg, "object", "reuse and edit specified note object", PARSE_OPT_NONEG, parse_reedit_arg}, - { OPTION_CALLBACK, 'C', "reuse-message", &msg, "OBJECT", + { OPTION_CALLBACK, 'C', "reuse-message", &msg, "object", "reuse specified note object", PARSE_OPT_NONEG, parse_reuse_arg}, OPT_END() diff --git a/builtin/patch-id.c b/builtin/patch-id.c index 512530022e..49a0472a9b 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -73,6 +73,8 @@ int get_one_patchid(unsigned char *next_sha1, git_SHA_CTX *ctx) p += 7; else if (!memcmp(line, "From ", 5)) p += 5; + else if (!memcmp(line, "\\ ", 2) && 12 < strlen(line)) + continue; if (!get_sha1_hex(p, next_sha1)) { found_next = 1; diff --git a/builtin/push.c b/builtin/push.c index e655eb7695..31da418cf4 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -64,17 +64,17 @@ static void set_refspecs(const char **refs, int nr) } } -static void setup_push_tracking(void) +static void setup_push_upstream(void) { struct strbuf refspec = STRBUF_INIT; struct branch *branch = branch_get(NULL); if (!branch) die("You are not currently on a branch."); if (!branch->merge_nr || !branch->merge) - die("The current branch %s is not tracking anything.", + die("The current branch %s has no upstream branch.", branch->name); if (branch->merge_nr != 1) - die("The current branch %s is tracking multiple branches, " + die("The current branch %s has multiple upstream branches, " "refusing to push.", branch->name); strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src); add_refspec(refspec.buf); @@ -88,8 +88,8 @@ static void setup_default_push_refspecs(void) add_refspec(":"); break; - case PUSH_DEFAULT_TRACKING: - setup_push_tracking(); + case PUSH_DEFAULT_UPSTREAM: + setup_push_upstream(); break; case PUSH_DEFAULT_CURRENT: diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 73c89ed15b..93c92814cf 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -104,8 +104,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) struct unpack_trees_options opts; int prefix_set = 0; const struct option read_tree_options[] = { - { OPTION_CALLBACK, 0, "index-output", NULL, "FILE", - "write resulting index to <FILE>", + { OPTION_CALLBACK, 0, "index-output", NULL, "file", + "write resulting index to <file>", PARSE_OPT_NONEG, index_output_cb }, OPT_SET_INT(0, "empty", &read_empty, "only empty the index", 1), diff --git a/builtin/tag.c b/builtin/tag.c index aa1f87d47a..7cf48abca8 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -376,9 +376,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_GROUP("Tag creation options"), OPT_BOOLEAN('a', NULL, &annotate, "annotated tag, needs a message"), - OPT_CALLBACK('m', NULL, &msg, "msg", - "message for the tag", parse_msg_arg), - OPT_FILENAME('F', NULL, &msgfile, "message in a file"), + OPT_CALLBACK('m', NULL, &msg, "message", + "tag message", parse_msg_arg), + OPT_FILENAME('F', NULL, &msgfile, "read message from 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"), |