On Fri, Nov 12, 2021 at 5:42 PM Han Xin <chiyutianyi@xxxxxxxxx> wrote: > > From: Han Xin <hanxin.hx@xxxxxxxxxxxxxxx> > > 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. > Helped-by: Jiang Xin <zhiyou.jx@xxxxxxxxxxxxxxx> > Signed-off-by: Han Xin <hanxin.hx@xxxxxxxxxxxxxxx> > --- > 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 >