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

[PATCH v2 0/2] Fix git stash with skip-worktree entries

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Oct 28, 2019, 11:20 UTC
Message-ID
<pull.355.v2.git.1572261615.gitgitgadget@gmail.com>
In-Reply-To
<pull.355.git.gitgitgadget@gmail.com>

My colleague Dan Thompson reported a bug in a sparse checkout, where git stash (after resolving merge conflicts and then making up their mind to stash the changes instead of committing them) would "lose" files (and files that were not even in the sparse checkout's cone!).

I first considered changing the behavior of git diff-index to simply ignore skip-worktree entries. But after re-reading the documentation of the skip-worktree bit, I became convinced that this would be incorrect a fix because the command really does what it advertises to do.

Then, I briefly considered introducing a flag that would change the behavior thusly, but ended up deciding against it.

The actual problem, after all, is the git update-index call and that it heeds the --remove (but not the --add) option for skip-worktree entries. "Heeds", I should say, because the idea of the skip-worktree bit really is documented to imply that the worktree files should be considered identical to their staged versions.

So arguably, it could be considered a bug that git update-index --remove even bothers to touch skip-worktree entries. But this behavior has been in place for over 10 years, so I opted to introduce a new mode that does what git stash needs in order to fix the bug.

Changes since v1:
 * Added a test even for the --ignore-skip-worktree-entries option alone
   (i.e. without going through git stash)
 * Rebased onto tg/stash-refresh-index to avoid merge conflicts in 
   t/t3903-stash.sh.
Johannes Schindelin (2):
  update-index: optionally leave skip-worktree entries alone
  stash: handle staged changes in skip-worktree files correctly
 Documentation/git-update-index.txt |  6 ++++++
 builtin/stash.c                    |  5 +++--
 builtin/update-index.c             |  6 +++++-
 git-legacy-stash.sh                |  3 ++-
 t/t3903-stash.sh                   | 11 +++++++++++
 t/t7012-skip-worktree-writing.sh   | 14 ++++++++++++++
 6 files changed, 41 insertions(+), 4 deletions(-)
base-commit: 34933d0eff5d4c91fae6ad6f71a6e6a69a496ced
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-355%2Fdscho%2Ffix-stash-with-skip-worktree-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-355/dscho/fix-stash-with-skip-worktree-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/355
Range-diff vs v1:
 1:  c263eb54b3 ! 1:  86dbb11f15 update-index: optionally leave skip-worktree entries alone
     @@ -72,3 +72,28 @@
       		OPT_SET_INT(0, "info-only", &info_only,
       			N_("add to index only; do not add content to object database"), 1),
       		OPT_SET_INT(0, "force-remove", &force_remove,
     +
     + diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
     + --- a/t/t7012-skip-worktree-writing.sh
     + +++ b/t/t7012-skip-worktree-writing.sh
     +@@
     + 	test_i18ncmp expected result
     + '
     + 
     ++test_expect_success '--ignore-skip-worktree-entries leaves worktree alone' '
     ++	test_commit geroff-me &&
     ++	git update-index --skip-worktree geroff-me.t &&
     ++	rm geroff-me.t &&
     ++
     ++	: ignoring the worktree &&
     ++	git update-index --remove --ignore-skip-worktree-entries geroff-me.t &&
     ++	git diff-index --cached --exit-code HEAD &&
     ++
     ++	: not ignoring the worktree, a deletion is staged &&
     ++	git update-index --remove geroff-me.t &&
     ++	test_must_fail git diff-index --cached --exit-code HEAD
     ++'
     ++
     + #TODO test_expect_failure 'git-apply adds file' false
     + #TODO test_expect_failure 'git-apply updates file' false
     + #TODO test_expect_failure 'git-apply removes file' false
 2:  4c684be179 ! 2:  9835e66399 stash: handle staged changes in skip-worktree files correctly
     @@ -59,7 +59,7 @@
       --- a/t/t3903-stash.sh
       +++ b/t/t3903-stash.sh
      @@
     - 	test_path_is_missing to-remove
     + 	git stash apply
       '
       
      +test_expect_success 'stash handles skip-worktree entries nicely' '
-- 
gitgitgadget
Previous: Johannes SchindelinNext: Johannes Schindelin via GitGitGadget
Message 13 of 23 in “Fix git stash with skip-worktree entries”
  1. 0/2 Fix git stash with skip-worktree entriesJohannes Schindelin via GitGitGadget, Sep 26, 2019
  2. 1/2 update-index: optionally leave skip-worktree entries aloneJohannes Schindelin via GitGitGadget, Sep 26, 2019
  3. Junio C HamanoOct 28, 2019
  4. Johannes SchindelinOct 28, 2019
  5. Junio C HamanoOct 29, 2019
  6. 2/2 stash: handle staged changes in skip-worktree files correctlyJohannes Schindelin via GitGitGadget, Sep 26, 2019
  7. Junio C HamanoOct 28, 2019
  8. Johannes SchindelinOct 27, 2019
  9. Junio C HamanoOct 28, 2019
  10. Johannes SchindelinOct 28, 2019
  11. Junio C HamanoOct 29, 2019
  12. Johannes SchindelinOct 29, 2019
  13. 0/2 Fix git stash with skip-worktree entriesJohannes Schindelin via GitGitGadget, Oct 28, 2019
  14. 2/2 stash: handle staged changes in skip-worktree files correctlyJohannes Schindelin via GitGitGadget, Oct 28, 2019
  15. Junio C HamanoOct 30, 2019
  16. 1/2 update-index: optionally leave skip-worktree entries aloneJohannes Schindelin via GitGitGadget, Oct 28, 2019
  17. Junio C HamanoOct 30, 2019
  18. Johannes SchindelinOct 30, 2019
  19. Junio C HamanoNov 2, 2019
  20. Johannes SchindelinNov 2, 2019
  21. 0/2 Fix git stash with skip-worktree entriesJohannes Schindelin via GitGitGadget, Oct 30, 2019
  22. 1/2 update-index: optionally leave skip-worktree entries aloneJohannes Schindelin via GitGitGadget, Oct 30, 2019
  23. 2/2 stash: handle staged changes in skip-worktree files correctlyJohannes Schindelin via GitGitGadget, Oct 30, 2019

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.