git.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).