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

[PATCH] diff: support --cached on unborn branches

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 3, 2011, 06:23 UTC
Message-ID
<1296714214-5165-1-git-send-email-pclouds@gmail.com>
In-Reply-To
<20101031032413.GA27346@do>

"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 still 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.

(Written by Junio)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 (Good) old stuff. I think it wasn't accepted because I was lazy in
 updating docs. Resend (with doc updates).
 Documentation/git-diff.txt          |    2 +
 builtin/diff.c                      |    7 ++++-
 t/t4013-diff-various.sh             |   11 ++++++++++
 t/t4013/diff.diff_--cached          |   38 +++++++++++++++++++++++++++++++++++
 t/t4013/diff.diff_--cached_--_file0 |   15 +++++++++++++
 5 files changed, 71 insertions(+), 2 deletions(-)
 create mode 100644 t/t4013/diff.diff_--cached
 create mode 100644 t/t4013/diff.diff_--cached_--_file0
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index f6ac847..4910510 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -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>...]::
diff --git a/builtin/diff.c b/builtin/diff.c
index 945e758..42822cd 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -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;
 			}
 		}
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 9a66520..b8f81d0 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -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
index 0000000..ff16e83
--- /dev/null
+++ b/t/t4013/diff.diff_--cached
@@ -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
index 0000000..b9bb858
--- /dev/null
+++ b/t/t4013/diff.diff_--cached_--_file0
@@ -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
-- 
1.7.3.4.878.g439c7
Previous: Nguyen Thai Ngoc DuyNext: Jeff King
Message 8 of 9 in “diff: support --root --cached combination”
  1. diff: support --root --cached combinationNguyễn Thái Ngọc Duy, Oct 29, 2010
  2. Jonathan NiederOct 29, 2010
  3. Nguyen Thai Ngoc DuyOct 29, 2010
  4. Junio C HamanoOct 29, 2010
  5. diff: support --cached on unborn branchesNguyễn Thái Ngọc Duy, Oct 30, 2010
  6. Junio C HamanoOct 31, 2010
  7. Nguyen Thai Ngoc DuyOct 31, 2010
  8. diff: support --cached on unborn branchesNguyễn Thái Ngọc Duy, Feb 3, 2011
  9. Jeff KingOct 29, 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.