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

Skip to content

Commit a1f4d65

Browse files
committed
Merge pull request #2655 from ethomson/v0.21.2
More backports to 0.21
2 parents 5757c02 + cc71348 commit a1f4d65

File tree

13 files changed

+164
-27
lines changed

13 files changed

+164
-27
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ after_success:
4646
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install valgrind; fi
4747
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline; fi
4848

49-
# Only watch the development branch
49+
# Watch development and stable branches
5050
branches:
5151
only:
5252
- development
53+
- /^maint\/.*$/
5354

5455
# Notify development list when needed
5556
notifications:

src/checkout.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,10 +1736,12 @@ static int checkout_write_merge(
17361736
checkout_conflictdata *conflict)
17371737
{
17381738
git_buf our_label = GIT_BUF_INIT, their_label = GIT_BUF_INIT,
1739-
path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT;
1739+
path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT,
1740+
in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT;
17401741
git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
17411742
git_merge_file_result result = {0};
17421743
git_filebuf output = GIT_FILEBUF_INIT;
1744+
git_filter_list *fl = NULL;
17431745
int error = 0;
17441746

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

1790+
if (!data->opts.disable_filters) {
1791+
in_data.ptr = (char *)result.ptr;
1792+
in_data.size = result.len;
1793+
1794+
if ((error = git_filter_list_load(&fl, data->repo, NULL, git_buf_cstr(&path_workdir),
1795+
GIT_FILTER_TO_WORKTREE, GIT_FILTER_OPT_DEFAULT)) < 0 ||
1796+
(error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0)
1797+
goto done;
1798+
} else {
1799+
out_data.ptr = (char *)result.ptr;
1800+
out_data.size = result.len;
1801+
}
1802+
17881803
if ((error = git_futils_mkpath2file(path_workdir.ptr, 0755)) < 0 ||
1789-
(error = git_filebuf_open(&output, path_workdir.ptr, GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
1790-
(error = git_filebuf_write(&output, result.ptr, result.len)) < 0 ||
1804+
(error = git_filebuf_open(&output, git_buf_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
1805+
(error = git_filebuf_write(&output, out_data.ptr, out_data.size)) < 0 ||
17911806
(error = git_filebuf_commit(&output)) < 0)
17921807
goto done;
17931808

17941809
done:
1810+
git_filter_list_free(fl);
1811+
1812+
git_buf_free(&out_data);
17951813
git_buf_free(&our_label);
17961814
git_buf_free(&their_label);
17971815

src/config_file.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,12 +767,17 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
767767
{
768768
diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
769769
diskfile_backend *src = b->snapshot_from;
770+
diskfile_header *src_header = &src->header;
770771
refcounted_strmap *src_map;
772+
int error;
773+
774+
if (!src_header->readonly && (error = config_refresh(&src_header->parent)) < 0)
775+
return error;
771776

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

775-
src_map = refcounted_strmap_take(&src->header);
780+
src_map = refcounted_strmap_take(src_header);
776781
b->header.values = src_map;
777782

778783
return 0;

src/global.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ void openssl_locking_function(int mode, int n, const char *file, int line)
6161
git_mutex_unlock(&openssl_locks[n]);
6262
}
6363
}
64-
#endif
6564

65+
static void shutdown_ssl(void)
66+
{
67+
git__free(openssl_locks);
68+
}
69+
#endif
6670

6771
static void init_ssl(void)
6872
{
@@ -110,6 +114,8 @@ static void init_ssl(void)
110114

111115
CRYPTO_set_locking_callback(openssl_locking_function);
112116
}
117+
118+
git__on_shutdown(shutdown_ssl);
113119
# endif
114120
#endif
115121
}

src/path.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -494,23 +494,33 @@ bool git_path_is_empty_dir(const char *path)
494494
WIN32_FIND_DATAW findData;
495495
HANDLE hFind = FindFirstFileW(filter_w, &findData);
496496

497+
/* FindFirstFile will fail if there are no children to the given
498+
* path, which can happen if the given path is a file (and obviously
499+
* has no children) or if the given path is an empty mount point.
500+
* (Most directories have at least directory entries '.' and '..',
501+
* but ridiculously another volume mounted in another drive letter's
502+
* path space do not, and thus have nothing to enumerate.) If
503+
* FindFirstFile fails, check if this is a directory-like thing
504+
* (a mount point).
505+
*/
506+
if (hFind == INVALID_HANDLE_VALUE)
507+
return git_path_isdir(path);
508+
497509
/* If the find handle was created successfully, then it's a directory */
498-
if (hFind != INVALID_HANDLE_VALUE) {
499-
empty = true;
500-
501-
do {
502-
/* Allow the enumeration to return . and .. and still be considered
503-
* empty. In the special case of drive roots (i.e. C:\) where . and
504-
* .. do not occur, we can still consider the path to be an empty
505-
* directory if there's nothing there. */
506-
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
507-
empty = false;
508-
break;
509-
}
510-
} while (FindNextFileW(hFind, &findData));
511-
512-
FindClose(hFind);
513-
}
510+
empty = true;
511+
512+
do {
513+
/* Allow the enumeration to return . and .. and still be considered
514+
* empty. In the special case of drive roots (i.e. C:\) where . and
515+
* .. do not occur, we can still consider the path to be an empty
516+
* directory if there's nothing there. */
517+
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
518+
empty = false;
519+
break;
520+
}
521+
} while (FindNextFileW(hFind, &findData));
522+
523+
FindClose(hFind);
514524
}
515525

516526
return empty;

src/repository.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1551,8 +1551,10 @@ int git_repository_head_unborn(git_repository *repo)
15511551
error = git_repository_head(&ref, repo);
15521552
git_reference_free(ref);
15531553

1554-
if (error == GIT_EUNBORNBRANCH)
1554+
if (error == GIT_EUNBORNBRANCH) {
1555+
giterr_clear();
15551556
return 1;
1557+
}
15561558

15571559
if (error < 0)
15581560
return -1;

src/tag.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,9 @@ int git_tag_delete(git_repository *repo, const char *tag_name)
406406
if (error < 0)
407407
return error;
408408

409-
if ((error = git_reference_delete(tag_ref)) == 0)
410-
git_reference_free(tag_ref);
409+
error = git_reference_delete(tag_ref);
410+
411+
git_reference_free(tag_ref);
411412

412413
return error;
413414
}

src/win32/posix_w32.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft)
110110
return (time_t)winTime;
111111
}
112112

113+
static bool path_is_volume(wchar_t *target, size_t target_len)
114+
{
115+
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
116+
}
117+
113118
/* On success, returns the length, in characters, of the path stored in dest.
114119
* On failure, returns a negative value. */
115120
static int readlink_w(
@@ -156,7 +161,13 @@ static int readlink_w(
156161
goto on_error;
157162
}
158163

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

tests/checkout/index.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,3 +618,72 @@ void test_checkout_index__can_get_repo_from_index(void)
618618

619619
git_index_free(index);
620620
}
621+
622+
static void add_conflict(void)
623+
{
624+
git_index *index;
625+
git_index_entry entry;
626+
627+
memset(&entry, 0, sizeof(git_index_entry));
628+
629+
cl_git_pass(git_repository_index(&index, g_repo));
630+
631+
entry.mode = 0100644;
632+
entry.path = "conflicting.txt";
633+
634+
git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46");
635+
entry.flags = (1 << GIT_IDXENTRY_STAGESHIFT);
636+
cl_git_pass(git_index_add(index, &entry));
637+
638+
git_oid_fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10");
639+
entry.flags = (2 << GIT_IDXENTRY_STAGESHIFT);
640+
cl_git_pass(git_index_add(index, &entry));
641+
642+
git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863");
643+
entry.flags = (3 << GIT_IDXENTRY_STAGESHIFT);
644+
cl_git_pass(git_index_add(index, &entry));
645+
646+
cl_git_pass(git_index_write(index));
647+
git_index_free(index);
648+
}
649+
650+
void test_checkout_index__writes_conflict_file(void)
651+
{
652+
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
653+
git_buf conflicting_buf = GIT_BUF_INIT;
654+
655+
add_conflict();
656+
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
657+
658+
cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
659+
cl_assert(strcmp(conflicting_buf.ptr,
660+
"<<<<<<< ours\n"
661+
"this file is changed in master and branch\n"
662+
"=======\n"
663+
"this file is changed in branch and master\n"
664+
">>>>>>> theirs\n") == 0);
665+
git_buf_free(&conflicting_buf);
666+
}
667+
668+
void test_checkout_index__conflicts_honor_coreautocrlf(void)
669+
{
670+
#ifdef GIT_WIN32
671+
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
672+
git_buf conflicting_buf = GIT_BUF_INIT;
673+
674+
cl_git_pass(p_unlink("./testrepo/.gitattributes"));
675+
cl_repo_set_bool(g_repo, "core.autocrlf", true);
676+
677+
add_conflict();
678+
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
679+
680+
cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt"));
681+
cl_assert(strcmp(conflicting_buf.ptr,
682+
"<<<<<<< ours\r\n"
683+
"this file is changed in master and branch\r\n"
684+
"=======\r\n"
685+
"this file is changed in branch and master\r\n"
686+
">>>>>>> theirs\r\n") == 0);
687+
git_buf_free(&conflicting_buf);
688+
#endif
689+
}

tests/config/snapshot.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
void test_config_snapshot__create_snapshot(void)
44
{
55
int32_t tmp;
6-
git_config *cfg, *snapshot;
6+
git_config *cfg, *snapshot, *new_snapshot;
77
const char *filename = "config-ext-change";
88

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

2424
cl_git_pass(git_config_get_int32(&tmp, snapshot, "old.value"));
2525
cl_assert_equal_i(5, tmp);
26+
27+
/* Change the value on the file itself (simulate external process) */
28+
cl_git_mkfile(filename, "[old]\nvalue = 999\n");
29+
30+
cl_git_pass(git_config_snapshot(&new_snapshot, cfg));
31+
32+
/* New snapshot should see new value */
33+
cl_git_pass(git_config_get_int32(&tmp, new_snapshot, "old.value"));
34+
cl_assert_equal_i(999, tmp);
35+
36+
/* Old snapshot should still have the old value */
37+
cl_git_pass(git_config_get_int32(&tmp, snapshot, "old.value"));
38+
cl_assert_equal_i(5, tmp);
2639

40+
git_config_free(new_snapshot);
2741
git_config_free(snapshot);
2842
git_config_free(cfg);
2943
}

0 commit comments

Comments
 (0)