Skip to content

Commit e56f350

Browse files
committed
refdb: teach filesystem refdb about sha256
1 parent fe2ee3a commit e56f350

File tree

3 files changed

+78
-48
lines changed

3 files changed

+78
-48
lines changed

src/libgit2/refdb_fs.c

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,17 @@ typedef struct refdb_fs_backend {
6060
/* path to common objects' directory */
6161
char *commonpath;
6262

63-
git_sortedcache *refcache;
63+
git_oid_t oid_type;
64+
65+
int fsync : 1,
66+
sorted : 1;
6467
int peeling_mode;
6568
git_iterator_flag_t iterator_flags;
6669
uint32_t direach_flags;
67-
int fsync;
70+
git_sortedcache *refcache;
6871
git_map packed_refs_map;
6972
git_mutex prlock; /* protect packed_refs_map */
7073
git_futils_filestamp packed_refs_stamp;
71-
bool sorted;
7274
} refdb_fs_backend;
7375

7476
static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name);
@@ -113,6 +115,7 @@ static int packed_reload(refdb_fs_backend *backend)
113115
{
114116
int error;
115117
git_str packedrefs = GIT_STR_INIT;
118+
size_t oid_hexsize = git_oid_hexsize(backend->oid_type);
116119
char *scan, *eof, *eol;
117120

118121
if (!backend->gitpath)
@@ -158,9 +161,9 @@ static int packed_reload(refdb_fs_backend *backend)
158161

159162
/* parse "<OID> <refname>\n" */
160163

161-
if (git_oid__fromstr(&oid, scan, GIT_OID_SHA1) < 0)
164+
if (git_oid__fromstr(&oid, scan, backend->oid_type) < 0)
162165
goto parse_failed;
163-
scan += GIT_OID_SHA1_HEXSIZE;
166+
scan += oid_hexsize;
164167

165168
if (*scan++ != ' ')
166169
goto parse_failed;
@@ -179,9 +182,9 @@ static int packed_reload(refdb_fs_backend *backend)
179182
/* look for optional "^<OID>\n" */
180183

181184
if (*scan == '^') {
182-
if (git_oid__fromstr(&oid, scan + 1, GIT_OID_SHA1) < 0)
185+
if (git_oid__fromstr(&oid, scan + 1, backend->oid_type) < 0)
183186
goto parse_failed;
184-
scan += GIT_OID_SHA1_HEXSIZE + 1;
187+
scan += oid_hexsize + 1;
185188

186189
if (scan < eof) {
187190
if (!(eol = strchr(scan, '\n')))
@@ -214,19 +217,23 @@ static int packed_reload(refdb_fs_backend *backend)
214217
}
215218

216219
static int loose_parse_oid(
217-
git_oid *oid, const char *filename, git_str *file_content)
220+
git_oid *oid,
221+
const char *filename,
222+
git_str *file_content,
223+
git_oid_t oid_type)
218224
{
219225
const char *str = git_str_cstr(file_content);
226+
size_t oid_hexsize = git_oid_hexsize(oid_type);
220227

221-
if (git_str_len(file_content) < GIT_OID_SHA1_HEXSIZE)
228+
if (git_str_len(file_content) < oid_hexsize)
222229
goto corrupted;
223230

224231
/* we need to get 40 OID characters from the file */
225-
if (git_oid__fromstr(oid, str, GIT_OID_SHA1) < 0)
232+
if (git_oid__fromstr(oid, str, oid_type) < 0)
226233
goto corrupted;
227234

228235
/* If the file is longer than 40 chars, the 41st must be a space */
229-
str += GIT_OID_SHA1_HEXSIZE;
236+
str += oid_hexsize;
230237
if (*str == '\0' || git__isspace(*str))
231238
return 0;
232239

@@ -266,7 +273,7 @@ static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name)
266273
goto done;
267274

268275
/* parse OID from file */
269-
if ((error = loose_parse_oid(&oid, name, &ref_file)) < 0)
276+
if ((error = loose_parse_oid(&oid, name, &ref_file, backend->oid_type)) < 0)
270277
goto done;
271278

272279
if ((error = git_sortedcache_wlock(backend->refcache)) < 0)
@@ -437,7 +444,7 @@ static int loose_lookup(
437444
} else {
438445
git_oid oid;
439446

440-
if (!(error = loose_parse_oid(&oid, ref_name, &ref_file)) &&
447+
if (!(error = loose_parse_oid(&oid, ref_name, &ref_file, backend->oid_type)) &&
441448
out != NULL)
442449
*out = git_reference__alloc(ref_name, &oid, NULL);
443450
}
@@ -615,19 +622,24 @@ static const char *end_of_record(const char *p, const char *end)
615622
return p;
616623
}
617624

618-
static int
619-
cmp_record_to_refname(const char *rec, size_t data_end, const char *ref_name)
625+
static int cmp_record_to_refname(
626+
const char *rec,
627+
size_t data_end,
628+
const char *ref_name,
629+
git_oid_t oid_type)
620630
{
621631
const size_t ref_len = strlen(ref_name);
622632
int cmp_val;
623633
const char *end;
634+
size_t oid_hexsize = git_oid_hexsize(oid_type);
624635

625-
rec += GIT_OID_SHA1_HEXSIZE + 1; /* <oid> + space */
626-
if (data_end < GIT_OID_SHA1_HEXSIZE + 3) {
627-
/* an incomplete (corrupt) record is treated as less than ref_name */
636+
rec += oid_hexsize + 1; /* <oid> + space */
637+
638+
/* an incomplete (corrupt) record is treated as less than ref_name */
639+
if (data_end < oid_hexsize + 3)
628640
return -1;
629-
}
630-
data_end -= GIT_OID_SHA1_HEXSIZE + 1;
641+
642+
data_end -= oid_hexsize + 1;
631643

632644
end = memchr(rec, '\n', data_end);
633645
if (end)
@@ -675,6 +687,7 @@ static int packed_lookup(
675687
{
676688
int error = 0;
677689
const char *left, *right, *data_end;
690+
size_t oid_hexsize = git_oid_hexsize(backend->oid_type);
678691

679692
if ((error = packed_map_check(backend)) < 0)
680693
return error;
@@ -698,7 +711,7 @@ static int packed_lookup(
698711

699712
mid = left + (right - left) / 2;
700713
rec = start_of_record(left, mid);
701-
compare = cmp_record_to_refname(rec, data_end - rec, ref_name);
714+
compare = cmp_record_to_refname(rec, data_end - rec, ref_name, backend->oid_type);
702715

703716
if (compare < 0) {
704717
left = end_of_record(mid, right);
@@ -708,11 +721,11 @@ static int packed_lookup(
708721
const char *eol;
709722
git_oid oid, peel, *peel_ptr = NULL;
710723

711-
if (data_end - rec < GIT_OID_SHA1_HEXSIZE ||
712-
git_oid__fromstr(&oid, rec, GIT_OID_SHA1) < 0) {
724+
if (data_end - rec < (long)oid_hexsize ||
725+
git_oid__fromstr(&oid, rec, backend->oid_type) < 0) {
713726
goto parse_failed;
714727
}
715-
rec += GIT_OID_SHA1_HEXSIZE + 1;
728+
rec += oid_hexsize + 1;
716729
if (!(eol = memchr(rec, '\n', data_end - rec))) {
717730
goto parse_failed;
718731
}
@@ -724,8 +737,8 @@ static int packed_lookup(
724737

725738
if (*rec == '^') {
726739
rec++;
727-
if (data_end - rec < GIT_OID_SHA1_HEXSIZE ||
728-
git_oid__fromstr(&peel, rec, GIT_OID_SHA1) < 0) {
740+
if (data_end - rec < (long)oid_hexsize ||
741+
git_oid__fromstr(&peel, rec, backend->oid_type) < 0) {
729742
goto parse_failed;
730743
}
731744
peel_ptr = &peel;
@@ -1108,7 +1121,7 @@ static int loose_commit(git_filebuf *file, const git_reference *ref)
11081121
GIT_ASSERT_ARG(ref);
11091122

11101123
if (ref->type == GIT_REFERENCE_DIRECT) {
1111-
char oid[GIT_OID_SHA1_HEXSIZE + 1];
1124+
char oid[GIT_OID_MAX_HEXSIZE + 1];
11121125
git_oid_nfmt(oid, sizeof(oid), &ref->target.oid);
11131126

11141127
git_filebuf_printf(file, "%s\n", oid);
@@ -1224,7 +1237,7 @@ static int packed_find_peel(refdb_fs_backend *backend, struct packref *ref)
12241237
*/
12251238
static int packed_write_ref(struct packref *ref, git_filebuf *file)
12261239
{
1227-
char oid[GIT_OID_SHA1_HEXSIZE + 1];
1240+
char oid[GIT_OID_MAX_HEXSIZE + 1];
12281241
git_oid_nfmt(oid, sizeof(oid), &ref->oid);
12291242

12301243
/*
@@ -1238,7 +1251,7 @@ static int packed_write_ref(struct packref *ref, git_filebuf *file)
12381251
* The required peels have already been loaded into `ref->peel_target`.
12391252
*/
12401253
if (ref->flags & PACKREF_HAS_PEEL) {
1241-
char peel[GIT_OID_SHA1_HEXSIZE + 1];
1254+
char peel[GIT_OID_MAX_HEXSIZE + 1];
12421255
git_oid_nfmt(peel, sizeof(peel), &ref->peel);
12431256

12441257
if (git_filebuf_printf(file, "%s %s\n^%s\n", oid, ref->name, peel) < 0)
@@ -1302,7 +1315,7 @@ static int packed_remove_loose(refdb_fs_backend *backend)
13021315
continue;
13031316

13041317
/* Figure out the current id; if we find a bad ref file, skip it so we can do the rest */
1305-
if (loose_parse_oid(&current_id, lock.path_original, &ref_content) < 0)
1318+
if (loose_parse_oid(&current_id, lock.path_original, &ref_content, backend->oid_type) < 0)
13061319
continue;
13071320

13081321
/* If the ref moved since we packed it, we must not delete it */
@@ -1891,7 +1904,10 @@ static char *setup_namespace(git_repository *repo, const char *in)
18911904
return out;
18921905
}
18931906

1894-
static int reflog_alloc(git_reflog **reflog, const char *name)
1907+
static int reflog_alloc(
1908+
git_reflog **reflog,
1909+
const char *name,
1910+
git_oid_t oid_type)
18951911
{
18961912
git_reflog *log;
18971913

@@ -1903,6 +1919,8 @@ static int reflog_alloc(git_reflog **reflog, const char *name)
19031919
log->ref_name = git__strdup(name);
19041920
GIT_ERROR_CHECK_ALLOC(log->ref_name);
19051921

1922+
log->oid_type = oid_type;
1923+
19061924
if (git_vector_init(&log->entries, 0, NULL) < 0) {
19071925
git__free(log->ref_name);
19081926
git__free(log);
@@ -2032,7 +2050,10 @@ static int refdb_reflog_fs__has_log(git_refdb_backend *_backend, const char *nam
20322050
return has_reflog(backend->repo, name);
20332051
}
20342052

2035-
static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, const char *name)
2053+
static int refdb_reflog_fs__read(
2054+
git_reflog **out,
2055+
git_refdb_backend *_backend,
2056+
const char *name)
20362057
{
20372058
int error = -1;
20382059
git_str log_path = GIT_STR_INIT;
@@ -2048,7 +2069,7 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend,
20482069
backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent);
20492070
repo = backend->repo;
20502071

2051-
if (reflog_alloc(&log, name) < 0)
2072+
if (reflog_alloc(&log, name, backend->oid_type) < 0)
20522073
return -1;
20532074

20542075
if (reflog_path(&log_path, repo, name) < 0)
@@ -2086,11 +2107,11 @@ static int serialize_reflog_entry(
20862107
const git_signature *committer,
20872108
const char *msg)
20882109
{
2089-
char raw_old[GIT_OID_SHA1_HEXSIZE+1];
2090-
char raw_new[GIT_OID_SHA1_HEXSIZE+1];
2110+
char raw_old[GIT_OID_MAX_HEXSIZE + 1];
2111+
char raw_new[GIT_OID_MAX_HEXSIZE + 1];
20912112

2092-
git_oid_tostr(raw_old, GIT_OID_SHA1_HEXSIZE+1, oid_old);
2093-
git_oid_tostr(raw_new, GIT_OID_SHA1_HEXSIZE+1, oid_new);
2113+
git_oid_tostr(raw_old, GIT_OID_MAX_HEXSIZE + 1, oid_old);
2114+
git_oid_tostr(raw_new, GIT_OID_MAX_HEXSIZE + 1, oid_new);
20942115

20952116
git_str_clear(buf);
20962117

@@ -2189,10 +2210,16 @@ static int refdb_reflog_fs__write(git_refdb_backend *_backend, git_reflog *reflo
21892210
}
21902211

21912212
/* Append to the reflog, must be called under reference lock */
2192-
static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *who, const char *message)
2213+
static int reflog_append(
2214+
refdb_fs_backend *backend,
2215+
const git_reference *ref,
2216+
const git_oid *old,
2217+
const git_oid *new,
2218+
const git_signature *who,
2219+
const char *message)
21932220
{
21942221
int error, is_symbolic, open_flags;
2195-
git_oid old_id = GIT_OID_SHA1_ZERO, new_id = GIT_OID_SHA1_ZERO;
2222+
git_oid old_id, new_id;
21962223
git_str buf = GIT_STR_INIT, path = GIT_STR_INIT;
21972224
git_repository *repo = backend->repo;
21982225

@@ -2206,6 +2233,9 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co
22062233

22072234
/* From here on is_symbolic also means that it's HEAD */
22082235

2236+
git_oid_clear(&old_id, backend->oid_type);
2237+
git_oid_clear(&new_id, backend->oid_type);
2238+
22092239
if (old) {
22102240
git_oid_cpy(&old_id, old);
22112241
} else {
@@ -2402,6 +2432,7 @@ int git_refdb_backend_fs(
24022432
goto fail;
24032433

24042434
backend->repo = repository;
2435+
backend->oid_type = repository->oid_type;
24052436

24062437
if (repository->gitdir) {
24072438
backend->gitpath = setup_namespace(repository, repository->gitdir);

src/libgit2/reflog.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ int git_reflog_write(git_reflog *reflog)
7171
return db->backend->reflog_write(db->backend, reflog);
7272
}
7373

74-
int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg)
74+
int git_reflog_append(
75+
git_reflog *reflog,
76+
const git_oid *new_oid,
77+
const git_signature *committer,
78+
const char *msg)
7579
{
7680
const git_reflog_entry *previous;
7781
git_reflog_entry *entry;
@@ -104,7 +108,7 @@ int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_sign
104108
previous = git_reflog_entry_byindex(reflog, 0);
105109

106110
if (previous == NULL)
107-
git_oid__fromstr(&entry->oid_old, GIT_OID_SHA1_HEXZERO, GIT_OID_SHA1);
111+
git_oid_clear(&entry->oid_old, reflog->oid_type);
108112
else
109113
git_oid_cpy(&entry->oid_old, &previous->oid_cur);
110114

@@ -218,12 +222,8 @@ int git_reflog_drop(git_reflog *reflog, size_t idx, int rewrite_previous_entry)
218222

219223
/* If the oldest entry has just been removed... */
220224
if (idx == entrycount - 1) {
221-
git_oid zero = GIT_OID_SHA1_ZERO;
222-
223225
/* ...clear the oid_old member of the "new" oldest entry */
224-
if (git_oid_cpy(&entry->oid_old, &zero) < 0)
225-
return -1;
226-
226+
git_oid_clear(&entry->oid_old, reflog->oid_type);
227227
return 0;
228228
}
229229

src/libgit2/reflog.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
#define GIT_REFLOG_DIR_MODE 0777
1717
#define GIT_REFLOG_FILE_MODE 0666
1818

19-
#define GIT_REFLOG_SIZE_MIN (2*GIT_OID_SHA1_HEXSIZE+2+17)
20-
2119
struct git_reflog_entry {
2220
git_oid oid_old;
2321
git_oid oid_cur;
@@ -30,6 +28,7 @@ struct git_reflog_entry {
3028
struct git_reflog {
3129
git_refdb *db;
3230
char *ref_name;
31+
git_oid_t oid_type;
3332
git_vector entries;
3433
};
3534

0 commit comments

Comments
 (0)