Skip to content

Commit fe2ee3a

Browse files
committed
object: lookup sha256 objects
This is much of the plumbing for the object database to support SHA256, and for objects to be able to parse SHA256 versions of themselves.
1 parent 6204499 commit fe2ee3a

File tree

29 files changed

+961
-174
lines changed

29 files changed

+961
-174
lines changed

examples/index-pack.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,18 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv)
2828
return EXIT_FAILURE;
2929
}
3030

31-
if (git_indexer_new(&idx, ".", 0, NULL, NULL) < 0) {
31+
#ifdef GIT_EXPERIMENTAL_SHA256
32+
error = git_indexer_new(&idx, ".", git_repository_oid_type(repo), NULL);
33+
#else
34+
error = git_indexer_new(&idx, ".", 0, NULL, NULL);
35+
#endif
36+
37+
if (error < 0) {
3238
puts("bad idx");
3339
return -1;
3440
}
3541

42+
3643
if ((fd = open(argv[1], 0)) < 0) {
3744
perror("open");
3845
return -1;

fuzzers/objects_fuzzer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
3939
* to do.
4040
*/
4141
for (i = 0; i < ARRAY_SIZE(types); i++) {
42-
if (git_object__from_raw(&object, (const char *) data, size, types[i]) < 0)
42+
if (git_object__from_raw(&object, (const char *) data, size, types[i], GIT_OID_SHA1) < 0)
4343
continue;
4444
git_object_free(object);
4545
object = NULL;

fuzzers/packfile_fuzzer.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
6767
git_str path = GIT_STR_INIT;
6868
git_oid oid;
6969
bool append_hash = false;
70+
int error;
7071

7172
if (size == 0)
7273
return 0;
@@ -82,7 +83,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
8283
abort();
8384
}
8485

85-
if (git_indexer_new(&indexer, ".", 0, odb, NULL) < 0) {
86+
#ifdef GIT_EXPERIMENTAL_SHA256
87+
error = git_indexer_new(&indexer, ".", GIT_OID_SHA1, NULL);
88+
#else
89+
error = git_indexer_new(&indexer, ".", 0, odb, NULL);
90+
#endif
91+
92+
if (error < 0) {
8693
fprintf(stderr, "Failed to create the indexer: %s\n",
8794
git_error_last()->message);
8895
abort();

include/git2/indexer.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ typedef int GIT_CALLBACK(git_indexer_progress_cb)(const git_indexer_progress *st
6262
typedef struct git_indexer_options {
6363
unsigned int version;
6464

65+
#ifdef GIT_EXPERIMENTAL_SHA256
66+
/** permissions to use creating packfile or 0 for defaults */
67+
unsigned int mode;
68+
69+
/**
70+
* object database from which to read base objects when
71+
* fixing thin packs. This can be NULL if there are no thin
72+
* packs; if a thin pack is encountered, an error will be
73+
* returned if there are bases missing.
74+
*/
75+
git_odb *odb;
76+
#endif
77+
6578
/** progress_cb function to call with progress information */
6679
git_indexer_progress_cb progress_cb;
6780

@@ -87,6 +100,21 @@ GIT_EXTERN(int) git_indexer_options_init(
87100
git_indexer_options *opts,
88101
unsigned int version);
89102

103+
#ifdef GIT_EXPERIMENTAL_SHA256
104+
/**
105+
* Create a new indexer instance
106+
*
107+
* @param out where to store the indexer instance
108+
* @param path to the directory where the packfile should be stored
109+
* @param oid_type the oid type to use for objects
110+
* @return 0 or an error code.
111+
*/
112+
GIT_EXTERN(int) git_indexer_new(
113+
git_indexer **out,
114+
const char *path,
115+
git_oid_t oid_type,
116+
git_indexer_options *opts);
117+
#else
90118
/**
91119
* Create a new indexer instance
92120
*
@@ -106,6 +134,7 @@ GIT_EXTERN(int) git_indexer_new(
106134
unsigned int mode,
107135
git_odb *odb,
108136
git_indexer_options *opts);
137+
#endif
109138

110139
/**
111140
* Add data to the indexer

include/git2/object.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ GIT_EXTERN(int) git_object_peel(
225225
*/
226226
GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
227227

228+
#ifdef GIT_EXPERIMENTAL_SHA256
228229
/**
229230
* Analyzes a buffer of raw object content and determines its validity.
230231
* Tree, commit, and tag objects will be parsed and ensured that they
@@ -238,14 +239,39 @@ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
238239
* @param valid Output pointer to set with validity of the object content
239240
* @param buf The contents to validate
240241
* @param len The length of the buffer
241-
* @param type The type of the object in the buffer
242+
* @param object_type The type of the object in the buffer
243+
* @param oid_type The object ID type for the OIDs in the given buffer
242244
* @return 0 on success or an error code
243245
*/
244246
GIT_EXTERN(int) git_object_rawcontent_is_valid(
245247
int *valid,
246248
const char *buf,
247249
size_t len,
248-
git_object_t type);
250+
git_object_t object_type,
251+
git_oid_t oid_type);
252+
#else
253+
/**
254+
* Analyzes a buffer of raw object content and determines its validity.
255+
* Tree, commit, and tag objects will be parsed and ensured that they
256+
* are valid, parseable content. (Blobs are always valid by definition.)
257+
* An error message will be set with an informative message if the object
258+
* is not valid.
259+
*
260+
* @warning This function is experimental and its signature may change in
261+
* the future.
262+
*
263+
* @param valid Output pointer to set with validity of the object content
264+
* @param buf The contents to validate
265+
* @param len The length of the buffer
266+
* @param object_type The type of the object in the buffer
267+
* @return 0 on success or an error code
268+
*/
269+
GIT_EXTERN(int) git_object_rawcontent_is_valid(
270+
int *valid,
271+
const char *buf,
272+
size_t len,
273+
git_object_t object_type);
274+
#endif
249275

250276
/** @} */
251277
GIT_END_DECL

src/cli/cmd_hash_object.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,37 @@ static void print_help(void)
4949
cli_opt_help_fprint(stdout, opts);
5050
}
5151

52-
static int hash_buf(git_odb *odb, git_str *buf, git_object_t type)
52+
static int hash_buf(
53+
git_odb *odb,
54+
git_str *buf,
55+
git_object_t object_type,
56+
git_oid_t oid_type)
5357
{
5458
git_oid oid;
5559

5660
if (!literally) {
5761
int valid = 0;
5862

59-
if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, type) < 0 || !valid)
63+
#ifdef GIT_EXPERIMENTAL_SHA256
64+
if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, object_type, oid_type) < 0 || !valid)
65+
return cli_error_git();
66+
#else
67+
GIT_UNUSED(oid_type);
68+
69+
if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, object_type) < 0 || !valid)
6070
return cli_error_git();
71+
#endif
6172
}
6273

6374
if (write_object) {
64-
if (git_odb_write(&oid, odb, buf->ptr, buf->size, type) < 0)
75+
if (git_odb_write(&oid, odb, buf->ptr, buf->size, object_type) < 0)
6576
return cli_error_git();
6677
} else {
6778
#ifdef GIT_EXPERIMENTAL_SHA256
68-
if (git_odb_hash(&oid, buf->ptr, buf->size, type, GIT_OID_SHA1) < 0)
79+
if (git_odb_hash(&oid, buf->ptr, buf->size, object_type, GIT_OID_SHA1) < 0)
6980
return cli_error_git();
7081
#else
71-
if (git_odb_hash(&oid, buf->ptr, buf->size, type) < 0)
82+
if (git_odb_hash(&oid, buf->ptr, buf->size, object_type) < 0)
7283
return cli_error_git();
7384
#endif
7485
}
@@ -83,9 +94,10 @@ int cmd_hash_object(int argc, char **argv)
8394
{
8495
git_repository *repo = NULL;
8596
git_odb *odb = NULL;
97+
git_oid_t oid_type;
8698
git_str buf = GIT_STR_INIT;
8799
cli_opt invalid_opt;
88-
git_object_t type = GIT_OBJECT_BLOB;
100+
git_object_t object_type = GIT_OBJECT_BLOB;
89101
char **filename;
90102
int ret = 0;
91103

@@ -97,7 +109,7 @@ int cmd_hash_object(int argc, char **argv)
97109
return 0;
98110
}
99111

100-
if (type_name && (type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID)
112+
if (type_name && (object_type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID)
101113
return cli_error_usage("invalid object type '%s'", type_name);
102114

103115
if (write_object &&
@@ -107,6 +119,8 @@ int cmd_hash_object(int argc, char **argv)
107119
goto done;
108120
}
109121

122+
oid_type = git_repository_oid_type(repo);
123+
110124
/*
111125
* TODO: we're reading blobs, we shouldn't pull them all into main
112126
* memory, we should just stream them into the odb instead.
@@ -118,7 +132,7 @@ int cmd_hash_object(int argc, char **argv)
118132
goto done;
119133
}
120134

121-
if ((ret = hash_buf(odb, &buf, type)) != 0)
135+
if ((ret = hash_buf(odb, &buf, object_type, oid_type)) != 0)
122136
goto done;
123137
} else {
124138
for (filename = filenames; *filename; filename++) {
@@ -127,7 +141,7 @@ int cmd_hash_object(int argc, char **argv)
127141
goto done;
128142
}
129143

130-
if ((ret = hash_buf(odb, &buf, type)) != 0)
144+
if ((ret = hash_buf(odb, &buf, object_type, oid_type)) != 0)
131145
goto done;
132146
}
133147
}

src/libgit2/blob.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,25 @@ void git_blob__free(void *_blob)
5252
git__free(blob);
5353
}
5454

55-
int git_blob__parse_raw(void *_blob, const char *data, size_t size)
55+
int git_blob__parse_raw(void *_blob, const char *data, size_t size, git_oid_t oid_type)
5656
{
5757
git_blob *blob = (git_blob *) _blob;
5858

5959
GIT_ASSERT_ARG(blob);
60+
GIT_UNUSED(oid_type);
6061

6162
blob->raw = 1;
6263
blob->data.raw.data = data;
6364
blob->data.raw.size = size;
6465
return 0;
6566
}
6667

67-
int git_blob__parse(void *_blob, git_odb_object *odb_obj)
68+
int git_blob__parse(void *_blob, git_odb_object *odb_obj, git_oid_t oid_type)
6869
{
6970
git_blob *blob = (git_blob *) _blob;
7071

7172
GIT_ASSERT_ARG(blob);
73+
GIT_UNUSED(oid_type);
7274

7375
git_cached_obj_incref((git_cached_obj *)odb_obj);
7476
blob->raw = 0;

src/libgit2/blob.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ struct git_blob {
3636
} while(0)
3737

3838
void git_blob__free(void *blob);
39-
int git_blob__parse(void *blob, git_odb_object *obj);
40-
int git_blob__parse_raw(void *blob, const char *data, size_t size);
39+
int git_blob__parse(void *blob, git_odb_object *obj, git_oid_t oid_type);
40+
int git_blob__parse_raw(void *blob, const char *data, size_t size, git_oid_t oid_type);
4141
int git_blob__getbuf(git_str *buffer, git_blob *blob);
4242

4343
extern int git_blob__create_from_paths(

0 commit comments

Comments
 (0)