git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH RFC] parse_object: pass on the original sha1, not the replaced one

From
Christian Couder <chriscool@tuxfamily.org>
Date
Aug 14, 2010, 02:03 UTC
Message-ID
<201008140403.33164.chriscool@tuxfamily.org>
In-Reply-To
<AANLkTinmJ0=VxFAaCXNjB2WAiPYHq3jXmRnzVoEiw_-f@mail.gmail.com>
On Friday 13 August 2010 11:02:40 Nguyen Thai Ngoc Duy wrote:
Show 31 quoted lines
> On Fri, Aug 13, 2010 at 1:59 PM, Christian Couder
> 
> <chriscool@tuxfamily.org> wrote:
> > On Saturday 07 August 2010 06:03:05 Nguyen Thai Ngoc Duy wrote:
> >> On Thu, Aug 5, 2010 at 9:41 PM, Christian Couder
> >> 
> >> <chriscool@tuxfamily.org> wrote:
> >> > It looks like parse_commit() is buggy regarding replaced objects. But
> >> > I am not sure how it should be fixed.
> >> 
> >> It could be fixed the same way you did with parse_object(): replace
> >> read_sha1_file() with read_sha1_file_repl(). You would also need to
> >> fix parse_tree() and parse_tag(). But..
> >> 
> >> > Anyway if you use parse_object(), then you don't need parse_commit().
> >> > So if possible you should use parse_object() instead of both
> >> > lookup_commit() and parse_commit().
> >> 
> >> That's how those functions are used. For example, in
> >> traverse_commit_list(), lookup_*() may be called and uninteresting
> >> objects marked UNINTERESTING. Later on in process_{tree,blob,tag},
> >> parse_* may be called if their content is interesting.
> >> 
> >> To me, the fix above will leave a gap when object->sha1 is the
> >> original sha1, until parse_*() is called. It just does not sound good.
> > 
> > What do you think about adding a parse_commit_repl() function like the
> > patch below and then using it instead of parse_commit()?
> 
> How do you plan to use this new function? #define parse_commit(c)
> parse_commit_repl(c) or use the new function explictly when needed?
We have to use the new function explicitly instead of parse_commit() but I 
think in most cases we just need to change parse_commit(stuff) into 
parse_commit_repl(&stuff) and it will work.
 
> You are going to need parse_tree_repl() too 
Yes, probably, I did not look at that yet.
> unless you declare
> tree/blob replacement is not supported and make git-replace refuse
> blob/tree replacement.

I think they should be supported as much as possible in the long run but it is not as important as supporting commits.

> Another thing to address is, there will be a duration between
> lookup_commit() and parse_commit_repl(), where object.sha1 is the
> original one. If it is saved elsewhere, troubles are ahead.

Yes, parse_commit_repl() may not be the only solution needed in some cases but I think it is good enough in most cases.

Show 39 quoted lines
> > ------- >8 ---------------------------------------------------
> > 
> > diff --git a/commit.c b/commit.c
> > index 652c1ba..183a735 100644
> > --- a/commit.c
> > +++ b/commit.c
> > @@ -316,6 +316,50 @@ int parse_commit(struct commit *item)
> >        return ret;
> >  }
> > 
> > +int parse_commit_repl(struct commit **commit)
> > +{
> > +       enum object_type type;
> > +       void *buffer;
> > +       unsigned long size;
> > +       int ret;
> > +       const unsigned char *repl;
> > +       struct commit *item = *commit;
> > +
> > +       if (!item)
> > +               return -1;
> > +       if (item->object.parsed)
> > +               return 0;
> > +       buffer = read_sha1_file_repl(item->object.sha1, &type, &size,
> > &repl); +       if (!buffer)
> > +               return error("Could not read %s",
> > +                            sha1_to_hex(item->object.sha1));
> > +
> > +       if (item->object.sha1 != repl) {
> > +               struct commit *repl_item = lookup_commit(repl);
> > +               if (!repl_item) {
> > +                       free(buffer);
> > +                       return error("Bad replacement %s for commit %s",
> > +                                    sha1_to_hex(repl),
> > +                                    sha1_to_hex(item->object.sha1));
> > +               }
> 
> You need to use lookup_object() instead here. lookup_commit() wil
> create new object if "repl" is not found.

We are inside the "if (item->object.sha1 != repl)" block, so we know that we will have to do "*commit = repl_item" with a repl_item that is different from item. So we have to create the repl_item commit if it doesn't exist.

Thanks, Christian.

Previous: Nguyen Thai Ngoc Duy
Message 14 of 14 in “parse_object: pass on the original sha1, not the replaced one”
  1. parse_object: pass on the original sha1, not the replaced oneNguyễn Thái Ngọc Duy, Jul 31, 2010
  2. Christian CouderAug 2, 2010
  3. Nguyen Thai Ngoc DuyAug 2, 2010
  4. Christian CouderAug 3, 2010
  5. Nguyen Thai Ngoc DuyAug 3, 2010
  6. Christian CouderAug 4, 2010
  7. Nguyen Thai Ngoc DuyAug 4, 2010
  8. Christian CouderAug 4, 2010
  9. Nguyen Thai Ngoc DuyAug 4, 2010
  10. Christian CouderAug 5, 2010
  11. Nguyen Thai Ngoc DuyAug 7, 2010
  12. Christian CouderAug 13, 2010
  13. Nguyen Thai Ngoc DuyAug 13, 2010
  14. Christian CouderAug 14, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.