Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ after_success:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install valgrind; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline; fi

# Only watch the development branch
# Watch development and stable branches
branches:
only:
- development
- /^maint\/.*$/

# Notify development list when needed
notifications:
Expand Down
24 changes: 21 additions & 3 deletions src/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1736,10 +1736,12 @@ static int checkout_write_merge(
checkout_conflictdata *conflict)
{
git_buf our_label = GIT_BUF_INIT, their_label = GIT_BUF_INIT,
path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT;
path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT,
in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT;
git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
git_merge_file_result result = {0};
git_filebuf output = GIT_FILEBUF_INIT;
git_filter_list *fl = NULL;
int error = 0;

if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3)
Expand Down Expand Up @@ -1785,13 +1787,29 @@ static int checkout_write_merge(
(error = checkout_safe_for_update_only(git_buf_cstr(&path_workdir), result.mode)) <= 0)
goto done;

if (!data->opts.disable_filters) {
in_data.ptr = (char *)result.ptr;
in_data.size = result.len;

if ((error = git_filter_list_load(&fl, data->repo, NULL, git_buf_cstr(&path_workdir),
GIT_FILTER_TO_WORKTREE, GIT_FILTER_OPT_DEFAULT)) < 0 ||
(error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0)
goto done;
} else {
out_data.ptr = (char *)result.ptr;
out_data.size = result.len;
}

if ((error = git_futils_mkpath2file(path_workdir.ptr, 0755)) < 0 ||
(error = git_filebuf_open(&output, path_workdir.ptr, GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
(error = git_filebuf_write(&output, result.ptr, result.len)) < 0 ||
(error = git_filebuf_open(&output, git_buf_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
(error = git_filebuf_write(&output, out_data.ptr, out_data.size)) < 0 ||
(error = git_filebuf_commit(&output)) < 0)
goto done;

done:
git_filter_list_free(fl);

git_buf_free(&out_data);
git_buf_free(&our_label);
git_buf_free(&their_label);

Expand Down
7 changes: 6 additions & 1 deletion src/config_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,12 +767,17 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
{
diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
diskfile_backend *src = b->snapshot_from;
diskfile_header *src_header = &src->header;
refcounted_strmap *src_map;
int error;

if (!src_header->readonly && (error = config_refresh(&src_header->parent)) < 0)
return error;

/* We're just copying data, don't care about the level */
GIT_UNUSED(level);

src_map = refcounted_strmap_take(&src->header);
src_map = refcounted_strmap_take(src_header);
b->header.values = src_map;

return 0;
Expand Down
8 changes: 7 additions & 1 deletion src/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,12 @@ void openssl_locking_function(int mode, int n, const char *file, int line)
git_mutex_unlock(&openssl_locks[n]);
}
}
#endif

static void shutdown_ssl(void)
{
git__free(openssl_locks);
}
#endif

static void init_ssl(void)
{
Expand Down Expand Up @@ -110,6 +114,8 @@ static void init_ssl(void)

CRYPTO_set_locking_callback(openssl_locking_function);
}

git__on_shutdown(shutdown_ssl);
# endif
#endif
}
Expand Down
42 changes: 26 additions & 16 deletions src/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,23 +494,33 @@ bool git_path_is_empty_dir(const char *path)
WIN32_FIND_DATAW findData;
HANDLE hFind = FindFirstFileW(filter_w, &findData);

/* FindFirstFile will fail if there are no children to the given
* path, which can happen if the given path is a file (and obviously
* has no children) or if the given path is an empty mount point.
* (Most directories have at least directory entries '.' and '..',
* but ridiculously another volume mounted in another drive letter's
* path space do not, and thus have nothing to enumerate.) If
* FindFirstFile fails, check if this is a directory-like thing
* (a mount point).
*/
if (hFind == INVALID_HANDLE_VALUE)
return git_path_isdir(path);

/* If the find handle was created successfully, then it's a directory */
if (hFind != INVALID_HANDLE_VALUE) {
empty = true;

do {
/* Allow the enumeration to return . and .. and still be considered
* empty. In the special case of drive roots (i.e. C:\) where . and
* .. do not occur, we can still consider the path to be an empty
* directory if there's nothing there. */
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
empty = false;
break;
}
} while (FindNextFileW(hFind, &findData));

FindClose(hFind);
}
empty = true;

do {
/* Allow the enumeration to return . and .. and still be considered
* empty. In the special case of drive roots (i.e. C:\) where . and
* .. do not occur, we can still consider the path to be an empty
* directory if there's nothing there. */
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
empty = false;
break;
}
} while (FindNextFileW(hFind, &findData));

FindClose(hFind);
}

return empty;
Expand Down
4 changes: 3 additions & 1 deletion src/repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -1551,8 +1551,10 @@ int git_repository_head_unborn(git_repository *repo)
error = git_repository_head(&ref, repo);
git_reference_free(ref);

if (error == GIT_EUNBORNBRANCH)
if (error == GIT_EUNBORNBRANCH) {
giterr_clear();
return 1;
}

if (error < 0)
return -1;
Expand Down
5 changes: 3 additions & 2 deletions src/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,9 @@ int git_tag_delete(git_repository *repo, const char *tag_name)
if (error < 0)
return error;

if ((error = git_reference_delete(tag_ref)) == 0)
git_reference_free(tag_ref);
error = git_reference_delete(tag_ref);

git_reference_free(tag_ref);

return error;
}
Expand Down
13 changes: 12 additions & 1 deletion src/win32/posix_w32.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft)
return (time_t)winTime;
}

static bool path_is_volume(wchar_t *target, size_t target_len)
{
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
}

/* On success, returns the length, in characters, of the path stored in dest.
* On failure, returns a negative value. */
static int readlink_w(
Expand Down Expand Up @@ -156,7 +161,13 @@ static int readlink_w(
goto on_error;
}

if (target_len) {
if (path_is_volume(target, target_len)) {
/* This path is a reparse point that represents another volume mounted
* at this location, it is not a symbolic link our input was canonical.
*/
errno = EINVAL;
error = -1;
} else if (target_len) {
/* The path may need to have a prefix removed. */
target_len = git_win32__canonicalize_path(target, target_len);

Expand Down
69 changes: 69 additions & 0 deletions tests/checkout/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,3 +618,72 @@ void test_checkout_index__can_get_repo_from_index(void)

git_index_free(index);
}

static void add_conflict(void)
{
git_index *index;
git_index_entry entry;

memset(&entry, 0, sizeof(git_index_entry));

cl_git_pass(git_repository_index(&index, g_repo));

entry.mode = 0100644;
entry.path = "conflicting.txt";

git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46");
entry.flags = (1 << GIT_IDXENTRY_STAGESHIFT);
cl_git_pass(git_index_add(index, &entry));

git_oid_fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10");
entry.flags = (2 << GIT_IDXENTRY_STAGESHIFT);
cl_git_pass(git_index_add(index, &entry));

git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863");
entry.flags = (3 << GIT_IDXENTRY_STAGESHIFT);
cl_git_pass(git_index_add(index, &entry));

cl_git_pass(git_index_write(index));
git_index_free(index);
}

void test_checkout_index__writes_conflict_file(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_buf conflicting_buf = GIT_BUF_INIT;

add_conflict();
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
cl_assert(strcmp(conflicting_buf.ptr,
"<<<<<<< ours\n"
"this file is changed in master and branch\n"
"=======\n"
"this file is changed in branch and master\n"
">>>>>>> theirs\n") == 0);
git_buf_free(&conflicting_buf);
}

void test_checkout_index__conflicts_honor_coreautocrlf(void)
{
#ifdef GIT_WIN32
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_buf conflicting_buf = GIT_BUF_INIT;

cl_git_pass(p_unlink("./testrepo/.gitattributes"));
cl_repo_set_bool(g_repo, "core.autocrlf", true);

add_conflict();
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
cl_assert(strcmp(conflicting_buf.ptr,
"<<<<<<< ours\r\n"
"this file is changed in master and branch\r\n"
"=======\r\n"
"this file is changed in branch and master\r\n"
">>>>>>> theirs\r\n") == 0);
git_buf_free(&conflicting_buf);
#endif
}
16 changes: 15 additions & 1 deletion tests/config/snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
void test_config_snapshot__create_snapshot(void)
{
int32_t tmp;
git_config *cfg, *snapshot;
git_config *cfg, *snapshot, *new_snapshot;
const char *filename = "config-ext-change";

cl_git_mkfile(filename, "[old]\nvalue = 5\n");
Expand All @@ -23,7 +23,21 @@ void test_config_snapshot__create_snapshot(void)

cl_git_pass(git_config_get_int32(&tmp, snapshot, "old.value"));
cl_assert_equal_i(5, tmp);

/* Change the value on the file itself (simulate external process) */
cl_git_mkfile(filename, "[old]\nvalue = 999\n");

cl_git_pass(git_config_snapshot(&new_snapshot, cfg));

/* New snapshot should see new value */
cl_git_pass(git_config_get_int32(&tmp, new_snapshot, "old.value"));
cl_assert_equal_i(999, tmp);

/* Old snapshot should still have the old value */
cl_git_pass(git_config_get_int32(&tmp, snapshot, "old.value"));
cl_assert_equal_i(5, tmp);

git_config_free(new_snapshot);
git_config_free(snapshot);
git_config_free(cfg);
}
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.