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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday 13 August 2010 11:02:40 Nguyen Thai Ngoc Duy wrote:
> On Fri, Aug 13, 2010 at 1:59 PM, Christian Couder
> 
> <chriscool@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> 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.

> > ------- >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.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]