summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attr.c6
-rw-r--r--src/config_file.c12
-rw-r--r--src/netops.c3
-rw-r--r--src/object.c4
-rw-r--r--src/path.c6
-rw-r--r--src/pkt.c1
-rw-r--r--src/posix.c15
-rw-r--r--src/posix.h2
-rw-r--r--src/remote.c60
-rw-r--r--src/repository.c5
-rw-r--r--src/status.c8
-rw-r--r--src/win32/posix.h2
-rw-r--r--src/win32/posix_w32.c41
13 files changed, 123 insertions, 42 deletions
diff --git a/src/attr.c b/src/attr.c
index b7ac6355d..616cec6ff 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -450,11 +450,11 @@ static int collect_attr_files(
git_vector_init(files, 4, NULL) < 0)
return -1;
- /* given a unrooted path in a non-bare repo, resolve it */
- if (workdir && git_path_root(path) < 0)
+ /* Resolve path in a non-bare repo */
+ if (workdir != NULL)
error = git_path_find_dir(&dir, path, workdir);
else
- error = git_buf_sets(&dir, path);
+ error = git_path_dirname_r(&dir, path);
if (error < 0)
goto cleanup;
diff --git a/src/config_file.c b/src/config_file.c
index 746d9655c..4ccec2bc1 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -258,18 +258,17 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
GITERR_CHECK_ALLOC(var->value);
}
+ if (config_write(b, key, NULL, value) < 0) {
+ cvar_free(var);
+ return -1;
+ }
+
git_strmap_insert2(b->values, key, var, old_var, rval);
if (rval < 0)
return -1;
if (old_var != NULL)
cvar_free(old_var);
- if (config_write(b, key, NULL, value) < 0) {
- git_strmap_delete(b->values, var->key);
- cvar_free(var);
- return -1;
- }
-
return 0;
}
@@ -1018,6 +1017,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
pre_end = post_start = cfg->reader.read_ptr;
git__free(current_section);
+ current_section = NULL;
if (parse_section_header(cfg, &current_section) < 0)
goto rewrite_fail;
diff --git a/src/netops.c b/src/netops.c
index 2d200002f..4d461a049 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -11,7 +11,6 @@
# include <sys/time.h>
# include <netdb.h>
#else
-# define _WIN32_WINNT 0x0501
# include <winsock2.h>
# include <Ws2tcpip.h>
# ifdef _MSC_VER
@@ -36,7 +35,7 @@ static void net_set_error(const char *str)
size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
0, error, 0, (LPSTR)&err_str, 0, 0);
- giterr_set(GITERR_NET, "%s: $s", str, err_str);
+ giterr_set(GITERR_NET, "%s: %s", str, err_str);
LocalFree(err_str);
}
#else
diff --git a/src/object.c b/src/object.c
index e02bd69ba..02be5dac8 100644
--- a/src/object.c
+++ b/src/object.c
@@ -150,8 +150,8 @@ int git_object_lookup_prefix(
if (type != GIT_OBJ_ANY && type != odb_obj->raw.type) {
git_odb_object_free(odb_obj);
- giterr_set(GITERR_INVALID, "The given type does not match the type on the ODB");
- return -1;
+ giterr_set(GITERR_ODB, "The given type does not match the type on the ODB");
+ return GIT_ENOTFOUND;
}
type = odb_obj->raw.type;
diff --git a/src/path.c b/src/path.c
index 703f43af1..9f31676b1 100644
--- a/src/path.c
+++ b/src/path.c
@@ -205,9 +205,13 @@ int git_path_prettify(git_buf *path_out, const char *path, const char *base)
}
if (p_realpath(path, buf) == NULL) {
+ /* giterr_set resets the errno when dealing with a GITERR_OS kind of error */
+ int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1;
giterr_set(GITERR_OS, "Failed to resolve path '%s'", path);
+
git_buf_clear(path_out);
- return (errno == ENOENT) ? GIT_ENOTFOUND : -1;
+
+ return error;
}
return git_buf_sets(path_out, buf);
diff --git a/src/pkt.c b/src/pkt.c
index 00836bc34..b9c87f169 100644
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -217,6 +217,7 @@ int git_pkt_parse_line(
* server is trying to send us the packfile already.
*/
if (bufflen >= 4 && !git__prefixcmp(line, "PACK")) {
+ giterr_clear();
*out = line;
return pack_pkt(head);
}
diff --git a/src/posix.c b/src/posix.c
index a3f81d767..a9a6af984 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -12,9 +12,20 @@
#ifndef GIT_WIN32
-int p_open(const char *path, int flags)
+int p_open(const char *path, int flags, ...)
{
- return open(path, flags | O_BINARY);
+ mode_t mode = 0;
+
+ if (flags & O_CREAT)
+ {
+ va_list arg_list;
+
+ va_start(arg_list, flags);
+ mode = (mode_t)va_arg(arg_list, int);
+ va_end(arg_list);
+ }
+
+ return open(path, flags | O_BINARY, mode);
}
int p_creat(const char *path, mode_t mode)
diff --git a/src/posix.h b/src/posix.h
index 752d5156f..d020d94ac 100644
--- a/src/posix.h
+++ b/src/posix.h
@@ -42,7 +42,7 @@ extern int p_write(git_file fd, const void *buf, size_t cnt);
#define p_close(fd) close(fd)
#define p_umask(m) umask(m)
-extern int p_open(const char *path, int flags);
+extern int p_open(const char *path, int flags, ...);
extern int p_creat(const char *path, mode_t mode);
extern int p_getcwd(char *buffer_out, size_t size);
extern int p_rename(const char *from, const char *to);
diff --git a/src/remote.c b/src/remote.c
index 98c256929..a5cfc822e 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -54,7 +54,7 @@ static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const cha
return refspec_parse(refspec, val);
}
-int git_remote_new(git_remote **out, git_repository *repo, const char *url, const char *name)
+int git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
{
git_remote *remote;
@@ -78,8 +78,17 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *url, cons
GITERR_CHECK_ALLOC(remote->name);
}
+ if (fetch != NULL) {
+ if (refspec_parse(&remote->fetch, fetch) < 0)
+ goto on_error;
+ }
+
*out = remote;
return 0;
+
+on_error:
+ git_remote_free(remote);
+ return -1;
}
int git_remote_load(git_remote **out, git_repository *repo, const char *name)
@@ -102,24 +111,28 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
remote->name = git__strdup(name);
GITERR_CHECK_ALLOC(remote->name);
- if (git_vector_init(&remote->refs, 32, NULL) < 0)
- return -1;
-
- if (git_buf_printf(&buf, "remote.%s.url", name) < 0)
- return -1;
+ if (git_vector_init(&remote->refs, 32, NULL) < 0) {
+ error = -1;
+ goto cleanup;
+ }
- if (git_config_get_string(config, git_buf_cstr(&buf), &val) < 0) {
+ if (git_buf_printf(&buf, "remote.%s.url", name) < 0) {
error = -1;
goto cleanup;
}
+ if ((error = git_config_get_string(config, git_buf_cstr(&buf), &val)) < 0)
+ goto cleanup;
+
remote->repo = repo;
remote->url = git__strdup(val);
GITERR_CHECK_ALLOC(remote->url);
git_buf_clear(&buf);
- if (git_buf_printf(&buf, "remote.%s.fetch", name) < 0)
- return -1;
+ if (git_buf_printf(&buf, "remote.%s.fetch", name) < 0) {
+ error = -1;
+ goto cleanup;
+ }
error = parse_remote_refspec(config, &remote->fetch, git_buf_cstr(&buf));
if (error == GIT_ENOTFOUND)
@@ -131,8 +144,10 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
}
git_buf_clear(&buf);
- if (git_buf_printf(&buf, "remote.%s.push", name) < 0)
- return -1;
+ if (git_buf_printf(&buf, "remote.%s.push", name) < 0) {
+ error = -1;
+ goto cleanup;
+ }
error = parse_remote_refspec(config, &remote->push, git_buf_cstr(&buf));
if (error == GIT_ENOTFOUND)
@@ -470,3 +485,26 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo)
return 0;
}
+
+int git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url)
+{
+ git_buf buf = GIT_BUF_INIT;
+
+ if (git_buf_printf(&buf, "refs/heads/*:refs/remotes/%s/*", name) < 0)
+ return -1;
+
+ if (git_remote_new(out, repo, name, url, git_buf_cstr(&buf)) < 0)
+ goto on_error;
+
+ git_buf_free(&buf);
+
+ if (git_remote_save(*out) < 0)
+ goto on_error;
+
+ return 0;
+
+on_error:
+ git_buf_free(&buf);
+ git_remote_free(*out);
+ return -1;
+}
diff --git a/src/repository.c b/src/repository.c
index d4de38104..ea9673731 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -397,13 +397,14 @@ int git_repository_discover(
{
git_buf path = GIT_BUF_INIT;
uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
+ int error;
assert(start_path && repository_path && size > 0);
*repository_path = '\0';
- if (find_repo(&path, NULL, start_path, flags, ceiling_dirs) < 0)
- return -1;
+ if ((error = find_repo(&path, NULL, start_path, flags, ceiling_dirs)) < 0)
+ return error != GIT_ENOTFOUND ? -1 : error;
if (size < (size_t)(path.size + 1)) {
giterr_set(GITERR_REPOSITORY,
diff --git a/src/status.c b/src/status.c
index ff8535c66..546dc863d 100644
--- a/src/status.c
+++ b/src/status.c
@@ -340,17 +340,17 @@ int git_status_file(
assert(status_flags && repo && path);
if ((workdir = git_repository_workdir(repo)) == NULL) {
- giterr_set(GITERR_OS, "Cannot get file status from bare repo");
- return GIT_ENOTFOUND;
+ giterr_set(GITERR_INVALID, "Cannot get file status from bare repo");
+ return -1;
}
if (git_buf_joinpath(&temp_path, workdir, path) < 0)
return -1;
if (git_path_isdir(temp_path.ptr)) {
- giterr_set(GITERR_OS, "Cannot get file status for directory '%s'", temp_path.ptr);
+ giterr_set(GITERR_INVALID, "Cannot get file status for directory '%s'", temp_path.ptr);
git_buf_free(&temp_path);
- return GIT_ENOTFOUND;
+ return -1;
}
e = status_entry_new(NULL, path);
diff --git a/src/win32/posix.h b/src/win32/posix.h
index d13d3e39b..2666fccb4 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -45,7 +45,7 @@ extern int p_chmod(const char* path, mode_t mode);
extern int p_rmdir(const char* path);
extern int p_access(const char* path, mode_t mode);
extern int p_fsync(int fd);
-extern int p_open(const char *path, int flags);
+extern int p_open(const char *path, int flags, ...);
extern int p_creat(const char *path, mode_t mode);
extern int p_getcwd(char *buffer_out, size_t size);
extern int p_rename(const char *from, const char *to);
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 8af664165..10de70da8 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -217,13 +217,27 @@ int p_readlink(const char *link, char *target, size_t target_len)
return dwRet;
}
-int p_open(const char *path, int flags)
+int p_open(const char *path, int flags, ...)
{
int fd;
- wchar_t* buf = gitwin_to_utf16(path);
+ wchar_t* buf;
+ mode_t mode = 0;
+
+ buf = gitwin_to_utf16(path);
if (!buf)
return -1;
- fd = _wopen(buf, flags | _O_BINARY);
+
+ if (flags & O_CREAT)
+ {
+ va_list arg_list;
+
+ va_start(arg_list, flags);
+ mode = va_arg(arg_list, mode_t);
+ va_end(arg_list);
+ }
+
+ fd = _wopen(buf, flags | _O_BINARY, mode);
+
git__free(buf);
return fd;
}
@@ -312,7 +326,7 @@ int p_hide_directory__w32(const char *path)
char *p_realpath(const char *orig_path, char *buffer)
{
- int ret;
+ int ret, buffer_sz = 0;
wchar_t* orig_path_w = gitwin_to_utf16(orig_path);
wchar_t* buffer_w = (wchar_t*)git__malloc(GIT_PATH_MAX * sizeof(wchar_t));
@@ -322,13 +336,14 @@ char *p_realpath(const char *orig_path, char *buffer)
ret = GetFullPathNameW(orig_path_w, GIT_PATH_MAX, buffer_w, NULL);
git__free(orig_path_w);
- if (!ret || ret > GIT_PATH_MAX) {
+ /* According to MSDN, a return value equals to zero means a failure. */
+ if (ret == 0 || ret > GIT_PATH_MAX) {
buffer = NULL;
goto done;
}
if (buffer == NULL) {
- int buffer_sz = WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, NULL, 0, NULL, NULL);
+ buffer_sz = WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, NULL, 0, NULL, NULL);
if (!buffer_sz ||
!(buffer = (char *)git__malloc(buffer_sz)) ||
@@ -336,10 +351,22 @@ char *p_realpath(const char *orig_path, char *buffer)
{
git__free(buffer);
buffer = NULL;
+ goto done;
}
} else {
- if (!WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, buffer, GIT_PATH_MAX, NULL, NULL))
+ if (!WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, buffer, GIT_PATH_MAX, NULL, NULL)) {
buffer = NULL;
+ goto done;
+ }
+ }
+
+ if (!git_path_exists(buffer))
+ {
+ if (buffer_sz > 0)
+ git__free(buffer);
+
+ buffer = NULL;
+ errno = ENOENT;
}
done: