Re: [RFC/PATCH] extend meaning of "--root" option to index comparisons
- From
Anatol Pomozov <anatol.pomozov@gmail.com>
- Date
- Sep 18, 2008, 16:31 UTC
- Message-ID
- <3665a1a00809180931t191b5a24wd58554cdb761535@mail.gmail.com>
- In-Reply-To
- <20080918092152.GA18732@coredump.intra.peff.net>
Hi, Jeff.
Thanks for your patch.
On Thu, Sep 18, 2008 at 2:21 AM, Jeff King <peff@peff.net> wrote:
Show 55 quoted lines
> The "--root" option generally means "treat any commits > without parents as a big creation event". This extends the > meaning to make an index comparison against a non-existant > HEAD into a big creation event. In other words, "if this > index _were_ to become a commit, this is how we would show > it with --root." > > Specifically, we cover the case of > > git diff --cached --root > > to show either the diff between the index and HEAD, or if > there is no HEAD, show the diff against the empty tree. > This can simplify calling scripts which must otherwise > special-case the initial commit when showing the index > status. > > We intentionally don't cover: > > - git diff --cached --root HEAD > > The user has specifically asked for HEAD, which doesn't > exist. > > - git diff-index > > The user is required to specify a tree-ish to > diff-index; if that tree-ish doesn't exist, we should > report an error. > > Signed-off-by: Jeff King <peff@peff.net> > --- > On Tue, Sep 16, 2008 at 02:21:05AM -0400, Jeff King wrote: > >> Right, that was what I meant by "incomplete". I think there are several >> other cases where giving "--root" would have expected behavior but is >> currently ignored. I'll take a closer look, but I probably won't have >> time for a few days. > > Actually, I wasn't able to find any more cases. I don't think it makes > sense to override the behavior when an explicit tree-ish is given, so > that cuts out the two places mentioned above. Though I think > that scripts using this might prefer the plumbing > diff-index, so maybe there is a better way to support this > (e.g., if --root is specified without a tree-ish, assume > HEAD or empty tree). > > diff-tree already handles --root itself. And there is no way to my > knowledge to provoke the same kind of "show the diff against its parent" > behavior via git-diff, since a single tree-ish there means "diff against > the working tree". > > And of course for diff-files, such an option makes no sense. > > Can you think of any other cases?
git log??
git log --root for empty repo should not print anything (instead of error message that we have now).
Show 5 quoted lines
> > builtin-diff.c | 7 +++++-- > revision.c | 17 ++++++++++++++--- > revision.h | 1 + > t/t4030-diff-root.sh | 21 +++++++++++++++++++++
Should documentation (man-pages) reflect your changes as well?
Show 97 quoted lines
> 4 files changed, 41 insertions(+), 5 deletions(-)
> create mode 100755 t/t4030-diff-root.sh
>
> diff --git a/builtin-diff.c b/builtin-diff.c
> index 037c303..0a1efb5 100644
> --- a/builtin-diff.c
> +++ b/builtin-diff.c
> @@ -315,8 +315,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
> break;
> else if (!strcmp(arg, "--cached")) {
> add_head_to_pending(&rev);
> - if (!rev.pending.nr)
> - die("No HEAD commit to compare with (yet)");
> + if (!rev.pending.nr) {
> + if (!rev.show_root_diff)
> + die("No HEAD commit to compare with (yet)");
> + add_empty_to_pending(&rev);
> + }
> break;
> }
> }
> diff --git a/revision.c b/revision.c
> index 499f0e0..de0fd89 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -145,16 +145,27 @@ void add_pending_object(struct rev_info *revs, struct object *obj, const char *n
> add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
> }
>
> -void add_head_to_pending(struct rev_info *revs)
> +static void add_to_pending_by_name(struct rev_info *revs, const char *name)
> {
> unsigned char sha1[20];
> struct object *obj;
> - if (get_sha1("HEAD", sha1))
> + if (get_sha1(name, sha1))
> return;
> obj = parse_object(sha1);
> if (!obj)
> return;
> - add_pending_object(revs, obj, "HEAD");
> + add_pending_object(revs, obj, name);
> +}
> +
> +void add_head_to_pending(struct rev_info *revs)
> +{
> + add_to_pending_by_name(revs, "HEAD");
> +}
> +
> +void add_empty_to_pending(struct rev_info *revs)
> +{
> + add_to_pending_by_name(revs,
> + "4b825dc642cb6eb9a060e54bf8d69288fbee4904");
> }
>
> static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
> diff --git a/revision.h b/revision.h
> index fc23522..108f43d 100644
> --- a/revision.h
> +++ b/revision.h
> @@ -151,6 +151,7 @@ extern void add_object(struct object *obj,
> extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
>
> extern void add_head_to_pending(struct rev_info *);
> +extern void add_empty_to_pending(struct rev_info *);
>
> enum commit_action {
> commit_ignore,
> diff --git a/t/t4030-diff-root.sh b/t/t4030-diff-root.sh
> new file mode 100755
> index 0000000..e5174b7
> --- /dev/null
> +++ b/t/t4030-diff-root.sh
> @@ -0,0 +1,21 @@
> +#!/bin/sh
> +
> +test_description='diff --root allows comparison between index and root'
> +. ./test-lib.sh
> +
> +test_expect_success 'setup' '
> + echo content >file &&
> + git add file
> +'
> +
> +test_expect_success 'diff --cached (without --root)' '
> + test_must_fail git diff --cached --name-only
> +'
> +
> +test_expect_success 'diff --cached (with --root)' '
> + echo file >expect &&
> + git diff --cached --name-only --root >actual &&
> + test_cmp expect actual
> +'
> +
> +test_done
> --
> 1.6.0.2.249.g97d7f.dirty-- anatol