summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2007-10-25 04:59:50 (GMT)
committerJunio C Hamano <gitster@pobox.com>2007-10-25 04:59:50 (GMT)
commitd90a7fda355c251b8ffdd79617fb083c18245ec2 (patch)
treedff9bc9d8e22b14c73cac403e65997a746aa03b2 /dir.c
parent2db9b49c6c19d3edaa3c20147f7d9f29588433df (diff)
parentca5bb5d5390e4ec709ca3e11c451c58a836d4ee6 (diff)
downloadgit-d90a7fda355c251b8ffdd79617fb083c18245ec2.zip
git-d90a7fda355c251b8ffdd79617fb083c18245ec2.tar.gz
git-d90a7fda355c251b8ffdd79617fb083c18245ec2.tar.bz2
Merge branch 'db/fetch-pack'
* db/fetch-pack: (60 commits) Define compat version of mkdtemp for systems lacking it Avoid scary errors about tagged trees/blobs during git-fetch fetch: if not fetching from default remote, ignore default merge Support 'push --dry-run' for http transport Support 'push --dry-run' for rsync transport Fix 'push --all branch...' error handling Fix compilation when NO_CURL is defined Added a test for fetching remote tags when there is not tags. Fix a crash in ls-remote when refspec expands into nothing Remove duplicate ref matches in fetch Restore default verbosity for http fetches. fetch/push: readd rsync support Introduce remove_dir_recursively() bundle transport: fix an alloc_ref() call Allow abbreviations in the first refspec to be merged Prevent send-pack from segfaulting when a branch doesn't match Cleanup unnecessary break in remote.c Cleanup style nit of 'x == NULL' in remote.c Fix memory leaks when disconnecting transport instances Ensure builtin-fetch honors {fetch,transfer}.unpackLimit ...
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/dir.c b/dir.c
index f843c4d..4c17d36 100644
--- a/dir.c
+++ b/dir.c
@@ -709,3 +709,44 @@ int is_inside_dir(const char *dir)
char buffer[PATH_MAX];
return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
}
+
+int remove_dir_recursively(struct strbuf *path, int only_empty)
+{
+ DIR *dir = opendir(path->buf);
+ struct dirent *e;
+ int ret = 0, original_len = path->len, len;
+
+ if (!dir)
+ return -1;
+ if (path->buf[original_len - 1] != '/')
+ strbuf_addch(path, '/');
+
+ len = path->len;
+ while ((e = readdir(dir)) != NULL) {
+ struct stat st;
+ if ((e->d_name[0] == '.') &&
+ ((e->d_name[1] == 0) ||
+ ((e->d_name[1] == '.') && e->d_name[2] == 0)))
+ continue; /* "." and ".." */
+
+ strbuf_setlen(path, len);
+ strbuf_addstr(path, e->d_name);
+ if (lstat(path->buf, &st))
+ ; /* fall thru */
+ else if (S_ISDIR(st.st_mode)) {
+ if (!remove_dir_recursively(path, only_empty))
+ continue; /* happy */
+ } else if (!only_empty && !unlink(path->buf))
+ continue; /* happy, too */
+
+ /* path too long, stat fails, or non-directory still exists */
+ ret = -1;
+ break;
+ }
+ closedir(dir);
+
+ strbuf_setlen(path, original_len);
+ if (!ret)
+ ret = rmdir(path->buf);
+ return ret;
+}