summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attr.c4
-rw-r--r--src/attr_file.c2
-rw-r--r--src/filebuf.c6
-rw-r--r--src/fileops.c181
-rw-r--r--src/fileops.h61
-rw-r--r--src/hashtable.c3
-rw-r--r--src/hashtable.h10
-rw-r--r--src/ignore.c2
-rw-r--r--src/index.c4
-rw-r--r--src/indexer.c2
-rw-r--r--src/odb.c2
-rw-r--r--src/odb_loose.c12
-rw-r--r--src/odb_pack.c4
-rw-r--r--src/pack.c2
-rw-r--r--src/path.c175
-rw-r--r--src/path.h149
-rw-r--r--src/reflog.c6
-rw-r--r--src/refs.c28
-rw-r--r--src/refspec.c2
-rw-r--r--src/remote.c3
-rw-r--r--src/repository.c18
-rw-r--r--src/status.c14
-rw-r--r--src/transport.c2
-rw-r--r--src/transports/http.c2
-rw-r--r--src/tree.c3
-rw-r--r--src/win32/dir.h (renamed from src/dir.h)8
-rw-r--r--src/win32/posix_w32.c2
27 files changed, 392 insertions, 315 deletions
diff --git a/src/attr.c b/src/attr.c
index fa1a4f121..da0f72371 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -230,7 +230,7 @@ int git_attr_cache__push_file(
/* either get attr_file from cache or read from disk */
file = git_hashtable_lookup(cache->files, filename);
- if (file == NULL && git_futils_exists(filename) == GIT_SUCCESS) {
+ if (file == NULL && git_path_exists(filename) == GIT_SUCCESS) {
if ((error = git_attr_file__new(&file)) == GIT_SUCCESS)
error = loader(repo, filename, file);
add_to_cache = (error == GIT_SUCCESS);
@@ -280,7 +280,7 @@ static int collect_attr_files(
if ((error = git_vector_init(files, 4, NULL)) < GIT_SUCCESS)
goto cleanup;
- if ((error = git_futils_dir_for_path(&dir, path, workdir)) < GIT_SUCCESS)
+ if ((error = git_path_find_dir(&dir, path, workdir)) < GIT_SUCCESS)
goto cleanup;
/* in precendence order highest to lowest:
diff --git a/src/attr_file.c b/src/attr_file.c
index 4303c7667..5fd136c77 100644
--- a/src/attr_file.c
+++ b/src/attr_file.c
@@ -243,7 +243,7 @@ int git_attr_path__init(
info->basename++;
if (!info->basename || !*info->basename)
info->basename = path;
- info->is_dir = (git_futils_isdir(path) == GIT_SUCCESS);
+ info->is_dir = (git_path_isdir(path) == GIT_SUCCESS);
return GIT_SUCCESS;
}
diff --git a/src/filebuf.c b/src/filebuf.c
index aa47d5eb0..447d8a089 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -16,7 +16,7 @@ static const size_t WRITE_BUFFER_SIZE = (4096 * 2);
static int lock_file(git_filebuf *file, int flags)
{
- if (git_futils_exists(file->path_lock) == 0) {
+ if (git_path_exists(file->path_lock) == 0) {
if (flags & GIT_FILEBUF_FORCE)
p_unlink(file->path_lock);
else
@@ -34,7 +34,7 @@ static int lock_file(git_filebuf *file, int flags)
if (file->fd < 0)
return git__throw(GIT_EOSERR, "Failed to create lock");
- if ((flags & GIT_FILEBUF_APPEND) && git_futils_exists(file->path_original) == 0) {
+ if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == 0) {
git_file source;
char buffer[2048];
size_t read_bytes;
@@ -60,7 +60,7 @@ void git_filebuf_cleanup(git_filebuf *file)
if (file->fd >= 0)
p_close(file->fd);
- if (file->fd >= 0 && file->path_lock && git_futils_exists(file->path_lock) == GIT_SUCCESS)
+ if (file->fd >= 0 && file->path_lock && git_path_exists(file->path_lock) == GIT_SUCCESS)
p_unlink(file->path_lock);
if (file->digest)
diff --git a/src/fileops.c b/src/fileops.c
index 3412a47e2..e2a6adf0b 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -23,7 +23,7 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode)
}
/* Does the containing folder exist? */
- if (git_futils_isdir(target_folder.ptr) != GIT_SUCCESS)
+ if (git_path_isdir(target_folder.ptr) != GIT_SUCCESS)
/* Let's create the tree structure */
error = git_futils_mkdir_r(target_folder.ptr, NULL, mode);
@@ -70,47 +70,6 @@ int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, con
return git_futils_creat_locked(path, mode);
}
-int git_futils_isdir(const char *path)
-{
-#ifdef GIT_WIN32
- DWORD attr = GetFileAttributes(path);
- if (attr == INVALID_FILE_ATTRIBUTES)
- return GIT_ERROR;
-
- return (attr & FILE_ATTRIBUTE_DIRECTORY) ? GIT_SUCCESS : GIT_ERROR;
-
-#else
- struct stat st;
- if (p_stat(path, &st) < GIT_SUCCESS)
- return GIT_ERROR;
-
- return S_ISDIR(st.st_mode) ? GIT_SUCCESS : GIT_ERROR;
-#endif
-}
-
-int git_futils_isfile(const char *path)
-{
- struct stat st;
- int stat_error;
-
- assert(path);
- stat_error = p_stat(path, &st);
-
- if (stat_error < GIT_SUCCESS)
- return -1;
-
- if (!S_ISREG(st.st_mode))
- return -1;
-
- return 0;
-}
-
-int git_futils_exists(const char *path)
-{
- assert(path);
- return p_access(path, F_OK);
-}
-
git_off_t git_futils_filesize(git_file fd)
{
struct stat sb;
@@ -219,54 +178,6 @@ void git_futils_mmap_free(git_map *out)
p_munmap(out);
}
-/* Taken from git.git */
-GIT_INLINE(int) is_dot_or_dotdot(const char *name)
-{
- return (name[0] == '.' &&
- (name[1] == '\0' ||
- (name[1] == '.' && name[2] == '\0')));
-}
-
-int git_futils_direach(
- git_buf *path,
- int (*fn)(void *, git_buf *),
- void *arg)
-{
- ssize_t wd_len;
- DIR *dir;
- struct dirent *de;
-
- if (git_path_to_dir(path) < GIT_SUCCESS)
- return git_buf_lasterror(path);
-
- wd_len = path->size;
- dir = opendir(path->ptr);
- if (!dir)
- return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure. An error occured while opening the directory", path->ptr);
-
- while ((de = readdir(dir)) != NULL) {
- int result;
-
- if (is_dot_or_dotdot(de->d_name))
- continue;
-
- if (git_buf_puts(path, de->d_name) < GIT_SUCCESS)
- return git_buf_lasterror(path);
-
- result = fn(arg, path);
-
- git_buf_truncate(path, wd_len); /* restore path */
-
- if (result != GIT_SUCCESS) {
- closedir(dir);
- return result; /* The callee is reponsible for setting the correct error message */
- }
- }
-
- closedir(dir);
- return GIT_SUCCESS;
-}
-
int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
{
int error, root_path_offset;
@@ -291,7 +202,7 @@ int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
pp += root_path_offset; /* On Windows, will skip the drive name (eg. C: or D:) */
while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != NULL) {
- if (sp != pp && git_futils_isdir(make_path.ptr) < GIT_SUCCESS) {
+ if (sp != pp && git_path_isdir(make_path.ptr) < GIT_SUCCESS) {
*sp = 0;
error = p_mkdir(make_path.ptr, mode);
@@ -324,8 +235,8 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
int error = GIT_SUCCESS;
int force = *(int *)opaque;
- if (git_futils_isdir(path->ptr) == GIT_SUCCESS) {
- error = git_futils_direach(path, _rmdir_recurs_foreach, opaque);
+ if (git_path_isdir(path->ptr) == GIT_SUCCESS) {
+ error = git_path_direach(path, _rmdir_recurs_foreach, opaque);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to remove directory `%s`", path->ptr);
return p_rmdir(path->ptr);
@@ -349,60 +260,6 @@ int git_futils_rmdir_r(const char *path, int force)
return error;
}
-int git_futils_cmp_path(const char *name1, int len1, int isdir1,
- const char *name2, int len2, int isdir2)
-{
- int len = len1 < len2 ? len1 : len2;
- int cmp;
-
- cmp = memcmp(name1, name2, len);
- if (cmp)
- return cmp;
- if (len1 < len2)
- return ((!isdir1 && !isdir2) ? -1 :
- (isdir1 ? '/' - name2[len1] : name2[len1] - '/'));
- if (len1 > len2)
- return ((!isdir1 && !isdir2) ? 1 :
- (isdir2 ? name1[len2] - '/' : '/' - name1[len2]));
- return 0;
-}
-
-static int _check_dir_contents(
- git_buf *dir,
- const char *sub,
- int append_on_success,
- int (*predicate)(const char *))
-{
- int error = GIT_SUCCESS;
- size_t dir_size = dir->size;
- size_t sub_size = strlen(sub);
-
- /* leave base valid even if we could not make space for subdir */
- if ((error = git_buf_try_grow(dir, dir_size + sub_size + 2)) < GIT_SUCCESS)
- return error;
-
- /* save excursion */
- git_buf_joinpath(dir, dir->ptr, sub);
-
- error = (*predicate)(dir->ptr);
-
- /* restore excursion */
- if (!append_on_success || error != GIT_SUCCESS)
- git_buf_truncate(dir, dir_size);
-
- return error;
-}
-
-int git_futils_contains_dir(git_buf *base, const char *subdir, int append_if_exists)
-{
- return _check_dir_contents(base, subdir, append_if_exists, &git_futils_isdir);
-}
-
-int git_futils_contains_file(git_buf *base, const char *file, int append_if_exists)
-{
- return _check_dir_contents(base, file, append_if_exists, &git_futils_isfile);
-}
-
int git_futils_find_global_file(git_buf *path, const char *filename)
{
int error;
@@ -420,7 +277,7 @@ int git_futils_find_global_file(git_buf *path, const char *filename)
if ((error = git_buf_joinpath(path, home, filename)) < GIT_SUCCESS)
return error;
- if (git_futils_exists(path->ptr) < GIT_SUCCESS) {
+ if (git_path_exists(path->ptr) < GIT_SUCCESS) {
git_buf_clear(path);
return GIT_ENOTFOUND;
}
@@ -522,7 +379,7 @@ int git_futils_find_system_file(git_buf *path, const char *filename)
if (git_buf_joinpath(path, "/etc", filename) < GIT_SUCCESS)
return git_buf_lasterror(path);
- if (git_futils_exists(path->ptr) == GIT_SUCCESS)
+ if (git_path_exists(path->ptr) == GIT_SUCCESS)
return GIT_SUCCESS;
git_buf_clear(path);
@@ -533,29 +390,3 @@ int git_futils_find_system_file(git_buf *path, const char *filename)
return GIT_ENOTFOUND;
#endif
}
-
-int git_futils_dir_for_path(git_buf *dir, const char *path, const char *base)
-{
- int error = GIT_SUCCESS;
-
- if (base != NULL && git_path_root(path) < 0)
- error = git_buf_joinpath(dir, base, path);
- else
- error = git_buf_sets(dir, path);
-
- if (error == GIT_SUCCESS) {
- char buf[GIT_PATH_MAX];
- if (p_realpath(dir->ptr, buf) != NULL)
- error = git_buf_sets(dir, buf);
- }
-
- /* call dirname if this is not a directory */
- if (error == GIT_SUCCESS && git_futils_isdir(dir->ptr) != GIT_SUCCESS)
- if (git_path_dirname_r(dir, dir->ptr) < GIT_SUCCESS)
- error = git_buf_lasterror(dir);
-
- if (error == GIT_SUCCESS)
- error = git_path_to_dir(dir);
-
- return error;
-}
diff --git a/src/fileops.h b/src/fileops.h
index 91903a731..1ded0d3b1 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -9,7 +9,6 @@
#include "common.h"
#include "map.h"
-#include "dir.h"
#include "posix.h"
#include "path.h"
@@ -41,11 +40,6 @@ extern void git_futils_fbuffer_rtrim(git_fbuffer *obj);
*/
/**
- * Check if a file exists and can be accessed.
- */
-extern int git_futils_exists(const char *path);
-
-/**
* Create and open a file, while also
* creating all the folders in its path
*/
@@ -63,32 +57,6 @@ extern int git_futils_creat_locked(const char *path, const mode_t mode);
extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmode, const mode_t mode);
/**
- * Check if the given path points to a directory
- */
-extern int git_futils_isdir(const char *path);
-
-/**
- * Check if the given path points to a regular file
- */
-extern int git_futils_isfile(const char *path);
-
-/**
- * Check if the given path contains the given subdirectory.
- *
- * If `append_if_exists` is true, then the subdir will be appended to the
- * parent path if it does exists.
- */
-extern int git_futils_contains_dir(git_buf *parent, const char *subdir, int append_if_exists);
-
-/**
- * Check if the given path contains the given file
- *
- * If `append_if_exists` is true, then the filename will be appended to the
- * parent path if it does exists.
- */
-extern int git_futils_contains_file(git_buf *parent, const char *file, int append_if_exists);
-
-/**
* Create a path recursively
*/
extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode);
@@ -99,17 +67,10 @@ extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t m
*/
extern int git_futils_mkpath2file(const char *path, const mode_t mode);
-extern int git_futils_rmdir_r(const char *path, int force);
-
/**
- * Get the directory for a path.
- *
- * If the path is a directory, this does nothing (save append a '/' as
- * needed). If path is a normal file, this gets the directory containing
- * it. If the path does not exist, then this treats it a filename and
- * returns the dirname of it.
+ * Remove path and any files and directories beneath it.
*/
-extern int git_futils_dir_for_path(git_buf *dir, const char *path, const char *base);
+extern int git_futils_rmdir_r(const char *path, int force);
/**
* Create and open a temporary file with a `_git2_` suffix.
@@ -158,24 +119,6 @@ extern int git_futils_mmap_ro(
extern void git_futils_mmap_free(git_map *map);
/**
- * Walk each directory entry, except '.' and '..', calling fn(state).
- *
- * @param pathbuf buffer the function reads the initial directory
- * path from, and updates with each successive entry's name.
- * @param fn function to invoke with each entry. The first arg is
- * the input state and the second arg is pathbuf. The function
- * may modify the pathbuf, but only by appending new text.
- * @param state to pass to fn as the first arg.
- */
-extern int git_futils_direach(
- git_buf *pathbuf,
- int (*fn)(void *, git_buf *),
- void *state);
-
-extern int git_futils_cmp_path(const char *name1, int len1, int isdir1,
- const char *name2, int len2, int isdir2);
-
-/**
* Find a "global" file (i.e. one in a user's home directory).
*
* @param pathbuf buffer to write the full path into
diff --git a/src/hashtable.c b/src/hashtable.c
index f836f166d..89c44ba9e 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -213,7 +213,7 @@ void *git_hashtable_lookup(git_hashtable *self, const void *key)
return NULL;
}
-int git_hashtable_remove(git_hashtable *self, const void *key)
+int git_hashtable_remove2(git_hashtable *self, const void *key, void **old_value)
{
int hash_id;
git_hashtable_node *node;
@@ -223,6 +223,7 @@ int git_hashtable_remove(git_hashtable *self, const void *key)
for (hash_id = 0; hash_id < GIT_HASHTABLE_HASHES; ++hash_id) {
node = node_with_hash(self, key, hash_id);
if (node->key && self->key_equal(key, node->key) == 0) {
+ *old_value = node->value;
node->key = NULL;
node->value = NULL;
self->key_count--;
diff --git a/src/hashtable.h b/src/hashtable.h
index 485b17aa6..cd458eb17 100644
--- a/src/hashtable.h
+++ b/src/hashtable.h
@@ -42,7 +42,15 @@ git_hashtable *git_hashtable_alloc(size_t min_size,
git_hash_ptr hash,
git_hash_keyeq_ptr key_eq);
void *git_hashtable_lookup(git_hashtable *h, const void *key);
-int git_hashtable_remove(git_hashtable *table, const void *key);
+int git_hashtable_remove2(git_hashtable *table, const void *key, void **old_value);
+
+GIT_INLINE(int) git_hashtable_remove(git_hashtable *table, const void *key)
+{
+ void *_unused;
+ return git_hashtable_remove2(table, key, &_unused);
+}
+
+
void git_hashtable_free(git_hashtable *h);
void git_hashtable_clear(git_hashtable *h);
int git_hashtable_merge(git_hashtable *self, git_hashtable *other);
diff --git a/src/ignore.c b/src/ignore.c
index 388a4b280..516da645c 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -88,7 +88,7 @@ int git_ignore__for_path(git_repository *repo, const char *path, git_vector *sta
if ((error = git_attr_cache__init(repo)) < GIT_SUCCESS)
goto cleanup;
- if ((error = git_futils_dir_for_path(&dir, path, workdir)) < GIT_SUCCESS)
+ if ((error = git_path_find_dir(&dir, path, workdir)) < GIT_SUCCESS)
goto cleanup;
/* insert internals */
diff --git a/src/index.c b/src/index.c
index 9e88012bb..66e7a81da 100644
--- a/src/index.c
+++ b/src/index.c
@@ -150,7 +150,7 @@ int git_index_open(git_index **index_out, const char *index_path)
git_vector_init(&index->entries, 32, index_cmp);
/* Check if index file is stored on disk already */
- if (git_futils_exists(index->index_file_path) == 0)
+ if (git_path_exists(index->index_file_path) == 0)
index->on_disk = 1;
*index_out = index;
@@ -221,7 +221,7 @@ int git_index_read(git_index *index)
assert(index->index_file_path);
- if (!index->on_disk || git_futils_exists(index->index_file_path) < 0) {
+ if (!index->on_disk || git_path_exists(index->index_file_path) < 0) {
git_index_clear(index);
index->on_disk = 0;
return GIT_SUCCESS;
diff --git a/src/indexer.c b/src/indexer.c
index 8fdf89d9d..1b2cd61e0 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -164,7 +164,7 @@ static int index_path(git_buf *path, git_indexer *idx)
GIT_OID_HEXSZ + strlen(suffix) + 1) < GIT_SUCCESS)
return GIT_ENOMEM;
- git_buf_truncate(path, slash + 1);
+ git_buf_truncate(path, slash);
git_buf_puts(path, prefix);
git_oid_fmt(path->ptr + path->size, &idx->hash);
path->size += GIT_OID_HEXSZ;
diff --git a/src/odb.c b/src/odb.c
index b52f87078..8905c2237 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -354,7 +354,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir)
if (error < GIT_SUCCESS)
return error;
- if (git_futils_exists(alternates_path.ptr) < GIT_SUCCESS) {
+ if (git_path_exists(alternates_path.ptr) < GIT_SUCCESS) {
git_buf_free(&alternates_path);
return GIT_SUCCESS;
}
diff --git a/src/odb_loose.c b/src/odb_loose.c
index f177af86c..d958fce9f 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -466,7 +466,7 @@ static int locate_object(
int error = object_file_name(object_location, backend->objects_dir, oid);
if (error == GIT_SUCCESS)
- error = git_futils_exists(git_buf_cstr(object_location));
+ error = git_path_exists(git_buf_cstr(object_location));
return error;
}
@@ -480,7 +480,7 @@ static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) {
return GIT_SUCCESS;
}
- if (!git_futils_exists(pathbuf->ptr) && git_futils_isdir(pathbuf->ptr)) {
+ if (!git_path_exists(pathbuf->ptr) && git_path_isdir(pathbuf->ptr)) {
/* We are already in the directory matching the 2 first hex characters,
* compare the first ncmp characters of the oids */
if (!memcmp(sstate->short_oid + 2,
@@ -533,8 +533,8 @@ static int locate_object_short_oid(
return git__rethrow(error, "Failed to locate object from short oid");
/* Check that directory exists */
- if (git_futils_exists(object_location->ptr) ||
- git_futils_isdir(object_location->ptr))
+ if (git_path_exists(object_location->ptr) ||
+ git_path_isdir(object_location->ptr))
return git__throw(GIT_ENOTFOUND, "Failed to locate object from short oid. Object not found");
state.dir_len = object_location->size;
@@ -542,7 +542,7 @@ static int locate_object_short_oid(
state.found = 0;
/* Explore directory to find a unique object matching short_oid */
- error = git_futils_direach(object_location, fn_locate_object_short_oid, &state);
+ error = git_path_direach(object_location, fn_locate_object_short_oid, &state);
if (error)
return git__rethrow(error, "Failed to locate object from short oid");
@@ -716,7 +716,7 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
* is what git does and allows us to sidestep the fact that
* we're not allowed to overwrite a read-only file on Windows.
*/
- if (git_futils_exists(final_path.ptr) == GIT_SUCCESS) {
+ if (git_path_exists(final_path.ptr) == GIT_SUCCESS) {
git_filebuf_cleanup(&stream->fbuf);
goto cleanup;
}
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 757d6277e..81168bfa6 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -254,7 +254,7 @@ static int packfile_refresh_all(struct pack_backend *backend)
git_buf_sets(&path, backend->pack_folder);
/* reload all packs */
- error = git_futils_direach(&path, packfile_load__cb, (void *)backend);
+ error = git_path_direach(&path, packfile_load__cb, (void *)backend);
git_buf_free(&path);
if (error < GIT_SUCCESS)
@@ -469,7 +469,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
if (error < GIT_SUCCESS)
goto cleanup;
- if (git_futils_isdir(git_buf_cstr(&path)) == GIT_SUCCESS) {
+ if (git_path_isdir(git_buf_cstr(&path)) == GIT_SUCCESS) {
backend->pack_folder = git_buf_detach(&path);
backend->pack_folder_mtime = 0;
}
diff --git a/src/pack.c b/src/pack.c
index 1510ded0c..cf64983ca 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -600,7 +600,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
memcpy(p->pack_name, path, path_len);
strcpy(p->pack_name + path_len, ".keep");
- if (git_futils_exists(p->pack_name) == GIT_SUCCESS)
+ if (git_path_exists(p->pack_name) == GIT_SUCCESS)
p->pack_keep = 1;
strcpy(p->pack_name + path_len, ".pack");
diff --git a/src/path.c b/src/path.c
index 03ebfe090..5319ca6a5 100644
--- a/src/path.c
+++ b/src/path.c
@@ -7,7 +7,11 @@
#include "common.h"
#include "path.h"
#include "posix.h"
-
+#ifdef GIT_WIN32
+#include "win32/dir.h"
+#else
+#include <dirent.h>
+#endif
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
@@ -349,3 +353,172 @@ int git_path_walk_up(
return error;
}
+
+int git_path_exists(const char *path)
+{
+ assert(path);
+ return p_access(path, F_OK);
+}
+
+int git_path_isdir(const char *path)
+{
+#ifdef GIT_WIN32
+ DWORD attr = GetFileAttributes(path);
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return GIT_ERROR;
+
+ return (attr & FILE_ATTRIBUTE_DIRECTORY) ? GIT_SUCCESS : GIT_ERROR;
+
+#else
+ struct stat st;
+ if (p_stat(path, &st) < GIT_SUCCESS)
+ return GIT_ERROR;
+
+ return S_ISDIR(st.st_mode) ? GIT_SUCCESS : GIT_ERROR;
+#endif
+}
+
+int git_path_isfile(const char *path)
+{
+ struct stat st;
+ int stat_error;
+
+ assert(path);
+ stat_error = p_stat(path, &st);
+
+ if (stat_error < GIT_SUCCESS)
+ return -1;
+
+ if (!S_ISREG(st.st_mode))
+ return -1;
+
+ return 0;
+}
+
+static int _check_dir_contents(
+ git_buf *dir,
+ const char *sub,
+ int append_on_success,
+ int (*predicate)(const char *))
+{
+ int error = GIT_SUCCESS;
+ size_t dir_size = dir->size;
+ size_t sub_size = strlen(sub);
+
+ /* leave base valid even if we could not make space for subdir */
+ if ((error = git_buf_try_grow(dir, dir_size + sub_size + 2)) < GIT_SUCCESS)
+ return error;
+
+ /* save excursion */
+ git_buf_joinpath(dir, dir->ptr, sub);
+
+ error = (*predicate)(dir->ptr);
+
+ /* restore excursion */
+ if (!append_on_success || error != GIT_SUCCESS)
+ git_buf_truncate(dir, dir_size);
+
+ return error;
+}
+
+int git_path_contains_dir(git_buf *base, const char *subdir, int append_if_exists)
+{
+ return _check_dir_contents(base, subdir, append_if_exists, &git_path_isdir);
+}
+
+int git_path_contains_file(git_buf *base, const char *file, int append_if_exists)
+{
+ return _check_dir_contents(base, file, append_if_exists, &git_path_isfile);
+}
+
+int git_path_find_dir(git_buf *dir, const char *path, const char *base)
+{
+ int error = GIT_SUCCESS;
+
+ if (base != NULL && git_path_root(path) < 0)
+ error = git_buf_joinpath(dir, base, path);
+ else
+ error = git_buf_sets(dir, path);
+
+ if (error == GIT_SUCCESS) {
+ char buf[GIT_PATH_MAX];
+ if (p_realpath(dir->ptr, buf) != NULL)
+ error = git_buf_sets(dir, buf);
+ }
+
+ /* call dirname if this is not a directory */
+ if (error == GIT_SUCCESS && git_path_isdir(dir->ptr) != GIT_SUCCESS)
+ if (git_path_dirname_r(dir, dir->ptr) < GIT_SUCCESS)
+ error = git_buf_lasterror(dir);
+
+ if (error == GIT_SUCCESS)
+ error = git_path_to_dir(dir);
+
+ return error;
+}
+
+int git_path_cmp(const char *name1, int len1, int isdir1,
+ const char *name2, int len2, int isdir2)
+{
+ int len = len1 < len2 ? len1 : len2;
+ int cmp;
+
+ cmp = memcmp(name1, name2, len);
+ if (cmp)
+ return cmp;
+ if (len1 < len2)
+ return ((!isdir1 && !isdir2) ? -1 :
+ (isdir1 ? '/' - name2[len1] : name2[len1] - '/'));
+ if (len1 > len2)
+ return ((!isdir1 && !isdir2) ? 1 :
+ (isdir2 ? name1[len2] - '/' : '/' - name1[len2]));
+ return 0;
+}
+
+/* Taken from git.git */
+GIT_INLINE(int) is_dot_or_dotdot(const char *name)
+{
+ return (name[0] == '.' &&
+ (name[1] == '\0' ||
+ (name[1] == '.' && name[2] == '\0')));
+}
+
+int git_path_direach(
+ git_buf *path,
+ int (*fn)(void *, git_buf *),
+ void *arg)
+{
+ ssize_t wd_len;
+ DIR *dir;
+ struct dirent *de;
+
+ if (git_path_to_dir(path) < GIT_SUCCESS)
+ return git_buf_lasterror(path);
+
+ wd_len = path->size;
+ dir = opendir(path->ptr);
+ if (!dir)
+ return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure. An error occured while opening the directory", path->ptr);
+
+ while ((de = readdir(dir)) != NULL) {
+ int result;
+
+ if (is_dot_or_dotdot(de->d_name))
+ continue;
+
+ if (git_buf_puts(path, de->d_name) < GIT_SUCCESS)
+ return git_buf_lasterror(path);
+
+ result = fn(arg, path);
+
+ git_buf_truncate(path, wd_len); /* restore path */
+
+ if (result != GIT_SUCCESS) {
+ closedir(dir);
+ return result; /* The callee is reponsible for setting the correct error message */
+ }
+ }
+
+ closedir(dir);
+ return GIT_SUCCESS;
+}
diff --git a/src/path.h b/src/path.h
index e59c19ad9..ee3607ce9 100644
--- a/src/path.h
+++ b/src/path.h
@@ -10,6 +10,13 @@
#include "common.h"
#include "buffer.h"
+/**
+ * Path manipulation utils
+ *
+ * These are path utilities that munge paths without actually
+ * looking at the real filesystem.
+ */
+
/*
* The dirname() function shall take a pointer to a character string
* that contains a pathname, and return a pointer to a string that is a
@@ -52,15 +59,30 @@ extern int git_path_basename_r(git_buf *buffer, const char *path);
extern const char *git_path_topdir(const char *path);
+/**
+ * Find offset to root of path if path has one.
+ *
+ * This will return a number >= 0 which is the offset to the start of the
+ * path, if the path is rooted (i.e. "/rooted/path" returns 0 and
+ * "c:/windows/rooted/path" returns 2). If the path is not rooted, this
+ * returns < 0.
+ */
extern int git_path_root(const char *path);
-extern int git_path_prettify(git_buf *path_out, const char *path, const char *base);
-extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base);
-
+/**
+ * Ensure path has a trailing '/'.
+ */
extern int git_path_to_dir(git_buf *path);
+
+/**
+ * Ensure string has a trailing '/' if there is space for it.
+ */
extern void git_path_string_to_dir(char* path, size_t size);
#ifdef GIT_WIN32
+/**
+ * Convert backslashes in path to forward slashes.
+ */
GIT_INLINE(void) git_path_mkposix(char *path)
{
while (*path) {
@@ -75,20 +97,123 @@ GIT_INLINE(void) git_path_mkposix(char *path)
#endif
extern int git__percent_decode(git_buf *decoded_out, const char *input);
+
+/**
+ * Extract path from file:// URL.
+ */
extern int git_path_fromurl(git_buf *local_path_out, const char *file_url);
+
+/**
+ * Path filesystem utils
+ *
+ * These are path utilities that actually access the filesystem.
+ */
+
+/**
+ * Check if a file exists and can be accessed.
+ * @return GIT_SUCCESS if file exists, < 0 otherwise.
+ */
+extern int git_path_exists(const char *path);
+
+/**
+ * Check if the given path points to a directory.
+ * @return GIT_SUCCESS if it is a directory, < 0 otherwise.
+ */
+extern int git_path_isdir(const char *path);
+
/**
- * Invoke callback directory by directory up the path until the ceiling
- * is reached (inclusive of a final call at the root_path).
+ * Check if the given path points to a regular file.
+ * @return GIT_SUCCESS if it is a regular file, < 0 otherwise.
+ */
+extern int git_path_isfile(const char *path);
+
+/**
+ * Check if the given path contains the given subdirectory.
+ *
+ * @param parent Directory path that might contain subdir
+ * @param subdir Subdirectory name to look for in parent
+ * @param append_if_exists If true, then subdir will be appended to the parent path if it does exist
+ * @return GIT_SUCCESS if subdirectory exists, < 0 otherwise.
+ */
+extern int git_path_contains_dir(git_buf *parent, const char *subdir, int append_if_exists);
+
+/**
+ * Check if the given path contains the given file.
+ *
+ * @param dir Directory path that might contain file
+ * @param file File name to look for in parent
+ * @param append_if_exists If true, then file will be appended to the path if it does exist
+ * @return GIT_SUCCESS if file exists, < 0 otherwise.
+ */
+extern int git_path_contains_file(git_buf *dir, const char *file, int append_if_exists);
+
+/**
+ * Clean up path, prepending base if it is not already rooted.
+ */
+extern int git_path_prettify(git_buf *path_out, const char *path, const char *base);
+
+/**
+ * Clean up path, prepending base if it is not already rooted and
+ * appending a slash.
+ */
+extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base);
+
+/**
+ * Get a directory from a path.
+ *
+ * If path is a directory, this acts like `git_path_prettify_dir`
+ * (cleaning up path and appending a '/'). If path is a normal file,
+ * this prettifies it, then removed the filename a la dirname and
+ * appends the trailing '/'. If the path does not exist, it is
+ * treated like a regular filename.
+ */
+extern int git_path_find_dir(git_buf *dir, const char *path, const char *base);
+
+/**
+ * Walk each directory entry, except '.' and '..', calling fn(state).
+ *
+ * @param pathbuf buffer the function reads the initial directory
+ * path from, and updates with each successive entry's name.
+ * @param fn function to invoke with each entry. The first arg is
+ * the input state and the second arg is pathbuf. The function
+ * may modify the pathbuf, but only by appending new text.
+ * @param state to pass to fn as the first arg.
+ */
+extern int git_path_direach(
+ git_buf *pathbuf,
+ int (*fn)(void *, git_buf *),
+ void *state);
+
+/**
+ * Sort function to order two paths.
+ */
+extern int git_path_cmp(
+ const char *name1, int len1, int isdir1,
+ const char *name2, int len2, int isdir2);
+
+/**
+ * Invoke callback up path directory by directory until the ceiling is
+ * reached (inclusive of a final call at the root_path).
+ *
+ * Returning anything other than GIT_SUCCESS from the callback function
+ * will stop the iteration and propogate the error to the caller.
*
- * If the ceiling is NULL, this will walk all the way up to the root.
- * If the ceiling is not a prefix of the path, the callback will be
- * invoked a single time on the verbatim input path. Returning anything
- * other than GIT_SUCCESS from the callback function will stop the
- * iteration and propogate the error to the caller.
+ * @param pathbuf Buffer the function reads the directory from and
+ * and updates with each successive name.
+ * @param ceiling Prefix of path at which to stop walking up. If NULL,
+ * this will walk all the way up to the root. If not a prefix of
+ * pathbuf, the callback will be invoked a single time on the
+ * original input path.
+ * @param fn Function to invoke on each path. The first arg is the
+ * input satte and the second arg is the pathbuf. The function
+ * should not modify the pathbuf.
+ * @param state Passed to fn as the first ath.
*/
extern int git_path_walk_up(
- git_buf *path, const char *ceiling,
- int (*cb)(void *data, git_buf *), void *data);
+ git_buf *pathbuf,
+ const char *ceiling,
+ int (*fn)(void *state, git_buf *),
+ void *state);
#endif
diff --git a/src/reflog.c b/src/reflog.c
index a327975d6..970e7c2de 100644
--- a/src/reflog.c
+++ b/src/reflog.c
@@ -246,12 +246,12 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old,
if (error < GIT_SUCCESS)
goto cleanup;
- if (git_futils_exists(log_path.ptr)) {
+ if (git_path_exists(log_path.ptr)) {
error = git_futils_mkpath2file(log_path.ptr, GIT_REFLOG_DIR_MODE);
if (error < GIT_SUCCESS)
git__rethrow(error,
"Failed to write reflog. Cannot create reflog directory");
- } else if (git_futils_isfile(log_path.ptr)) {
+ } else if (git_path_isfile(log_path.ptr)) {
error = git__throw(GIT_ERROR,
"Failed to write reflog. `%s` is directory", log_path.ptr);
} else if (oid_old == NULL) {
@@ -302,7 +302,7 @@ int git_reflog_delete(git_reference *ref)
error = git_buf_join_n(&path, '/', 3,
ref->owner->path_repository, GIT_REFLOG_DIR, ref->name);
- if (error == GIT_SUCCESS && git_futils_exists(path.ptr) == 0)
+ if (error == GIT_SUCCESS && git_path_exists(path.ptr) == 0)
error = p_unlink(path.ptr);
git_buf_free(&path);
diff --git a/src/refs.c b/src/refs.c
index 2842adab1..86e5f5dba 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -525,8 +525,8 @@ static int _dirent_loose_listall(void *_data, git_buf *full_path)
struct dirent_list_data *data = (struct dirent_list_data *)_data;
const char *file_path = full_path->ptr + data->repo_path_len;
- if (git_futils_isdir(full_path->ptr) == GIT_SUCCESS)
- return git_futils_direach(full_path, _dirent_loose_listall, _data);
+ if (git_path_isdir(full_path->ptr) == GIT_SUCCESS)
+ return git_path_direach(full_path, _dirent_loose_listall, _data);
/* do not add twice a reference that exists already in the packfile */
if ((data->list_flags & GIT_REF_PACKED) != 0 &&
@@ -549,8 +549,8 @@ static int _dirent_loose_load(void *data, git_buf *full_path)
const char *file_path;
int error;
- if (git_futils_isdir(full_path->ptr) == GIT_SUCCESS)
- return git_futils_direach(full_path, _dirent_loose_load, repository);
+ if (git_path_isdir(full_path->ptr) == GIT_SUCCESS)
+ return git_path_direach(full_path, _dirent_loose_load, repository);
file_path = full_path->ptr + strlen(repository->path_repository);
error = loose_lookup_to_packfile(&ref, repository, file_path);
@@ -596,7 +596,7 @@ static int packed_loadloose(git_repository *repository)
* This will overwrite any old packed entries with their
* updated loose versions
*/
- error = git_futils_direach(&refs_path, _dirent_loose_load, repository);
+ error = git_path_direach(&refs_path, _dirent_loose_load, repository);
git_buf_free(&refs_path);
return error;
}
@@ -719,7 +719,7 @@ static int packed_remove_loose(git_repository *repo, git_vector *packing_list)
an_error = git_buf_joinpath(&full_path, repo->path_repository, ref->name);
if (an_error == GIT_SUCCESS &&
- git_futils_exists(full_path.ptr) == GIT_SUCCESS &&
+ git_path_exists(full_path.ptr) == GIT_SUCCESS &&
p_unlink(full_path.ptr) < GIT_SUCCESS)
an_error = GIT_EOSERR;
@@ -902,7 +902,7 @@ static int reference_exists(int *exists, git_repository *repo, const char *ref_n
if (error < GIT_SUCCESS)
return git__rethrow(error, "Cannot resolve if a reference exists");
- if (git_futils_isfile(ref_path.ptr) == GIT_SUCCESS ||
+ if (git_path_isfile(ref_path.ptr) == GIT_SUCCESS ||
git_hashtable_lookup(repo->references.packfile, ref_path.ptr) != NULL) {
*exists = 1;
} else {
@@ -984,14 +984,16 @@ static int reference_delete(git_reference *ref)
* We need to reload the packfile, remove the reference from the
* packing list, and repack */
if (ref->flags & GIT_REF_PACKED) {
+ struct packref *packref;
/* load the existing packfile */
if ((error = packed_load(ref->owner)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to delete reference");
- if (git_hashtable_remove(ref->owner->references.packfile,
- ref->name) < GIT_SUCCESS)
+ if (git_hashtable_remove2(ref->owner->references.packfile,
+ ref->name, (void **) &packref) < GIT_SUCCESS)
return git__throw(GIT_ENOTFOUND, "Reference not found");
+ git__free (packref);
error = packed_write(ref->owner);
/* If the reference is loose, we can just remove the reference
@@ -1352,8 +1354,8 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force)
if ((error = reference_delete(ref)) < GIT_SUCCESS)
goto cleanup;
- if (git_futils_exists(aux_path.ptr) == GIT_SUCCESS) {
- if (git_futils_isdir(aux_path.ptr) == GIT_SUCCESS) {
+ if (git_path_exists(aux_path.ptr) == GIT_SUCCESS) {
+ if (git_path_isdir(aux_path.ptr) == GIT_SUCCESS) {
if ((error = git_futils_rmdir_r(aux_path.ptr, 0)) < GIT_SUCCESS)
goto rollback;
} else goto rollback;
@@ -1398,7 +1400,7 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force)
if (error < GIT_SUCCESS)
goto cleanup;
- if (git_futils_exists(aux_path.ptr) == GIT_SUCCESS)
+ if (git_path_exists(aux_path.ptr) == GIT_SUCCESS)
error = git_reflog_rename(ref, new_name);
/*
@@ -1536,7 +1538,7 @@ int git_reference_foreach(
repo->path_repository, GIT_REFS_DIR)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to alloc space for references");
- error = git_futils_direach(&refs_path, _dirent_loose_listall, &data);
+ error = git_path_direach(&refs_path, _dirent_loose_listall, &data);
git_buf_free(&refs_path);
diff --git a/src/refspec.c b/src/refspec.c
index 7ce32ba14..7694be525 100644
--- a/src/refspec.c
+++ b/src/refspec.c
@@ -57,7 +57,7 @@ const char *git_refspec_dst(const git_refspec *refspec)
int git_refspec_src_match(const git_refspec *refspec, const char *refname)
{
- return refspec == NULL ? GIT_ENOMATCH : git__fnmatch(refspec->src, refname, 0);
+ return (refspec == NULL || refspec->src == NULL) ? GIT_ENOMATCH : git__fnmatch(refspec->src, refname, 0);
}
int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name)
diff --git a/src/remote.c b/src/remote.c
index ef42c6e2a..cdf28789b 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -279,9 +279,10 @@ int git_remote_update_tips(git_remote *remote)
if (!strcmp(head->name, GIT_HEAD_FILE)) {
error = git_reference_create_oid(&ref, remote->repo, GIT_FETCH_HEAD_FILE, &head->oid, 1);
i = 1;
- git_reference_free(ref);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to update FETCH_HEAD");
+
+ git_reference_free(ref);
}
for (; i < refs->length; ++i) {
diff --git a/src/repository.c b/src/repository.c
index a408599f7..97d70c437 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -79,14 +79,14 @@ void git_repository_free(git_repository *repo)
static int quickcheck_repository_dir(git_buf *repository_path)
{
/* Check OBJECTS_DIR first, since it will generate the longest path name */
- if (git_futils_contains_dir(repository_path, GIT_OBJECTS_DIR, 0) < 0)
+ if (git_path_contains_dir(repository_path, GIT_OBJECTS_DIR, 0) < 0)
return GIT_ERROR;
/* Ensure HEAD file exists */
- if (git_futils_contains_file(repository_path, GIT_HEAD_FILE, 0) < 0)
+ if (git_path_contains_file(repository_path, GIT_HEAD_FILE, 0) < 0)
return GIT_ERROR;
- if (git_futils_contains_dir(repository_path, GIT_REFS_DIR, 0) < 0)
+ if (git_path_contains_dir(repository_path, GIT_REFS_DIR, 0) < 0)
return GIT_ERROR;
return GIT_SUCCESS;
@@ -164,12 +164,12 @@ int git_repository_open(git_repository **repo_out, const char *path)
* of the working dir, by testing if it contains a `.git`
* folder inside of it.
*/
- git_futils_contains_dir(&path_buf, DOT_GIT, 1); /* append on success */
+ git_path_contains_dir(&path_buf, DOT_GIT, 1); /* append on success */
/* ignore error, since it just means `path/.git` doesn't exist */
if (quickcheck_repository_dir(&path_buf) < GIT_SUCCESS) {
error = git__throw(GIT_ENOTAREPO,
- "The given path is not a valid Git repository");
+ "The given path (%s) is not a valid Git repository", git_buf_cstr(&path_buf));
goto cleanup;
}
@@ -491,7 +491,7 @@ static int read_gitfile(git_buf *path_out, const char *file_path, const char *ba
git_futils_freebuffer(&file);
- if (error == GIT_SUCCESS && git_futils_exists(path_out->ptr) == 0)
+ if (error == GIT_SUCCESS && git_path_exists(path_out->ptr) == 0)
return GIT_SUCCESS;
return git__throw(GIT_EOBJCORRUPTED, "The `.git` file points to a nonexistent path");
@@ -535,7 +535,7 @@ int git_repository_discover(
* If the `.git` file is regular instead of
* a directory, it should contain the path of the actual git repository
*/
- if (git_futils_isfile(normal_path.ptr) == GIT_SUCCESS) {
+ if (git_path_isfile(normal_path.ptr) == GIT_SUCCESS) {
git_buf gitfile_path = GIT_BUF_INIT;
error = read_gitfile(&gitfile_path, normal_path.ptr, bare_path.ptr);
@@ -557,7 +557,7 @@ int git_repository_discover(
/**
* If the `.git` file is a folder, we check inside of it
*/
- if (git_futils_isdir(normal_path.ptr) == GIT_SUCCESS) {
+ if (git_path_isdir(normal_path.ptr) == GIT_SUCCESS) {
error = quickcheck_repository_dir(&normal_path);
if (error == GIT_SUCCESS) {
found_path = &normal_path;
@@ -733,7 +733,7 @@ int git_repository_init(git_repository **repo_out, const char *path, unsigned is
if (error < GIT_SUCCESS)
return error;
- if (git_futils_isdir(repository_path.ptr) == GIT_SUCCESS) {
+ if (git_path_isdir(repository_path.ptr) == GIT_SUCCESS) {
if (quickcheck_repository_dir(&repository_path) == GIT_SUCCESS) {
error = repo_init_reinit(repository_path.ptr, is_bare);
git_buf_free(&repository_path);
diff --git a/src/status.c b/src/status.c
index 3ead15a87..492edf568 100644
--- a/src/status.c
+++ b/src/status.c
@@ -489,7 +489,7 @@ int git_status_foreach(
dirent_st.index_position = 0;
dirent_st.is_dir = 1;
- if (git_futils_isdir(workdir)) {
+ if (git_path_isdir(workdir)) {
error = git__throw(GIT_EINVALIDPATH,
"Failed to determine status of file '%s'. "
"The given path doesn't lead to a folder", workdir);
@@ -592,7 +592,7 @@ int git_status_file(unsigned int *status_flags, git_repository *repo, const char
return git__rethrow(error,
"Failed to determine status of file '%s'", path);
- if (git_futils_isdir(temp_path.ptr) == GIT_SUCCESS) {
+ if (git_path_isdir(temp_path.ptr) == GIT_SUCCESS) {
git_buf_free(&temp_path);
return git__throw(GIT_EINVALIDPATH,
"Failed to determine status of file '%s'. "
@@ -606,7 +606,7 @@ int git_status_file(unsigned int *status_flags, git_repository *repo, const char
}
/* Find file in Workdir */
- if (git_futils_exists(temp_path.ptr) == GIT_SUCCESS) {
+ if (git_path_exists(temp_path.ptr) == GIT_SUCCESS) {
if ((error = status_entry_update_from_workdir(e, temp_path.ptr)) < GIT_SUCCESS)
goto cleanup; /* The callee has already set the error message */
}
@@ -672,8 +672,8 @@ cleanup:
}
/*
- * git_futils_direach is not supposed to return entries in an ordered manner.
- * alphasorted_futils_direach wraps git_futils_direach and invokes the callback
+ * git_path_direach is not supposed to return entries in an ordered manner.
+ * alphasorted_futils_direach wraps git_path_direach and invokes the callback
* function by passing it alphabeticcally sorted paths parameters.
*
*/
@@ -686,7 +686,7 @@ static char *alphasorted_dirent_info_new(const git_buf *path)
git_buf_copy_cstr(di, path->size + 1, path);
- if (git_futils_isdir(path->ptr) == GIT_SUCCESS) {
+ if (git_path_isdir(path->ptr) == GIT_SUCCESS) {
/*
* Append a forward slash to the name to force folders
* to be ordered in a similar way than in a tree
@@ -734,7 +734,7 @@ static int alphasorted_futils_direach(
if (git_vector_init(&entry_names, 16, git__strcmp_cb) < GIT_SUCCESS)
return GIT_ENOMEM;
- error = git_futils_direach(path, alphasorted_dirent_cb, &entry_names);
+ error = git_path_direach(path, alphasorted_dirent_cb, &entry_names);
git_vector_sort(&entry_names);
diff --git a/src/transport.c b/src/transport.c
index d836561b4..00b79dc6d 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -23,7 +23,7 @@ static struct {
{NULL, 0}
};
-#define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0]))
+#define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1
static git_transport_cb transport_find_fn(const char *url)
{
diff --git a/src/transports/http.c b/src/transports/http.c
index 48ea78dce..38446bdef 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -71,7 +71,7 @@ static int gen_request(git_buf *buf, const char *url, const char *host, const ch
if (content_length > 0) {
git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", service);
git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", service);
- git_buf_printf(buf, "Content-Length: %zd\r\n", content_length);
+ git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length);
} else {
git_buf_puts(buf, "Accept: */*\r\n");
}
diff --git a/src/tree.c b/src/tree.c
index 8bc17d975..373d82b3a 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -30,7 +30,7 @@ static int entry_sort_cmp(const void *a, const void *b)
const git_tree_entry *entry_a = (const git_tree_entry *)(a);
const git_tree_entry *entry_b = (const git_tree_entry *)(b);
- return git_futils_cmp_path(
+ return git_path_cmp(
entry_a->filename, entry_a->filename_len, entry_is_tree(entry_a),
entry_b->filename, entry_b->filename_len, entry_is_tree(entry_b));
}
@@ -993,6 +993,7 @@ static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data)
if (!ientry) {
error = signal_deletion(tentry, cbdata->cb, cbdata->data);
+ git_buf_free(&fn_buf);
goto exit;
}
diff --git a/src/dir.h b/src/win32/dir.h
index 5d50692e4..b16a3cfeb 100644
--- a/src/dir.h
+++ b/src/win32/dir.h
@@ -9,12 +9,6 @@
#include "common.h"
-#ifndef GIT_WIN32
-# include <dirent.h>
-#endif
-
-#ifdef GIT_WIN32
-
struct git__dirent {
int d_ino;
char d_name[261];
@@ -42,6 +36,4 @@ extern int git__closedir(git__DIR *);
# define closedir git__closedir
# endif
-#endif
-
#endif /* INCLUDE_dir_h__ */
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index f68742fc0..3786f0162 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -80,7 +80,7 @@ static int do_lstat(const char *file_name, struct stat *buf)
buf->st_uid = 0;
buf->st_nlink = 1;
buf->st_mode = (mode_t)fMode;
- buf->st_size = (fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow;
+ buf->st_size = ((git_off_t)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow;
buf->st_dev = buf->st_rdev = (_getdrive() - 1);
buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));