From: Benjamin Woodruff <benjamin.woodruff@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 --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 -- gitgitgadget