>>>>> "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; } - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.htmlReceived on Wed May 11 08:57:46 2005
This archive was generated by hypermail 2.1.8 : 2005-05-11 08:57:46 EST