Thread (183 messages) 183 messages, 9 authors, 2022-06-11

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(&parano_oid, &c);
-       if (!oideq(oid, &parano_oid))
+       if (!is_null_oid(oid) && !oideq(oid, &parano_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, &parano_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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help