}
qsort(array, cnt, sizeof(*array), compare_commit_dist);
for (p = list, i = 0; i < cnt; i++) {
- struct name_decoration *r = xmalloc(sizeof(*r) + 100);
+ char buf[100]; /* enough for dist=%d */
struct object *obj = &(array[i].commit->object);
- sprintf(r->name, "dist=%d", array[i].distance);
- r->next = add_decoration(&name_decoration, obj, r);
+ snprintf(buf, sizeof(buf), "dist=%d", array[i].distance);
+ add_name_decoration(DECORATION_NONE, buf, obj);
+
p->item = array[i].commit;
p = p->next;
}
int rev_nr;
struct commit **rev = get_bad_and_good_commits(&rev_nr);
- result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1, 0);
+ result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1);
for (; result; result = result->next) {
const unsigned char *mb = result->item->object.sha1;
#include "cache.h"
#include "parse-options.h"
#include "builtin.h"
+#include "lockfile.h"
#include "run-command.h"
#include "diff.h"
#include "refs.h"
#include "remote.h"
#include "fmt-merge-msg.h"
#include "gpg-interface.h"
+#include "sequencer.h"
#define DEFAULT_TWOHEAD (1<<0)
#define DEFAULT_OCTOPUS (1<<1)
static int allow_rerere_auto;
static int abort_current_merge;
static int show_progress = -1;
-static int default_to_upstream;
+static int default_to_upstream = 1;
static const char *sign_commit;
static struct strategy all_strategy[] = {
static int save_state(unsigned char *stash)
{
int len;
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
struct strbuf buffer = STRBUF_INIT;
const char *argv[] = {"stash", "create", NULL};
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.out = -1;
cp.git_cmd = 1;
const char *argv_gc_auto[] = { "gc", "--auto", NULL };
update_ref(reflog_message.buf, "HEAD",
new_head, head, 0,
- DIE_ON_ERR);
+ UPDATE_REFS_DIE_ON_ERR);
/*
* We ignore errors in 'gc --auto', since the
* user should see them.
if (argc < 0)
die(_("Bad branch.%s.mergeoptions string: %s"), branch,
split_cmdline_strerror(argc));
- argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
+ REALLOC_ARRAY(argv, argc + 2);
memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
argc++;
argv[0] = "branch.*.mergeoptions";
struct commit_list *remoteheads,
struct commit *head, const char *head_arg)
{
- int index_fd;
- struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+ static struct lock_file lock;
- index_fd = hold_locked_index(lock, 1);
+ hold_locked_index(&lock, 1);
refresh_cache(REFRESH_QUIET);
if (active_cache_changed &&
- (write_cache(index_fd, active_cache, active_nr) ||
- commit_locked_index(lock)))
+ write_locked_index(&the_index, &lock, COMMIT_LOCK))
return error(_("Unable to write index."));
- rollback_lock_file(lock);
+ rollback_lock_file(&lock);
if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) {
int clean, x;
struct commit *result;
- struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
- int index_fd;
struct commit_list *reversed = NULL;
struct merge_options o;
struct commit_list *j;
for (j = common; j; j = j->next)
commit_list_insert(j->item, &reversed);
- index_fd = hold_locked_index(lock, 1);
+ hold_locked_index(&lock, 1);
clean = merge_recursive(&o, head,
remoteheads->item, reversed, &result);
if (active_cache_changed &&
- (write_cache(index_fd, active_cache, active_nr) ||
- commit_locked_index(lock)))
+ write_locked_index(&the_index, &lock, COMMIT_LOCK))
die (_("unable to write %s"), get_index_file());
- rollback_lock_file(lock);
+ rollback_lock_file(&lock);
return clean ? 0 : 1;
} else {
return try_merge_command(strategy, xopts_nr, xopts,
static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
{
unsigned char result_tree[20], result_commit[20];
- struct commit_list *parent = xmalloc(sizeof(*parent));
+ struct commit_list *parents, **pptr = &parents;
write_tree_trivial(result_tree);
printf(_("Wonderful.\n"));
- parent->item = head;
- parent->next = xmalloc(sizeof(*parent->next));
- parent->next->item = remoteheads->item;
- parent->next->next = NULL;
+ pptr = commit_list_append(head, pptr);
+ pptr = commit_list_append(remoteheads->item, pptr);
prepare_to_commit(remoteheads);
- if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parent,
+ if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,
result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
finish(head, remoteheads, result_commit, "In-index merge");
return 0;
}
-static int suggest_conflicts(int renormalizing)
+static int suggest_conflicts(void)
{
const char *filename;
FILE *fp;
- int pos;
+ struct strbuf msgbuf = STRBUF_INIT;
filename = git_path("MERGE_MSG");
fp = fopen(filename, "a");
if (!fp)
die_errno(_("Could not open '%s' for writing"), filename);
- fprintf(fp, "\nConflicts:\n");
- for (pos = 0; pos < active_nr; pos++) {
- const struct cache_entry *ce = active_cache[pos];
-
- if (ce_stage(ce)) {
- fprintf(fp, "\t%s\n", ce->name);
- while (pos + 1 < active_nr &&
- !strcmp(ce->name,
- active_cache[pos + 1]->name))
- pos++;
- }
- }
+
+ append_conflicts_hint(&msgbuf);
+ fputs(msgbuf.buf, fp);
fclose(fp);
rerere(allow_rerere_auto);
printf(_("Automatic merge failed; "
* Check if we are _not_ on a detached HEAD, i.e. if there is a
* current branch.
*/
- branch = branch_to_free = resolve_refdup("HEAD", head_sha1, 0, &flag);
+ branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, &flag);
if (branch && starts_with(branch, "refs/heads/"))
branch += 11;
if (!branch || is_null_sha1(head_sha1))
*/
if (advice_resolve_conflict)
die(_("You have not concluded your merge (MERGE_HEAD exists).\n"
- "Please, commit your changes before you can merge."));
+ "Please, commit your changes before you merge."));
else
die(_("You have not concluded your merge (MERGE_HEAD exists)."));
}
if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
if (advice_resolve_conflict)
die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
- "Please, commit your changes before you can merge."));
+ "Please, commit your changes before you merge."));
else
die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."));
}
die(_("%s - not something we can merge"), argv[0]);
read_empty(remote_head->object.sha1, 0);
update_ref("initial pull", "HEAD", remote_head->object.sha1,
- NULL, 0, DIE_ON_ERR);
+ NULL, 0, UPDATE_REFS_DIE_ON_ERR);
goto done;
} else {
struct strbuf merge_names = STRBUF_INIT;
printf(_("Commit %s has a good GPG signature by %s\n"),
hex, signature_check.signer);
- free(signature_check.gpg_output);
- free(signature_check.gpg_status);
- free(signature_check.signer);
- free(signature_check.key);
+ signature_check_clear(&signature_check);
}
}
if (!remoteheads)
; /* already up-to-date */
else if (!remoteheads->next)
- common = get_merge_bases(head_commit, remoteheads->item, 1);
+ common = get_merge_bases(head_commit, remoteheads->item);
else {
struct commit_list *list = remoteheads;
commit_list_insert(head_commit, &list);
}
update_ref("updating ORIG_HEAD", "ORIG_HEAD", head_commit->object.sha1,
- NULL, 0, DIE_ON_ERR);
+ NULL, 0, UPDATE_REFS_DIE_ON_ERR);
if (remoteheads && !common)
; /* No common ancestors found. We need a real merge. */
* merge_bases again, otherwise "git merge HEAD^
* HEAD^^" would be missed.
*/
- common_one = get_merge_bases(head_commit, j->item, 1);
+ common_one = get_merge_bases(head_commit, j->item);
if (hashcmp(common_one->item->object.sha1,
j->item->object.sha1)) {
up_to_date = 0;
fprintf(stderr, _("Automatic merge went well; "
"stopped before committing as requested\n"));
else
- ret = suggest_conflicts(option_renormalize);
+ ret = suggest_conflicts();
done:
free(branch_to_free);
#include "parse-options.h"
#include "diff.h"
#include "revision.h"
+#include "split-index.h"
#define DO_REVS 1
#define DO_NOREV 2
error("refname '%s' is ambiguous", name);
break;
}
+ free(full);
} else {
show_with_type(type, name);
}
struct commit *a, *b;
a = lookup_commit_reference(sha1);
b = lookup_commit_reference(end);
- exclude = get_merge_bases(a, b, 1);
+ exclude = get_merge_bases(a, b);
while (exclude) {
struct commit_list *n = exclude->next;
show_rev(REVERSED,
int has_dashdash = 0;
int output_prefix = 0;
unsigned char sha1[20];
+ unsigned int flags = 0;
const char *name = NULL;
+ struct object_context unused;
if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
}
if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) {
quiet = 1;
+ flags |= GET_SHA1_QUIETLY;
continue;
}
if (!strcmp(arg, "--short") ||
}
if (!strcmp(arg, "--git-dir")) {
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
- static char cwd[PATH_MAX];
+ char *cwd;
int len;
if (gitdir) {
puts(gitdir);
puts(".git");
continue;
}
- if (!getcwd(cwd, PATH_MAX))
- die_errno("unable to get current working directory");
+ cwd = xgetcwd();
len = strlen(cwd);
printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
+ free(cwd);
continue;
}
if (!strcmp(arg, "--resolve-git-dir")) {
: "false");
continue;
}
+ if (!strcmp(arg, "--shared-index-path")) {
+ if (read_cache() < 0)
+ die(_("Could not read the index"));
+ if (the_index.split_index) {
+ const unsigned char *sha1 = the_index.split_index->base_sha1;
+ puts(git_path("sharedindex.%s", sha1_to_hex(sha1)));
+ }
+ continue;
+ }
if (starts_with(arg, "--since=")) {
show_datestring("--max-age=", arg+8);
continue;
name++;
type = REVERSED;
}
- if (!get_sha1(name, sha1)) {
+ if (!get_sha1_with_context(name, flags, sha1, &unused)) {
if (verify)
revs_count++;
else
struct commit_list *head = NULL;
struct commit_list **pp = &head;
while (list) {
- struct commit_list *new;
- new = xmalloc(sizeof(struct commit_list));
- new->item = list->item;
- new->next = NULL;
- *pp = new;
- pp = &new->next;
+ pp = commit_list_append(list->item, pp);
list = list->next;
}
return head;
static void record_author_date(struct author_date_slab *author_date,
struct commit *commit)
{
- const char *buf, *line_end, *ident_line;
const char *buffer = get_commit_buffer(commit, NULL);
struct ident_split ident;
+ const char *ident_line;
+ size_t ident_len;
char *date_end;
unsigned long date;
- for (buf = buffer; buf; buf = line_end + 1) {
- line_end = strchrnul(buf, '\n');
- ident_line = skip_prefix(buf, "author ");
- if (!ident_line) {
- if (!line_end[0] || line_end[1] == '\n')
- return; /* end of header */
- continue;
- }
- if (split_ident_line(&ident,
- ident_line, line_end - ident_line) ||
- !ident.date_begin || !ident.date_end)
- goto fail_exit; /* malformed "author" line */
- break;
- }
+ ident_line = find_commit_header(buffer, "author", &ident_len);
+ if (!ident_line)
+ goto fail_exit; /* no author line */
+ if (split_ident_line(&ident, ident_line, ident_len) ||
+ !ident.date_begin || !ident.date_end)
+ goto fail_exit; /* malformed "author" line */
date = strtoul(ident.date_begin, &date_end, 10);
if (date_end != ident.date_end)
static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
-static struct commit *interesting(struct commit_list *list)
+static int queue_has_nonstale(struct prio_queue *queue)
{
- while (list) {
- struct commit *commit = list->item;
- list = list->next;
- if (commit->object.flags & STALE)
- continue;
- return commit;
+ int i;
+ for (i = 0; i < queue->nr; i++) {
+ struct commit *commit = queue->array[i].data;
+ if (!(commit->object.flags & STALE))
+ return 1;
}
- return NULL;
+ return 0;
}
/* all input commits in one and twos[] must have been parsed! */
static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos)
{
- struct commit_list *list = NULL;
+ struct prio_queue queue = { compare_commits_by_commit_date };
struct commit_list *result = NULL;
int i;
one->object.flags |= PARENT1;
- commit_list_insert_by_date(one, &list);
- if (!n)
- return list;
+ if (!n) {
+ commit_list_append(one, &result);
+ return result;
+ }
+ prio_queue_put(&queue, one);
+
for (i = 0; i < n; i++) {
twos[i]->object.flags |= PARENT2;
- commit_list_insert_by_date(twos[i], &list);
+ prio_queue_put(&queue, twos[i]);
}
- while (interesting(list)) {
- struct commit *commit;
+ while (queue_has_nonstale(&queue)) {
+ struct commit *commit = prio_queue_get(&queue);
struct commit_list *parents;
- struct commit_list *next;
int flags;
- commit = list->item;
- next = list->next;
- free(list);
- list = next;
-
flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
if (flags == (PARENT1 | PARENT2)) {
if (!(commit->object.flags & RESULT)) {
if (parse_commit(p))
return NULL;
p->object.flags |= flags;
- commit_list_insert_by_date(p, &list);
+ prio_queue_put(&queue, p);
}
}
- free_commit_list(list);
+ clear_prio_queue(&queue);
return result;
}
for (j = ret; j; j = j->next) {
struct commit_list *bases;
- bases = get_merge_bases(i->item, j->item, 1);
+ bases = get_merge_bases(i->item, j->item);
if (!new)
new = bases;
else
return filled;
}
- struct commit_list *get_merge_bases_many(struct commit *one,
- int n,
- struct commit **twos,
- int cleanup)
+ static struct commit_list *get_merge_bases_many_0(struct commit *one,
+ int n,
+ struct commit **twos,
+ int cleanup)
{
struct commit_list *list;
struct commit **rslt;
}
/* There are more than one */
- cnt = 0;
- list = result;
- while (list) {
- list = list->next;
- cnt++;
- }
+ cnt = commit_list_count(result);
rslt = xcalloc(cnt, sizeof(*rslt));
for (list = result, i = 0; list; list = list->next)
rslt[i++] = list->item;
return result;
}
- struct commit_list *get_merge_bases(struct commit *one, struct commit *two,
- int cleanup)
+ struct commit_list *get_merge_bases_many(struct commit *one,
+ int n,
+ struct commit **twos)
+ {
+ return get_merge_bases_many_0(one, n, twos, 1);
+ }
+
+ struct commit_list *get_merge_bases_many_dirty(struct commit *one,
+ int n,
+ struct commit **twos)
+ {
+ return get_merge_bases_many_0(one, n, twos, 0);
+ }
+
+ struct commit_list *get_merge_bases(struct commit *one, struct commit *two)
{
- return get_merge_bases_many(one, 1, &two, cleanup);
+ return get_merge_bases_many_0(one, 1, &two, 1);
}
/*
return saw_signature;
}
+int remove_signature(struct strbuf *buf)
+{
+ const char *line = buf->buf;
+ const char *tail = buf->buf + buf->len;
+ int in_signature = 0;
+ const char *sig_start = NULL;
+ const char *sig_end = NULL;
+
+ while (line < tail) {
+ const char *next = memchr(line, '\n', tail - line);
+ next = next ? next + 1 : tail;
+
+ if (in_signature && line[0] == ' ')
+ sig_end = next;
+ else if (starts_with(line, gpg_sig_header) &&
+ line[gpg_sig_header_len] == ' ') {
+ sig_start = line;
+ sig_end = next;
+ in_signature = 1;
+ } else {
+ if (*line == '\n')
+ /* dump the whole remainder of the buffer */
+ next = tail;
+ in_signature = 0;
+ }
+ line = next;
+ }
+
+ if (sig_start)
+ strbuf_remove(buf, sig_start - buf->buf, sig_end - sig_start);
+
+ return sig_start != NULL;
+}
+
static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
{
struct merge_remote_desc *desc;
free(buf);
}
-static struct {
- char result;
- const char *check;
-} sigcheck_gpg_status[] = {
- { 'G', "\n[GNUPG:] GOODSIG " },
- { 'B', "\n[GNUPG:] BADSIG " },
- { 'U', "\n[GNUPG:] TRUST_NEVER" },
- { 'U', "\n[GNUPG:] TRUST_UNDEFINED" },
-};
-
-static void parse_gpg_output(struct signature_check *sigc)
-{
- const char *buf = sigc->gpg_status;
- int i;
-
- /* Iterate over all search strings */
- for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) {
- const char *found, *next;
-
- found = skip_prefix(buf, sigcheck_gpg_status[i].check + 1);
- if (!found) {
- found = strstr(buf, sigcheck_gpg_status[i].check);
- if (!found)
- continue;
- found += strlen(sigcheck_gpg_status[i].check);
- }
- sigc->result = sigcheck_gpg_status[i].result;
- /* The trust messages are not followed by key/signer information */
- if (sigc->result != 'U') {
- sigc->key = xmemdupz(found, 16);
- found += 17;
- next = strchrnul(found, '\n');
- sigc->signer = xmemdupz(found, next - found);
- }
- }
-}
-
-void check_commit_signature(const struct commit* commit, struct signature_check *sigc)
+void check_commit_signature(const struct commit *commit, struct signature_check *sigc)
{
struct strbuf payload = STRBUF_INIT;
struct strbuf signature = STRBUF_INIT;
&gpg_output, &gpg_status);
if (status && !gpg_output.len)
goto out;
+ sigc->payload = strbuf_detach(&payload, NULL);
sigc->gpg_output = strbuf_detach(&gpg_output, NULL);
sigc->gpg_status = strbuf_detach(&gpg_status, NULL);
parse_gpg_output(sigc);
return extra;
}
+void for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data)
+{
+ struct commit_extra_header *extra, *to_free;
+
+ to_free = read_commit_extra_headers(commit, NULL);
+ for (extra = to_free; extra; extra = extra->next) {
+ if (strcmp(extra->key, "mergetag"))
+ continue; /* not a merge tag */
+ fn(commit, extra, data);
+ }
+ free_commit_extra_headers(to_free);
+}
+
static inline int standard_header_field(const char *field, size_t len)
{
return ((len == 4 && !memcmp(field, "tree ", 5)) ||
printf(format, sha1_to_hex(list->item->object.sha1));
}
}
+
+const char *find_commit_header(const char *msg, const char *key, size_t *out_len)
+{
+ int key_len = strlen(key);
+ const char *line = msg;
+
+ while (line) {
+ const char *eol = strchrnul(line, '\n');
+
+ if (line == eol)
+ return NULL;
+
+ if (eol - line > key_len &&
+ !strncmp(line, key, key_len) &&
+ line[key_len] == ' ') {
+ *out_len = eol - line - key_len - 1;
+ return line + key_len + 1;
+ }
+ line = *eol ? eol + 1 : NULL;
+ }
+ return NULL;
+}
+
+/*
+ * Inspect sb and determine the true "end" of the log message, in
+ * order to find where to put a new Signed-off-by: line. Ignored are
+ * trailing comment lines and blank lines, and also the traditional
+ * "Conflicts:" block that is not commented out, so that we can use
+ * "git commit -s --amend" on an existing commit that forgot to remove
+ * it.
+ *
+ * Returns the number of bytes from the tail to ignore, to be fed as
+ * the second parameter to append_signoff().
+ */
+int ignore_non_trailer(struct strbuf *sb)
+{
+ int boc = 0;
+ int bol = 0;
+ int in_old_conflicts_block = 0;
+
+ while (bol < sb->len) {
+ char *next_line;
+
+ if (!(next_line = memchr(sb->buf + bol, '\n', sb->len - bol)))
+ next_line = sb->buf + sb->len;
+ else
+ next_line++;
+
+ if (sb->buf[bol] == comment_line_char || sb->buf[bol] == '\n') {
+ /* is this the first of the run of comments? */
+ if (!boc)
+ boc = bol;
+ /* otherwise, it is just continuing */
+ } else if (starts_with(sb->buf + bol, "Conflicts:\n")) {
+ in_old_conflicts_block = 1;
+ if (!boc)
+ boc = bol;
+ } else if (in_old_conflicts_block && sb->buf[bol] == '\t') {
+ ; /* a pathname in the conflicts block */
+ } else if (boc) {
+ /* the previous was not trailing comment */
+ boc = 0;
+ in_old_conflicts_block = 0;
+ }
+ bol = next_line - sb->buf;
+ }
+ return boc ? sb->len - boc : 0;
+}
extern const char *commit_type;
/* While we can decorate any object with a name, it's only used for commits.. */
-extern struct decoration name_decoration;
struct name_decoration {
struct name_decoration *next;
int type;
- char name[1];
+ char name[FLEX_ARRAY];
};
+enum decoration_type {
+ DECORATION_NONE = 0,
+ DECORATION_REF_LOCAL,
+ DECORATION_REF_REMOTE,
+ DECORATION_REF_TAG,
+ DECORATION_REF_STASH,
+ DECORATION_REF_HEAD,
+ DECORATION_GRAFTED,
+};
+
+void add_name_decoration(enum decoration_type type, const char *name, struct object *obj);
+const struct name_decoration *get_name_decoration(const struct object *obj);
+
struct commit *lookup_commit(const unsigned char *sha1);
struct commit *lookup_commit_reference(const unsigned char *sha1);
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
extern const char *format_subject(struct strbuf *sb, const char *msg,
const char *line_separator);
extern void userformat_find_requirements(const char *fmt, struct userformat_want *w);
+extern int commit_format_is_empty(enum cmit_fmt);
extern void format_commit_message(const struct commit *commit,
const char *format, struct strbuf *sb,
const struct pretty_print_context *context);
int register_commit_graft(struct commit_graft *, int);
struct commit_graft *lookup_commit_graft(const unsigned char *sha1);
- extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
- extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
+ extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2);
+ extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos);
extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
+ /* To be used only when object flags after this call no longer matter */
+ extern struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);
+
/* largest positive number a signed 32-bit integer can contain */
#define INFINITE_DEPTH 0x7fffffff
int *ref_status);
extern int delayed_reachability_test(struct shallow_info *si, int c);
extern void prune_shallow(int show_only);
+extern struct trace_key trace_shallow;
int is_descendant_of(struct commit *, struct commit_list *);
int in_merge_bases(struct commit *, struct commit *);
extern void free_commit_extra_headers(struct commit_extra_header *extra);
+/*
+ * Search the commit object contents given by "msg" for the header "key".
+ * Returns a pointer to the start of the header contents, or NULL. The length
+ * of the header, up to the first newline, is returned via out_len.
+ *
+ * Note that some headers (like mergetag) may be multi-line. It is the caller's
+ * responsibility to parse further in this case!
+ */
+extern const char *find_commit_header(const char *msg, const char *key,
+ size_t *out_len);
+
+/* Find the end of the log message, the right place for a new trailer. */
+extern int ignore_non_trailer(struct strbuf *sb);
+
+typedef void (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra,
+ void *cb_data);
+
+extern void for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data);
+
struct merge_remote_desc {
struct object *obj; /* the named object, could be a tag */
const char *name;
extern int parse_signed_commit(const struct commit *commit,
struct strbuf *message, struct strbuf *signature);
+extern int remove_signature(struct strbuf *buf);
+
extern void print_commit_list(struct commit_list *list,
const char *format_cur,
const char *format_last);
* at all. This may allocate memory for sig->gpg_output, sig->gpg_status,
* sig->signer and sig->key.
*/
-extern void check_commit_signature(const struct commit* commit, struct signature_check *sigc);
+extern void check_commit_signature(const struct commit *commit, struct signature_check *sigc);
int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);
* Fredrik Kuivinen.
* The thieves were Alex Riesen and Johannes Schindelin, in June/July 2006
*/
-#include "advice.h"
#include "cache.h"
+#include "advice.h"
+#include "lockfile.h"
#include "cache-tree.h"
#include "commit.h"
#include "blob.h"
if (!show(o, v))
return;
- strbuf_grow(&o->obuf, o->call_depth * 2 + 2);
- memset(o->obuf.buf + o->obuf.len, ' ', o->call_depth * 2);
- strbuf_setlen(&o->obuf, o->obuf.len + o->call_depth * 2);
+ strbuf_addchars(&o->obuf, ' ', o->call_depth * 2);
va_start(ap, fmt);
strbuf_vaddf(&o->obuf, fmt, ap);
va_end(ap);
- strbuf_add(&o->obuf, "\n", 1);
+ strbuf_addch(&o->obuf, '\n');
if (!o->buffer_output)
flush_output(o);
}
active_cache_tree = cache_tree();
if (!cache_tree_fully_valid(active_cache_tree) &&
- cache_tree_update(active_cache_tree,
- (const struct cache_entry * const *)active_cache,
- active_nr, 0) < 0)
+ cache_tree_update(&the_index, 0) < 0)
die(_("error building trees"));
result = lookup_tree(active_cache_tree->sha1);
}
static int save_files_dirs(const unsigned char *sha1,
- const char *base, int baselen, const char *path,
+ struct strbuf *base, const char *path,
unsigned int mode, int stage, void *context)
{
- int len = strlen(path);
- char *newpath = xmalloc(baselen + len + 1);
+ int baselen = base->len;
struct merge_options *o = context;
- memcpy(newpath, base, baselen);
- memcpy(newpath + baselen, path, len);
- newpath[baselen + len] = '\0';
+ strbuf_addstr(base, path);
if (S_ISDIR(mode))
- string_list_insert(&o->current_directory_set, newpath);
+ string_list_insert(&o->current_directory_set, base->buf);
else
- string_list_insert(&o->current_file_set, newpath);
- free(newpath);
+ string_list_insert(&o->current_file_set, base->buf);
+ strbuf_setlen(base, baselen);
return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
}
return 0;
}
+/* add a string to a strbuf, but converting "/" to "_" */
+static void add_flattened_path(struct strbuf *out, const char *s)
+{
+ size_t i = out->len;
+ strbuf_addstr(out, s);
+ for (; i < out->len; i++)
+ if (out->buf[i] == '/')
+ out->buf[i] = '_';
+}
+
static char *unique_path(struct merge_options *o, const char *path, const char *branch)
{
- char *newpath = xmalloc(strlen(path) + 1 + strlen(branch) + 8 + 1);
+ struct strbuf newpath = STRBUF_INIT;
int suffix = 0;
struct stat st;
- char *p = newpath + strlen(path);
- strcpy(newpath, path);
- *(p++) = '~';
- strcpy(p, branch);
- for (; *p; ++p)
- if ('/' == *p)
- *p = '_';
- while (string_list_has_string(&o->current_file_set, newpath) ||
- string_list_has_string(&o->current_directory_set, newpath) ||
- lstat(newpath, &st) == 0)
- sprintf(p, "_%d", suffix++);
-
- string_list_insert(&o->current_file_set, newpath);
- return newpath;
+ size_t base_len;
+
+ strbuf_addf(&newpath, "%s~", path);
+ add_flattened_path(&newpath, branch);
+
+ base_len = newpath.len;
+ while (string_list_has_string(&o->current_file_set, newpath.buf) ||
+ string_list_has_string(&o->current_directory_set, newpath.buf) ||
+ lstat(newpath.buf, &st) == 0) {
+ strbuf_setlen(&newpath, base_len);
+ strbuf_addf(&newpath, "_%d", suffix++);
+ }
+
+ string_list_insert(&o->current_file_set, newpath.buf);
+ return strbuf_detach(&newpath, NULL);
}
static int dir_in_way(const char *path, int check_working_copy)
char *side2 = NULL;
struct merge_file_info mfi;
- if (filename1) {
- side1 = xmalloc(strlen(branch1) + strlen(filename1) + 2);
- sprintf(side1, "%s:%s", branch1, filename1);
- }
- if (filename2) {
- side2 = xmalloc(strlen(branch2) + strlen(filename2) + 2);
- sprintf(side2, "%s:%s", branch2, filename2);
- }
+ if (filename1)
+ side1 = xstrfmt("%s:%s", branch1, filename1);
+ if (filename2)
+ side2 = xstrfmt("%s:%s", branch2, filename2);
mfi = merge_file_1(o, one, a, b,
side1 ? side1 : branch1, side2 ? side2 : branch2);
* unchanged since their sha1s have already been compared.
*/
if (renormalize_buffer(path, o.buf, o.len, &o) |
- renormalize_buffer(path, a.buf, o.len, &a))
+ renormalize_buffer(path, a.buf, a.len, &a))
ret = (o.len == a.len && !memcmp(o.buf, a.buf, o.len));
error_return:
static int process_entry(struct merge_options *o,
const char *path, struct stage_data *entry)
{
- /*
- printf("processing entry, clean cache: %s\n", index_only ? "yes": "no");
- print_index_entry("\tpath: ", entry);
- */
int clean_merge = 1;
int normalize = o->renormalize;
unsigned o_mode = entry->stages[1].mode;
}
if (!ca) {
- ca = get_merge_bases(h1, h2, 1);
+ ca = get_merge_bases(h1, h2);
ca = reverse_commit_list(ca);
}
const unsigned char **base_list,
struct commit **result)
{
- int clean, index_fd;
+ int clean;
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
struct commit *head_commit = get_ref(head, o->branch1);
struct commit *next_commit = get_ref(merge, o->branch2);
}
}
- index_fd = hold_locked_index(lock, 1);
+ hold_locked_index(lock, 1);
clean = merge_recursive(o, head_commit, next_commit, ca,
result);
if (active_cache_changed &&
- (write_cache(index_fd, active_cache, active_nr) ||
- commit_locked_index(lock)))
+ write_locked_index(&the_index, lock, COMMIT_LOCK))
return error(_("Unable to write index."));
return clean ? 0 : 1;
}
-static int merge_recursive_config(const char *var, const char *value, void *cb)
+static void merge_recursive_config(struct merge_options *o)
{
- struct merge_options *o = cb;
- if (!strcmp(var, "merge.verbosity")) {
- o->verbosity = git_config_int(var, value);
- return 0;
- }
- if (!strcmp(var, "diff.renamelimit")) {
- o->diff_rename_limit = git_config_int(var, value);
- return 0;
- }
- if (!strcmp(var, "merge.renamelimit")) {
- o->merge_rename_limit = git_config_int(var, value);
- return 0;
- }
- return git_xmerge_config(var, value, cb);
+ git_config_get_int("merge.verbosity", &o->verbosity);
+ git_config_get_int("diff.renamelimit", &o->diff_rename_limit);
+ git_config_get_int("merge.renamelimit", &o->merge_rename_limit);
+ git_config(git_xmerge_config, NULL);
}
void init_merge_options(struct merge_options *o)
o->diff_rename_limit = -1;
o->merge_rename_limit = -1;
o->renormalize = 0;
- git_config(merge_recursive_config, o);
+ merge_recursive_config(o);
if (getenv("GIT_MERGE_VERBOSITY"))
o->verbosity =
strtol(getenv("GIT_MERGE_VERBOSITY"), NULL, 10);
if (o->verbosity >= 5)
o->buffer_output = 0;
strbuf_init(&o->obuf, 0);
- memset(&o->current_file_set, 0, sizeof(struct string_list));
- o->current_file_set.strdup_strings = 1;
- memset(&o->current_directory_set, 0, sizeof(struct string_list));
- o->current_directory_set.strdup_strings = 1;
- memset(&o->df_conflict_file_set, 0, sizeof(struct string_list));
- o->df_conflict_file_set.strdup_strings = 1;
+ string_list_init(&o->current_file_set, 1);
+ string_list_init(&o->current_directory_set, 1);
+ string_list_init(&o->df_conflict_file_set, 1);
}
int parse_merge_opt(struct merge_options *o, const char *s)
{
+ const char *arg;
+
if (!s || !*s)
return -1;
if (!strcmp(s, "ours"))
o->recursive_variant = MERGE_RECURSIVE_THEIRS;
else if (!strcmp(s, "subtree"))
o->subtree_shift = "";
- else if (starts_with(s, "subtree="))
- o->subtree_shift = s + strlen("subtree=");
+ else if (skip_prefix(s, "subtree=", &arg))
+ o->subtree_shift = arg;
else if (!strcmp(s, "patience"))
o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
else if (!strcmp(s, "histogram"))
o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
- else if (starts_with(s, "diff-algorithm=")) {
- long value = parse_algorithm_value(s + strlen("diff-algorithm="));
+ else if (skip_prefix(s, "diff-algorithm=", &arg)) {
+ long value = parse_algorithm_value(arg);
if (value < 0)
return -1;
/* clear out previous settings */
o->renormalize = 1;
else if (!strcmp(s, "no-renormalize"))
o->renormalize = 0;
- else if (starts_with(s, "rename-threshold=")) {
- const char *score = s + strlen("rename-threshold=");
- if ((o->rename_score = parse_rename_score(&score)) == -1 || *score != 0)
+ else if (skip_prefix(s, "rename-threshold=", &arg)) {
+ if ((o->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0)
return -1;
}
else
o->local_ref, o->remote_ref);
/* Dereference o->local_ref into local_sha1 */
- if (read_ref_full(o->local_ref, local_sha1, 0, NULL))
+ if (read_ref_full(o->local_ref, 0, local_sha1, NULL))
die("Failed to resolve local notes ref '%s'", o->local_ref);
else if (!check_refname_format(o->local_ref, 0) &&
is_null_sha1(local_sha1))
assert(local && remote);
/* Find merge bases */
- bases = get_merge_bases(local, remote, 1);
+ bases = get_merge_bases(local, remote);
if (!bases) {
base_sha1 = null_sha1;
base_tree_sha1 = EMPTY_TREE_SHA1_BIN;
#include "mailmap.h"
#include "commit-slab.h"
#include "dir.h"
+#include "cache-tree.h"
volatile show_early_output_fn_t show_early_output;
fputc('\n', out);
}
-void add_object(struct object *obj,
- struct object_array *p,
- struct name_path *path,
- const char *name)
-{
- char *pn = path_name(path, name);
- add_object_array(obj, pn, p);
- free(pn);
-}
-
static void mark_blob_uninteresting(struct blob *blob)
{
if (!blob)
}
}
-static void add_pending_object_with_mode(struct rev_info *revs,
+static void add_pending_object_with_path(struct rev_info *revs,
struct object *obj,
- const char *name, unsigned mode)
+ const char *name, unsigned mode,
+ const char *path)
{
if (!obj)
return;
if (st)
return;
}
- add_object_array_with_mode(obj, name, &revs->pending, mode);
+ add_object_array_with_path(obj, name, &revs->pending, mode, path);
+}
+
+static void add_pending_object_with_mode(struct rev_info *revs,
+ struct object *obj,
+ const char *name, unsigned mode)
+{
+ add_pending_object_with_path(revs, obj, name, mode, NULL);
}
void add_pending_object(struct rev_info *revs,
}
static struct commit *handle_commit(struct rev_info *revs,
- struct object *object, const char *name)
+ struct object_array_entry *entry)
{
+ struct object *object = entry->item;
+ const char *name = entry->name;
+ const char *path = entry->path;
+ unsigned int mode = entry->mode;
unsigned long flags = object->flags;
/*
die("bad object %s", sha1_to_hex(tag->tagged->sha1));
}
object->flags |= flags;
+ /*
+ * We'll handle the tagged object by looping or dropping
+ * through to the non-tag handlers below. Do not
+ * propagate data from the tag's pending entry.
+ */
+ name = "";
+ path = NULL;
+ mode = 0;
}
/*
revs->limited = 1;
}
if (revs->show_source && !commit->util)
- commit->util = (void *) name;
+ commit->util = xstrdup(name);
return commit;
}
mark_tree_contents_uninteresting(tree);
return NULL;
}
- add_pending_object(revs, object, "");
+ add_pending_object_with_path(revs, object, name, mode, path);
return NULL;
}
return NULL;
if (flags & UNINTERESTING)
return NULL;
- add_pending_object(revs, object, "");
+ add_pending_object_with_path(revs, object, name, mode, path);
return NULL;
}
die("%s is unknown object", name);
* If we are simplifying by decoration, then the commit
* is worth showing if it has a tag pointing at it.
*/
- if (lookup_decoration(&name_decoration, &commit->object))
+ if (get_name_decoration(&commit->object))
return REV_TREE_DIFFERENT;
/*
* A commit that is not pointed by a tag is uninteresting
return 0;
}
-static void handle_reflog(struct rev_info *revs, unsigned flags)
+void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
{
struct all_refs_cb cb;
cb.all_revs = revs;
for_each_reflog(handle_one_reflog, &cb);
}
+static void add_cache_tree(struct cache_tree *it, struct rev_info *revs,
+ struct strbuf *path)
+{
+ size_t baselen = path->len;
+ int i;
+
+ if (it->entry_count >= 0) {
+ struct tree *tree = lookup_tree(it->sha1);
+ add_pending_object_with_path(revs, &tree->object, "",
+ 040000, path->buf);
+ }
+
+ for (i = 0; i < it->subtree_nr; i++) {
+ struct cache_tree_sub *sub = it->down[i];
+ strbuf_addf(path, "%s%s", baselen ? "/" : "", sub->name);
+ add_cache_tree(sub->cache_tree, revs, path);
+ strbuf_setlen(path, baselen);
+ }
+
+}
+
+void add_index_objects_to_pending(struct rev_info *revs, unsigned flags)
+{
+ int i;
+
+ read_cache();
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+ struct blob *blob;
+
+ if (S_ISGITLINK(ce->ce_mode))
+ continue;
+
+ blob = lookup_blob(ce->sha1);
+ if (!blob)
+ die("unable to add index blob to traversal");
+ add_pending_object_with_path(revs, &blob->object, "",
+ ce->ce_mode, ce->name);
+ }
+
+ if (active_cache_tree) {
+ struct strbuf path = STRBUF_INIT;
+ add_cache_tree(active_cache_tree, revs, &path);
+ strbuf_release(&path);
+ }
+}
+
static int add_parents_only(struct rev_info *revs, const char *arg_, int flags)
{
unsigned char sha1[20];
other = lookup_commit_or_die(sha1, "MERGE_HEAD");
add_pending_object(revs, &head->object, "HEAD");
add_pending_object(revs, &other->object, "MERGE_HEAD");
- bases = get_merge_bases(head, other, 1);
+ bases = get_merge_bases(head, other);
add_rev_cmdline_list(revs, bases, REV_CMD_MERGE_BASE, UNINTERESTING | BOTTOM);
add_pending_commit_list(revs, bases, UNINTERESTING | BOTTOM);
free_commit_list(bases);
continue;
if (ce_path_match(ce, &revs->prune_data, NULL)) {
prune_num++;
- prune = xrealloc(prune, sizeof(*prune) * prune_num);
+ REALLOC_ARRAY(prune, prune_num);
prune[prune_num-2] = ce->name;
prune[prune_num-1] = NULL;
}
: lookup_commit_reference(b_obj->sha1));
if (!a || !b)
goto missing;
- exclude = get_merge_bases(a, b, 1);
+ exclude = get_merge_bases(a, b);
add_rev_cmdline_list(revs, exclude,
REV_CMD_MERGE_BASE,
flags_exclude);
!strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
!strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
!strcmp(arg, "--bisect") || starts_with(arg, "--glob=") ||
+ !strcmp(arg, "--indexed-objects") ||
starts_with(arg, "--exclude=") ||
starts_with(arg, "--branches=") || starts_with(arg, "--tags=") ||
starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk="))
} else if (!strcmp(arg, "--pretty")) {
revs->verbose_header = 1;
revs->pretty_given = 1;
- get_commit_format(arg+8, revs);
+ get_commit_format(NULL, revs);
} else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) {
/*
* Detached form ("--pretty X" as opposed to "--pretty=X")
for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
clear_ref_exclusion(&revs->ref_excludes);
} else if (!strcmp(arg, "--reflog")) {
- handle_reflog(revs, *flags);
+ add_reflogs_to_pending(revs, *flags);
+ } else if (!strcmp(arg, "--indexed-objects")) {
+ add_index_objects_to_pending(revs, *flags);
} else if (!strcmp(arg, "--not")) {
*flags ^= UNINTERESTING | BOTTOM;
} else if (!strcmp(arg, "--no-walk")) {
int prepare_revision_walk(struct rev_info *revs)
{
- int nr = revs->pending.nr;
- struct object_array_entry *e, *list;
+ int i;
+ struct object_array old_pending;
struct commit_list **next = &revs->commits;
- e = list = revs->pending.objects;
+ memcpy(&old_pending, &revs->pending, sizeof(old_pending));
revs->pending.nr = 0;
revs->pending.alloc = 0;
revs->pending.objects = NULL;
- while (--nr >= 0) {
- struct commit *commit = handle_commit(revs, e->item, e->name);
+ for (i = 0; i < old_pending.nr; i++) {
+ struct object_array_entry *e = old_pending.objects + i;
+ struct commit *commit = handle_commit(revs, e);
if (commit) {
if (!(commit->object.flags & SEEN)) {
commit->object.flags |= SEEN;
next = commit_list_append(commit, next);
}
}
- e++;
}
if (!revs->leak_pending)
- free(list);
+ object_array_clear(&old_pending);
/* Signal whether we need per-parent treesame decoration */
if (revs->simplify_merges ||
int status, exists;
static char hex[41];
- exists = has_sha1_file(sha1);
memcpy(hex, sha1_to_hex(sha1), 40);
if (len == 40 || !len)
return hex;
+ exists = has_sha1_file(sha1);
while (len < 40) {
unsigned char sha1_ret[20];
status = get_short_sha1(hex, len, sha1_ret, GET_SHA1_QUIETLY);
static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf);
-static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
+static int get_sha1_basic(const char *str, int len, unsigned char *sha1,
+ unsigned int flags)
{
static const char *warn_msg = "refname '%.*s' is ambiguous.";
static const char *object_name_msg = N_(
if (!refs_found)
return -1;
- if (warn_ambiguous_refs &&
+ if (warn_ambiguous_refs && !(flags & GET_SHA1_QUIETLY) &&
(refs_found > 1 ||
!get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))
warning(warn_msg, len, str);
char *tmp = xstrndup(str + at + 2, reflog_len);
at_time = approxidate_careful(tmp, &errors);
free(tmp);
- if (errors)
+ if (errors) {
+ free(real_ref);
return -1;
+ }
}
- if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
+ if (read_ref_at(real_ref, flags, at_time, nth, sha1, NULL,
&co_time, &co_tz, &co_cnt)) {
if (!len) {
if (starts_with(real_ref, "refs/heads/")) {
len = 4;
}
}
- if (at_time)
- warning("Log for '%.*s' only goes "
- "back to %s.", len, str,
- show_date(co_time, co_tz, DATE_RFC2822));
- else {
+ if (at_time) {
+ if (!(flags & GET_SHA1_QUIETLY)) {
+ warning("Log for '%.*s' only goes "
+ "back to %s.", len, str,
+ show_date(co_time, co_tz, DATE_RFC2822));
+ }
+ } else {
+ if (flags & GET_SHA1_QUIETLY) {
+ exit(128);
+ }
die("Log for '%.*s' only has %d entries.",
len, str, co_cnt);
}
if (!ret)
return 0;
- ret = get_sha1_basic(name, len, sha1);
+ ret = get_sha1_basic(name, len, sha1, lookup_flags);
if (!ret)
return 0;
}
if (object->type != OBJ_COMMIT)
return 0;
- commit_list_insert_by_date((struct commit *)object, list);
+ commit_list_insert((struct commit *)object, list);
return 0;
}
const char *match = NULL, *target = NULL;
size_t len;
- if (starts_with(message, "checkout: moving from ")) {
- match = message + strlen("checkout: moving from ");
+ if (skip_prefix(message, "checkout: moving from ", &match))
target = strstr(match, " to ");
- }
if (!match || !target)
return 0;
retval = 0;
if (0 < for_each_reflog_ent_reverse("HEAD", grab_nth_branch_switch, &cb)) {
strbuf_reset(buf);
- strbuf_add(buf, cb.buf.buf, cb.buf.len);
+ strbuf_addbuf(buf, &cb.buf);
retval = brace - name + 1;
}
two = lookup_commit_reference_gently(sha1_tmp, 0);
if (!two)
return -1;
- mbs = get_merge_bases(one, two, 1);
+ mbs = get_merge_bases(one, two);
if (!mbs || mbs->next)
st = -1;
else {
die("Path '%s' exists on disk, but not in '%.*s'.",
filename, object_name_len, object_name);
if (errno == ENOENT || errno == ENOTDIR) {
- char *fullname = xmalloc(strlen(filename)
- + strlen(prefix) + 1);
- strcpy(fullname, prefix);
- strcat(fullname, filename);
+ char *fullname = xstrfmt("%s%s", prefix, filename);
if (!get_tree_entry(tree_sha1, fullname,
sha1, &mode)) {
if (!only_to_die && namelen > 2 && name[1] == '/') {
struct commit_list *list = NULL;
for_each_ref(handle_one_ref, &list);
+ commit_list_sort_by_date(&list);
return get_sha1_oneline(name + 2, sha1, list);
}
if (namelen < 3 ||
left->object.flags |= SYMMETRIC_LEFT;
add_pending_object(rev, &left->object, path);
add_pending_object(rev, &right->object, path);
- merge_bases = get_merge_bases(left, right, 1);
+ merge_bases = get_merge_bases(left, right);
if (merge_bases) {
if (merge_bases->item == left)
*fast_forward = 1;
return 0;
if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
const char *argv[] = {"rev-list", NULL, "--not", "--remotes", "-n", "1" , NULL};
struct strbuf buf = STRBUF_INIT;
int needs_pushing = 0;
argv[1] = sha1_to_hex(sha1);
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = local_repo_env;
cp.git_cmd = 1;
return 1;
if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
const char *argv[] = {"push", NULL};
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = local_repo_env;
cp.git_cmd = 1;
int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)
{
int i, ret = 1;
- struct string_list needs_pushing;
-
- memset(&needs_pushing, 0, sizeof(struct string_list));
- needs_pushing.strdup_strings = 1;
+ struct string_list needs_pushing = STRING_LIST_INIT_DUP;
if (!find_unpushed_submodules(new_sha1, remotes_name, &needs_pushing))
return 1;
if (!add_submodule_odb(path) && lookup_commit_reference(sha1)) {
/* Even if the submodule is checked out and the commit is
* present, make sure it is reachable from a ref. */
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
const char *argv[] = {"rev-list", "-n", "1", NULL, "--not", "--all", NULL};
struct strbuf buf = STRBUF_INIT;
argv[3] = sha1_to_hex(sha1);
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = local_repo_env;
cp.git_cmd = 1;
int quiet)
{
int i, result = 0;
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
struct argv_array argv = ARGV_ARRAY_INIT;
struct string_list_item *name_for_path;
const char *work_tree = get_git_work_tree();
argv_array_push(&argv, "--recurse-submodules-default");
/* default value, "--submodule-prefix" and its value are added later */
- memset(&cp, 0, sizeof(cp));
cp.env = local_repo_env;
cp.git_cmd = 1;
cp.no_stdin = 1;
unsigned is_submodule_modified(const char *path, int ignore_untracked)
{
ssize_t len;
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
const char *argv[] = {
"status",
"--porcelain",
if (ignore_untracked)
argv[2] = "-uno";
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = local_repo_env;
cp.git_cmd = 1;
int submodule_uses_gitfile(const char *path)
{
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
const char *argv[] = {
"submodule",
"foreach",
strbuf_release(&buf);
/* Now test that all nested submodules use a gitfile too */
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = local_repo_env;
cp.git_cmd = 1;
{
struct stat st;
ssize_t len;
- struct child_process cp;
+ struct child_process cp = CHILD_PROCESS_INIT;
const char *argv[] = {
"status",
"--porcelain",
if (!submodule_uses_gitfile(path))
return 0;
- memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = local_repo_env;
cp.git_cmd = 1;
sha1_to_hex(a->object.sha1));
init_revisions(&revs, NULL);
rev_opts.submodule = path;
- setup_revisions(sizeof(rev_args)/sizeof(char *)-1, rev_args, &revs, &rev_opts);
+ setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts);
/* save all revisions from the above list that contain b */
if (prepare_revision_walk(&revs))