All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: git@vger.kernel.org
Subject: [PATCH] read-tree -m -u: avoid getting confused by intermediate symlinks.
Date: Fri, 11 May 2007 00:13:56 -0700	[thread overview]
Message-ID: <7vveezde8b.fsf@assigned-by-dhcp.cox.net> (raw)

When switching from a branch with both x86_64/boot/Makefile and
i386/boot/Makefile to another branch that has x86_64/boot as a
symlink pointing at ../i386/boot, the code incorrectly removed
i386/boot/Makefile.

This was because we first removed everything under x86_64/boot
to make room to create a symbolic link x86_64/boot, then removed
x86_64/boot/Makefile which no longer exists but now is pointing
at i386/boot/Makefile, thanks to the symlink we just created.

This fixes it by using the has_symlink_leading_path() function
introduced previously for git-apply in the checkout codepath.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

 * This comes on top of the previous git-apply patch.

 Makefile                        |    2 +-
 builtin-apply.c                 |   36 +-----------------------------------
 cache.h                         |    1 +
 symlinks.c                      |   35 +++++++++++++++++++++++++++++++++++
 t/t4122-apply-symlink-inside.sh |    1 -
 unpack-trees.c                  |    2 ++
 6 files changed, 40 insertions(+), 37 deletions(-)
 create mode 100644 symlinks.c

diff --git a/Makefile b/Makefile
index 7cf146b..29243c6 100644
--- a/Makefile
+++ b/Makefile
@@ -318,7 +318,7 @@ LIB_OBJS = \
 	write_or_die.o trace.o list-objects.o grep.o match-trees.o \
 	alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
 	color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
-	convert.o attr.o decorate.o progress.o mailmap.o
+	convert.o attr.o decorate.o progress.o mailmap.o symlinks.o
 
 BUILTIN_OBJS = \
 	builtin-add.o \
diff --git a/builtin-apply.c b/builtin-apply.c
index 38d20ef..01acba8 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2009,40 +2009,6 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
 	return 0;
 }
 
-static int has_symlink_component(const char *new_name)
-{
-	char path[PATH_MAX];
-	const char *sp, *ep;
-	char *dp;
-
-	sp = new_name;
-	dp = path;
-
-	while (1) {
-		size_t len;
-		struct stat st;
-
-		ep = strchr(sp, '/');
-		if (!ep)
-			break;
-		len = ep - sp;
-		if (PATH_MAX <= dp + len - path + 2)
-			return 0; /* new name is longer than that??? */
-		memcpy(dp, sp, len);
-		dp[len] = 0;
-
-		if (lstat(path, &st))
-			return 0; /* why? we already lstat() new_name successfully. */
-		if (S_ISLNK(st.st_mode))
-			return 1;
-
-		dp[len++] = '/';
-		dp = dp + len;
-		sp = ep + 1;
-	}
-	return 0;
-}
-
 static int check_to_create_blob(const char *new_name, int ok_if_exists)
 {
 	struct stat nst;
@@ -2056,7 +2022,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists)
 		 * In such a case, path "new_name" does not exist as
 		 * far as git is concerned.
 		 */
-		if (has_symlink_component(new_name))
+		if (has_symlink_leading_path(new_name))
 			return 0;
 
 		return error("%s: already exists in working directory", new_name);
diff --git a/cache.h b/cache.h
index 8e76152..ab66263 100644
--- a/cache.h
+++ b/cache.h
@@ -410,6 +410,7 @@ struct checkout {
 };
 
 extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
+extern int has_symlink_leading_path(const char *name);
 
 extern struct alternate_object_database {
 	struct alternate_object_database *next;
diff --git a/symlinks.c b/symlinks.c
new file mode 100644
index 0000000..cfecfcf
--- /dev/null
+++ b/symlinks.c
@@ -0,0 +1,35 @@
+#include "cache.h"
+
+int has_symlink_leading_path(const char *name)
+{
+	char path[PATH_MAX];
+	const char *sp, *ep;
+	char *dp;
+
+	sp = name;
+	dp = path;
+
+	while (1) {
+		size_t len;
+		struct stat st;
+
+		ep = strchr(sp, '/');
+		if (!ep)
+			break;
+		len = ep - sp;
+		if (PATH_MAX <= dp + len - path + 2)
+			return 0; /* new name is longer than that??? */
+		memcpy(dp, sp, len);
+		dp[len] = 0;
+
+		if (lstat(path, &st))
+			return 0;
+		if (S_ISLNK(st.st_mode))
+			return 1;
+
+		dp[len++] = '/';
+		dp = dp + len;
+		sp = ep + 1;
+	}
+	return 0;
+}
diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh
index 37c9a9f..3ddfe64 100755
--- a/t/t4122-apply-symlink-inside.sh
+++ b/t/t4122-apply-symlink-inside.sh
@@ -34,7 +34,6 @@ test_expect_success setup '
 test_expect_success apply '
 
 	git checkout test &&
-	git reset --hard && #### checkout seems to be buggy
 	git diff --exit-code test &&
 	git diff --exit-code --cached test &&
 	git apply --index test.patch
diff --git a/unpack-trees.c b/unpack-trees.c
index 675a999..a6fa32f 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -268,6 +268,8 @@ static void unlink_entry(char *name)
 {
 	char *cp, *prev;
 
+	if (has_symlink_leading_path(name))
+		return;
 	if (unlink(name))
 		return;
 	prev = NULL;
-- 
1.5.2.rc3.706.g498a

             reply	other threads:[~2007-05-11  7:14 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-11  7:13 Junio C Hamano [this message]
2007-05-11 14:08 ` [PATCH] read-tree -m -u: avoid getting confused by intermediate symlinks Alex Riesen
2007-05-11 17:10   ` Junio C Hamano
2007-05-11 20:38     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vveezde8b.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.