From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Ramsay Jones <ramsay@ramsayjones.plus.com>,
Gregoire Geis <opensource@gregoirege.is>
Subject: [PATCH v2] diff: --no-index should ignore the worktree
Date: Sat, 09 Aug 2025 17:20:36 -0700 [thread overview]
Message-ID: <xmqq1ppk58ob.fsf@gitster.g> (raw)
The act of giving "--no-index" tells Git to pretend that the current
directory is not under control of any Git index or repository, so
even when you happen to be in a Git controlled working tree, where
in that working tree should not matter.
But the start-up sequence tries to discover the top of the working
tree and chdir(2)'s there, even before Git passes control to the
subcommand being run. When diff_no_index() starts running, it
starts at a wrong (from the end-user's point of view who thinks "git
diff --no-index" is merely a better version of GNU diff) directory,
and the original directory the user started the command is at
"prefix".
Because the paths given from argv[] have already been adjusted to
account for this path shuffling by prepending the prefix, and
showing the resulting path by stripping the prefix, the effect of
these nonsense operations (nonsense in the context of "--no-index",
that is) is usually not observable.
Except for special cases like "-", where it is not preprocessed by
prepending the prefix.
Instead of papering over by adding more special cases only to cater
to the no-index codepath in the generic code, drive the diff
machinery more faithfully to what is going on. If the user started
"git diff --no-index" in directory X/Y/Z in a working tree
controlled by Git, and the start up sequence of Git chdir(2)'ed up
to directory X and left Y/Z in the prefix, revert the effect of the
start up sequence by chdir'ing back to Y/Z and emptying the prefix.
Reported-by: Gregoire Geis <opensource@gregoirege.is>
Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/diff.c | 15 +++++++++++++++
t/t4053-diff-no-index.sh | 17 +++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/builtin/diff.c b/builtin/diff.c
index 9a89e25a98..0b23c41456 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -487,6 +487,21 @@ int cmd_diff(int argc,
init_diff_ui_defaults();
repo_config(the_repository, git_diff_ui_config, NULL);
+
+ /*
+ * If we are ignoring the fact that our current directory may
+ * be part of a working tree controlled by a Git repository to
+ * pretend to be a "better GNU diff", we should undo the
+ * effect of the setup code that did a chdir() to the top of
+ * the working tree. Where we came from is recorded in the
+ * prefix.
+ */
+ if (no_index && prefix) {
+ if (chdir(prefix))
+ die(_("cannot come back to cwd"));
+ prefix = NULL;
+ }
+
prefix = precompose_argv_prefix(argc, argv, prefix);
repo_init_revisions(the_repository, &rev, prefix);
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 01db9243ab..44b4b13f5d 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -26,6 +26,23 @@ test_expect_success 'git diff --no-index directories' '
test_line_count = 14 cnt
'
+test_expect_success 'git diff --no-index with -' '
+ cat >expect <<-\EOF &&
+ diff --git a/- b/-
+ new file mode 100644
+ --- /dev/null
+ +++ b/-
+ @@ -0,0 +1 @@
+ +frotz
+ EOF
+ (
+ cd a &&
+ echo frotz |
+ test_expect_code 1 git diff --no-index /dev/null - >../actual
+ ) &&
+ test_cmp expect actual
+'
+
test_expect_success 'git diff --no-index relative path outside repo' '
(
cd repo &&
Range-diff against v1:
1: 456a265746 ! 1: 4166ccb163 diff: --no-index should ignore the worktree
@@ builtin/diff.c: int cmd_diff(int argc,
+ * prefix.
+ */
+ if (no_index && prefix) {
-+ chdir(prefix);
++ if (chdir(prefix))
++ die(_("cannot come back to cwd"));
+ prefix = NULL;
+ }
+
--
2.51.0-rc1-130-g831cc762e6
next reply other threads:[~2025-08-10 0:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-10 0:20 Junio C Hamano [this message]
2025-08-12 14:37 ` [PATCH v2] diff: --no-index should ignore the worktree opensource
2025-08-12 15:07 ` Junio C Hamano
2025-08-15 22:01 ` [PATCH] diff: simplify --no-index taking advantage of the fact that prefix==NULL Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqq1ppk58ob.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=opensource@gregoirege.is \
--cc=ramsay@ramsayjones.plus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).