summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c7
-rw-r--r--builtin/am.c45
-rw-r--r--builtin/blame.c5
-rw-r--r--builtin/branch.c46
-rw-r--r--builtin/cat-file.c9
-rw-r--r--builtin/checkout.c6
-rw-r--r--builtin/clean.c22
-rw-r--r--builtin/clone.c4
-rw-r--r--builtin/commit-tree.c4
-rw-r--r--builtin/commit.c34
-rw-r--r--builtin/count-objects.c1
-rw-r--r--builtin/describe.c9
-rw-r--r--builtin/diff-files.c1
-rw-r--r--builtin/diff-index.c1
-rw-r--r--builtin/diff-tree.c1
-rw-r--r--builtin/diff.c2
-rw-r--r--builtin/difftool.c39
-rw-r--r--builtin/fetch.c32
-rw-r--r--builtin/fmt-merge-msg.c3
-rw-r--r--builtin/for-each-ref.c27
-rw-r--r--builtin/fsck.c74
-rw-r--r--builtin/gc.c1
-rw-r--r--builtin/grep.c408
-rw-r--r--builtin/hash-object.c12
-rw-r--r--builtin/index-pack.c1
-rw-r--r--builtin/interpret-trailers.c107
-rw-r--r--builtin/log.c33
-rw-r--r--builtin/ls-files.c11
-rw-r--r--builtin/merge-tree.c16
-rw-r--r--builtin/merge.c30
-rw-r--r--builtin/mv.c3
-rw-r--r--builtin/notes.c2
-rw-r--r--builtin/pack-objects.c14
-rw-r--r--builtin/pack-redundant.c1
-rw-r--r--builtin/prune-packed.c4
-rw-r--r--builtin/prune.c2
-rw-r--r--builtin/pull.c4
-rw-r--r--builtin/push.c2
-rw-r--r--builtin/read-tree.c2
-rw-r--r--builtin/receive-pack.c7
-rw-r--r--builtin/remote.c2
-rw-r--r--builtin/replace.c6
-rw-r--r--builtin/reset.c17
-rw-r--r--builtin/rev-list.c9
-rw-r--r--builtin/rev-parse.c8
-rw-r--r--builtin/revert.c2
-rw-r--r--builtin/rm.c3
-rw-r--r--builtin/send-pack.c2
-rw-r--r--builtin/show-branch.c10
-rw-r--r--builtin/submodule--helper.c127
-rw-r--r--builtin/tag.c66
-rw-r--r--builtin/unpack-file.c12
-rw-r--r--builtin/update-index.c2
-rw-r--r--builtin/update-ref.c69
-rw-r--r--builtin/verify-tag.c21
55 files changed, 654 insertions, 734 deletions
diff --git a/builtin/add.c b/builtin/add.c
index e888fb8c5f..c20548e4f5 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -32,7 +32,7 @@ struct update_callback_data {
int add_errors;
};
-static void chmod_pathspec(struct pathspec *pathspec, int force_mode)
+static void chmod_pathspec(struct pathspec *pathspec, char flip)
{
int i;
@@ -42,8 +42,8 @@ static void chmod_pathspec(struct pathspec *pathspec, int force_mode)
if (pathspec && !ce_path_match(ce, pathspec, NULL))
continue;
- if (chmod_cache_entry(ce, force_mode) < 0)
- fprintf(stderr, "cannot chmod '%s'", ce->name);
+ if (chmod_cache_entry(ce, flip) < 0)
+ fprintf(stderr, "cannot chmod %cx '%s'\n", flip, ce->name);
}
}
@@ -116,6 +116,7 @@ int add_files_to_cache(const char *prefix,
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
rev.diffopt.format_callback_data = &data;
+ rev.diffopt.flags |= DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
return !!data.add_errors;
diff --git a/builtin/am.c b/builtin/am.c
index c973bd96dc..c369dd1dce 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -31,6 +31,7 @@
#include "mailinfo.h"
#include "apply.h"
#include "string-list.h"
+#include "packfile.h"
/**
* Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -431,6 +432,14 @@ static void am_load(struct am_state *state)
read_state_file(&sb, state, "utf8", 1);
state->utf8 = !strcmp(sb.buf, "t");
+ if (file_exists(am_path(state, "rerere-autoupdate"))) {
+ read_state_file(&sb, state, "rerere-autoupdate", 1);
+ state->allow_rerere_autoupdate = strcmp(sb.buf, "t") ?
+ RERERE_NOAUTOUPDATE : RERERE_AUTOUPDATE;
+ } else {
+ state->allow_rerere_autoupdate = 0;
+ }
+
read_state_file(&sb, state, "keep", 1);
if (!strcmp(sb.buf, "t"))
state->keep = KEEP_TRUE;
@@ -1003,6 +1012,10 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
write_state_bool(state, "sign", state->signoff);
write_state_bool(state, "utf8", state->utf8);
+ if (state->allow_rerere_autoupdate)
+ write_state_bool(state, "rerere-autoupdate",
+ state->allow_rerere_autoupdate == RERERE_AUTOUPDATE);
+
switch (state->keep) {
case KEEP_FALSE:
str = "f";
@@ -1131,7 +1144,7 @@ static int index_has_changes(struct strbuf *sb)
struct object_id head;
int i;
- if (!get_sha1_tree("HEAD", head.hash)) {
+ if (!get_oid_tree("HEAD", &head)) {
struct diff_options opt;
diff_setup(&opt);
@@ -1181,34 +1194,10 @@ static void NORETURN die_user_resolve(const struct am_state *state)
*/
static void am_append_signoff(struct am_state *state)
{
- char *cp;
- struct strbuf mine = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
-
- /* our sign-off */
- strbuf_addf(&mine, "\n%s%s\n",
- sign_off_header,
- fmt_name(getenv("GIT_COMMITTER_NAME"),
- getenv("GIT_COMMITTER_EMAIL")));
-
- /* Does sb end with it already? */
- if (mine.len < sb.len &&
- !strcmp(mine.buf, sb.buf + sb.len - mine.len))
- goto exit; /* no need to duplicate */
-
- /* Does it have any Signed-off-by: in the text */
- for (cp = sb.buf;
- cp && *cp && (cp = strstr(cp, sign_off_header)) != NULL;
- cp = strchr(cp, '\n')) {
- if (sb.buf == cp || cp[-1] == '\n')
- break;
- }
-
- strbuf_addstr(&sb, mine.buf + !!cp);
-exit:
- strbuf_release(&mine);
+ append_signoff(&sb, 0, 0);
state->msg = strbuf_detach(&sb, &state->msg_len);
}
@@ -1432,7 +1421,7 @@ static void write_index_patch(const struct am_state *state)
struct rev_info rev_info;
FILE *fp;
- if (!get_sha1_tree("HEAD", head.hash))
+ if (!get_oid_tree("HEAD", &head))
tree = lookup_tree(&head);
else
tree = lookup_tree(&empty_tree_oid);
@@ -1661,7 +1650,7 @@ static void do_commit(const struct am_state *state)
if (write_cache_as_tree(tree.hash, 0, NULL))
die(_("git write-tree failed to write a tree"));
- if (!get_sha1_commit("HEAD", parent.hash)) {
+ if (!get_oid_commit("HEAD", &parent)) {
old_oid = &parent;
commit_list_insert(lookup_commit(&parent), &parents);
} else {
diff --git a/builtin/blame.c b/builtin/blame.c
index bda1a78726..67adaef4d8 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -488,7 +488,7 @@ static int read_ancestry(const char *graft_file)
return -1;
while (!strbuf_getwholeline(&buf, fp, '\n')) {
/* The format is just "Commit Parent1 Parent2 ...\n" */
- struct commit_graft *graft = read_graft_line(buf.buf, buf.len);
+ struct commit_graft *graft = read_graft_line(&buf);
if (graft)
register_commit_graft(graft, 0);
}
@@ -925,8 +925,7 @@ parse_done:
sb.found_guilty_entry = &found_guilty_entry;
sb.found_guilty_entry_data = &pi;
if (show_progress)
- pi.progress = start_progress_delay(_("Blaming lines"),
- sb.num_lines, 50, 1);
+ pi.progress = start_delayed_progress(_("Blaming lines"), sb.num_lines);
assign_blame(&sb, opt);
diff --git a/builtin/branch.c b/builtin/branch.c
index 8a0595e115..355f9ef5da 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -92,7 +92,7 @@ static int git_branch_config(const char *var, const char *value, void *cb)
return config_error_nonbool(var);
return color_parse(value, branch_colors[slot]);
}
- return git_color_default_config(var, value, cb);
+ return git_default_config(var, value, cb);
}
static const char *branch_get_color(enum color_branch ix)
@@ -383,7 +383,7 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
return strbuf_detach(&fmt, NULL);
}
-static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, const char *format)
+static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format)
{
int i;
struct ref_array array;
@@ -407,14 +407,17 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
if (filter->verbose)
maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
- if (!format)
- format = to_free = build_format(filter, maxwidth, remote_prefix);
- verify_ref_format(format);
+ if (!format->format)
+ format->format = to_free = build_format(filter, maxwidth, remote_prefix);
+ format->use_color = branch_use_color;
+
+ if (verify_ref_format(format))
+ die(_("unable to parse format string"));
ref_array_sort(sorting, &array);
for (i = 0; i < array.nr; i++) {
- format_ref_array_item(array.items[i], format, 0, &out);
+ format_ref_array_item(array.items[i], format, &out);
if (column_active(colopts)) {
assert(!filter->verbose && "--column and --verbose are incompatible");
/* format to a string_list to let print_columns() do its job */
@@ -549,7 +552,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
struct ref_filter filter;
int icase = 0;
static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
- const char *format = NULL;
+ struct ref_format format = REF_FORMAT_INIT;
struct option options[] = {
OPT_GROUP(N_("Generic options")),
@@ -558,8 +561,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT__QUIET(&quiet, N_("suppress informational messages")),
OPT_SET_INT('t', "track", &track, N_("set up tracking mode (see git-pull(1))"),
BRANCH_TRACK_EXPLICIT),
- OPT_SET_INT( 0, "set-upstream", &track, N_("change upstream info"),
- BRANCH_TRACK_OVERRIDE),
+ { OPTION_SET_INT, 0, "set-upstream", &track, NULL, N_("do not use"),
+ PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, BRANCH_TRACK_OVERRIDE },
OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")),
OPT_BOOL(0, "unset-upstream", &unset_upstream, N_("Unset the upstream info")),
OPT__COLOR(&branch_use_color, N_("use colored output")),
@@ -593,7 +596,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
N_("print only branches of the object"), 0, parse_opt_object_name
},
OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
- OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
+ OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")),
OPT_END(),
};
@@ -667,7 +670,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (!sorting)
sorting = ref_default_sorting();
sorting->ignore_case = icase;
- print_ref_list(&filter, sorting, format);
+ print_ref_list(&filter, sorting, &format);
print_columns(&output, colopts, NULL);
string_list_clear(&output, 0);
return 0;
@@ -756,8 +759,6 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
strbuf_release(&buf);
} else if (argc > 0 && argc <= 2) {
struct branch *branch = branch_get(argv[0]);
- int branch_existed = 0, remote_tracking = 0;
- struct strbuf buf = STRBUF_INIT;
if (!strcmp(argv[0], "HEAD"))
die(_("it does not make sense to create 'HEAD' manually"));
@@ -769,28 +770,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
if (track == BRANCH_TRACK_OVERRIDE)
- fprintf(stderr, _("The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to\n"));
-
- strbuf_addf(&buf, "refs/remotes/%s", branch->name);
- remote_tracking = ref_exists(buf.buf);
- strbuf_release(&buf);
+ die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead."));
- branch_existed = ref_exists(branch->refname);
create_branch(argv[0], (argc == 2) ? argv[1] : head,
force, reflog, 0, quiet, track);
- /*
- * We only show the instructions if the user gave us
- * one branch which doesn't exist locally, but is the
- * name of a remote-tracking branch.
- */
- if (argc == 1 && track == BRANCH_TRACK_OVERRIDE &&
- !branch_existed && remote_tracking) {
- fprintf(stderr, _("\nIf you wanted to make '%s' track '%s', do this:\n\n"), head, branch->name);
- fprintf(stderr, " git branch -d %s\n", branch->name);
- fprintf(stderr, " git branch --set-upstream-to %s\n", branch->name);
- }
-
} else
usage_with_options(builtin_branch_usage, options);
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 96b786e489..4ccbfaac31 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -12,6 +12,7 @@
#include "streaming.h"
#include "tree-walk.h"
#include "sha1-array.h"
+#include "packfile.h"
struct batch_options {
int enabled;
@@ -63,8 +64,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
if (unknown_type)
flags |= OBJECT_INFO_ALLOW_UNKNOWN_TYPE;
- if (get_sha1_with_context(obj_name, GET_SHA1_RECORD_PATH,
- oid.hash, &obj_context))
+ if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH,
+ &oid, &obj_context))
die("Not a valid object name %s", obj_name);
if (!path)
@@ -361,10 +362,10 @@ static void batch_one_object(const char *obj_name, struct batch_options *opt,
struct expand_data *data)
{
struct object_context ctx;
- int flags = opt->follow_symlinks ? GET_SHA1_FOLLOW_SYMLINKS : 0;
+ int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
enum follow_symlinks_result result;
- result = get_sha1_with_context(obj_name, flags, data->oid.hash, &ctx);
+ result = get_oid_with_context(obj_name, flags, &data->oid, &ctx);
if (result != FOUND) {
switch (result) {
case MISSING_OBJECT:
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 9661e1bcba..5c202b7af5 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -358,6 +358,8 @@ static int checkout_paths(const struct checkout_opts *opts,
state.force = 1;
state.refresh_cache = 1;
state.istate = &the_index;
+
+ enable_delayed_checkout(&state);
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
if (ce->ce_flags & CE_MATCHED) {
@@ -372,6 +374,7 @@ static int checkout_paths(const struct checkout_opts *opts,
pos = skip_same_name(ce, pos) - 1;
}
}
+ errs |= finish_delayed_checkout(&state);
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
@@ -858,7 +861,7 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
}
if (starts_with(var, "submodule."))
- return submodule_config(var, value, NULL);
+ return git_default_submodule_config(var, value, NULL);
return git_xmerge_config(var, value, NULL);
}
@@ -1179,7 +1182,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.prefix = prefix;
opts.show_progress = -1;
- gitmodules_config();
git_config(git_checkout_config, &opts);
opts.track = BRANCH_TRACK_UNSPECIFIED;
diff --git a/builtin/clean.c b/builtin/clean.c
index 057fc97fe4..21a7a32994 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -33,15 +33,6 @@ static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
static const char *msg_warn_remove_failed = N_("failed to remove %s");
-static int clean_use_color = -1;
-static char clean_colors[][COLOR_MAXLEN] = {
- GIT_COLOR_RESET,
- GIT_COLOR_NORMAL, /* PLAIN */
- GIT_COLOR_BOLD_BLUE, /* PROMPT */
- GIT_COLOR_BOLD, /* HEADER */
- GIT_COLOR_BOLD_RED, /* HELP */
- GIT_COLOR_BOLD_RED, /* ERROR */
-};
enum color_clean {
CLEAN_COLOR_RESET = 0,
CLEAN_COLOR_PLAIN = 1,
@@ -51,6 +42,16 @@ enum color_clean {
CLEAN_COLOR_ERROR = 5
};
+static int clean_use_color = -1;
+static char clean_colors[][COLOR_MAXLEN] = {
+ [CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED,
+ [CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD,
+ [CLEAN_COLOR_HELP] = GIT_COLOR_BOLD_RED,
+ [CLEAN_COLOR_PLAIN] = GIT_COLOR_NORMAL,
+ [CLEAN_COLOR_PROMPT] = GIT_COLOR_BOLD_BLUE,
+ [CLEAN_COLOR_RESET] = GIT_COLOR_RESET,
+};
+
#define MENU_OPTS_SINGLETON 01
#define MENU_OPTS_IMMEDIATE 02
#define MENU_OPTS_LIST_ONLY 04
@@ -125,8 +126,7 @@ static int git_clean_config(const char *var, const char *value, void *cb)
return 0;
}
- /* inspect the color.ui config variable and others */
- return git_color_default_config(var, value, cb);
+ return git_default_config(var, value, cb);
}
static const char *clean_get_color(enum color_clean ix)
diff --git a/builtin/clone.c b/builtin/clone.c
index 08b5cc433c..8d11b570a1 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -25,6 +25,7 @@
#include "remote.h"
#include "run-command.h"
#include "connected.h"
+#include "packfile.h"
/*
* Overall FIXMEs:
@@ -768,6 +769,9 @@ static int checkout(int submodule_progress)
if (submodule_progress)
argv_array_push(&args, "--progress");
+ if (option_verbosity < 0)
+ argv_array_push(&args, "--quiet");
+
err = run_command_v_opt(args.argv, RUN_GIT_CMD);
argv_array_clear(&args);
}
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index a4a923d7c0..19e898fa4e 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -56,7 +56,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
struct object_id oid;
if (argc <= ++i)
usage(commit_tree_usage);
- if (get_sha1_commit(argv[i], oid.hash))
+ if (get_oid_commit(argv[i], &oid))
die("Not a valid object name %s", argv[i]);
assert_sha1_type(oid.hash, OBJ_COMMIT);
new_parent(lookup_commit(&oid), &parents);
@@ -106,7 +106,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
continue;
}
- if (get_sha1_tree(arg, tree_oid.hash))
+ if (get_oid_tree(arg, &tree_oid))
die("Not a valid object name %s", arg);
if (got_tree)
die("Cannot give more than one trees");
diff --git a/builtin/commit.c b/builtin/commit.c
index 8e93802511..b3b04f5dd3 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -195,7 +195,6 @@ static void determine_whence(struct wt_status *s)
static void status_init_config(struct wt_status *s, config_fn_t fn)
{
wt_status_prepare(s);
- gitmodules_config();
git_config(fn, s);
determine_whence(s);
init_diff_ui_defaults();
@@ -510,7 +509,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
s->index_file = index_file;
s->fp = fp;
s->nowarn = nowarn;
- s->is_initial = get_sha1(s->reference, oid.hash) ? 1 : 0;
+ s->is_initial = get_oid(s->reference, &oid) ? 1 : 0;
if (!s->is_initial)
hashcpy(s->sha1_commit, oid.hash);
s->status_format = status_format;
@@ -891,7 +890,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (amend)
parent = "HEAD^1";
- if (get_sha1(parent, oid.hash)) {
+ if (get_oid(parent, &oid)) {
int i, ita_nr = 0;
for (i = 0; i < active_nr; i++)
@@ -940,13 +939,16 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
return 0;
}
- /*
- * Re-read the index as pre-commit hook could have updated it,
- * and write it out as a tree. We must do this before we invoke
- * the editor and after we invoke run_status above.
- */
- discard_cache();
+ if (!no_verify && find_hook("pre-commit")) {
+ /*
+ * Re-read the index as pre-commit hook could have updated it,
+ * and write it out as a tree. We must do this before we invoke
+ * the editor and after we invoke run_status above.
+ */
+ discard_cache();
+ }
read_cache_from(index_file);
+
if (update_main_cache_tree(0)) {
error(_("Error building trees"));
return 0;
@@ -1387,7 +1389,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
fd = hold_locked_index(&index_lock, 0);
- s.is_initial = get_sha1(s.reference, oid.hash) ? 1 : 0;
+ s.is_initial = get_oid(s.reference, &oid) ? 1 : 0;
if (!s.is_initial)
hashcpy(s.sha1_commit, oid.hash);
@@ -1657,7 +1659,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
status_format = STATUS_FORMAT_NONE; /* Ignore status.short */
s.colopts = 0;
- if (get_sha1("HEAD", oid.hash))
+ if (get_oid("HEAD", &oid))
current_head = NULL;
else {
current_head = lookup_commit_or_die(&oid, "HEAD");
@@ -1739,17 +1741,17 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (verbose || /* Truncate the message just before the diff, if any. */
cleanup_mode == CLEANUP_SCISSORS)
strbuf_setlen(&sb, wt_status_locate_end(sb.buf, sb.len));
-
if (cleanup_mode != CLEANUP_NONE)
strbuf_stripspace(&sb, cleanup_mode == CLEANUP_ALL);
- if (template_untouched(&sb) && !allow_empty_message) {
+
+ if (message_is_empty(&sb) && !allow_empty_message) {
rollback_index_files();
- fprintf(stderr, _("Aborting commit; you did not edit the message.\n"));
+ fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
exit(1);
}
- if (message_is_empty(&sb) && !allow_empty_message) {
+ if (template_untouched(&sb) && !allow_empty_message) {
rollback_index_files();
- fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
+ fprintf(stderr, _("Aborting commit; you did not edit the message.\n"));
exit(1);
}
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 1d82e61f2a..33343818c8 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -10,6 +10,7 @@
#include "builtin.h"
#include "parse-options.h"
#include "quote.h"
+#include "packfile.h"
static unsigned long garbage;
static off_t size_garbage;
diff --git a/builtin/describe.c b/builtin/describe.c
index 89ea1cdd60..9c13c6817b 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -55,10 +55,13 @@ static const char *prio_names[] = {
};
static int commit_name_cmp(const void *unused_cmp_data,
- const struct commit_name *cn1,
- const struct commit_name *cn2,
+ const void *entry,
+ const void *entry_or_key,
const void *peeled)
{
+ const struct commit_name *cn1 = entry;
+ const struct commit_name *cn2 = entry_or_key;
+
return oidcmp(&cn1->peeled, peeled ? peeled : &cn2->peeled);
}
@@ -503,7 +506,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
return cmd_name_rev(args.argc, args.argv, prefix);
}
- hashmap_init(&names, (hashmap_cmp_fn) commit_name_cmp, NULL, 0);
+ hashmap_init(&names, commit_name_cmp, NULL, 0);
for_each_rawref(get_name, NULL);
if (!names.size && !always)
die(_("No names found, cannot describe anything."));
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 17bf84d18f..e88493ffe5 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -26,7 +26,6 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(&rev, prefix);
- gitmodules_config();
rev.abbrev = 0;
precompose_argv(argc, argv);
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 185e6f9b58..9d772f8f27 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -23,7 +23,6 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(&rev, prefix);
- gitmodules_config();
rev.abbrev = 0;
precompose_argv(argc, argv);
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 31d2cb4107..d66499909e 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -110,7 +110,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(opt, prefix);
- gitmodules_config();
opt->abbrev = 0;
opt->diff = 1;
opt->disable_stdin = 1;
diff --git a/builtin/diff.c b/builtin/diff.c
index 7cde6abbcf..7e3ebcea38 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -315,8 +315,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
no_index = DIFF_NO_INDEX_IMPLICIT;
}
- if (!no_index)
- gitmodules_config();
init_diff_ui_defaults();
git_config(git_diff_ui_config, NULL);
precompose_argv(argc, argv);
diff --git a/builtin/difftool.c b/builtin/difftool.c
index a1a26ba891..b2d3ba7539 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -111,7 +111,7 @@ static int use_wt_file(const char *workdir, const char *name,
int fd = open(buf.buf, O_RDONLY);
if (fd >= 0 &&
- !index_fd(wt_oid.hash, fd, &st, OBJ_BLOB, name, 0)) {
+ !index_fd(&wt_oid, fd, &st, OBJ_BLOB, name, 0)) {
if (is_null_oid(oid)) {
oidcpy(oid, &wt_oid);
use = 1;
@@ -131,10 +131,12 @@ struct working_tree_entry {
};
static int working_tree_entry_cmp(const void *unused_cmp_data,
- struct working_tree_entry *a,
- struct working_tree_entry *b,
- void *unused_keydata)
+ const void *entry,
+ const void *entry_or_key,
+ const void *unused_keydata)
{
+ const struct working_tree_entry *a = entry;
+ const struct working_tree_entry *b = entry_or_key;
return strcmp(a->path, b->path);
}
@@ -149,9 +151,13 @@ struct pair_entry {
};
static int pair_cmp(const void *unused_cmp_data,
- struct pair_entry *a, struct pair_entry *b,
- void *unused_keydata)
+ const void *entry,
+ const void *entry_or_key,
+ const void *unused_keydata)
{
+ const struct pair_entry *a = entry;
+ const struct pair_entry *b = entry_or_key;
+
return strcmp(a->path, b->path);
}
@@ -179,9 +185,13 @@ struct path_entry {
};
static int path_entry_cmp(const void *unused_cmp_data,
- struct path_entry *a, struct path_entry *b,
- void *key)
+ const void *entry,
+ const void *entry_or_key,
+ const void *key)
{
+ const struct path_entry *a = entry;
+ const struct path_entry *b = entry_or_key;
+
return strcmp(a->path, key ? key : b->path);
}
@@ -372,10 +382,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
rdir_len = rdir.len;
wtdir_len = wtdir.len;
- hashmap_init(&working_tree_dups,
- (hashmap_cmp_fn)working_tree_entry_cmp, NULL, 0);
- hashmap_init(&submodules, (hashmap_cmp_fn)pair_cmp, NULL, 0);
- hashmap_init(&symlinks2, (hashmap_cmp_fn)pair_cmp, NULL, 0);
+ hashmap_init(&working_tree_dups, working_tree_entry_cmp, NULL, 0);
+ hashmap_init(&submodules, pair_cmp, NULL, 0);
+ hashmap_init(&symlinks2, pair_cmp, NULL, 0);
child.no_stdin = 1;
child.git_cmd = 1;
@@ -585,10 +594,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
* in the common case of --symlinks and the difftool updating
* files through the symlink.
*/
- hashmap_init(&wt_modified, (hashmap_cmp_fn)path_entry_cmp,
- NULL, wtindex.cache_nr);
- hashmap_init(&tmp_modified, (hashmap_cmp_fn)path_entry_cmp,
- NULL, wtindex.cache_nr);
+ hashmap_init(&wt_modified, path_entry_cmp, NULL, wtindex.cache_nr);
+ hashmap_init(&tmp_modified, path_entry_cmp, NULL, wtindex.cache_nr);
for (i = 0; i < wtindex.cache_nr; i++) {
struct hashmap_entry dummy;
diff --git a/builtin/fetch.c b/builtin/fetch.c
index c87e59f3b1..225c734924 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -17,6 +17,7 @@
#include "connected.h"
#include "argv-array.h"
#include "utf8.h"
+#include "packfile.h"
static const char * const builtin_fetch_usage[] = {
N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -39,7 +40,7 @@ static int prune = -1; /* unspecified */
static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity, deepen_relative;
static int progress = -1;
static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
-static int max_children = -1;
+static int max_children = 1;
static enum transport_family family;
static const char *depth;
static const char *deepen_since;
@@ -68,9 +69,30 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
recurse_submodules = r;
}
+ if (!strcmp(k, "submodule.fetchjobs")) {
+ max_children = parse_submodule_fetchjobs(k, v);
+ return 0;
+ } else if (!strcmp(k, "fetch.recursesubmodules")) {
+ recurse_submodules = parse_fetch_recurse_submodules_arg(k, v);
+ return 0;
+ }
+
return git_default_config(k, v, cb);
}
+static int gitmodules_fetch_config(const char *var, const char *value, void *cb)
+{
+ if (!strcmp(var, "submodule.fetchjobs")) {
+ max_children = parse_submodule_fetchjobs(var, value);
+ return 0;
+ } else if (!strcmp(var, "fetch.recursesubmodules")) {
+ recurse_submodules = parse_fetch_recurse_submodules_arg(var, value);
+ return 0;
+ }
+
+ return 0;
+}
+
static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
{
ALLOC_GROW(refmap_array, refmap_nr + 1, refmap_alloc);
@@ -1311,6 +1333,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]);
+ config_from_gitmodules(gitmodules_fetch_config, NULL);
git_config(git_fetch_config, NULL);
argc = parse_options(argc, argv, prefix,
@@ -1338,12 +1361,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
if (depth || deepen_since || deepen_not.nr)
deepen = 1;
- if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
- set_config_fetch_recurse_submodules(recurse_submodules_default);
- gitmodules_config();
- git_config(submodule_config, NULL);
- }
-
if (all) {
if (argc == 1)
die(_("fetch --all does not take a repository argument"));
@@ -1383,6 +1400,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
result = fetch_populated_submodules(&options,
submodule_prefix,
recurse_submodules,
+ recurse_submodules_default,
verbosity < 0,
max_children);
argv_array_clear(&options);
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 10cbb43416..e99b5ddbf9 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -408,7 +408,8 @@ static void shortlog(const char *name,
}
static void fmt_merge_msg_title(struct strbuf *out,
- const char *current_branch) {
+ const char *current_branch)
+{
int i = 0;
char *sep = "";
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 52be99cbac..5d7c921a77 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -17,25 +17,25 @@ static char const * const for_each_ref_usage[] = {
int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
{
int i;
- const char *format = "%(objectname) %(objecttype)\t%(refname)";
struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
- int maxcount = 0, quote_style = 0, icase = 0;
+ int maxcount = 0, icase = 0;
struct ref_array array;
struct ref_filter filter;
+ struct ref_format format = REF_FORMAT_INIT;
struct option opts[] = {
- OPT_BIT('s', "shell", &quote_style,
+ OPT_BIT('s', "shell", &format.quote_style,
N_("quote placeholders suitably for shells"), QUOTE_SHELL),
- OPT_BIT('p', "perl", &quote_style,
+ OPT_BIT('p', "perl", &format.quote_style,
N_("quote placeholders suitably for perl"), QUOTE_PERL),
- OPT_BIT(0 , "python", &quote_style,
+ OPT_BIT(0 , "python", &format.quote_style,
N_("quote placeholders suitably for python"), QUOTE_PYTHON),
- OPT_BIT(0 , "tcl", &quote_style,
+ OPT_BIT(0 , "tcl", &format.quote_style,
N_("quote placeholders suitably for Tcl"), QUOTE_TCL),
OPT_GROUP(""),
OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")),
- OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
+ OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")),
OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
N_("field name to sort on"), &parse_opt_ref_sorting),
OPT_CALLBACK(0, "points-at", &filter.points_at,
@@ -52,16 +52,20 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
memset(&array, 0, sizeof(array));
memset(&filter, 0, sizeof(filter));
+ format.format = "%(objectname) %(objecttype)\t%(refname)";
+
+ git_config(git_default_config, NULL);
+
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);
}
- if (HAS_MULTI_BITS(quote_style)) {
+ if (HAS_MULTI_BITS(format.quote_style)) {
error("more than one quoting style?");
usage_with_options(for_each_ref_usage, opts);
}
- if (verify_ref_format(format))
+ if (verify_ref_format(&format))
usage_with_options(for_each_ref_usage, opts);
if (!sorting)
@@ -69,9 +73,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
sorting->ignore_case = icase;
filter.ignore_case = icase;
- /* for warn_ambiguous_refs */
- git_config(git_default_config, NULL);
-
filter.name_patterns = argv;
filter.match_as_path = 1;
filter_refs(&array, &filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN);
@@ -80,7 +81,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
if (!maxcount || array.nr < maxcount)
maxcount = array.nr;
for (i = 0; i < maxcount; i++)
- show_ref_array_item(array.items[i], format, quote_style);
+ show_ref_array_item(array.items[i], &format);
ref_array_clear(&array);
return 0;
}
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 99dea7adf6..1e4c471b41 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -15,10 +15,13 @@
#include "progress.h"
#include "streaming.h"
#include "decorate.h"
+#include "packfile.h"
#define REACHABLE 0x0001
#define SEEN 0x0002
#define HAS_OBJ 0x0004
+/* This flag is set if something points to this object. */
+#define USED 0x0008
static int show_root;
static int show_tags;
@@ -168,18 +171,7 @@ static void mark_object_reachable(struct object *obj)
static int traverse_one_object(struct object *obj)
{
- int result;
- struct tree *tree = NULL;
-
- if (obj->type == OBJ_TREE) {
- tree = (struct tree *)obj;
- if (parse_tree(tree) < 0)
- return 1; /* error already displayed */
- }
- result = fsck_walk(obj, obj, &fsck_walk_options);
- if (tree)
- free_tree_buffer(tree);
- return result;
+ return fsck_walk(obj, obj, &fsck_walk_options);
}
static int traverse_reachable(void)
@@ -188,7 +180,7 @@ static int traverse_reachable(void)
unsigned int nr = 0;
int result = 0;
if (show_progress)
- progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);
+ progress = start_delayed_progress(_("Checking connectivity"), 0);
while (pending.nr) {
struct object_array_entry *entry;
struct object *obj;
@@ -206,7 +198,7 @@ static int mark_used(struct object *obj, int type, void *data, struct fsck_optio
{
if (!obj)
return 1;
- obj->used = 1;
+ obj->flags |= USED;
return 0;
}
@@ -255,7 +247,7 @@ static void check_unreachable_object(struct object *obj)
}
/*
- * "!used" means that nothing at all points to it, including
+ * "!USED" means that nothing at all points to it, including
* other unreachable objects. In other words, it's the "tip"
* of some set of unreachable objects, usually a commit that
* got dropped.
@@ -266,7 +258,7 @@ static void check_unreachable_object(struct object *obj)
* deleted a branch by mistake, this is a prime candidate to
* start looking at, for example.
*/
- if (!obj->used) {
+ if (!(obj->flags & USED)) {
if (show_dangling)
printf("dangling %s %s\n", printable_type(obj),
describe_object(obj));
@@ -335,6 +327,8 @@ static void check_connectivity(void)
static int fsck_obj(struct object *obj)
{
+ int err;
+
if (obj->flags & SEEN)
return 0;
obj->flags |= SEEN;
@@ -345,20 +339,13 @@ static int fsck_obj(struct object *obj)
if (fsck_walk(obj, NULL, &fsck_obj_options))
objerror(obj, "broken links");
- if (fsck_object(obj, NULL, 0, &fsck_obj_options))
- return -1;
-
- if (obj->type == OBJ_TREE) {
- struct tree *item = (struct tree *) obj;
-
- free_tree_buffer(item);
- }
+ err = fsck_object(obj, NULL, 0, &fsck_obj_options);
+ if (err)
+ goto out;
if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj;
- free_commit_buffer(commit);
-
if (!commit->parents && show_root)
printf("root %s\n", describe_object(&commit->object));
}
@@ -374,7 +361,12 @@ static int fsck_obj(struct object *obj)
}
}
- return 0;
+out:
+ if (obj->type == OBJ_TREE)
+ free_tree_buffer((struct tree *)obj);
+ if (obj->type == OBJ_COMMIT)
+ free_commit_buffer((struct commit *)obj);
+ return err;
}
static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
@@ -390,7 +382,8 @@ static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
errors_found |= ERROR_OBJECT;
return error("%s: object corrupt or missing", oid_to_hex(oid));
}
- obj->flags = HAS_OBJ;
+ obj->flags &= ~(REACHABLE | SEEN);
+ obj->flags |= HAS_OBJ;
return fsck_obj(obj);
}
@@ -408,7 +401,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
add_decoration(fsck_walk_options.object_names,
obj,
xstrfmt("%s@{%"PRItime"}", refname, timestamp));
- obj->used = 1;
+ obj->flags |= USED;
mark_object_reachable(obj);
} else {
error("%s: invalid reflog entry %s", refname, oid_to_hex(oid));
@@ -456,7 +449,7 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
errors_found |= ERROR_REFS;
}
default_refs++;
- obj->used = 1;
+ obj->flags |= USED;
if (name_objects)
add_decoration(fsck_walk_options.object_names,
obj, xstrdup(refname));
@@ -524,7 +517,8 @@ static int fsck_loose(const struct object_id *oid, const char *path, void *data)
return 0; /* keep checking other objects */
}
- obj->flags = HAS_OBJ;
+ obj->flags &= ~(REACHABLE | SEEN);
+ obj->flags |= HAS_OBJ;
if (fsck_obj(obj))
errors_found |= ERROR_OBJECT;
return 0;
@@ -606,7 +600,7 @@ static int fsck_cache_tree(struct cache_tree *it)
errors_found |= ERROR_REFS;
return 1;
}
- obj->used = 1;
+ obj->flags |= USED;
if (name_objects)
add_decoration(fsck_walk_options.object_names,
obj, xstrdup(":"));
@@ -667,7 +661,7 @@ static struct option fsck_opts[] = {
int cmd_fsck(int argc, const char **argv, const char *prefix)
{
- int i, heads;
+ int i;
struct alternate_object_database *alt;
errors_found = 0;
@@ -735,25 +729,23 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
}
}
- heads = 0;
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
- unsigned char sha1[20];
- if (!get_sha1(arg, sha1)) {
- struct object *obj = lookup_object(sha1);
+ struct object_id oid;
+ if (!get_oid(arg, &oid)) {
+ struct object *obj = lookup_object(oid.hash);
if (!obj || !(obj->flags & HAS_OBJ)) {
- error("%s: object missing", sha1_to_hex(sha1));
+ error("%s: object missing", oid_to_hex(&oid));
errors_found |= ERROR_OBJECT;
continue;
}
- obj->used = 1;
+ obj->flags |= USED;
if (name_objects)
add_decoration(fsck_walk_options.object_names,
obj, xstrdup(arg));
mark_object_reachable(obj);
- heads++;
continue;
}
error("invalid parameter: expected sha1, got '%s'", arg);
@@ -785,7 +777,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
if (!blob)
continue;
obj = &blob->object;
- obj->used = 1;
+ obj->flags |= USED;
if (name_objects)
add_decoration(fsck_walk_options.object_names,
obj,
diff --git a/builtin/gc.c b/builtin/gc.c
index e6b84475ae..3c78fcb9b1 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -19,6 +19,7 @@
#include "sigchain.h"
#include "argv-array.h"
#include "commit.h"
+#include "packfile.h"
#define FAILED_RUN "failed to run %s"
diff --git a/builtin/grep.c b/builtin/grep.c
index 7e79eb1a75..19e23946ac 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -28,13 +28,7 @@ static char const * const grep_usage[] = {
NULL
};
-static const char *super_prefix;
static int recurse_submodules;
-static struct argv_array submodule_options = ARGV_ARRAY_INIT;
-static const char *parent_basename;
-
-static int grep_submodule_launch(struct grep_opt *opt,
- const struct grep_source *gs);
#define GREP_NUM_THREADS_DEFAULT 8
static int num_threads;
@@ -186,10 +180,7 @@ static void *run(void *arg)
break;
opt->output_priv = w;
- if (w->source.type == GREP_SOURCE_SUBMODULE)
- hit |= grep_submodule_launch(opt, &w->source);
- else
- hit |= grep_source(opt, &w->source);
+ hit |= grep_source(opt, &w->source);
grep_source_clear_data(&w->source);
work_done(w);
}
@@ -284,7 +275,7 @@ static int wait_all(void)
static int grep_cmd_config(const char *var, const char *value, void *cb)
{
int st = grep_config(var, value, cb);
- if (git_color_default_config(var, value, cb) < 0)
+ if (git_default_config(var, value, cb) < 0)
st = -1;
if (!strcmp(var, "grep.threads")) {
@@ -327,21 +318,13 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
{
struct strbuf pathbuf = STRBUF_INIT;
- if (super_prefix) {
- strbuf_add(&pathbuf, filename, tree_name_len);
- strbuf_addstr(&pathbuf, super_prefix);
- strbuf_addstr(&pathbuf, filename + tree_name_len);
+ if (opt->relative && opt->prefix_length) {
+ quote_path_relative(filename + tree_name_len, opt->prefix, &pathbuf);
+ strbuf_insert(&pathbuf, 0, filename, tree_name_len);
} else {
strbuf_addstr(&pathbuf, filename);
}
- if (opt->relative && opt->prefix_length) {
- char *name = strbuf_detach(&pathbuf, NULL);
- quote_path_relative(name + tree_name_len, opt->prefix, &pathbuf);
- strbuf_insert(&pathbuf, 0, name, tree_name_len);
- free(name);
- }
-
#ifndef NO_PTHREADS
if (num_threads) {
add_work(opt, GREP_SOURCE_OID, pathbuf.buf, path, oid);
@@ -366,15 +349,10 @@ static int grep_file(struct grep_opt *opt, const char *filename)
{
struct strbuf buf = STRBUF_INIT;
- if (super_prefix)
- strbuf_addstr(&buf, super_prefix);
- strbuf_addstr(&buf, filename);
-
- if (opt->relative && opt->prefix_length) {
- char *name = strbuf_detach(&buf, NULL);
- quote_path_relative(name, opt->prefix, &buf);
- free(name);
- }
+ if (opt->relative && opt->prefix_length)
+ quote_path_relative(filename, opt->prefix, &buf);
+ else
+ strbuf_addstr(&buf, filename);
#ifndef NO_PTHREADS
if (num_threads) {
@@ -421,284 +399,89 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
exit(status);
}
-static void compile_submodule_options(const struct grep_opt *opt,
- const char **argv,
- int cached, int untracked,
- int opt_exclude, int use_index,
- int pattern_type_arg)
-{
- struct grep_pat *pattern;
-
- if (recurse_submodules)
- argv_array_push(&submodule_options, "--recurse-submodules");
-
- if (cached)
- argv_array_push(&submodule_options, "--cached");
- if (!use_index)
- argv_array_push(&submodule_options, "--no-index");
- if (untracked)
- argv_array_push(&submodule_options, "--untracked");
- if (opt_exclude > 0)
- argv_array_push(&submodule_options, "--exclude-standard");
-
- if (opt->invert)
- argv_array_push(&submodule_options, "-v");
- if (opt->ignore_case)
- argv_array_push(&submodule_options, "-i");
- if (opt->word_regexp)
- argv_array_push(&submodule_options, "-w");
- switch (opt->binary) {
- case GREP_BINARY_NOMATCH:
- argv_array_push(&submodule_options, "-I");
- break;
- case GREP_BINARY_TEXT:
- argv_array_push(&submodule_options, "-a");
- break;
- default:
- break;
- }
- if (opt->allow_textconv)
- argv_array_push(&submodule_options, "--textconv");
- if (opt->max_depth != -1)
- argv_array_pushf(&submodule_options, "--max-depth=%d",
- opt->max_depth);
- if (opt->linenum)
- argv_array_push(&submodule_options, "-n");
- if (!opt->pathname)
- argv_array_push(&submodule_options, "-h");
- if (!opt->relative)
- argv_array_push(&submodule_options, "--full-name");
- if (opt->name_only)
- argv_array_push(&submodule_options, "-l");
- if (opt->unmatch_name_only)
- argv_array_push(&submodule_options, "-L");
- if (opt->null_following_name)
- argv_array_push(&submodule_options, "-z");
- if (opt->count)
- argv_array_push(&submodule_options, "-c");
- if (opt->file_break)
- argv_array_push(&submodule_options, "--break");
- if (opt->heading)
- argv_array_push(&submodule_options, "--heading");
- if (opt->pre_context)
- argv_array_pushf(&submodule_options, "--before-context=%d",
- opt->pre_context);
- if (opt->post_context)
- argv_array_pushf(&submodule_options, "--after-context=%d",
- opt->post_context);
- if (opt->funcname)
- argv_array_push(&submodule_options, "-p");
- if (opt->funcbody)
- argv_array_push(&submodule_options, "-W");
- if (opt->all_match)
- argv_array_push(&submodule_options, "--all-match");
- if (opt->debug)
- argv_array_push(&submodule_options, "--debug");
- if (opt->status_only)
- argv_array_push(&submodule_options, "-q");
-
- switch (pattern_type_arg) {
- case GREP_PATTERN_TYPE_BRE:
- argv_array_push(&submodule_options, "-G");
- break;
- case GREP_PATTERN_TYPE_ERE:
- argv_array_push(&submodule_options, "-E");
- break;
- case GREP_PATTERN_TYPE_FIXED:
- argv_array_push(&submodule_options, "-F");
- break;
- case GREP_PATTERN_TYPE_PCRE:
- argv_array_push(&submodule_options, "-P");
- break;
- case GREP_PATTERN_TYPE_UNSPECIFIED:
- break;
- default:
- die("BUG: Added a new grep pattern type without updating switch statement");
- }
-
- for (pattern = opt->pattern_list; pattern != NULL;
- pattern = pattern->next) {
- switch (pattern->token) {
- case GREP_PATTERN:
- argv_array_pushf(&submodule_options, "-e%s",
- pattern->pattern);
- break;
- case GREP_AND:
- case GREP_OPEN_PAREN:
- case GREP_CLOSE_PAREN:
- case GREP_NOT:
- case GREP_OR:
- argv_array_push(&submodule_options, pattern->pattern);
- break;
- /* BODY and HEAD are not used by git-grep */
- case GREP_PATTERN_BODY:
- case GREP_PATTERN_HEAD:
- break;
- }
- }
-
- /*
- * Limit number of threads for child process to use.
- * This is to prevent potential fork-bomb behavior of git-grep as each
- * submodule process has its own thread pool.
- */
- argv_array_pushf(&submodule_options, "--threads=%d",
- DIV_ROUND_UP(num_threads, 2));
-
- /* Add Pathspecs */
- argv_array_push(&submodule_options, "--");
- for (; *argv; argv++)
- argv_array_push(&submodule_options, *argv);
-}
+static int grep_cache(struct grep_opt *opt, struct repository *repo,
+ const struct pathspec *pathspec, int cached);
+static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
+ struct tree_desc *tree, struct strbuf *base, int tn_len,
+ int check_attr, struct repository *repo);
-/*
- * Launch child process to grep contents of a submodule
- */
-static int grep_submodule_launch(struct grep_opt *opt,
- const struct grep_source *gs)
+static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
+ const struct pathspec *pathspec,
+ const struct object_id *oid,
+ const char *filename, const char *path)
{
- struct child_process cp = CHILD_PROCESS_INIT;
- int status, i;
- const char *end_of_base;
- const char *name;
- struct strbuf child_output = STRBUF_INIT;
-
- end_of_base = strchr(gs->name, ':');
- if (gs->identifier && end_of_base)
- name = end_of_base + 1;
- else
- name = gs->name;
+ struct repository submodule;
+ int hit;
- prepare_submodule_repo_env(&cp.env_array);
- argv_array_push(&cp.env_array, GIT_DIR_ENVIRONMENT);
+ if (!is_submodule_active(superproject, path))
+ return 0;
- if (opt->relative && opt->prefix_length)
- argv_array_pushf(&cp.env_array, "%s=%s",
- GIT_TOPLEVEL_PREFIX_ENVIRONMENT,
- opt->prefix);
+ if (repo_submodule_init(&submodule, superproject, path))
+ return 0;
- /* Add super prefix */
- argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
- super_prefix ? super_prefix : "",
- name);
- argv_array_push(&cp.args, "grep");
+ repo_read_gitmodules(&submodule);
/*
- * Add basename of parent project
- * When performing grep on a tree object the filename is prefixed
- * with the object's name: 'tree-name:filename'. In order to
- * provide uniformity of output we want to pass the name of the
- * parent project's object name to the submodule so the submodule can
- * prefix its output with the parent's name and not its own OID.
+ * NEEDSWORK: This adds the submodule's object directory to the list of
+ * alternates for the single in-memory object store. This has some bad
+ * consequences for memory (processed objects will never be freed) and
+ * performance (this increases the number of pack files git has to pay
+ * attention to, to the sum of the number of pack files in all the
+ * repositories processed so far). This can be removed once the object
+ * store is no longer global and instead is a member of the repository
+ * object.
*/
- if (gs->identifier && end_of_base)
- argv_array_pushf(&cp.args, "--parent-basename=%.*s",
- (int) (end_of_base - gs->name),
- gs->name);
+ add_to_alternates_memory(submodule.objectdir);
- /* Add options */
- for (i = 0; i < submodule_options.argc; i++) {
- /*
- * If there is a tree identifier for the submodule, add the
- * rev after adding the submodule options but before the
- * pathspecs. To do this we listen for the '--' and insert the
- * oid before pushing the '--' onto the child process argv
- * array.
- */
- if (gs->identifier &&
- !strcmp("--", submodule_options.argv[i])) {
- argv_array_push(&cp.args, oid_to_hex(gs->identifier));
- }
+ if (oid) {
+ struct object *object;
+ struct tree_desc tree;
+ void *data;
+ unsigned long size;
+ struct strbuf base = STRBUF_INIT;
- argv_array_push(&cp.args, submodule_options.argv[i]);
- }
+ object = parse_object_or_die(oid, oid_to_hex(oid));
- cp.git_cmd = 1;
- cp.dir = gs->path;
+ grep_read_lock();
+ data = read_object_with_reference(object->oid.hash, tree_type,
+ &size, NULL);
+ grep_read_unlock();
- /*
- * Capture output to output buffer and check the return code from the
- * child process. A '0' indicates a hit, a '1' indicates no hit and
- * anything else is an error.
- */
- status = capture_command(&cp, &child_output, 0);
- if (status && (status != 1)) {
- /* flush the buffer */
- write_or_die(1, child_output.buf, child_output.len);
- die("process for submodule '%s' failed with exit code: %d",
- gs->name, status);
- }
+ if (!data)
+ die(_("unable to read tree (%s)"), oid_to_hex(&object->oid));
- opt->output(opt, child_output.buf, child_output.len);
- strbuf_release(&child_output);
- /* invert the return code to make a hit equal to 1 */
- return !status;
-}
+ strbuf_addstr(&base, filename);
+ strbuf_addch(&base, '/');
-/*
- * Prep grep structures for a submodule grep
- * oid: the oid of the submodule or NULL if using the working tree
- * filename: name of the submodule including tree name of parent
- * path: location of the submodule
- */
-static int grep_submodule(struct grep_opt *opt, const struct object_id *oid,
- const char *filename, const char *path)
-{
- if (!is_submodule_active(the_repository, path))
- return 0;
- if (!is_submodule_populated_gently(path, NULL)) {
- /*
- * If searching history, check for the presence of the
- * submodule's gitdir before skipping the submodule.
- */
- if (oid) {
- const struct submodule *sub =
- submodule_from_path(null_sha1, path);
- if (sub)
- path = git_path("modules/%s", sub->name);
-
- if (!(is_directory(path) && is_git_directory(path)))
- return 0;
- } else {
- return 0;
- }
+ init_tree_desc(&tree, data, size);
+ hit = grep_tree(opt, pathspec, &tree, &base, base.len,
+ object->type == OBJ_COMMIT, &submodule);
+ strbuf_release(&base);
+ free(data);
+ } else {
+ hit = grep_cache(opt, &submodule, pathspec, 1);
}
-#ifndef NO_PTHREADS
- if (num_threads) {
- add_work(opt, GREP_SOURCE_SUBMODULE, filename, path, oid);
- return 0;
- } else
-#endif
- {
- struct grep_source gs;
- int hit;
-
- grep_source_init(&gs, GREP_SOURCE_SUBMODULE,
- filename, path, oid);
- hit = grep_submodule_launch(opt, &gs);
-
- grep_source_clear(&gs);
- return hit;
- }
+ repo_clear(&submodule);
+ return hit;
}
-static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec,
- int cached)
+static int grep_cache(struct grep_opt *opt, struct repository *repo,
+ const struct pathspec *pathspec, int cached)
{
int hit = 0;
int nr;
struct strbuf name = STRBUF_INIT;
int name_base_len = 0;
- if (super_prefix) {
- name_base_len = strlen(super_prefix);
- strbuf_addstr(&name, super_prefix);
+ if (repo->submodule_prefix) {
+ name_base_len = strlen(repo->submodule_prefix);
+ strbuf_addstr(&name, repo->submodule_prefix);
}
- read_cache();
+ repo_read_index(repo);
- for (nr = 0; nr < active_nr; nr++) {
- const struct cache_entry *ce = active_cache[nr];
+ for (nr = 0; nr < repo->index->cache_nr; nr++) {
+ const struct cache_entry *ce = repo->index->cache[nr];
strbuf_setlen(&name, name_base_len);
strbuf_addstr(&name, ce->name);
@@ -715,14 +498,14 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec,
ce_skip_worktree(ce)) {
if (ce_stage(ce) || ce_intent_to_add(ce))
continue;
- hit |= grep_oid(opt, &ce->oid, ce->name,
- 0, ce->name);
+ hit |= grep_oid(opt, &ce->oid, name.buf,
+ 0, name.buf);
} else {
- hit |= grep_file(opt, ce->name);
+ hit |= grep_file(opt, name.buf);
}
} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
submodule_path_match(pathspec, name.buf, NULL)) {
- hit |= grep_submodule(opt, NULL, ce->name, ce->name);
+ hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);
} else {
continue;
}
@@ -730,8 +513,8 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec,
if (ce_stage(ce)) {
do {
nr++;
- } while (nr < active_nr &&
- !strcmp(ce->name, active_cache[nr]->name));
+ } while (nr < repo->index->cache_nr &&
+ !strcmp(ce->name, repo->index->cache[nr]->name));
nr--; /* compensate for loop control */
}
if (hit && opt->status_only)
@@ -744,7 +527,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec,
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len,
- int check_attr)
+ int check_attr, struct repository *repo)
{
int hit = 0;
enum interesting match = entry_not_interesting;
@@ -752,8 +535,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
int old_baselen = base->len;
struct strbuf name = STRBUF_INIT;
int name_base_len = 0;
- if (super_prefix) {
- strbuf_addstr(&name, super_prefix);
+ if (repo->submodule_prefix) {
+ strbuf_addstr(&name, repo->submodule_prefix);
name_base_len = name.len;
}
@@ -791,11 +574,11 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
strbuf_addch(base, '/');
init_tree_desc(&sub, data, size);
hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
- check_attr);
+ check_attr, repo);
free(data);
} else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
- hit |= grep_submodule(opt, entry.oid, base->buf,
- base->buf + tn_len);
+ hit |= grep_submodule(opt, repo, pathspec, entry.oid,
+ base->buf, base->buf + tn_len);
}
strbuf_setlen(base, old_baselen);
@@ -809,7 +592,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
}
static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
- struct object *obj, const char *name, const char *path)
+ struct object *obj, const char *name, const char *path,
+ struct repository *repo)
{
if (obj->type == OBJ_BLOB)
return grep_oid(opt, &obj->oid, name, 0, path);
@@ -828,10 +612,6 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
if (!data)
die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid));
- /* Use parent's name as base when recursing submodules */
- if (recurse_submodules && parent_basename)
- name = parent_basename;
-
len = name ? strlen(name) : 0;
strbuf_init(&base, PATH_MAX + len + 1);
if (len) {
@@ -840,7 +620,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
}
init_tree_desc(&tree, data, size);
hit = grep_tree(opt, pathspec, &tree, &base, base.len,
- obj->type == OBJ_COMMIT);
+ obj->type == OBJ_COMMIT, repo);
strbuf_release(&base);
free(data);
return hit;
@@ -849,6 +629,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
}
static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
+ struct repository *repo,
const struct object_array *list)
{
unsigned int i;
@@ -862,9 +643,10 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
/* load the gitmodules file for this rev */
if (recurse_submodules) {
submodule_free();
- gitmodules_config_sha1(real_obj->oid.hash);
+ gitmodules_config_oid(&real_obj->oid);
}
- if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].path)) {
+ if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].path,
+ repo)) {
hit = 1;
if (opt->status_only)
break;
@@ -1005,9 +787,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
N_("ignore files specified via '.gitignore'"), 1),
OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
N_("recursively search in each submodule")),
- OPT_STRING(0, "parent-basename", &parent_basename,
- N_("basename"),
- N_("prepend parent project's basename to output")),
OPT_GROUP(""),
OPT_BOOL('v', "invert-match", &opt.invert,
N_("show non-matching lines")),
@@ -1112,7 +891,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
init_grep_defaults();
git_config(grep_cmd_config, NULL);
grep_init(&opt, prefix);
- super_prefix = get_super_prefix();
/*
* If there is no -- then the paths must exist in the working
@@ -1205,8 +983,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
break;
}
- if (get_sha1_with_context(arg, GET_SHA1_RECORD_PATH,
- oid.hash, &oc)) {
+ if (get_oid_with_context(arg, GET_OID_RECORD_PATH,
+ &oid, &oc)) {
if (seen_dashdash)
die(_("unable to resolve revision: %s"), arg);
break;
@@ -1270,13 +1048,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
}
#endif
- if (recurse_submodules) {
- gitmodules_config();
- compile_submodule_options(&opt, argv + i, cached, untracked,
- opt_exclude, use_index,
- pattern_type_arg);
- }
-
if (show_in_pager && (cached || list.nr))
die(_("--open-files-in-pager only works on the worktree"));
@@ -1318,11 +1089,12 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (!cached)
setup_work_tree();
- hit = grep_cache(&opt, &pathspec, cached);
+ hit = grep_cache(&opt, the_repository, &pathspec, cached);
} else {
if (cached)
die(_("both --cached and trees are given."));
- hit = grep_objects(&opt, &pathspec, &list);
+
+ hit = grep_objects(&opt, &pathspec, the_repository, &list);
}
if (num_threads)
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index d04baf999a..c532ff9320 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -16,7 +16,7 @@
* needs to bypass the data conversion performed by, and the type
* limitation imposed by, index_fd() and its callees.
*/
-static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigned flags)
+static int hash_literally(struct object_id *oid, int fd, const char *type, unsigned flags)
{
struct strbuf buf = STRBUF_INIT;
int ret;
@@ -24,7 +24,7 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
if (strbuf_read(&buf, fd, 4096) < 0)
ret = -1;
else
- ret = hash_sha1_file_literally(buf.buf, buf.len, type, sha1, flags);
+ ret = hash_sha1_file_literally(buf.buf, buf.len, type, oid, flags);
strbuf_release(&buf);
return ret;
}
@@ -33,16 +33,16 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
int literally)
{
struct stat st;
- unsigned char sha1[20];
+ struct object_id oid;
if (fstat(fd, &st) < 0 ||
(literally
- ? hash_literally(sha1, fd, type, flags)
- : index_fd(sha1, fd, &st, type_from_string(type), path, flags)))
+ ? hash_literally(&oid, fd, type, flags)
+ : index_fd(&oid, fd, &st, type_from_string(type), path, flags)))
die((flags & HASH_WRITE_OBJECT)
? "Unable to add %s to database"
: "Unable to hash %s", path);
- printf("%s\n", sha1_to_hex(sha1));
+ printf("%s\n", oid_to_hex(&oid));
maybe_flush_or_die(stdout, "hash to stdout");
}
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 26828c1d82..f2be145e12 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -12,6 +12,7 @@
#include "exec_cmd.h"
#include "streaming.h"
#include "thread-utils.h"
+#include "packfile.h"
static const char index_pack_usage[] =
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index 175f14797b..b742539d4d 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -16,34 +16,119 @@ static const char * const git_interpret_trailers_usage[] = {
NULL
};
+static enum trailer_where where;
+static enum trailer_if_exists if_exists;
+static enum trailer_if_missing if_missing;
+
+static int option_parse_where(const struct option *opt,
+ const char *arg, int unset)
+{
+ return trailer_set_where(&where, arg);
+}
+
+static int option_parse_if_exists(const struct option *opt,
+ const char *arg, int unset)
+{
+ return trailer_set_if_exists(&if_exists, arg);
+}
+
+static int option_parse_if_missing(const struct option *opt,
+ const char *arg, int unset)
+{
+ return trailer_set_if_missing(&if_missing, arg);
+}
+
+static void new_trailers_clear(struct list_head *trailers)
+{
+ struct list_head *pos, *tmp;
+ struct new_trailer_item *item;
+
+ list_for_each_safe(pos, tmp, trailers) {
+ item = list_entry(pos, struct new_trailer_item, list);
+ list_del(pos);
+ free(item);
+ }
+}
+
+static int option_parse_trailer(const struct option *opt,
+ const char *arg, int unset)
+{
+ struct list_head *trailers = opt->value;
+ struct new_trailer_item *item;
+
+ if (unset) {
+ new_trailers_clear(trailers);
+ return 0;
+ }
+
+ if (!arg)
+ return -1;
+
+ item = xmalloc(sizeof(*item));
+ item->text = arg;
+ item->where = where;
+ item->if_exists = if_exists;
+ item->if_missing = if_missing;
+ list_add_tail(&item->list, trailers);
+ return 0;
+}
+
+static int parse_opt_parse(const struct option *opt, const char *arg,
+ int unset)
+{
+ struct process_trailer_options *v = opt->value;
+ v->only_trailers = 1;
+ v->only_input = 1;
+ v->unfold = 1;
+ return 0;
+}
+
int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
{
- int in_place = 0;
- int trim_empty = 0;
- struct string_list trailers = STRING_LIST_INIT_NODUP;
+ struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
+ LIST_HEAD(trailers);
struct option options[] = {
- OPT_BOOL(0, "in-place", &in_place, N_("edit files in place")),
- OPT_BOOL(0, "trim-empty", &trim_empty, N_("trim empty trailers")),
- OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"),
- N_("trailer(s) to add")),
+ OPT_BOOL(0, "in-place", &opts.in_place, N_("edit files in place")),
+ OPT_BOOL(0, "trim-empty", &opts.trim_empty, N_("trim empty trailers")),
+
+ OPT_CALLBACK(0, "where", NULL, N_("action"),
+ N_("where to place the new trailer"), option_parse_where),
+ OPT_CALLBACK(0, "if-exists", NULL, N_("action"),
+ N_("action if trailer already exists"), option_parse_if_exists),
+ OPT_CALLBACK(0, "if-missing", NULL, N_("action"),
+ N_("action if trailer is missing"), option_parse_if_missing),
+
+ OPT_BOOL(0, "only-trailers", &opts.only_trailers, N_("output only the trailers")),
+ OPT_BOOL(0, "only-input", &opts.only_input, N_("do not apply config rules")),
+ OPT_BOOL(0, "unfold", &opts.unfold, N_("join whitespace-continued values")),
+ { OPTION_CALLBACK, 0, "parse", &opts, NULL, N_("set parsing options"),
+ PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_parse },
+ OPT_CALLBACK(0, "trailer", &trailers, N_("trailer"),
+ N_("trailer(s) to add"), option_parse_trailer),
OPT_END()
};
argc = parse_options(argc, argv, prefix, options,
git_interpret_trailers_usage, 0);
+ if (opts.only_input && !list_empty(&trailers))
+ usage_msg_opt(
+ _("--trailer with --only-input does not make sense"),
+ git_interpret_trailers_usage,
+ options);
+
if (argc) {
int i;
for (i = 0; i < argc; i++)
- process_trailers(argv[i], in_place, trim_empty, &trailers);
+ process_trailers(argv[i], &opts, &trailers);
} else {
- if (in_place)
+ if (opts.in_place)
die(_("no input file given for in-place editing"));
- process_trailers(NULL, in_place, trim_empty, &trailers);
+ process_trailers(NULL, &opts, &trailers);
}
- string_list_clear(&trailers, 0);
+ new_trailers_clear(&trailers);
return 0;
}
diff --git a/builtin/log.c b/builtin/log.c
index c6362cf92e..f8cccbc964 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -27,6 +27,7 @@
#include "version.h"
#include "mailmap.h"
#include "gpg-interface.h"
+#include "progress.h"
/* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL;
@@ -58,9 +59,9 @@ static int auto_decoration_style(void)
return (isatty(1) || pager_in_use()) ? DECORATE_SHORT_REFS : 0;
}
-static int parse_decoration_style(const char *var, const char *value)
+static int parse_decoration_style(const char *value)
{
- switch (git_config_maybe_bool(var, value)) {
+ switch (git_parse_maybe_bool(value)) {
case 1:
return DECORATE_SHORT_REFS;
case 0:
@@ -82,7 +83,7 @@ static int decorate_callback(const struct option *opt, const char *arg, int unse
if (unset)
decoration_style = 0;
else if (arg)
- decoration_style = parse_decoration_style("command line", arg);
+ decoration_style = parse_decoration_style(arg);
else
decoration_style = DECORATE_SHORT_REFS;
@@ -372,11 +373,14 @@ static int cmd_log_walk(struct rev_info *rev)
*/
rev->max_count++;
if (!rev->reflog_info) {
- /* we allow cycles in reflog ancestry */
+ /*
+ * We may show a given commit multiple times when
+ * walking the reflogs.
+ */
free_commit_buffer(commit);
+ free_commit_list(commit->parents);
+ commit->parents = NULL;
}
- free_commit_list(commit->parents);
- commit->parents = NULL;
if (saved_nrl < rev->diffopt.needed_rename_limit)
saved_nrl = rev->diffopt.needed_rename_limit;
if (rev->diffopt.degraded_cc_to_c)
@@ -409,7 +413,7 @@ static int git_log_config(const char *var, const char *value, void *cb)
if (!strcmp(var, "log.date"))
return git_config_string(&default_date_mode, var, value);
if (!strcmp(var, "log.decorate")) {
- decoration_style = parse_decoration_style(var, value);
+ decoration_style = parse_decoration_style(value);
if (decoration_style < 0)
decoration_style = 0; /* maybe warn? */
return 0;
@@ -484,8 +488,8 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
!DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
return stream_blob_to_fd(1, oid, NULL, 0);
- if (get_sha1_with_context(obj_name, GET_SHA1_RECORD_PATH,
- oidc.hash, &obj_context))
+ if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH,
+ &oidc, &obj_context))
die(_("Not a valid object name %s"), obj_name);
if (!obj_context.path ||
!textconv_object(obj_context.path, obj_context.mode, &oidc, 1, &buf, &size)) {
@@ -821,7 +825,7 @@ static int git_format_config(const char *var, const char *value, void *cb)
return 0;
}
if (!strcmp(var, "format.from")) {
- int b = git_config_maybe_bool(var, value);
+ int b = git_parse_maybe_bool(value);
free(from);
if (b < 0)
from = xstrdup(value);
@@ -1419,6 +1423,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
char *branch_name = NULL;
char *base_commit = NULL;
struct base_tree_info bases;
+ int show_progress = 0;
+ struct progress *progress = NULL;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
@@ -1490,6 +1496,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
OPT_FILENAME(0, "signature-file", &signature_file,
N_("add a signature from a file")),
OPT__QUIET(&quiet, N_("don't print the patch filenames")),
+ OPT_BOOL(0, "progress", &show_progress,
+ N_("show progress while generating patches")),
OPT_END()
};
@@ -1749,8 +1757,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
start_number--;
}
rev.add_signoff = do_signoff;
+
+ if (show_progress)
+ progress = start_delayed_progress(_("Generating patches"), total);
while (0 <= --nr) {
int shown;
+ display_progress(progress, total - nr);
commit = list[nr];
rev.nr = total - nr + (start_number - 1);
/* Make the second and subsequent mails replies to the first */
@@ -1815,6 +1827,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (!use_stdout)
fclose(rev.diffopt.file);
}
+ stop_progress(&progress);
free(list);
free(branch_name);
string_list_clear(&extra_to, 0);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b8514a0029..e1339e6d17 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -19,6 +19,7 @@
#include "pathspec.h"
#include "run-command.h"
#include "submodule.h"
+#include "submodule-config.h"
static int abbrev;
static int show_deleted;
@@ -210,8 +211,6 @@ static void show_submodule(struct repository *superproject,
if (repo_read_index(&submodule) < 0)
die("index file corrupt");
- repo_read_gitmodules(&submodule);
-
show_files(&submodule, dir);
repo_clear(&submodule);
@@ -362,7 +361,7 @@ static void prune_index(struct index_state *istate,
int pos;
unsigned int first, last;
- if (!prefix)
+ if (!prefix || !istate->cache_nr)
return;
pos = index_name_pos(istate, prefix, prefixlen);
if (pos < 0)
@@ -378,8 +377,7 @@ static void prune_index(struct index_state *istate,
}
last = next;
}
- memmove(istate->cache, istate->cache + pos,
- (last - pos) * sizeof(struct cache_entry *));
+ MOVE_ARRAY(istate->cache, istate->cache + pos, last - pos);
istate->cache_nr = last - pos;
}
@@ -610,9 +608,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
if (require_work_tree && !is_inside_work_tree())
setup_work_tree();
- if (recurse_submodules)
- repo_read_gitmodules(the_repository);
-
if (recurse_submodules &&
(show_stage || show_deleted || show_others || show_unmerged ||
show_killed || show_modified || show_resolve_undo || with_tree))
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index bad6735c76..d01ddecf66 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -213,11 +213,11 @@ static void unresolved_directory(const struct traverse_info *info,
newbase = traverse_path(info, p);
-#define ENTRY_SHA1(e) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->oid->hash : NULL)
- buf0 = fill_tree_descriptor(t+0, ENTRY_SHA1(n + 0));
- buf1 = fill_tree_descriptor(t+1, ENTRY_SHA1(n + 1));
- buf2 = fill_tree_descriptor(t+2, ENTRY_SHA1(n + 2));
-#undef ENTRY_SHA1
+#define ENTRY_OID(e) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->oid : NULL)
+ buf0 = fill_tree_descriptor(t + 0, ENTRY_OID(n + 0));
+ buf1 = fill_tree_descriptor(t + 1, ENTRY_OID(n + 1));
+ buf2 = fill_tree_descriptor(t + 2, ENTRY_OID(n + 2));
+#undef ENTRY_OID
merge_trees(t, newbase);
@@ -347,12 +347,12 @@ static void merge_trees(struct tree_desc t[3], const char *base)
static void *get_tree_descriptor(struct tree_desc *desc, const char *rev)
{
- unsigned char sha1[20];
+ struct object_id oid;
void *buf;
- if (get_sha1(rev, sha1))
+ if (get_oid(rev, &oid))
die("unknown rev %s", rev);
- buf = fill_tree_descriptor(desc, sha1);
+ buf = fill_tree_descriptor(desc, &oid);
if (!buf)
die("%s is not a tree", rev);
return buf;
diff --git a/builtin/merge.c b/builtin/merge.c
index a0789c798f..3672e38974 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -32,6 +32,7 @@
#include "gpg-interface.h"
#include "sequencer.h"
#include "string-list.h"
+#include "packfile.h"
#define DEFAULT_TWOHEAD (1<<0)
#define DEFAULT_OCTOPUS (1<<1)
@@ -70,6 +71,7 @@ static int continue_current_merge;
static int allow_unrelated_histories;
static int show_progress = -1;
static int default_to_upstream = 1;
+static int signoff;
static const char *sign_commit;
static struct strategy all_strategy[] = {
@@ -233,6 +235,7 @@ static struct option builtin_merge_options[] = {
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
+ OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")),
OPT_END()
};
@@ -537,7 +540,7 @@ static void parse_branch_merge_options(char *bmo)
die(_("Bad branch.%s.mergeoptions string: %s"), branch,
split_cmdline_strerror(argc));
REALLOC_ARRAY(argv, argc + 2);
- memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
+ MOVE_ARRAY(argv + 1, argv, argc + 1);
argc++;
argv[0] = "branch.*.mergeoptions";
parse_options(argc, argv, NULL, builtin_merge_options,
@@ -566,7 +569,7 @@ static int git_merge_config(const char *k, const char *v, void *cb)
else if (!strcmp(k, "merge.renormalize"))
option_renormalize = git_config_bool(k, v);
else if (!strcmp(k, "merge.ff")) {
- int boolval = git_config_maybe_bool(k, v);
+ int boolval = git_parse_maybe_bool(v);
if (0 <= boolval) {
fast_forward = boolval ? FF_ALLOW : FF_NO;
} else if (v && !strcmp(v, "only")) {
@@ -756,13 +759,19 @@ N_("Please enter a commit message to explain why this merge is necessary,\n"
"Lines starting with '%c' will be ignored, and an empty message aborts\n"
"the commit.\n");
+static void write_merge_heads(struct commit_list *);
static void prepare_to_commit(struct commit_list *remoteheads)
{
struct strbuf msg = STRBUF_INIT;
strbuf_addbuf(&msg, &merge_msg);
strbuf_addch(&msg, '\n');
+ if (squash)
+ BUG("the control must not reach here under --squash");
if (0 < option_edit)
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
+ if (signoff)
+ append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0);
+ write_merge_heads(remoteheads);
write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
git_path_merge_msg(), "merge", NULL))
@@ -904,7 +913,7 @@ static int setup_with_upstream(const char ***argv)
return i;
}
-static void write_merge_state(struct commit_list *remoteheads)
+static void write_merge_heads(struct commit_list *remoteheads)
{
struct commit_list *j;
struct strbuf buf = STRBUF_INIT;
@@ -920,8 +929,6 @@ static void write_merge_state(struct commit_list *remoteheads)
strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
}
write_file_buf(git_path_merge_head(), buf.buf, buf.len);
- strbuf_addch(&merge_msg, '\n');
- write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
strbuf_reset(&buf);
if (fast_forward == FF_NO)
@@ -929,6 +936,13 @@ static void write_merge_state(struct commit_list *remoteheads)
write_file_buf(git_path_merge_mode(), buf.buf, buf.len);
}
+static void write_merge_state(struct commit_list *remoteheads)
+{
+ write_merge_heads(remoteheads);
+ strbuf_addch(&merge_msg, '\n');
+ write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
+}
+
static int default_edit_option(void)
{
static const char name[] = "GIT_MERGE_AUTOEDIT";
@@ -940,7 +954,7 @@ static int default_edit_option(void)
return 0;
if (e) {
- int v = git_config_maybe_bool(name, e);
+ int v = git_parse_maybe_bool(e);
if (v < 0)
die(_("Bad value '%s' in environment '%s'"), e, name);
return v;
@@ -1117,8 +1131,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* current branch.
*/
branch = branch_to_free = resolve_refdup("HEAD", 0, head_oid.hash, NULL);
- if (branch && starts_with(branch, "refs/heads/"))
- branch += 11;
+ if (branch)
+ skip_prefix(branch, "refs/heads/", &branch);
if (!branch || is_null_oid(&head_oid))
head_commit = NULL;
else
diff --git a/builtin/mv.c b/builtin/mv.c
index dcf6736b5b..ffdd5f01a1 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -81,7 +81,7 @@ static void prepare_move_submodule(const char *src, int first,
struct strbuf submodule_dotgit = STRBUF_INIT;
if (!S_ISGITLINK(active_cache[first]->ce_mode))
die(_("Directory %s is in index and no submodule?"), src);
- if (!is_staging_gitmodules_ok())
+ if (!is_staging_gitmodules_ok(&the_index))
die(_("Please stage your changes to .gitmodules or stash them to proceed"));
strbuf_addf(&submodule_dotgit, "%s/.git", src);
*submodule_gitfile = read_gitfile(submodule_dotgit.buf);
@@ -131,7 +131,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
struct stat st;
struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
- gitmodules_config();
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_mv_options,
diff --git a/builtin/notes.c b/builtin/notes.c
index 77573cf1ea..4303848e04 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -456,7 +456,7 @@ static int add(int argc, const char **argv, const char *prefix)
oid_to_hex(&object));
}
- prepare_note_data(&object, &d, note->hash);
+ prepare_note_data(&object, &d, note ? note->hash : NULL);
if (d.buf.len || allow_empty) {
write_note_data(&d, new_note.hash);
if (add_note(t, &object, &new_note, combine_notes_overwrite))
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index f4a8441fe9..a57b4f058d 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -25,6 +25,7 @@
#include "sha1-array.h"
#include "argv-array.h"
#include "mru.h"
+#include "packfile.h"
static const char *pack_usage[] = {
N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
@@ -1289,7 +1290,7 @@ static int done_pbase_path_pos(unsigned hash)
static int check_pbase_path(unsigned hash)
{
- int pos = (!done_pbase_paths) ? -1 : done_pbase_path_pos(hash);
+ int pos = done_pbase_path_pos(hash);
if (0 <= pos)
return 1;
pos = -pos - 1;
@@ -1298,9 +1299,8 @@ static int check_pbase_path(unsigned hash)
done_pbase_paths_alloc);
done_pbase_paths_num++;
if (pos < done_pbase_paths_num)
- memmove(done_pbase_paths + pos + 1,
- done_pbase_paths + pos,
- (done_pbase_paths_num - pos - 1) * sizeof(unsigned));
+ MOVE_ARRAY(done_pbase_paths + pos + 1, done_pbase_paths + pos,
+ done_pbase_paths_num - pos - 1);
done_pbase_paths[pos] = hash;
return 0;
}
@@ -2171,7 +2171,10 @@ static void *threaded_find_deltas(void *arg)
{
struct thread_params *me = arg;
+ progress_lock();
while (me->remaining) {
+ progress_unlock();
+
find_deltas(me->list, &me->remaining,
me->window, me->depth, me->processed);
@@ -2193,7 +2196,10 @@ static void *threaded_find_deltas(void *arg)
pthread_cond_wait(&me->cond, &me->mutex);
me->data_ready = 0;
pthread_mutex_unlock(&me->mutex);
+
+ progress_lock();
}
+ progress_unlock();
/* leave ->working 1 so that this doesn't get more work assigned */
return NULL;
}
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index cb1df1c761..aaa8136322 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -7,6 +7,7 @@
*/
#include "builtin.h"
+#include "packfile.h"
#define BLKSIZE 512
diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c
index ac978ad401..419238171d 100644
--- a/builtin/prune-packed.c
+++ b/builtin/prune-packed.c
@@ -2,6 +2,7 @@
#include "cache.h"
#include "progress.h"
#include "parse-options.h"
+#include "packfile.h"
static const char * const prune_packed_usage[] = {
N_("git prune-packed [-n | --dry-run] [-q | --quiet]"),
@@ -37,8 +38,7 @@ static int prune_object(const struct object_id *oid, const char *path,
void prune_packed_objects(int opts)
{
if (opts & PRUNE_PACKED_VERBOSE)
- progress = start_progress_delay(_("Removing duplicate objects"),
- 256, 95, 2);
+ progress = start_delayed_progress(_("Removing duplicate objects"), 256);
for_each_loose_file_in_objdir(get_object_directory(),
prune_object, NULL, prune_subdir, &opts);
diff --git a/builtin/prune.c b/builtin/prune.c
index c378690545..cddabf26a9 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -138,7 +138,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
if (show_progress == -1)
show_progress = isatty(2);
if (show_progress)
- progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);
+ progress = start_delayed_progress(_("Checking connectivity"), 0);
mark_reachable_objects(&revs, 1, expire, progress);
stop_progress(&progress);
diff --git a/builtin/pull.c b/builtin/pull.c
index 9b86e519b1..7fe281414e 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -39,7 +39,7 @@ enum rebase_type {
static enum rebase_type parse_config_rebase(const char *key, const char *value,
int fatal)
{
- int v = git_config_maybe_bool("pull.rebase", value);
+ int v = git_parse_maybe_bool(value);
if (!v)
return REBASE_FALSE;
@@ -274,7 +274,7 @@ static const char *config_get_ff(void)
if (git_config_get_value("pull.ff", &value))
return NULL;
- switch (git_config_maybe_bool("pull.ff", value)) {
+ switch (git_parse_maybe_bool(value)) {
case 0:
return "--no-ff";
case 1:
diff --git a/builtin/push.c b/builtin/push.c
index 03846e8379..2ac8104229 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -481,7 +481,7 @@ static int git_push_config(const char *k, const char *v, void *cb)
} else if (!strcmp(k, "push.gpgsign")) {
const char *value;
if (!git_config_get_value("push.gpgsign", &value)) {
- switch (git_config_maybe_bool("push.gpgsign", value)) {
+ switch (git_parse_maybe_bool(value)) {
case 0:
set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER);
break;
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index d5f618d086..bf87a2710b 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -164,8 +164,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
argc = parse_options(argc, argv, unused_prefix, read_tree_options,
read_tree_usage, 0);
- load_submodule_cache();
-
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
prefix_set = opts.prefix ? 1 : 0;
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index cabdc55e09..52c63ebfdc 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -23,6 +23,7 @@
#include "fsck.h"
#include "tmp-objdir.h"
#include "oidset.h"
+#include "packfile.h"
static const char * const receive_pack_usage[] = {
N_("git receive-pack <git-dir>"),
@@ -919,9 +920,9 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
*/
static int head_has_history(void)
{
- unsigned char sha1[20];
+ struct object_id oid;
- return !get_sha1("HEAD", sha1);
+ return !get_oid("HEAD", &oid);
}
static const char *push_to_deploy(unsigned char *sha1,
@@ -1138,7 +1139,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
}
if (ref_transaction_delete(transaction,
namespaced_name,
- old_oid->hash,
+ old_oid ? old_oid->hash : NULL,
0, "push", &err)) {
rp_error("%s", err.buf);
strbuf_release(&err);
diff --git a/builtin/remote.c b/builtin/remote.c
index 6273c0c23c..a995ea86c1 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -301,7 +301,7 @@ static int config_read_branches(const char *key, const char *value, void *cb)
}
string_list_append(&info->merge, xstrdup(value));
} else {
- int v = git_config_maybe_bool(orig_key, value);
+ int v = git_parse_maybe_bool(value);
if (v >= 0)
info->rebase = v;
else if (!strcmp(value, "preserve"))
diff --git a/builtin/replace.c b/builtin/replace.c
index fba336a68a..3e71a77152 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -50,7 +50,7 @@ static int show_reference(const char *refname, const struct object_id *oid,
struct object_id object;
enum object_type obj_type, repl_type;
- if (get_sha1(refname, object.hash))
+ if (get_oid(refname, &object))
return error("Failed to resolve '%s' as a valid ref.", refname);
obj_type = sha1_object_info(object.hash, NULL);
@@ -269,7 +269,7 @@ static void import_object(struct object_id *oid, enum object_type type,
if (fstat(fd, &st) < 0)
die_errno("unable to fstat %s", filename);
- if (index_fd(oid->hash, fd, &st, type, NULL, flags) < 0)
+ if (index_fd(oid, fd, &st, type, NULL, flags) < 0)
die("unable to write object to database");
/* index_fd close()s fd for us */
}
@@ -365,7 +365,7 @@ static void check_one_mergetag(struct commit *commit,
/* iterate over new parents */
for (i = 1; i < mergetag_data->argc; i++) {
struct object_id oid;
- if (get_sha1(mergetag_data->argv[i], oid.hash) < 0)
+ if (get_oid(mergetag_data->argv[i], &oid) < 0)
die(_("Not a valid object name: '%s'"), mergetag_data->argv[i]);
if (!oidcmp(&tag->tagged->oid, &oid))
return; /* found */
diff --git a/builtin/reset.c b/builtin/reset.c
index 7aeaea2737..d72c7d1c96 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -75,13 +75,13 @@ static int reset_index(const struct object_id *oid, int reset_type, int quiet)
struct object_id head_oid;
if (get_oid("HEAD", &head_oid))
return error(_("You do not have a valid HEAD."));
- if (!fill_tree_descriptor(desc, head_oid.hash))
+ if (!fill_tree_descriptor(desc, &head_oid))
return error(_("Failed to find tree of HEAD."));
nr++;
opts.fn = twoway_merge;
}
- if (!fill_tree_descriptor(desc + nr - 1, oid->hash))
+ if (!fill_tree_descriptor(desc + nr - 1, oid))
return error(_("Failed to find tree of %s."), oid_to_hex(oid));
if (unpack_trees(nr, desc, &opts))
return -1;
@@ -156,6 +156,7 @@ static int read_from_tree(const struct pathspec *pathspec,
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
opt.format_callback_data = &intent_to_add;
+ opt.flags |= DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
if (do_diff_cache(tree_oid, &opt))
return 1;
@@ -219,8 +220,8 @@ static void parse_args(struct pathspec *pathspec,
* has to be unambiguous. If there is a single argument, it
* can not be a tree
*/
- else if ((!argv[1] && !get_sha1_committish(argv[0], unused.hash)) ||
- (argv[1] && !get_sha1_treeish(argv[0], unused.hash))) {
+ else if ((!argv[1] && !get_oid_committish(argv[0], &unused)) ||
+ (argv[1] && !get_oid_treeish(argv[0], &unused))) {
/*
* Ok, argv[0] looks like a commit/tree; it should not
* be a filename.
@@ -308,15 +309,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_DASHDASH);
parse_args(&pathspec, argv, prefix, patch_mode, &rev);
- load_submodule_cache();
-
- unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", oid.hash);
+ unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid);
if (unborn) {
/* reset on unborn branch: treat as reset to empty tree */
hashcpy(oid.hash, EMPTY_TREE_SHA1_BIN);
} else if (!pathspec.nr) {
struct commit *commit;
- if (get_sha1_committish(rev, oid.hash))
+ if (get_oid_committish(rev, &oid))
die(_("Failed to resolve '%s' as a valid revision."), rev);
commit = lookup_commit_reference(&oid);
if (!commit)
@@ -324,7 +323,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
oidcpy(&oid, &commit->object.oid);
} else {
struct tree *tree;
- if (get_sha1_treeish(rev, oid.hash))
+ if (get_oid_treeish(rev, &oid))
die(_("Failed to resolve '%s' as a valid tree."), rev);
tree = parse_tree_indirect(&oid);
if (!tree)
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 95d84d5cda..c1c74d4a79 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -11,6 +11,7 @@
#include "graph.h"
#include "bisect.h"
#include "progress.h"
+#include "reflog-walk.h"
static const char rev_list_usage[] =
"git rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
@@ -122,6 +123,7 @@ static void show_commit(struct commit *commit, void *data)
ctx.date_mode_explicit = revs->date_mode_explicit;
ctx.fmt = revs->commit_format;
ctx.output_encoding = get_log_output_encoding();
+ ctx.color = revs->diffopt.use_color;
pretty_print_commit(&ctx, commit, &buf);
if (buf.len) {
if (revs->commit_format != CMIT_FMT_ONELINE)
@@ -348,9 +350,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
/* Only --header was specified */
revs.commit_format = CMIT_FMT_RAW;
- if ((!revs.commits &&
+ if ((!revs.commits && reflog_walk_empty(revs.reflog_info) &&
(!(revs.tag_objects || revs.tree_objects || revs.blob_objects) &&
- !revs.pending.nr)) ||
+ !revs.pending.nr) &&
+ !revs.rev_input_given) ||
revs.diff)
usage(rev_list_usage);
@@ -364,7 +367,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
revs.limited = 1;
if (show_progress)
- progress = start_progress_delay(show_progress, 0, 0, 2);
+ progress = start_delayed_progress(show_progress, 0);
if (use_bitmap_index && !revs.prune) {
if (revs.count && !revs.left_right && !revs.cherry_mark) {
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index c78b7b33d6..2bd28d3c08 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -274,7 +274,7 @@ static int try_difference(const char *arg)
return 0;
}
- if (!get_sha1_committish(this, oid.hash) && !get_sha1_committish(next, end.hash)) {
+ if (!get_oid_committish(this, &oid) && !get_oid_committish(next, &end)) {
show_rev(NORMAL, &end, next);
show_rev(symmetric ? NORMAL : REVERSED, &oid, this);
if (symmetric) {
@@ -328,7 +328,7 @@ static int try_parent_shorthands(const char *arg)
return 0;
*dotdot = 0;
- if (get_sha1_committish(arg, oid.hash)) {
+ if (get_oid_committish(arg, &oid)) {
*dotdot = '^';
return 0;
}
@@ -702,7 +702,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) {
quiet = 1;
- flags |= GET_SHA1_QUIETLY;
+ flags |= GET_OID_QUIETLY;
continue;
}
if (opt_with_value(arg, "--short", &arg)) {
@@ -911,7 +911,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
name++;
type = REVERSED;
}
- if (!get_sha1_with_context(name, flags, oid.hash, &unused)) {
+ if (!get_oid_with_context(name, flags, &oid, &unused)) {
if (verify)
revs_count++;
else
diff --git a/builtin/revert.c b/builtin/revert.c
index 16028b9ea8..b9d927eb09 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -155,6 +155,8 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
"--strategy-option", opts->xopts ? 1 : 0,
"-x", opts->record_origin,
"--ff", opts->allow_ff,
+ "--rerere-autoupdate", opts->allow_rerere_auto == RERERE_AUTOUPDATE,
+ "--no-rerere-autoupdate", opts->allow_rerere_auto == RERERE_NOAUTOUPDATE,
NULL);
}
diff --git a/builtin/rm.c b/builtin/rm.c
index 52826d1379..d91451fea1 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -255,7 +255,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
struct pathspec pathspec;
char *seen;
- gitmodules_config();
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_rm_options,
@@ -286,7 +285,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
list.entry[list.nr].name = xstrdup(ce->name);
list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
if (list.entry[list.nr++].is_submodule &&
- !is_staging_gitmodules_ok())
+ !is_staging_gitmodules_ok(&the_index))
die (_("Please stage your changes to .gitmodules or stash them to proceed"));
}
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 633e0c3cdd..fc4f0bb5fb 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -105,7 +105,7 @@ static int send_pack_config(const char *k, const char *v, void *cb)
if (!strcmp(k, "push.gpgsign")) {
const char *value;
if (!git_config_get_value("push.gpgsign", &value)) {
- switch (git_config_maybe_bool("push.gpgsign", value)) {
+ switch (git_parse_maybe_bool(value)) {
case 0:
args.push_cert = SEND_PACK_PUSH_CERT_NEVER;
break;
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 7073a3eb97..84547d6fba 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -393,7 +393,7 @@ static int append_head_ref(const char *refname, const struct object_id *oid,
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
- if (get_sha1(refname + ofs, tmp.hash) || oidcmp(&tmp, oid))
+ if (get_oid(refname + ofs, &tmp) || oidcmp(&tmp, oid))
ofs = 5;
return append_ref(refname + ofs, oid, 0);
}
@@ -408,7 +408,7 @@ static int append_remote_ref(const char *refname, const struct object_id *oid,
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
- if (get_sha1(refname + ofs, tmp.hash) || oidcmp(&tmp, oid))
+ if (get_oid(refname + ofs, &tmp) || oidcmp(&tmp, oid))
ofs = 5;
return append_ref(refname + ofs, oid, 0);
}
@@ -514,7 +514,7 @@ static int show_independent(struct commit **rev,
static void append_one_rev(const char *av)
{
struct object_id revkey;
- if (!get_sha1(av, revkey.hash)) {
+ if (!get_oid(av, &revkey)) {
append_ref(av, &revkey, 0);
return;
}
@@ -554,7 +554,7 @@ static int git_show_branch_config(const char *var, const char *value, void *cb)
return 0;
}
- return git_color_default_config(var, value, cb);
+ return git_default_config(var, value, cb);
}
static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
@@ -808,7 +808,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
die(Q_("cannot handle more than %d rev.",
"cannot handle more than %d revs.",
MAX_REVS), MAX_REVS);
- if (get_sha1(ref_name[num_rev], revkey.hash))
+ if (get_oid(ref_name[num_rev], &revkey))
die(_("'%s' is not a valid ref."), ref_name[num_rev]);
commit = lookup_commit_reference(&revkey);
if (!commit)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 6abdad3294..818fe74f0a 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -275,8 +275,6 @@ static void module_list_active(struct module_list *list)
int i;
struct module_list active_modules = MODULE_LIST_INIT;
- gitmodules_config();
-
for (i = 0; i < list->nr; i++) {
const struct cache_entry *ce = list->entries[i];
@@ -337,9 +335,6 @@ static void init_submodule(const char *path, const char *prefix, int quiet)
struct strbuf sb = STRBUF_INIT;
char *upd = NULL, *url = NULL, *displaypath;
- /* Only loads from .gitmodules, no overlay with .git/config */
- gitmodules_config();
-
if (prefix && get_super_prefix())
die("BUG: cannot have prefix and superprefix");
else if (prefix)
@@ -350,7 +345,7 @@ static void init_submodule(const char *path, const char *prefix, int quiet)
} else
displaypath = xstrdup(path);
- sub = submodule_from_path(null_sha1, path);
+ sub = submodule_from_path(&null_oid, path);
if (!sub)
die(_("No url found for submodule path '%s' in .gitmodules"),
@@ -475,8 +470,7 @@ static int module_name(int argc, const char **argv, const char *prefix)
if (argc != 2)
usage(_("git submodule--helper name <path>"));
- gitmodules_config();
- sub = submodule_from_path(null_sha1, argv[1]);
+ sub = submodule_from_path(&null_oid, argv[1]);
if (!sub)
die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -780,6 +774,10 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
struct strbuf *out)
{
const struct submodule *sub = NULL;
+ const char *url = NULL;
+ const char *update_string;
+ enum submodule_update_type update_type;
+ char *key;
struct strbuf displaypath_sb = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
const char *displaypath = NULL;
@@ -795,7 +793,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
goto cleanup;
}
- sub = submodule_from_path(null_sha1, ce->name);
+ sub = submodule_from_path(&null_oid, ce->name);
if (suc->recursive_prefix)
displaypath = relative_path(suc->recursive_prefix,
@@ -808,9 +806,17 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
goto cleanup;
}
+ key = xstrfmt("submodule.%s.update", sub->name);
+ if (!repo_config_get_string_const(the_repository, key, &update_string)) {
+ update_type = parse_submodule_update_type(update_string);
+ } else {
+ update_type = sub->update_strategy.type;
+ }
+ free(key);
+
if (suc->update.type == SM_UPDATE_NONE
|| (suc->update.type == SM_UPDATE_UNSPECIFIED
- && sub->update_strategy.type == SM_UPDATE_NONE)) {
+ && update_type == SM_UPDATE_NONE)) {
strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
strbuf_addch(out, '\n');
goto cleanup;
@@ -823,6 +829,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
}
strbuf_reset(&sb);
+ strbuf_addf(&sb, "submodule.%s.url", sub->name);
+ if (repo_config_get_string_const(the_repository, sb.buf, &url))
+ url = sub->url;
+
+ strbuf_reset(&sb);
strbuf_addf(&sb, "%s/.git", ce->name);
needs_cloning = !file_exists(sb.buf);
@@ -851,7 +862,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
argv_array_push(&child->args, "--depth=1");
argv_array_pushl(&child->args, "--path", sub->path, NULL);
argv_array_pushl(&child->args, "--name", sub->name, NULL);
- argv_array_pushl(&child->args, "--url", sub->url, NULL);
+ argv_array_pushl(&child->args, "--url", url, NULL);
if (suc->references.nr) {
struct string_list_item *item;
for_each_string_list_item(item, &suc->references)
@@ -930,7 +941,7 @@ static int update_clone_task_finished(int result,
const struct cache_entry *ce;
struct submodule_update_clone *suc = suc_cb;
- int *idxP = *(int**)idx_task_cb;
+ int *idxP = idx_task_cb;
int idx = *idxP;
free(idxP);
@@ -960,10 +971,19 @@ static int update_clone_task_finished(int result,
return 0;
}
+static int gitmodules_update_clone_config(const char *var, const char *value,
+ void *cb)
+{
+ int *max_jobs = cb;
+ if (!strcmp(var, "submodule.fetchjobs"))
+ *max_jobs = parse_submodule_fetchjobs(var, value);
+ return 0;
+}
+
static int update_clone(int argc, const char **argv, const char *prefix)
{
const char *update = NULL;
- int max_jobs = -1;
+ int max_jobs = 1;
struct string_list_item *item;
struct pathspec pathspec;
struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
@@ -1000,6 +1020,9 @@ static int update_clone(int argc, const char **argv, const char *prefix)
};
suc.prefix = prefix;
+ config_from_gitmodules(gitmodules_update_clone_config, &max_jobs);
+ git_config(gitmodules_update_clone_config, &max_jobs);
+
argc = parse_options(argc, argv, prefix, module_update_clone_options,
git_submodule_helper_usage, 0);
@@ -1013,13 +1036,6 @@ static int update_clone(int argc, const char **argv, const char *prefix)
if (pathspec.nr)
suc.warn_if_uninitialized = 1;
- /* Overlay the parsed .gitmodules file with .git/config */
- gitmodules_config();
- git_config(submodule_config, NULL);
-
- if (max_jobs < 0)
- max_jobs = parallel_submodules();
-
run_processes_parallel(max_jobs,
update_clone_get_next_task,
update_clone_start_failure,
@@ -1057,17 +1073,22 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix
static const char *remote_submodule_branch(const char *path)
{
const struct submodule *sub;
- gitmodules_config();
- git_config(submodule_config, NULL);
+ const char *branch = NULL;
+ char *key;
- sub = submodule_from_path(null_sha1, path);
+ sub = submodule_from_path(&null_oid, path);
if (!sub)
return NULL;
- if (!sub->branch)
+ key = xstrfmt("submodule.%s.branch", sub->name);
+ if (repo_config_get_string_const(the_repository, key, &branch))
+ branch = sub->branch;
+ free(key);
+
+ if (!branch)
return "master";
- if (!strcmp(sub->branch, ".")) {
+ if (!strcmp(branch, ".")) {
unsigned char sha1[20];
const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
@@ -1085,7 +1106,7 @@ static const char *remote_submodule_branch(const char *path)
return refname;
}
- return sub->branch;
+ return branch;
}
static int resolve_remote_submodule_branch(int argc, const char **argv,
@@ -1108,9 +1129,28 @@ static int resolve_remote_submodule_branch(int argc, const char **argv,
static int push_check(int argc, const char **argv, const char *prefix)
{
struct remote *remote;
+ const char *superproject_head;
+ char *head;
+ int detached_head = 0;
+ struct object_id head_oid;
+
+ if (argc < 3)
+ die("submodule--helper push-check requires at least 2 arguments");
- if (argc < 2)
- die("submodule--helper push-check requires at least 1 argument");
+ /*
+ * superproject's resolved head ref.
+ * if HEAD then the superproject is in a detached head state, otherwise
+ * it will be the resolved head ref.
+ */
+ superproject_head = argv[1];
+ argv++;
+ argc--;
+ /* Get the submodule's head ref and determine if it is detached */
+ head = resolve_refdup("HEAD", 0, head_oid.hash, NULL);
+ if (!head)
+ die(_("Failed to resolve HEAD as a valid ref."));
+ if (!strcmp(head, "HEAD"))
+ detached_head = 1;
/*
* The remote must be configured.
@@ -1133,18 +1173,30 @@ static int push_check(int argc, const char **argv, const char *prefix)
if (rs->pattern || rs->matching)
continue;
- /*
- * LHS must match a single ref
- * NEEDSWORK: add logic to special case 'HEAD' once
- * working with submodules in a detached head state
- * ceases to be the norm.
- */
- if (count_refspec_match(rs->src, local_refs, NULL) != 1)
+ /* LHS must match a single ref */
+ switch (count_refspec_match(rs->src, local_refs, NULL)) {
+ case 1:
+ break;
+ case 0:
+ /*
+ * If LHS matches 'HEAD' then we need to ensure
+ * that it matches the same named branch
+ * checked out in the superproject.
+ */
+ if (!strcmp(rs->src, "HEAD")) {
+ if (!detached_head &&
+ !strcmp(head, superproject_head))
+ break;
+ die("HEAD does not match the named branch in the superproject");
+ }
+ default:
die("src refspec '%s' must name a ref",
rs->src);
+ }
}
free_refspec(refspec_nr, refspec);
}
+ free(head);
return 0;
}
@@ -1173,9 +1225,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, embed_gitdir_options,
git_submodule_helper_usage, 0);
- gitmodules_config();
- git_config(submodule_config, NULL);
-
if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
return 1;
@@ -1191,8 +1240,6 @@ static int is_active(int argc, const char **argv, const char *prefix)
if (argc != 2)
die("submodule--helper is-active takes exactly 1 argument");
- gitmodules_config();
-
return !is_submodule_active(the_repository, argv[1]);
}
diff --git a/builtin/tag.c b/builtin/tag.c
index 01154ea8dc..c627794181 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -32,7 +32,8 @@ static const char * const git_tag_usage[] = {
static unsigned int colopts;
static int force_sign_annotate;
-static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format)
+static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
+ struct ref_format *format)
{
struct ref_array array;
char *to_free = NULL;
@@ -43,23 +44,24 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con
if (filter->lines == -1)
filter->lines = 0;
- if (!format) {
+ if (!format->format) {
if (filter->lines) {
to_free = xstrfmt("%s %%(contents:lines=%d)",
"%(align:15)%(refname:lstrip=2)%(end)",
filter->lines);
- format = to_free;
+ format->format = to_free;
} else
- format = "%(refname:lstrip=2)";
+ format->format = "%(refname:lstrip=2)";
}
- verify_ref_format(format);
+ if (verify_ref_format(format))
+ die(_("unable to parse format string"));
filter->with_commit_tag_algo = 1;
filter_refs(&array, filter, FILTER_REFS_TAGS);
ref_array_sort(sorting, &array);
for (i = 0; i < array.nr; i++)
- show_ref_array_item(array.items[i], format, 0);
+ show_ref_array_item(array.items[i], format);
ref_array_clear(&array);
free(to_free);
@@ -105,17 +107,17 @@ static int verify_tag(const char *name, const char *ref,
const struct object_id *oid, const void *cb_data)
{
int flags;
- const char *fmt_pretty = cb_data;
+ const struct ref_format *format = cb_data;
flags = GPG_VERIFY_VERBOSE;
- if (fmt_pretty)
+ if (format->format)
flags = GPG_VERIFY_OMIT_STATUS;
- if (gpg_verify_tag(oid->hash, name, flags))
+ if (gpg_verify_tag(oid, name, flags))
return -1;
- if (fmt_pretty)
- pretty_print_ref(name, oid->hash, fmt_pretty);
+ if (format->format)
+ pretty_print_ref(name, oid->hash, format);
return 0;
}
@@ -134,30 +136,6 @@ static const char tag_template_nocleanup[] =
"Lines starting with '%c' will be kept; you may remove them"
" yourself if you want to.\n");
-/* Parse arg given and add it the ref_sorting array */
-static int parse_sorting_string(const char *arg, struct ref_sorting **sorting_tail)
-{
- struct ref_sorting *s;
- int len;
-
- s = xcalloc(1, sizeof(*s));
- s->next = *sorting_tail;
- *sorting_tail = s;
-
- if (*arg == '-') {
- s->reverse = 1;
- arg++;
- }
- if (skip_prefix(arg, "version:", &arg) ||
- skip_prefix(arg, "v:", &arg))
- s->version = 1;
-
- len = strlen(arg);
- s->atom = parse_ref_filter_atom(arg, arg+len);
-
- return 0;
-}
-
static int git_tag_config(const char *var, const char *value, void *cb)
{
int status;
@@ -166,7 +144,7 @@ static int git_tag_config(const char *var, const char *value, void *cb)
if (!strcmp(var, "tag.sort")) {
if (!value)
return config_error_nonbool(var);
- parse_sorting_string(value, sorting_tail);
+ parse_ref_sorting(sorting_tail, value);
return 0;
}
@@ -392,7 +370,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
struct strbuf err = STRBUF_INIT;
struct ref_filter filter;
static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
- const char *format = NULL;
+ struct ref_format format = REF_FORMAT_INIT;
int icase = 0;
struct option options[] = {
OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
@@ -431,7 +409,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
N_("print only tags of the object"), PARSE_OPT_LASTARG_DEFAULT,
parse_opt_object_name, (intptr_t) "HEAD"
},
- OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
+ OPT_STRING( 0 , "format", &format.format, N_("format"),
+ N_("format to use for the output")),
OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
OPT_END()
};
@@ -461,6 +440,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
cmdmode = 'l';
}
+ if (cmdmode == 'l')
+ setup_auto_pager("tag", 1);
+
if ((create_tag_object || force) && (cmdmode != 0))
usage_with_options(git_tag_usage, options);
@@ -483,7 +465,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
run_column_filter(colopts, &copts);
}
filter.name_patterns = argv;
- ret = list_tags(&filter, sorting, format);
+ ret = list_tags(&filter, sorting, &format);
if (column_active(colopts))
stop_column_filter();
return ret;
@@ -501,9 +483,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (cmdmode == 'd')
return for_each_tag_name(argv, delete_tag, NULL);
if (cmdmode == 'v') {
- if (format)
- verify_ref_format(format);
- return for_each_tag_name(argv, verify_tag, format);
+ if (format.format && verify_ref_format(&format))
+ usage_with_options(git_tag_usage, options);
+ return for_each_tag_name(argv, verify_tag, &format);
}
if (msg.given || msgfile) {
diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c
index 73f1334191..281ca1db6c 100644
--- a/builtin/unpack-file.c
+++ b/builtin/unpack-file.c
@@ -1,7 +1,7 @@
#include "builtin.h"
#include "config.h"
-static char *create_temp_file(unsigned char *sha1)
+static char *create_temp_file(struct object_id *oid)
{
static char path[50];
void *buf;
@@ -9,9 +9,9 @@ static char *create_temp_file(unsigned char *sha1)
unsigned long size;
int fd;
- buf = read_sha1_file(sha1, &type, &size);
+ buf = read_sha1_file(oid->hash, &type, &size);
if (!buf || type != OBJ_BLOB)
- die("unable to read blob object %s", sha1_to_hex(sha1));
+ die("unable to read blob object %s", oid_to_hex(oid));
xsnprintf(path, sizeof(path), ".merge_file_XXXXXX");
fd = xmkstemp(path);
@@ -23,15 +23,15 @@ static char *create_temp_file(unsigned char *sha1)
int cmd_unpack_file(int argc, const char **argv, const char *prefix)
{
- unsigned char sha1[20];
+ struct object_id oid;
if (argc != 2 || !strcmp(argv[1], "-h"))
usage("git unpack-file <sha1>");
- if (get_sha1(argv[1], sha1))
+ if (get_oid(argv[1], &oid))
die("Not a valid object name %s", argv[1]);
git_config(git_default_config, NULL);
- puts(create_temp_file(sha1));
+ puts(create_temp_file(&oid));
return 0;
}
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 56721cf03d..d562f2ec69 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -280,7 +280,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len
fill_stat_cache_info(ce, st);
ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
- if (index_path(ce->oid.hash, path, st,
+ if (index_path(&ce->oid, path, st,
info_only ? 0 : HASH_WRITE_OBJECT)) {
free(ce);
return -1;
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 40ccfc193b..6b90c5dead 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -94,10 +94,10 @@ static char *parse_refname(struct strbuf *input, const char **next)
* provided but cannot be converted to a SHA-1, die. flags can
* include PARSE_SHA1_OLD and/or PARSE_SHA1_ALLOW_EMPTY.
*/
-static int parse_next_sha1(struct strbuf *input, const char **next,
- unsigned char *sha1,
- const char *command, const char *refname,
- int flags)
+static int parse_next_oid(struct strbuf *input, const char **next,
+ struct object_id *oid,
+ const char *command, const char *refname,
+ int flags)
{
struct strbuf arg = STRBUF_INIT;
int ret = 0;
@@ -115,11 +115,11 @@ static int parse_next_sha1(struct strbuf *input, const char **next,
(*next)++;
*next = parse_arg(*next, &arg);
if (arg.len) {
- if (get_sha1(arg.buf, sha1))
+ if (get_oid(arg.buf, oid))
goto invalid;
} else {
/* Without -z, an empty value means all zeros: */
- hashclr(sha1);
+ oidclr(oid);
}
} else {
/* With -z, read the next NUL-terminated line */
@@ -133,13 +133,13 @@ static int parse_next_sha1(struct strbuf *input, const char **next,
*next += arg.len;
if (arg.len) {
- if (get_sha1(arg.buf, sha1))
+ if (get_oid(arg.buf, oid))
goto invalid;
} else if (flags & PARSE_SHA1_ALLOW_EMPTY) {
/* With -z, treat an empty value as all zeros: */
warning("%s %s: missing <newvalue>, treating as zero",
command, refname);
- hashclr(sha1);
+ oidclr(oid);
} else {
/*
* With -z, an empty non-required value means
@@ -182,26 +182,25 @@ static const char *parse_cmd_update(struct ref_transaction *transaction,
{
struct strbuf err = STRBUF_INIT;
char *refname;
- unsigned char new_sha1[20];
- unsigned char old_sha1[20];
+ struct object_id new_oid, old_oid;
int have_old;
refname = parse_refname(input, &next);
if (!refname)
die("update: missing <ref>");
- if (parse_next_sha1(input, &next, new_sha1, "update", refname,
- PARSE_SHA1_ALLOW_EMPTY))
+ if (parse_next_oid(input, &next, &new_oid, "update", refname,
+ PARSE_SHA1_ALLOW_EMPTY))
die("update %s: missing <newvalue>", refname);
- have_old = !parse_next_sha1(input, &next, old_sha1, "update", refname,
- PARSE_SHA1_OLD);
+ have_old = !parse_next_oid(input, &next, &old_oid, "update", refname,
+ PARSE_SHA1_OLD);
if (*next != line_termination)
die("update %s: extra input: %s", refname, next);
if (ref_transaction_update(transaction, refname,
- new_sha1, have_old ? old_sha1 : NULL,
+ new_oid.hash, have_old ? old_oid.hash : NULL,
update_flags | create_reflog_flag,
msg, &err))
die("%s", err.buf);
@@ -218,22 +217,22 @@ static const char *parse_cmd_create(struct ref_transaction *transaction,
{
struct strbuf err = STRBUF_INIT;
char *refname;
- unsigned char new_sha1[20];
+ struct object_id new_oid;
refname = parse_refname(input, &next);
if (!refname)
die("create: missing <ref>");
- if (parse_next_sha1(input, &next, new_sha1, "create", refname, 0))
+ if (parse_next_oid(input, &next, &new_oid, "create", refname, 0))
die("create %s: missing <newvalue>", refname);
- if (is_null_sha1(new_sha1))
+ if (is_null_oid(&new_oid))
die("create %s: zero <newvalue>", refname);
if (*next != line_termination)
die("create %s: extra input: %s", refname, next);
- if (ref_transaction_create(transaction, refname, new_sha1,
+ if (ref_transaction_create(transaction, refname, new_oid.hash,
update_flags | create_reflog_flag,
msg, &err))
die("%s", err.buf);
@@ -250,18 +249,18 @@ static const char *parse_cmd_delete(struct ref_transaction *transaction,
{
struct strbuf err = STRBUF_INIT;
char *refname;
- unsigned char old_sha1[20];
+ struct object_id old_oid;
int have_old;
refname = parse_refname(input, &next);
if (!refname)
die("delete: missing <ref>");
- if (parse_next_sha1(input, &next, old_sha1, "delete", refname,
- PARSE_SHA1_OLD)) {
+ if (parse_next_oid(input, &next, &old_oid, "delete", refname,
+ PARSE_SHA1_OLD)) {
have_old = 0;
} else {
- if (is_null_sha1(old_sha1))
+ if (is_null_oid(&old_oid))
die("delete %s: zero <oldvalue>", refname);
have_old = 1;
}
@@ -270,7 +269,7 @@ static const char *parse_cmd_delete(struct ref_transaction *transaction,
die("delete %s: extra input: %s", refname, next);
if (ref_transaction_delete(transaction, refname,
- have_old ? old_sha1 : NULL,
+ have_old ? old_oid.hash : NULL,
update_flags, msg, &err))
die("%s", err.buf);
@@ -286,20 +285,20 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
{
struct strbuf err = STRBUF_INIT;
char *refname;
- unsigned char old_sha1[20];
+ struct object_id old_oid;
refname = parse_refname(input, &next);
if (!refname)
die("verify: missing <ref>");
- if (parse_next_sha1(input, &next, old_sha1, "verify", refname,
- PARSE_SHA1_OLD))
- hashclr(old_sha1);
+ if (parse_next_oid(input, &next, &old_oid, "verify", refname,
+ PARSE_SHA1_OLD))
+ oidclr(&old_oid);
if (*next != line_termination)
die("verify %s: extra input: %s", refname, next);
- if (ref_transaction_verify(transaction, refname, old_sha1,
+ if (ref_transaction_verify(transaction, refname, old_oid.hash,
update_flags, &err))
die("%s", err.buf);
@@ -355,7 +354,7 @@ static void update_refs_stdin(struct ref_transaction *transaction)
int cmd_update_ref(int argc, const char **argv, const char *prefix)
{
const char *refname, *oldval;
- unsigned char sha1[20], oldsha1[20];
+ struct object_id oid, oldoid;
int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0;
unsigned int flags = 0;
int create_reflog = 0;
@@ -412,7 +411,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
refname = argv[0];
value = argv[1];
oldval = argv[2];
- if (get_sha1(value, sha1))
+ if (get_oid(value, &oid))
die("%s: not a valid SHA1", value);
}
@@ -422,8 +421,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
* The empty string implies that the reference
* must not already exist:
*/
- hashclr(oldsha1);
- else if (get_sha1(oldval, oldsha1))
+ oidclr(&oldoid);
+ else if (get_oid(oldval, &oldoid))
die("%s: not a valid old SHA1", oldval);
}
@@ -435,10 +434,10 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
* NULL_SHA1 as "don't care" here:
*/
return delete_ref(msg, refname,
- (oldval && !is_null_sha1(oldsha1)) ? oldsha1 : NULL,
+ (oldval && !is_null_oid(&oldoid)) ? oldoid.hash : NULL,
flags);
else
- return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
+ return update_ref(msg, refname, oid.hash, oldval ? oldoid.hash : NULL,
flags | create_reflog_flag,
UPDATE_REFS_DIE_ON_ERR);
}
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index f9a5f7535a..ad7b79fa5c 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -32,11 +32,11 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
{
int i = 1, verbose = 0, had_error = 0;
unsigned flags = 0;
- char *fmt_pretty = NULL;
+ struct ref_format format = REF_FORMAT_INIT;
const struct option verify_tag_options[] = {
OPT__VERBOSE(&verbose, N_("print tag contents")),
OPT_BIT(0, "raw", &flags, N_("print raw gpg status output"), GPG_VERIFY_RAW),
- OPT_STRING( 0 , "format", &fmt_pretty, N_("format"), N_("format to use for the output")),
+ OPT_STRING(0, "format", &format.format, N_("format"), N_("format to use for the output")),
OPT_END()
};
@@ -50,26 +50,29 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
if (verbose)
flags |= GPG_VERIFY_VERBOSE;
- if (fmt_pretty) {
- verify_ref_format(fmt_pretty);
+ if (format.format) {
+ if (verify_ref_format(&format))
+ usage_with_options(verify_tag_usage,
+ verify_tag_options);
flags |= GPG_VERIFY_OMIT_STATUS;
}
while (i < argc) {
- unsigned char sha1[20];
+ struct object_id oid;
const char *name = argv[i++];
- if (get_sha1(name, sha1)) {
+
+ if (get_oid(name, &oid)) {
had_error = !!error("tag '%s' not found.", name);
continue;
}
- if (gpg_verify_tag(sha1, name, flags)) {
+ if (gpg_verify_tag(&oid, name, flags)) {
had_error = 1;
continue;
}
- if (fmt_pretty)
- pretty_print_ref(name, sha1, fmt_pretty);
+ if (format.format)
+ pretty_print_ref(name, oid.hash, &format);
}
return had_error;
}