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

[PATCH] t7800: fix racy "difftool --dir-diff syncs worktree" test

From
PGPaul Tarjan via GitGitGadget <gitgitgadget@gmail.com>
Date
Dec 31, 2025, 22:19 UTC
Message-ID
<pull.2149.git.git.1767219599334.gitgitgadget@gmail.com>
From: Paul Tarjan <github@paulisageek.com>

The "difftool --dir-diff syncs worktree without unstaged change" test fails intermittently, particularly on Windows CI.

The test modifies a file in difftool's temp directory via an extcmd script and expects the change to be synced back to the worktree. The sync-back detection relies on git's change detection mechanisms.

The root cause is that the original file content and the replacement content have identical sizes:

  - Original: "main\ntest\na\n" = 12 bytes
  - New:      "new content\n"   = 12 bytes

When difftool creates the temporary index (wtindex), the cache entries have sd_size = 0 (zero-initialized via make_cache_entry with no refresh). Git's ie_modified() is designed to handle this by calling ce_modified_check_fs() for content hashing when sd_size is 0.

However, Windows has known filesystem issues that may cause this to fail intermittently:

 - UNRELIABLE_FSTAT: Windows fstat() on open files may not return the
   same information as lstat() after close (config.mak.uname:506)
 - NTFS timestamp issues: The racy-git documentation notes that NTFS
   is "still broken" regarding timestamp granularity between in-core
   and on-disk representations (Documentation/technical/racy-git.adoc)
 - Attribute caching: Windows GetFileAttributesExW may cache results

Fix this by changing the replacement content to "modified content\n" (17 bytes), ensuring the change is detected at the earliest size comparison in match_stat_data(), bypassing any platform-specific edge cases in the more complex code paths.

Note: Other tests with same-size file patterns (t0010-racy-git.sh,
t2200-add-update.sh, t1701-racy-split-index.sh) are not vulnerable
because they use normal Git index operations with proper racy git
detection. The difftool case is unique due to its ephemeral wtindex
created via make_cache_entry() without full stat refresh.
Signed-off-by: Paul Tarjan <github@paulisageek.com>
---
    t7800: fix racy "difftool --dir-diff syncs worktree" test
    
    In
    https://github.com/git/git/actions/runs/20624095002/job/59231745784#step:5:416
    this test failed for me on an unrelated commit. I had Claude look into
    it and it thought that this could be a racy git problem. I'm skeptical
    but a) I don't know the source well enough and b) the fix is low risk so
    I thought I'd send it to you folks. Everything below is the AI generated
    explanation.
    
    The "difftool --dir-diff syncs worktree without unstaged change" test
    fails intermittently, particularly on Windows CI.
    
    The test modifies a file in difftool's temp directory via an extcmd
    script and expects the change to be synced back to the worktree. The
    sync-back detection relies on git's change detection mechanisms.
    
    The root cause is that the original file content and the replacement
    content have identical sizes:
    
     * Original: "main\ntest\na\n" = 12 bytes
     * New: "new content\n" = 12 bytes
    
    When difftool creates the temporary index (wtindex), the cache entries
    have sd_size = 0 (zero-initialized via make_cache_entry with no
    refresh). Git's ie_modified() is designed to handle this by calling
    ce_modified_check_fs() for content hashing when sd_size is 0.
    
    However, Windows has known filesystem issues that may cause this to fail
    intermittently:
    
     * UNRELIABLE_FSTAT: Windows fstat() on open files may not return the
       same information as lstat() after close (config.mak.uname:506)
    
     * NTFS timestamp issues: The racy-git documentation notes that NTFS is
       "still broken" regarding timestamp granularity between in-core and
       on-disk representations (Documentation/technical/racy-git.adoc)
    
     * Attribute caching: Windows GetFileAttributesExW may cache results
    
    Fix this by changing the replacement content to "modified content\n" (17
    bytes), ensuring the change is detected at the earliest size comparison
    in match_stat_data(), bypassing any platform-specific edge cases in the
    more complex code paths.
    
    Note: Other tests with same-size file patterns (t0010-racy-git.sh,
    t2200-add-update.sh, t1701-racy-split-index.sh) are not vulnerable
    because they use normal Git index operations with proper racy git
    detection. The difftool case is unique due to its ephemeral wtindex
    created via make_cache_entry() without full stat refresh.
    
    Signed-off-by: Paul Tarjan github@paulisageek.com
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2149%2Fptarjan%2Fclaude%2Ffix-difftool-test-DDxDC-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2149/ptarjan/claude/fix-difftool-test-DDxDC-v1
Pull-Request: https://github.com/git/git/pull/2149
 t/t7800-difftool.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index bf0f67378d..8a91ff3603 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -647,21 +647,21 @@ test_expect_success SYMLINKS 'difftool --dir-diff --symlinks without unstaged ch
 '
 
 write_script modify-right-file <<\EOF
-echo "new content" >"$2/file"
+echo "modified content" >"$2/file"
 EOF
 
 run_dir_diff_test 'difftool --dir-diff syncs worktree with unstaged change' '
 	test_when_finished git reset --hard &&
 	echo "orig content" >file &&
 	git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
-	echo "new content" >expect &&
+	echo "modified content" >expect &&
 	test_cmp expect file
 '
 
 run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' '
 	test_when_finished git reset --hard &&
 	git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
-	echo "new content" >expect &&
+	echo "modified content" >expect &&
 	test_cmp expect file
 '
 

base-commit: 68cb7f9e92a5d8e9824f5b52ac3d0a9d8f653dbe
-- 
gitgitgadget
Next: Johannes Schindelin
Message 1 of 11 in “t7800: fix racy "difftool --dir-diff syncs worktree" test”
  1. t7800: fix racy "difftool --dir-diff syncs worktree" testPaul Tarjan via GitGitGadget, Dec 31, 2025
  2. Johannes SchindelinJan 1, 2026
  3. t7800: fix racy "difftool --dir-diff syncs worktree" testPaul Tarjan via GitGitGadget, Jan 1, 2026
  4. Junio C HamanoJan 1, 2026
  5. Phillip WoodJan 3, 2026
  6. Paul TarjanJan 3, 2026
  7. Johannes SchindelinJan 3, 2026
  8. Junio C HamanoJan 4, 2026
  9. t7800: fix racy "difftool --dir-diff syncs worktree" testPaul Tarjan via GitGitGadget, Jan 3, 2026
  10. Junio C HamanoJan 4, 2026
  11. Phillip WoodJan 5, 2026

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.