All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Morten Welinder <mwelinder@gmail.com>
Cc: GIT Mailing List <git@vger.kernel.org>,
	Linus Torvalds <torvalds@osdl.org>
Subject: Re: "git-checkout-cache -f -a" failure
Date: Tue, 10 May 2005 15:57:34 -0700	[thread overview]
Message-ID: <7vr7gewuxt.fsf@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: 118833cc05050911255e601fc@mail.gmail.com

>>>>> "MW" == Morten Welinder <mwelinder@gmail.com> writes:

MW> git-checkout-cache is having problems when files change from directories to
MW> plain files or vice versa.  cg-seek seems to be similarly affected.

Could you give this patch a try?  It lets checkout-cache remove
a file where you want to have a directory (because you want to
create something underneath) or remove a whole subdirectory
where you want to have a non-directory, when '-f' parameter is
specified.

If things test well, I'll put this in the git-jc repository and
ask Linus to pull from it alongside with other accumulated
patches when he returns.

Thanks.


Signed-off-by: Junio C Hamano <junkio@cox.net>
------------
# - HEAD: Adjust quoting styles for some environment variables in the documentation.
# + 7: Let checkout-cache stomp on existing file/directory with -f.
--- a/checkout-cache.c
+++ b/checkout-cache.c
@@ -32,6 +32,8 @@
  * of "-a" causing problems (not possible in the above example,
  * but get used to it in scripting!).
  */
+#include <sys/types.h>
+#include <dirent.h>
 #include "cache.h"
 
 static int force = 0, quiet = 0, not_new = 0;
@@ -46,11 +48,51 @@ static void create_directories(const cha
 		len = slash - path;
 		memcpy(buf, path, len);
 		buf[len] = 0;
-		mkdir(buf, 0755);
+		if (mkdir(buf, 0755)) {
+			if (errno == EEXIST) {
+				struct stat st;
+				if (!lstat(buf, &st) && S_ISDIR(st.st_mode))
+					continue; /* ok */
+				if (force && !unlink(buf) && !mkdir(buf, 0755))
+					continue;
+			}
+			die("cannot create directory at %s", buf);
+		}
 	}
 	free(buf);
 }
 
+static void remove_subtree(const char *path)
+{
+	DIR *dir = opendir(path);
+	struct dirent *de;
+	char pathbuf[PATH_MAX];
+	char *name;
+	
+	if (!dir)
+		die("cannot opendir %s", path);
+	strcpy(pathbuf, path);
+	name = pathbuf + strlen(path);
+	*name++ = '/';
+	while ((de = readdir(dir)) != NULL) {
+		struct stat st;
+		if (de->d_name[0] == '.')
+			continue; /* we mean . and .. but verify_path would
+				   * have rejected any dotfiles earlier.
+				   */
+		strcpy(name, de->d_name);
+		if (lstat(pathbuf, &st))
+			die("cannot lstat %s", pathbuf);
+		if (S_ISDIR(st.st_mode))
+			remove_subtree(pathbuf);
+		else if (unlink(pathbuf))
+			die("cannot unlink %s", pathbuf);
+	}
+	closedir(dir);
+	if (rmdir(path))
+		die("cannot rmdir %s", path);
+}
+
 static int create_file(const char *path, unsigned int mode)
 {
 	int fd;
@@ -62,6 +104,14 @@ static int create_file(const char *path,
 			create_directories(path);
 			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
 		}
+		else if (errno == EISDIR && force) {
+			remove_subtree(path);
+			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
+		}
+		else if (errno == ENOTDIR && force) {
+			create_directories(path);
+			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
+		}
 	}
 	return fd;
 }




  parent reply	other threads:[~2005-05-10 22:50 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-09 18:25 "git-checkout-cache -f -a" failure Morten Welinder
2005-05-10  2:29 ` Junio C Hamano
2005-05-10  3:04   ` Morten Welinder
2005-05-10 22:57 ` Junio C Hamano [this message]
2005-05-10 23:03   ` Petr Baudis
2005-05-11  5:16     ` Junio C Hamano
2005-05-11 18:31       ` Morten Welinder
2005-05-11 21:37         ` Junio C Hamano
2005-05-11 22:12           ` Junio C Hamano
2005-05-11 22:40             ` Test suite Petr Baudis
2005-05-12  0:01               ` [PATCH] " Junio C Hamano
2005-05-12 19:29                 ` Petr Baudis
2005-05-12 19:48                   ` Junio C Hamano
2005-05-12 23:51                   ` [PATCH] Fix git-diff-files for symlinks Junio C Hamano
2005-05-13  0:14                   ` [PATCH 0/3] Core GIT fixes and additions Junio C Hamano
2005-05-12  0:02               ` [PATCH] checkout-cache fix Junio C Hamano
2005-05-12 19:38                 ` Petr Baudis
2005-05-12 19:54                   ` Junio C Hamano
2005-05-11  2:53   ` "git-checkout-cache -f -a" failure 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=7vr7gewuxt.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=mwelinder@gmail.com \
    --cc=torvalds@osdl.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.