From: Christian Couder Date: Fri, 06 Jun 2014 15:29:01 GMT Subject: Re: [PATCH v3 1/4] replace: add --graft option Message-ID: In-Reply-To: On Thu, Jun 5, 2014 at 11:49 PM, Junio C Hamano wrote: > Christian Couder writes: > >> +static int create_graft(int argc, const char **argv, int force) >> +{ >> + unsigned char old[20], new[20]; >> + const char *old_ref = argv[0]; >> + struct commit *commit; >> + struct strbuf buf = STRBUF_INIT; >> + struct strbuf new_parents = STRBUF_INIT; >> + const char *parent_start, *parent_end; >> + int i; >> + >> + if (get_sha1(old_ref, old) < 0) >> + die(_("Not a valid object name: '%s'"), old_ref); >> + commit = lookup_commit_or_die(old, old_ref); > > Not a problem with this patch, but the above sequence somehow makes > me wonder if lookup-commit-or-die is a good API for this sort of > thing. Wouldn't it be more natural if it took not "unsigned char > old[20]" but anything that would be understood by get_sha1()? > > It could be that this particular caller is peculiar and all the > existing callers are happy, though. I didn't "git grep" to spot > patterns in existing callers. lookup_commit_or_die() looked like a good API to me because I saw that it checked a lot of things and die in case of problems, which could make the patch shorter. >> + if (read_sha1_commit(old, &buf)) >> + die(_("Invalid commit: '%s'"), old_ref); >> + /* make sure the commit is not corrupt */ >> + if (parse_commit_buffer(commit, buf.buf, buf.len)) >> + die(_("Could not parse commit: '%s'"), old_ref); > > It is unclear to me what you are trying to achieve with these two. > If the earlier lookup-commit has returned a commit object that has > already been parsed, parse_commit_buffer() would not check anything, > would it? Yeah, you are right. I missed the fact that lookup_commit_or_die() calls parse_object() which itself calls read_sha1_file() and then parse_object_buffer() which calls parse_commit_buffer(). Here is a backtrace that shows this: #0 parse_commit_buffer (item=0x8597b0, buffer=0x851730, size=228) at commit.c:251 #1 0x00000000004fa215 in parse_object_buffer (sha1=0x7fffffffdbf0 "\t>A\247\235J\213\376A\247\235J\213\376A\247\235J\213\376A\247\235J\213\376A\247\235J\213\376 A typical sequence would look more like this: > > commit = lookup_commit(...); > if (parse_commit(commit)) > oops there is an error; > /* otherwise */ > use(commit->buffer); > > without reading a commit object using low-level read-sha1-file > interface yourself, no? Yeah, or I could just rely on the fact that lookup_commit_or_die() already parses the commit, with something like this: if (get_sha1(old_ref, old) < 0) die(_("Not a valid object name: '%s'"), old_ref); /* parse the commit buffer to make sure the commit is not corrupt */ commit = lookup_commit_or_die(old, old_ref); /* find existing parents */ parent_start = buf.buf; parent_start += 46; /* "tree " + "hex sha1" + "\n" */ parent_end = parent_start; ... Thanks, Christian.