Commit 5915a2a2 by Carlos Martín Nieto

Merge pull request #3349 from libgit2/cmn/for-v23

A second round of 0.23 maint updates
parents 6a0d5696 16cee5d6
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# > cmake --build . --target install # > cmake --build . --target install
PROJECT(libgit2 C) PROJECT(libgit2 C)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_POLICY(SET CMP0015 NEW) CMAKE_POLICY(SET CMP0015 NEW)
# Add find modules to the path # Add find modules to the path
...@@ -412,6 +412,7 @@ ELSE () ...@@ -412,6 +412,7 @@ ELSE ()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
ENDIF () ENDIF ()
ADD_C_FLAG_IF_SUPPORTED(-Wdocumentation)
ADD_C_FLAG_IF_SUPPORTED(-Wno-missing-field-initializers) ADD_C_FLAG_IF_SUPPORTED(-Wno-missing-field-initializers)
ADD_C_FLAG_IF_SUPPORTED(-Wstrict-aliasing=2) ADD_C_FLAG_IF_SUPPORTED(-Wstrict-aliasing=2)
ADD_C_FLAG_IF_SUPPORTED(-Wstrict-prototypes) ADD_C_FLAG_IF_SUPPORTED(-Wstrict-prototypes)
......
...@@ -88,7 +88,7 @@ Under Unix-like systems, like Linux, \*BSD and Mac OS X, libgit2 expects `pthrea ...@@ -88,7 +88,7 @@ Under Unix-like systems, like Linux, \*BSD and Mac OS X, libgit2 expects `pthrea
they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API
for threading. for threading.
The `libgit2` library is built using [CMake](<http://www.cmake.org>) (version 2.6 or newer) on all platforms. The `libgit2` library is built using [CMake](<http://www.cmake.org>) (version 2.8 or newer) on all platforms.
On most systems you can build the library using the following commands On most systems you can build the library using the following commands
......
...@@ -745,7 +745,7 @@ GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, cons ...@@ -745,7 +745,7 @@ GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, cons
* *
* @param repo the repository to configure * @param repo the repository to configure
* @param name the name to use for the reflog entries * @param name the name to use for the reflog entries
* @param name the email to use for the reflog entries * @param email the email to use for the reflog entries
*/ */
GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email); GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email);
......
...@@ -76,7 +76,7 @@ struct git_config_backend { ...@@ -76,7 +76,7 @@ struct git_config_backend {
* Initializes a `git_config_backend` with default values. Equivalent to * Initializes a `git_config_backend` with default values. Equivalent to
* creating an instance with GIT_CONFIG_BACKEND_INIT. * creating an instance with GIT_CONFIG_BACKEND_INIT.
* *
* @param opts the `git_config_backend` struct to initialize. * @param backend the `git_config_backend` struct to initialize.
* @param version Version of struct; pass `GIT_CONFIG_BACKEND_VERSION` * @param version Version of struct; pass `GIT_CONFIG_BACKEND_VERSION`
* @return Zero on success; -1 on failure. * @return Zero on success; -1 on failure.
*/ */
......
...@@ -38,7 +38,7 @@ GIT_EXTERN(int) git_diff_print_callback__to_buf( ...@@ -38,7 +38,7 @@ GIT_EXTERN(int) git_diff_print_callback__to_buf(
const git_diff_delta *delta, const git_diff_delta *delta,
const git_diff_hunk *hunk, const git_diff_hunk *hunk,
const git_diff_line *line, const git_diff_line *line,
void *payload); /*< payload must be a `git_buf *` */ void *payload); /**< payload must be a `git_buf *` */
/** /**
* Diff print callback that writes to stdio FILE handle. * Diff print callback that writes to stdio FILE handle.
...@@ -58,7 +58,7 @@ GIT_EXTERN(int) git_diff_print_callback__to_file_handle( ...@@ -58,7 +58,7 @@ GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
const git_diff_delta *delta, const git_diff_delta *delta,
const git_diff_hunk *hunk, const git_diff_hunk *hunk,
const git_diff_line *line, const git_diff_line *line,
void *payload); /*< payload must be a `FILE *` */ void *payload); /**< payload must be a `FILE *` */
/** /**
...@@ -66,8 +66,8 @@ GIT_EXTERN(int) git_diff_print_callback__to_file_handle( ...@@ -66,8 +66,8 @@ GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
*/ */
typedef struct { typedef struct {
unsigned int version; unsigned int version;
size_t stat_calls; /*< Number of stat() calls performed */ size_t stat_calls; /**< Number of stat() calls performed */
size_t oid_calculations; /*< Number of ID calculations */ size_t oid_calculations; /**< Number of ID calculations */
} git_diff_perfdata; } git_diff_perfdata;
#define GIT_DIFF_PERFDATA_VERSION 1 #define GIT_DIFF_PERFDATA_VERSION 1
......
...@@ -93,7 +93,7 @@ struct git_odb_backend { ...@@ -93,7 +93,7 @@ struct git_odb_backend {
* Initializes a `git_odb_backend` with default values. Equivalent to * Initializes a `git_odb_backend` with default values. Equivalent to
* creating an instance with GIT_ODB_BACKEND_INIT. * creating an instance with GIT_ODB_BACKEND_INIT.
* *
* @param opts the `git_odb_backend` struct to initialize. * @param backend the `git_odb_backend` struct to initialize.
* @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION` * @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION`
* @return Zero on success; -1 on failure. * @return Zero on success; -1 on failure.
*/ */
......
...@@ -175,7 +175,7 @@ struct git_refdb_backend { ...@@ -175,7 +175,7 @@ struct git_refdb_backend {
* Initializes a `git_refdb_backend` with default values. Equivalent to * Initializes a `git_refdb_backend` with default values. Equivalent to
* creating an instance with GIT_REFDB_BACKEND_INIT. * creating an instance with GIT_REFDB_BACKEND_INIT.
* *
* @param opts the `git_refdb_backend` struct to initialize * @param backend the `git_refdb_backend` struct to initialize
* @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION` * @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
* @return Zero on success; -1 on failure. * @return Zero on success; -1 on failure.
*/ */
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "vector.h" #include "vector.h"
#include "repository.h" #include "repository.h"
GIT__USE_OIDMAP; GIT__USE_OIDMAP
/* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */ /* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */
......
...@@ -101,7 +101,7 @@ void git_filebuf_cleanup(git_filebuf *file) ...@@ -101,7 +101,7 @@ void git_filebuf_cleanup(git_filebuf *file)
if (file->fd_is_open && file->fd >= 0) if (file->fd_is_open && file->fd >= 0)
p_close(file->fd); p_close(file->fd);
if (file->fd_is_open && file->path_lock && git_path_exists(file->path_lock)) if (file->created_lock && !file->did_rename && file->path_lock && git_path_exists(file->path_lock))
p_unlink(file->path_lock); p_unlink(file->path_lock);
if (file->compute_digest) { if (file->compute_digest) {
...@@ -258,6 +258,7 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode ...@@ -258,6 +258,7 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode
goto cleanup; goto cleanup;
} }
file->fd_is_open = true; file->fd_is_open = true;
file->created_lock = true;
/* No original path */ /* No original path */
file->path_original = NULL; file->path_original = NULL;
...@@ -281,6 +282,8 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode ...@@ -281,6 +282,8 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode
/* open the file for locking */ /* open the file for locking */
if ((error = lock_file(file, flags, mode)) < 0) if ((error = lock_file(file, flags, mode)) < 0)
goto cleanup; goto cleanup;
file->created_lock = true;
} }
return 0; return 0;
...@@ -340,6 +343,8 @@ int git_filebuf_commit(git_filebuf *file) ...@@ -340,6 +343,8 @@ int git_filebuf_commit(git_filebuf *file)
goto on_error; goto on_error;
} }
file->did_rename = true;
git_filebuf_cleanup(file); git_filebuf_cleanup(file);
return 0; return 0;
......
...@@ -44,6 +44,8 @@ struct git_filebuf { ...@@ -44,6 +44,8 @@ struct git_filebuf {
size_t buf_size, buf_pos; size_t buf_size, buf_pos;
git_file fd; git_file fd;
bool fd_is_open; bool fd_is_open;
bool created_lock;
bool did_rename;
bool do_not_buffer; bool do_not_buffer;
int last_error; int last_error;
}; };
......
...@@ -1228,6 +1228,45 @@ int git_index_add_frombuffer( ...@@ -1228,6 +1228,45 @@ int git_index_add_frombuffer(
return 0; return 0;
} }
static int add_repo_as_submodule(git_index_entry **out, git_index *index, const char *path)
{
git_repository *sub;
git_buf abspath = GIT_BUF_INIT;
git_repository *repo = INDEX_OWNER(index);
git_reference *head;
git_index_entry *entry;
struct stat st;
int error;
if (index_entry_create(&entry, INDEX_OWNER(index), path) < 0)
return -1;
if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0)
return error;
if ((error = p_stat(abspath.ptr, &st)) < 0) {
giterr_set(GITERR_OS, "failed to stat repository dir");
return -1;
}
git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
if ((error = git_repository_open(&sub, abspath.ptr)) < 0)
return error;
if ((error = git_repository_head(&head, sub)) < 0)
return error;
git_oid_cpy(&entry->id, git_reference_target(head));
entry->mode = GIT_FILEMODE_COMMIT;
git_reference_free(head);
git_repository_free(sub);
git_buf_free(&abspath);
*out = entry;
return 0;
}
int git_index_add_bypath(git_index *index, const char *path) int git_index_add_bypath(git_index *index, const char *path)
{ {
...@@ -1252,12 +1291,26 @@ int git_index_add_bypath(git_index *index, const char *path) ...@@ -1252,12 +1291,26 @@ int git_index_add_bypath(git_index *index, const char *path)
ret = git_submodule_lookup(&sm, INDEX_OWNER(index), path); ret = git_submodule_lookup(&sm, INDEX_OWNER(index), path);
if (ret == GIT_ENOTFOUND) if (ret == GIT_ENOTFOUND)
return giterr_restore(&err); return giterr_restore(&err);
else
git__free(err.error_msg.message);
ret = git_submodule_add_to_index(sm, false); git__free(err.error_msg.message);
git_submodule_free(sm);
return ret; /*
* EEXISTS means that there is a repository at that path, but it's not known
* as a submodule. We add its HEAD as an entry and don't register it.
*/
if (ret == GIT_EEXISTS) {
if ((ret = add_repo_as_submodule(&entry, index, path)) < 0)
return ret;
if ((ret = index_insert(index, &entry, 1, false)) < 0)
return ret;
} else if (ret < 0) {
return ret;
} else {
ret = git_submodule_add_to_index(sm, false);
git_submodule_free(sm);
return ret;
}
} }
/* Adding implies conflict was resolved, move conflict entries to REUC */ /* Adding implies conflict was resolved, move conflict entries to REUC */
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "oidmap.h" #include "oidmap.h"
#include "zstream.h" #include "zstream.h"
GIT__USE_OIDMAP; GIT__USE_OIDMAP
extern git_mutex git__mwindow_mutex; extern git_mutex git__mwindow_mutex;
......
...@@ -1027,8 +1027,11 @@ static int dirload_with_stat( ...@@ -1027,8 +1027,11 @@ static int dirload_with_stat(
strncomp = (flags & GIT_PATH_DIR_IGNORE_CASE) != 0 ? strncomp = (flags & GIT_PATH_DIR_IGNORE_CASE) != 0 ?
git__strncasecmp : git__strncmp; git__strncasecmp : git__strncmp;
if ((error = git_path_diriter_init(&diriter, dirpath, flags)) < 0) /* Any error here is equivalent to the dir not existing, skip over it */
if ((error = git_path_diriter_init(&diriter, dirpath, flags)) < 0) {
error = GIT_ENOTFOUND;
goto done; goto done;
}
while ((error = git_path_diriter_next(&diriter)) == 0) { while ((error = git_path_diriter_next(&diriter)) == 0) {
if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0) if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0)
......
...@@ -41,7 +41,7 @@ struct pack_write_context { ...@@ -41,7 +41,7 @@ struct pack_write_context {
git_transfer_progress *stats; git_transfer_progress *stats;
}; };
GIT__USE_OIDMAP; GIT__USE_OIDMAP
#ifdef GIT_THREADS #ifdef GIT_THREADS
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
#include <zlib.h> #include <zlib.h>
GIT__USE_OFFMAP; GIT__USE_OFFMAP
GIT__USE_OIDMAP; GIT__USE_OIDMAP
static int packfile_open(struct git_pack_file *p); static int packfile_open(struct git_pack_file *p);
static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n); static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n);
......
...@@ -319,7 +319,7 @@ extern int git_path_cmp( ...@@ -319,7 +319,7 @@ extern int git_path_cmp(
* @param callback Function to invoke on each path. Passed the `payload` * @param callback Function to invoke on each path. Passed the `payload`
* and the buffer containing the current path. The path should not * and the buffer containing the current path. The path should not
* be modified in any way. Return non-zero to stop iteration. * be modified in any way. Return non-zero to stop iteration.
* @param state Passed to fn as the first ath. * @param payload Passed to fn as the first ath.
*/ */
extern int git_path_walk_up( extern int git_path_walk_up(
git_buf *pathbuf, git_buf *pathbuf,
......
...@@ -83,7 +83,7 @@ int git_push_add_refspec(git_push *push, const char *refspec); ...@@ -83,7 +83,7 @@ int git_push_add_refspec(git_push *push, const char *refspec);
* Update remote tips after a push * Update remote tips after a push
* *
* @param push The push object * @param push The push object
* @param signature The identity to use when updating reflogs * @param callbacks the callbacks to use for this connection
* *
* @return 0 or an error code * @return 0 or an error code
*/ */
...@@ -100,6 +100,7 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks); ...@@ -100,6 +100,7 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks);
* order to find out which updates were accepted or rejected. * order to find out which updates were accepted or rejected.
* *
* @param push The push object * @param push The push object
* @param callbacks the callbacks to use for this connection
* *
* @return 0 or an error code * @return 0 or an error code
*/ */
...@@ -117,6 +118,7 @@ int git_push_finish(git_push *push, const git_remote_callbacks *callbacks); ...@@ -117,6 +118,7 @@ int git_push_finish(git_push *push, const git_remote_callbacks *callbacks);
* *
* @param push The push object * @param push The push object
* @param cb The callback to call on each object * @param cb The callback to call on each object
* @param data The payload passed to the callback
* *
* @return 0 on success, non-zero callback return value, or error code * @return 0 on success, non-zero callback return value, or error code
*/ */
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "git2/revparse.h" #include "git2/revparse.h"
#include "merge.h" #include "merge.h"
GIT__USE_OIDMAP; GIT__USE_OIDMAP
git_commit_list_node *git_revwalk__commit_lookup( git_commit_list_node *git_revwalk__commit_lookup(
git_revwalk *walk, const git_oid *oid) git_revwalk *walk, const git_oid *oid)
......
...@@ -50,6 +50,8 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) ...@@ -50,6 +50,8 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
} }
repo = delim; repo = delim;
if (repo[1] == '~')
++repo;
delim = strchr(url, ':'); delim = strchr(url, ':');
if (delim == NULL) if (delim == NULL)
......
...@@ -255,7 +255,7 @@ static int on_header_ready(http_subtransport *t) ...@@ -255,7 +255,7 @@ static int on_header_ready(http_subtransport *t)
GITERR_CHECK_ALLOC(t->content_type); GITERR_CHECK_ALLOC(t->content_type);
} }
} }
else if (!strcmp("WWW-Authenticate", git_buf_cstr(name))) { else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) {
char *dup = git__strdup(git_buf_cstr(value)); char *dup = git__strdup(git_buf_cstr(value));
GITERR_CHECK_ALLOC(dup); GITERR_CHECK_ALLOC(dup);
......
...@@ -66,6 +66,8 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) ...@@ -66,6 +66,8 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
if (!git__prefixcmp(url, prefix_ssh)) { if (!git__prefixcmp(url, prefix_ssh)) {
url = url + strlen(prefix_ssh); url = url + strlen(prefix_ssh);
repo = strchr(url, '/'); repo = strchr(url, '/');
if (repo && repo[1] == '~')
++repo;
} else { } else {
repo = strchr(url, ':'); repo = strchr(url, ':');
if (repo) repo++; if (repo) repo++;
......
...@@ -124,3 +124,30 @@ void test_core_filebuf__umask(void) ...@@ -124,3 +124,30 @@ void test_core_filebuf__umask(void)
cl_must_pass(p_unlink(test)); cl_must_pass(p_unlink(test));
} }
void test_core_filebuf__rename_error(void)
{
git_filebuf file = GIT_FILEBUF_INIT;
char *dir = "subdir", *test = "subdir/test", *test_lock = "subdir/test.lock";
int fd;
#ifndef GIT_WIN32
cl_skip();
#endif
cl_git_pass(p_mkdir(dir, 0666));
cl_git_mkfile(test, "dummy content");
fd = p_open(test, O_RDONLY);
cl_assert(fd > 0);
cl_git_pass(git_filebuf_open(&file, test, 0, 0666));
cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks"));
cl_assert_equal_i(true, git_path_exists(test_lock));
cl_git_fail(git_filebuf_commit(&file));
p_close(fd);
git_filebuf_cleanup(&file);
cl_assert_equal_i(false, git_path_exists(test_lock));
}
...@@ -33,3 +33,16 @@ void test_index_bypath__add_submodule(void) ...@@ -33,3 +33,16 @@ void test_index_bypath__add_submodule(void)
cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0)); cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
cl_assert_equal_i(0, status & GIT_SUBMODULE_STATUS_WD_MODIFIED); cl_assert_equal_i(0, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
} }
void test_index_bypath__add_submodule_unregistered(void)
{
const char *sm_name = "not-submodule";
const char *sm_head = "68e92c611b80ee1ed8f38314ff9577f0d15b2444";
const git_index_entry *entry;
cl_git_pass(git_index_add_bypath(g_idx, sm_name));
cl_assert(entry = git_index_get_bypath(g_idx, sm_name, 0));
cl_assert_equal_s(sm_head, git_oid_tostr_s(&entry->id));
cl_assert_equal_s(sm_name, entry->path);
}
...@@ -928,7 +928,7 @@ void test_repo_iterator__fs2(void) ...@@ -928,7 +928,7 @@ void test_repo_iterator__fs2(void)
git_iterator_free(i); git_iterator_free(i);
} }
void test_repo_iterator__fs_preserves_error(void) void test_repo_iterator__unreadable_dir(void)
{ {
git_iterator *i; git_iterator *i;
const git_index_entry *e; const git_index_entry *e;
...@@ -951,10 +951,6 @@ void test_repo_iterator__fs_preserves_error(void) ...@@ -951,10 +951,6 @@ void test_repo_iterator__fs_preserves_error(void)
cl_git_pass(git_iterator_advance(&e, i)); /* a */ cl_git_pass(git_iterator_advance(&e, i)); /* a */
cl_git_fail(git_iterator_advance(&e, i)); /* b */ cl_git_fail(git_iterator_advance(&e, i)); /* b */
cl_assert(giterr_last());
cl_assert(giterr_last()->message != NULL);
/* skip 'c/' empty directory */
cl_git_pass(git_iterator_advance(&e, i)); /* d */
cl_assert_equal_i(GIT_ITEROVER, git_iterator_advance(&e, i)); cl_assert_equal_i(GIT_ITEROVER, git_iterator_advance(&e, i));
cl_must_pass(p_chmod("empty_standard_repo/r/b", 0777)); cl_must_pass(p_chmod("empty_standard_repo/r/b", 0777));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment