Re: [PATCH v2 3/6] object-file.c: handle nil oid in write_loose_object()
From: Jiang Xin <hidden>
Date: 2021-11-18 05:50:01
On Fri, Nov 12, 2021 at 5:42 PM Han Xin [off-list ref] wrote:
From: Han Xin <redacted> When read input stream, oid can't get before reading all, and it will be filled after reading.
Under what circumstances is the oid a null oid? Can we get the oid from “obj_list[nr].oid” ? See unpack_non_delta_entry() of builtin/unpack-objects.c.
quoted hunk ↗ jump to hunk
Helped-by: Jiang Xin [off-list ref] Signed-off-by: Han Xin <redacted> --- object-file.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-)diff --git a/object-file.c b/object-file.c index b0838c847e..8393659f0d 100644 --- a/object-file.c +++ b/object-file.c@@ -1893,7 +1893,13 @@ static int write_loose_object(const struct object_id *oid, char *hdr, const char *buf; unsigned long len; - loose_object_path(the_repository, &filename, oid); + if (is_null_oid(oid)) { + /* When oid is not determined, save tmp file to odb path. */ + strbuf_reset(&filename); + strbuf_addstr(&filename, the_repository->objects->odb->path); + strbuf_addch(&filename, '/'); + } else + loose_object_path(the_repository, &filename, oid); if (!dry_run) { fd = create_tmpfile(&tmp_file, filename.buf);@@ -1942,7 +1948,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid), ret); the_hash_algo->final_oid_fn(¶no_oid, &c); - if (!oideq(oid, ¶no_oid)) + if (!is_null_oid(oid) && !oideq(oid, ¶no_oid)) die(_("confused by unstable object source data for %s"), oid_to_hex(oid));@@ -1951,6 +1957,30 @@ static int write_loose_object(const struct object_id *oid, char *hdr, close_loose_object(fd); + if (is_null_oid(oid)) { + int dirlen; + + /* copy oid */ + oidcpy((struct object_id *)oid, ¶no_oid); + /* We get the oid now */ + loose_object_path(the_repository, &filename, oid); + + dirlen = directory_size(filename.buf); + if (dirlen) { + struct strbuf dir = STRBUF_INIT; + /* + * Make sure the directory exists; note that the + * contents of the buffer are undefined after mkstemp + * returns an error, so we have to rewrite the whole + * buffer from scratch. + */ + strbuf_reset(&dir); + strbuf_add(&dir, filename.buf, dirlen - 1); + if (mkdir(dir.buf, 0777) && errno != EEXIST) + return -1; + } + } + if (mtime) { struct utimbuf utb; utb.actime = mtime; --2.33.1.44.g9344627884.agit.6.5.4