aboutsummaryrefslogtreecommitdiff
path: root/builtin-reflog.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin-reflog.c')
-rw-r--r--builtin-reflog.c82
1 files changed, 44 insertions, 38 deletions
diff --git a/builtin-reflog.c b/builtin-reflog.c
index fb37984ae..341555139 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -13,7 +13,7 @@
*/
static const char reflog_expire_usage[] =
-"git-reflog expire [--verbose] [--dry-run] [--fix-stale] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
+"git-reflog (show|expire) [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
static unsigned long default_reflog_expire;
static unsigned long default_reflog_expire_unreachable;
@@ -173,7 +173,6 @@ static int keep_entry(struct commit **it, unsigned char *sha1)
{
struct commit *commit;
- *it = NULL;
if (is_null_sha1(sha1))
return 1;
commit = lookup_commit_reference_gently(sha1, 1);
@@ -195,41 +194,46 @@ static int keep_entry(struct commit **it, unsigned char *sha1)
}
static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
- char *data, void *cb_data)
+ const char *email, unsigned long timestamp, int tz,
+ const char *message, void *cb_data)
{
struct expire_reflog_cb *cb = cb_data;
- unsigned long timestamp;
- char *cp, *ep;
struct commit *old, *new;
- cp = strchr(data, '>');
- if (!cp || *++cp != ' ')
- goto prune;
- timestamp = strtoul(cp, &ep, 10);
- if (*ep != ' ')
- goto prune;
if (timestamp < cb->cmd->expire_total)
goto prune;
+ old = new = NULL;
if (cb->cmd->stalefix &&
(!keep_entry(&old, osha1) || !keep_entry(&new, nsha1)))
goto prune;
- if ((timestamp < cb->cmd->expire_unreachable) &&
- (!cb->ref_commit ||
- (old && !in_merge_bases(old, &cb->ref_commit, 1)) ||
- (new && !in_merge_bases(new, &cb->ref_commit, 1))))
- goto prune;
+ if (timestamp < cb->cmd->expire_unreachable) {
+ if (!cb->ref_commit)
+ goto prune;
+ if (!old && !is_null_sha1(osha1))
+ old = lookup_commit_reference_gently(osha1, 1);
+ if (!new && !is_null_sha1(nsha1))
+ new = lookup_commit_reference_gently(nsha1, 1);
+ if ((old && !in_merge_bases(old, &cb->ref_commit, 1)) ||
+ (new && !in_merge_bases(new, &cb->ref_commit, 1)))
+ goto prune;
+ }
- if (cb->newlog)
- fprintf(cb->newlog, "%s %s %s",
- sha1_to_hex(osha1), sha1_to_hex(nsha1), data);
+ if (cb->newlog) {
+ char sign = (tz < 0) ? '-' : '+';
+ int zone = (tz < 0) ? (-tz) : tz;
+ fprintf(cb->newlog, "%s %s %s %lu %c%04d\t%s",
+ sha1_to_hex(osha1), sha1_to_hex(nsha1),
+ email, timestamp, sign, zone,
+ message);
+ }
if (cb->cmd->verbose)
- printf("keep %s", data);
+ printf("keep %s", message);
return 0;
prune:
if (!cb->newlog || cb->cmd->verbose)
- printf("%sprune %s", cb->newlog ? "" : "would ", data);
+ printf("%sprune %s", cb->newlog ? "" : "would ", message);
return 0;
}
@@ -238,20 +242,18 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
struct cmd_reflog_expire_cb *cmd = cb_data;
struct expire_reflog_cb cb;
struct ref_lock *lock;
- char *newlog_path = NULL;
+ char *log_file, *newlog_path = NULL;
int status = 0;
- if (strncmp(ref, "refs/", 5))
- return error("not a ref '%s'", ref);
-
memset(&cb, 0, sizeof(cb));
/* we take the lock for the ref itself to prevent it from
* getting updated.
*/
- lock = lock_ref_sha1(ref + 5, sha1);
+ lock = lock_any_ref_for_update(ref, sha1);
if (!lock)
return error("cannot lock ref '%s'", ref);
- if (!file_exists(lock->log_file))
+ log_file = xstrdup(git_path("logs/%s", ref));
+ if (!file_exists(log_file))
goto finish;
if (!cmd->dry_run) {
newlog_path = xstrdup(git_path("logs/%s.lock", ref));
@@ -259,9 +261,6 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
}
cb.ref_commit = lookup_commit_reference_gently(sha1, 1);
- if (!cb.ref_commit)
- fprintf(stderr,
- "warning: ref '%s' does not point at a commit\n", ref);
cb.ref = ref;
cb.cmd = cmd;
for_each_reflog_ent(ref, expire_reflog_ent, &cb);
@@ -270,13 +269,14 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
if (fclose(cb.newlog))
status |= error("%s: %s", strerror(errno),
newlog_path);
- if (rename(newlog_path, lock->log_file)) {
+ if (rename(newlog_path, log_file)) {
status |= error("cannot rename %s to %s",
- newlog_path, lock->log_file);
+ newlog_path, log_file);
unlink(newlog_path);
}
}
free(newlog_path);
+ free(log_file);
unlock_ref(lock);
return status;
}
@@ -350,7 +350,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
}
if (do_all)
- status |= for_each_ref(expire_reflog, &cb);
+ status |= for_each_reflog(expire_reflog, &cb);
while (i < argc) {
const char *ref = argv[i++];
unsigned char sha1[20];
@@ -372,10 +372,16 @@ static const char reflog_usage[] =
int cmd_reflog(int argc, const char **argv, const char *prefix)
{
- if (argc < 2)
- usage(reflog_usage);
- else if (!strcmp(argv[1], "expire"))
+ /* With no command, we default to showing it. */
+ if (argc < 2 || *argv[1] == '-')
+ return cmd_log_reflog(argc, argv, prefix);
+
+ if (!strcmp(argv[1], "show"))
+ return cmd_log_reflog(argc - 1, argv + 1, prefix);
+
+ if (!strcmp(argv[1], "expire"))
return cmd_reflog_expire(argc - 1, argv + 1, prefix);
- else
- usage(reflog_usage);
+
+ /* Not a recognized reflog command..*/
+ usage(reflog_usage);
}