Code simplification.
* rs/pop-commit:
use pop_commit() for consuming the first entry of a struct commit_list
#include "builtin.h"
#include "cache.h"
+#include "refs.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
static void find_merge_parents(struct merge_parents *result,
struct strbuf *in, unsigned char *head)
{
- struct commit_list *parents, *next;
+ struct commit_list *parents;
struct commit *head_commit;
int pos = 0, i, j;
parents = reduce_heads(parents);
while (parents) {
+ struct commit *cmit = pop_commit(&parents);
for (i = 0; i < result->nr; i++)
- if (!hashcmp(result->item[i].commit,
- parents->item->object.sha1))
+ if (!hashcmp(result->item[i].commit, cmit->object.sha1))
result->item[i].used = 1;
- next = parents->next;
- free(parents);
- parents = next;
}
for (i = j = 0; i < result->nr; i++) {
/* Cleans up metadata that is uninteresting after a succeeded merge. */
static void drop_save(void)
{
- unlink(git_path("MERGE_HEAD"));
- unlink(git_path("MERGE_MSG"));
- unlink(git_path("MERGE_MODE"));
+ unlink(git_path_merge_head());
+ unlink(git_path_merge_msg());
+ unlink(git_path_merge_mode());
}
static int save_state(unsigned char *stash)
struct pretty_print_context ctx = {0};
printf(_("Squash commit -- not updating HEAD\n"));
- filename = git_path("SQUASH_MSG");
+ filename = git_path_squash_msg();
fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not write to '%s'"), filename);
static void write_merge_msg(struct strbuf *msg)
{
- const char *filename = git_path("MERGE_MSG");
+ const char *filename = git_path_merge_msg();
int fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"),
static void read_merge_msg(struct strbuf *msg)
{
- const char *filename = git_path("MERGE_MSG");
+ const char *filename = git_path_merge_msg();
strbuf_reset(msg);
if (strbuf_read_file(msg, filename, 0) < 0)
die_errno(_("Could not read from '%s'"), filename);
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
write_merge_msg(&msg);
if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
- git_path("MERGE_MSG"), "merge", NULL))
+ git_path_merge_msg(), "merge", NULL))
abort_commit(remoteheads, NULL);
if (0 < option_edit) {
- if (launch_editor(git_path("MERGE_MSG"), NULL, NULL))
+ if (launch_editor(git_path_merge_msg(), NULL, NULL))
abort_commit(remoteheads, NULL);
}
read_merge_msg(&msg);
- stripspace(&msg, 0 < option_edit);
+ strbuf_stripspace(&msg, 0 < option_edit);
if (!msg.len)
abort_commit(remoteheads, _("Empty commit message."));
strbuf_release(&merge_msg);
FILE *fp;
struct strbuf msgbuf = STRBUF_INIT;
- filename = git_path("MERGE_MSG");
+ filename = git_path_merge_msg();
fp = fopen(filename, "a");
if (!fp)
die_errno(_("Could not open '%s' for writing"), filename);
}
strbuf_addf(&buf, "%s\n", sha1_to_hex(sha1));
}
- filename = git_path("MERGE_HEAD");
+ filename = git_path_merge_head();
fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"), filename);
strbuf_addch(&merge_msg, '\n');
write_merge_msg(&merge_msg);
- filename = git_path("MERGE_MODE");
+ filename = git_path_merge_mode();
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"), filename);
int *head_subsumed,
struct commit_list *remoteheads)
{
- struct commit_list *parents, *next, **remotes = &remoteheads;
+ struct commit_list *parents, **remotes;
/*
* Is the current HEAD reachable from another commit being
/* Find what parents to record by checking independent ones. */
parents = reduce_heads(remoteheads);
- for (remoteheads = NULL, remotes = &remoteheads;
- parents;
- parents = next) {
- struct commit *commit = parents->item;
- next = parents->next;
+ remoteheads = NULL;
+ remotes = &remoteheads;
+ while (parents) {
+ struct commit *commit = pop_commit(&parents);
if (commit == head_commit)
*head_subsumed = 0;
else
remotes = &commit_list_insert(commit, remotes)->next;
- free(parents);
}
return remoteheads;
}
if (!merge_names)
merge_names = &fetch_head_file;
- filename = git_path("FETCH_HEAD");
+ filename = git_path_fetch_head();
fd = open(filename, O_RDONLY);
if (fd < 0)
die_errno(_("could not open '%s' for reading"), filename);
int nargc = 2;
const char *nargv[] = {"reset", "--merge", NULL};
- if (!file_exists(git_path("MERGE_HEAD")))
+ if (!file_exists(git_path_merge_head()))
die(_("There is no merge to abort (MERGE_HEAD missing)."));
/* Invoke 'git reset --merge' */
if (read_cache_unmerged())
die_resolve_conflict("merge");
- if (file_exists(git_path("MERGE_HEAD"))) {
+ if (file_exists(git_path_merge_head())) {
/*
* There is no unmerged entry, don't advise 'git
* add/rm <file>', just 'git commit'.
else
die(_("You have not concluded your merge (MERGE_HEAD exists)."));
}
- if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
+ 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 merge."));
"git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] <refs>...";
static const char reflog_delete_usage[] =
"git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] <refs>...";
+static const char reflog_exists_usage[] =
+"git reflog exists <ref>";
static unsigned long default_reflog_expire;
static unsigned long default_reflog_expire_unreachable;
*/
static void mark_reachable(struct expire_reflog_policy_cb *cb)
{
- struct commit *commit;
struct commit_list *pending;
unsigned long expire_limit = cb->mark_limit;
struct commit_list *leftover = NULL;
pending = cb->mark_list;
while (pending) {
- struct commit_list *entry = pending;
struct commit_list *parent;
- pending = entry->next;
- commit = entry->item;
- free(entry);
+ struct commit *commit = pop_commit(&pending);
if (commit->object.flags & REACHABLE)
continue;
if (parse_commit(commit))
if (!value)
return config_error_nonbool(var);
if (parse_expiry_date(value, expire))
- return error(_("%s' for '%s' is not a valid timestamp"),
+ return error(_("'%s' for '%s' is not a valid timestamp"),
value, var);
return 0;
}
return status;
}
+static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)
+{
+ int i, start = 0;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (!strcmp(arg, "--")) {
+ i++;
+ break;
+ }
+ else if (arg[0] == '-')
+ usage(reflog_exists_usage);
+ else
+ break;
+ }
+
+ start = i;
+
+ if (argc - start != 1)
+ usage(reflog_exists_usage);
+
+ if (check_refname_format(argv[start], REFNAME_ALLOW_ONELEVEL))
+ die("invalid ref format: %s", argv[start]);
+ return !reflog_exists(argv[start]);
+}
+
/*
* main "reflog"
*/
static const char reflog_usage[] =
-"git reflog [ show | expire | delete ]";
+"git reflog [ show | expire | delete | exists ]";
int cmd_reflog(int argc, const char **argv, const char *prefix)
{
if (!strcmp(argv[1], "delete"))
return cmd_reflog_delete(argc - 1, argv + 1, prefix);
+ if (!strcmp(argv[1], "exists"))
+ return cmd_reflog_exists(argc - 1, argv + 1, prefix);
+
return cmd_log_reflog(argc, argv, prefix);
}
return NULL;
}
- static struct commit *pop_one_commit(struct commit_list **list_p)
- {
- struct commit *commit;
- struct commit_list *list;
- list = *list_p;
- commit = list->item;
- *list_p = list->next;
- free(list);
- return commit;
- }
-
struct commit_name {
const char *head_name; /* which head's ancestor? */
int generation; /* how many parents away from head_name */
while (*list_p) {
struct commit_list *parents;
int still_interesting = !!interesting(*list_p);
- struct commit *commit = pop_one_commit(list_p);
+ struct commit *commit = pop_commit(list_p);
int flags = commit->object.flags & all_mask;
if (!still_interesting && extra <= 0)
int exit_status = 1;
while (seen) {
- struct commit *commit = pop_one_commit(&seen);
+ struct commit *commit = pop_commit(&seen);
int flags = commit->object.flags & all_mask;
if (!(flags & UNINTERESTING) &&
((flags & all_revs) == all_revs)) {
else
msg++;
reflog_msg[i] = xstrfmt("(%s) %s",
- show_date(timestamp, tz, 1),
+ show_date(timestamp, tz,
+ DATE_MODE(RELATIVE)),
msg);
free(logmsg);
all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
while (seen) {
- struct commit *commit = pop_one_commit(&seen);
+ struct commit *commit = pop_commit(&seen);
int this_flag = commit->object.flags;
int is_merge_point = ((this_flag & all_revs) == all_revs);
const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
- struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+ if (!v) {
+ if (sizep)
+ *sizep = 0;
+ return NULL;
+ }
if (sizep)
*sizep = v->size;
return v->buffer;
void unuse_commit_buffer(const struct commit *commit, const void *buffer)
{
- struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
- if (v->buffer != buffer)
+ struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+ if (!(v && v->buffer == buffer))
free((void *)buffer);
}
void free_commit_buffer(struct commit *commit)
{
- struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
- free(v->buffer);
- v->buffer = NULL;
- v->size = 0;
+ struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
+ if (v) {
+ free(v->buffer);
+ v->buffer = NULL;
+ v->size = 0;
+ }
}
const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
{
- struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
+ struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
void *ret;
+ if (!v) {
+ if (sizep)
+ *sizep = 0;
+ return NULL;
+ }
ret = v->buffer;
if (sizep)
*sizep = v->size;
void free_commit_list(struct commit_list *list)
{
- while (list) {
- struct commit_list *temp = list;
- list = temp->next;
- free(temp);
- }
+ while (list)
+ pop_commit(&list);
}
struct commit_list * commit_list_insert_by_date(struct commit *item, struct commit_list **list)
struct commit *pop_most_recent_commit(struct commit_list **list,
unsigned int mark)
{
- struct commit *ret = (*list)->item;
+ struct commit *ret = pop_commit(list);
struct commit_list *parents = ret->parents;
- struct commit_list *old = *list;
-
- *list = (*list)->next;
- free(old);
while (parents) {
struct commit *commit = parents->item;
list = paint_down_to_common(one, n, twos);
while (list) {
- struct commit_list *next = list->next;
- if (!(list->item->object.flags & STALE))
- commit_list_insert_by_date(list->item, &result);
- free(list);
- list = next;
+ struct commit *commit = pop_commit(&list);
+ if (!(commit->object.flags & STALE))
+ commit_list_insert_by_date(commit, &result);
}
return result;
}
free(buf);
}
-void check_commit_signature(const struct commit *commit, struct signature_check *sigc)
+int check_commit_signature(const struct commit *commit, struct signature_check *sigc)
{
struct strbuf payload = STRBUF_INIT;
struct strbuf signature = STRBUF_INIT;
- struct strbuf gpg_output = STRBUF_INIT;
- struct strbuf gpg_status = STRBUF_INIT;
- int status;
+ int ret = 1;
sigc->result = 'N';
if (parse_signed_commit(commit, &payload, &signature) <= 0)
goto out;
- status = verify_signed_buffer(payload.buf, payload.len,
- signature.buf, signature.len,
- &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);
+ ret = check_signature(payload.buf, payload.len, signature.buf,
+ signature.len, sigc);
out:
- strbuf_release(&gpg_status);
- strbuf_release(&gpg_output);
strbuf_release(&payload);
strbuf_release(&signature);
+
+ return ret;
}
* if everything else stays the same.
*/
while (parents) {
- struct commit_list *next = parents->next;
- struct commit *parent = parents->item;
-
+ struct commit *parent = pop_commit(&parents);
strbuf_addf(&buffer, "parent %s\n",
sha1_to_hex(parent->object.sha1));
- free(parents);
- parents = next;
}
/* Person/date information */
#include "commit-slab.h"
#include "dir.h"
#include "cache-tree.h"
+#include "bisect.h"
volatile show_early_output_fn_t show_early_output;
+static const char *term_bad;
+static const char *term_good;
+
char *path_name(const struct name_path *path, const char *name)
{
const struct name_path *p;
commit_list_insert(l->item, &parents);
while (parents) {
- struct commit *commit = parents->item;
- l = parents;
- parents = parents->next;
- free(l);
+ struct commit *commit = pop_commit(&parents);
while (commit) {
/*
}
while (list) {
- struct commit_list *entry = list;
- struct commit *commit = list->item;
+ struct commit *commit = pop_commit(&list);
struct object *obj = &commit->object;
show_early_output_fn_t show;
- list = list->next;
- free(entry);
-
if (commit == interesting_cache)
interesting_cache = NULL;
} else if (!strcmp(arg, "--full-history")) {
revs->simplify_history = 0;
} else if (!strcmp(arg, "--relative-date")) {
- revs->date_mode = DATE_RELATIVE;
+ revs->date_mode.type = DATE_RELATIVE;
revs->date_mode_explicit = 1;
} else if ((argcount = parse_long_opt("date", argv, &optarg))) {
- revs->date_mode = parse_date_format(optarg);
+ parse_date_format(optarg, &revs->date_mode);
revs->date_mode_explicit = 1;
return argcount;
} else if (!strcmp(arg, "--log-size")) {
ctx->argc -= n;
}
+static int for_each_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data, const char *term) {
+ struct strbuf bisect_refs = STRBUF_INIT;
+ int status;
+ strbuf_addf(&bisect_refs, "refs/bisect/%s", term);
+ status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);
+ strbuf_release(&bisect_refs);
+ return status;
+}
+
static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)
{
- return for_each_ref_in_submodule(submodule, "refs/bisect/bad", fn, cb_data);
+ return for_each_bisect_ref(submodule, fn, cb_data, term_bad);
}
static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)
{
- return for_each_ref_in_submodule(submodule, "refs/bisect/good", fn, cb_data);
+ return for_each_bisect_ref(submodule, fn, cb_data, term_good);
}
static int handle_revision_pseudo_opt(const char *submodule,
handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);
clear_ref_exclusion(&revs->ref_excludes);
} else if (!strcmp(arg, "--bisect")) {
+ read_bisect_terms(&term_bad, &term_good);
handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);
handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);
revs->bisect = 1;
yet_to_do = NULL;
tail = &yet_to_do;
while (list) {
- commit = list->item;
- next = list->next;
- free(list);
- list = next;
+ commit = pop_commit(&list);
tail = simplify_one(revs, commit, tail);
}
}
while (list) {
struct merge_simplify_state *st;
- commit = list->item;
- next = list->next;
- free(list);
- list = next;
+ commit = pop_commit(&list);
st = locate_simplify_state(revs, commit);
if (st->simplified == commit)
tail = &commit_list_insert(commit, tail)->next;
return NULL;
do {
- struct commit_list *entry = revs->commits;
- struct commit *commit = entry->item;
-
- revs->commits = entry->next;
- free(entry);
+ struct commit *commit = pop_commit(&revs->commits);
if (revs->reflog_info) {
save_parents(revs, commit);
#include "cache.h"
+#include "tempfile.h"
#include "lockfile.h"
#include "commit.h"
#include "tag.h"
return is_shallow;
if (!path)
- path = git_path("shallow");
+ path = git_path_shallow();
/*
* fetch-pack sets '--shallow-file ""' as an indicator that no
* shallow file should be used. We could just open it and it
if (is_shallow == -1)
die("BUG: shallow must be initialized by now");
- if (!stat_validity_check(&shallow_stat, git_path("shallow")))
+ if (!stat_validity_check(&shallow_stat, git_path_shallow()))
die("shallow file has changed since we read it");
}
return write_shallow_commits_1(out, use_pack_protocol, extra, 0);
}
-static struct strbuf temporary_shallow = STRBUF_INIT;
-
-static void remove_temporary_shallow(void)
-{
- if (temporary_shallow.len) {
- unlink_or_warn(temporary_shallow.buf);
- strbuf_reset(&temporary_shallow);
- }
-}
-
-static void remove_temporary_shallow_on_signal(int signo)
-{
- remove_temporary_shallow();
- sigchain_pop(signo);
- raise(signo);
-}
+static struct tempfile temporary_shallow;
const char *setup_temporary_shallow(const struct sha1_array *extra)
{
struct strbuf sb = STRBUF_INIT;
int fd;
- if (temporary_shallow.len)
- die("BUG: attempt to create two temporary shallow files");
-
if (write_shallow_commits(&sb, 0, extra)) {
- strbuf_addstr(&temporary_shallow, git_path("shallow_XXXXXX"));
- fd = xmkstemp(temporary_shallow.buf);
-
- atexit(remove_temporary_shallow);
- sigchain_push_common(remove_temporary_shallow_on_signal);
+ fd = xmks_tempfile(&temporary_shallow, git_path("shallow_XXXXXX"));
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
die_errno("failed to write to %s",
- temporary_shallow.buf);
- close(fd);
+ get_tempfile_path(&temporary_shallow));
+ close_tempfile(&temporary_shallow);
strbuf_release(&sb);
- return temporary_shallow.buf;
+ return get_tempfile_path(&temporary_shallow);
}
/*
* is_repository_shallow() sees empty string as "no shallow
* file".
*/
- return temporary_shallow.buf;
+ return get_tempfile_path(&temporary_shallow);
}
void setup_alternate_shallow(struct lock_file *shallow_lock,
struct strbuf sb = STRBUF_INIT;
int fd;
- fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
+ fd = hold_lock_file_for_update(shallow_lock, git_path_shallow(),
LOCK_DIE_ON_ERROR);
check_shallow_file_for_update();
if (write_shallow_commits(&sb, 0, extra)) {
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
die_errno("failed to write to %s",
- shallow_lock->filename.buf);
- *alternate_shallow_file = shallow_lock->filename.buf;
+ get_lock_file_path(shallow_lock));
+ *alternate_shallow_file = get_lock_file_path(shallow_lock);
} else
/*
* is_repository_shallow() sees empty string as "no
strbuf_release(&sb);
return;
}
- fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
+ fd = hold_lock_file_for_update(&shallow_lock, git_path_shallow(),
LOCK_DIE_ON_ERROR);
check_shallow_file_for_update();
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
die_errno("failed to write to %s",
- shallow_lock.filename.buf);
+ get_lock_file_path(&shallow_lock));
commit_lock_file(&shallow_lock);
} else {
- unlink(git_path("shallow"));
+ unlink(git_path_shallow());
rollback_lock_file(&shallow_lock);
}
strbuf_release(&sb);
commit_list_insert(c, &head);
while (head) {
struct commit_list *p;
- struct commit *c = head->item;
+ struct commit *c = pop_commit(&head);
uint32_t **refs = ref_bitmap_at(&info->ref_bitmap, c);
- p = head;
- head = head->next;
- free(p);
-
/* XXX check "UNINTERESTING" from pack bitmaps if available */
if (c->object.flags & (SEEN | UNINTERESTING))
continue;