refs: add methods for reflog
In the file-based backend, the reflog piggybacks on the ref lock. Since other backends won't have the same sort of ref lock, ref backends must also handle reflogs. Signed-off-by: Ronnie Sahlberg <rsahlberg@google.com> Signed-off-by: David Turner <dturner@twopensource.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
David Turner committed
Sep 4, 2016 at 18:08 UTC
e3688bd6cf159f6026a6bca7a6f53d0a22fe21a2
3 files changed
+150
-27
refs.c
+63
@@ -1461,3 +1461,66 @@ int verify_refname_available(const char *refname,
1461
1462
return refs->be->verify_refname_available(refs, refname, extra, skip, err);
1463
}
1464
+
1465
+int for_each_reflog(each_ref_fn fn, void *cb_data)
1466
+{
1467
+ struct ref_store *refs = get_ref_store(NULL);
1468
+ struct ref_iterator *iter;
1469
+
1470
+ iter = refs->be->reflog_iterator_begin(refs);
1471
+
1472
+ return do_for_each_ref_iterator(iter, fn, cb_data);
1473
+}
1474
+
1475
+int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
1476
+ void *cb_data)
1477
+{
1478
+ struct ref_store *refs = get_ref_store(NULL);
1479
+
1480
+ return refs->be->for_each_reflog_ent_reverse(refs, refname,
1481
+ fn, cb_data);
1482
+}
1483
+
1484
+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
1485
+ void *cb_data)
1486
+{
1487
+ struct ref_store *refs = get_ref_store(NULL);
1488
+
1489
+ return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
1490
+}
1491
+
1492
+int reflog_exists(const char *refname)
1493
+{
1494
+ struct ref_store *refs = get_ref_store(NULL);
1495
+
1496
+ return refs->be->reflog_exists(refs, refname);
1497
+}
1498
+
1499
+int safe_create_reflog(const char *refname, int force_create,
1500
+ struct strbuf *err)
1501
+{
1502
+ struct ref_store *refs = get_ref_store(NULL);
1503
+
1504
+ return refs->be->create_reflog(refs, refname, force_create, err);
1505
+}
1506
+
1507
+int delete_reflog(const char *refname)
1508
+{
1509
+ struct ref_store *refs = get_ref_store(NULL);
1510
+
1511
+ return refs->be->delete_reflog(refs, refname);
1512
+}
1513
+
1514
+int reflog_expire(const char *refname, const unsigned char *sha1,
1515
+ unsigned int flags,
1516
+ reflog_expiry_prepare_fn prepare_fn,
1517
+ reflog_expiry_should_prune_fn should_prune_fn,
1518
+ reflog_expiry_cleanup_fn cleanup_fn,
1519
+ void *policy_cb_data)
1520
+{
1521
+ struct ref_store *refs = get_ref_store(NULL);
1522
+
1523
+ return refs->be->reflog_expire(refs, refname, sha1, flags,
1524
+ prepare_fn, should_prune_fn,
1525
+ cleanup_fn, policy_cb_data);
1526
+}
refs/files-backend.c
+50
-20
@@ -2777,11 +2777,16 @@ static int log_ref_setup(const char *refname, struct strbuf *logfile, struct str
2777
}
2778
2779
2780
-int safe_create_reflog(const char *refname, int force_create, struct strbuf *err)
2780
+static int files_create_reflog(struct ref_store *ref_store,
2781
+ const char *refname, int force_create,
2782
+ struct strbuf *err)
2783
{
2784
int ret;
2785
struct strbuf sb = STRBUF_INIT;
2786
2787
+ /* Check validity (but we don't need the result): */
2788
+ files_downcast(ref_store, 0, "create_reflog");
2789
+
2790
ret = log_ref_setup(refname, &sb, err, force_create);
2791
strbuf_release(&sb);
2792
return ret;
@@ -3075,16 +3080,24 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
3080
return ret;
3081
}
3082
3078
-int reflog_exists(const char *refname)
3083
+static int files_reflog_exists(struct ref_store *ref_store,
3084
+ const char *refname)
3085
{
3086
struct stat st;
3087
3088
+ /* Check validity (but we don't need the result): */
3089
+ files_downcast(ref_store, 0, "reflog_exists");
3090
+
3091
return !lstat(git_path("logs/%s", refname), &st) &&
3092
S_ISREG(st.st_mode);
3093
}
3094
3086
-int delete_reflog(const char *refname)
3095
+static int files_delete_reflog(struct ref_store *ref_store,
3096
+ const char *refname)
3097
{
3098
+ /* Check validity (but we don't need the result): */
3099
+ files_downcast(ref_store, 0, "delete_reflog");
3100
+
3101
return remove_path(git_path("logs/%s", refname));
3102
}
3103
@@ -3127,13 +3140,19 @@ static char *find_beginning_of_line(char *bob, char *scan)
3140
return scan;
3141
}
3142
3130
-int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data)
3143
+static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
3144
+ const char *refname,
3145
+ each_reflog_ent_fn fn,
3146
+ void *cb_data)
3147
{
3148
struct strbuf sb = STRBUF_INIT;
3149
FILE *logfp;
3150
long pos;
3151
int ret = 0, at_tail = 1;
3152
3153
+ /* Check validity (but we don't need the result): */
3154
+ files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
3155
+
3156
logfp = fopen(git_path("logs/%s", refname), "r");
3157
if (!logfp)
3158
return -1;
@@ -3229,12 +3248,17 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void
3248
return ret;
3249
}
3250
3232
-int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data)
3251
+static int files_for_each_reflog_ent(struct ref_store *ref_store,
3252
+ const char *refname,
3253
+ each_reflog_ent_fn fn, void *cb_data)
3254
{
3255
FILE *logfp;
3256
struct strbuf sb = STRBUF_INIT;
3257
int ret = 0;
3258
3259
+ /* Check validity (but we don't need the result): */
3260
+ files_downcast(ref_store, 0, "for_each_reflog_ent");
3261
+
3262
logfp = fopen(git_path("logs/%s", refname), "r");
3263
if (!logfp)
3264
return -1;
@@ -3313,22 +3337,19 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
3337
files_reflog_iterator_abort
3338
};
3339
3316
-struct ref_iterator *files_reflog_iterator_begin(void)
3340
+static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
3341
{
3342
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
3343
struct ref_iterator *ref_iterator = &iter->base;
3344
3345
+ /* Check validity (but we don't need the result): */
3346
+ files_downcast(ref_store, 0, "reflog_iterator_begin");
3347
+
3348
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
3349
iter->dir_iterator = dir_iterator_begin(git_path("logs"));
3350
return ref_iterator;
3351
}
3352
3326
-int for_each_reflog(each_ref_fn fn, void *cb_data)
3327
-{
3328
- return do_for_each_ref_iterator(files_reflog_iterator_begin(),
3329
- fn, cb_data);
3330
-}
3331
-
3353
static int ref_update_reject_duplicates(struct string_list *refnames,
3354
struct strbuf *err)
3355
{
@@ -3925,15 +3946,16 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
3946
return 0;
3947
}
3948
3928
-int reflog_expire(const char *refname, const unsigned char *sha1,
3929
- unsigned int flags,
3930
- reflog_expiry_prepare_fn prepare_fn,
3931
- reflog_expiry_should_prune_fn should_prune_fn,
3932
- reflog_expiry_cleanup_fn cleanup_fn,
3933
- void *policy_cb_data)
3949
+static int files_reflog_expire(struct ref_store *ref_store,
3950
+ const char *refname, const unsigned char *sha1,
3951
+ unsigned int flags,
3952
+ reflog_expiry_prepare_fn prepare_fn,
3953
+ reflog_expiry_should_prune_fn should_prune_fn,
3954
+ reflog_expiry_cleanup_fn cleanup_fn,
3955
+ void *policy_cb_data)
3956
{
3957
struct files_ref_store *refs =
3936
- get_files_ref_store(NULL, "reflog_expire");
3958
+ files_downcast(ref_store, 0, "reflog_expire");
3959
static struct lock_file reflog_lock;
3960
struct expire_reflog_cb cb;
3961
struct ref_lock *lock;
@@ -4046,5 +4068,13 @@ struct ref_storage_be refs_be_files = {
4068
4069
files_ref_iterator_begin,
4070
files_read_raw_ref,
4049
- files_verify_refname_available
4071
+ files_verify_refname_available,
4072
+
4073
+ files_reflog_iterator_begin,
4074
+ files_for_each_reflog_ent,
4075
+ files_for_each_reflog_ent_reverse,
4076
+ files_reflog_exists,
4077
+ files_create_reflog,
4078
+ files_delete_reflog,
4079
+ files_reflog_expire
4080
};
refs/refs-internal.h
+37
-7
@@ -404,13 +404,6 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
404
const char *prefix,
405
int trim);
406
407
-/*
408
- * Iterate over the references in the main ref_store that have a
409
- * reflog. The paths within a directory are iterated over in arbitrary
410
- * order.
411
- */
412
-struct ref_iterator *files_reflog_iterator_begin(void);
413
-
407
/* Internal implementation of reference iteration: */
408
409
/*
@@ -507,6 +500,35 @@ typedef struct ref_iterator *ref_iterator_begin_fn(
500
struct ref_store *ref_store,
501
const char *prefix, unsigned int flags);
502
503
+/* reflog functions */
504
+
505
+/*
506
+ * Iterate over the references in the specified ref_store that have a
507
+ * reflog. The refs are iterated over in arbitrary order.
508
+ */
509
+typedef struct ref_iterator *reflog_iterator_begin_fn(
510
+ struct ref_store *ref_store);
511
+
512
+typedef int for_each_reflog_ent_fn(struct ref_store *ref_store,
513
+ const char *refname,
514
+ each_reflog_ent_fn fn,
515
+ void *cb_data);
516
+typedef int for_each_reflog_ent_reverse_fn(struct ref_store *ref_store,
517
+ const char *refname,
518
+ each_reflog_ent_fn fn,
519
+ void *cb_data);
520
+typedef int reflog_exists_fn(struct ref_store *ref_store, const char *refname);
521
+typedef int create_reflog_fn(struct ref_store *ref_store, const char *refname,
522
+ int force_create, struct strbuf *err);
523
+typedef int delete_reflog_fn(struct ref_store *ref_store, const char *refname);
524
+typedef int reflog_expire_fn(struct ref_store *ref_store,
525
+ const char *refname, const unsigned char *sha1,
526
+ unsigned int flags,
527
+ reflog_expiry_prepare_fn prepare_fn,
528
+ reflog_expiry_should_prune_fn should_prune_fn,
529
+ reflog_expiry_cleanup_fn cleanup_fn,
530
+ void *policy_cb_data);
531
+
532
/*
533
* Read a reference from the specified reference store, non-recursively.
534
* Set type to describe the reference, and:
@@ -568,6 +590,14 @@ struct ref_storage_be {
590
ref_iterator_begin_fn *iterator_begin;
591
read_raw_ref_fn *read_raw_ref;
592
verify_refname_available_fn *verify_refname_available;
593
+
594
+ reflog_iterator_begin_fn *reflog_iterator_begin;
595
+ for_each_reflog_ent_fn *for_each_reflog_ent;
596
+ for_each_reflog_ent_reverse_fn *for_each_reflog_ent_reverse;
597
+ reflog_exists_fn *reflog_exists;
598
+ create_reflog_fn *create_reflog;
599
+ delete_reflog_fn *delete_reflog;
600
+ reflog_expire_fn *reflog_expire;
601
};
602
603
extern struct ref_storage_be refs_be_files;