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

Re: Troubles when directory is replaced by symlink

From
KBKjetil Barvik <barvik@broadpark.no>
Date
Jun 26, 2009, 13:14 UTC
Message-ID
<868wjf9lxq.fsf@broadpark.no>
In-Reply-To
<885649360906241507r6ac78495s802f8b7758bcabf9@mail.gmail.com>
From: Kjetil Barvik <barvik@broadpark.no>
Date: Fri, 26 Jun 2009 14:51:02 +0200
Subject: [PATCH] lstat_cache: guard against full match of length of 'name' parameter

longest_path_match() in symlinks.c does exactly what it's name says, but in some cases that match can be too long, since the has_*_leading_path() functions assumes that the match will newer be as long as the name string given to the function.

Fix this by adding an extra if test which checks if the match length is equal to the 'len' parameter. Also, add a test-case to catch this

Signed-off-by: Kjetil Barvik <barvik@broadpark.no>
---
* James Pickens <jepicken@gmail.com> writes:
Show 11 quoted lines
> On Sun, Jun 14, 2009, Kjetil Barvik<barvik@broadpark.no> wrote:
>> From: Kjetil Barvik <barvik@broadpark.no>
>> Date: Sun, 14 Jun 2009 15:08:28 +0200
>> Subject: [PATCH] lstat_cache: guard against full match of length of 'name' parameter
>
> My project ran into this bug today, and I can confirm that this patch
> fixes it.  I think it's an important bug; it hasn't been mentioned yet,
> but this can result in lost work if the user had modified, but not added,
> one of the files that Git wrongly deleted.
>
> So, what's the status of this patch?
  OK, here is a more final patch with a test case.  
  -- kjetil
 symlinks.c                  |    2 ++
 t/t2007-checkout-symlink.sh |   31 +++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/symlinks.c b/symlinks.c
index 8dcd632..66a0e16 100644
--- a/symlinks.c
+++ b/symlinks.c
@@ -96,6 +96,8 @@ static int lstat_cache(const char *name, int len,
 		match_len = last_slash =
 			longest_path_match(name, len, cache.path, cache.len,
 					   &previous_slash);
+		if (!(track_flags & FL_FULLPATH) && match_len == len)
+			match_len = last_slash = previous_slash;
 		match_flags = cache.flags & track_flags & (FL_NOENT|FL_SYMLINK);
 		if (match_flags && match_len == cache.len)
 			return match_flags;
diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh
index 20f3343..08e3c32 100755
--- a/t/t2007-checkout-symlink.sh
+++ b/t/t2007-checkout-symlink.sh
@@ -53,4 +53,35 @@ test_expect_success 'switch from dir to symlink' '
 
 '
 
+test_expect_success 'setup of new directories and a branch' '
+
+	git checkout master &&
+
+	mkdir alpha &&
+	echo content >alpha/file &&
+	git add . &&
+	git commit -m one &&
+
+	mkdir beta &&
+	cp -R alpha beta &&
+	git add . &&
+	git commit -m two &&
+
+	git checkout -b branch &&
+	rm -rf beta/alpha &&
+	git add -u &&
+	git commit -m deleted &&
+	ln -s ../alpha beta/alpha &&
+	git add . &&
+	git commit -m symlink
+
+'
+
+test_expect_success 'checkout of master - alpha/file and beta/alpha/file should exist' '
+
+	git checkout master &&
+	ls alpha/file beta/alpha/file
+
+'
+
 test_done
-- 
1.6.3.2.277.gd10543
Previous: Kjetil BarvikNext: Johannes Sixt
Message 8 of 9 in “Troubles when directory is replaced by symlink”
  1. Alexander GladyshJun 5, 2009
  2. Alexander GladyshJun 9, 2009
  3. Jeff KingJun 11, 2009
  4. Kjetil BarvikJun 11, 2009
  5. Kjetil BarvikJun 14, 2009
  6. James PickensJun 24, 2009
  7. Kjetil BarvikJun 25, 2009
  8. Kjetil BarvikJun 26, 2009
  9. Johannes SixtJun 26, 2009

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.