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@xxxxxxxx> --- 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? builtin-diff.c | 7 +++++-- revision.c | 17 ++++++++++++++--- revision.h | 1 + t/t4030-diff-root.sh | 21 +++++++++++++++++++++ 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 -- 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