Commit 928b4cad by Carlos Martín Nieto

Merge pull request #3005 from libgit2/cmn/maint-update

Backports for the maint branch
parents 79010d09 1f726d05
...@@ -42,7 +42,6 @@ OPTION( VALGRIND "Configure build for valgrind" OFF ) ...@@ -42,7 +42,6 @@ OPTION( VALGRIND "Configure build for valgrind" OFF )
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
SET( USE_ICONV ON ) SET( USE_ICONV ON )
ADD_DEFINITIONS(-DGIT_COMMON_CRYPTO)
ENDIF() ENDIF()
IF(MSVC) IF(MSVC)
...@@ -172,6 +171,8 @@ ENDIF() ...@@ -172,6 +171,8 @@ ENDIF()
IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin") IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin")
ADD_DEFINITIONS(-DWIN32_SHA1) ADD_DEFINITIONS(-DWIN32_SHA1)
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c) FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
ADD_DEFINITIONS(-DGIT_COMMON_CRYPTO)
ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin") ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin")
ADD_DEFINITIONS(-DOPENSSL_SHA1) ADD_DEFINITIONS(-DOPENSSL_SHA1)
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
...@@ -217,7 +218,8 @@ IF (USE_SSH) ...@@ -217,7 +218,8 @@ IF (USE_SSH)
ENDIF() ENDIF()
IF (LIBSSH2_FOUND) IF (LIBSSH2_FOUND)
ADD_DEFINITIONS(-DGIT_SSH) ADD_DEFINITIONS(-DGIT_SSH)
INCLUDE_DIRECTORIES(${LIBSSH2_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${LIBSSH2_INCLUDE_DIRS})
LINK_DIRECTORIES(${LIBSSH2_LIBRARY_DIRS})
SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} libssh2") SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} libssh2")
SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES}) SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES})
ENDIF() ENDIF()
......
...@@ -342,8 +342,8 @@ GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo); ...@@ -342,8 +342,8 @@ GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo);
/** /**
* Check if a repository is empty * Check if a repository is empty
* *
* An empty repository has just been initialized and contains * An empty repository has just been initialized and contains no references
* no references. * apart from HEAD, which must be pointing to the unborn master branch.
* *
* @param repo Repo to test * @param repo Repo to test
* @return 1 if the repository is empty, 0 if it isn't, error code * @return 1 if the repository is empty, 0 if it isn't, error code
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
#ifndef INCLUDE_sys_git_repository_h__ #ifndef INCLUDE_sys_git_repository_h__
#define INCLUDE_sys_git_repository_h__ #define INCLUDE_sys_git_repository_h__
#include "git2/common.h"
#include "git2/types.h"
/** /**
* @file git2/sys/repository.h * @file git2/sys/repository.h
* @brief Git repository custom implementation routines * @brief Git repository custom implementation routines
...@@ -53,7 +56,7 @@ GIT_EXTERN(void) git_repository__cleanup(git_repository *repo); ...@@ -53,7 +56,7 @@ GIT_EXTERN(void) git_repository__cleanup(git_repository *repo);
* *
* @param repo A repository object * @param repo A repository object
* @param recurse_submodules Should submodules be updated recursively * @param recurse_submodules Should submodules be updated recursively
* @returrn 0 on success, < 0 on error * @return 0 on success, < 0 on error
*/ */
GIT_EXTERN(int) git_repository_reinit_filesystem( GIT_EXTERN(int) git_repository_reinit_filesystem(
git_repository *repo, git_repository *repo,
......
...@@ -138,8 +138,13 @@ int git_branch_delete(git_reference *branch) ...@@ -138,8 +138,13 @@ int git_branch_delete(git_reference *branch)
if (git_reference_delete(branch) < 0) if (git_reference_delete(branch) < 0)
goto on_error; goto on_error;
if (git_reflog_delete(git_reference_owner(branch), git_reference_name(branch)) < 0) if ((error = git_reflog_delete(git_reference_owner(branch), git_reference_name(branch))) < 0) {
if (error == GIT_ENOTFOUND) {
giterr_clear();
error = 0;
}
goto on_error; goto on_error;
}
error = 0; error = 0;
......
...@@ -191,7 +191,10 @@ bool git_buf_text_is_binary(const git_buf *buf) ...@@ -191,7 +191,10 @@ bool git_buf_text_is_binary(const git_buf *buf)
while (scan < end) { while (scan < end) {
unsigned char c = *scan++; unsigned char c = *scan++;
if (c > 0x1F && c < 0x7F) /* Printable characters are those above SPACE (0x1F) excluding DEL,
* and including BS, ESC and FF.
*/
if ((c > 0x1F && c != 127) || c == '\b' || c == '\033' || c == '\014')
printable++; printable++;
else if (c == '\0') else if (c == '\0')
return true; return true;
......
...@@ -2212,6 +2212,7 @@ static void checkout_data_clear(checkout_data *data) ...@@ -2212,6 +2212,7 @@ static void checkout_data_clear(checkout_data *data)
git__free(data->pfx); git__free(data->pfx);
data->pfx = NULL; data->pfx = NULL;
git_buf_free(&data->last_mkdir);
git_buf_free(&data->path); git_buf_free(&data->path);
git_buf_free(&data->tmp); git_buf_free(&data->tmp);
......
...@@ -1284,6 +1284,7 @@ static int config_parse(git_strmap *values, diskfile_backend *cfg_file, struct r ...@@ -1284,6 +1284,7 @@ static int config_parse(git_strmap *values, diskfile_backend *cfg_file, struct r
if (result == 0) { if (result == 0) {
result = config_parse(values, cfg_file, r, level, depth+1); result = config_parse(values, cfg_file, r, level, depth+1);
r = git_array_get(cfg_file->readers, index); r = git_array_get(cfg_file->readers, index);
reader = git_array_get(cfg_file->readers, reader_idx);
} }
else if (result == GIT_ENOTFOUND) { else if (result == GIT_ENOTFOUND) {
giterr_clear(); giterr_clear();
......
...@@ -822,7 +822,8 @@ int git_patch__invoke_callbacks( ...@@ -822,7 +822,8 @@ int git_patch__invoke_callbacks(
for (i = 0; !error && i < git_array_size(patch->hunks); ++i) { for (i = 0; !error && i < git_array_size(patch->hunks); ++i) {
diff_patch_hunk *h = git_array_get(patch->hunks, i); diff_patch_hunk *h = git_array_get(patch->hunks, i);
error = hunk_cb(patch->delta, &h->hunk, payload); if (hunk_cb)
error = hunk_cb(patch->delta, &h->hunk, payload);
if (!line_cb) if (!line_cb)
continue; continue;
......
...@@ -330,7 +330,7 @@ int git_futils_mkdir_withperf( ...@@ -330,7 +330,7 @@ int git_futils_mkdir_withperf(
{ {
int error = -1; int error = -1;
git_buf make_path = GIT_BUF_INIT; git_buf make_path = GIT_BUF_INIT;
ssize_t root = 0, min_root_len; ssize_t root = 0, min_root_len, root_len;
char lastch = '/', *tail; char lastch = '/', *tail;
struct stat st; struct stat st;
...@@ -343,22 +343,29 @@ int git_futils_mkdir_withperf( ...@@ -343,22 +343,29 @@ int git_futils_mkdir_withperf(
goto done; goto done;
} }
/* remove trailing slashes on path */ /* Trim trailing slashes (except the root) */
while (make_path.ptr[make_path.size - 1] == '/') { if ((root_len = git_path_root(make_path.ptr)) < 0)
make_path.size--; root_len = 0;
make_path.ptr[make_path.size] = '\0'; else
} root_len++;
while (make_path.size > (size_t)root_len &&
make_path.ptr[make_path.size - 1] == '/')
make_path.ptr[--make_path.size] = '\0';
/* if we are not supposed to made the last element, truncate it */ /* if we are not supposed to made the last element, truncate it */
if ((flags & GIT_MKDIR_SKIP_LAST2) != 0) { if ((flags & GIT_MKDIR_SKIP_LAST2) != 0) {
git_buf_rtruncate_at_char(&make_path, '/'); git_path_dirname_r(&make_path, make_path.ptr);
flags |= GIT_MKDIR_SKIP_LAST; flags |= GIT_MKDIR_SKIP_LAST;
} }
if ((flags & GIT_MKDIR_SKIP_LAST) != 0) if ((flags & GIT_MKDIR_SKIP_LAST) != 0) {
git_buf_rtruncate_at_char(&make_path, '/'); git_path_dirname_r(&make_path, make_path.ptr);
}
/* if nothing left after truncation, then we're done! */ /* We were either given the root path (or trimmed it to
if (!make_path.size) { * the root), we don't have anything to do.
*/
if (make_path.size <= (size_t)root_len) {
error = 0; error = 0;
goto done; goto done;
} }
......
...@@ -292,6 +292,9 @@ static void index_entry_reuc_free(git_index_reuc_entry *reuc) ...@@ -292,6 +292,9 @@ static void index_entry_reuc_free(git_index_reuc_entry *reuc)
static void index_entry_free(git_index_entry *entry) static void index_entry_free(git_index_entry *entry)
{ {
if (!entry)
return;
memset(&entry->id, 0, sizeof(entry->id)); memset(&entry->id, 0, sizeof(entry->id));
git__free(entry); git__free(entry);
} }
......
...@@ -289,6 +289,7 @@ static int store_object(git_indexer *idx) ...@@ -289,6 +289,7 @@ static int store_object(git_indexer *idx)
k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error); k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
if (!error) { if (!error) {
git__free(pentry); git__free(pentry);
giterr_set(GITERR_INDEXER, "cannot handle duplicate objects in pack");
goto on_error; goto on_error;
} }
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#ifdef GIT_SSL #ifdef GIT_SSL
#include <ctype.h> #include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "global.h" #include "global.h"
#include "posix.h" #include "posix.h"
......
...@@ -56,6 +56,7 @@ static git_pack_cache_entry *new_cache_object(git_rawobj *source) ...@@ -56,6 +56,7 @@ static git_pack_cache_entry *new_cache_object(git_rawobj *source)
if (!e) if (!e)
return NULL; return NULL;
git_atomic_inc(&e->refcount);
memcpy(&e->raw, source, sizeof(git_rawobj)); memcpy(&e->raw, source, sizeof(git_rawobj));
return e; return e;
...@@ -145,7 +146,11 @@ static void free_lowest_entry(git_pack_cache *cache) ...@@ -145,7 +146,11 @@ static void free_lowest_entry(git_pack_cache *cache)
} }
} }
static int cache_add(git_pack_cache *cache, git_rawobj *base, git_off_t offset) static int cache_add(
git_pack_cache_entry **cached_out,
git_pack_cache *cache,
git_rawobj *base,
git_off_t offset)
{ {
git_pack_cache_entry *entry; git_pack_cache_entry *entry;
int error, exists = 0; int error, exists = 0;
...@@ -171,6 +176,8 @@ static int cache_add(git_pack_cache *cache, git_rawobj *base, git_off_t offset) ...@@ -171,6 +176,8 @@ static int cache_add(git_pack_cache *cache, git_rawobj *base, git_off_t offset)
assert(error != 0); assert(error != 0);
kh_value(cache->entries, k) = entry; kh_value(cache->entries, k) = entry;
cache->memory_used += entry->raw.len; cache->memory_used += entry->raw.len;
*cached_out = entry;
} }
git_mutex_unlock(&cache->lock); git_mutex_unlock(&cache->lock);
/* Somebody beat us to adding it into the cache */ /* Somebody beat us to adding it into the cache */
...@@ -699,7 +706,7 @@ int git_packfile_unpack( ...@@ -699,7 +706,7 @@ int git_packfile_unpack(
* long as it's not already the cached one. * long as it's not already the cached one.
*/ */
if (!cached) if (!cached)
free_base = !!cache_add(&p->bases, obj, elem->base_key); free_base = !!cache_add(&cached, &p->bases, obj, elem->base_key);
elem = &stack[elem_pos - 1]; elem = &stack[elem_pos - 1];
curpos = elem->offset; curpos = elem->offset;
......
...@@ -634,7 +634,7 @@ int git_rebase_init( ...@@ -634,7 +634,7 @@ int git_rebase_init(
*out = NULL; *out = NULL;
GITERR_CHECK_VERSION(given_opts, GIT_MERGE_OPTIONS_VERSION, "git_merge_options"); GITERR_CHECK_VERSION(given_opts, GIT_REBASE_OPTIONS_VERSION, "git_rebase_options");
if (!onto) if (!onto)
onto = upstream; onto = upstream;
...@@ -1058,6 +1058,8 @@ int git_rebase_finish( ...@@ -1058,6 +1058,8 @@ int git_rebase_finish(
assert(rebase); assert(rebase);
GITERR_CHECK_VERSION(given_opts, GIT_REBASE_OPTIONS_VERSION, "git_rebase_options");
if ((error = rebase_normalize_opts(rebase->repo, &opts, given_opts)) < 0) if ((error = rebase_normalize_opts(rebase->repo, &opts, given_opts)) < 0)
goto done; goto done;
......
...@@ -1771,6 +1771,15 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co ...@@ -1771,6 +1771,15 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co
goto cleanup; goto cleanup;
} }
/* If the new branch matches part of the namespace of a previously deleted branch,
* there maybe an obsolete/unused directory (or directory hierarchy) in the way.
*/
if (git_path_isdir(git_buf_cstr(&path)) &&
(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) {
error = -1;
goto cleanup;
}
error = git_futils_writebuffer(&buf, git_buf_cstr(&path), O_WRONLY|O_CREAT|O_APPEND, GIT_REFLOG_FILE_MODE); error = git_futils_writebuffer(&buf, git_buf_cstr(&path), O_WRONLY|O_CREAT|O_APPEND, GIT_REFLOG_FILE_MODE);
cleanup: cleanup:
......
...@@ -1459,7 +1459,7 @@ int git_remote_update_tips( ...@@ -1459,7 +1459,7 @@ int git_remote_update_tips(
const char *reflog_message) const char *reflog_message)
{ {
git_refspec *spec, tagspec; git_refspec *spec, tagspec;
git_vector refs; git_vector refs = GIT_VECTOR_INIT;
int error; int error;
size_t i; size_t i;
...@@ -2330,6 +2330,10 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi ...@@ -2330,6 +2330,10 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
(error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0) (error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0)
goto cleanup; goto cleanup;
free_refspecs(&remote->active_refspecs);
if (dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs) < 0)
goto cleanup;
if (remote->push) { if (remote->push) {
git_push_free(remote->push); git_push_free(remote->push);
remote->push = NULL; remote->push = NULL;
......
...@@ -1724,7 +1724,7 @@ int git_repository_set_bare(git_repository *repo) ...@@ -1724,7 +1724,7 @@ int git_repository_set_bare(git_repository *repo)
if ((error = git_repository_config__weakptr(&config, repo)) < 0) if ((error = git_repository_config__weakptr(&config, repo)) < 0)
return error; return error;
if ((error = git_config_set_bool(config, "core.bare", false)) < 0) if ((error = git_config_set_bool(config, "core.bare", true)) < 0)
return error; return error;
if ((error = git_config__update_entry(config, "core.worktree", NULL, true, true)) < 0) if ((error = git_config__update_entry(config, "core.worktree", NULL, true, true)) < 0)
......
...@@ -15,6 +15,11 @@ GIT_INLINE(int) git_stream_connect(git_stream *st) ...@@ -15,6 +15,11 @@ GIT_INLINE(int) git_stream_connect(git_stream *st)
return st->connect(st); return st->connect(st);
} }
GIT_INLINE(int) git_stream_is_encrypted(git_stream *st)
{
return st->encrypted;
}
GIT_INLINE(int) git_stream_certificate(git_cert **out, git_stream *st) GIT_INLINE(int) git_stream_certificate(git_cert **out, git_stream *st)
{ {
if (!st->encrypted) { if (!st->encrypted) {
......
...@@ -136,6 +136,7 @@ static void git_proto_stream_free(git_smart_subtransport_stream *stream) ...@@ -136,6 +136,7 @@ static void git_proto_stream_free(git_smart_subtransport_stream *stream)
t->current_stream = NULL; t->current_stream = NULL;
git_stream_close(s->io);
git_stream_free(s->io); git_stream_free(s->io);
git__free(s->url); git__free(s->url);
git__free(s); git__free(s);
......
...@@ -350,6 +350,11 @@ static int on_headers_complete(http_parser *parser) ...@@ -350,6 +350,11 @@ static int on_headers_complete(http_parser *parser)
} else { } else {
assert(t->cred); assert(t->cred);
if (!(t->cred->credtype & allowed_auth_types)) {
giterr_set(GITERR_NET, "credentials callback returned an invalid cred type");
return t->parse_error = PARSE_ERROR_GENERIC;
}
/* Successfully acquired a credential. */ /* Successfully acquired a credential. */
t->parse_error = PARSE_ERROR_REPLAY; t->parse_error = PARSE_ERROR_REPLAY;
return 0; return 0;
...@@ -553,7 +558,8 @@ static int http_connect(http_subtransport *t) ...@@ -553,7 +558,8 @@ static int http_connect(http_subtransport *t)
error = git_stream_connect(t->io); error = git_stream_connect(t->io);
#ifdef GIT_SSL #ifdef GIT_SSL
if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL) { if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL &&
git_stream_is_encrypted(t->io)) {
git_cert *cert; git_cert *cert;
int is_valid; int is_valid;
......
...@@ -448,12 +448,8 @@ int p_stat(const char* path, struct stat* buf) ...@@ -448,12 +448,8 @@ int p_stat(const char* path, struct stat* buf)
git_win32_path path_w; git_win32_path path_w;
int len; int len;
if ((len = git_win32_path_from_utf8(path_w, path)) < 0) if ((len = git_win32_path_from_utf8(path_w, path)) < 0 ||
return -1; lstat_w(path_w, buf, false) < 0)
git_win32__path_trim_end(path_w, len);
if (lstat_w(path_w, buf, false) < 0)
return -1; return -1;
/* The item is a symbolic link or mount point. No need to iterate /* The item is a symbolic link or mount point. No need to iterate
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "path.h" #include "path.h"
#ifdef GIT_WIN32 #ifdef GIT_WIN32
# include <Windows.h> # include <windows.h>
#endif #endif
static git_repository *repo; static git_repository *repo;
......
...@@ -830,7 +830,7 @@ void test_core_buffer__classify_with_utf8(void) ...@@ -830,7 +830,7 @@ void test_core_buffer__classify_with_utf8(void)
cl_assert(!git_buf_text_contains_nul(&b)); cl_assert(!git_buf_text_contains_nul(&b));
b.ptr = data1; b.size = b.asize = data1len; b.ptr = data1; b.size = b.asize = data1len;
cl_assert(git_buf_text_is_binary(&b)); cl_assert(!git_buf_text_is_binary(&b));
cl_assert(!git_buf_text_contains_nul(&b)); cl_assert(!git_buf_text_contains_nul(&b));
b.ptr = data2; b.size = b.asize = data2len; b.ptr = data2; b.size = b.asize = data2len;
......
...@@ -95,3 +95,20 @@ void test_core_stat__0(void) ...@@ -95,3 +95,20 @@ void test_core_stat__0(void)
cl_assert_error(ENOTDIR); cl_assert_error(ENOTDIR);
} }
void test_core_stat__root(void)
{
const char *sandbox = clar_sandbox_path();
git_buf root = GIT_BUF_INIT;
int root_len;
struct stat st;
root_len = git_path_root(sandbox);
cl_assert(root_len >= 0);
git_buf_set(&root, sandbox, root_len+1);
cl_must_pass(p_stat(root.ptr, &st));
cl_assert(S_ISDIR(st.st_mode));
git_buf_free(&root);
}
...@@ -58,17 +58,17 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n) ...@@ -58,17 +58,17 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
void test_online_fetch__default_git(void) void test_online_fetch__default_git(void)
{ {
do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 5); do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
} }
void test_online_fetch__default_http(void) void test_online_fetch__default_http(void)
{ {
do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 5); do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
} }
void test_online_fetch__default_https(void) void test_online_fetch__default_https(void)
{ {
do_fetch("https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 5); do_fetch("https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6);
} }
void test_online_fetch__no_tags_git(void) void test_online_fetch__no_tags_git(void)
......
...@@ -196,3 +196,107 @@ void test_refs_branches_create__can_create_branch_with_unicode(void) ...@@ -196,3 +196,107 @@ void test_refs_branches_create__can_create_branch_with_unicode(void)
branch = NULL; branch = NULL;
} }
} }
/**
* Verify that we can create a branch with a name that matches the
* namespace of a previously delete branch.
*
* git branch level_one/level_two
* git branch -D level_one/level_two
* git branch level_one
*
* We expect the delete to have deleted the files:
* ".git/refs/heads/level_one/level_two"
* ".git/logs/refs/heads/level_one/level_two"
* It may or may not have deleted the (now empty)
* containing directories. To match git.git behavior,
* the second create needs to implicilty delete the
* directories and create the new files.
* "refs/heads/level_one"
* "logs/refs/heads/level_one"
*
* We should not fail to create the branch or its
* reflog because of an obsolete namespace container
* directory.
*/
void test_refs_branches_create__name_vs_namespace(void)
{
const char * name;
struct item {
const char *first;
const char *second;
};
static const struct item item[] = {
{ "level_one/level_two", "level_one" },
{ "a/b/c/d/e", "a/b/c/d" },
{ "ss/tt/uu/vv/ww", "ss" },
/* And one test case that is deeper. */
{ "xx1/xx2/xx3/xx4", "xx1/xx2/xx3/xx4/xx5/xx6" },
{ NULL, NULL },
};
const struct item *p;
retrieve_known_commit(&target, repo);
for (p=item; p->first; p++) {
cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0, NULL, NULL));
cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
cl_git_pass(git_branch_name(&name, branch));
cl_assert_equal_s(name, p->first);
cl_git_pass(git_branch_delete(branch));
git_reference_free(branch);
branch = NULL;
cl_git_pass(git_branch_create(&branch, repo, p->second, target, 0, NULL, NULL));
git_reference_free(branch);
branch = NULL;
}
}
/**
* We still need to fail if part of the namespace is
* still in use.
*/
void test_refs_branches_create__name_vs_namespace_fail(void)
{
const char * name;
struct item {
const char *first;
const char *first_alternate;
const char *second;
};
static const struct item item[] = {
{ "level_one/level_two", "level_one/alternate", "level_one" },
{ "a/b/c/d/e", "a/b/c/d/alternate", "a/b/c/d" },
{ "ss/tt/uu/vv/ww", "ss/alternate", "ss" },
{ NULL, NULL, NULL },
};
const struct item *p;
retrieve_known_commit(&target, repo);
for (p=item; p->first; p++) {
cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0, NULL, NULL));
cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
cl_git_pass(git_branch_name(&name, branch));
cl_assert_equal_s(name, p->first);
cl_git_pass(git_branch_delete(branch));
git_reference_free(branch);
branch = NULL;
cl_git_pass(git_branch_create(&branch, repo, p->first_alternate, target, 0, NULL, NULL));
cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target)));
cl_git_pass(git_branch_name(&name, branch));
cl_assert_equal_s(name, p->first_alternate);
/* we do not delete the alternate. */
git_reference_free(branch);
branch = NULL;
cl_git_fail(git_branch_create(&branch, repo, p->second, target, 0, NULL, NULL));
git_reference_free(branch);
branch = NULL;
}
}
...@@ -714,3 +714,29 @@ void test_repo_init__init_with_initial_commit(void) ...@@ -714,3 +714,29 @@ void test_repo_init__init_with_initial_commit(void)
git_index_free(index); git_index_free(index);
} }
void test_repo_init__at_filesystem_root(void)
{
git_repository *repo;
const char *sandbox = clar_sandbox_path();
git_buf root = GIT_BUF_INIT;
int root_len;
if (!cl_getenv("GITTEST_INVASIVE_FILESYSTEM"))
cl_skip();
root_len = git_path_root(sandbox);
cl_assert(root_len >= 0);
git_buf_put(&root, sandbox, root_len+1);
git_buf_joinpath(&root, root.ptr, "libgit2_test_dir");
cl_assert(!git_path_exists(root.ptr));
cl_git_pass(git_repository_init(&repo, root.ptr, 0));
cl_assert(git_path_isdir(root.ptr));
cl_git_pass(git_futils_rmdir_r(root.ptr, NULL, GIT_RMDIR_REMOVE_FILES));
git_buf_free(&root);
git_repository_free(repo);
}
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