diff: support --cached on unborn branches
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Thu, 3 Feb 2011 06:23:34 +0000 (13:23 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 Feb 2011 23:04:30 +0000 (15:04 -0800)
"git diff --cached" (without revision) used to mean "git diff --cached
HEAD" (i.e. the user was too lazy to type HEAD). This "correctly"
failed when there was no commit yet. But was that correctness useful?

This patch changes the definition of what particular command means.
It is a request to show what _would_ be committed without further "git
add". The internal implementation is the same "git diff --cached HEAD"
when HEAD exists, but when there is no commit yet, it compares the index
with an empty tree object to achieve the desired result.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-diff.txt
builtin/diff.c
t/t4013-diff-various.sh
t/t4013/diff.diff_--cached [new file with mode: 0644]
t/t4013/diff.diff_--cached_--_file0 [new file with mode: 0644]
index f6ac847507a635759323565be44b088b479d8bf0..49105102dbf899c62833572fdda51cefaed53476 100644 (file)
@@ -38,6 +38,8 @@ directories. This behavior can be forced by --no-index.
        commit relative to the named <commit>.  Typically you
        would want comparison with the latest commit, so if you
        do not give <commit>, it defaults to HEAD.
+       If HEAD does not exist (e.g. unborned branches) and
+       <commit> is not given, it shows all staged changes.
        --staged is a synonym of --cached.
 
 'git diff' [--options] <commit> [--] [<path>...]::
index 945e7583a8294f0612682f3228687498e5c61822..42822cd5374dbcf0e63c17078a55284c432ddc77 100644 (file)
@@ -330,8 +330,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                        else if (!strcmp(arg, "--cached") ||
                                 !strcmp(arg, "--staged")) {
                                add_head_to_pending(&rev);
-                               if (!rev.pending.nr)
-                                       die("No HEAD commit to compare with (yet)");
+                               if (!rev.pending.nr) {
+                                       struct tree *tree;
+                                       tree = lookup_tree((const unsigned char*)EMPTY_TREE_SHA1_BIN);
+                                       add_pending_object(&rev, &tree->object, "HEAD");
+                               }
                                break;
                        }
                }
index 9a665205884fcdb1c5888558d6edf960e335e013..b8f81d07c33d3596fef5f5a361f4774d5e357fca 100755 (executable)
@@ -290,4 +290,15 @@ test_expect_success 'log -S requires an argument' '
        test_must_fail git log -S
 '
 
+test_expect_success 'diff --cached on unborn branch' '
+       echo ref: refs/heads/unborn >.git/HEAD &&
+       git diff --cached >result &&
+       test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached" result
+'
+
+test_expect_success 'diff --cached -- file on unborn branch' '
+       git diff --cached -- file0 >result &&
+       test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" result
+'
+
 test_done
diff --git a/t/t4013/diff.diff_--cached b/t/t4013/diff.diff_--cached
new file mode 100644 (file)
index 0000000..ff16e83
--- /dev/null
@@ -0,0 +1,38 @@
+diff --git a/dir/sub b/dir/sub
+new file mode 100644
+index 0000000..992913c
+--- /dev/null
++++ b/dir/sub
+@@ -0,0 +1,8 @@
++A
++B
++C
++D
++E
++F
++1
++2
+diff --git a/file0 b/file0
+new file mode 100644
+index 0000000..10a8a9f
+--- /dev/null
++++ b/file0
+@@ -0,0 +1,9 @@
++1
++2
++3
++4
++5
++6
++A
++B
++C
+diff --git a/file1 b/file1
+new file mode 100644
+index 0000000..b1e6722
+--- /dev/null
++++ b/file1
+@@ -0,0 +1,3 @@
++A
++B
++C
diff --git a/t/t4013/diff.diff_--cached_--_file0 b/t/t4013/diff.diff_--cached_--_file0
new file mode 100644 (file)
index 0000000..b9bb858
--- /dev/null
@@ -0,0 +1,15 @@
+diff --git a/file0 b/file0
+new file mode 100644
+index 0000000..10a8a9f
+--- /dev/null
++++ b/file0
+@@ -0,0 +1,9 @@
++1
++2
++3
++4
++5
++6
++A
++B
++C