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

[PATCH v2 2/3] stash: avoid feeding directories to update-index

From
Elijah Newren via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 10, 2021, 10:29 UTC
Message-ID
<31e38c6c33cea596cb926a2df13cf0df34766a7a.1631269796.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1086.v2.git.git.1631269796.gitgitgadget@gmail.com>
From: Elijah Newren <newren@gmail.com>

When a file is removed from the cache, but there is a file of the same name present in the working directory, we would normally treat that file in the working directory as untracked. However, in the case of stash, doing that would prevent a simple 'git stash push', because the untracked file would be in the way of restoring the deleted file.

git stash, however, blindly assumes that whatever is in the working directory for a deleted file is wanted and passes that path along to update-index. That causes problems when the working directory contains a directory with the same name as the deleted file. Add some code for this special case that will avoid passing directory names to update-index.

Signed-off-by: Elijah Newren <newren@gmail.com>
---
 builtin/stash.c  | 14 ++++++++++++++
 t/t3903-stash.sh |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/builtin/stash.c b/builtin/stash.c
index 8f42360ca91..9ad2940f87a 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -313,6 +313,17 @@ static int reset_head(void)
 	return run_command(&cp);
 }
 
+static int is_path_a_directory(const char *path)
+{
+	/*
+	 * This function differs from abspath.c:is_directory() in that
+	 * here we use lstat() instead of stat(); we do not want to
+	 * follow symbolic links here.
+	 */
+	struct stat st;
+	return (!lstat(path, &st) && S_ISDIR(st.st_mode));
+}
+
 static void add_diff_to_buf(struct diff_queue_struct *q,
 			    struct diff_options *options,
 			    void *data)
@@ -320,6 +331,9 @@ static void add_diff_to_buf(struct diff_queue_struct *q,
 	int i;
 
 	for (i = 0; i < q->nr; i++) {
+		if (is_path_a_directory(q->queue[i]->one->path))
+			continue;
+
 		strbuf_addstr(data, q->queue[i]->one->path);
 
 		/* NUL-terminate: will be fed to update-index -z */
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 7346f8d1037..34d1ad9837f 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -1307,7 +1307,7 @@ test_expect_success 'stash -c stash.useBuiltin=false warning ' '
 	test_must_be_empty err
 '
 
-test_expect_failure 'git stash succeeds despite directory/file change' '
+test_expect_success 'git stash succeeds despite directory/file change' '
 	test_create_repo directory_file_switch_v1 &&
 	(
 		cd directory_file_switch_v1 &&
-- 
gitgitgadget
Previous: Elijah Newren via GitGitGadgetNext: Elijah Newren via GitGitGadget
Message 13 of 14 in “Fix D/F issues in stash”
  1. 0/3 Fix D/F issues in stashElijah Newren via GitGitGadget, Sep 8, 2021
  2. 1/3 t3903: document a pair of directory/file bugsElijah Newren via GitGitGadget, Sep 8, 2021
  3. Junio C HamanoSep 8, 2021
  4. 2/3 stash: avoid feeding directories to update-indexElijah Newren via GitGitGadget, Sep 8, 2021
  5. Johannes SchindelinSep 8, 2021
  6. 3/3 stash: restore untracked files AFTER restoring tracked filesElijah Newren via GitGitGadget, Sep 8, 2021
  7. Derrick StoleeSep 8, 2021
  8. Junio C HamanoSep 8, 2021
  9. Johannes SchindelinSep 8, 2021
  10. Derrick StoleeSep 8, 2021
  11. 0/3 Fix D/F issues in stashElijah Newren via GitGitGadget, Sep 10, 2021
  12. 1/3 t3903: document a pair of directory/file bugsElijah Newren via GitGitGadget, Sep 10, 2021
  13. 2/3 stash: avoid feeding directories to update-indexElijah Newren via GitGitGadget, Sep 10, 2021
  14. 3/3 stash: restore untracked files AFTER restoring tracked filesElijah Newren via GitGitGadget, Sep 10, 2021

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.