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

[PATCH] pathspec: always honor `PATHSPEC_PREFIX_ORIGIN` flag

From
Patrick Steinhardt <ps@pks.im>
Date
Apr 3, 2017, 08:03 UTC
Message-ID
<1556910880cfce391bdca2d8f0cbcb8c71371691.1491206540.git.ps@pks.im>

Previous to commit 5d8f084a5 (pathspec: simpler logic to prefix original pathspec elements, 2017-01-04), we were always using the computed `match` variable to perform pathspec matching whenever `PATHSPEC_PREFIX_ORIGIN` is set. This is for example useful when passing the parsed pathspecs to other commands, as the computed `match` may contain a pathspec relative to the repository root. The commit changed this logic to only do so when we do have an actual prefix and when literal pathspecs are deactivated.

But this change may actually break some commands which expect passed pathspecs to be relative to the repository root. One such case is `git add --patch`, which now fails when using relative paths from a subdirectory. For example if executing "git add -p ../foo.c" in a subdirectory, the `git-add--interactive` command will directly pass "../foo.c" to `git-ls-files`. As ls-files is executed at the repository's root, the command will notice that "../foo.c" is outside the repository and fail.

Fix the issue by again using the computed `match` variable whenever `PATHSPEC_PREFIX_ORIGIN` is set. This restores behavior previous to 5d8f084a5 and fixes interactive add.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 pathspec.c                 |  6 +++---
 t/t3701-add-interactive.sh | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/pathspec.c b/pathspec.c
index 303efda83..3193e45a6 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -504,12 +504,12 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
 	 * Prefix the pathspec (keep all magic) and assign to
 	 * original. Useful for passing to another command.
 	 */
-	if ((flags & PATHSPEC_PREFIX_ORIGIN) &&
-	    prefixlen && !get_literal_global()) {
+	if (flags & PATHSPEC_PREFIX_ORIGIN) {
 		struct strbuf sb = STRBUF_INIT;
 
 		/* Preserve the actual prefix length of each pattern */
-		prefix_magic(&sb, prefixlen, element_magic);
+		if (prefixlen && !get_literal_global())
+			prefix_magic(&sb, prefixlen, element_magic);
 
 		strbuf_addstr(&sb, match);
 		item->original = strbuf_detach(&sb, NULL);
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index f9528fa00..640088dd6 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -436,6 +436,26 @@ test_expect_success 'add -p handles globs' '
 	test_cmp expect actual
 '
 
+test_expect_success 'add -p handles relative paths' '
+	git reset --hard &&
+
+	echo base >root.c &&
+	git add "*.c" &&
+	git commit -m base &&
+
+	echo change >root.c &&
+	mkdir -p subdir &&
+	git -C subdir add -p "../root.c" <<-\EOF &&
+	y
+	EOF
+
+	cat >expect <<-\EOF &&
+	root.c
+	EOF
+	git diff --cached --name-only >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'add -p does not expand argument lists' '
 	git reset --hard &&
 
-- 
2.12.2
Next: Brandon Williams
Message 1 of 4 in “pathspec: always honor `PATHSPEC_PREFIX_ORIGIN` flag”
  1. pathspec: always honor `PATHSPEC_PREFIX_ORIGIN` flagPatrick Steinhardt, Apr 3, 2017
  2. Brandon WilliamsApr 3, 2017
  3. Patrick SteinhardtApr 4, 2017
  4. Duy NguyenApr 5, 2017

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.