34
35
struct expire_reflog_cb {
36
FILE *newlog;
37
- const char *ref;
38
- struct commit *ref_commit;
37
+ enum {
38
+ UE_NORMAL,
39
+ UE_ALWAYS,
40
+ UE_HEAD
41
+ } unreachable_expire_kind;
42
struct commit_list *mark_list;
43
unsigned long mark_limit;
44
struct cmd_reflog_expire_cb *cmd;
308
goto prune;
309
310
if (timestamp < cb->cmd->expire_unreachable) {
308
- if (!cb->ref_commit)
311
+ if (cb->unreachable_expire_kind == UE_ALWAYS)
312
goto prune;
313
if (unreachable(cb, old, osha1) || unreachable(cb, new, nsha1))
314
goto prune;
335
return 0;
336
}
337
338
+static int push_tip_to_list(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
339
+{
340
+ struct commit_list **list = cb_data;
341
+ struct commit *tip_commit;
342
+ if (flags & REF_ISSYMREF)
343
+ return 0;
344
+ tip_commit = lookup_commit_reference_gently(sha1, 1);
345
+ if (!tip_commit)
346
+ return 0;
347
+ commit_list_insert(tip_commit, list);
348
+ return 0;
349
+}
350
+
351
static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)
352
{
353
struct cmd_reflog_expire_cb *cmd = cb_data;
354
struct expire_reflog_cb cb;
355
struct ref_lock *lock;
356
char *log_file, *newlog_path = NULL;
357
+ struct commit *tip_commit;
358
+ struct commit_list *tips;
359
int status = 0;
360
361
memset(&cb, 0, sizeof(cb));
375
cb.newlog = fopen(newlog_path, "w");
376
}
377
360
- cb.ref_commit = lookup_commit_reference_gently(sha1, 1);
361
- cb.ref = ref;
378
cb.cmd = cmd;
363
- if (cb.ref_commit) {
364
- cb.mark_list = NULL;
365
- commit_list_insert(cb.ref_commit, &cb.mark_list);
379
+
380
+ if (!cmd->expire_unreachable || !strcmp(ref, "HEAD")) {
381
+ tip_commit = NULL;
382
+ cb.unreachable_expire_kind = UE_HEAD;
383
+ } else {
384
+ tip_commit = lookup_commit_reference_gently(sha1, 1);
385
+ if (!tip_commit)
386
+ cb.unreachable_expire_kind = UE_ALWAYS;
387
+ else
388
+ cb.unreachable_expire_kind = UE_NORMAL;
389
+ }
390
+
391
+ if (cmd->expire_unreachable <= cmd->expire_total)
392
+ cb.unreachable_expire_kind = UE_ALWAYS;
393
+
394
+ cb.mark_list = NULL;
395
+ tips = NULL;
396
+ if (cb.unreachable_expire_kind != UE_ALWAYS) {
397
+ if (cb.unreachable_expire_kind == UE_HEAD) {
398
+ struct commit_list *elem;
399
+ for_each_ref(push_tip_to_list, &tips);
400
+ for (elem = tips; elem; elem = elem->next)
401
+ commit_list_insert(elem->item, &cb.mark_list);
402
+ } else {
403
+ commit_list_insert(tip_commit, &cb.mark_list);
404
+ }
405
cb.mark_limit = cmd->expire_total;
406
mark_reachable(&cb);
407
}
408
+
409
for_each_reflog_ent(ref, expire_reflog_ent, &cb);
370
- if (cb.ref_commit)
371
- clear_commit_marks(cb.ref_commit, REACHABLE);
410
+
411
+ if (cb.unreachable_expire_kind != UE_ALWAYS) {
412
+ if (cb.unreachable_expire_kind == UE_HEAD) {
413
+ struct commit_list *elem;
414
+ for (elem = tips; elem; elem = elem->next)
415
+ clear_commit_marks(tip_commit, REACHABLE);
416
+ free_commit_list(tips);
417
+ } else {
418
+ clear_commit_marks(tip_commit, REACHABLE);
419
+ }
420
+ }
421
finish:
422
if (cb.newlog) {
423
if (fclose(cb.newlog)) {