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;
}
next prev 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).