diff mbox series

[2/2] diff: implement --no-optional-locks

Message ID 3ba3113738e913d51156703b7cf86daf43c7d1b4.1741240685.git.gitgitgadget@gmail.com (mailing list archive)
State New
Headers show
Series describe and diff: implement --no-optional-locks | expand

Commit Message

Benjamin Woodruff March 6, 2025, 5:58 a.m. UTC
From: Benjamin Woodruff <benjamin.woodruff@vercel.com>

When used with `autoRefreshIndex`, `git diff` may update the index in
the background for similar performance reasons to `git-status`.

This commit implements the `--no-optional-locks` option for `git diff`,
which allows scripts to bypass this behavior.

Signed-off-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
---
 Documentation/config/diff.adoc     |  4 ++-
 Documentation/git.adoc             |  3 +-
 builtin/diff.c                     |  4 +++
 t/meson.build                      |  1 +
 t/t4070-diff-auto-refresh-index.sh | 46 ++++++++++++++++++++++++++++++
 5 files changed, 56 insertions(+), 2 deletions(-)
 create mode 100755 t/t4070-diff-auto-refresh-index.sh
diff mbox series

Patch

diff --git a/Documentation/config/diff.adoc b/Documentation/config/diff.adoc
index 1135a62a0ad..2dadcf7a1da 100644
--- a/Documentation/config/diff.adoc
+++ b/Documentation/config/diff.adoc
@@ -6,7 +6,9 @@ 
 	contents in the work tree match the contents in the
 	index.  This option defaults to `true`.  Note that this
 	affects only `git diff` Porcelain, and not lower level
-	`diff` commands such as `git diff-files`.
+	`diff` commands such as `git diff-files`. If
+	`--no-optional-locks` is set (see linkgit:git[1] for
+	details), the index file is not updated.
 
 `diff.dirstat`::
 ifdef::git-diff[]
diff --git a/Documentation/git.adoc b/Documentation/git.adoc
index f084b2f0f1e..754880b8672 100644
--- a/Documentation/git.adoc
+++ b/Documentation/git.adoc
@@ -190,7 +190,8 @@  If you just want to run git as if it was started in `<path>` then use
 --no-optional-locks::
 	Do not perform optional operations that require locks. This is
 	equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`. This
-	functionality is implemented for `git status` and `git describe`.
+	functionality is implemented for `git status`, `git describe`,
+	and `git diff`.
 
 --no-advice::
 	Disable all advice hints from being printed.
diff --git a/builtin/diff.c b/builtin/diff.c
index a4fffee42c6..5469e58bf5d 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -9,6 +9,7 @@ 
 
 #include "builtin.h"
 #include "config.h"
+#include "environment.h"
 #include "ewah/ewok.h"
 #include "lockfile.h"
 #include "color.h"
@@ -239,6 +240,9 @@  static void refresh_index_quietly(void)
 	struct lock_file lock_file = LOCK_INIT;
 	int fd;
 
+	if (!use_optional_locks())
+		return;
+
 	fd = repo_hold_locked_index(the_repository, &lock_file, 0);
 	if (fd < 0)
 		return;
diff --git a/t/meson.build b/t/meson.build
index a59da26be3f..10d7cace3c6 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -500,6 +500,7 @@  integration_tests = [
   't4067-diff-partial-clone.sh',
   't4068-diff-symmetric-merge-base.sh',
   't4069-remerge-diff.sh',
+  't4070-diff-auto-refresh-index.sh',
   't4100-apply-stat.sh',
   't4101-apply-nonl.sh',
   't4102-apply-rename.sh',
diff --git a/t/t4070-diff-auto-refresh-index.sh b/t/t4070-diff-auto-refresh-index.sh
new file mode 100755
index 00000000000..9e38f1d3206
--- /dev/null
+++ b/t/t4070-diff-auto-refresh-index.sh
@@ -0,0 +1,46 @@ 
+#!/bin/sh
+#
+# Copyright (c) 2025 Benjamin Woodruff
+#
+
+test_description='diff.autoRefreshIndex config option'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-diff.sh
+
+test_expect_success 'index is updated when autoRefreshIndex is true' '
+	>tracked &&
+	git add tracked &&
+
+	# stat() must change (but not file contents) to trigger an index update
+	test_set_magic_mtime tracked &&
+
+	# check the mtime of .git/index does not change without autoRefreshIndex
+	test_set_magic_mtime .git/index &&
+	git config diff.autoRefreshIndex false &&
+	git diff &&
+	test_is_magic_mtime .git/index &&
+
+	# but it does change when autoRefreshIndex is true (the default)
+	git config diff.autoRefreshIndex true &&
+	git diff &&
+	! test_is_magic_mtime .git/index
+'
+
+test_expect_success '--no-optional-locks overrides autoRefreshIndex' '
+	>tracked &&
+	git add tracked &&
+	test_set_magic_mtime tracked &&
+
+	# `--no-optional-locks` overrides `autoRefreshIndex`
+	test_set_magic_mtime .git/index &&
+	git config diff.autoRefreshIndex true &&
+	git --no-optional-locks diff &&
+
+	# sanity check that without `--no-optional-locks` it still updates
+	test_is_magic_mtime .git/index &&
+	git diff &&
+	! test_is_magic_mtime .git/index
+'
+
+test_done