Skip to content

Commit e3688bd

Browse files
dturner-twgitster
authored andcommitted
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>
1 parent 1a76900 commit e3688bd

3 files changed

Lines changed: 150 additions & 27 deletions

File tree

refs.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,3 +1461,66 @@ int verify_refname_available(const char *refname,
14611461

14621462
return refs->be->verify_refname_available(refs, refname, extra, skip, err);
14631463
}
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

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,11 +2777,16 @@ static int log_ref_setup(const char *refname, struct strbuf *logfile, struct str
27772777
}
27782778

27792779

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)
27812783
{
27822784
int ret;
27832785
struct strbuf sb = STRBUF_INIT;
27842786

2787+
/* Check validity (but we don't need the result): */
2788+
files_downcast(ref_store, 0, "create_reflog");
2789+
27852790
ret = log_ref_setup(refname, &sb, err, force_create);
27862791
strbuf_release(&sb);
27872792
return ret;
@@ -3075,16 +3080,24 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
30753080
return ret;
30763081
}
30773082

3078-
int reflog_exists(const char *refname)
3083+
static int files_reflog_exists(struct ref_store *ref_store,
3084+
const char *refname)
30793085
{
30803086
struct stat st;
30813087

3088+
/* Check validity (but we don't need the result): */
3089+
files_downcast(ref_store, 0, "reflog_exists");
3090+
30823091
return !lstat(git_path("logs/%s", refname), &st) &&
30833092
S_ISREG(st.st_mode);
30843093
}
30853094

3086-
int delete_reflog(const char *refname)
3095+
static int files_delete_reflog(struct ref_store *ref_store,
3096+
const char *refname)
30873097
{
3098+
/* Check validity (but we don't need the result): */
3099+
files_downcast(ref_store, 0, "delete_reflog");
3100+
30883101
return remove_path(git_path("logs/%s", refname));
30893102
}
30903103

@@ -3127,13 +3140,19 @@ static char *find_beginning_of_line(char *bob, char *scan)
31273140
return scan;
31283141
}
31293142

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)
31313147
{
31323148
struct strbuf sb = STRBUF_INIT;
31333149
FILE *logfp;
31343150
long pos;
31353151
int ret = 0, at_tail = 1;
31363152

3153+
/* Check validity (but we don't need the result): */
3154+
files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
3155+
31373156
logfp = fopen(git_path("logs/%s", refname), "r");
31383157
if (!logfp)
31393158
return -1;
@@ -3229,12 +3248,17 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void
32293248
return ret;
32303249
}
32313250

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)
32333254
{
32343255
FILE *logfp;
32353256
struct strbuf sb = STRBUF_INIT;
32363257
int ret = 0;
32373258

3259+
/* Check validity (but we don't need the result): */
3260+
files_downcast(ref_store, 0, "for_each_reflog_ent");
3261+
32383262
logfp = fopen(git_path("logs/%s", refname), "r");
32393263
if (!logfp)
32403264
return -1;
@@ -3313,22 +3337,19 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
33133337
files_reflog_iterator_abort
33143338
};
33153339

3316-
struct ref_iterator *files_reflog_iterator_begin(void)
3340+
static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
33173341
{
33183342
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
33193343
struct ref_iterator *ref_iterator = &iter->base;
33203344

3345+
/* Check validity (but we don't need the result): */
3346+
files_downcast(ref_store, 0, "reflog_iterator_begin");
3347+
33213348
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
33223349
iter->dir_iterator = dir_iterator_begin(git_path("logs"));
33233350
return ref_iterator;
33243351
}
33253352

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-
33323353
static int ref_update_reject_duplicates(struct string_list *refnames,
33333354
struct strbuf *err)
33343355
{
@@ -3925,15 +3946,16 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
39253946
return 0;
39263947
}
39273948

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)
39343956
{
39353957
struct files_ref_store *refs =
3936-
get_files_ref_store(NULL, "reflog_expire");
3958+
files_downcast(ref_store, 0, "reflog_expire");
39373959
static struct lock_file reflog_lock;
39383960
struct expire_reflog_cb cb;
39393961
struct ref_lock *lock;
@@ -4046,5 +4068,13 @@ struct ref_storage_be refs_be_files = {
40464068

40474069
files_ref_iterator_begin,
40484070
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
40504080
};

refs/refs-internal.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -404,13 +404,6 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
404404
const char *prefix,
405405
int trim);
406406

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-
414407
/* Internal implementation of reference iteration: */
415408

416409
/*
@@ -507,6 +500,35 @@ typedef struct ref_iterator *ref_iterator_begin_fn(
507500
struct ref_store *ref_store,
508501
const char *prefix, unsigned int flags);
509502

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+
510532
/*
511533
* Read a reference from the specified reference store, non-recursively.
512534
* Set type to describe the reference, and:
@@ -568,6 +590,14 @@ struct ref_storage_be {
568590
ref_iterator_begin_fn *iterator_begin;
569591
read_raw_ref_fn *read_raw_ref;
570592
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;
571601
};
572602

573603
extern struct ref_storage_be refs_be_files;

0 commit comments

Comments
 (0)