summaryrefslogtreecommitdiff
path: root/builtin-reflog.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin-reflog.c')
-rw-r--r--builtin-reflog.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 5e5498945f..8af75bc3e1 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -35,6 +35,16 @@ struct expire_reflog_cb {
struct cmd_reflog_expire_cb *cmd;
};
+struct collected_reflog {
+ unsigned char sha1[20];
+ char reflog[FLEX_ARRAY];
+};
+struct collect_reflog_cb {
+ struct collected_reflog **e;
+ int alloc;
+ int nr;
+};
+
#define INCOMPLETE (1u<<10)
#define STUDYING (1u<<11)
@@ -270,10 +280,11 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
for_each_reflog_ent(ref, expire_reflog_ent, &cb);
finish:
if (cb.newlog) {
- if (fclose(cb.newlog))
+ if (fclose(cb.newlog)) {
status |= error("%s: %s", strerror(errno),
newlog_path);
- if (rename(newlog_path, log_file)) {
+ unlink(newlog_path);
+ } else if (rename(newlog_path, log_file)) {
status |= error("cannot rename %s to %s",
newlog_path, log_file);
unlink(newlog_path);
@@ -285,15 +296,35 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
return status;
}
+static int collect_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)
+{
+ struct collected_reflog *e;
+ struct collect_reflog_cb *cb = cb_data;
+ size_t namelen = strlen(ref);
+
+ e = xmalloc(sizeof(*e) + namelen + 1);
+ hashcpy(e->sha1, sha1);
+ memcpy(e->reflog, ref, namelen + 1);
+ ALLOC_GROW(cb->e, cb->nr + 1, cb->alloc);
+ cb->e[cb->nr++] = e;
+ return 0;
+}
+
static int reflog_expire_config(const char *var, const char *value)
{
- if (!strcmp(var, "gc.reflogexpire"))
+ if (!strcmp(var, "gc.reflogexpire")) {
+ if (!value)
+ config_error_nonbool(var);
default_reflog_expire = approxidate(value);
- else if (!strcmp(var, "gc.reflogexpireunreachable"))
+ return 0;
+ }
+ if (!strcmp(var, "gc.reflogexpireunreachable")) {
+ if (!value)
+ config_error_nonbool(var);
default_reflog_expire_unreachable = approxidate(value);
- else
- return git_default_config(var, value);
- return 0;
+ return 0;
+ }
+ return git_default_config(var, value);
}
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
@@ -353,8 +384,20 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
putchar('\n');
}
- if (do_all)
- status |= for_each_reflog(expire_reflog, &cb);
+ if (do_all) {
+ struct collect_reflog_cb collected;
+ int i;
+
+ memset(&collected, 0, sizeof(collected));
+ for_each_reflog(collect_reflog, &collected);
+ for (i = 0; i < collected.nr; i++) {
+ struct collected_reflog *e = collected.e[i];
+ status |= expire_reflog(e->reflog, e->sha1, 0, &cb);
+ free(e);
+ }
+ free(collected.e);
+ }
+
while (i < argc) {
const char *ref = argv[i++];
unsigned char sha1[20];