Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c7
-rw-r--r--builtin/am.c135
-rw-r--r--builtin/blame.c32
-rw-r--r--builtin/branch.c17
-rw-r--r--builtin/cat-file.c15
-rw-r--r--builtin/check-ignore.c3
-rw-r--r--builtin/checkout.c75
-rw-r--r--builtin/clean.c4
-rw-r--r--builtin/clone.c71
-rw-r--r--builtin/commit-tree.c2
-rw-r--r--builtin/commit.c22
-rw-r--r--builtin/config.c31
-rw-r--r--builtin/describe.c10
-rw-r--r--builtin/diff-tree.c8
-rw-r--r--builtin/diff.c44
-rw-r--r--builtin/difftool.c67
-rw-r--r--builtin/fast-export.c10
-rw-r--r--builtin/fetch-pack.c2
-rw-r--r--builtin/fetch.c19
-rw-r--r--builtin/fmt-merge-msg.c8
-rw-r--r--builtin/for-each-ref.c5
-rw-r--r--builtin/fsck.c23
-rw-r--r--builtin/gc.c22
-rw-r--r--builtin/grep.c69
-rw-r--r--builtin/index-pack.c78
-rw-r--r--builtin/log.c23
-rw-r--r--builtin/ls-files.c60
-rw-r--r--builtin/ls-remote.c10
-rw-r--r--builtin/ls-tree.c6
-rw-r--r--builtin/mailsplit.c10
-rw-r--r--builtin/merge-base.c8
-rw-r--r--builtin/merge-index.c2
-rw-r--r--builtin/merge-tree.c10
-rw-r--r--builtin/merge.c73
-rw-r--r--builtin/mktree.c5
-rw-r--r--builtin/name-rev.c68
-rw-r--r--builtin/notes.c11
-rw-r--r--builtin/pack-objects.c117
-rw-r--r--builtin/pack-redundant.c1
-rw-r--r--builtin/pack-refs.c2
-rw-r--r--builtin/patch-id.c2
-rw-r--r--builtin/prune.c11
-rw-r--r--builtin/pull.c96
-rw-r--r--builtin/push.c5
-rw-r--r--builtin/read-tree.c46
-rw-r--r--builtin/receive-pack.c227
-rw-r--r--builtin/reflog.c60
-rw-r--r--builtin/repack.c5
-rw-r--r--builtin/replace.c57
-rw-r--r--builtin/reset.c40
-rw-r--r--builtin/rev-list.c6
-rw-r--r--builtin/rev-parse.c63
-rw-r--r--builtin/send-pack.c4
-rw-r--r--builtin/show-branch.c8
-rw-r--r--builtin/submodule--helper.c141
-rw-r--r--builtin/tag.c141
-rw-r--r--builtin/unpack-objects.c65
-rw-r--r--builtin/update-index.c6
-rw-r--r--builtin/verify-commit.c12
-rw-r--r--builtin/worktree.c33
60 files changed, 1279 insertions, 934 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 9f53f020d0..36cad00ae6 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -400,7 +400,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
}
/* This picks up the paths that are not tracked */
- baselen = fill_directory(&dir, &pathspec);
+ baselen = fill_directory(&dir, &the_index, &pathspec);
if (pathspec.nr)
seen = prune_directory(&dir, &pathspec, baselen);
}
@@ -436,8 +436,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
!file_exists(path))) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
- if (is_excluded(&dir, path, &dtype))
- dir_add_ignored(&dir, path, pathspec.items[i].len);
+ if (is_excluded(&dir, &the_index, path, &dtype))
+ dir_add_ignored(&dir, &the_index,
+ path, pathspec.items[i].len);
} else
die(_("pathspec '%s' did not match any files"),
pathspec.items[i].original);
diff --git a/builtin/am.c b/builtin/am.c
index f7a7a971fb..0f63dcab16 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -134,17 +134,15 @@ struct am_state {
};
/**
- * Initializes am_state with the default values. The state directory is set to
- * dir.
+ * Initializes am_state with the default values.
*/
-static void am_state_init(struct am_state *state, const char *dir)
+static void am_state_init(struct am_state *state)
{
int gpgsign;
memset(state, 0, sizeof(*state));
- assert(dir);
- state->dir = xstrdup(dir);
+ state->dir = git_pathdup("rebase-apply");
state->prec = 4;
@@ -762,14 +760,18 @@ static int split_mail_conv(mail_conv_fn fn, struct am_state *state,
mail = mkpath("%s/%0*d", state->dir, state->prec, i + 1);
out = fopen(mail, "w");
- if (!out)
+ if (!out) {
+ if (in != stdin)
+ fclose(in);
return error_errno(_("could not open '%s' for writing"),
mail);
+ }
ret = fn(out, in, keep_cr);
fclose(out);
- fclose(in);
+ if (in != stdin)
+ fclose(in);
if (ret)
return error(_("could not parse patch '%s'"), *paths);
@@ -877,12 +879,12 @@ static int hg_patch_to_mail(FILE *out, FILE *in, int keep_cr)
if (skip_prefix(sb.buf, "# User ", &str))
fprintf(out, "From: %s\n", str);
else if (skip_prefix(sb.buf, "# Date ", &str)) {
- unsigned long timestamp;
+ timestamp_t timestamp;
long tz, tz2;
char *end;
errno = 0;
- timestamp = strtoul(str, &end, 10);
+ timestamp = parse_timestamp(str, &end, 10);
if (errno)
return error(_("invalid timestamp"));
@@ -1143,7 +1145,7 @@ static int index_has_changes(struct strbuf *sb)
DIFF_OPT_SET(&opt, EXIT_WITH_STATUS);
if (!sb)
DIFF_OPT_SET(&opt, QUICK);
- do_diff_cache(head.hash, &opt);
+ do_diff_cache(&head, &opt);
diffcore_std(&opt);
for (i = 0; sb && i < diff_queued_diff.nr; i++) {
if (i)
@@ -1181,42 +1183,39 @@ static void NORETURN die_user_resolve(const struct am_state *state)
exit(128);
}
-static void am_signoff(struct strbuf *sb)
+/**
+ * Appends signoff to the "msg" field of the am_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);
- /* Does it end with our own sign-off? */
+ /* our sign-off */
strbuf_addf(&mine, "\n%s%s\n",
sign_off_header,
fmt_name(getenv("GIT_COMMITTER_NAME"),
getenv("GIT_COMMITTER_EMAIL")));
- if (mine.len < sb->len &&
- !strcmp(mine.buf, sb->buf + sb->len - mine.len))
+
+ /* 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;
+ for (cp = sb.buf;
cp && *cp && (cp = strstr(cp, sign_off_header)) != NULL;
cp = strchr(cp, '\n')) {
- if (sb->buf == cp || cp[-1] == '\n')
+ if (sb.buf == cp || cp[-1] == '\n')
break;
}
- strbuf_addstr(sb, mine.buf + !!cp);
+ strbuf_addstr(&sb, mine.buf + !!cp);
exit:
strbuf_release(&mine);
-}
-
-/**
- * Appends signoff to the "msg" field of the am_state.
- */
-static void am_append_signoff(struct am_state *state)
-{
- struct strbuf sb = STRBUF_INIT;
-
- strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
- am_signoff(&sb);
state->msg = strbuf_detach(&sb, &state->msg_len);
}
@@ -1313,7 +1312,7 @@ static int parse_mail(struct am_state *state, const char *mail)
}
if (is_empty_file(am_path(state, "patch"))) {
- printf_ln(_("Patch is empty. Was it split wrong?"));
+ printf_ln(_("Patch is empty."));
die_user_resolve(state);
}
@@ -1321,9 +1320,6 @@ static int parse_mail(struct am_state *state, const char *mail)
strbuf_addbuf(&msg, &mi.log_message);
strbuf_stripspace(&msg, 0);
- if (state->signoff)
- am_signoff(&msg);
-
assert(!state->author_name);
state->author_name = strbuf_detach(&author_name, NULL);
@@ -1355,19 +1351,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)
struct strbuf sb = STRBUF_INIT;
FILE *fp = xfopen(mail, "r");
const char *x;
+ int ret = 0;
- if (strbuf_getline_lf(&sb, fp))
- return -1;
-
- if (!skip_prefix(sb.buf, "From ", &x))
- return -1;
-
- if (get_oid_hex(x, commit_id) < 0)
- return -1;
+ if (strbuf_getline_lf(&sb, fp) ||
+ !skip_prefix(sb.buf, "From ", &x) ||
+ get_oid_hex(x, commit_id) < 0)
+ ret = -1;
strbuf_release(&sb);
fclose(fp);
- return 0;
+ return ret;
}
/**
@@ -1376,40 +1369,33 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)
*/
static void get_commit_info(struct am_state *state, struct commit *commit)
{
- const char *buffer, *ident_line, *author_date, *msg;
+ const char *buffer, *ident_line, *msg;
size_t ident_len;
- struct ident_split ident_split;
- struct strbuf sb = STRBUF_INIT;
+ struct ident_split id;
buffer = logmsg_reencode(commit, NULL, get_commit_output_encoding());
ident_line = find_commit_header(buffer, "author", &ident_len);
- if (split_ident_line(&ident_split, ident_line, ident_len) < 0) {
- strbuf_add(&sb, ident_line, ident_len);
- die(_("invalid ident line: %s"), sb.buf);
- }
+ if (split_ident_line(&id, ident_line, ident_len) < 0)
+ die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);
assert(!state->author_name);
- if (ident_split.name_begin) {
- strbuf_add(&sb, ident_split.name_begin,
- ident_split.name_end - ident_split.name_begin);
- state->author_name = strbuf_detach(&sb, NULL);
- } else
+ if (id.name_begin)
+ state->author_name =
+ xmemdupz(id.name_begin, id.name_end - id.name_begin);
+ else
state->author_name = xstrdup("");
assert(!state->author_email);
- if (ident_split.mail_begin) {
- strbuf_add(&sb, ident_split.mail_begin,
- ident_split.mail_end - ident_split.mail_begin);
- state->author_email = strbuf_detach(&sb, NULL);
- } else
+ if (id.mail_begin)
+ state->author_email =
+ xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);
+ else
state->author_email = xstrdup("");
- author_date = show_ident_date(&ident_split, DATE_MODE(NORMAL));
- strbuf_addstr(&sb, author_date);
assert(!state->author_date);
- state->author_date = strbuf_detach(&sb, NULL);
+ state->author_date = xstrdup(show_ident_date(&id, DATE_MODE(NORMAL)));
assert(!state->msg);
msg = strstr(buffer, "\n\n");
@@ -1417,6 +1403,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit)
die(_("unable to parse commit %s"), oid_to_hex(&commit->object.oid));
state->msg = xstrdup(msg + 2);
state->msg_len = strlen(state->msg);
+ unuse_commit_buffer(commit, buffer);
}
/**
@@ -1457,9 +1444,9 @@ static void write_index_patch(const struct am_state *state)
FILE *fp;
if (!get_sha1_tree("HEAD", head.hash))
- tree = lookup_tree(head.hash);
+ tree = lookup_tree(&head);
else
- tree = lookup_tree(EMPTY_TREE_SHA1_BIN);
+ tree = lookup_tree(&empty_tree_oid);
fp = xfopen(am_path(state, "patch"), "w");
init_revisions(&rev_info, NULL);
@@ -1492,7 +1479,7 @@ static int parse_mail_rebase(struct am_state *state, const char *mail)
if (get_mail_commit_oid(&commit_oid, mail) < 0)
die(_("could not parse %s"), mail);
- commit = lookup_commit_or_die(commit_oid.hash, mail);
+ commit = lookup_commit_or_die(&commit_oid, mail);
get_commit_info(state, commit);
@@ -1622,7 +1609,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
init_revisions(&rev_info, NULL);
rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;
diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1, rev_info.prefix);
- add_pending_sha1(&rev_info, "HEAD", our_tree.hash, 0);
+ add_pending_oid(&rev_info, "HEAD", &our_tree, 0);
diff_setup_done(&rev_info.diffopt);
run_diff_index(&rev_info, 1);
}
@@ -1687,7 +1674,7 @@ static void do_commit(const struct am_state *state)
if (!get_sha1_commit("HEAD", parent.hash)) {
old_oid = &parent;
- commit_list_insert(lookup_commit(parent.hash), &parents);
+ commit_list_insert(lookup_commit(&parent), &parents);
} else {
old_oid = NULL;
say(state, stderr, _("applying to an empty history"));
@@ -1848,6 +1835,9 @@ static void am_run(struct am_state *state, int resume)
if (skip)
goto next; /* mail should be skipped */
+ if (state->signoff)
+ am_append_signoff(state);
+
write_author_script(state);
write_commit_msg(state);
}
@@ -1941,7 +1931,8 @@ static void am_resolve(struct am_state *state)
if (unmerged_cache()) {
printf_ln(_("You still have unmerged paths in your index.\n"
- "Did you forget to use 'git add'?"));
+ "You should 'git add' each file with resolved conflicts to mark them as such.\n"
+ "You might run `git rm` on a file to accept \"deleted by them\" for it."));
die_user_resolve(state);
}
@@ -2046,11 +2037,11 @@ static int clean_index(const struct object_id *head, const struct object_id *rem
struct tree *head_tree, *remote_tree, *index_tree;
struct object_id index;
- head_tree = parse_tree_indirect(head->hash);
+ head_tree = parse_tree_indirect(head);
if (!head_tree)
return error(_("Could not parse object '%s'."), oid_to_hex(head));
- remote_tree = parse_tree_indirect(remote->hash);
+ remote_tree = parse_tree_indirect(remote);
if (!remote_tree)
return error(_("Could not parse object '%s'."), oid_to_hex(remote));
@@ -2062,7 +2053,7 @@ static int clean_index(const struct object_id *head, const struct object_id *rem
if (write_cache_as_tree(index.hash, 0, NULL))
return -1;
- index_tree = parse_tree_indirect(index.hash);
+ index_tree = parse_tree_indirect(&index);
if (!index_tree)
return error(_("Could not parse object '%s'."), oid_to_hex(&index));
@@ -2157,7 +2148,7 @@ static void am_abort(struct am_state *state)
am_rerere_clear();
curr_branch = resolve_refdup("HEAD", 0, curr_head.hash, NULL);
- has_curr_head = !is_null_oid(&curr_head);
+ has_curr_head = curr_branch && !is_null_oid(&curr_head);
if (!has_curr_head)
hashcpy(curr_head.hash, EMPTY_TREE_SHA1_BIN);
@@ -2322,7 +2313,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
git_config(git_am_config, NULL);
- am_state_init(&state, git_path("rebase-apply"));
+ am_state_init(&state);
in_progress = am_in_progress(&state);
if (in_progress)
diff --git a/builtin/blame.c b/builtin/blame.c
index f7aa95f4ba..1043e5376f 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -563,7 +563,7 @@ static struct origin *find_origin(struct scoreboard *sb,
diff_setup_done(&diff_opts);
if (is_null_oid(&origin->commit->object.oid))
- do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
+ do_diff_cache(&parent->tree->object.oid, &diff_opts);
else
diff_tree_sha1(parent->tree->object.oid.hash,
origin->commit->tree->object.oid.hash,
@@ -633,7 +633,7 @@ static struct origin *find_rename(struct scoreboard *sb,
diff_setup_done(&diff_opts);
if (is_null_oid(&origin->commit->object.oid))
- do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
+ do_diff_cache(&parent->tree->object.oid, &diff_opts);
else
diff_tree_sha1(parent->tree->object.oid.hash,
origin->commit->tree->object.oid.hash,
@@ -1272,7 +1272,7 @@ static void find_copy_in_parent(struct scoreboard *sb,
DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
if (is_null_oid(&target->commit->object.oid))
- do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
+ do_diff_cache(&parent->tree->object.oid, &diff_opts);
else
diff_tree_sha1(parent->tree->object.oid.hash,
target->commit->tree->object.oid.hash,
@@ -1561,13 +1561,13 @@ finish:
struct commit_info {
struct strbuf author;
struct strbuf author_mail;
- unsigned long author_time;
+ timestamp_t author_time;
struct strbuf author_tz;
/* filled only when asked for details */
struct strbuf committer;
struct strbuf committer_mail;
- unsigned long committer_time;
+ timestamp_t committer_time;
struct strbuf committer_tz;
struct strbuf summary;
@@ -1578,7 +1578,7 @@ struct commit_info {
*/
static void get_ac_line(const char *inbuf, const char *what,
struct strbuf *name, struct strbuf *mail,
- unsigned long *time, struct strbuf *tz)
+ timestamp_t *time, struct strbuf *tz)
{
struct ident_split ident;
size_t len, maillen, namelen;
@@ -1727,11 +1727,11 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
get_commit_info(suspect->commit, &ci, 1);
printf("author %s\n", ci.author.buf);
printf("author-mail %s\n", ci.author_mail.buf);
- printf("author-time %lu\n", ci.author_time);
+ printf("author-time %"PRItime"\n", ci.author_time);
printf("author-tz %s\n", ci.author_tz.buf);
printf("committer %s\n", ci.committer.buf);
printf("committer-mail %s\n", ci.committer_mail.buf);
- printf("committer-time %lu\n", ci.committer_time);
+ printf("committer-time %"PRItime"\n", ci.committer_time);
printf("committer-tz %s\n", ci.committer_tz.buf);
printf("summary %s\n", ci.summary.buf);
if (suspect->commit->object.flags & UNINTERESTING)
@@ -1837,14 +1837,14 @@ static void assign_blame(struct scoreboard *sb, int opt)
stop_progress(&pi.progress);
}
-static const char *format_time(unsigned long time, const char *tz_str,
+static const char *format_time(timestamp_t time, const char *tz_str,
int show_raw_time)
{
static struct strbuf time_buf = STRBUF_INIT;
strbuf_reset(&time_buf);
if (show_raw_time) {
- strbuf_addf(&time_buf, "%lu %s", time, tz_str);
+ strbuf_addf(&time_buf, "%"PRItime" %s", time, tz_str);
}
else {
const char *time_str;
@@ -1890,7 +1890,7 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent,
int cnt;
const char *cp;
struct origin *suspect = ent->suspect;
- char hex[GIT_SHA1_HEXSZ + 1];
+ char hex[GIT_MAX_HEXSZ + 1];
oid_to_hex_r(hex, &suspect->commit->object.oid);
printf("%s %d %d %d\n",
@@ -1928,7 +1928,7 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
const char *cp;
struct origin *suspect = ent->suspect;
struct commit_info ci;
- char hex[GIT_SHA1_HEXSZ + 1];
+ char hex[GIT_MAX_HEXSZ + 1];
int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
get_commit_info(suspect->commit, &ci, 1);
@@ -2253,7 +2253,7 @@ static struct commit_list **append_parent(struct commit_list **tail, const struc
{
struct commit *parent;
- parent = lookup_commit_reference(oid->hash);
+ parent = lookup_commit_reference(oid);
if (!parent)
die("no such commit %s", oid_to_hex(oid));
return &commit_list_insert(parent, tail)->next;
@@ -2461,7 +2461,7 @@ static const char *dwim_reverse_initial(struct scoreboard *sb)
*/
struct object *obj;
struct commit *head_commit;
- unsigned char head_sha1[20];
+ struct object_id head_oid;
if (sb->revs->pending.nr != 1)
return NULL;
@@ -2473,9 +2473,9 @@ static const char *dwim_reverse_initial(struct scoreboard *sb)
return NULL;
/* Do we have HEAD? */
- if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
+ if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL))
return NULL;
- head_commit = lookup_commit_reference_gently(head_sha1, 1);
+ head_commit = lookup_commit_reference_gently(&head_oid, 1);
if (!head_commit)
return NULL;
diff --git a/builtin/branch.c b/builtin/branch.c
index 52688f2e1b..83fcda43dc 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -124,7 +124,7 @@ static int branch_merged(int kind, const char *name,
(reference_name = reference_name_to_free =
resolve_refdup(upstream, RESOLVE_REF_READING,
oid.hash, NULL)) != NULL)
- reference_rev = lookup_commit_reference(oid.hash);
+ reference_rev = lookup_commit_reference(&oid);
}
if (!reference_rev)
reference_rev = head_rev;
@@ -157,7 +157,7 @@ static int check_branch_commit(const char *branchname, const char *refname,
const struct object_id *oid, struct commit *head_rev,
int kinds, int force)
{
- struct commit *rev = lookup_commit_reference(oid->hash);
+ struct commit *rev = lookup_commit_reference(oid);
if (!rev) {
error(_("Couldn't look up commit object for '%s'"), refname);
return -1;
@@ -211,7 +211,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
}
if (!force) {
- head_rev = lookup_commit_reference(head_oid.hash);
+ head_rev = lookup_commit_reference(&head_oid);
if (!head_rev)
die(_("Couldn't look up commit object for HEAD"));
}
@@ -504,7 +504,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
strbuf_release(&newsection);
}
-static const char edit_description[] = "BRANCH_DESCRIPTION";
+static GIT_PATH_FUNC(edit_description, "EDIT_DESCRIPTION")
static int edit_branch_description(const char *branch_name)
{
@@ -519,9 +519,9 @@ static int edit_branch_description(const char *branch_name)
" %s\n"
"Lines starting with '%c' will be stripped.\n"),
branch_name, comment_line_char);
- write_file_buf(git_path(edit_description), buf.buf, buf.len);
+ write_file_buf(edit_description(), buf.buf, buf.len);
strbuf_reset(&buf);
- if (launch_editor(git_path(edit_description), &buf, NULL)) {
+ if (launch_editor(edit_description(), &buf, NULL)) {
strbuf_release(&buf);
return -1;
}
@@ -562,7 +562,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_SET_INT('r', "remotes", &filter.kind, N_("act on remote-tracking branches"),
FILTER_REFS_REMOTES),
OPT_CONTAINS(&filter.with_commit, N_("print only branches that contain the commit")),
+ OPT_NO_CONTAINS(&filter.no_commit, N_("print only branches that don't contain the commit")),
OPT_WITH(&filter.with_commit, N_("print only branches that contain the commit")),
+ OPT_WITHOUT(&filter.no_commit, N_("print only branches that don't contain the commit")),
OPT__ABBREV(&filter.abbrev),
OPT_GROUP(N_("Specific git-branch actions:")),
@@ -618,7 +620,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (!delete && !rename && !edit_description && !new_upstream && !unset_upstream && argc == 0)
list = 1;
- if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || filter.points_at.nr)
+ if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || filter.points_at.nr ||
+ filter.no_commit)
list = 1;
if (!!delete + !!rename + !!new_upstream +
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 8b85cb8cf0..9af863e791 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
die("git cat-file %s: bad file", obj_name);
write_or_die(1, buf, size);
+ free(buf);
return 0;
}
@@ -401,10 +402,10 @@ struct object_cb_data {
struct expand_data *expand;
};
-static int batch_object_cb(const unsigned char sha1[20], void *vdata)
+static int batch_object_cb(const struct object_id *oid, void *vdata)
{
struct object_cb_data *data = vdata;
- hashcpy(data->expand->oid.hash, sha1);
+ oidcpy(&data->expand->oid, oid);
batch_object_write(NULL, data->opt, data->expand);
return 0;
}
@@ -413,7 +414,7 @@ static int batch_loose_object(const struct object_id *oid,
const char *path,
void *data)
{
- sha1_array_append(data, oid->hash);
+ oid_array_append(data, oid);
return 0;
}
@@ -422,7 +423,7 @@ static int batch_packed_object(const struct object_id *oid,
uint32_t pos,
void *data)
{
- sha1_array_append(data, oid->hash);
+ oid_array_append(data, oid);
return 0;
}
@@ -462,7 +463,7 @@ static int batch_objects(struct batch_options *opt)
data.info.typep = &data.type;
if (opt->all_objects) {
- struct sha1_array sa = SHA1_ARRAY_INIT;
+ struct oid_array sa = OID_ARRAY_INIT;
struct object_cb_data cb;
for_each_loose_object(batch_loose_object, &sa, 0);
@@ -470,9 +471,9 @@ static int batch_objects(struct batch_options *opt)
cb.opt = opt;
cb.expand = &data;
- sha1_array_for_each_unique(&sa, batch_object_cb, &cb);
+ oid_array_for_each_unique(&sa, batch_object_cb, &cb);
- sha1_array_clear(&sa);
+ oid_array_clear(&sa);
return 0;
}
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 1d73d3ca3d..d2293b22e1 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -101,7 +101,8 @@ static int check_ignore(struct dir_struct *dir,
full_path = pathspec.items[i].match;
exclude = NULL;
if (!seen[i]) {
- exclude = last_exclude_matching(dir, full_path, &dtype);
+ exclude = last_exclude_matching(dir, &the_index,
+ full_path, &dtype);
}
if (!quiet && (exclude || show_non_matching))
output_exclude(pathspec.items[i].original, exclude);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 81f07c3ef2..a6b2af39d3 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -21,12 +21,31 @@
#include "submodule-config.h"
#include "submodule.h"
+static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+
static const char * const checkout_usage[] = {
N_("git checkout [<options>] <branch>"),
N_("git checkout [<options>] [<branch>] -- <file>..."),
NULL,
};
+static int option_parse_recurse_submodules(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset) {
+ recurse_submodules = RECURSE_SUBMODULES_OFF;
+ return 0;
+ }
+ if (arg)
+ recurse_submodules =
+ parse_update_recurse_submodules_arg(opt->long_name,
+ arg);
+ else
+ recurse_submodules = RECURSE_SUBMODULES_ON;
+
+ return 0;
+}
+
struct checkout_opts {
int patch_mode;
int quiet;
@@ -216,22 +235,24 @@ static int checkout_merged(int pos, const struct checkout *state)
/*
* NEEDSWORK:
* There is absolutely no reason to write this as a blob object
- * and create a phony cache entry just to leak. This hack is
- * primarily to get to the write_entry() machinery that massages
- * the contents to work-tree format and writes out which only
- * allows it for a cache entry. The code in write_entry() needs
- * to be refactored to allow us to feed a <buffer, size, mode>
- * instead of a cache entry. Such a refactoring would help
- * merge_recursive as well (it also writes the merge result to the
- * object database even when it may contain conflicts).
+ * and create a phony cache entry. This hack is primarily to get
+ * to the write_entry() machinery that massages the contents to
+ * work-tree format and writes out which only allows it for a
+ * cache entry. The code in write_entry() needs to be refactored
+ * to allow us to feed a <buffer, size, mode> instead of a cache
+ * entry. Such a refactoring would help merge_recursive as well
+ * (it also writes the merge result to the object database even
+ * when it may contain conflicts).
*/
if (write_sha1_file(result_buf.ptr, result_buf.size,
blob_type, oid.hash))
die(_("Unable to add merge result for '%s'"), path);
+ free(result_buf.ptr);
ce = make_cache_entry(mode, oid.hash, path, 2, 0);
if (!ce)
die(_("make_cache_entry failed for path '%s'"), path);
status = checkout_entry(ce, state, NULL);
+ free(ce);
return status;
}
@@ -374,7 +395,7 @@ static int checkout_paths(const struct checkout_opts *opts,
die(_("unable to write new index file"));
read_ref_full("HEAD", 0, rev.hash, NULL);
- head = lookup_commit_reference_gently(rev.hash, 1);
+ head = lookup_commit_reference_gently(&rev, 1);
errs |= post_checkout_hook(head, head, 0);
return errs;
@@ -508,10 +529,10 @@ static int merge_working_tree(const struct checkout_opts *opts,
setup_standard_excludes(topts.dir);
}
tree = parse_tree_indirect(old->commit ?
- old->commit->object.oid.hash :
- EMPTY_TREE_SHA1_BIN);
+ &old->commit->object.oid :
+ &empty_tree_oid);
init_tree_desc(&trees[0], tree->buffer, tree->size);
- tree = parse_tree_indirect(new->commit->object.oid.hash);
+ tree = parse_tree_indirect(&new->commit->object.oid);
init_tree_desc(&trees[1], tree->buffer, tree->size);
ret = unpack_trees(2, trees, &topts);
@@ -702,7 +723,7 @@ static int add_pending_uninteresting_ref(const char *refname,
const struct object_id *oid,
int flags, void *cb_data)
{
- add_pending_sha1(cb_data, refname, oid->hash, UNINTERESTING);
+ add_pending_oid(cb_data, refname, oid, UNINTERESTING);
return 0;
}
@@ -788,7 +809,7 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new)
add_pending_object(&revs, object, oid_to_hex(&object->oid));
for_each_ref(add_pending_uninteresting_ref, &revs);
- add_pending_sha1(&revs, "HEAD", new->object.oid.hash, UNINTERESTING);
+ add_pending_oid(&revs, "HEAD", &new->object.oid, UNINTERESTING);
refs = revs.pending;
revs.leak_pending = 1;
@@ -814,7 +835,8 @@ static int switch_branches(const struct checkout_opts *opts,
int flag, writeout_error = 0;
memset(&old, 0, sizeof(old));
old.path = path_to_free = resolve_refdup("HEAD", 0, rev.hash, &flag);
- old.commit = lookup_commit_reference_gently(rev.hash, 1);
+ if (old.path)
+ old.commit = lookup_commit_reference_gently(&rev, 1);
if (!(flag & REF_ISSYMREF))
old.path = NULL;
@@ -889,11 +911,10 @@ static int check_tracking_name(struct remote *remote, void *cb_data)
static const char *unique_tracking_name(const char *name, struct object_id *oid)
{
struct tracking_name_data cb_data = { NULL, NULL, NULL, 1 };
- char src_ref[PATH_MAX];
- snprintf(src_ref, PATH_MAX, "refs/heads/%s", name);
- cb_data.src_ref = src_ref;
+ cb_data.src_ref = xstrfmt("refs/heads/%s", name);
cb_data.dst_oid = oid;
for_each_remote(check_tracking_name, &cb_data);
+ free(cb_data.src_ref);
if (cb_data.unique)
return cb_data.dst_ref;
free(cb_data.dst_ref);
@@ -1029,10 +1050,10 @@ static int parse_branchname_arg(int argc, const char **argv,
else
new->path = NULL; /* not an existing branch */
- new->commit = lookup_commit_reference_gently(rev->hash, 1);
+ new->commit = lookup_commit_reference_gently(rev, 1);
if (!new->commit) {
/* not a commit */
- *source_tree = parse_tree_indirect(rev->hash);
+ *source_tree = parse_tree_indirect(rev);
} else {
parse_commit_or_die(new->commit);
*source_tree = new->commit->tree;
@@ -1163,6 +1184,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
N_("second guess 'git checkout <no-such-branch>'")),
OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
N_("do not check if another worktree is holding the given ref")),
+ { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules,
+ "checkout", "control recursive updating of submodules",
+ PARSE_OPT_OPTARG, option_parse_recurse_submodules },
OPT_BOOL(0, "progress", &opts.show_progress, N_("force progress reporting")),
OPT_END(),
};
@@ -1193,6 +1217,12 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
}
+ if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
+ git_config(submodule_config, NULL);
+ if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
+ set_config_update_recurse_submodules(recurse_submodules);
+ }
+
if ((!!opts.new_branch + !!opts.new_branch_force + !!opts.new_orphan_branch) > 1)
die(_("-b, -B and --orphan are mutually exclusive"));
@@ -1259,9 +1289,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
* new_branch && argc > 1 will be caught later.
*/
if (opts.new_branch && argc == 1)
- die(_("Cannot update paths and switch to branch '%s' at the same time.\n"
- "Did you intend to checkout '%s' which can not be resolved as commit?"),
- opts.new_branch, argv[0]);
+ die(_("'%s' is not a commit and a branch '%s' cannot be created from it"),
+ argv[0], opts.new_branch);
if (opts.force_detach)
die(_("git checkout: --detach does not take a path argument '%s'"),
diff --git a/builtin/clean.c b/builtin/clean.c
index d861f836a2..329b68c40b 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -683,7 +683,7 @@ static int filter_by_patterns_cmd(void)
for_each_string_list_item(item, &del_list) {
int dtype = DT_UNKNOWN;
- if (is_excluded(&dir, item->string, &dtype)) {
+ if (is_excluded(&dir, &the_index, item->string, &dtype)) {
*item->string = '\0';
changed++;
}
@@ -930,7 +930,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
PATHSPEC_PREFER_CWD,
prefix, argv);
- fill_directory(&dir, &pathspec);
+ fill_directory(&dir, &the_index, &pathspec);
for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
diff --git a/builtin/clone.c b/builtin/clone.c
index b4c929bb8a..743f16ae2a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -39,7 +39,8 @@ static const char * const builtin_clone_usage[] = {
};
static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
-static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
+static int option_local = -1, option_no_hardlinks, option_shared;
+static int option_no_tags;
static int option_shallow_submodules;
static int deepen;
static char *option_template, *option_depth, *option_since;
@@ -56,6 +57,21 @@ static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
static int option_dissociate;
static int max_jobs = -1;
+static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
+
+static int recurse_submodules_cb(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset)
+ string_list_clear((struct string_list *)opt->value, 0);
+ else if (arg)
+ string_list_append((struct string_list *)opt->value, arg);
+ else
+ string_list_append((struct string_list *)opt->value,
+ (const char *)opt->defval);
+
+ return 0;
+}
static struct option builtin_clone_options[] = {
OPT__VERBOSITY(&option_verbosity),
@@ -74,10 +90,13 @@ static struct option builtin_clone_options[] = {
N_("don't use local hardlinks, always copy")),
OPT_BOOL('s', "shared", &option_shared,
N_("setup as shared repository")),
- OPT_BOOL(0, "recursive", &option_recursive,
- N_("initialize submodules in the clone")),
- OPT_BOOL(0, "recurse-submodules", &option_recursive,
- N_("initialize submodules in the clone")),
+ { OPTION_CALLBACK, 0, "recursive", &option_recurse_submodules,
+ N_("pathspec"), N_("initialize submodules in the clone"),
+ PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, recurse_submodules_cb,
+ (intptr_t)"." },
+ { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
+ N_("pathspec"), N_("initialize submodules in the clone"),
+ PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
OPT_INTEGER('j', "jobs", &max_jobs,
N_("number of submodules cloned in parallel")),
OPT_STRING(0, "template", &option_template, N_("template-directory"),
@@ -102,6 +121,8 @@ static struct option builtin_clone_options[] = {
N_("deepen history of shallow clone, excluding rev")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
+ OPT_BOOL(0, "no-tags", &option_no_tags,
+ N_("don't clone any tags, and make later fetches not to follow them")),
OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules,
N_("any cloned submodules will be shallow")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
@@ -545,7 +566,7 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
} else
get_fetch_map(refs, refspec, &tail, 0);
- if (!option_mirror && !option_single_branch)
+ if (!option_mirror && !option_single_branch && !option_no_tags)
get_fetch_map(refs, tag_refspec, &tail, 0);
return local_refs;
@@ -634,7 +655,7 @@ static void update_remote_refs(const struct ref *refs,
if (refs) {
write_remote_refs(mapped_refs);
- if (option_single_branch)
+ if (option_single_branch && !option_no_tags)
write_followtags(refs, msg);
}
@@ -664,7 +685,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
install_branch_config(0, head, option_origin, our->name);
}
} else if (our) {
- struct commit *c = lookup_commit_reference(our->old_oid.hash);
+ struct commit *c = lookup_commit_reference(&our->old_oid);
/* --branch specifies a non-branch (i.e. tags), detach HEAD */
update_ref(msg, "HEAD", c->object.oid.hash,
NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
@@ -721,7 +742,7 @@ static int checkout(int submodule_progress)
opts.src_index = &the_index;
opts.dst_index = &the_index;
- tree = parse_tree_indirect(oid.hash);
+ tree = parse_tree_indirect(&oid);
parse_tree(tree);
init_tree_desc(&t, tree->buffer, tree->size);
if (unpack_trees(1, &t, &opts) < 0)
@@ -733,7 +754,7 @@ static int checkout(int submodule_progress)
err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
oid_to_hex(&oid), "1", NULL);
- if (!err && option_recursive) {
+ if (!err && (option_recurse_submodules.nr > 0)) {
struct argv_array args = ARGV_ARRAY_INIT;
argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
@@ -755,7 +776,9 @@ static int checkout(int submodule_progress)
static int write_one_config(const char *key, const char *value, void *data)
{
- return git_config_set_multivar_gently(key, value ? value : "true", "^$", 0);
+ return git_config_set_multivar_gently(key,
+ value ? value : "true",
+ CONFIG_REGEX_NONE, 0);
}
static void write_config(struct string_list *config)
@@ -957,7 +980,25 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Cloning into '%s'...\n"), dir);
}
- if (option_recursive) {
+ if (option_recurse_submodules.nr > 0) {
+ struct string_list_item *item;
+ struct strbuf sb = STRBUF_INIT;
+
+ /* remove duplicates */
+ string_list_sort(&option_recurse_submodules);
+ string_list_remove_duplicates(&option_recurse_submodules, 0);
+
+ /*
+ * NEEDSWORK: In a multi-working-tree world, this needs to be
+ * set in the per-worktree config.
+ */
+ for_each_string_list_item(item, &option_recurse_submodules) {
+ strbuf_addf(&sb, "submodule.active=%s",
+ item->string);
+ string_list_append(&option_config,
+ strbuf_detach(&sb, NULL));
+ }
+
if (option_required_reference.nr &&
option_optional_reference.nr)
die(_("clone --recursive is not compatible with "
@@ -999,6 +1040,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
git_config_set(key.buf, repo);
strbuf_reset(&key);
+ if (option_no_tags) {
+ strbuf_addf(&key, "remote.%s.tagOpt", option_origin);
+ git_config_set(key.buf, "--no-tags");
+ strbuf_reset(&key);
+ }
+
if (option_required_reference.nr || option_optional_reference.nr)
setup_reference();
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index 605017261c..f39c2b2737 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -58,7 +58,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
if (get_sha1_commit(argv[i], oid.hash))
die("Not a valid object name %s", argv[i]);
assert_sha1_type(oid.hash, OBJ_COMMIT);
- new_parent(lookup_commit(oid.hash), &parents);
+ new_parent(lookup_commit(&oid), &parents);
continue;
}
diff --git a/builtin/commit.c b/builtin/commit.c
index 4e288bc513..da1ba4c862 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -313,7 +313,7 @@ static void create_base_index(const struct commit *current_head)
opts.dst_index = &the_index;
opts.fn = oneway_merge;
- tree = parse_tree_indirect(current_head->object.oid.hash);
+ tree = parse_tree_indirect(&current_head->object.oid);
if (!tree)
die(_("failed to unpack HEAD tree object"));
parse_tree(tree);
@@ -821,9 +821,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
"If this is not correct, please remove the file\n"
" %s\n"
"and try again.\n"),
- git_path(whence == FROM_MERGE
- ? "MERGE_HEAD"
- : "CHERRY_PICK_HEAD"));
+ whence == FROM_MERGE ?
+ git_path_merge_head() :
+ git_path_cherry_pick_head());
}
fprintf(s->fp, "\n");
@@ -1263,6 +1263,10 @@ static int parse_status_slot(const char *slot)
return WT_STATUS_NOBRANCH;
if (!strcasecmp(slot, "unmerged"))
return WT_STATUS_UNMERGED;
+ if (!strcasecmp(slot, "localBranch"))
+ return WT_STATUS_LOCAL_BRANCH;
+ if (!strcasecmp(slot, "remoteBranch"))
+ return WT_STATUS_REMOTE_BRANCH;
return -1;
}
@@ -1404,7 +1408,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
static const char *implicit_ident_advice(void)
{
- char *user_config = expand_user_path("~/.gitconfig");
+ char *user_config = expand_user_path("~/.gitconfig", 0);
char *xdg_config = xdg_config_home("config");
int config_exists = file_exists(user_config) || file_exists(xdg_config);
@@ -1430,7 +1434,7 @@ static void print_summary(const char *prefix, const struct object_id *oid,
struct strbuf author_ident = STRBUF_INIT;
struct strbuf committer_ident = STRBUF_INIT;
- commit = lookup_commit(oid->hash);
+ commit = lookup_commit(oid);
if (!commit)
die(_("couldn't look up newly created commit"));
if (parse_commit(commit))
@@ -1654,7 +1658,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (get_sha1("HEAD", oid.hash))
current_head = NULL;
else {
- current_head = lookup_commit_or_die(oid.hash, "HEAD");
+ current_head = lookup_commit_or_die(&oid, "HEAD");
if (parse_commit(current_head))
die(_("could not parse HEAD commit"));
}
@@ -1735,7 +1739,7 @@ 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)
- wt_status_truncate_message_at_cut_line(&sb);
+ strbuf_setlen(&sb, wt_status_locate_end(sb.buf, sb.len));
if (cleanup_mode != CLEANUP_NONE)
strbuf_stripspace(&sb, cleanup_mode == CLEANUP_ALL);
@@ -1758,7 +1762,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
append_merge_tag_headers(parents, &tail);
}
- if (commit_tree_extended(sb.buf, sb.len, active_cache_tree->sha1,
+ if (commit_tree_extended(sb.buf, sb.len, active_cache_tree->oid.hash,
parents, oid.hash, author_ident.buf, sign_commit, extra)) {
rollback_index_files();
die(_("failed to write commit object"));
diff --git a/builtin/config.c b/builtin/config.c
index 4f49a0edb9..7f6c25d4d9 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -26,7 +26,8 @@ static int use_global_config, use_system_config, use_local_config;
static struct git_config_source given_config_source;
static int actions, types;
static int end_null;
-static int respect_includes = -1;
+static int respect_includes_opt = -1;
+static struct config_options config_options;
static int show_origin;
#define ACTION_GET (1<<0)
@@ -81,7 +82,7 @@ static struct option builtin_config_options[] = {
OPT_GROUP(N_("Other")),
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
- OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
+ OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
OPT_END(),
};
@@ -242,7 +243,7 @@ static int get_value(const char *key_, const char *regex_)
}
git_config_with_options(collect_config, &values,
- &given_config_source, respect_includes);
+ &given_config_source, &config_options);
ret = !values.nr;
@@ -320,7 +321,7 @@ static void get_color(const char *var, const char *def_color)
get_color_found = 0;
parsed_color[0] = '\0';
git_config_with_options(git_get_color_config, NULL,
- &given_config_source, respect_includes);
+ &given_config_source, &config_options);
if (!get_color_found && def_color) {
if (color_parse(def_color, parsed_color) < 0)
@@ -352,7 +353,7 @@ static int get_colorbool(const char *var, int print)
get_diff_color_found = -1;
get_color_ui_found = -1;
git_config_with_options(git_get_colorbool_config, NULL,
- &given_config_source, respect_includes);
+ &given_config_source, &config_options);
if (get_colorbool_found < 0) {
if (!strcmp(get_colorbool_slot, "color.diff"))
@@ -441,7 +442,7 @@ static int get_urlmatch(const char *var, const char *url)
}
git_config_with_options(urlmatch_config_entry, &config,
- &given_config_source, respect_includes);
+ &given_config_source, &config_options);
ret = !values.nr;
@@ -495,6 +496,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
usage_with_options(builtin_config_usage, builtin_config_options);
}
+ if (use_local_config && nongit)
+ die(_("--local can only be used inside a git repository"));
+
if (given_config_source.file &&
!strcmp(given_config_source.file, "-")) {
given_config_source.file = NULL;
@@ -502,7 +506,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
}
if (use_global_config) {
- char *user_config = expand_user_path("~/.gitconfig");
+ char *user_config = expand_user_path("~/.gitconfig", 0);
char *xdg_config = xdg_config_home("config");
if (!user_config)
@@ -530,8 +534,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
prefix_filename(prefix, given_config_source.file);
}
- if (respect_includes == -1)
- respect_includes = !given_config_source.file;
+ if (respect_includes_opt == -1)
+ config_options.respect_includes = !given_config_source.file;
+ else
+ config_options.respect_includes = respect_includes_opt;
if (end_null) {
term = '\0';
@@ -578,7 +584,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
check_argc(argc, 0, 0);
if (git_config_with_options(show_all_config, NULL,
&given_config_source,
- respect_includes) < 0) {
+ &config_options) < 0) {
if (given_config_source.file)
die_errno("unable to read config file '%s'",
given_config_source.file);
@@ -597,8 +603,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
if (given_config_source.blob)
die("editing blobs is not supported");
git_config(git_default_config, NULL);
- config_file = xstrdup(given_config_source.file ?
- given_config_source.file : git_path("config"));
+ config_file = given_config_source.file ?
+ xstrdup(given_config_source.file) :
+ git_pathdup("config");
if (use_global_config) {
int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (fd >= 0) {
diff --git a/builtin/describe.c b/builtin/describe.c
index a5cd8c513f..893c8789f4 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -79,13 +79,13 @@ static int replace_name(struct commit_name *e,
struct tag *t;
if (!e->tag) {
- t = lookup_tag(e->oid.hash);
+ t = lookup_tag(&e->oid);
if (!t || parse_tag(t))
return 1;
e->tag = t;
}
- t = lookup_tag(oid->hash);
+ t = lookup_tag(oid);
if (!t || parse_tag(t))
return 0;
*tag = t;
@@ -245,7 +245,7 @@ static unsigned long finish_depth_computation(
static void display_name(struct commit_name *n)
{
if (n->prio == 2 && !n->tag) {
- n->tag = lookup_tag(n->oid.hash);
+ n->tag = lookup_tag(&n->oid);
if (!n->tag || parse_tag(n->tag))
die(_("annotated tag %s not available"), n->path);
}
@@ -281,7 +281,7 @@ static void describe(const char *arg, int last_one)
if (get_oid(arg, &oid))
die(_("Not a valid object name %s"), arg);
- cmit = lookup_commit_reference(oid.hash);
+ cmit = lookup_commit_reference(&oid);
if (!cmit)
die(_("%s is not a valid '%s' object"), arg, commit_type);
@@ -309,7 +309,7 @@ static void describe(const char *arg, int last_one)
struct commit *c;
struct commit_name *n = hashmap_iter_first(&names, &iter);
for (; n; n = hashmap_iter_next(&iter)) {
- c = lookup_commit_reference_gently(n->peeled.hash, 1);
+ c = lookup_commit_reference_gently(&n->peeled, 1);
if (c)
c->util = n;
}
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 326f88b657..5ea1c14317 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -9,7 +9,7 @@ static struct rev_info log_tree_opt;
static int diff_tree_commit_sha1(const struct object_id *oid)
{
- struct commit *commit = lookup_commit_reference(oid->hash);
+ struct commit *commit = lookup_commit_reference(oid);
if (!commit)
return -1;
return log_tree_commit(&log_tree_opt, commit);
@@ -23,7 +23,7 @@ static int stdin_diff_commit(struct commit *commit, const char *p)
/* Graft the fake parents locally to the commit */
while (isspace(*p++) && !parse_oid_hex(p, &oid, &p)) {
- struct commit *parent = lookup_commit(oid.hash);
+ struct commit *parent = lookup_commit(&oid);
if (!pptr) {
/* Free the real parent list */
free_commit_list(commit->parents);
@@ -44,7 +44,7 @@ static int stdin_diff_trees(struct tree *tree1, const char *p)
struct tree *tree2;
if (!isspace(*p++) || parse_oid_hex(p, &oid, &p) || *p)
return error("Need exactly two trees, separated by a space");
- tree2 = lookup_tree(oid.hash);
+ tree2 = lookup_tree(&oid);
if (!tree2 || parse_tree(tree2))
return -1;
printf("%s %s\n", oid_to_hex(&tree1->object.oid),
@@ -67,7 +67,7 @@ static int diff_tree_stdin(char *line)
line[len-1] = 0;
if (parse_oid_hex(line, &oid, &p))
return -1;
- obj = parse_object(oid.hash);
+ obj = parse_object(&oid);
if (!obj)
return -1;
if (obj->type == OBJ_COMMIT)
diff --git a/builtin/diff.c b/builtin/diff.c
index 3d64b85337..8c03ddaf58 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -21,7 +21,7 @@
#define DIFF_NO_INDEX_IMPLICIT 2
struct blobinfo {
- unsigned char sha1[20];
+ struct object_id oid;
const char *name;
unsigned mode;
};
@@ -31,22 +31,22 @@ static const char builtin_diff_usage[] =
static void stuff_change(struct diff_options *opt,
unsigned old_mode, unsigned new_mode,
- const unsigned char *old_sha1,
- const unsigned char *new_sha1,
- int old_sha1_valid,
- int new_sha1_valid,
+ const struct object_id *old_oid,
+ const struct object_id *new_oid,
+ int old_oid_valid,
+ int new_oid_valid,
const char *old_name,
const char *new_name)
{
struct diff_filespec *one, *two;
- if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) &&
- !hashcmp(old_sha1, new_sha1) && (old_mode == new_mode))
+ if (!is_null_oid(old_oid) && !is_null_oid(new_oid) &&
+ !oidcmp(old_oid, new_oid) && (old_mode == new_mode))
return;
if (DIFF_OPT_TST(opt, REVERSE_DIFF)) {
SWAP(old_mode, new_mode);
- SWAP(old_sha1, new_sha1);
+ SWAP(old_oid, new_oid);
SWAP(old_name, new_name);
}
@@ -57,8 +57,8 @@ static void stuff_change(struct diff_options *opt,
one = alloc_filespec(old_name);
two = alloc_filespec(new_name);
- fill_filespec(one, old_sha1, old_sha1_valid, old_mode);
- fill_filespec(two, new_sha1, new_sha1_valid, new_mode);
+ fill_filespec(one, old_oid->hash, old_oid_valid, old_mode);
+ fill_filespec(two, new_oid->hash, new_oid_valid, new_mode);
diff_queue(&diff_queued_diff, one, two);
}
@@ -89,7 +89,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
stuff_change(&revs->diffopt,
blob[0].mode, canon_mode(st.st_mode),
- blob[0].sha1, null_sha1,
+ &blob[0].oid, &null_oid,
1, 0,
path, path);
diffcore_std(&revs->diffopt);
@@ -114,7 +114,7 @@ static int builtin_diff_blobs(struct rev_info *revs,
stuff_change(&revs->diffopt,
blob[0].mode, blob[1].mode,
- blob[0].sha1, blob[1].sha1,
+ &blob[0].oid, &blob[1].oid,
1, 1,
blob[0].name, blob[1].name);
diffcore_std(&revs->diffopt);
@@ -160,7 +160,7 @@ static int builtin_diff_tree(struct rev_info *revs,
struct object_array_entry *ent0,
struct object_array_entry *ent1)
{
- const unsigned char *(sha1[2]);
+ const struct object_id *(oid[2]);
int swap = 0;
if (argc > 1)
@@ -172,9 +172,9 @@ static int builtin_diff_tree(struct rev_info *revs,
*/
if (ent1->item->flags & UNINTERESTING)
swap = 1;
- sha1[swap] = ent0->item->oid.hash;
- sha1[1 - swap] = ent1->item->oid.hash;
- diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
+ oid[swap] = &ent0->item->oid;
+ oid[1 - swap] = &ent1->item->oid;
+ diff_tree_sha1(oid[0]->hash, oid[1]->hash, "", &revs->diffopt);
log_tree_diff_flush(revs);
return 0;
}
@@ -184,7 +184,7 @@ static int builtin_diff_combined(struct rev_info *revs,
struct object_array_entry *ent,
int ents)
{
- struct sha1_array parents = SHA1_ARRAY_INIT;
+ struct oid_array parents = OID_ARRAY_INIT;
int i;
if (argc > 1)
@@ -193,10 +193,10 @@ static int builtin_diff_combined(struct rev_info *revs,
if (!revs->dense_combined_merges && !revs->combine_merges)
revs->dense_combined_merges = revs->combine_merges = 1;
for (i = 1; i < ents; i++)
- sha1_array_append(&parents, ent[i].item->oid.hash);
+ oid_array_append(&parents, &ent[i].item->oid);
diff_tree_combined(ent[0].item->oid.hash, &parents,
revs->dense_combined_merges, revs);
- sha1_array_clear(&parents);
+ oid_array_clear(&parents);
return 0;
}
@@ -381,7 +381,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
add_head_to_pending(&rev);
if (!rev.pending.nr) {
struct tree *tree;
- tree = lookup_tree(EMPTY_TREE_SHA1_BIN);
+ tree = lookup_tree(&empty_tree_oid);
add_pending_object(&rev, &tree->object, "HEAD");
}
break;
@@ -395,7 +395,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
const char *name = entry->name;
int flags = (obj->flags & UNINTERESTING);
if (!obj->parsed)
- obj = parse_object(obj->oid.hash);
+ obj = parse_object(&obj->oid);
obj = deref_tag(obj, NULL, 0);
if (!obj)
die(_("invalid object '%s' given."), name);
@@ -408,7 +408,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
} else if (obj->type == OBJ_BLOB) {
if (2 <= blobs)
die(_("more than two blobs given: '%s'"), name);
- hashcpy(blob[blobs].sha1, obj->oid.hash);
+ oidcpy(&blob[blobs].oid, &obj->oid);
blob[blobs].name = name;
blob[blobs].mode = entry->mode;
blobs++;
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 25e54ad3ed..b9a892f269 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,
hashmap_entry_init(entry, strhash(buf.buf));
hashmap_add(result, entry);
}
+ fclose(fp);
if (finish_command(&diff_files))
die("diff-files did not exit properly");
strbuf_release(&index_env);
@@ -297,6 +298,19 @@ static char *get_symlink(const struct object_id *oid, const char *path)
return data;
}
+static int checkout_path(unsigned mode, struct object_id *oid,
+ const char *path, const struct checkout *state)
+{
+ struct cache_entry *ce;
+ int ret;
+
+ ce = make_cache_entry(mode, oid->hash, path, 0, 0);
+ ret = checkout_entry(ce, state, NULL);
+
+ free(ce);
+ return ret;
+}
+
static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
int argc, const char **argv)
{
@@ -305,8 +319,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
struct strbuf rpath = STRBUF_INIT, buf = STRBUF_INIT;
struct strbuf ldir = STRBUF_INIT, rdir = STRBUF_INIT;
struct strbuf wtdir = STRBUF_INIT;
+ char *lbase_dir, *rbase_dir;
size_t ldir_len, rdir_len, wtdir_len;
- struct cache_entry *ce = xcalloc(1, sizeof(ce) + PATH_MAX + 1);
const char *workdir, *tmp;
int ret = 0, i;
FILE *fp;
@@ -339,11 +353,11 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
memset(&wtindex, 0, sizeof(wtindex));
memset(&lstate, 0, sizeof(lstate));
- lstate.base_dir = ldir.buf;
+ lstate.base_dir = lbase_dir = xstrdup(ldir.buf);
lstate.base_dir_len = ldir.len;
lstate.force = 1;
memset(&rstate, 0, sizeof(rstate));
- rstate.base_dir = rdir.buf;
+ rstate.base_dir = rbase_dir = xstrdup(rdir.buf);
rstate.base_dir_len = rdir.len;
rstate.force = 1;
@@ -377,7 +391,6 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
struct object_id loid, roid;
char status;
const char *src_path, *dst_path;
- size_t src_path_len, dst_path_len;
if (starts_with(info.buf, "::"))
die(N_("combined diff formats('-c' and '--cc') are "
@@ -390,17 +403,14 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
if (strbuf_getline_nul(&lpath, fp))
break;
src_path = lpath.buf;
- src_path_len = lpath.len;
i++;
if (status != 'C' && status != 'R') {
dst_path = src_path;
- dst_path_len = src_path_len;
} else {
if (strbuf_getline_nul(&rpath, fp))
break;
dst_path = rpath.buf;
- dst_path_len = rpath.len;
}
if (S_ISGITLINK(lmode) || S_ISGITLINK(rmode)) {
@@ -430,12 +440,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
}
if (lmode && status != 'C') {
- ce->ce_mode = lmode;
- oidcpy(&ce->oid, &loid);
- strcpy(ce->name, src_path);
- ce->ce_namelen = src_path_len;
- if (checkout_entry(ce, &lstate, NULL))
- return error("could not write '%s'", src_path);
+ if (checkout_path(lmode, &loid, src_path, &lstate)) {
+ ret = error("could not write '%s'", src_path);
+ goto finish;
+ }
}
if (rmode && !S_ISLNK(rmode)) {
@@ -451,13 +459,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
hashmap_add(&working_tree_dups, entry);
if (!use_wt_file(workdir, dst_path, &roid)) {
- ce->ce_mode = rmode;
- oidcpy(&ce->oid, &roid);
- strcpy(ce->name, dst_path);
- ce->ce_namelen = dst_path_len;
- if (checkout_entry(ce, &rstate, NULL))
- return error("could not write '%s'",
- dst_path);
+ if (checkout_path(rmode, &roid, dst_path,
+ &rstate)) {
+ ret = error("could not write '%s'",
+ dst_path);
+ goto finish;
+ }
} else if (!is_null_oid(&roid)) {
/*
* Changes in the working tree need special
@@ -472,10 +479,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
ADD_CACHE_JUST_APPEND);
add_path(&rdir, rdir_len, dst_path);
- if (ensure_leading_directories(rdir.buf))
- return error("could not create "
- "directory for '%s'",
- dst_path);
+ if (ensure_leading_directories(rdir.buf)) {
+ ret = error("could not create "
+ "directory for '%s'",
+ dst_path);
+ goto finish;
+ }
add_path(&wtdir, wtdir_len, dst_path);
if (symlinks) {
if (symlink(wtdir.buf, rdir.buf)) {
@@ -496,13 +505,15 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
}
}
+ fclose(fp);
+ fp = NULL;
if (finish_command(&child)) {
ret = error("error occurred running diff --raw");
goto finish;
}
if (!i)
- return 0;
+ goto finish;
/*
* Changes to submodules require special treatment.This loop writes a
@@ -625,7 +636,11 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
exit_cleanup(tmpdir, rc);
finish:
- free(ce);
+ if (fp)
+ fclose(fp);
+
+ free(lbase_dir);
+ free(rbase_dir);
strbuf_release(&ldir);
strbuf_release(&rdir);
strbuf_release(&wtdir);
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index e0220630d0..24e29ad7ea 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -232,7 +232,7 @@ static void export_blob(const struct object_id *oid)
if (anonymize) {
buf = anonymize_blob(&size);
- object = (struct object *)lookup_blob(oid->hash);
+ object = (struct object *)lookup_blob(oid);
eaten = 0;
} else {
buf = read_sha1_file(oid->hash, &type, &size);
@@ -240,7 +240,7 @@ static void export_blob(const struct object_id *oid)
die ("Could not read blob %s", oid_to_hex(oid));
if (check_sha1_signature(oid->hash, buf, size, typename(type)) < 0)
die("sha1 mismatch in blob %s", oid_to_hex(oid));
- object = parse_object_buffer(oid->hash, type, size, buf, &eaten);
+ object = parse_object_buffer(oid, type, size, buf, &eaten);
}
if (!object)
@@ -734,6 +734,7 @@ static void handle_tag(const char *name, struct tag *tag)
oid_to_hex(&tag->object.oid));
case DROP:
/* Ignore this tag altogether */
+ free(buf);
return;
case REWRITE:
if (tagged->type != OBJ_COMMIT) {
@@ -765,6 +766,7 @@ static void handle_tag(const char *name, struct tag *tag)
(int)(tagger_end - tagger), tagger,
tagger == tagger_end ? "" : "\n",
(int)message_size, (int)message_size, message ? message : "");
+ free(buf);
}
static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
@@ -777,7 +779,7 @@ static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
/* handle nested tags */
while (tag && tag->object.type == OBJ_TAG) {
- parse_object(tag->object.oid.hash);
+ parse_object(&tag->object.oid);
string_list_append(&extra_refs, full_name)->util = tag;
tag = (struct tag *)tag->tagged;
}
@@ -938,7 +940,7 @@ static void import_marks(char *input_file)
/* only commits */
continue;
- commit = lookup_commit(oid.hash);
+ commit = lookup_commit(&oid);
if (!commit)
die("not a commit? can't happen: %s", oid_to_hex(&oid));
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 2a1c1c213f..366b9d13f9 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -50,7 +50,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
char **pack_lockfile_ptr = NULL;
struct child_process *conn;
struct fetch_pack_args args;
- struct sha1_array shallow = SHA1_ARRAY_INIT;
+ struct oid_array shallow = OID_ARRAY_INIT;
struct string_list deepen_not = STRING_LIST_INIT_DUP;
packet_trace_identity("fetch-pack");
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b5ad09d046..d4d573b985 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -421,7 +421,7 @@ static int s_update_ref(const char *action,
struct ref *ref,
int check_old)
{
- char msg[1024];
+ char *msg;
char *rla = getenv("GIT_REFLOG_ACTION");
struct ref_transaction *transaction;
struct strbuf err = STRBUF_INIT;
@@ -431,7 +431,7 @@ static int s_update_ref(const char *action,
return 0;
if (!rla)
rla = default_rla.buf;
- snprintf(msg, sizeof(msg), "%s: %s", rla, action);
+ msg = xstrfmt("%s: %s", rla, action);
transaction = ref_transaction_begin(&err);
if (!transaction ||
@@ -449,11 +449,13 @@ static int s_update_ref(const char *action,
ref_transaction_free(transaction);
strbuf_release(&err);
+ free(msg);
return 0;
fail:
ref_transaction_free(transaction);
error("%s", err.buf);
strbuf_release(&err);
+ free(msg);
return df_conflict ? STORE_REF_ERROR_DF_CONFLICT
: STORE_REF_ERROR_OTHER;
}
@@ -634,8 +636,8 @@ static int update_local_ref(struct ref *ref,
return r;
}
- current = lookup_commit_reference_gently(ref->old_oid.hash, 1);
- updated = lookup_commit_reference_gently(ref->new_oid.hash, 1);
+ current = lookup_commit_reference_gently(&ref->old_oid, 1);
+ updated = lookup_commit_reference_gently(&ref->new_oid, 1);
if (!current || !updated) {
const char *msg;
const char *what;
@@ -659,7 +661,7 @@ static int update_local_ref(struct ref *ref,
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
- check_for_new_submodule_commits(ref->new_oid.hash);
+ check_for_new_submodule_commits(&ref->new_oid);
r = s_update_ref(msg, ref, 0);
format_display(display, r ? '!' : '*', what,
r ? _("unable to update local ref") : NULL,
@@ -675,7 +677,7 @@ static int update_local_ref(struct ref *ref,
strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
- check_for_new_submodule_commits(ref->new_oid.hash);
+ check_for_new_submodule_commits(&ref->new_oid);
r = s_update_ref("fast-forward", ref, 1);
format_display(display, r ? '!' : ' ', quickref.buf,
r ? _("unable to update local ref") : NULL,
@@ -690,7 +692,7 @@ static int update_local_ref(struct ref *ref,
strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
- check_for_new_submodule_commits(ref->new_oid.hash);
+ check_for_new_submodule_commits(&ref->new_oid);
r = s_update_ref("forced-update", ref, 1);
format_display(display, r ? '!' : '+', quickref.buf,
r ? _("unable to update local ref") : _("forced update"),
@@ -768,7 +770,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
continue;
}
- commit = lookup_commit_reference_gently(rm->old_oid.hash, 1);
+ commit = lookup_commit_reference_gently(&rm->old_oid,
+ 1);
if (!commit)
rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE;
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 6faa3c0d24..70137b0b7e 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -341,7 +341,7 @@ static void shortlog(const char *name,
const struct object_id *oid = &origin_data->oid;
int limit = opts->shortlog_len;
- branch = deref_tag(parse_object(oid->hash), oid_to_hex(oid), GIT_SHA1_HEXSZ);
+ branch = deref_tag(parse_object(oid), oid_to_hex(oid), GIT_SHA1_HEXSZ);
if (!branch || branch->type != OBJ_COMMIT)
return;
@@ -559,14 +559,14 @@ static void find_merge_parents(struct merge_parents *result,
* "name" here and we do not want to contaminate its
* util field yet.
*/
- obj = parse_object(oid.hash);
+ obj = parse_object(&oid);
parent = (struct commit *)peel_to_type(NULL, 0, obj, OBJ_COMMIT);
if (!parent)
continue;
commit_list_insert(parent, &parents);
add_merge_parent(result, &obj->oid, &parent->object.oid);
}
- head_commit = lookup_commit(head->hash);
+ head_commit = lookup_commit(head);
if (head_commit)
commit_list_insert(head_commit, &parents);
parents = reduce_heads(parents);
@@ -633,7 +633,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
struct commit *head;
struct rev_info rev;
- head = lookup_commit_or_die(head_oid.hash, "HEAD");
+ head = lookup_commit_or_die(&head_oid, "HEAD");
init_revisions(&rev, NULL);
rev.commit_format = CMIT_FMT_ONELINE;
rev.ignore_merges = 1;
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index df41fa0350..eca365bf89 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -8,8 +8,8 @@
static char const * const for_each_ref_usage[] = {
N_("git for-each-ref [<options>] [<pattern>]"),
N_("git for-each-ref [--points-at <object>]"),
- N_("git for-each-ref [(--merged | --no-merged) [<object>]]"),
- N_("git for-each-ref [--contains [<object>]]"),
+ N_("git for-each-ref [(--merged | --no-merged) [<commit>]]"),
+ N_("git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"),
NULL
};
@@ -43,6 +43,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
OPT_MERGED(&filter, N_("print only refs that are merged")),
OPT_NO_MERGED(&filter, N_("print only refs that are not merged")),
OPT_CONTAINS(&filter.with_commit, N_("print only refs which contain the commit")),
+ OPT_NO_CONTAINS(&filter.no_commit, N_("print only refs which don't contain the commit")),
OPT_BOOL(0, "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
OPT_END(),
};
diff --git a/builtin/fsck.c b/builtin/fsck.c
index f76e4163ab..cb2ba6cd1b 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -377,7 +377,7 @@ static int fsck_obj(struct object *obj)
return 0;
}
-static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
+static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
unsigned long size, void *buffer, int *eaten)
{
/*
@@ -385,10 +385,10 @@ static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
* verify_packfile(), data_valid variable for details.
*/
struct object *obj;
- obj = parse_object_buffer(sha1, type, size, buffer, eaten);
+ obj = parse_object_buffer(oid, type, size, buffer, eaten);
if (!obj) {
errors_found |= ERROR_OBJECT;
- return error("%s: object corrupt or missing", sha1_to_hex(sha1));
+ return error("%s: object corrupt or missing", oid_to_hex(oid));
}
obj->flags = HAS_OBJ;
return fsck_obj(obj);
@@ -397,7 +397,7 @@ static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
static int default_refs;
static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
- unsigned long timestamp)
+ timestamp_t timestamp)
{
struct object *obj;
@@ -407,7 +407,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
if (timestamp && name_objects)
add_decoration(fsck_walk_options.object_names,
obj,
- xstrfmt("%s@{%ld}", refname, timestamp));
+ xstrfmt("%s@{%"PRItime"}", refname, timestamp));
obj->used = 1;
mark_object_reachable(obj);
} else {
@@ -418,7 +418,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
}
static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, unsigned long timestamp, int tz,
+ const char *email, timestamp_t timestamp, int tz,
const char *message, void *cb_data)
{
const char *refname = cb_data;
@@ -444,7 +444,7 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
{
struct object *obj;
- obj = parse_object(oid->hash);
+ obj = parse_object(oid);
if (!obj) {
error("%s: invalid sha1 pointer %s", refname, oid_to_hex(oid));
errors_found |= ERROR_REACHABLE;
@@ -506,7 +506,7 @@ static struct object *parse_loose_object(const struct object_id *oid,
if (!contents && type != OBJ_BLOB)
die("BUG: read_loose_object streamed a non-blob");
- obj = parse_object_buffer(oid->hash, type, size, contents, &eaten);
+ obj = parse_object_buffer(oid, type, size, contents, &eaten);
if (!eaten)
free(contents);
@@ -599,10 +599,10 @@ static int fsck_cache_tree(struct cache_tree *it)
fprintf(stderr, "Checking cache tree\n");
if (0 <= it->entry_count) {
- struct object *obj = parse_object(it->sha1);
+ struct object *obj = parse_object(&it->oid);
if (!obj) {
error("%s: invalid sha1 pointer in cache-tree",
- sha1_to_hex(it->sha1));
+ oid_to_hex(&it->oid));
errors_found |= ERROR_REFS;
return 1;
}
@@ -771,6 +771,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
}
if (keep_cache_objects) {
+ verify_index_checksum = 1;
read_cache();
for (i = 0; i < active_nr; i++) {
unsigned int mode;
@@ -780,7 +781,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
mode = active_cache[i]->ce_mode;
if (S_ISGITLINK(mode))
continue;
- blob = lookup_blob(active_cache[i]->oid.hash);
+ blob = lookup_blob(&active_cache[i]->oid);
if (!blob)
continue;
obj = &blob->object;
diff --git a/builtin/gc.c b/builtin/gc.c
index c2c61a57bb..f484eda43c 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -33,7 +33,7 @@ static int aggressive_window = 250;
static int gc_auto_threshold = 6700;
static int gc_auto_pack_limit = 50;
static int detach_auto = 1;
-static unsigned long gc_log_expire_time;
+static timestamp_t gc_log_expire_time;
static const char *gc_log_expire = "1.day.ago";
static const char *prune_expire = "2.weeks.ago";
static const char *prune_worktrees_expire = "3.months.ago";
@@ -135,8 +135,6 @@ static int too_many_loose_objects(void)
* distributed, we can check only one and get a reasonable
* estimate.
*/
- char path[PATH_MAX];
- const char *objdir = get_object_directory();
DIR *dir;
struct dirent *ent;
int auto_threshold;
@@ -146,11 +144,7 @@ static int too_many_loose_objects(void)
if (gc_auto_threshold <= 0)
return 0;
- if (sizeof(path) <= snprintf(path, sizeof(path), "%s/17", objdir)) {
- warning(_("insanely long object directory %.*s"), 50, objdir);
- return 0;
- }
- dir = opendir(path);
+ dir = opendir(git_path("objects/17"));
if (!dir)
return 0;
@@ -238,7 +232,7 @@ static int need_to_gc(void)
static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
{
static struct lock_file lock;
- char my_host[128];
+ char my_host[HOST_NAME_MAX + 1];
struct strbuf sb = STRBUF_INIT;
struct stat st;
uintmax_t pid;
@@ -250,15 +244,19 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
/* already locked */
return NULL;
- if (gethostname(my_host, sizeof(my_host)))
+ if (xgethostname(my_host, sizeof(my_host)))
xsnprintf(my_host, sizeof(my_host), "unknown");
pidfile_path = git_pathdup("gc.pid");
fd = hold_lock_file_for_update(&lock, pidfile_path,
LOCK_DIE_ON_ERROR);
if (!force) {
- static char locking_host[128];
+ static char locking_host[HOST_NAME_MAX + 1];
+ static char *scan_fmt;
int should_exit;
+
+ if (!scan_fmt)
+ scan_fmt = xstrfmt("%s %%%dc", "%"SCNuMAX, HOST_NAME_MAX);
fp = fopen(pidfile_path, "r");
memset(locking_host, 0, sizeof(locking_host));
should_exit =
@@ -274,7 +272,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
* running.
*/
time(NULL) - st.st_mtime <= 12 * 3600 &&
- fscanf(fp, "%"SCNuMAX" %127c", &pid, locking_host) == 2 &&
+ fscanf(fp, scan_fmt, &pid, locking_host) == 2 &&
/* be gentle to concurrent "gc" on remote hosts */
(strcmp(locking_host, my_host) || !kill(pid, 0) || errno == EPERM);
if (fp != NULL)
diff --git a/builtin/grep.c b/builtin/grep.c
index 837836fb3e..c6c26e9b9e 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -310,10 +310,7 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
{
struct strbuf pathbuf = STRBUF_INIT;
- 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 if (super_prefix) {
+ if (super_prefix) {
strbuf_add(&pathbuf, filename, tree_name_len);
strbuf_addstr(&pathbuf, super_prefix);
strbuf_addstr(&pathbuf, filename + tree_name_len);
@@ -321,6 +318,13 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
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_SHA1, pathbuf.buf, path, oid);
@@ -345,12 +349,14 @@ 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) {
- quote_path_relative(filename, opt->prefix, &buf);
- } else {
- if (super_prefix)
- strbuf_addstr(&buf, super_prefix);
- strbuf_addstr(&buf, filename);
+ char *name = strbuf_detach(&buf, NULL);
+ quote_path_relative(name, opt->prefix, &buf);
+ free(name);
}
#ifndef NO_PTHREADS
@@ -399,13 +405,12 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
}
static void compile_submodule_options(const struct grep_opt *opt,
- const struct pathspec *pathspec,
+ const char **argv,
int cached, int untracked,
int opt_exclude, int use_index,
int pattern_type_arg)
{
struct grep_pat *pattern;
- int i;
if (recurse_submodules)
argv_array_push(&submodule_options, "--recurse-submodules");
@@ -523,9 +528,8 @@ static void compile_submodule_options(const struct grep_opt *opt,
/* Add Pathspecs */
argv_array_push(&submodule_options, "--");
- for (i = 0; i < pathspec->nr; i++)
- argv_array_push(&submodule_options,
- pathspec->items[i].original);
+ for (; *argv; argv++)
+ argv_array_push(&submodule_options, *argv);
}
/*
@@ -538,7 +542,7 @@ static int grep_submodule_launch(struct grep_opt *opt,
int status, i;
const char *end_of_base;
const char *name;
- struct work_item *w = opt->output_priv;
+ struct strbuf child_output = STRBUF_INIT;
end_of_base = strchr(gs->name, ':');
if (gs->identifier && end_of_base)
@@ -549,6 +553,11 @@ static int grep_submodule_launch(struct grep_opt *opt,
prepare_submodule_repo_env(&cp.env_array);
argv_array_push(&cp.env_array, GIT_DIR_ENVIRONMENT);
+ if (opt->relative && opt->prefix_length)
+ argv_array_pushf(&cp.env_array, "%s=%s",
+ GIT_TOPLEVEL_PREFIX_ENVIRONMENT,
+ opt->prefix);
+
/* Add super prefix */
argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
super_prefix ? super_prefix : "",
@@ -593,14 +602,16 @@ static int grep_submodule_launch(struct grep_opt *opt,
* child process. A '0' indicates a hit, a '1' indicates no hit and
* anything else is an error.
*/
- status = capture_command(&cp, &w->out, 0);
+ status = capture_command(&cp, &child_output, 0);
if (status && (status != 1)) {
/* flush the buffer */
- write_or_die(1, w->out.buf, w->out.len);
+ write_or_die(1, child_output.buf, child_output.len);
die("process for submodule '%s' failed with exit code: %d",
gs->name, status);
}
+ 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;
}
@@ -616,7 +627,7 @@ static int grep_submodule(struct grep_opt *opt, const unsigned char *sha1,
{
if (!is_submodule_initialized(path))
return 0;
- if (!is_submodule_populated(path)) {
+ if (!is_submodule_populated_gently(path, NULL)) {
/*
* If searching history, check for the presense of the
* submodule's gitdir before skipping the submodule.
@@ -641,19 +652,14 @@ static int grep_submodule(struct grep_opt *opt, const unsigned char *sha1,
} else
#endif
{
- struct work_item w;
+ struct grep_source gs;
int hit;
- grep_source_init(&w.source, GREP_SOURCE_SUBMODULE,
+ grep_source_init(&gs, GREP_SOURCE_SUBMODULE,
filename, path, sha1);
- strbuf_init(&w.out, 0);
- opt->output_priv = &w;
- hit = grep_submodule_launch(opt, &w.source);
-
- write_or_die(1, w.out.buf, w.out.len);
+ hit = grep_submodule_launch(opt, &gs);
- grep_source_clear(&w.source);
- strbuf_release(&w.out);
+ grep_source_clear(&gs);
return hit;
}
}
@@ -860,7 +866,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
if (exc_std)
setup_standard_excludes(&dir);
- fill_directory(&dir, pathspec);
+ fill_directory(&dir, &the_index, pathspec);
for (i = 0; i < dir.nr; i++) {
if (!dir_path_match(dir.entries[i], pathspec, 0, NULL))
continue;
@@ -979,7 +985,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_SET_INT(0, "exclude-standard", &opt_exclude,
N_("ignore files specified via '.gitignore'"), 1),
OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
- N_("recursivley search in each submodule")),
+ N_("recursively search in each submodule")),
OPT_STRING(0, "parent-basename", &parent_basename,
N_("basename"),
N_("prepend parent project's basename to output")),
@@ -1190,7 +1196,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
break;
}
- object = parse_object_or_die(oid.hash, arg);
+ object = parse_object_or_die(&oid, arg);
if (!seen_dashdash)
verify_non_filename(prefix, arg);
add_object_array_with_path(object, arg, &list, oc.mode, oc.path);
@@ -1236,7 +1242,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (recurse_submodules) {
gitmodules_config();
- compile_submodule_options(&opt, &pathspec, cached, untracked,
+ compile_submodule_options(&opt, argv + i, cached, untracked,
opt_exclude, use_index,
pattern_type_arg);
}
@@ -1293,6 +1299,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
hit |= wait_all();
if (hit && show_in_pager)
run_pager(&opt, prefix);
+ clear_pathspec(&pathspec);
free_grep_patterns(&opt);
return !hit;
}
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 88d205f858..04b9dcaf0f 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -307,14 +307,15 @@ static const char *open_pack_file(const char *pack_name)
if (from_stdin) {
input_fd = 0;
if (!pack_name) {
- static char tmp_file[PATH_MAX];
- output_fd = odb_mkstemp(tmp_file, sizeof(tmp_file),
+ struct strbuf tmp_file = STRBUF_INIT;
+ output_fd = odb_mkstemp(&tmp_file,
"pack/tmp_pack_XXXXXX");
- pack_name = xstrdup(tmp_file);
- } else
+ pack_name = strbuf_detach(&tmp_file, NULL);
+ } else {
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
- if (output_fd < 0)
- die_errno(_("unable to create '%s'"), pack_name);
+ if (output_fd < 0)
+ die_errno(_("unable to create '%s'"), pack_name);
+ }
nothread_data.pack_fd = output_fd;
} else {
input_fd = open(pack_name, O_RDONLY);
@@ -746,13 +747,13 @@ static int compare_objects(const unsigned char *buf, unsigned long size,
ssize_t len = read_istream(data->st, data->buf, size);
if (len == 0)
die(_("SHA1 COLLISION FOUND WITH %s !"),
- sha1_to_hex(data->entry->idx.sha1));
+ oid_to_hex(&data->entry->idx.oid));
if (len < 0)
die(_("unable to read %s"),
- sha1_to_hex(data->entry->idx.sha1));
+ oid_to_hex(&data->entry->idx.oid));
if (memcmp(buf, data->buf, len))
die(_("SHA1 COLLISION FOUND WITH %s !"),
- sha1_to_hex(data->entry->idx.sha1));
+ oid_to_hex(&data->entry->idx.oid));
size -= len;
buf += len;
}
@@ -770,12 +771,12 @@ static int check_collison(struct object_entry *entry)
memset(&data, 0, sizeof(data));
data.entry = entry;
- data.st = open_istream(entry->idx.sha1, &type, &size, NULL);
+ data.st = open_istream(entry->idx.oid.hash, &type, &size, NULL);
if (!data.st)
return -1;
if (size != entry->size || type != entry->type)
die(_("SHA1 COLLISION FOUND WITH %s !"),
- sha1_to_hex(entry->idx.sha1));
+ oid_to_hex(&entry->idx.oid));
unpack_data(entry, compare_objects, &data);
close_istream(data.st);
free(data.buf);
@@ -784,7 +785,7 @@ static int check_collison(struct object_entry *entry)
static void sha1_object(const void *data, struct object_entry *obj_entry,
unsigned long size, enum object_type type,
- const unsigned char *sha1)
+ const struct object_id *oid)
{
void *new_data = NULL;
int collision_test_needed = 0;
@@ -793,7 +794,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
if (startup_info->have_repository) {
read_lock();
- collision_test_needed = has_sha1_file_with_flags(sha1, HAS_SHA1_QUICK);
+ collision_test_needed = has_sha1_file_with_flags(oid->hash, HAS_SHA1_QUICK);
read_unlock();
}
@@ -808,29 +809,31 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
enum object_type has_type;
unsigned long has_size;
read_lock();
- has_type = sha1_object_info(sha1, &has_size);
+ has_type = sha1_object_info(oid->hash, &has_size);
+ if (has_type < 0)
+ die(_("cannot read existing object info %s"), oid_to_hex(oid));
if (has_type != type || has_size != size)
- die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1));
- has_data = read_sha1_file(sha1, &has_type, &has_size);
+ die(_("SHA1 COLLISION FOUND WITH %s !"), oid_to_hex(oid));
+ has_data = read_sha1_file(oid->hash, &has_type, &has_size);
read_unlock();
if (!data)
data = new_data = get_data_from_pack(obj_entry);
if (!has_data)
- die(_("cannot read existing object %s"), sha1_to_hex(sha1));
+ die(_("cannot read existing object %s"), oid_to_hex(oid));
if (size != has_size || type != has_type ||
memcmp(data, has_data, size) != 0)
- die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1));
+ die(_("SHA1 COLLISION FOUND WITH %s !"), oid_to_hex(oid));
free(has_data);
}
if (strict) {
read_lock();
if (type == OBJ_BLOB) {
- struct blob *blob = lookup_blob(sha1);
+ struct blob *blob = lookup_blob(oid);
if (blob)
blob->object.flags |= FLAG_CHECKED;
else
- die(_("invalid blob object %s"), sha1_to_hex(sha1));
+ die(_("invalid blob object %s"), oid_to_hex(oid));
} else {
struct object *obj;
int eaten;
@@ -842,7 +845,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
* we do not need to free the memory here, as the
* buf is deleted by the caller.
*/
- obj = parse_object_buffer(sha1, type, size, buf, &eaten);
+ obj = parse_object_buffer(oid, type, size, buf,
+ &eaten);
if (!obj)
die(_("invalid %s"), typename(type));
if (do_fsck_object &&
@@ -954,9 +958,10 @@ static void resolve_delta(struct object_entry *delta_obj,
if (!result->data)
bad_object(delta_obj->idx.offset, _("failed to apply delta"));
hash_sha1_file(result->data, result->size,
- typename(delta_obj->real_type), delta_obj->idx.sha1);
+ typename(delta_obj->real_type),
+ delta_obj->idx.oid.hash);
sha1_object(result->data, NULL, result->size, delta_obj->real_type,
- delta_obj->idx.sha1);
+ &delta_obj->idx.oid);
counter_lock();
nr_resolved_deltas++;
counter_unlock();
@@ -986,7 +991,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
struct base_data *prev_base)
{
if (base->ref_last == -1 && base->ofs_last == -1) {
- find_ref_delta_children(base->obj->idx.sha1,
+ find_ref_delta_children(base->obj->idx.oid.hash,
&base->ref_first, &base->ref_last,
OBJ_REF_DELTA);
@@ -1127,7 +1132,8 @@ static void parse_pack_objects(unsigned char *sha1)
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
void *data = unpack_raw_entry(obj, &ofs_delta->offset,
- ref_delta_sha1, obj->idx.sha1);
+ ref_delta_sha1,
+ obj->idx.oid.hash);
obj->real_type = obj->type;
if (obj->type == OBJ_OFS_DELTA) {
nr_ofs_deltas++;
@@ -1143,7 +1149,8 @@ static void parse_pack_objects(unsigned char *sha1)
obj->real_type = OBJ_BAD;
nr_delays++;
} else
- sha1_object(data, NULL, obj->size, obj->type, obj->idx.sha1);
+ sha1_object(data, NULL, obj->size, obj->type,
+ &obj->idx.oid);
free(data);
display_progress(progress, i+1);
}
@@ -1169,7 +1176,8 @@ static void parse_pack_objects(unsigned char *sha1)
if (obj->real_type != OBJ_BAD)
continue;
obj->real_type = obj->type;
- sha1_object(NULL, obj, obj->size, obj->type, obj->idx.sha1);
+ sha1_object(NULL, obj, obj->size, obj->type,
+ &obj->idx.oid);
nr_delays--;
}
if (nr_delays)
@@ -1327,7 +1335,7 @@ static struct object_entry *append_obj_to_pack(struct sha1file *f,
obj[1].idx.offset += write_compressed(f, buf, size);
obj[0].idx.crc32 = crc32_end(f);
sha1flush(f);
- hashcpy(obj->idx.sha1, sha1);
+ hashcpy(obj->idx.oid.hash, sha1);
return obj;
}
@@ -1442,10 +1450,11 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
if (!from_stdin) {
printf("%s\n", sha1_to_hex(sha1));
} else {
- char buf[48];
- int len = snprintf(buf, sizeof(buf), "%s\t%s\n",
- report, sha1_to_hex(sha1));
- write_or_die(1, buf, len);
+ struct strbuf buf = STRBUF_INIT;
+
+ strbuf_addf(&buf, "%s\t%s\n", report, sha1_to_hex(sha1));
+ write_or_die(1, buf.buf, buf.len);
+ strbuf_release(&buf);
/*
* Let's just mimic git-unpack-objects here and write
@@ -1577,13 +1586,14 @@ static void show_pack_info(int stat_only)
if (stat_only)
continue;
printf("%s %-6s %lu %lu %"PRIuMAX,
- sha1_to_hex(obj->idx.sha1),
+ oid_to_hex(&obj->idx.oid),
typename(obj->real_type), obj->size,
(unsigned long)(obj[1].idx.offset - obj->idx.offset),
(uintmax_t)obj->idx.offset);
if (is_delta_type(obj->type)) {
struct object_entry *bobj = &objects[obj_stat[i].base_object_no];
- printf(" %u %s", obj_stat[i].delta_depth, sha1_to_hex(bobj->idx.sha1));
+ printf(" %u %s", obj_stat[i].delta_depth,
+ oid_to_hex(&bobj->idx.oid));
}
putchar('\n');
}
diff --git a/builtin/log.c b/builtin/log.c
index 670229cbb4..a440601efe 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -52,6 +52,11 @@ struct line_opt_callback_data {
struct string_list args;
};
+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)
{
switch (git_config_maybe_bool(var, value)) {
@@ -67,7 +72,7 @@ static int parse_decoration_style(const char *var, const char *value)
else if (!strcmp(value, "short"))
return DECORATE_SHORT_REFS;
else if (!strcmp(value, "auto"))
- return (isatty(1) || pager_in_use()) ? DECORATE_SHORT_REFS : 0;
+ return auto_decoration_style();
return -1;
}
@@ -105,6 +110,8 @@ static void init_log_defaults(void)
{
init_grep_defaults();
init_diff_ui_defaults();
+
+ decoration_style = auto_decoration_style();
}
static void cmd_log_init_defaults(struct rev_info *rev)
@@ -589,7 +596,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
rev.shown_one = 1;
if (ret)
break;
- o = parse_object(t->tagged->oid.hash);
+ o = parse_object(&t->tagged->oid);
if (!o)
ret = error(_("Could not read object %s"),
oid_to_hex(&t->tagged->oid));
@@ -871,8 +878,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
o2 = rev->pending.objects[1].item;
flags1 = o1->flags;
flags2 = o2->flags;
- c1 = lookup_commit_reference(o1->oid.hash);
- c2 = lookup_commit_reference(o2->oid.hash);
+ c1 = lookup_commit_reference(&o1->oid);
+ c2 = lookup_commit_reference(&o2->oid);
if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
die(_("Not a range."));
@@ -903,8 +910,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
static void gen_message_id(struct rev_info *info, char *base)
{
struct strbuf buf = STRBUF_INIT;
- strbuf_addf(&buf, "%s.%lu.git.%s", base,
- (unsigned long) time(NULL),
+ strbuf_addf(&buf, "%s.%"PRItime".git.%s", base,
+ (timestamp_t) time(NULL),
git_committer_info(IDENT_NO_NAME|IDENT_NO_DATE|IDENT_STRICT));
info->message_id = strbuf_detach(&buf, NULL);
}
@@ -1256,7 +1263,7 @@ static struct commit *get_base_commit(const char *base_commit,
if (get_oid(upstream, &oid))
die(_("Failed to resolve '%s' as a valid ref."), upstream);
- commit = lookup_commit_or_die(oid.hash, "upstream base");
+ commit = lookup_commit_or_die(&oid, "upstream base");
base_list = get_merge_bases_many(commit, total, list);
/* There should be one and only one merge base. */
if (!base_list || base_list->next)
@@ -1812,7 +1819,7 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
{
struct object_id oid;
if (get_oid(arg, &oid) == 0) {
- struct commit *commit = lookup_commit_reference(oid.hash);
+ struct commit *commit = lookup_commit_reference(&oid);
if (commit) {
commit->object.flags |= flags;
add_pending_object(revs, &commit->object, arg);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 1c0f057d02..530e6ae7f7 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -15,6 +15,7 @@
#include "string-list.h"
#include "pathspec.h"
#include "run-command.h"
+#include "submodule.h"
static int abbrev;
static int show_deleted;
@@ -30,7 +31,7 @@ static int line_terminator = '\n';
static int debug_mode;
static int show_eol;
static int recurse_submodules;
-static struct argv_array submodules_options = ARGV_ARRAY_INIT;
+static struct argv_array submodule_options = ARGV_ARRAY_INIT;
static const char *prefix;
static const char *super_prefix;
@@ -172,20 +173,27 @@ static void show_killed_files(struct dir_struct *dir)
/*
* Compile an argv_array with all of the options supported by --recurse_submodules
*/
-static void compile_submodule_options(const struct dir_struct *dir, int show_tag)
+static void compile_submodule_options(const char **argv,
+ const struct dir_struct *dir,
+ int show_tag)
{
if (line_terminator == '\0')
- argv_array_push(&submodules_options, "-z");
+ argv_array_push(&submodule_options, "-z");
if (show_tag)
- argv_array_push(&submodules_options, "-t");
+ argv_array_push(&submodule_options, "-t");
if (show_valid_bit)
- argv_array_push(&submodules_options, "-v");
+ argv_array_push(&submodule_options, "-v");
if (show_cached)
- argv_array_push(&submodules_options, "--cached");
+ argv_array_push(&submodule_options, "--cached");
if (show_eol)
- argv_array_push(&submodules_options, "--eol");
+ argv_array_push(&submodule_options, "--eol");
if (debug_mode)
- argv_array_push(&submodules_options, "--debug");
+ argv_array_push(&submodule_options, "--debug");
+
+ /* Add Pathspecs */
+ argv_array_push(&submodule_options, "--");
+ for (; *argv; argv++)
+ argv_array_push(&submodule_options, *argv);
}
/**
@@ -195,8 +203,15 @@ static void show_gitlink(const struct cache_entry *ce)
{
struct child_process cp = CHILD_PROCESS_INIT;
int status;
- int i;
+ char *dir;
+
+ prepare_submodule_repo_env(&cp.env_array);
+ argv_array_push(&cp.env_array, GIT_DIR_ENVIRONMENT);
+ if (prefix_len)
+ argv_array_pushf(&cp.env_array, "%s=%s",
+ GIT_TOPLEVEL_PREFIX_ENVIRONMENT,
+ prefix);
argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
super_prefix ? super_prefix : "",
ce->name);
@@ -204,20 +219,13 @@ static void show_gitlink(const struct cache_entry *ce)
argv_array_push(&cp.args, "--recurse-submodules");
/* add supported options */
- argv_array_pushv(&cp.args, submodules_options.argv);
-
- /*
- * Pass in the original pathspec args. The submodule will be
- * responsible for prepending the 'submodule_prefix' prior to comparing
- * against the pathspec for matches.
- */
- argv_array_push(&cp.args, "--");
- for (i = 0; i < pathspec.nr; i++)
- argv_array_push(&cp.args, pathspec.items[i].original);
+ argv_array_pushv(&cp.args, submodule_options.argv);
cp.git_cmd = 1;
- cp.dir = ce->name;
+ dir = mkpathdup("%s/%s", get_git_work_tree(), ce->name);
+ cp.dir = dir;
status = run_command(&cp);
+ free(dir);
if (status)
exit(status);
}
@@ -314,7 +322,7 @@ static void show_ru_info(void)
static int ce_excluded(struct dir_struct *dir, const struct cache_entry *ce)
{
int dtype = ce_to_dtype(ce);
- return is_excluded(dir, ce->name, &dtype);
+ return is_excluded(dir, &the_index, ce->name, &dtype);
}
static void show_files(struct dir_struct *dir)
@@ -325,7 +333,7 @@ static void show_files(struct dir_struct *dir)
if (show_others || show_killed) {
if (!show_others)
dir->flags |= DIR_COLLECT_KILLED_ONLY;
- fill_directory(dir, &pathspec);
+ fill_directory(dir, &the_index, &pathspec);
if (show_others)
show_other_files(dir);
if (show_killed)
@@ -406,14 +414,14 @@ static void prune_cache(const char *prefix, size_t prefixlen)
void overlay_tree_on_cache(const char *tree_name, const char *prefix)
{
struct tree *tree;
- unsigned char sha1[20];
+ struct object_id oid;
struct pathspec pathspec;
struct cache_entry *last_stage0 = NULL;
int i;
- if (get_sha1(tree_name, sha1))
+ if (get_oid(tree_name, &oid))
die("tree-ish %s not found.", tree_name);
- tree = parse_tree_indirect(sha1);
+ tree = parse_tree_indirect(&oid);
if (!tree)
die("bad tree-ish %s", tree_name);
@@ -604,7 +612,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
setup_work_tree();
if (recurse_submodules)
- compile_submodule_options(&dir, show_tag);
+ compile_submodule_options(argv, &dir, show_tag);
if (recurse_submodules &&
(show_stage || show_deleted || show_others || show_unmerged ||
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 66cdd45cc1..b2d7d5ce68 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -17,17 +17,19 @@ static const char * const ls_remote_usage[] = {
static int tail_match(const char **pattern, const char *path)
{
const char *p;
- char pathbuf[PATH_MAX];
+ char *pathbuf;
if (!pattern)
return 1; /* no restriction */
- if (snprintf(pathbuf, sizeof(pathbuf), "/%s", path) > sizeof(pathbuf))
- return error("insanely long ref %.*s...", 20, path);
+ pathbuf = xstrfmt("/%s", path);
while ((p = *(pattern++)) != NULL) {
- if (!wildmatch(p, pathbuf, 0, NULL))
+ if (!wildmatch(p, pathbuf, 0, NULL)) {
+ free(pathbuf);
return 1;
+ }
}
+ free(pathbuf);
return 0;
}
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index d7ebeb4ce6..ee7b293b11 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -119,7 +119,7 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base,
int cmd_ls_tree(int argc, const char **argv, const char *prefix)
{
- unsigned char sha1[20];
+ struct object_id oid;
struct tree *tree;
int i, full_tree = 0;
const struct option ls_tree_options[] = {
@@ -164,7 +164,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
if (argc < 1)
usage_with_options(ls_tree_usage, ls_tree_options);
- if (get_sha1(argv[0], sha1))
+ if (get_oid(argv[0], &oid))
die("Not a valid object name %s", argv[0]);
/*
@@ -180,7 +180,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
for (i = 0; i < pathspec.nr; i++)
pathspec.items[i].nowildcard_len = pathspec.items[i].len;
pathspec.has_wildcard = 0;
- tree = parse_tree_indirect(sha1);
+ tree = parse_tree_indirect(&oid);
if (!tree)
die("not a tree object");
return !!read_tree_recursive(tree, "", 0, 0, &pathspec, show_tree, NULL);
diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c
index 30681681c1..664400b816 100644
--- a/builtin/mailsplit.c
+++ b/builtin/mailsplit.c
@@ -232,6 +232,16 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,
do {
peek = fgetc(f);
+ if (peek == EOF) {
+ if (f == stdin)
+ /* empty stdin is OK */
+ ret = skip;
+ else {
+ fclose(f);
+ error(_("empty mbox: '%s'"), file);
+ }
+ goto out;
+ }
} while (isspace(peek));
ungetc(peek, f);
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index cfe2a796f8..0c36a70ad8 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -41,7 +41,7 @@ static struct commit *get_commit_reference(const char *arg)
if (get_oid(arg, &revkey))
die("Not a valid object name %s", arg);
- r = lookup_commit_reference(revkey.hash);
+ r = lookup_commit_reference(&revkey);
if (!r)
die("Not a valid commit name %s", arg);
@@ -120,7 +120,7 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs)
if (is_null_oid(oid))
return;
- commit = lookup_commit(oid->hash);
+ commit = lookup_commit(oid);
if (!commit ||
(commit->object.flags & TMP_MARK) ||
parse_commit(commit))
@@ -132,7 +132,7 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs)
}
static int collect_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *ident, unsigned long timestamp,
+ const char *ident, timestamp_t timestamp,
int tz, const char *message, void *cbdata)
{
struct rev_collect *revs = cbdata;
@@ -168,7 +168,7 @@ static int handle_fork_point(int argc, const char **argv)
if (get_oid(commitname, &oid))
die("Not a valid object name: '%s'", commitname);
- derived = lookup_commit_reference(oid.hash);
+ derived = lookup_commit_reference(&oid);
memset(&revs, 0, sizeof(revs));
revs.initial = 1;
for_each_reflog_ent(refname, collect_one_reflog_ent, &revs);
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index 2d1b6db6bd..c99443b095 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -9,7 +9,7 @@ static int merge_entry(int pos, const char *path)
{
int found;
const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
- char hexbuf[4][GIT_SHA1_HEXSZ + 1];
+ char hexbuf[4][GIT_MAX_HEXSZ + 1];
char ownbuf[4][60];
if (pos >= active_nr)
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 5b7ab9b967..bad6735c76 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -161,14 +161,14 @@ static int both_empty(struct name_entry *a, struct name_entry *b)
return !(a->oid || b->oid);
}
-static struct merge_list *create_entry(unsigned stage, unsigned mode, const unsigned char *sha1, const char *path)
+static struct merge_list *create_entry(unsigned stage, unsigned mode, const struct object_id *oid, const char *path)
{
struct merge_list *res = xcalloc(1, sizeof(*res));
res->stage = stage;
res->path = path;
res->mode = mode;
- res->blob = lookup_blob(sha1);
+ res->blob = lookup_blob(oid);
return res;
}
@@ -188,8 +188,8 @@ static void resolve(const struct traverse_info *info, struct name_entry *ours, s
return;
path = traverse_path(info, result);
- orig = create_entry(2, ours->mode, ours->oid->hash, path);
- final = create_entry(0, result->mode, result->oid->hash, path);
+ orig = create_entry(2, ours->mode, ours->oid, path);
+ final = create_entry(0, result->mode, result->oid, path);
final->link = orig;
@@ -239,7 +239,7 @@ static struct merge_list *link_entry(unsigned stage, const struct traverse_info
path = entry->path;
else
path = traverse_path(info, n);
- link = create_entry(stage, n->mode, n->oid->hash, path);
+ link = create_entry(stage, n->mode, n->oid, path);
link->link = entry;
return link;
}
diff --git a/builtin/merge.c b/builtin/merge.c
index 7554b8d412..a4a098f40f 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -44,7 +44,6 @@ struct strategy {
static const char * const builtin_merge_usage[] = {
N_("git merge [<options>] [<commit>...]"),
- N_("git merge [<options>] <msg> HEAD <commit>"),
N_("git merge --abort"),
N_("git merge --continue"),
NULL
@@ -606,13 +605,13 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,
opts.verbose_update = 1;
opts.trivial_merges_only = 1;
opts.merge = 1;
- trees[nr_trees] = parse_tree_indirect(common->hash);
+ trees[nr_trees] = parse_tree_indirect(common);
if (!trees[nr_trees++])
return -1;
- trees[nr_trees] = parse_tree_indirect(head->hash);
+ trees[nr_trees] = parse_tree_indirect(head);
if (!trees[nr_trees++])
return -1;
- trees[nr_trees] = parse_tree_indirect(one->hash);
+ trees[nr_trees] = parse_tree_indirect(one);
if (!trees[nr_trees++])
return -1;
opts.fn = threeway_merge;
@@ -634,9 +633,10 @@ static void write_tree_trivial(struct object_id *oid)
static int try_merge_strategy(const char *strategy, struct commit_list *common,
struct commit_list *remoteheads,
- struct commit *head, const char *head_arg)
+ struct commit *head)
{
static struct lock_file lock;
+ const char *head_arg = "HEAD";
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
refresh_cache(REFRESH_QUIET);
@@ -853,24 +853,6 @@ static int suggest_conflicts(void)
return 1;
}
-static struct commit *is_old_style_invocation(int argc, const char **argv,
- const struct object_id *head)
-{
- struct commit *second_token = NULL;
- if (argc > 2) {
- struct object_id second_oid;
-
- if (get_oid(argv[1], &second_oid))
- return NULL;
- second_token = lookup_commit_reference_gently(second_oid.hash, 0);
- if (!second_token)
- die(_("'%s' is not a commit"), argv[1]);
- if (oidcmp(&second_token->object.oid, head))
- return NULL;
- }
- return second_token;
-}
-
static int evaluate_result(void)
{
int cnt = 0;
@@ -1120,7 +1102,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
struct object_id result_tree, stash, head_oid;
struct commit *head_commit;
struct strbuf buf = STRBUF_INIT;
- const char *head_arg;
int i, ret = 0, head_subsumed;
int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0;
struct commit_list *common = NULL;
@@ -1142,7 +1123,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (!branch || is_null_oid(&head_oid))
head_commit = NULL;
else
- head_commit = lookup_commit_or_die(head_oid.hash, "HEAD");
+ head_commit = lookup_commit_or_die(&head_oid, "HEAD");
init_diff_ui_defaults();
git_config(git_merge_config, NULL);
@@ -1260,34 +1241,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
}
/*
- * This could be traditional "merge <msg> HEAD <commit>..." and
- * the way we can tell it is to see if the second token is HEAD,
- * but some people might have misused the interface and used a
- * commit-ish that is the same as HEAD there instead.
- * Traditional format never would have "-m" so it is an
- * additional safety measure to check for it.
+ * All the rest are the commits being merged; prepare
+ * the standard merge summary message to be appended
+ * to the given message.
*/
- if (!have_message &&
- is_old_style_invocation(argc, argv, &head_commit->object.oid)) {
- warning("old-style 'git merge <msg> HEAD <commit>' is deprecated.");
- strbuf_addstr(&merge_msg, argv[0]);
- head_arg = argv[1];
- argv += 2;
- argc -= 2;
- remoteheads = collect_parents(head_commit, &head_subsumed,
- argc, argv, NULL);
- } else {
- /* We are invoked directly as the first-class UI. */
- head_arg = "HEAD";
-
- /*
- * All the rest are the commits being merged; prepare
- * the standard merge summary message to be appended
- * to the given message.
- */
- remoteheads = collect_parents(head_commit, &head_subsumed,
- argc, argv, &merge_msg);
- }
+ remoteheads = collect_parents(head_commit, &head_subsumed,
+ argc, argv, &merge_msg);
if (!head_commit || !argc)
usage_with_options(builtin_merge_usage,
@@ -1296,7 +1255,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (verify_signatures) {
for (p = remoteheads; p; p = p->next) {
struct commit *commit = p->item;
- char hex[GIT_SHA1_HEXSZ + 1];
+ char hex[GIT_MAX_HEXSZ + 1];
struct signature_check signature_check;
memset(&signature_check, 0, sizeof(signature_check));
@@ -1413,8 +1372,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
goto done;
}
- if (checkout_fast_forward(head_commit->object.oid.hash,
- commit->object.oid.hash,
+ if (checkout_fast_forward(&head_commit->object.oid,
+ &commit->object.oid,
overwrite_ignore)) {
ret = 1;
goto done;
@@ -1513,7 +1472,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
ret = try_merge_strategy(use_strategies[i]->name,
common, remoteheads,
- head_commit, head_arg);
+ head_commit);
if (!option_commit && !ret) {
merge_was_ok = 1;
/*
@@ -1583,7 +1542,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
printf(_("Using the %s to prepare resolving by hand.\n"),
best_strategy);
try_merge_strategy(best_strategy, common, remoteheads,
- head_commit, head_arg);
+ head_commit);
}
if (squash)
diff --git a/builtin/mktree.c b/builtin/mktree.c
index de9b40fc63..da0fd8cd70 100644
--- a/builtin/mktree.c
+++ b/builtin/mktree.c
@@ -72,7 +72,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
unsigned mode;
enum object_type mode_type; /* object type derived from mode */
enum object_type obj_type; /* object type derived from sha */
- char *path;
+ char *path, *to_free = NULL;
unsigned char sha1[20];
ptr = buf;
@@ -102,7 +102,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
struct strbuf p_uq = STRBUF_INIT;
if (unquote_c_style(&p_uq, path, NULL))
die("invalid quoting");
- path = strbuf_detach(&p_uq, NULL);
+ path = to_free = strbuf_detach(&p_uq, NULL);
}
/*
@@ -136,6 +136,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
}
append_to_tree(mode, sha1, path);
+ free(to_free);
}
int cmd_mktree(int ac, const char **av, const char *prefix)
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index bf7ed015ae..663e26ebbd 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -10,7 +10,7 @@
typedef struct rev_name {
const char *tip_name;
- unsigned long taggerdate;
+ timestamp_t taggerdate;
int generation;
int distance;
int from_tag;
@@ -23,7 +23,7 @@ static long cutoff = LONG_MAX;
static int is_better_name(struct rev_name *name,
const char *tip_name,
- unsigned long taggerdate,
+ timestamp_t taggerdate,
int generation,
int distance,
int from_tag)
@@ -60,13 +60,14 @@ static int is_better_name(struct rev_name *name,
}
static void name_rev(struct commit *commit,
- const char *tip_name, unsigned long taggerdate,
+ const char *tip_name, timestamp_t taggerdate,
int generation, int distance, int from_tag,
int deref)
{
struct rev_name *name = (struct rev_name *)commit->util;
struct commit_list *parents;
int parent_number = 1;
+ char *to_free = NULL;
parse_commit(commit);
@@ -74,7 +75,7 @@ static void name_rev(struct commit *commit,
return;
if (deref) {
- tip_name = xstrfmt("%s^0", tip_name);
+ tip_name = to_free = xstrfmt("%s^0", tip_name);
if (generation)
die("generation: %d, but deref?", generation);
@@ -92,8 +93,10 @@ copy_data:
name->generation = generation;
name->distance = distance;
name->from_tag = from_tag;
- } else
+ } else {
+ free(to_free);
return;
+ }
for (parents = commit->parents;
parents;
@@ -155,7 +158,7 @@ struct name_ref_data {
static struct tip_table {
struct tip_table_entry {
- unsigned char sha1[20];
+ struct object_id oid;
const char *refname;
} *table;
int nr;
@@ -163,13 +166,13 @@ static struct tip_table {
int sorted;
} tip_table;
-static void add_to_tip_table(const unsigned char *sha1, const char *refname,
+static void add_to_tip_table(const struct object_id *oid, const char *refname,
int shorten_unambiguous)
{
refname = name_ref_abbrev(refname, shorten_unambiguous);
ALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);
- hashcpy(tip_table.table[tip_table.nr].sha1, sha1);
+ oidcpy(&tip_table.table[tip_table.nr].oid, oid);
tip_table.table[tip_table.nr].refname = xstrdup(refname);
tip_table.nr++;
tip_table.sorted = 0;
@@ -178,16 +181,16 @@ static void add_to_tip_table(const unsigned char *sha1, const char *refname,
static int tipcmp(const void *a_, const void *b_)
{
const struct tip_table_entry *a = a_, *b = b_;
- return hashcmp(a->sha1, b->sha1);
+ return oidcmp(&a->oid, &b->oid);
}
static int name_ref(const char *path, const struct object_id *oid, int flags, void *cb_data)
{
- struct object *o = parse_object(oid->hash);
+ struct object *o = parse_object(oid);
struct name_ref_data *data = cb_data;
int can_abbreviate_output = data->tags_only && data->name_only;
int deref = 0;
- unsigned long taggerdate = ULONG_MAX;
+ timestamp_t taggerdate = TIME_MAX;
if (data->tags_only && !starts_with(path, "refs/tags/"))
return 0;
@@ -235,13 +238,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
return 0;
}
- add_to_tip_table(oid->hash, path, can_abbreviate_output);
+ add_to_tip_table(oid, path, can_abbreviate_output);
while (o && o->type == OBJ_TAG) {
struct tag *t = (struct tag *) o;
if (!t->tagged)
break; /* broken repository */
- o = parse_object(t->tagged->oid.hash);
+ o = parse_object(&t->tagged->oid);
deref = 1;
taggerdate = t->date;
}
@@ -261,7 +264,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
static const unsigned char *nth_tip_table_ent(size_t ix, void *table_)
{
struct tip_table_entry *table = table_;
- return table[ix].sha1;
+ return table[ix].oid.hash;
}
static const char *get_exact_ref_match(const struct object *o)
@@ -283,10 +286,9 @@ static const char *get_exact_ref_match(const struct object *o)
return NULL;
}
-/* returns a static buffer */
-static const char *get_rev_name(const struct object *o)
+/* may return a constant string or use "buf" as scratch space */
+static const char *get_rev_name(const struct object *o, struct strbuf *buf)
{
- static char buffer[1024];
struct rev_name *n;
struct commit *c;
@@ -303,10 +305,9 @@ static const char *get_rev_name(const struct object *o)
int len = strlen(n->tip_name);
if (len > 2 && !strcmp(n->tip_name + len - 2, "^0"))
len -= 2;
- snprintf(buffer, sizeof(buffer), "%.*s~%d", len, n->tip_name,
- n->generation);
-
- return buffer;
+ strbuf_reset(buf);
+ strbuf_addf(buf, "%.*s~%d", len, n->tip_name, n->generation);
+ return buf->buf;
}
}
@@ -316,10 +317,11 @@ static void show_name(const struct object *obj,
{
const char *name;
const struct object_id *oid = &obj->oid;
+ struct strbuf buf = STRBUF_INIT;
if (!name_only)
printf("%s ", caller_name ? caller_name : oid_to_hex(oid));
- name = get_rev_name(obj);
+ name = get_rev_name(obj, &buf);
if (name)
printf("%s\n", name);
else if (allow_undefined)
@@ -328,6 +330,7 @@ static void show_name(const struct object *obj,
printf("%s\n", find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
else
die("cannot describe '%s'", oid_to_hex(oid));
+ strbuf_release(&buf);
}
static char const * const name_rev_usage[] = {
@@ -339,15 +342,16 @@ static char const * const name_rev_usage[] = {
static void name_rev_line(char *p, struct name_ref_data *data)
{
+ struct strbuf buf = STRBUF_INIT;
int forty = 0;
char *p_start;
for (p_start = p; *p; p++) {
#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))
if (!ishex(*p))
forty = 0;
- else if (++forty == 40 &&
+ else if (++forty == GIT_SHA1_HEXSZ &&
!ishex(*(p+1))) {
- unsigned char sha1[40];
+ struct object_id oid;
const char *name = NULL;
char c = *(p+1);
int p_len = p - p_start + 1;
@@ -355,11 +359,11 @@ static void name_rev_line(char *p, struct name_ref_data *data)
forty = 0;
*(p+1) = 0;
- if (!get_sha1(p - 39, sha1)) {
+ if (!get_oid(p - (GIT_SHA1_HEXSZ - 1), &oid)) {
struct object *o =
- lookup_object(sha1);
+ lookup_object(oid.hash);
if (o)
- name = get_rev_name(o);
+ name = get_rev_name(o, &buf);
}
*(p+1) = c;
@@ -367,7 +371,7 @@ static void name_rev_line(char *p, struct name_ref_data *data)
continue;
if (data->name_only)
- printf("%.*s%s", p_len - 40, p_start, name);
+ printf("%.*s%s", p_len - GIT_SHA1_HEXSZ, p_start, name);
else
printf("%.*s (%s)", p_len, p_start, name);
p_start = p + 1;
@@ -377,6 +381,8 @@ static void name_rev_line(char *p, struct name_ref_data *data)
/* flush */
if (p_start != p)
fwrite(p_start, p - p_start, 1, stdout);
+
+ strbuf_release(&buf);
}
int cmd_name_rev(int argc, const char **argv, const char *prefix)
@@ -416,18 +422,18 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
cutoff = 0;
for (; argc; argc--, argv++) {
- unsigned char sha1[20];
+ struct object_id oid;
struct object *object;
struct commit *commit;
- if (get_sha1(*argv, sha1)) {
+ if (get_oid(*argv, &oid)) {
fprintf(stderr, "Could not get sha1 for %s. Skipping.\n",
*argv);
continue;
}
commit = NULL;
- object = parse_object(sha1);
+ object = parse_object(&oid);
if (object) {
struct object *peeled = deref_tag(object, *argv, 0);
if (peeled && peeled->type == OBJ_COMMIT)
diff --git a/builtin/notes.c b/builtin/notes.c
index 0513f7455d..f2847c41e0 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -554,7 +554,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
struct notes_tree *t;
unsigned char object[20], new_note[20];
const unsigned char *note;
- char logmsg[100];
+ char *logmsg;
const char * const *usage;
struct note_data d = { 0, 0, NULL, STRBUF_INIT };
struct option options[] = {
@@ -618,17 +618,16 @@ static int append_edit(int argc, const char **argv, const char *prefix)
write_note_data(&d, new_note);
if (add_note(t, object, new_note, combine_notes_overwrite))
die("BUG: combine_notes_overwrite failed");
- snprintf(logmsg, sizeof(logmsg), "Notes added by 'git notes %s'",
- argv[0]);
+ logmsg = xstrfmt("Notes added by 'git notes %s'", argv[0]);
} else {
fprintf(stderr, _("Removing note for object %s\n"),
sha1_to_hex(object));
remove_note(t, object);
- snprintf(logmsg, sizeof(logmsg), "Notes removed by 'git notes %s'",
- argv[0]);
+ logmsg = xstrfmt("Notes removed by 'git notes %s'", argv[0]);
}
commit_notes(t, logmsg);
+ free(logmsg);
free_note_data(&d);
free_notes(t);
return 0;
@@ -707,7 +706,7 @@ static int merge_commit(struct notes_merge_options *o)
if (get_oid("NOTES_MERGE_PARTIAL", &oid))
die(_("failed to read ref NOTES_MERGE_PARTIAL"));
- else if (!(partial = lookup_commit_reference(oid.hash)))
+ else if (!(partial = lookup_commit_reference(&oid)))
die(_("could not find commit from NOTES_MERGE_PARTIAL."));
else if (parse_commit(partial))
die(_("could not parse commit from NOTES_MERGE_PARTIAL."));
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 16517f2637..80439047aa 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -44,7 +44,7 @@ static uint32_t nr_result, nr_written;
static int non_empty;
static int reuse_delta = 1, reuse_object = 1;
static int keep_unreachable, unpack_unreachable, include_tag;
-static unsigned long unpack_unreachable_expiration;
+static timestamp_t unpack_unreachable_expiration;
static int pack_loose_unreachable;
static int local;
static int have_non_local_packs;
@@ -106,12 +106,14 @@ static void *get_delta(struct object_entry *entry)
void *buf, *base_buf, *delta_buf;
enum object_type type;
- buf = read_sha1_file(entry->idx.sha1, &type, &size);
+ buf = read_sha1_file(entry->idx.oid.hash, &type, &size);
if (!buf)
- die("unable to read %s", sha1_to_hex(entry->idx.sha1));
- base_buf = read_sha1_file(entry->delta->idx.sha1, &type, &base_size);
+ die("unable to read %s", oid_to_hex(&entry->idx.oid));
+ base_buf = read_sha1_file(entry->delta->idx.oid.hash, &type,
+ &base_size);
if (!base_buf)
- die("unable to read %s", sha1_to_hex(entry->delta->idx.sha1));
+ die("unable to read %s",
+ oid_to_hex(&entry->delta->idx.oid));
delta_buf = diff_delta(base_buf, base_size,
buf, size, &delta_size, 0);
if (!delta_buf || delta_size != entry->delta_size)
@@ -239,7 +241,8 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
unsigned long limit, int usable_delta)
{
unsigned long size, datalen;
- unsigned char header[10], dheader[10];
+ unsigned char header[MAX_PACK_OBJECT_HEADER],
+ dheader[MAX_PACK_OBJECT_HEADER];
unsigned hdrlen;
enum object_type type;
void *buf;
@@ -248,12 +251,14 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
if (!usable_delta) {
if (entry->type == OBJ_BLOB &&
entry->size > big_file_threshold &&
- (st = open_istream(entry->idx.sha1, &type, &size, NULL)) != NULL)
+ (st = open_istream(entry->idx.oid.hash, &type, &size, NULL)) != NULL)
buf = NULL;
else {
- buf = read_sha1_file(entry->idx.sha1, &type, &size);
+ buf = read_sha1_file(entry->idx.oid.hash, &type,
+ &size);
if (!buf)
- die(_("unable to read %s"), sha1_to_hex(entry->idx.sha1));
+ die(_("unable to read %s"),
+ oid_to_hex(&entry->idx.oid));
}
/*
* make sure no cached delta data remains from a
@@ -286,7 +291,8 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
* The object header is a byte of 'type' followed by zero or
* more bytes of length.
*/
- hdrlen = encode_in_pack_object_header(type, size, header);
+ hdrlen = encode_in_pack_object_header(header, sizeof(header),
+ type, size);
if (type == OBJ_OFS_DELTA) {
/*
@@ -320,7 +326,7 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
return 0;
}
sha1write(f, header, hdrlen);
- sha1write(f, entry->delta->idx.sha1, 20);
+ sha1write(f, entry->delta->idx.oid.hash, 20);
hdrlen += 20;
} else {
if (limit && hdrlen + datalen + 20 >= limit) {
@@ -332,7 +338,7 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
sha1write(f, header, hdrlen);
}
if (st) {
- datalen = write_large_blob_data(st, f, entry->idx.sha1);
+ datalen = write_large_blob_data(st, f, entry->idx.oid.hash);
close_istream(st);
} else {
sha1write(f, buf, datalen);
@@ -352,20 +358,23 @@ static off_t write_reuse_object(struct sha1file *f, struct object_entry *entry,
off_t offset;
enum object_type type = entry->type;
off_t datalen;
- unsigned char header[10], dheader[10];
+ unsigned char header[MAX_PACK_OBJECT_HEADER],
+ dheader[MAX_PACK_OBJECT_HEADER];
unsigned hdrlen;
if (entry->delta)
type = (allow_ofs_delta && entry->delta->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
- hdrlen = encode_in_pack_object_header(type, entry->size, header);
+ hdrlen = encode_in_pack_object_header(header, sizeof(header),
+ type, entry->size);
offset = entry->in_pack_offset;
revidx = find_pack_revindex(p, offset);
datalen = revidx[1].offset - offset;
if (!pack_to_stdout && p->index_version > 1 &&
check_pack_crc(p, &w_curs, offset, datalen, revidx->nr)) {
- error("bad packed object CRC for %s", sha1_to_hex(entry->idx.sha1));
+ error("bad packed object CRC for %s",
+ oid_to_hex(&entry->idx.oid));
unuse_pack(&w_curs);
return write_no_reuse_object(f, entry, limit, usable_delta);
}
@@ -375,7 +384,8 @@ static off_t write_reuse_object(struct sha1file *f, struct object_entry *entry,
if (!pack_to_stdout && p->index_version == 1 &&
check_pack_inflate(p, &w_curs, offset, datalen, entry->size)) {
- error("corrupt packed object for %s", sha1_to_hex(entry->idx.sha1));
+ error("corrupt packed object for %s",
+ oid_to_hex(&entry->idx.oid));
unuse_pack(&w_curs);
return write_no_reuse_object(f, entry, limit, usable_delta);
}
@@ -400,7 +410,7 @@ static off_t write_reuse_object(struct sha1file *f, struct object_entry *entry,
return 0;
}
sha1write(f, header, hdrlen);
- sha1write(f, entry->delta->idx.sha1, 20);
+ sha1write(f, entry->delta->idx.oid.hash, 20);
hdrlen += 20;
reused_delta++;
} else {
@@ -505,7 +515,7 @@ static enum write_one_status write_one(struct sha1file *f,
recursing = (e->idx.offset == 1);
if (recursing) {
warning("recursive delta detected for object %s",
- sha1_to_hex(e->idx.sha1));
+ oid_to_hex(&e->idx.oid));
return WRITE_ONE_RECURSIVE;
} else if (e->idx.offset || e->preferred_base) {
/* offset is non zero if object is written already. */
@@ -1428,7 +1438,7 @@ static void check_object(struct object_entry *entry)
ofs += 1;
if (!ofs || MSB(ofs, 7)) {
error("delta base offset overflow in pack for %s",
- sha1_to_hex(entry->idx.sha1));
+ oid_to_hex(&entry->idx.oid));
goto give_up;
}
c = buf[used_0++];
@@ -1437,7 +1447,7 @@ static void check_object(struct object_entry *entry)
ofs = entry->in_pack_offset - ofs;
if (ofs <= 0 || ofs >= entry->in_pack_offset) {
error("delta base offset out of bound for %s",
- sha1_to_hex(entry->idx.sha1));
+ oid_to_hex(&entry->idx.oid));
goto give_up;
}
if (reuse_delta && !entry->preferred_base) {
@@ -1494,7 +1504,7 @@ static void check_object(struct object_entry *entry)
unuse_pack(&w_curs);
}
- entry->type = sha1_object_info(entry->idx.sha1, &entry->size);
+ entry->type = sha1_object_info(entry->idx.oid.hash, &entry->size);
/*
* The error condition is checked in prepare_pack(). This is
* to permit a missing preferred base object to be ignored
@@ -1510,7 +1520,7 @@ static int pack_offset_sort(const void *_a, const void *_b)
/* avoid filesystem trashing with loose objects */
if (!a->in_pack && !b->in_pack)
- return hashcmp(a->idx.sha1, b->idx.sha1);
+ return oidcmp(&a->idx.oid, &b->idx.oid);
if (a->in_pack < b->in_pack)
return -1;
@@ -1556,7 +1566,8 @@ static void drop_reused_delta(struct object_entry *entry)
* And if that fails, the error will be recorded in entry->type
* and dealt with in prepare_pack().
*/
- entry->type = sha1_object_info(entry->idx.sha1, &entry->size);
+ entry->type = sha1_object_info(entry->idx.oid.hash,
+ &entry->size);
}
}
@@ -1848,26 +1859,29 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
/* Load data if not already done */
if (!trg->data) {
read_lock();
- trg->data = read_sha1_file(trg_entry->idx.sha1, &type, &sz);
+ trg->data = read_sha1_file(trg_entry->idx.oid.hash, &type,
+ &sz);
read_unlock();
if (!trg->data)
die("object %s cannot be read",
- sha1_to_hex(trg_entry->idx.sha1));
+ oid_to_hex(&trg_entry->idx.oid));
if (sz != trg_size)
die("object %s inconsistent object length (%lu vs %lu)",
- sha1_to_hex(trg_entry->idx.sha1), sz, trg_size);
+ oid_to_hex(&trg_entry->idx.oid), sz,
+ trg_size);
*mem_usage += sz;
}
if (!src->data) {
read_lock();
- src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz);
+ src->data = read_sha1_file(src_entry->idx.oid.hash, &type,
+ &sz);
read_unlock();
if (!src->data) {
if (src_entry->preferred_base) {
static int warned = 0;
if (!warned++)
warning("object %s cannot be read",
- sha1_to_hex(src_entry->idx.sha1));
+ oid_to_hex(&src_entry->idx.oid));
/*
* Those objects are not included in the
* resulting pack. Be resilient and ignore
@@ -1877,11 +1891,12 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
return 0;
}
die("object %s cannot be read",
- sha1_to_hex(src_entry->idx.sha1));
+ oid_to_hex(&src_entry->idx.oid));
}
if (sz != src_size)
die("object %s inconsistent object length (%lu vs %lu)",
- sha1_to_hex(src_entry->idx.sha1), sz, src_size);
+ oid_to_hex(&src_entry->idx.oid), sz,
+ src_size);
*mem_usage += sz;
}
if (!src->index) {
@@ -2333,7 +2348,7 @@ static void add_tag_chain(const struct object_id *oid)
if (packlist_find(&to_pack, oid->hash, NULL))
return;
- tag = lookup_tag(oid->hash);
+ tag = lookup_tag(oid);
while (1) {
if (!tag || parse_tag(tag) || !tag->tagged)
die("unable to pack objects reachable from tag %s",
@@ -2402,7 +2417,7 @@ static void prepare_pack(int window, int depth)
nr_deltas++;
if (entry->type < 0)
die("unable to get type of object %s",
- sha1_to_hex(entry->idx.sha1));
+ oid_to_hex(&entry->idx.oid));
} else {
if (entry->type < 0) {
/*
@@ -2668,16 +2683,16 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
*
* This is filled by get_object_list.
*/
-static struct sha1_array recent_objects;
+static struct oid_array recent_objects;
-static int loosened_object_can_be_discarded(const unsigned char *sha1,
- unsigned long mtime)
+static int loosened_object_can_be_discarded(const struct object_id *oid,
+ timestamp_t mtime)
{
if (!unpack_unreachable_expiration)
return 0;
if (mtime > unpack_unreachable_expiration)
return 0;
- if (sha1_array_lookup(&recent_objects, sha1) >= 0)
+ if (oid_array_lookup(&recent_objects, oid) >= 0)
return 0;
return 1;
}
@@ -2686,7 +2701,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
{
struct packed_git *p;
uint32_t i;
- const unsigned char *sha1;
+ struct object_id oid;
for (p = packed_git; p; p = p->next) {
if (!p->pack_local || p->pack_keep)
@@ -2696,11 +2711,11 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
die("cannot open pack index");
for (i = 0; i < p->num_objects; i++) {
- sha1 = nth_packed_object_sha1(p, i);
- if (!packlist_find(&to_pack, sha1, NULL) &&
- !has_sha1_pack_kept_or_nonlocal(sha1) &&
- !loosened_object_can_be_discarded(sha1, p->mtime))
- if (force_object_loose(sha1, p->mtime))
+ nth_packed_object_oid(&oid, p, i);
+ if (!packlist_find(&to_pack, oid.hash, NULL) &&
+ !has_sha1_pack_kept_or_nonlocal(oid.hash) &&
+ !loosened_object_can_be_discarded(&oid, p->mtime))
+ if (force_object_loose(oid.hash, p->mtime))
die("unable to force loose object");
}
}
@@ -2713,7 +2728,11 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
*/
static int pack_options_allow_reuse(void)
{
- return pack_to_stdout && allow_ofs_delta;
+ return pack_to_stdout &&
+ allow_ofs_delta &&
+ !ignore_packed_keep &&
+ (!local || !have_non_local_packs) &&
+ !incremental;
}
static int get_object_list_from_bitmap(struct rev_info *revs)
@@ -2739,12 +2758,12 @@ static void record_recent_object(struct object *obj,
const char *name,
void *data)
{
- sha1_array_append(&recent_objects, obj->oid.hash);
+ oid_array_append(&recent_objects, &obj->oid);
}
static void record_recent_commit(struct commit *commit, void *data)
{
- sha1_array_append(&recent_objects, commit->object.oid.hash);
+ oid_array_append(&recent_objects, &commit->object.oid);
}
static void get_object_list(int ac, const char **av)
@@ -2773,10 +2792,10 @@ static void get_object_list(int ac, const char **av)
continue;
}
if (starts_with(line, "--shallow ")) {
- unsigned char sha1[20];
- if (get_sha1_hex(line + 10, sha1))
+ struct object_id oid;
+ if (get_oid_hex(line + 10, &oid))
die("not an SHA-1 '%s'", line + 10);
- register_shallow(sha1);
+ register_shallow(&oid);
use_bitmap_index = 0;
continue;
}
@@ -2812,7 +2831,7 @@ static void get_object_list(int ac, const char **av)
if (unpack_unreachable)
loosen_unused_packed_objects(&revs);
- sha1_array_clear(&recent_objects);
+ oid_array_clear(&recent_objects);
}
static int option_parse_index_version(const struct option *opt,
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 72c815844d..cb1df1c761 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -442,6 +442,7 @@ static void minimize(struct pack_list **min)
/* return if there are no objects missing from the unique set */
if (missing->size == 0) {
*min = unique;
+ free(missing);
return;
}
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index 39f9a55d16..b106a392a4 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -17,5 +17,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
};
if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
usage_with_options(pack_refs_usage, opts);
- return pack_refs(flags);
+ return refs_pack_refs(get_main_ref_store(), flags);
}
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index a84d0003a3..81552e02e4 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -55,7 +55,7 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after)
static void flush_one_hunk(struct object_id *result, git_SHA_CTX *ctx)
{
- unsigned char hash[GIT_SHA1_RAWSZ];
+ unsigned char hash[GIT_MAX_RAWSZ];
unsigned short carry = 0;
int i;
diff --git a/builtin/prune.c b/builtin/prune.c
index 42633e0c6e..f0e2bff04c 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -13,7 +13,7 @@ static const char * const prune_usage[] = {
};
static int show_only;
static int verbose;
-static unsigned long expire;
+static timestamp_t expire;
static int show_progress = -1;
static int prune_tmp_file(const char *fullpath)
@@ -111,7 +111,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
};
char *s;
- expire = ULONG_MAX;
+ expire = TIME_MAX;
save_commit_buffer = 0;
check_replace_refs = 0;
ref_paranoia = 1;
@@ -123,11 +123,12 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
die(_("cannot prune in a precious-objects repo"));
while (argc--) {
- unsigned char sha1[20];
+ struct object_id oid;
const char *name = *argv++;
- if (!get_sha1(name, sha1)) {
- struct object *object = parse_object_or_die(sha1, name);
+ if (!get_oid(name, &oid)) {
+ struct object *object = parse_object_or_die(&oid,
+ name);
add_pending_object(&revs, object, "");
}
else
diff --git a/builtin/pull.c b/builtin/pull.c
index 3ecb881b0b..318c273eb3 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -330,21 +330,21 @@ static int git_pull_config(const char *var, const char *value, void *cb)
* Appends merge candidates from FETCH_HEAD that are not marked not-for-merge
* into merge_heads.
*/
-static void get_merge_heads(struct sha1_array *merge_heads)
+static void get_merge_heads(struct oid_array *merge_heads)
{
- const char *filename = git_path("FETCH_HEAD");
+ const char *filename = git_path_fetch_head();
FILE *fp;
struct strbuf sb = STRBUF_INIT;
- unsigned char sha1[GIT_SHA1_RAWSZ];
+ struct object_id oid;
if (!(fp = fopen(filename, "r")))
die_errno(_("could not open '%s' for reading"), filename);
while (strbuf_getline_lf(&sb, fp) != EOF) {
- if (get_sha1_hex(sb.buf, sha1))
+ if (get_oid_hex(sb.buf, &oid))
continue; /* invalid line: does not start with SHA1 */
if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t"))
continue; /* ref is not-for-merge */
- sha1_array_append(merge_heads, sha1);
+ oid_array_append(merge_heads, &oid);
}
fclose(fp);
strbuf_release(&sb);
@@ -514,8 +514,8 @@ static int run_fetch(const char *repo, const char **refspecs)
/**
* "Pulls into void" by branching off merge_head.
*/
-static int pull_into_void(const unsigned char *merge_head,
- const unsigned char *curr_head)
+static int pull_into_void(const struct object_id *merge_head,
+ const struct object_id *curr_head)
{
/*
* Two-way merge: we treat the index as based on an empty tree,
@@ -523,10 +523,10 @@ static int pull_into_void(const unsigned char *merge_head,
* index/worktree changes that the user already made on the unborn
* branch.
*/
- if (checkout_fast_forward(EMPTY_TREE_SHA1_BIN, merge_head, 0))
+ if (checkout_fast_forward(&empty_tree_oid, merge_head, 0))
return 1;
- if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR))
+ if (update_ref("initial pull", "HEAD", merge_head->hash, curr_head->hash, 0, UPDATE_REFS_DIE_ON_ERR))
return 1;
return 0;
@@ -647,7 +647,7 @@ static const char *get_tracking_branch(const char *remote, const char *refspec)
* current branch forked from its remote tracking branch. Returns 0 on success,
* -1 on failure.
*/
-static int get_rebase_fork_point(unsigned char *fork_point, const char *repo,
+static int get_rebase_fork_point(struct object_id *fork_point, const char *repo,
const char *refspec)
{
int ret;
@@ -678,7 +678,7 @@ static int get_rebase_fork_point(unsigned char *fork_point, const char *repo,
if (ret)
goto cleanup;
- ret = get_sha1_hex(sb.buf, fork_point);
+ ret = get_oid_hex(sb.buf, fork_point);
if (ret)
goto cleanup;
@@ -691,16 +691,16 @@ cleanup:
* Sets merge_base to the octopus merge base of curr_head, merge_head and
* fork_point. Returns 0 if a merge base is found, 1 otherwise.
*/
-static int get_octopus_merge_base(unsigned char *merge_base,
- const unsigned char *curr_head,
- const unsigned char *merge_head,
- const unsigned char *fork_point)
+static int get_octopus_merge_base(struct object_id *merge_base,
+ const struct object_id *curr_head,
+ const struct object_id *merge_head,
+ const struct object_id *fork_point)
{
struct commit_list *revs = NULL, *result;
commit_list_insert(lookup_commit_reference(curr_head), &revs);
commit_list_insert(lookup_commit_reference(merge_head), &revs);
- if (!is_null_sha1(fork_point))
+ if (!is_null_oid(fork_point))
commit_list_insert(lookup_commit_reference(fork_point), &revs);
result = reduce_heads(get_octopus_merge_bases(revs));
@@ -708,7 +708,7 @@ static int get_octopus_merge_base(unsigned char *merge_base,
if (!result)
return 1;
- hashcpy(merge_base, result->item->object.oid.hash);
+ oidcpy(merge_base, &result->item->object.oid);
return 0;
}
@@ -717,16 +717,16 @@ static int get_octopus_merge_base(unsigned char *merge_base,
* fork point calculated by get_rebase_fork_point(), runs git-rebase with the
* appropriate arguments and returns its exit status.
*/
-static int run_rebase(const unsigned char *curr_head,
- const unsigned char *merge_head,
- const unsigned char *fork_point)
+static int run_rebase(const struct object_id *curr_head,
+ const struct object_id *merge_head,
+ const struct object_id *fork_point)
{
int ret;
- unsigned char oct_merge_base[GIT_SHA1_RAWSZ];
+ struct object_id oct_merge_base;
struct argv_array args = ARGV_ARRAY_INIT;
- if (!get_octopus_merge_base(oct_merge_base, curr_head, merge_head, fork_point))
- if (!is_null_sha1(fork_point) && !hashcmp(oct_merge_base, fork_point))
+ if (!get_octopus_merge_base(&oct_merge_base, curr_head, merge_head, fork_point))
+ if (!is_null_oid(fork_point) && !oidcmp(&oct_merge_base, fork_point))
fork_point = NULL;
argv_array_push(&args, "rebase");
@@ -754,12 +754,12 @@ static int run_rebase(const unsigned char *curr_head,
warning(_("ignoring --verify-signatures for rebase"));
argv_array_push(&args, "--onto");
- argv_array_push(&args, sha1_to_hex(merge_head));
+ argv_array_push(&args, oid_to_hex(merge_head));
- if (fork_point && !is_null_sha1(fork_point))
- argv_array_push(&args, sha1_to_hex(fork_point));
+ if (fork_point && !is_null_oid(fork_point))
+ argv_array_push(&args, oid_to_hex(fork_point));
else
- argv_array_push(&args, sha1_to_hex(merge_head));
+ argv_array_push(&args, oid_to_hex(merge_head));
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
argv_array_clear(&args);
@@ -769,9 +769,9 @@ static int run_rebase(const unsigned char *curr_head,
int cmd_pull(int argc, const char **argv, const char *prefix)
{
const char *repo, **refspecs;
- struct sha1_array merge_heads = SHA1_ARRAY_INIT;
- unsigned char orig_head[GIT_SHA1_RAWSZ], curr_head[GIT_SHA1_RAWSZ];
- unsigned char rebase_fork_point[GIT_SHA1_RAWSZ];
+ struct oid_array merge_heads = OID_ARRAY_INIT;
+ struct object_id orig_head, curr_head;
+ struct object_id rebase_fork_point;
if (!getenv("GIT_REFLOG_ACTION"))
set_reflog_message(argc, argv);
@@ -791,11 +791,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
if (read_cache_unmerged())
die_resolve_conflict("pull");
- if (file_exists(git_path("MERGE_HEAD")))
+ if (file_exists(git_path_merge_head()))
die_conclude_merge();
- if (get_sha1("HEAD", orig_head))
- hashclr(orig_head);
+ if (get_oid("HEAD", &orig_head))
+ oidclr(&orig_head);
if (!opt_rebase && opt_autostash != -1)
die(_("--[no-]autostash option is only valid with --rebase."));
@@ -805,15 +805,15 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
if (opt_autostash != -1)
autostash = opt_autostash;
- if (is_null_sha1(orig_head) && !is_cache_unborn())
+ if (is_null_oid(&orig_head) && !is_cache_unborn())
die(_("Updating an unborn branch with changes added to the index."));
if (!autostash)
require_clean_work_tree(N_("pull with rebase"),
_("please commit or stash them."), 1, 0);
- if (get_rebase_fork_point(rebase_fork_point, repo, *refspecs))
- hashclr(rebase_fork_point);
+ if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))
+ oidclr(&rebase_fork_point);
}
if (run_fetch(repo, refspecs))
@@ -822,11 +822,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
if (opt_dry_run)
return 0;
- if (get_sha1("HEAD", curr_head))
- hashclr(curr_head);
+ if (get_oid("HEAD", &curr_head))
+ oidclr(&curr_head);
- if (!is_null_sha1(orig_head) && !is_null_sha1(curr_head) &&
- hashcmp(orig_head, curr_head)) {
+ if (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) &&
+ oidcmp(&orig_head, &curr_head)) {
/*
* The fetch involved updating the current branch.
*
@@ -837,15 +837,15 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
warning(_("fetch updated the current branch head.\n"
"fast-forwarding your working tree from\n"
- "commit %s."), sha1_to_hex(orig_head));
+ "commit %s."), oid_to_hex(&orig_head));
- if (checkout_fast_forward(orig_head, curr_head, 0))
+ if (checkout_fast_forward(&orig_head, &curr_head, 0))
die(_("Cannot fast-forward your working tree.\n"
"After making sure that you saved anything precious from\n"
"$ git diff %s\n"
"output, run\n"
"$ git reset --hard\n"
- "to recover."), sha1_to_hex(orig_head));
+ "to recover."), oid_to_hex(&orig_head));
}
get_merge_heads(&merge_heads);
@@ -853,10 +853,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
if (!merge_heads.nr)
die_no_merge_candidates(repo, refspecs);
- if (is_null_sha1(orig_head)) {
+ if (is_null_oid(&orig_head)) {
if (merge_heads.nr > 1)
die(_("Cannot merge multiple branches into empty head."));
- return pull_into_void(*merge_heads.sha1, curr_head);
+ return pull_into_void(merge_heads.oid, &curr_head);
}
if (opt_rebase && merge_heads.nr > 1)
die(_("Cannot rebase onto multiple branches."));
@@ -865,15 +865,15 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
struct commit_list *list = NULL;
struct commit *merge_head, *head;
- head = lookup_commit_reference(orig_head);
+ head = lookup_commit_reference(&orig_head);
commit_list_insert(head, &list);
- merge_head = lookup_commit_reference(merge_heads.sha1[0]);
+ merge_head = lookup_commit_reference(&merge_heads.oid[0]);
if (is_descendant_of(merge_head, list)) {
/* we can fast-forward this without invoking rebase */
opt_ff = "--ff-only";
return run_merge();
}
- return run_rebase(curr_head, *merge_heads.sha1, rebase_fork_point);
+ return run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
} else {
return run_merge();
}
diff --git a/builtin/push.c b/builtin/push.c
index 5c22e9f2e5..a597759d8f 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -510,8 +510,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
int push_cert = -1;
int rc;
const char *repo = NULL; /* default repository */
- static struct string_list push_options = STRING_LIST_INIT_DUP;
- static struct string_list_item *item;
+ struct string_list push_options = STRING_LIST_INIT_DUP;
+ const struct string_list_item *item;
struct option options[] = {
OPT__VERBOSITY(&verbosity),
@@ -584,6 +584,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
die(_("push options must not have new line characters"));
rc = do_push(repo, flags, &push_options);
+ string_list_clear(&push_options, 0);
if (rc == -1)
usage_with_options(push_usage, options);
else
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 8ba64bc785..78d3193659 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -15,18 +15,21 @@
#include "builtin.h"
#include "parse-options.h"
#include "resolve-undo.h"
+#include "submodule.h"
+#include "submodule-config.h"
static int nr_trees;
static int read_empty;
static struct tree *trees[MAX_UNPACK_TREES];
+static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int list_tree(unsigned char *sha1)
+static int list_tree(struct object_id *oid)
{
struct tree *tree;
if (nr_trees >= MAX_UNPACK_TREES)
die("I cannot read more than %d trees", MAX_UNPACK_TREES);
- tree = parse_tree_indirect(sha1);
+ tree = parse_tree_indirect(oid);
if (!tree)
return -1;
trees[nr_trees++] = tree;
@@ -96,12 +99,29 @@ static int debug_merge(const struct cache_entry * const *stages,
return 0;
}
+static int option_parse_recurse_submodules(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset) {
+ recurse_submodules = RECURSE_SUBMODULES_OFF;
+ return 0;
+ }
+ if (arg)
+ recurse_submodules =
+ parse_update_recurse_submodules_arg(opt->long_name,
+ arg);
+ else
+ recurse_submodules = RECURSE_SUBMODULES_ON;
+
+ return 0;
+}
+
static struct lock_file lock_file;
int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
{
int i, stage = 0;
- unsigned char sha1[20];
+ struct object_id oid;
struct tree_desc t[MAX_UNPACK_TREES];
struct unpack_trees_options opts;
int prefix_set = 0;
@@ -137,6 +157,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
N_("skip applying sparse checkout filter")),
OPT_BOOL(0, "debug-unpack", &opts.debug_unpack,
N_("debug unpack-trees")),
+ { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules,
+ "checkout", "control recursive updating of submodules",
+ PARSE_OPT_OPTARG, option_parse_recurse_submodules },
OPT_END()
};
@@ -152,6 +175,12 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
+ if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT) {
+ gitmodules_config();
+ git_config(submodule_config, NULL);
+ set_config_update_recurse_submodules(RECURSE_SUBMODULES_ON);
+ }
+
prefix_set = opts.prefix ? 1 : 0;
if (1 < opts.merge + opts.reset + prefix_set)
die("Which one? -m, --reset, or --prefix?");
@@ -175,13 +204,13 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
- if (get_sha1(arg, sha1))
+ if (get_oid(arg, &oid))
die("Not a valid object name %s", arg);
- if (list_tree(sha1) < 0)
+ if (list_tree(&oid) < 0)
die("failed to unpack tree object %s", arg);
stage++;
}
- if (nr_trees == 0 && !read_empty)
+ if (!nr_trees && !read_empty && !opts.merge)
warning("read-tree: emptying the index with no arguments is deprecated; use --empty");
else if (nr_trees > 0 && read_empty)
die("passing trees as arguments contradicts --empty");
@@ -197,9 +226,10 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
setup_work_tree();
if (opts.merge) {
- if (stage < 2)
- die("just how do you expect me to merge %d trees?", stage-1);
switch (stage - 1) {
+ case 0:
+ die("you must specify at least one tree to merge");
+ break;
case 1:
opts.fn = opts.prefix ? bind_merge : oneway_merge;
break;
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index fb2a090a0c..b1706a5731 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -78,7 +78,7 @@ static const char *NONCE_OK = "OK";
static const char *NONCE_SLOP = "SLOP";
static const char *nonce_status;
static long nonce_stamp_slop;
-static unsigned long nonce_stamp_slop_limit;
+static timestamp_t nonce_stamp_slop_limit;
static struct ref_transaction *transaction;
static enum {
@@ -225,10 +225,10 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
-static void show_ref(const char *path, const unsigned char *sha1)
+static void show_ref(const char *path, const struct object_id *oid)
{
if (sent_capabilities) {
- packet_write_fmt(1, "%s %s\n", sha1_to_hex(sha1), path);
+ packet_write_fmt(1, "%s %s\n", oid_to_hex(oid), path);
} else {
struct strbuf cap = STRBUF_INIT;
@@ -244,7 +244,7 @@ static void show_ref(const char *path, const unsigned char *sha1)
strbuf_addstr(&cap, " push-options");
strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
packet_write_fmt(1, "%s %s%c%s\n",
- sha1_to_hex(sha1), path, 0, cap.buf);
+ oid_to_hex(oid), path, 0, cap.buf);
strbuf_release(&cap);
sent_capabilities = 1;
}
@@ -271,7 +271,7 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid,
} else {
oidset_insert(seen, oid);
}
- show_ref(path, oid->hash);
+ show_ref(path, oid);
return 0;
}
@@ -284,7 +284,7 @@ static void show_one_alternate_ref(const char *refname,
if (oidset_insert(seen, oid))
return;
- show_ref(".have", oid->hash);
+ show_ref(".have", oid);
}
static void write_head_info(void)
@@ -295,7 +295,7 @@ static void write_head_info(void)
for_each_alternate_ref(show_one_alternate_ref, &seen);
oidset_clear(&seen);
if (!sent_capabilities)
- show_ref("capabilities^{}", null_sha1);
+ show_ref("capabilities^{}", &null_oid);
advertise_shallow_grafts(1);
@@ -309,8 +309,8 @@ struct command {
unsigned int skip_update:1,
did_not_exist:1;
int index;
- unsigned char old_sha1[20];
- unsigned char new_sha1[20];
+ struct object_id old_oid;
+ struct object_id new_oid;
char ref_name[FLEX_ARRAY]; /* more */
};
@@ -454,17 +454,17 @@ static void hmac_sha1(unsigned char *out,
git_SHA1_Final(out, &ctx);
}
-static char *prepare_push_cert_nonce(const char *path, unsigned long stamp)
+static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
{
struct strbuf buf = STRBUF_INIT;
unsigned char sha1[20];
- strbuf_addf(&buf, "%s:%lu", path, stamp);
+ strbuf_addf(&buf, "%s:%"PRItime, path, stamp);
hmac_sha1(sha1, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));;
strbuf_release(&buf);
/* RFC 2104 5. HMAC-SHA1-80 */
- strbuf_addf(&buf, "%lu-%.*s", stamp, 20, sha1_to_hex(sha1));
+ strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, 20, sha1_to_hex(sha1));
return strbuf_detach(&buf, NULL);
}
@@ -473,7 +473,8 @@ static char *prepare_push_cert_nonce(const char *path, unsigned long stamp)
* after dropping "_commit" from its name and possibly moving it out
* of commit.c
*/
-static char *find_header(const char *msg, size_t len, const char *key)
+static char *find_header(const char *msg, size_t len, const char *key,
+ const char **next_line)
{
int key_len = strlen(key);
const char *line = msg;
@@ -486,6 +487,8 @@ static char *find_header(const char *msg, size_t len, const char *key)
if (line + key_len < eol &&
!memcmp(line, key, key_len) && line[key_len] == ' ') {
int offset = key_len + 1;
+ if (next_line)
+ *next_line = *eol ? eol + 1 : eol;
return xmemdupz(line + offset, (eol - line) - offset);
}
line = *eol ? eol + 1 : NULL;
@@ -495,8 +498,8 @@ static char *find_header(const char *msg, size_t len, const char *key)
static const char *check_nonce(const char *buf, size_t len)
{
- char *nonce = find_header(buf, len, "nonce");
- unsigned long stamp, ostamp;
+ char *nonce = find_header(buf, len, "nonce", NULL);
+ timestamp_t stamp, ostamp;
char *bohmac, *expect = NULL;
const char *retval = NONCE_BAD;
@@ -534,7 +537,7 @@ static const char *check_nonce(const char *buf, size_t len)
retval = NONCE_BAD;
goto leave;
}
- stamp = strtoul(nonce, &bohmac, 10);
+ stamp = parse_timestamp(nonce, &bohmac, 10);
if (bohmac == nonce || bohmac[0] != '-') {
retval = NONCE_BAD;
goto leave;
@@ -552,7 +555,7 @@ static const char *check_nonce(const char *buf, size_t len)
* would mean it was issued by another server with its clock
* skewed in the future.
*/
- ostamp = strtoul(push_cert_nonce, NULL, 10);
+ ostamp = parse_timestamp(push_cert_nonce, NULL, 10);
nonce_stamp_slop = (long)ostamp - (long)stamp;
if (nonce_stamp_slop_limit &&
@@ -575,6 +578,45 @@ leave:
return retval;
}
+/*
+ * Return 1 if there is no push_cert or if the push options in push_cert are
+ * the same as those in the argument; 0 otherwise.
+ */
+static int check_cert_push_options(const struct string_list *push_options)
+{
+ const char *buf = push_cert.buf;
+ int len = push_cert.len;
+
+ char *option;
+ const char *next_line;
+ int options_seen = 0;
+
+ int retval = 1;
+
+ if (!len)
+ return 1;
+
+ while ((option = find_header(buf, len, "push-option", &next_line))) {
+ len -= (next_line - buf);
+ buf = next_line;
+ options_seen++;
+ if (options_seen > push_options->nr
+ || strcmp(option,
+ push_options->items[options_seen - 1].string)) {
+ retval = 0;
+ goto leave;
+ }
+ free(option);
+ }
+
+ if (options_seen != push_options->nr)
+ retval = 0;
+
+leave:
+ free(option);
+ return retval;
+}
+
static void prepare_push_cert_sha1(struct child_process *proc)
{
static int already_done;
@@ -723,7 +765,7 @@ static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
return -1; /* EOF */
strbuf_reset(&state->buf);
strbuf_addf(&state->buf, "%s %s %s\n",
- sha1_to_hex(cmd->old_sha1), sha1_to_hex(cmd->new_sha1),
+ oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
cmd->ref_name);
state->cmd = cmd->next;
if (bufp) {
@@ -764,15 +806,14 @@ static int run_update_hook(struct command *cmd)
return 0;
argv[1] = cmd->ref_name;
- argv[2] = sha1_to_hex(cmd->old_sha1);
- argv[3] = sha1_to_hex(cmd->new_sha1);
+ argv[2] = oid_to_hex(&cmd->old_oid);
+ argv[3] = oid_to_hex(&cmd->new_oid);
argv[4] = NULL;
proc.no_stdin = 1;
proc.stdout_to_stderr = 1;
proc.err = use_sideband ? -1 : 0;
proc.argv = argv;
- proc.env = tmp_objdir_env(tmp_objdir);
code = start_command(&proc);
if (code)
@@ -831,7 +872,7 @@ static int command_singleton_iterator(void *cb_data, unsigned char sha1[20]);
static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
{
static struct lock_file shallow_lock;
- struct sha1_array extra = SHA1_ARRAY_INIT;
+ struct oid_array extra = OID_ARRAY_INIT;
struct check_connected_options opt = CHECK_CONNECTED_INIT;
uint32_t mask = 1 << (cmd->index % 32);
int i;
@@ -842,13 +883,13 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
if (si->used_shallow[i] &&
(si->used_shallow[i][cmd->index / 32] & mask) &&
!delayed_reachability_test(si, i))
- sha1_array_append(&extra, si->shallow->sha1[i]);
+ oid_array_append(&extra, &si->shallow->oid[i]);
opt.env = tmp_objdir_env(tmp_objdir);
setup_alternate_shallow(&shallow_lock, &opt.shallow_file, &extra);
if (check_connected(command_singleton_iterator, cmd, &opt)) {
rollback_lock_file(&shallow_lock);
- sha1_array_clear(&extra);
+ oid_array_clear(&extra);
return -1;
}
@@ -859,10 +900,10 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
* not lose these new roots..
*/
for (i = 0; i < extra.nr; i++)
- register_shallow(extra.sha1[i]);
+ register_shallow(&extra.oid[i]);
si->shallow_ref[cmd->index] = 0;
- sha1_array_clear(&extra);
+ oid_array_clear(&extra);
return 0;
}
@@ -987,9 +1028,10 @@ static const char *update(struct command *cmd, struct shallow_info *si)
{
const char *name = cmd->ref_name;
struct strbuf namespaced_name_buf = STRBUF_INIT;
- const char *namespaced_name, *ret;
- unsigned char *old_sha1 = cmd->old_sha1;
- unsigned char *new_sha1 = cmd->new_sha1;
+ static char *namespaced_name;
+ const char *ret;
+ struct object_id *old_oid = &cmd->old_oid;
+ struct object_id *new_oid = &cmd->new_oid;
/* only refs/... are allowed */
if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
@@ -998,6 +1040,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
}
strbuf_addf(&namespaced_name_buf, "%s%s", get_git_namespace(), name);
+ free(namespaced_name);
namespaced_name = strbuf_detach(&namespaced_name_buf, NULL);
if (is_ref_checked_out(namespaced_name)) {
@@ -1014,20 +1057,20 @@ static const char *update(struct command *cmd, struct shallow_info *si)
refuse_unconfigured_deny();
return "branch is currently checked out";
case DENY_UPDATE_INSTEAD:
- ret = update_worktree(new_sha1);
+ ret = update_worktree(new_oid->hash);
if (ret)
return ret;
break;
}
}
- if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
+ if (!is_null_oid(new_oid) && !has_object_file(new_oid)) {
error("unpack should have generated %s, "
- "but I can't find it!", sha1_to_hex(new_sha1));
+ "but I can't find it!", oid_to_hex(new_oid));
return "bad pack";
}
- if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
+ if (!is_null_oid(old_oid) && is_null_oid(new_oid)) {
if (deny_deletes && starts_with(name, "refs/heads/")) {
rp_error("denying ref deletion for %s", name);
return "deletion prohibited";
@@ -1053,14 +1096,14 @@ static const char *update(struct command *cmd, struct shallow_info *si)
}
}
- if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
- !is_null_sha1(old_sha1) &&
+ if (deny_non_fast_forwards && !is_null_oid(new_oid) &&
+ !is_null_oid(old_oid) &&
starts_with(name, "refs/heads/")) {
struct object *old_object, *new_object;
struct commit *old_commit, *new_commit;
- old_object = parse_object(old_sha1);
- new_object = parse_object(new_sha1);
+ old_object = parse_object(old_oid);
+ new_object = parse_object(new_oid);
if (!old_object || !new_object ||
old_object->type != OBJ_COMMIT ||
@@ -1081,10 +1124,10 @@ static const char *update(struct command *cmd, struct shallow_info *si)
return "hook declined";
}
- if (is_null_sha1(new_sha1)) {
+ if (is_null_oid(new_oid)) {
struct strbuf err = STRBUF_INIT;
- if (!parse_object(old_sha1)) {
- old_sha1 = NULL;
+ if (!parse_object(old_oid)) {
+ old_oid = NULL;
if (ref_exists(name)) {
rp_warning("Allowing deletion of corrupt ref.");
} else {
@@ -1094,7 +1137,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
}
if (ref_transaction_delete(transaction,
namespaced_name,
- old_sha1,
+ old_oid->hash,
0, "push", &err)) {
rp_error("%s", err.buf);
strbuf_release(&err);
@@ -1111,7 +1154,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
if (ref_transaction_update(transaction,
namespaced_name,
- new_sha1, old_sha1,
+ new_oid->hash, old_oid->hash,
0, "push",
&err)) {
rp_error("%s", err.buf);
@@ -1162,7 +1205,7 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
const char *dst_name;
struct string_list_item *item;
struct command *dst_cmd;
- unsigned char sha1[GIT_SHA1_RAWSZ];
+ unsigned char sha1[GIT_MAX_RAWSZ];
int flag;
strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name);
@@ -1187,8 +1230,8 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
dst_cmd = (struct command *) item->util;
- if (!hashcmp(cmd->old_sha1, dst_cmd->old_sha1) &&
- !hashcmp(cmd->new_sha1, dst_cmd->new_sha1))
+ if (!oidcmp(&cmd->old_oid, &dst_cmd->old_oid) &&
+ !oidcmp(&cmd->new_oid, &dst_cmd->new_oid))
return;
dst_cmd->skip_update = 1;
@@ -1196,11 +1239,11 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
rp_error("refusing inconsistent update between symref '%s' (%s..%s) and"
" its target '%s' (%s..%s)",
cmd->ref_name,
- find_unique_abbrev(cmd->old_sha1, DEFAULT_ABBREV),
- find_unique_abbrev(cmd->new_sha1, DEFAULT_ABBREV),
+ find_unique_abbrev(cmd->old_oid.hash, DEFAULT_ABBREV),
+ find_unique_abbrev(cmd->new_oid.hash, DEFAULT_ABBREV),
dst_cmd->ref_name,
- find_unique_abbrev(dst_cmd->old_sha1, DEFAULT_ABBREV),
- find_unique_abbrev(dst_cmd->new_sha1, DEFAULT_ABBREV));
+ find_unique_abbrev(dst_cmd->old_oid.hash, DEFAULT_ABBREV),
+ find_unique_abbrev(dst_cmd->new_oid.hash, DEFAULT_ABBREV));
cmd->error_string = dst_cmd->error_string =
"inconsistent aliased update";
@@ -1231,10 +1274,10 @@ static int command_singleton_iterator(void *cb_data, unsigned char sha1[20])
struct command **cmd_list = cb_data;
struct command *cmd = *cmd_list;
- if (!cmd || is_null_sha1(cmd->new_sha1))
+ if (!cmd || is_null_oid(&cmd->new_oid))
return -1; /* end of list */
*cmd_list = NULL; /* this returns only one */
- hashcpy(sha1, cmd->new_sha1);
+ hashcpy(sha1, cmd->new_oid.hash);
return 0;
}
@@ -1275,8 +1318,8 @@ static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
if (shallow_update && data->si->shallow_ref[cmd->index])
/* to be checked in update_shallow_ref() */
continue;
- if (!is_null_sha1(cmd->new_sha1) && !cmd->skip_update) {
- hashcpy(sha1, cmd->new_sha1);
+ if (!is_null_oid(&cmd->new_oid) && !cmd->skip_update) {
+ hashcpy(sha1, cmd->new_oid.hash);
*cmd_list = cmd->next;
return 0;
}
@@ -1303,7 +1346,7 @@ static void reject_updates_to_hidden(struct command *commands)
if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
continue;
- if (is_null_sha1(cmd->new_sha1))
+ if (is_null_oid(&cmd->new_oid))
cmd->error_string = "deny deleting a hidden ref";
else
cmd->error_string = "deny updating a hidden ref";
@@ -1486,23 +1529,23 @@ static struct command **queue_command(struct command **tail,
const char *line,
int linelen)
{
- unsigned char old_sha1[20], new_sha1[20];
+ struct object_id old_oid, new_oid;
struct command *cmd;
const char *refname;
int reflen;
+ const char *p;
- if (linelen < 83 ||
- line[40] != ' ' ||
- line[81] != ' ' ||
- get_sha1_hex(line, old_sha1) ||
- get_sha1_hex(line + 41, new_sha1))
+ if (parse_oid_hex(line, &old_oid, &p) ||
+ *p++ != ' ' ||
+ parse_oid_hex(p, &new_oid, &p) ||
+ *p++ != ' ')
die("protocol error: expected old/new/ref, got '%s'", line);
- refname = line + 82;
- reflen = linelen - 82;
+ refname = p;
+ reflen = linelen - (p - line);
FLEX_ALLOC_MEM(cmd, ref_name, refname, reflen);
- hashcpy(cmd->old_sha1, old_sha1);
- hashcpy(cmd->new_sha1, new_sha1);
+ oidcpy(&cmd->old_oid, &old_oid);
+ oidcpy(&cmd->new_oid, &new_oid);
*tail = cmd;
return &cmd->next;
}
@@ -1524,12 +1567,12 @@ static void queue_commands_from_cert(struct command **tail,
while (boc < eoc) {
const char *eol = memchr(boc, '\n', eoc - boc);
- tail = queue_command(tail, boc, eol ? eol - boc : eoc - eol);
+ tail = queue_command(tail, boc, eol ? eol - boc : eoc - boc);
boc = eol ? eol + 1 : eoc;
}
}
-static struct command *read_head_info(struct sha1_array *shallow)
+static struct command *read_head_info(struct oid_array *shallow)
{
struct command *commands = NULL;
struct command **p = &commands;
@@ -1541,12 +1584,12 @@ static struct command *read_head_info(struct sha1_array *shallow)
if (!line)
break;
- if (len == 48 && starts_with(line, "shallow ")) {
- unsigned char sha1[20];
- if (get_sha1_hex(line + 8, sha1))
+ if (len > 8 && starts_with(line, "shallow ")) {
+ struct object_id oid;
+ if (get_oid_hex(line + 8, &oid))
die("protocol error: expected shallow sha, got '%s'",
line + 8);
- sha1_array_append(shallow, sha1);
+ oid_array_append(shallow, &oid);
continue;
}
@@ -1634,12 +1677,17 @@ static const char *parse_pack_header(struct pack_header *hdr)
static const char *pack_lockfile;
+static void push_header_arg(struct argv_array *args, struct pack_header *hdr)
+{
+ argv_array_pushf(args, "--pack_header=%"PRIu32",%"PRIu32,
+ ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries));
+}
+
static const char *unpack(int err_fd, struct shallow_info *si)
{
struct pack_header hdr;
const char *hdr_err;
int status;
- char hdr_arg[38];
struct child_process child = CHILD_PROCESS_INIT;
int fsck_objects = (receive_fsck_objects >= 0
? receive_fsck_objects
@@ -1653,9 +1701,6 @@ static const char *unpack(int err_fd, struct shallow_info *si)
close(err_fd);
return hdr_err;
}
- snprintf(hdr_arg, sizeof(hdr_arg),
- "--pack_header=%"PRIu32",%"PRIu32,
- ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
if (si->nr_ours || si->nr_theirs) {
alt_shallow_file = setup_temporary_shallow(si->shallow);
@@ -1679,7 +1724,8 @@ static const char *unpack(int err_fd, struct shallow_info *si)
tmp_objdir_add_as_alternate(tmp_objdir);
if (ntohl(hdr.hdr_entries) < unpack_limit) {
- argv_array_pushl(&child.args, "unpack-objects", hdr_arg, NULL);
+ argv_array_push(&child.args, "unpack-objects");
+ push_header_arg(&child.args, &hdr);
if (quiet)
argv_array_push(&child.args, "-q");
if (fsck_objects)
@@ -1695,12 +1741,12 @@ static const char *unpack(int err_fd, struct shallow_info *si)
if (status)
return "unpack-objects abnormal exit";
} else {
- char hostname[256];
+ char hostname[HOST_NAME_MAX + 1];
- argv_array_pushl(&child.args, "index-pack",
- "--stdin", hdr_arg, NULL);
+ argv_array_pushl(&child.args, "index-pack", "--stdin", NULL);
+ push_header_arg(&child.args, &hdr);
- if (gethostname(hostname, sizeof(hostname)))
+ if (xgethostname(hostname, sizeof(hostname)))
xsnprintf(hostname, sizeof(hostname), "localhost");
argv_array_pushf(&child.args,
"--keep=receive-pack %"PRIuMAX" on %s",
@@ -1804,7 +1850,7 @@ static void prepare_shallow_update(struct command *commands,
static void update_shallow_info(struct command *commands,
struct shallow_info *si,
- struct sha1_array *ref)
+ struct oid_array *ref)
{
struct command *cmd;
int *ref_status;
@@ -1815,9 +1861,9 @@ static void update_shallow_info(struct command *commands,
}
for (cmd = commands; cmd; cmd = cmd->next) {
- if (is_null_sha1(cmd->new_sha1))
+ if (is_null_oid(&cmd->new_oid))
continue;
- sha1_array_append(ref, cmd->new_sha1);
+ oid_array_append(ref, &cmd->new_oid);
cmd->index = ref->nr - 1;
}
si->ref = ref;
@@ -1830,7 +1876,7 @@ static void update_shallow_info(struct command *commands,
ALLOC_ARRAY(ref_status, ref->nr);
assign_shallow_commits_to_refs(si, NULL, ref_status);
for (cmd = commands; cmd; cmd = cmd->next) {
- if (is_null_sha1(cmd->new_sha1))
+ if (is_null_oid(&cmd->new_oid))
continue;
if (ref_status[cmd->index]) {
cmd->error_string = "shallow update not allowed";
@@ -1868,7 +1914,7 @@ static int delete_only(struct command *commands)
{
struct command *cmd;
for (cmd = commands; cmd; cmd = cmd->next) {
- if (!is_null_sha1(cmd->new_sha1))
+ if (!is_null_oid(&cmd->new_oid))
return 0;
}
return 1;
@@ -1878,8 +1924,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
{
int advertise_refs = 0;
struct command *commands;
- struct sha1_array shallow = SHA1_ARRAY_INIT;
- struct sha1_array ref = SHA1_ARRAY_INIT;
+ struct oid_array shallow = OID_ARRAY_INIT;
+ struct oid_array ref = OID_ARRAY_INIT;
struct shallow_info si;
struct option options[] = {
@@ -1927,6 +1973,11 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
if (use_push_options)
read_push_options(&push_options);
+ if (!check_cert_push_options(&push_options)) {
+ struct command *cmd;
+ for (cmd = commands; cmd; cmd = cmd->next)
+ cmd->error_string = "inconsistent push options";
+ }
prepare_shallow_info(&si, &shallow);
if (!si.nr_ours && !si.nr_theirs)
@@ -1971,8 +2022,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
}
if (use_sideband)
packet_flush(1);
- sha1_array_clear(&shallow);
- sha1_array_clear(&ref);
+ oid_array_clear(&shallow);
+ oid_array_clear(&ref);
free((void *)push_cert_nonce);
return 0;
}
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 7472775778..920c16dac0 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -16,14 +16,14 @@ static const char reflog_delete_usage[] =
static const char reflog_exists_usage[] =
"git reflog exists <ref>";
-static unsigned long default_reflog_expire;
-static unsigned long default_reflog_expire_unreachable;
+static timestamp_t default_reflog_expire;
+static timestamp_t default_reflog_expire_unreachable;
struct cmd_reflog_expire_cb {
struct rev_info revs;
int stalefix;
- unsigned long expire_total;
- unsigned long expire_unreachable;
+ timestamp_t expire_total;
+ timestamp_t expire_unreachable;
int recno;
};
@@ -55,14 +55,14 @@ struct collect_reflog_cb {
#define STUDYING (1u<<11)
#define REACHABLE (1u<<12)
-static int tree_is_complete(const unsigned char *sha1)
+static int tree_is_complete(const struct object_id *oid)
{
struct tree_desc desc;
struct name_entry entry;
int complete;
struct tree *tree;
- tree = lookup_tree(sha1);
+ tree = lookup_tree(oid);
if (!tree)
return 0;
if (tree->object.flags & SEEN)
@@ -73,7 +73,7 @@ static int tree_is_complete(const unsigned char *sha1)
if (!tree->buffer) {
enum object_type type;
unsigned long size;
- void *data = read_sha1_file(sha1, &type, &size);
+ void *data = read_sha1_file(oid->hash, &type, &size);
if (!data) {
tree->object.flags |= INCOMPLETE;
return 0;
@@ -85,7 +85,7 @@ static int tree_is_complete(const unsigned char *sha1)
complete = 1;
while (tree_entry(&desc, &entry)) {
if (!has_sha1_file(entry.oid->hash) ||
- (S_ISDIR(entry.mode) && !tree_is_complete(entry.oid->hash))) {
+ (S_ISDIR(entry.mode) && !tree_is_complete(entry.oid))) {
tree->object.flags |= INCOMPLETE;
complete = 0;
}
@@ -126,7 +126,7 @@ static int commit_is_complete(struct commit *commit)
struct commit_list *parent;
c = (struct commit *)study.objects[--study.nr].item;
- if (!c->object.parsed && !parse_object(c->object.oid.hash))
+ if (!c->object.parsed && !parse_object(&c->object.oid))
c->object.flags |= INCOMPLETE;
if (c->object.flags & INCOMPLETE) {
@@ -152,7 +152,7 @@ static int commit_is_complete(struct commit *commit)
for (i = 0; i < found.nr; i++) {
struct commit *c =
(struct commit *)found.objects[i].item;
- if (!tree_is_complete(c->tree->object.oid.hash)) {
+ if (!tree_is_complete(&c->tree->object.oid)) {
is_incomplete = 1;
c->object.flags |= INCOMPLETE;
}
@@ -186,13 +186,13 @@ static int commit_is_complete(struct commit *commit)
return !is_incomplete;
}
-static int keep_entry(struct commit **it, unsigned char *sha1)
+static int keep_entry(struct commit **it, struct object_id *oid)
{
struct commit *commit;
- if (is_null_sha1(sha1))
+ if (is_null_oid(oid))
return 1;
- commit = lookup_commit_reference_gently(sha1, 1);
+ commit = lookup_commit_reference_gently(oid, 1);
if (!commit)
return 0;
@@ -219,7 +219,7 @@ static int keep_entry(struct commit **it, unsigned char *sha1)
static void mark_reachable(struct expire_reflog_policy_cb *cb)
{
struct commit_list *pending;
- unsigned long expire_limit = cb->mark_limit;
+ timestamp_t expire_limit = cb->mark_limit;
struct commit_list *leftover = NULL;
for (pending = cb->mark_list; pending; pending = pending->next)
@@ -251,17 +251,17 @@ static void mark_reachable(struct expire_reflog_policy_cb *cb)
cb->mark_list = leftover;
}
-static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, unsigned char *sha1)
+static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, struct object_id *oid)
{
/*
* We may or may not have the commit yet - if not, look it
* up using the supplied sha1.
*/
if (!commit) {
- if (is_null_sha1(sha1))
+ if (is_null_oid(oid))
return 0;
- commit = lookup_commit_reference_gently(sha1, 1);
+ commit = lookup_commit_reference_gently(oid, 1);
/* Not a commit -- keep it */
if (!commit)
@@ -283,8 +283,8 @@ static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit
/*
* Return true iff the specified reflog entry should be expired.
*/
-static int should_expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
- const char *email, unsigned long timestamp, int tz,
+static int should_expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
+ const char *email, timestamp_t timestamp, int tz,
const char *message, void *cb_data)
{
struct expire_reflog_policy_cb *cb = cb_data;
@@ -295,13 +295,13 @@ static int should_expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
old = new = NULL;
if (cb->cmd.stalefix &&
- (!keep_entry(&old, osha1) || !keep_entry(&new, nsha1)))
+ (!keep_entry(&old, ooid) || !keep_entry(&new, noid)))
return 1;
if (timestamp < cb->cmd.expire_unreachable) {
if (cb->unreachable_expire_kind == UE_ALWAYS)
return 1;
- if (unreachable(cb, old, osha1) || unreachable(cb, new, nsha1))
+ if (unreachable(cb, old, ooid) || unreachable(cb, new, noid))
return 1;
}
@@ -318,7 +318,7 @@ static int push_tip_to_list(const char *refname, const struct object_id *oid,
struct commit *tip_commit;
if (flags & REF_ISSYMREF)
return 0;
- tip_commit = lookup_commit_reference_gently(oid->hash, 1);
+ tip_commit = lookup_commit_reference_gently(oid, 1);
if (!tip_commit)
return 0;
commit_list_insert(tip_commit, list);
@@ -326,7 +326,7 @@ static int push_tip_to_list(const char *refname, const struct object_id *oid,
}
static void reflog_expiry_prepare(const char *refname,
- const unsigned char *sha1,
+ const struct object_id *oid,
void *cb_data)
{
struct expire_reflog_policy_cb *cb = cb_data;
@@ -335,7 +335,7 @@ static void reflog_expiry_prepare(const char *refname,
cb->tip_commit = NULL;
cb->unreachable_expire_kind = UE_HEAD;
} else {
- cb->tip_commit = lookup_commit_reference_gently(sha1, 1);
+ cb->tip_commit = lookup_commit_reference_gently(oid, 1);
if (!cb->tip_commit)
cb->unreachable_expire_kind = UE_ALWAYS;
else
@@ -392,8 +392,8 @@ static int collect_reflog(const char *ref, const struct object_id *oid, int unus
static struct reflog_expire_cfg {
struct reflog_expire_cfg *next;
- unsigned long expire_total;
- unsigned long expire_unreachable;
+ timestamp_t expire_total;
+ timestamp_t expire_unreachable;
char pattern[FLEX_ARRAY];
} *reflog_expire_cfg, **reflog_expire_cfg_tail;
@@ -415,7 +415,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
return ent;
}
-static int parse_expire_cfg_value(const char *var, const char *value, unsigned long *expire)
+static int parse_expire_cfg_value(const char *var, const char *value, timestamp_t *expire)
{
if (!value)
return config_error_nonbool(var);
@@ -433,7 +433,7 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
{
const char *pattern, *key;
int pattern_len;
- unsigned long expire;
+ timestamp_t expire;
int slot;
struct reflog_expire_cfg *ent;
@@ -515,7 +515,7 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
{
struct expire_reflog_policy_cb cb;
- unsigned long now = time(NULL);
+ timestamp_t now = time(NULL);
int i, status, do_all;
int explicit_expiry = 0;
unsigned int flags = 0;
@@ -616,7 +616,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
}
static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
- const char *email, unsigned long timestamp, int tz,
+ const char *email, timestamp_t timestamp, int tz,
const char *message, void *cb_data)
{
struct expire_reflog_policy_cb *cb = cb_data;
diff --git a/builtin/repack.c b/builtin/repack.c
index 677bc7c81a..38ba4ef825 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -155,6 +155,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
int keep_unreachable = 0;
const char *window = NULL, *window_memory = NULL;
const char *depth = NULL;
+ const char *threads = NULL;
const char *max_pack_size = NULL;
int no_reuse_delta = 0, no_reuse_object = 0;
int no_update_server_info = 0;
@@ -190,6 +191,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
N_("same as the above, but limit memory size instead of entries count")),
OPT_STRING(0, "depth", &depth, N_("n"),
N_("limits the maximum delta depth")),
+ OPT_STRING(0, "threads", &threads, N_("n"),
+ N_("limits the maximum number of threads")),
OPT_STRING(0, "max-pack-size", &max_pack_size, N_("bytes"),
N_("maximum size of each packfile")),
OPT_BOOL(0, "pack-kept-objects", &pack_kept_objects,
@@ -234,6 +237,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
argv_array_pushf(&cmd.args, "--window-memory=%s", window_memory);
if (depth)
argv_array_pushf(&cmd.args, "--depth=%s", depth);
+ if (threads)
+ argv_array_pushf(&cmd.args, "--threads=%s", threads);
if (max_pack_size)
argv_array_pushf(&cmd.args, "--max-pack-size=%s", max_pack_size);
if (no_reuse_delta)
diff --git a/builtin/replace.c b/builtin/replace.c
index f83e7b8fc1..c921bc976f 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -93,28 +93,34 @@ typedef int (*each_replace_name_fn)(const char *name, const char *ref,
static int for_each_replace_name(const char **argv, each_replace_name_fn fn)
{
const char **p, *full_hex;
- char ref[PATH_MAX];
+ struct strbuf ref = STRBUF_INIT;
+ size_t base_len;
int had_error = 0;
struct object_id oid;
+ strbuf_addstr(&ref, git_replace_ref_base);
+ base_len = ref.len;
+
for (p = argv; *p; p++) {
if (get_oid(*p, &oid)) {
error("Failed to resolve '%s' as a valid ref.", *p);
had_error = 1;
continue;
}
- full_hex = oid_to_hex(&oid);
- snprintf(ref, sizeof(ref), "%s%s", git_replace_ref_base, full_hex);
- /* read_ref() may reuse the buffer */
- full_hex = ref + strlen(git_replace_ref_base);
- if (read_ref(ref, oid.hash)) {
+
+ strbuf_setlen(&ref, base_len);
+ strbuf_addstr(&ref, oid_to_hex(&oid));
+ full_hex = ref.buf + base_len;
+
+ if (read_ref(ref.buf, oid.hash)) {
error("replace ref '%s' not found.", full_hex);
had_error = 1;
continue;
}
- if (fn(full_hex, ref, &oid))
+ if (fn(full_hex, ref.buf, &oid))
had_error = 1;
}
+ strbuf_release(&ref);
return had_error;
}
@@ -129,21 +135,18 @@ static int delete_replace_ref(const char *name, const char *ref,
static void check_ref_valid(struct object_id *object,
struct object_id *prev,
- char *ref,
- int ref_size,
+ struct strbuf *ref,
int force)
{
- if (snprintf(ref, ref_size,
- "%s%s", git_replace_ref_base,
- oid_to_hex(object)) > ref_size - 1)
- die("replace ref name too long: %.*s...", 50, ref);
- if (check_refname_format(ref, 0))
- die("'%s' is not a valid ref name.", ref);
-
- if (read_ref(ref, prev->hash))
+ strbuf_reset(ref);
+ strbuf_addf(ref, "%s%s", git_replace_ref_base, oid_to_hex(object));
+ if (check_refname_format(ref->buf, 0))
+ die("'%s' is not a valid ref name.", ref->buf);
+
+ if (read_ref(ref->buf, prev->hash))
oidclr(prev);
else if (!force)
- die("replace ref '%s' already exists", ref);
+ die("replace ref '%s' already exists", ref->buf);
}
static int replace_object_oid(const char *object_ref,
@@ -154,7 +157,7 @@ static int replace_object_oid(const char *object_ref,
{
struct object_id prev;
enum object_type obj_type, repl_type;
- char ref[PATH_MAX];
+ struct strbuf ref = STRBUF_INIT;
struct ref_transaction *transaction;
struct strbuf err = STRBUF_INIT;
@@ -167,16 +170,17 @@ static int replace_object_oid(const char *object_ref,
object_ref, typename(obj_type),
replace_ref, typename(repl_type));
- check_ref_valid(object, &prev, ref, sizeof(ref), force);
+ check_ref_valid(object, &prev, &ref, force);
transaction = ref_transaction_begin(&err);
if (!transaction ||
- ref_transaction_update(transaction, ref, repl->hash, prev.hash,
+ ref_transaction_update(transaction, ref.buf, repl->hash, prev.hash,
0, NULL, &err) ||
ref_transaction_commit(transaction, &err))
die("%s", err.buf);
ref_transaction_free(transaction);
+ strbuf_release(&ref);
return 0;
}
@@ -280,7 +284,7 @@ static int edit_and_replace(const char *object_ref, int force, int raw)
char *tmpfile = git_pathdup("REPLACE_EDITOBJ");
enum object_type type;
struct object_id old, new, prev;
- char ref[PATH_MAX];
+ struct strbuf ref = STRBUF_INIT;
if (get_oid(object_ref, &old) < 0)
die("Not a valid object name: '%s'", object_ref);
@@ -289,7 +293,8 @@ static int edit_and_replace(const char *object_ref, int force, int raw)
if (type < 0)
die("unable to get object type for %s", oid_to_hex(&old));
- check_ref_valid(&old, &prev, ref, sizeof(ref), force);
+ check_ref_valid(&old, &prev, &ref, force);
+ strbuf_release(&ref);
export_object(&old, type, raw, tmpfile);
if (launch_editor(tmpfile, NULL, NULL) < 0)
@@ -323,7 +328,7 @@ static void replace_parents(struct strbuf *buf, int argc, const char **argv)
struct object_id oid;
if (get_oid(argv[i], &oid) < 0)
die(_("Not a valid object name: '%s'"), argv[i]);
- lookup_commit_or_die(oid.hash, argv[i]);
+ lookup_commit_or_die(&oid, argv[i]);
strbuf_addf(&new_parents, "parent %s\n", oid_to_hex(&oid));
}
@@ -350,7 +355,7 @@ static void check_one_mergetag(struct commit *commit,
int i;
hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), tag_oid.hash);
- tag = lookup_tag(tag_oid.hash);
+ tag = lookup_tag(&tag_oid);
if (!tag)
die(_("bad mergetag in commit '%s'"), ref);
if (parse_tag_buffer(tag, extra->value, extra->len))
@@ -389,7 +394,7 @@ static int create_graft(int argc, const char **argv, int force)
if (get_oid(old_ref, &old) < 0)
die(_("Not a valid object name: '%s'"), old_ref);
- commit = lookup_commit_or_die(old.hash, old_ref);
+ commit = lookup_commit_or_die(&old, old_ref);
buffer = get_commit_buffer(commit, &size);
strbuf_add(&buf, buffer, size);
diff --git a/builtin/reset.c b/builtin/reset.c
index fc3b906c47..0afe1df250 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -21,6 +21,27 @@
#include "parse-options.h"
#include "unpack-trees.h"
#include "cache-tree.h"
+#include "submodule.h"
+#include "submodule-config.h"
+
+static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+
+static int option_parse_recurse_submodules(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset) {
+ recurse_submodules = RECURSE_SUBMODULES_OFF;
+ return 0;
+ }
+ if (arg)
+ recurse_submodules =
+ parse_update_recurse_submodules_arg(opt->long_name,
+ arg);
+ else
+ recurse_submodules = RECURSE_SUBMODULES_ON;
+
+ return 0;
+}
static const char * const git_reset_usage[] = {
N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"),
@@ -84,7 +105,7 @@ static int reset_index(const struct object_id *oid, int reset_type, int quiet)
return -1;
if (reset_type == MIXED || reset_type == HARD) {
- tree = parse_tree_indirect(oid->hash);
+ tree = parse_tree_indirect(oid);
prime_cache_tree(&the_index, tree);
}
@@ -154,7 +175,7 @@ static int read_from_tree(const struct pathspec *pathspec,
opt.format_callback = update_index_from_diff;
opt.format_callback_data = &intent_to_add;
- if (do_diff_cache(tree_oid->hash, &opt))
+ if (do_diff_cache(tree_oid, &opt))
return 1;
diffcore_std(&opt);
diff_flush(&opt);
@@ -283,6 +304,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
N_("reset HEAD, index and working tree"), MERGE),
OPT_SET_INT(0, "keep", &reset_type,
N_("reset HEAD but keep local changes"), KEEP),
+ { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules,
+ "reset", "control recursive updating of submodules",
+ PARSE_OPT_OPTARG, option_parse_recurse_submodules },
OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
OPT_BOOL('N', "intent-to-add", &intent_to_add,
N_("record only the fact that removed paths will be added later")),
@@ -295,6 +319,12 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_DASHDASH);
parse_args(&pathspec, argv, prefix, patch_mode, &rev);
+ if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT) {
+ gitmodules_config();
+ git_config(submodule_config, NULL);
+ set_config_update_recurse_submodules(RECURSE_SUBMODULES_ON);
+ }
+
unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", oid.hash);
if (unborn) {
/* reset on unborn branch: treat as reset to empty tree */
@@ -303,7 +333,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
struct commit *commit;
if (get_sha1_committish(rev, oid.hash))
die(_("Failed to resolve '%s' as a valid revision."), rev);
- commit = lookup_commit_reference(oid.hash);
+ commit = lookup_commit_reference(&oid);
if (!commit)
die(_("Could not parse object '%s'."), rev);
oidcpy(&oid, &commit->object.oid);
@@ -311,7 +341,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
struct tree *tree;
if (get_sha1_treeish(rev, oid.hash))
die(_("Failed to resolve '%s' as a valid tree."), rev);
- tree = parse_tree_indirect(oid.hash);
+ tree = parse_tree_indirect(&oid);
if (!tree)
die(_("Could not parse object '%s'."), rev);
oidcpy(&oid, &tree->object.oid);
@@ -380,7 +410,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
update_ref_status = reset_refs(rev, &oid);
if (reset_type == HARD && !update_ref_status && !quiet)
- print_new_head_line(lookup_commit_reference(oid.hash));
+ print_new_head_line(lookup_commit_reference(&oid));
}
if (!pathspec.nr)
remove_branch_state();
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 0aa93d5891..718c6059c9 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -80,7 +80,7 @@ static void show_commit(struct commit *commit, void *data)
}
if (info->show_timestamp)
- printf("%lu ", commit->date);
+ printf("%"PRItime" ", commit->date);
if (info->header_prefix)
fputs(info->header_prefix, stdout);
@@ -181,7 +181,7 @@ static void finish_object(struct object *obj, const char *name, void *cb_data)
if (obj->type == OBJ_BLOB && !has_object_file(&obj->oid))
die("missing blob object '%s'", oid_to_hex(&obj->oid));
if (info->revs->verify_objects && !obj->parsed && obj->type != OBJ_COMMIT)
- parse_object(obj->oid.hash);
+ parse_object(&obj->oid);
}
static void show_object(struct object *obj, const char *name, void *cb_data)
@@ -212,7 +212,7 @@ static void print_var_int(const char *var, int val)
static int show_bisect_vars(struct rev_list_info *info, int reaches, int all)
{
int cnt, flags = info->flags;
- char hex[GIT_SHA1_HEXSZ + 1] = "";
+ char hex[GIT_MAX_HEXSZ + 1] = "";
struct commit_list *tried;
struct rev_info *revs = info->revs;
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 9e53a1a7ca..efdc14473b 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -121,7 +121,7 @@ static void show_with_type(int type, const char *arg)
}
/* Output a revision, only if filter allows it */
-static void show_rev(int type, const unsigned char *sha1, const char *name)
+static void show_rev(int type, const struct object_id *oid, const char *name)
{
if (!(filter & DO_REVS))
return;
@@ -129,10 +129,10 @@ static void show_rev(int type, const unsigned char *sha1, const char *name)
if ((symbolic || abbrev_ref) && name) {
if (symbolic == SHOW_SYMBOLIC_FULL || abbrev_ref) {
- unsigned char discard[20];
+ struct object_id discard;
char *full;
- switch (dwim_ref(name, strlen(name), discard, &full)) {
+ switch (dwim_ref(name, strlen(name), discard.hash, &full)) {
case 0:
/*
* Not found -- not a ref. We could
@@ -158,9 +158,9 @@ static void show_rev(int type, const unsigned char *sha1, const char *name)
}
}
else if (abbrev)
- show_with_type(type, find_unique_abbrev(sha1, abbrev));
+ show_with_type(type, find_unique_abbrev(oid->hash, abbrev));
else
- show_with_type(type, sha1_to_hex(sha1));
+ show_with_type(type, oid_to_hex(oid));
}
/* Output a flag, only if filter allows it. */
@@ -180,11 +180,11 @@ static int show_default(void)
const char *s = def;
if (s) {
- unsigned char sha1[20];
+ struct object_id oid;
def = NULL;
- if (!get_sha1(s, sha1)) {
- show_rev(NORMAL, sha1, s);
+ if (!get_oid(s, &oid)) {
+ show_rev(NORMAL, &oid, s);
return 1;
}
}
@@ -195,31 +195,32 @@ static int show_reference(const char *refname, const struct object_id *oid, int
{
if (ref_excluded(ref_excludes, refname))
return 0;
- show_rev(NORMAL, oid->hash, refname);
+ show_rev(NORMAL, oid, refname);
return 0;
}
static int anti_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data)
{
- show_rev(REVERSED, oid->hash, refname);
+ show_rev(REVERSED, oid, refname);
return 0;
}
-static int show_abbrev(const unsigned char *sha1, void *cb_data)
+static int show_abbrev(const struct object_id *oid, void *cb_data)
{
- show_rev(NORMAL, sha1, NULL);
+ show_rev(NORMAL, oid, NULL);
return 0;
}
static void show_datestring(const char *flag, const char *datestr)
{
- static char buffer[100];
+ char *buffer;
/* date handling requires both flags and revs */
if ((filter & (DO_FLAGS | DO_REVS)) != (DO_FLAGS | DO_REVS))
return;
- snprintf(buffer, sizeof(buffer), "%s%lu", flag, approxidate(datestr));
+ buffer = xstrfmt("%s%"PRItime, flag, approxidate(datestr));
show(buffer);
+ free(buffer);
}
static int show_file(const char *arg, int output_prefix)
@@ -241,8 +242,8 @@ static int show_file(const char *arg, int output_prefix)
static int try_difference(const char *arg)
{
char *dotdot;
- unsigned char sha1[20];
- unsigned char end[20];
+ struct object_id oid;
+ struct object_id end;
const char *next;
const char *this;
int symmetric;
@@ -272,18 +273,18 @@ static int try_difference(const char *arg)
return 0;
}
- if (!get_sha1_committish(this, sha1) && !get_sha1_committish(next, end)) {
- show_rev(NORMAL, end, next);
- show_rev(symmetric ? NORMAL : REVERSED, sha1, this);
+ if (!get_sha1_committish(this, oid.hash) && !get_sha1_committish(next, end.hash)) {
+ show_rev(NORMAL, &end, next);
+ show_rev(symmetric ? NORMAL : REVERSED, &oid, this);
if (symmetric) {
struct commit_list *exclude;
struct commit *a, *b;
- a = lookup_commit_reference(sha1);
- b = lookup_commit_reference(end);
+ a = lookup_commit_reference(&oid);
+ b = lookup_commit_reference(&end);
exclude = get_merge_bases(a, b);
while (exclude) {
struct commit *commit = pop_commit(&exclude);
- show_rev(REVERSED, commit->object.oid.hash, NULL);
+ show_rev(REVERSED, &commit->object.oid, NULL);
}
}
*dotdot = '.';
@@ -296,7 +297,7 @@ static int try_difference(const char *arg)
static int try_parent_shorthands(const char *arg)
{
char *dotdot;
- unsigned char sha1[20];
+ struct object_id oid;
struct commit *commit;
struct commit_list *parents;
int parent_number;
@@ -326,12 +327,12 @@ static int try_parent_shorthands(const char *arg)
return 0;
*dotdot = 0;
- if (get_sha1_committish(arg, sha1)) {
+ if (get_sha1_committish(arg, oid.hash)) {
*dotdot = '^';
return 0;
}
- commit = lookup_commit_reference(sha1);
+ commit = lookup_commit_reference(&oid);
if (exclude_parent &&
exclude_parent > commit_list_count(commit->parents)) {
*dotdot = '^';
@@ -339,7 +340,7 @@ static int try_parent_shorthands(const char *arg)
}
if (include_rev)
- show_rev(NORMAL, sha1, arg);
+ show_rev(NORMAL, &oid, arg);
for (parents = commit->parents, parent_number = 1;
parents;
parents = parents->next, parent_number++) {
@@ -351,7 +352,7 @@ static int try_parent_shorthands(const char *arg)
if (symbolic)
name = xstrfmt("%s^%d", arg, parent_number);
show_rev(include_parents ? NORMAL : REVERSED,
- parents->item->object.oid.hash, name);
+ &parents->item->object.oid, name);
free(name);
}
@@ -570,7 +571,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
int did_repo_setup = 0;
int has_dashdash = 0;
int output_prefix = 0;
- unsigned char sha1[20];
+ struct object_id oid;
unsigned int flags = 0;
const char *name = NULL;
struct object_context unused;
@@ -909,11 +910,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
name++;
type = REVERSED;
}
- if (!get_sha1_with_context(name, flags, sha1, &unused)) {
+ if (!get_sha1_with_context(name, flags, oid.hash, &unused)) {
if (verify)
revs_count++;
else
- show_rev(type, sha1, name);
+ show_rev(type, &oid, name);
continue;
}
if (verify)
@@ -928,7 +929,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
strbuf_release(&buf);
if (verify) {
if (revs_count == 1) {
- show_rev(type, sha1, name);
+ show_rev(type, &oid, name);
return 0;
} else if (revs_count == 0 && show_default())
return 0;
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 832fd7ed0a..b8e2e74fe0 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -131,8 +131,8 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
const char *dest = NULL;
int fd[2];
struct child_process *conn;
- struct sha1_array extra_have = SHA1_ARRAY_INIT;
- struct sha1_array shallow = SHA1_ARRAY_INIT;
+ struct oid_array extra_have = OID_ARRAY_INIT;
+ struct oid_array shallow = OID_ARRAY_INIT;
struct ref *remote_refs, *local_refs;
int ret;
int helper_status = 0;
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index 19756595d5..4a6cc6f490 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -358,7 +358,7 @@ static void sort_ref_range(int bottom, int top)
static int append_ref(const char *refname, const struct object_id *oid,
int allow_dups)
{
- struct commit *commit = lookup_commit_reference_gently(oid->hash, 1);
+ struct commit *commit = lookup_commit_reference_gently(oid, 1);
int i;
if (!commit)
@@ -735,7 +735,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
base = strtoul(reflog_base, &ep, 10);
if (*ep) {
/* Ah, that is a date spec... */
- unsigned long at;
+ timestamp_t at;
at = approxidate(reflog_base);
read_ref_at(ref, flags, at, -1, oid.hash, NULL,
NULL, NULL, &base);
@@ -746,7 +746,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
char *logmsg;
char *nth_desc;
const char *msg;
- unsigned long timestamp;
+ timestamp_t timestamp;
int tz;
if (read_ref_at(ref, flags, 0, base+i, oid.hash, &logmsg,
@@ -816,7 +816,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
MAX_REVS), MAX_REVS);
if (get_sha1(ref_name[num_rev], revkey.hash))
die(_("'%s' is not a valid ref."), ref_name[num_rev]);
- commit = lookup_commit_reference(revkey.hash);
+ commit = lookup_commit_reference(&revkey);
if (!commit)
die(_("cannot find commit %s (%s)"),
ref_name[num_rev], oid_to_hex(&revkey));
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 15a5430c00..566a5b6a6f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -270,6 +270,29 @@ static int module_list_compute(int argc, const char **argv,
return result;
}
+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];
+
+ if (!is_submodule_initialized(ce->name))
+ continue;
+
+ ALLOC_GROW(active_modules.entries,
+ active_modules.nr + 1,
+ active_modules.alloc);
+ active_modules.entries[active_modules.nr++] = ce;
+ }
+
+ free(list->entries);
+ *list = active_modules;
+}
+
static int module_list(int argc, const char **argv, const char *prefix)
{
int i;
@@ -334,6 +357,18 @@ static void init_submodule(const char *path, const char *prefix, int quiet)
displaypath);
/*
+ * NEEDSWORK: In a multi-working-tree world, this needs to be
+ * set in the per-worktree config.
+ *
+ * Set active flag for the submodule being initialized
+ */
+ if (!is_submodule_initialized(path)) {
+ strbuf_reset(&sb);
+ strbuf_addf(&sb, "submodule.%s.active", sub->name);
+ git_config_set_gently(sb.buf, "true");
+ }
+
+ /*
* Copy url setting when it is not set yet.
* To look up the url in .git/config, we must not fall back to
* .gitmodules, so look it up directly.
@@ -341,12 +376,12 @@ static void init_submodule(const char *path, const char *prefix, int quiet)
strbuf_reset(&sb);
strbuf_addf(&sb, "submodule.%s.url", sub->name);
if (git_config_get_string(sb.buf, &url)) {
- url = xstrdup(sub->url);
-
- if (!url)
+ if (!sub->url)
die(_("No url found for submodule path '%s' in .gitmodules"),
displaypath);
+ url = xstrdup(sub->url);
+
/* Possibly a url relative to parent */
if (starts_with_dot_dot_slash(url) ||
starts_with_dot_slash(url)) {
@@ -420,6 +455,13 @@ static int module_init(int argc, const char **argv, const char *prefix)
if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
return 1;
+ /*
+ * If there are no path args and submodule.active is set then,
+ * by default, only initialize 'active' modules.
+ */
+ if (!argc && git_config_get_value_multi("submodule.active"))
+ module_list_active(&list);
+
for (i = 0; i < list.nr; i++)
init_submodule(list.entries[i]->name, prefix, quiet);
@@ -577,9 +619,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
const char *name = NULL, *url = NULL, *depth = NULL;
int quiet = 0;
int progress = 0;
- FILE *submodule_dot_git;
char *p, *path = NULL, *sm_gitdir;
- struct strbuf rel_path = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
struct string_list reference = STRING_LIST_INIT_NODUP;
char *sm_alternate = NULL, *error_strategy = NULL;
@@ -651,27 +691,12 @@ static int module_clone(int argc, const char **argv, const char *prefix)
strbuf_reset(&sb);
}
- /* Write a .git file in the submodule to redirect to the superproject. */
- strbuf_addf(&sb, "%s/.git", path);
- if (safe_create_leading_directories_const(sb.buf) < 0)
- die(_("could not create leading directories of '%s'"), sb.buf);
- submodule_dot_git = fopen(sb.buf, "w");
- if (!submodule_dot_git)
- die_errno(_("cannot open file '%s'"), sb.buf);
-
- fprintf_or_die(submodule_dot_git, "gitdir: %s\n",
- relative_path(sm_gitdir, path, &rel_path));
- if (fclose(submodule_dot_git))
- die(_("could not close file %s"), sb.buf);
- strbuf_reset(&sb);
- strbuf_reset(&rel_path);
+ /* Connect module worktree and git dir */
+ connect_work_tree_and_git_dir(path, sm_gitdir);
- /* Redirect the worktree of the submodule in the superproject's config */
p = git_pathdup_submodule(path, "config");
if (!p)
die(_("could not get submodule directory for '%s'"), path);
- git_config_set_in_file(p, "core.worktree",
- relative_path(path, sm_gitdir, &rel_path));
/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
git_config_get_string("submodule.alternateLocation", &sm_alternate);
@@ -687,7 +712,6 @@ static int module_clone(int argc, const char **argv, const char *prefix)
free(error_strategy);
strbuf_release(&sb);
- strbuf_release(&rel_path);
free(sm_gitdir);
free(path);
free(p);
@@ -759,7 +783,6 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
struct strbuf displaypath_sb = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
const char *displaypath = NULL;
- char *url = NULL;
int needs_cloning = 0;
if (ce_stage(ce)) {
@@ -793,15 +816,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
goto cleanup;
}
- /*
- * Looking up the url in .git/config.
- * We must not fall back to .gitmodules as we only want
- * to process configured submodules.
- */
- strbuf_reset(&sb);
- strbuf_addf(&sb, "submodule.%s.url", sub->name);
- git_config_get_string(sb.buf, &url);
- if (!url) {
+ /* Check if the submodule has been initialized. */
+ if (!is_submodule_initialized(ce->name)) {
next_submodule_warn_missing(suc, out, displaypath);
goto cleanup;
}
@@ -835,7 +851,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", url, NULL);
+ argv_array_pushl(&child->args, "--url", sub->url, NULL);
if (suc->references.nr) {
struct string_list_item *item;
for_each_string_list_item(item, &suc->references)
@@ -845,7 +861,6 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
argv_array_push(&child->args, suc->depth);
cleanup:
- free(url);
strbuf_reset(&displaypath_sb);
strbuf_reset(&sb);
@@ -1090,6 +1105,50 @@ static int resolve_remote_submodule_branch(int argc, const char **argv,
return 0;
}
+static int push_check(int argc, const char **argv, const char *prefix)
+{
+ struct remote *remote;
+
+ if (argc < 2)
+ die("submodule--helper push-check requires at least 1 argument");
+
+ /*
+ * The remote must be configured.
+ * This is to avoid pushing to the exact same URL as the parent.
+ */
+ remote = pushremote_get(argv[1]);
+ if (!remote || remote->origin == REMOTE_UNCONFIGURED)
+ die("remote '%s' not configured", argv[1]);
+
+ /* Check the refspec */
+ if (argc > 2) {
+ int i, refspec_nr = argc - 2;
+ struct ref *local_refs = get_local_heads();
+ struct refspec *refspec = parse_push_refspec(refspec_nr,
+ argv + 2);
+
+ for (i = 0; i < refspec_nr; i++) {
+ struct refspec *rs = refspec + i;
+
+ 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)
+ die("src refspec '%s' must name a ref",
+ rs->src);
+ }
+ free_refspec(refspec_nr, refspec);
+ }
+
+ return 0;
+}
+
static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
{
int i;
@@ -1127,6 +1186,16 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
return 0;
}
+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_initialized(argv[1]);
+}
+
#define SUPPORT_SUPER_PREFIX (1<<0)
struct cmd_struct {
@@ -1145,7 +1214,9 @@ static struct cmd_struct commands[] = {
{"resolve-relative-url-test", resolve_relative_url_test, 0},
{"init", module_init, SUPPORT_SUPER_PREFIX},
{"remote-branch", resolve_remote_submodule_branch, 0},
+ {"push-check", push_check, 0},
{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
+ {"is-active", is_active, 0},
};
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
diff --git a/builtin/tag.c b/builtin/tag.c
index ad29be6923..1f74a56db7 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -22,7 +22,7 @@
static const char * const git_tag_usage[] = {
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<head>]"),
N_("git tag -d <tagname>..."),
- N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>]"
+ N_("git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at <object>]"
"\n\t\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]"),
N_("git tag -v [--format=<format>] <tagname>..."),
NULL
@@ -66,45 +66,42 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con
}
typedef int (*each_tag_name_fn)(const char *name, const char *ref,
- const unsigned char *sha1, const void *cb_data);
+ const struct object_id *oid, const void *cb_data);
static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
const void *cb_data)
{
const char **p;
- char ref[PATH_MAX];
+ struct strbuf ref = STRBUF_INIT;
int had_error = 0;
- unsigned char sha1[20];
+ struct object_id oid;
for (p = argv; *p; p++) {
- if (snprintf(ref, sizeof(ref), "refs/tags/%s", *p)
- >= sizeof(ref)) {
- error(_("tag name too long: %.*s..."), 50, *p);
- had_error = 1;
- continue;
- }
- if (read_ref(ref, sha1)) {
+ strbuf_reset(&ref);
+ strbuf_addf(&ref, "refs/tags/%s", *p);
+ if (read_ref(ref.buf, oid.hash)) {
error(_("tag '%s' not found."), *p);
had_error = 1;
continue;
}
- if (fn(*p, ref, sha1, cb_data))
+ if (fn(*p, ref.buf, &oid, cb_data))
had_error = 1;
}
+ strbuf_release(&ref);
return had_error;
}
static int delete_tag(const char *name, const char *ref,
- const unsigned char *sha1, const void *cb_data)
+ const struct object_id *oid, const void *cb_data)
{
- if (delete_ref(NULL, ref, sha1, 0))
+ if (delete_ref(NULL, ref, oid->hash, 0))
return 1;
- printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(sha1, DEFAULT_ABBREV));
+ printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
return 0;
}
static int verify_tag(const char *name, const char *ref,
- const unsigned char *sha1, const void *cb_data)
+ const struct object_id *oid, const void *cb_data)
{
int flags;
const char *fmt_pretty = cb_data;
@@ -113,11 +110,11 @@ static int verify_tag(const char *name, const char *ref,
if (fmt_pretty)
flags = GPG_VERIFY_OMIT_STATUS;
- if (gpg_verify_tag(sha1, name, flags))
+ if (gpg_verify_tag(oid->hash, name, flags))
return -1;
if (fmt_pretty)
- pretty_print_ref(name, sha1, fmt_pretty);
+ pretty_print_ref(name, oid->hash, fmt_pretty);
return 0;
}
@@ -185,13 +182,13 @@ static int git_tag_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
-static void write_tag_body(int fd, const unsigned char *sha1)
+static void write_tag_body(int fd, const struct object_id *oid)
{
unsigned long size;
enum object_type type;
char *buf, *sp;
- buf = read_sha1_file(sha1, &type, &size);
+ buf = read_sha1_file(oid->hash, &type, &size);
if (!buf)
return;
/* skip header */
@@ -207,11 +204,11 @@ static void write_tag_body(int fd, const unsigned char *sha1)
free(buf);
}
-static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)
+static int build_tag_object(struct strbuf *buf, int sign, struct object_id *result)
{
if (sign && do_sign(buf) < 0)
return error(_("unable to sign the tag"));
- if (write_sha1_file(buf->buf, buf->len, tag_type, result) < 0)
+ if (write_sha1_file(buf->buf, buf->len, tag_type, result->hash) < 0)
return error(_("unable to write tag file"));
return 0;
}
@@ -226,31 +223,27 @@ struct create_tag_options {
} cleanup_mode;
};
-static void create_tag(const unsigned char *object, const char *tag,
+static void create_tag(const struct object_id *object, const char *tag,
struct strbuf *buf, struct create_tag_options *opt,
- unsigned char *prev, unsigned char *result)
+ struct object_id *prev, struct object_id *result)
{
enum object_type type;
- char header_buf[1024];
- int header_len;
+ struct strbuf header = STRBUF_INIT;
char *path = NULL;
- type = sha1_object_info(object, NULL);
+ type = sha1_object_info(object->hash, NULL);
if (type <= OBJ_NONE)
die(_("bad object type."));
- header_len = snprintf(header_buf, sizeof(header_buf),
- "object %s\n"
- "type %s\n"
- "tag %s\n"
- "tagger %s\n\n",
- sha1_to_hex(object),
- typename(type),
- tag,
- git_committer_info(IDENT_STRICT));
-
- if (header_len > sizeof(header_buf) - 1)
- die(_("tag header too big."));
+ strbuf_addf(&header,
+ "object %s\n"
+ "type %s\n"
+ "tag %s\n"
+ "tagger %s\n\n",
+ oid_to_hex(object),
+ typename(type),
+ tag,
+ git_committer_info(IDENT_STRICT));
if (!opt->message_given) {
int fd;
@@ -261,7 +254,7 @@ static void create_tag(const unsigned char *object, const char *tag,
if (fd < 0)
die_errno(_("could not create file '%s'"), path);
- if (!is_null_sha1(prev)) {
+ if (!is_null_oid(prev)) {
write_tag_body(fd, prev);
} else {
struct strbuf buf = STRBUF_INIT;
@@ -288,7 +281,8 @@ static void create_tag(const unsigned char *object, const char *tag,
if (!opt->message_given && !buf->len)
die(_("no tag message?"));
- strbuf_insert(buf, 0, header_buf, header_len);
+ strbuf_insert(buf, 0, header.buf, header.len);
+ strbuf_release(&header);
if (build_tag_object(buf, opt->sign, result) < 0) {
if (path)
@@ -302,7 +296,7 @@ static void create_tag(const unsigned char *object, const char *tag,
}
}
-static void create_reflog_msg(const unsigned char *sha1, struct strbuf *sb)
+static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
{
enum object_type type;
struct commit *c;
@@ -315,36 +309,36 @@ static void create_reflog_msg(const unsigned char *sha1, struct strbuf *sb)
if (rla) {
strbuf_addstr(sb, rla);
} else {
- strbuf_addstr(sb, _("tag: tagging "));
- strbuf_add_unique_abbrev(sb, sha1, DEFAULT_ABBREV);
+ strbuf_addstr(sb, "tag: tagging ");
+ strbuf_add_unique_abbrev(sb, oid->hash, DEFAULT_ABBREV);
}
strbuf_addstr(sb, " (");
- type = sha1_object_info(sha1, NULL);
+ type = sha1_object_info(oid->hash, NULL);
switch (type) {
default:
- strbuf_addstr(sb, _("object of unknown type"));
+ strbuf_addstr(sb, "object of unknown type");
break;
case OBJ_COMMIT:
- if ((buf = read_sha1_file(sha1, &type, &size)) != NULL) {
+ if ((buf = read_sha1_file(oid->hash, &type, &size)) != NULL) {
subject_len = find_commit_subject(buf, &subject_start);
strbuf_insert(sb, sb->len, subject_start, subject_len);
} else {
- strbuf_addstr(sb, _("commit object"));
+ strbuf_addstr(sb, "commit object");
}
free(buf);
- if ((c = lookup_commit_reference(sha1)) != NULL)
+ if ((c = lookup_commit_reference(oid)) != NULL)
strbuf_addf(sb, ", %s", show_date(c->date, 0, DATE_MODE(SHORT)));
break;
case OBJ_TREE:
- strbuf_addstr(sb, _("tree object"));
+ strbuf_addstr(sb, "tree object");
break;
case OBJ_BLOB:
- strbuf_addstr(sb, _("blob object"));
+ strbuf_addstr(sb, "blob object");
break;
case OBJ_TAG:
- strbuf_addstr(sb, _("other tag object"));
+ strbuf_addstr(sb, "other tag object");
break;
}
strbuf_addch(sb, ')');
@@ -384,7 +378,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
struct strbuf buf = STRBUF_INIT;
struct strbuf ref = STRBUF_INIT;
struct strbuf reflog_msg = STRBUF_INIT;
- unsigned char object[20], prev[20];
+ struct object_id object, prev;
const char *object_ref, *tag;
struct create_tag_options opt;
char *cleanup_arg = NULL;
@@ -424,14 +418,17 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_GROUP(N_("Tag listing options")),
OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
OPT_CONTAINS(&filter.with_commit, N_("print only tags that contain the commit")),
+ OPT_NO_CONTAINS(&filter.no_commit, N_("print only tags that don't contain the commit")),
OPT_WITH(&filter.with_commit, N_("print only tags that contain the commit")),
+ OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")),
OPT_MERGED(&filter, N_("print only tags that are merged")),
OPT_NO_MERGED(&filter, N_("print only tags that are not merged")),
OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
N_("field name to sort on"), &parse_opt_ref_sorting),
{
OPTION_CALLBACK, 0, "points-at", &filter.points_at, N_("object"),
- N_("print only tags of the object"), 0, parse_opt_object_name
+ 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_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
@@ -454,8 +451,14 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
}
create_tag_object = (opt.sign || annotate || msg.given || msgfile);
- if (argc == 0 && !cmdmode)
- cmdmode = 'l';
+ if (!cmdmode) {
+ if (argc == 0)
+ cmdmode = 'l';
+ else if (filter.with_commit || filter.no_commit ||
+ filter.points_at.nr || filter.merge_commit ||
+ filter.lines != -1)
+ cmdmode = 'l';
+ }
if ((create_tag_object || force) && (cmdmode != 0))
usage_with_options(git_tag_usage, options);
@@ -485,13 +488,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
return ret;
}
if (filter.lines != -1)
- die(_("-n option is only allowed with -l."));
+ die(_("-n option is only allowed in list mode"));
if (filter.with_commit)
- die(_("--contains option is only allowed with -l."));
+ die(_("--contains option is only allowed in list mode"));
+ if (filter.no_commit)
+ die(_("--no-contains option is only allowed in list mode"));
if (filter.points_at.nr)
- die(_("--points-at option is only allowed with -l."));
+ die(_("--points-at option is only allowed in list mode"));
if (filter.merge_commit)
- die(_("--merged and --no-merged option are only allowed with -l"));
+ die(_("--merged and --no-merged options are only allowed in list mode"));
if (cmdmode == 'd')
return for_each_tag_name(argv, delete_tag, NULL);
if (cmdmode == 'v') {
@@ -523,14 +528,14 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (argc > 2)
die(_("too many params"));
- if (get_sha1(object_ref, object))
+ if (get_oid(object_ref, &object))
die(_("Failed to resolve '%s' as a valid ref."), object_ref);
if (strbuf_check_tag_ref(&ref, tag))
die(_("'%s' is not a valid tag name."), tag);
- if (read_ref(ref.buf, prev))
- hashclr(prev);
+ if (read_ref(ref.buf, prev.hash))
+ oidclr(&prev);
else if (!force)
die(_("tag '%s' already exists"), tag);
@@ -545,24 +550,24 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
else
die(_("Invalid cleanup mode %s"), cleanup_arg);
- create_reflog_msg(object, &reflog_msg);
+ create_reflog_msg(&object, &reflog_msg);
if (create_tag_object) {
if (force_sign_annotate && !annotate)
opt.sign = 1;
- create_tag(object, tag, &buf, &opt, prev, object);
+ create_tag(&object, tag, &buf, &opt, &prev, &object);
}
transaction = ref_transaction_begin(&err);
if (!transaction ||
- ref_transaction_update(transaction, ref.buf, object, prev,
+ ref_transaction_update(transaction, ref.buf, object.hash, prev.hash,
create_reflog ? REF_FORCE_CREATE_REFLOG : 0,
reflog_msg.buf, &err) ||
ref_transaction_commit(transaction, &err))
die("%s", err.buf);
ref_transaction_free(transaction);
- if (force && !is_null_sha1(prev) && hashcmp(prev, object))
- printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev, DEFAULT_ABBREV));
+ if (force && !is_null_oid(&prev) && oidcmp(&prev, &object))
+ printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev.hash, DEFAULT_ABBREV));
strbuf_release(&err);
strbuf_release(&buf);
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 4532aa0831..8bc9997767 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -127,7 +127,7 @@ static void *get_data(unsigned long size)
}
struct delta_info {
- unsigned char base_sha1[20];
+ struct object_id base_oid;
unsigned nr;
off_t base_offset;
unsigned long size;
@@ -137,13 +137,13 @@ struct delta_info {
static struct delta_info *delta_list;
-static void add_delta_to_list(unsigned nr, unsigned const char *base_sha1,
+static void add_delta_to_list(unsigned nr, const struct object_id *base_oid,
off_t base_offset,
void *delta, unsigned long size)
{
struct delta_info *info = xmalloc(sizeof(*info));
- hashcpy(info->base_sha1, base_sha1);
+ oidcpy(&info->base_oid, base_oid);
info->base_offset = base_offset;
info->size = size;
info->delta = delta;
@@ -154,7 +154,7 @@ static void add_delta_to_list(unsigned nr, unsigned const char *base_sha1,
struct obj_info {
off_t offset;
- unsigned char sha1[20];
+ struct object_id oid;
struct object *obj;
};
@@ -170,9 +170,9 @@ static unsigned nr_objects;
*/
static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
{
- unsigned char sha1[20];
+ struct object_id oid;
- if (write_sha1_file(obj_buf->buffer, obj_buf->size, typename(obj->type), sha1) < 0)
+ if (write_sha1_file(obj_buf->buffer, obj_buf->size, typename(obj->type), oid.hash) < 0)
die("failed to write object %s", oid_to_hex(&obj->oid));
obj->flags |= FLAG_WRITTEN;
}
@@ -237,19 +237,19 @@ static void write_object(unsigned nr, enum object_type type,
void *buf, unsigned long size)
{
if (!strict) {
- if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
+ if (write_sha1_file(buf, size, typename(type), obj_list[nr].oid.hash) < 0)
die("failed to write object");
added_object(nr, type, buf, size);
free(buf);
obj_list[nr].obj = NULL;
} else if (type == OBJ_BLOB) {
struct blob *blob;
- if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
+ if (write_sha1_file(buf, size, typename(type), obj_list[nr].oid.hash) < 0)
die("failed to write object");
added_object(nr, type, buf, size);
free(buf);
- blob = lookup_blob(obj_list[nr].sha1);
+ blob = lookup_blob(&obj_list[nr].oid);
if (blob)
blob->object.flags |= FLAG_WRITTEN;
else
@@ -258,9 +258,10 @@ static void write_object(unsigned nr, enum object_type type,
} else {
struct object *obj;
int eaten;
- hash_sha1_file(buf, size, typename(type), obj_list[nr].sha1);
+ hash_sha1_file(buf, size, typename(type), obj_list[nr].oid.hash);
added_object(nr, type, buf, size);
- obj = parse_object_buffer(obj_list[nr].sha1, type, size, buf, &eaten);
+ obj = parse_object_buffer(&obj_list[nr].oid, type, size, buf,
+ &eaten);
if (!obj)
die("invalid %s", typename(type));
add_object_buffer(obj, buf, size);
@@ -296,7 +297,7 @@ static void added_object(unsigned nr, enum object_type type,
struct delta_info *info;
while ((info = *p) != NULL) {
- if (!hashcmp(info->base_sha1, obj_list[nr].sha1) ||
+ if (!oidcmp(&info->base_oid, &obj_list[nr].oid) ||
info->base_offset == obj_list[nr].offset) {
*p = info->next;
p = &delta_list;
@@ -320,12 +321,12 @@ static void unpack_non_delta_entry(enum object_type type, unsigned long size,
free(buf);
}
-static int resolve_against_held(unsigned nr, const unsigned char *base,
+static int resolve_against_held(unsigned nr, const struct object_id *base,
void *delta_data, unsigned long delta_size)
{
struct object *obj;
struct obj_buffer *obj_buffer;
- obj = lookup_object(base);
+ obj = lookup_object(base->hash);
if (!obj)
return 0;
obj_buffer = lookup_object_buffer(obj);
@@ -341,25 +342,25 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
{
void *delta_data, *base;
unsigned long base_size;
- unsigned char base_sha1[20];
+ struct object_id base_oid;
if (type == OBJ_REF_DELTA) {
- hashcpy(base_sha1, fill(20));
- use(20);
+ hashcpy(base_oid.hash, fill(GIT_SHA1_RAWSZ));
+ use(GIT_SHA1_RAWSZ);
delta_data = get_data(delta_size);
if (dry_run || !delta_data) {
free(delta_data);
return;
}
- if (has_sha1_file(base_sha1))
+ if (has_object_file(&base_oid))
; /* Ok we have this one */
- else if (resolve_against_held(nr, base_sha1,
+ else if (resolve_against_held(nr, &base_oid,
delta_data, delta_size))
return; /* we are done */
else {
/* cannot resolve yet --- queue it */
- hashclr(obj_list[nr].sha1);
- add_delta_to_list(nr, base_sha1, 0, delta_data, delta_size);
+ oidclr(&obj_list[nr].oid);
+ add_delta_to_list(nr, &base_oid, 0, delta_data, delta_size);
return;
}
} else {
@@ -399,8 +400,8 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
} else if (base_offset > obj_list[mid].offset) {
lo = mid + 1;
} else {
- hashcpy(base_sha1, obj_list[mid].sha1);
- base_found = !is_null_sha1(base_sha1);
+ oidcpy(&base_oid, &obj_list[mid].oid);
+ base_found = !is_null_oid(&base_oid);
break;
}
}
@@ -409,19 +410,19 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
* The delta base object is itself a delta that
* has not been resolved yet.
*/
- hashclr(obj_list[nr].sha1);
- add_delta_to_list(nr, null_sha1, base_offset, delta_data, delta_size);
+ oidclr(&obj_list[nr].oid);
+ add_delta_to_list(nr, &null_oid, base_offset, delta_data, delta_size);
return;
}
}
- if (resolve_against_held(nr, base_sha1, delta_data, delta_size))
+ if (resolve_against_held(nr, &base_oid, delta_data, delta_size))
return;
- base = read_sha1_file(base_sha1, &type, &base_size);
+ base = read_sha1_file(base_oid.hash, &type, &base_size);
if (!base) {
error("failed to read delta-pack base object %s",
- sha1_to_hex(base_sha1));
+ oid_to_hex(&base_oid));
if (!recover)
exit(1);
has_errors = 1;
@@ -505,7 +506,7 @@ static void unpack_all(void)
int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
{
int i;
- unsigned char sha1[20];
+ struct object_id oid;
check_replace_refs = 0;
@@ -566,12 +567,12 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
git_SHA1_Init(&ctx);
unpack_all();
git_SHA1_Update(&ctx, buffer, offset);
- git_SHA1_Final(sha1, &ctx);
+ git_SHA1_Final(oid.hash, &ctx);
if (strict)
write_rest();
- if (hashcmp(fill(20), sha1))
+ if (hashcmp(fill(GIT_SHA1_RAWSZ), oid.hash))
die("final sha1 did not match");
- use(20);
+ use(GIT_SHA1_RAWSZ);
/* Write the last part of the buffer to stdout */
while (len) {
diff --git a/builtin/update-index.c b/builtin/update-index.c
index d74d72cc7f..ebfc09faa0 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -125,12 +125,16 @@ static int test_if_untracked_cache_is_supported(void)
struct stat st;
struct stat_data base;
int fd, ret = 0;
+ char *cwd;
strbuf_addstr(&mtime_dir, "mtime-test-XXXXXX");
if (!mkdtemp(mtime_dir.buf))
die_errno("Could not make temporary directory");
- fprintf(stderr, _("Testing mtime in '%s' "), xgetcwd());
+ cwd = xgetcwd();
+ fprintf(stderr, _("Testing mtime in '%s' "), cwd);
+ free(cwd);
+
atexit(remove_test_directory);
xstat_mtime_dir(&st);
fill_stat_data(&base, &st);
diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c
index 38bedf8f9f..05b734e6d1 100644
--- a/builtin/verify-commit.c
+++ b/builtin/verify-commit.c
@@ -18,14 +18,14 @@ static const char * const verify_commit_usage[] = {
NULL
};
-static int run_gpg_verify(const unsigned char *sha1, const char *buf, unsigned long size, unsigned flags)
+static int run_gpg_verify(const struct object_id *oid, const char *buf, unsigned long size, unsigned flags)
{
struct signature_check signature_check;
int ret;
memset(&signature_check, 0, sizeof(signature_check));
- ret = check_commit_signature(lookup_commit(sha1), &signature_check);
+ ret = check_commit_signature(lookup_commit(oid), &signature_check);
print_signature_buffer(&signature_check, flags);
signature_check_clear(&signature_check);
@@ -35,22 +35,22 @@ static int run_gpg_verify(const unsigned char *sha1, const char *buf, unsigned l
static int verify_commit(const char *name, unsigned flags)
{
enum object_type type;
- unsigned char sha1[20];
+ struct object_id oid;
char *buf;
unsigned long size;
int ret;
- if (get_sha1(name, sha1))
+ if (get_oid(name, &oid))
return error("commit '%s' not found.", name);
- buf = read_sha1_file(sha1, &type, &size);
+ buf = read_sha1_file(oid.hash, &type, &size);
if (!buf)
return error("%s: unable to read file.", name);
if (type != OBJ_COMMIT)
return error("%s: cannot verify a non-commit object of type %s.",
name, typename(type));
- ret = run_gpg_verify(sha1, buf, size, flags);
+ ret = run_gpg_verify(&oid, buf, size, flags);
free(buf);
return ret;
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 9993ded41a..793306ea51 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -24,13 +24,14 @@ struct add_opts {
int force;
int detach;
int checkout;
+ int keep_locked;
const char *new_branch;
int force_new_branch;
};
static int show_only;
static int verbose;
-static unsigned long expire;
+static timestamp_t expire;
static int prune_worktree(const char *id, struct strbuf *reason)
{
@@ -106,8 +107,7 @@ static void prune_worktrees(void)
printf("%s\n", reason.buf);
if (show_only)
continue;
- strbuf_reset(&path);
- strbuf_addstr(&path, git_path("worktrees/%s", d->d_name));
+ git_path_buf(&path, "worktrees/%s", d->d_name);
ret = remove_dir_recursively(&path, 0);
if (ret < 0 && errno == ENOTDIR)
ret = unlink(path.buf);
@@ -131,7 +131,7 @@ static int prune(int ac, const char **av, const char *prefix)
OPT_END()
};
- expire = ULONG_MAX;
+ expire = TIME_MAX;
ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
if (ac)
usage_with_options(worktree_usage, options);
@@ -215,8 +215,7 @@ static int add_worktree(const char *path, const char *refname,
}
name = worktree_basename(path, &len);
- strbuf_addstr(&sb_repo,
- git_path("worktrees/%.*s", (int)(path + len - name), name));
+ git_path_buf(&sb_repo, "worktrees/%.*s", (int)(path + len - name), name);
len = sb_repo.len;
if (safe_create_leading_directories_const(sb_repo.buf))
die_errno(_("could not create leading directories of '%s'"),
@@ -242,7 +241,10 @@ static int add_worktree(const char *path, const char *refname,
* after the preparation is over.
*/
strbuf_addf(&sb, "%s/locked", sb_repo.buf);
- write_file(sb.buf, "initializing");
+ if (!opts->keep_locked)
+ write_file(sb.buf, "initializing");
+ else
+ write_file(sb.buf, "added with --lock");
strbuf_addf(&sb_git, "%s/.git", path);
if (safe_create_leading_directories_const(sb_git.buf))
@@ -303,9 +305,11 @@ static int add_worktree(const char *path, const char *refname,
junk_git_dir = NULL;
done:
- strbuf_reset(&sb);
- strbuf_addf(&sb, "%s/locked", sb_repo.buf);
- unlink_or_warn(sb.buf);
+ if (ret || !opts->keep_locked) {
+ strbuf_reset(&sb);
+ strbuf_addf(&sb, "%s/locked", sb_repo.buf);
+ unlink_or_warn(sb.buf);
+ }
argv_array_clear(&child_env);
strbuf_release(&sb);
strbuf_release(&symref);
@@ -328,6 +332,7 @@ static int add(int ac, const char **av, const char *prefix)
N_("create or reset a branch")),
OPT_BOOL(0, "detach", &opts.detach, N_("detach HEAD at named commit")),
OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")),
+ OPT_BOOL(0, "lock", &opts.keep_locked, N_("keep the new working tree locked")),
OPT_END()
};
@@ -409,9 +414,11 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
find_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));
if (wt->is_detached)
strbuf_addstr(&sb, "(detached HEAD)");
- else if (wt->head_ref)
- strbuf_addf(&sb, "[%s]", shorten_unambiguous_ref(wt->head_ref, 0));
- else
+ else if (wt->head_ref) {
+ char *ref = shorten_unambiguous_ref(wt->head_ref, 0);
+ strbuf_addf(&sb, "[%s]", ref);
+ free(ref);
+ } else
strbuf_addstr(&sb, "(error)");
}
printf("%s\n", sb.buf);