static struct complete_reflogs *read_complete_reflog(const char *ref) { struct complete_reflogs *reflogs = xcalloc(1, sizeof(struct complete_reflogs)); reflogs->ref = xstrdup(ref); for_each_reflog_ent(ref, read_one_reflog, reflogs); if (reflogs->nr == 0) { struct object_id oid; const char *name; void *name_to_free; name = name_to_free = resolve_refdup(ref, RESOLVE_REF_READING, oid.hash, NULL); if (name) { for_each_reflog_ent(name, read_one_reflog, reflogs); free(name_to_free); } } if (reflogs->nr == 0) { char *refname = xstrfmt("refs/%s", ref); for_each_reflog_ent(refname, read_one_reflog, reflogs); if (reflogs->nr == 0) { free(refname); refname = xstrfmt("refs/heads/%s", ref); for_each_reflog_ent(refname, read_one_reflog, reflogs); } free(refname); } return reflogs; }
int read_ref_at(const char *refname, unsigned int flags, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt) { struct read_ref_at_cb cb; memset(&cb, 0, sizeof(cb)); cb.refname = refname; cb.at_time = at_time; cb.cnt = cnt; cb.msg = msg; cb.cutoff_time = cutoff_time; cb.cutoff_tz = cutoff_tz; cb.cutoff_cnt = cutoff_cnt; cb.sha1 = sha1; for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb); if (!cb.reccnt) { if (flags & GET_SHA1_QUIETLY) exit(128); else die("Log for %s is empty.", refname); } if (cb.found_it) return 0; for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb); return 1; }
static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data) { struct all_refs_cb *cb = cb_data; cb->warned_bad_reflog = 0; cb->name_for_errormsg = path; for_each_reflog_ent(path, handle_one_reflog_ent, cb_data); return 0; }
static int handle_fork_point(int argc, const char **argv) { unsigned char sha1[20]; char *refname; const char *commitname; struct rev_collect revs; struct commit *derived; struct commit_list *bases; int i, ret = 0; switch (dwim_ref(argv[0], strlen(argv[0]), sha1, &refname)) { case 0: die("No such ref: '%s'", argv[0]); case 1: break; /* good */ default: die("Ambiguous refname: '%s'", argv[0]); } commitname = (argc == 2) ? argv[1] : "HEAD"; if (get_sha1(commitname, sha1)) die("Not a valid object name: '%s'", commitname); derived = lookup_commit_reference(sha1); memset(&revs, 0, sizeof(revs)); revs.initial = 1; for_each_reflog_ent(refname, collect_one_reflog_ent, &revs); for (i = 0; i < revs.nr; i++) revs.commit[i]->object.flags &= ~TMP_MARK; bases = get_merge_bases_many_dirty(derived, revs.nr, revs.commit); /* * There should be one and only one merge base, when we found * a common ancestor among reflog entries. */ if (!bases || bases->next) { ret = 1; goto cleanup_return; } /* And the found one must be one of the reflog entries */ for (i = 0; i < revs.nr; i++) if (&bases->item->object == &revs.commit[i]->object) break; /* found */ if (revs.nr <= i) { ret = 1; /* not found */ goto cleanup_return; } printf("%s\n", oid_to_hex(&bases->item->object.oid)); cleanup_return: free_commit_list(bases); return ret; }
static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) { struct expire_reflog_policy_cb cb; int i, status = 0; unsigned int flags = 0; memset(&cb, 0, sizeof(cb)); for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n")) flags |= EXPIRE_REFLOGS_DRY_RUN; else if (!strcmp(arg, "--rewrite")) flags |= EXPIRE_REFLOGS_REWRITE; else if (!strcmp(arg, "--updateref")) flags |= EXPIRE_REFLOGS_UPDATE_REF; else if (!strcmp(arg, "--verbose")) flags |= EXPIRE_REFLOGS_VERBOSE; else if (!strcmp(arg, "--")) { i++; break; } else if (arg[0] == '-') usage(_(reflog_delete_usage)); else break; } if (argc - i < 1) return error(_("no reflog specified to delete")); for ( ; i < argc; i++) { const char *spec = strstr(argv[i], "@{"); struct object_id oid; char *ep, *ref; int recno; if (!spec) { status |= error(_("not a reflog: %s"), argv[i]); continue; } if (!dwim_log(argv[i], spec - argv[i], &oid, &ref)) { status |= error(_("no reflog for '%s'"), argv[i]); continue; } recno = strtoul(spec + 2, &ep, 10); if (*ep == '}') { cb.cmd.recno = -recno; for_each_reflog_ent(ref, count_reflog_ent, &cb); } else { cb.cmd.expire_total = approxidate(spec + 2); for_each_reflog_ent(ref, count_reflog_ent, &cb); cb.cmd.expire_total = 0; } status |= reflog_expire(ref, &oid, flags, reflog_expiry_prepare, should_expire_reflog_ent, reflog_expiry_cleanup, &cb); free(ref); } return status; }
static int fsck_handle_reflog(const char *logname, const struct object_id *oid, int flag, void *cb_data) { for_each_reflog_ent(logname, fsck_handle_reflog_ent, (void *)logname); return 0; }
int git_for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data) { return for_each_reflog_ent(ref,fn,cb_data); }