summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt10
-rw-r--r--examples/Makefile2
-rw-r--r--examples/cat-file.c229
-rw-r--r--examples/diff.c10
-rw-r--r--examples/general.c2
-rw-r--r--examples/rev-list.c1
-rw-r--r--include/git2/attr.h2
-rw-r--r--include/git2/branch.h2
-rw-r--r--include/git2/checkout.h3
-rw-r--r--include/git2/commit.h17
-rw-r--r--include/git2/config.h31
-rw-r--r--include/git2/diff.h39
-rw-r--r--include/git2/index.h141
-rw-r--r--include/git2/inttypes.h18
-rw-r--r--include/git2/merge.h10
-rw-r--r--include/git2/pack.h6
-rw-r--r--include/git2/refs.h57
-rw-r--r--include/git2/repository.h23
-rw-r--r--include/git2/reset.h6
-rw-r--r--include/git2/strarray.h4
-rw-r--r--include/git2/sys/commit.h5
-rw-r--r--include/git2/sys/index.h1
-rw-r--r--include/git2/sys/refdb_backend.h66
-rw-r--r--include/git2/trace.h3
-rw-r--r--include/git2/tree.h6
-rw-r--r--include/git2/types.h4
-rw-r--r--src/attr.c8
-rw-r--r--src/attr_file.h6
-rw-r--r--src/branch.c74
-rw-r--r--src/checkout.c77
-rw-r--r--src/clone.c82
-rw-r--r--src/commit.c10
-rw-r--r--src/config.c83
-rw-r--r--src/config.h3
-rw-r--r--src/config_file.c2
-rw-r--r--src/date.c6
-rw-r--r--src/diff.c138
-rw-r--r--src/diff.h1
-rw-r--r--src/diff_output.c58
-rw-r--r--src/diff_tform.c21
-rw-r--r--src/fetch.c12
-rw-r--r--src/fileops.c8
-rw-r--r--src/hash/hash_generic.h6
-rw-r--r--src/hash/hash_win32.h8
-rw-r--r--src/hashsig.c1
-rw-r--r--src/index.c89
-rw-r--r--src/indexer.c4
-rw-r--r--src/merge.c330
-rw-r--r--src/merge.h64
-rw-r--r--src/merge_file.c47
-rw-r--r--src/merge_file.h6
-rw-r--r--src/notes.c79
-rw-r--r--src/object.c19
-rw-r--r--src/odb.c68
-rw-r--r--src/pathspec.c2
-rw-r--r--src/push.c16
-rw-r--r--src/refdb.c80
-rw-r--r--src/refdb.h16
-rw-r--r--src/refdb_fs.c189
-rw-r--r--src/reflog.c4
-rw-r--r--src/refs.c149
-rw-r--r--src/remote.c159
-rw-r--r--src/repository.c20
-rw-r--r--src/reset.c2
-rw-r--r--src/revparse.c63
-rw-r--r--src/revwalk.c2
-rw-r--r--src/signature.c21
-rw-r--r--src/stash.c6
-rw-r--r--src/status.c24
-rw-r--r--src/submodule.c4
-rw-r--r--src/tag.c2
-rw-r--r--src/trace.c3
-rw-r--r--src/trace.h6
-rw-r--r--src/transports/local.c6
-rw-r--r--src/transports/smart_protocol.c20
-rw-r--r--src/transports/winhttp.c2
-rw-r--r--src/tree.c25
-rw-r--r--src/tree.h2
-rw-r--r--src/util.c2
-rw-r--r--src/util.h8
-rw-r--r--src/win32/dir.c2
-rw-r--r--src/win32/findfile.c1
-rw-r--r--src/win32/posix_w32.c140
-rw-r--r--tests-clar/checkout/tree.c65
-rw-r--r--tests-clar/clar_libgit2.c12
-rw-r--r--tests-clar/clar_libgit2.h1
-rw-r--r--tests-clar/clone/empty.c4
-rw-r--r--tests-clar/clone/nonetwork.c20
-rw-r--r--tests-clar/commit/parse.c4
-rw-r--r--tests-clar/commit/signature.c4
-rw-r--r--tests-clar/commit/write.c2
-rw-r--r--tests-clar/config/global.c67
-rw-r--r--tests-clar/config/read.c7
-rw-r--r--tests-clar/diff/diff_helpers.c11
-rw-r--r--tests-clar/diff/patch.c190
-rw-r--r--tests-clar/diff/rename.c57
-rw-r--r--tests-clar/diff/workdir.c25
-rw-r--r--tests-clar/index/names.c22
-rw-r--r--tests-clar/index/reuc.c34
-rw-r--r--tests-clar/merge/merge_helpers.c100
-rw-r--r--tests-clar/merge/trees/automerge.c28
-rw-r--r--tests-clar/merge/trees/modeconflict.c4
-rw-r--r--tests-clar/merge/trees/renames.c25
-rw-r--r--tests-clar/merge/trees/treediff.c105
-rw-r--r--tests-clar/merge/trees/trivial.c40
-rw-r--r--tests-clar/network/fetchlocal.c6
-rw-r--r--tests-clar/network/remote/local.c17
-rw-r--r--tests-clar/network/remote/remotes.c12
-rw-r--r--tests-clar/object/cache.c4
-rw-r--r--tests-clar/object/peel.c5
-rw-r--r--tests-clar/online/clone.c3
-rw-r--r--tests-clar/refdb/inmemory.c4
-rw-r--r--tests-clar/refdb/testdb.c56
-rw-r--r--tests-clar/refs/branches/foreach.c34
-rw-r--r--tests-clar/refs/branches/move.c22
-rw-r--r--tests-clar/refs/branches/remote.c6
-rw-r--r--tests-clar/refs/branches/upstream.c13
-rw-r--r--tests-clar/refs/foreachglob.c14
-rw-r--r--tests-clar/refs/iterator.c94
-rw-r--r--tests-clar/refs/list.c15
-rw-r--r--tests-clar/refs/listall.c4
-rw-r--r--tests-clar/refs/ref_helpers.c6
-rw-r--r--tests-clar/refs/revparse.c21
-rw-r--r--tests-clar/refs/setter.c16
-rw-r--r--tests-clar/repo/config.c75
-rw-r--r--tests-clar/repo/message.c7
-rw-r--r--tests-clar/repo/open.c2
-rw-r--r--tests-clar/reset/hard.c30
-rw-r--r--tests-clar/resources/testrepo2/.gitted/HEAD1
-rw-r--r--tests-clar/resources/testrepo2/.gitted/config14
-rw-r--r--tests-clar/resources/testrepo2/.gitted/description1
-rw-r--r--tests-clar/resources/testrepo2/.gitted/indexbin0 -> 512 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/info/exclude6
-rw-r--r--tests-clar/resources/testrepo2/.gitted/logs/HEAD1
-rw-r--r--tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master1
-rw-r--r--tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD1
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1dbin0 -> 134 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08bin0 -> 19 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7bin0 -> 51 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccdbin0 -> 119 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2bin0 -> 125 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a2
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057bin0 -> 18 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd20452
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf36442
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96bin0 -> 116 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60abin0 -> 119 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0bin0 -> 55 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344dbin0 -> 82 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479bin0 -> 126 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a3
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f2
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bdbin0 -> 28 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6bin0 -> 26 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f6443
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd3
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90bbin0 -> 116 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391bin0 -> 15 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1bin0 -> 82 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92bin0 -> 24 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765bin0 -> 82 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idxbin0 -> 1240 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.packbin0 -> 491 bytes
-rw-r--r--tests-clar/resources/testrepo2/.gitted/packed-refs6
-rw-r--r--tests-clar/resources/testrepo2/.gitted/refs/heads/master1
-rw-r--r--tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD1
-rw-r--r--tests-clar/resources/testrepo2/README1
-rw-r--r--tests-clar/resources/testrepo2/new.txt1
-rw-r--r--tests-clar/resources/testrepo2/subdir/README1
-rw-r--r--tests-clar/resources/testrepo2/subdir/new.txt1
-rw-r--r--tests-clar/resources/testrepo2/subdir/subdir2/README1
-rw-r--r--tests-clar/resources/testrepo2/subdir/subdir2/new.txt1
-rw-r--r--tests-clar/status/submodules.c1
-rw-r--r--tests-clar/status/worktree.c23
-rw-r--r--tests-clar/submodule/status.c2
-rw-r--r--tests-clar/trace/trace.c1
-rw-r--r--tests-clar/valgrind-supp-mac.txt72
177 files changed, 2967 insertions, 1465 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cdecd1804..3aa3770b8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,6 +26,7 @@ OPTION( BUILD_EXAMPLES "Build library usage example apps" OFF )
OPTION( TAGS "Generate tags" OFF )
OPTION( PROFILE "Generate profiling information" OFF )
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
+OPTION( SONAME_APPEND "Append the given string to the library's filename" OFF )
IF(MSVC)
# This option is only availalbe when building with MSVC. By default,
# libgit2 is build using the stdcall calling convention, as that's what
@@ -133,7 +134,9 @@ ENDIF()
IF (ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
LINK_LIBRARIES(${ZLIB_LIBRARIES})
-ELSE()
+ # Fake the message CMake would have shown
+ MESSAGE("-- Found zlib: ${ZLIB_LIBRARY}")
+ELSEIF (NOT ZLIB_LIBRARY)
MESSAGE( "zlib was not found; using bundled 3rd-party sources." )
INCLUDE_DIRECTORIES(deps/zlib)
ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP)
@@ -314,6 +317,9 @@ MSVC_SPLIT_SOURCES(git2)
IF (SONAME)
SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_VERSION_MAJOR})
+ IF (SONAME_APPEND)
+ SET_TARGET_PROPERTIES(git2 PROPERTIES OUTPUT_NAME "git2-${SONAME_APPEND}")
+ ENDIF()
ENDIF()
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY)
@@ -349,7 +355,7 @@ IF (BUILD_CLAR)
ADD_CUSTOM_COMMAND(
OUTPUT ${CLAR_PATH}/clar.suite
- COMMAND ${PYTHON_EXECUTABLE} generate.py -xonline .
+ COMMAND ${PYTHON_EXECUTABLE} generate.py -f -xonline .
DEPENDS ${SRC_TEST}
WORKING_DIRECTORY ${CLAR_PATH}
)
diff --git a/examples/Makefile b/examples/Makefile
index 2c18731fd..c5d555566 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -3,7 +3,7 @@
CC = gcc
CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
LFLAGS = -L../build -lgit2 -lz
-APPS = general showindex diff rev-list
+APPS = general showindex diff rev-list cat-file
all: $(APPS)
diff --git a/examples/cat-file.c b/examples/cat-file.c
new file mode 100644
index 000000000..ebb6cb0ca
--- /dev/null
+++ b/examples/cat-file.c
@@ -0,0 +1,229 @@
+#include <stdio.h>
+#include <git2.h>
+#include <stdlib.h>
+#include <string.h>
+
+static git_repository *g_repo;
+
+static void check(int error, const char *message)
+{
+ if (error) {
+ fprintf(stderr, "%s (%d)\n", message, error);
+ exit(1);
+ }
+}
+
+static void usage(const char *message, const char *arg)
+{
+ if (message && arg)
+ fprintf(stderr, "%s: %s\n", message, arg);
+ else if (message)
+ fprintf(stderr, "%s\n", message);
+ fprintf(stderr, "usage: cat-file (-t | -s | -e | -p) [<options>] <object>\n");
+ exit(1);
+}
+
+static int check_str_param(
+ const char *arg, const char *pattern, const char **val)
+{
+ size_t len = strlen(pattern);
+ if (strncmp(arg, pattern, len))
+ return 0;
+ *val = (const char *)(arg + len);
+ return 1;
+}
+
+static void print_signature(const char *header, const git_signature *sig)
+{
+ char sign;
+ int offset, hours, minutes;
+
+ if (!sig)
+ return;
+
+ offset = sig->when.offset;
+ if (offset < 0) {
+ sign = '-';
+ offset = -offset;
+ } else {
+ sign = '+';
+ }
+
+ hours = offset / 60;
+ minutes = offset % 60;
+
+ printf("%s %s <%s> %ld %c%02d%02d\n",
+ header, sig->name, sig->email, (long)sig->when.time,
+ sign, hours, minutes);
+}
+
+static void show_blob(const git_blob *blob)
+{
+ /* ? Does this need crlf filtering? */
+ fwrite(git_blob_rawcontent(blob), git_blob_rawsize(blob), 1, stdout);
+}
+
+static void show_tree(const git_tree *tree)
+{
+ size_t i, max_i = (int)git_tree_entrycount(tree);
+ char oidstr[GIT_OID_HEXSZ + 1];
+ const git_tree_entry *te;
+
+ for (i = 0; i < max_i; ++i) {
+ te = git_tree_entry_byindex(tree, i);
+
+ git_oid_tostr(oidstr, sizeof(oidstr), git_tree_entry_id(te));
+
+ printf("%06o %s %s\t%s\n",
+ git_tree_entry_filemode(te),
+ git_object_type2string(git_tree_entry_type(te)),
+ oidstr, git_tree_entry_name(te));
+ }
+}
+
+static void show_commit(const git_commit *commit)
+{
+ unsigned int i, max_i;
+ char oidstr[GIT_OID_HEXSZ + 1];
+
+ git_oid_tostr(oidstr, sizeof(oidstr), git_commit_tree_id(commit));
+ printf("tree %s\n", oidstr);
+
+ max_i = (unsigned int)git_commit_parentcount(commit);
+ for (i = 0; i < max_i; ++i) {
+ git_oid_tostr(oidstr, sizeof(oidstr), git_commit_parent_id(commit, i));
+ printf("parent %s\n", oidstr);
+ }
+
+ print_signature("author", git_commit_author(commit));
+ print_signature("committer", git_commit_committer(commit));
+
+ if (git_commit_message(commit))
+ printf("\n%s\n", git_commit_message(commit));
+}
+
+static void show_tag(const git_tag *tag)
+{
+ char oidstr[GIT_OID_HEXSZ + 1];
+
+ git_oid_tostr(oidstr, sizeof(oidstr), git_tag_target_id(tag));;
+ printf("object %s\n", oidstr);
+ printf("type %s\n", git_object_type2string(git_tag_target_type(tag)));
+ printf("tag %s\n", git_tag_name(tag));
+ print_signature("tagger", git_tag_tagger(tag));
+
+ if (git_tag_message(tag))
+ printf("\n%s\n", git_tag_message(tag));
+}
+
+enum {
+ SHOW_TYPE = 1,
+ SHOW_SIZE = 2,
+ SHOW_NONE = 3,
+ SHOW_PRETTY = 4
+};
+
+int main(int argc, char *argv[])
+{
+ const char *dir = ".", *rev = NULL;
+ int i, action = 0, verbose = 0;
+ git_object *obj = NULL;
+ char oidstr[GIT_OID_HEXSZ + 1];
+
+ git_threads_init();
+
+ for (i = 1; i < argc; ++i) {
+ char *a = argv[i];
+
+ if (a[0] != '-') {
+ if (rev != NULL)
+ usage("Only one rev should be provided", NULL);
+ else
+ rev = a;
+ }
+ else if (!strcmp(a, "-t"))
+ action = SHOW_TYPE;
+ else if (!strcmp(a, "-s"))
+ action = SHOW_SIZE;
+ else if (!strcmp(a, "-e"))
+ action = SHOW_NONE;
+ else if (!strcmp(a, "-p"))
+ action = SHOW_PRETTY;
+ else if (!strcmp(a, "-q"))
+ verbose = 0;
+ else if (!strcmp(a, "-v"))
+ verbose = 1;
+ else if (!strcmp(a, "--help") || !strcmp(a, "-h"))
+ usage(NULL, NULL);
+ else if (!check_str_param(a, "--git-dir=", &dir))
+ usage("Unknown option", a);
+ }
+
+ if (!action || !rev)
+ usage(NULL, NULL);
+
+ check(git_repository_open_ext(&g_repo, dir, 0, NULL),
+ "Could not open repository");
+
+ if (git_revparse_single(&obj, g_repo, rev) < 0) {
+ fprintf(stderr, "Could not resolve '%s'\n", rev);
+ exit(1);
+ }
+ if (verbose) {
+ char oidstr[GIT_OID_HEXSZ + 1];
+ git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj));
+
+ printf("%s %s\n--\n",
+ git_object_type2string(git_object_type(obj)), oidstr);
+ }
+
+ switch (action) {
+ case SHOW_TYPE:
+ printf("%s\n", git_object_type2string(git_object_type(obj)));
+ break;
+ case SHOW_SIZE: {
+ git_odb *odb;
+ git_odb_object *odbobj;
+
+ check(git_repository_odb(&odb, g_repo), "Could not open ODB");
+ check(git_odb_read(&odbobj, odb, git_object_id(obj)),
+ "Could not find obj");
+
+ printf("%ld\n", (long)git_odb_object_size(odbobj));
+
+ git_odb_object_free(odbobj);
+ git_odb_free(odb);
+ }
+ break;
+ case SHOW_NONE:
+ /* just want return result */
+ break;
+ case SHOW_PRETTY:
+
+ switch (git_object_type(obj)) {
+ case GIT_OBJ_BLOB:
+ show_blob((const git_blob *)obj);
+ break;
+ case GIT_OBJ_COMMIT:
+ show_commit((const git_commit *)obj);
+ break;
+ case GIT_OBJ_TREE:
+ show_tree((const git_tree *)obj);
+ break;
+ case GIT_OBJ_TAG:
+ show_tag((const git_tag *)obj);
+ break;
+ default:
+ printf("unknown %s\n", oidstr);
+ break;
+ }
+ break;
+ }
+
+ git_object_free(obj);
+ git_repository_free(g_repo);
+
+ git_threads_shutdown();
+
+ return 0;
+}
diff --git a/examples/diff.c b/examples/diff.c
index 2ef405665..bb4f0ec21 100644
--- a/examples/diff.c
+++ b/examples/diff.c
@@ -117,7 +117,10 @@ int main(int argc, char *argv[])
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
int i, color = -1, compact = 0, cached = 0;
- char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL;
+ char *a, *treeish1 = NULL, *treeish2 = NULL;
+ const char *dir = ".";
+
+ git_threads_init();
/* parse arguments as copied from git-diff */
@@ -162,7 +165,8 @@ int main(int argc, char *argv[])
!check_uint16_param(a, "--inter-hunk-context=",
&opts.interhunk_lines) &&
!check_str_param(a, "--src-prefix=", &opts.old_prefix) &&
- !check_str_param(a, "--dst-prefix=", &opts.new_prefix))
+ !check_str_param(a, "--dst-prefix=", &opts.new_prefix) &&
+ !check_str_param(a, "--git-dir=", &dir))
usage("Unknown arg", a);
}
@@ -216,6 +220,8 @@ int main(int argc, char *argv[])
git_tree_free(t2);
git_repository_free(repo);
+ git_threads_shutdown();
+
return 0;
}
diff --git a/examples/general.c b/examples/general.c
index adc7ed8d2..d7a58479c 100644
--- a/examples/general.c
+++ b/examples/general.c
@@ -453,7 +453,7 @@ int main (int argc, char** argv)
// Here we will implement something like `git for-each-ref` simply listing
// out all available references and the object SHA they resolve to.
git_strarray ref_list;
- git_reference_list(&ref_list, repo, GIT_REF_LISTALL);
+ git_reference_list(&ref_list, repo);
const char *refname;
git_reference *ref;
diff --git a/examples/rev-list.c b/examples/rev-list.c
index d9ec15f76..1fb7ebf9f 100644
--- a/examples/rev-list.c
+++ b/examples/rev-list.c
@@ -117,4 +117,3 @@ int main (int argc, char **argv)
return 0;
}
-
diff --git a/include/git2/attr.h b/include/git2/attr.h
index f099245b0..0d8a910f2 100644
--- a/include/git2/attr.h
+++ b/include/git2/attr.h
@@ -141,7 +141,7 @@ GIT_EXTERN(git_attr_t) git_attr_value(const char *attr);
*/
GIT_EXTERN(int) git_attr_get(
const char **value_out,
- git_repository *repo,
+ git_repository *repo,
uint32_t flags,
const char *path,
const char *name);
diff --git a/include/git2/branch.h b/include/git2/branch.h
index b15171360..d1838a63a 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -237,7 +237,7 @@ GIT_EXTERN(int) git_branch_is_head(
*
* @return Number of characters in the reference name
* including the trailing NUL byte; GIT_ENOTFOUND
- * when no remote matching remote was gound,
+ * when no remote matching remote was found,
* GIT_EAMBIGUOUS when the branch maps to several remotes,
* otherwise an error code.
*/
diff --git a/include/git2/checkout.h b/include/git2/checkout.h
index d3e971b43..6798bf31c 100644
--- a/include/git2/checkout.h
+++ b/include/git2/checkout.h
@@ -134,6 +134,9 @@ typedef enum {
/** Treat pathspec as simple list of exact match file paths */
GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
+ /** Ignore directories in use, they will be left empty */
+ GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18),
+
/**
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
*/
diff --git a/include/git2/commit.h b/include/git2/commit.h
index f536ac7c8..20b345f84 100644
--- a/include/git2/commit.h
+++ b/include/git2/commit.h
@@ -70,6 +70,14 @@ GIT_EXTERN(void) git_commit_free(git_commit *commit);
GIT_EXTERN(const git_oid *) git_commit_id(const git_commit *commit);
/**
+ * Get the repository that contains the commit.
+ *
+ * @param commit A previously loaded commit.
+ * @return Repository that contains this commit.
+ */
+GIT_EXTERN(git_repository *) git_commit_owner(const git_commit *commit);
+
+/**
* Get the encoding for the message of a commit,
* as a string representing a standard encoding name.
*
@@ -156,7 +164,10 @@ GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit);
* @param n the position of the parent (from 0 to `parentcount`)
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned int n);
+GIT_EXTERN(int) git_commit_parent(
+ git_commit **out,
+ const git_commit *commit,
+ unsigned int n);
/**
* Get the oid of a specified parent for a commit. This is different from
@@ -167,7 +178,9 @@ GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned
* @param n the position of the parent (from 0 to `parentcount`)
* @return the id of the parent, NULL on error.
*/
-GIT_EXTERN(const git_oid *) git_commit_parent_id(git_commit *commit, unsigned int n);
+GIT_EXTERN(const git_oid *) git_commit_parent_id(
+ const git_commit *commit,
+ unsigned int n);
/**
* Get the commit object that is the <n>th generation ancestor
diff --git a/include/git2/config.h b/include/git2/config.h
index 5a2f956fd..8d1a1a5a6 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -190,9 +190,24 @@ GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
* multi-level parent config, or an error code
*/
GIT_EXTERN(int) git_config_open_level(
- git_config **out,
- const git_config *parent,
- unsigned int level);
+ git_config **out,
+ const git_config *parent,
+ unsigned int level);
+
+/**
+ * Open the global/XDG configuration file according to git's rules
+ *
+ * Git allows you to store your global configuration at
+ * `$HOME/.config` or `$XDG_CONFIG_HOME/git/config`. For backwards
+ * compatability, the XDG file shouldn't be used unless the use has
+ * created it explicitly. With this function you'll open the correct
+ * one to write to.
+ *
+ * @param out pointer in which to store the config object
+ * @param config the config object in which to look
+ */
+GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config);
+
/**
* Reload changed config files
@@ -444,11 +459,11 @@ GIT_EXTERN(int) git_config_foreach_match(
* @return 0 on success, error code otherwise
*/
GIT_EXTERN(int) git_config_get_mapped(
- int *out,
- const git_config *cfg,
- const char *name,
- const git_cvar_map *maps,
- size_t map_n);
+ int *out,
+ const git_config *cfg,
+ const char *name,
+ const git_cvar_map *maps,
+ size_t map_n);
/**
* Maps a string value to an integer constant
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 0ef47c018..1feddd7a2 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -356,8 +356,10 @@ typedef enum {
GIT_DIFF_LINE_CONTEXT = ' ',
GIT_DIFF_LINE_ADDITION = '+',
GIT_DIFF_LINE_DELETION = '-',
- GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< Removed line w/o LF & added one with */
- GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */
+
+ GIT_DIFF_LINE_CONTEXT_EOFNL = '=', /**< Both files have no LF at end */
+ GIT_DIFF_LINE_ADD_EOFNL = '>', /**< Old has no LF at end, new does */
+ GIT_DIFF_LINE_DEL_EOFNL = '<', /**< Old has LF at end, new does not */
/* The following values will only be sent to a `git_diff_data_cb` when
* the content of a diff is being formatted (eg. through
@@ -488,6 +490,8 @@ typedef struct {
/**
* Deallocate a diff list.
+ *
+ * @param diff The previously created diff list; cannot be used after free.
*/
GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff);
@@ -497,12 +501,14 @@ GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff);
* This is equivalent to `git diff <old-tree> <new-tree>`
*
* The first tree will be used for the "old_file" side of the delta and the
- * second tree will be used for the "new_file" side of the delta.
+ * second tree will be used for the "new_file" side of the delta. You can
+ * pass NULL to indicate an empty tree, although it is an error to pass
+ * NULL for both the `old_tree` and `new_tree`.
*
* @param diff Output pointer to a git_diff_list pointer to be allocated.
* @param repo The repository containing the trees.
- * @param old_tree A git_tree object to diff from.
- * @param new_tree A git_tree object to diff to.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param new_tree A git_tree object to diff to, or NULL for empty tree.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_tree_to_tree(
@@ -523,7 +529,7 @@ GIT_EXTERN(int) git_diff_tree_to_tree(
*
* @param diff Output pointer to a git_diff_list pointer to be allocated.
* @param repo The repository containing the tree and index.
- * @param old_tree A git_tree object to diff from.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
* @param index The index to diff with; repo index used if NULL.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
@@ -582,7 +588,7 @@ GIT_EXTERN(int) git_diff_index_to_workdir(
*
* @param diff A pointer to a git_diff_list pointer that will be allocated.
* @param repo The repository containing the tree.
- * @param old_tree A git_tree object to diff from.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
* @param opts Structure with options to influence diff or NULL for defaults.
*/
GIT_EXTERN(int) git_diff_tree_to_workdir(
@@ -926,7 +932,14 @@ GIT_EXTERN(int) git_diff_patch_to_str(
* to 1 and no call to the hunk_cb nor line_cb will be made (unless you pass
* `GIT_DIFF_FORCE_TEXT` of course).
*
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param new_blob Blob for new side of diff, or NULL for empty blob
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, GIT_EUSER on non-zero callback return, or error code
*/
GIT_EXTERN(int) git_diff_blobs(
const git_blob *old_blob,
@@ -949,7 +962,15 @@ GIT_EXTERN(int) git_diff_blobs(
* entire content of the buffer added). Passing NULL to the buffer will do
* the reverse, with GIT_DELTA_REMOVED and blob content removed.
*
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ * @param old_blob Blob for old side of diff, or NULL for empty blob
+ * @param buffer Raw data for new side of diff
+ * @param buffer_len Length of raw data for new side of diff
+ * @param options Options for diff, or NULL for default options
+ * @param file_cb Callback for "file"; made once if there is a diff; can be NULL
+ * @param hunk_cb Callback for each hunk in diff; can be NULL
+ * @param line_cb Callback for each line in diff; can be NULL
+ * @param payload Payload passed to each callback function
+ * @return 0 on success, GIT_EUSER on non-zero callback return, or error code
*/
GIT_EXTERN(int) git_diff_blob_to_buffer(
const git_blob *old_blob,
diff --git a/include/git2/index.h b/include/git2/index.h
index d23c3a8ea..8a1ccce55 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -21,50 +21,29 @@
*/
GIT_BEGIN_DECL
-#define GIT_IDXENTRY_NAMEMASK (0x0fff)
-#define GIT_IDXENTRY_STAGEMASK (0x3000)
-#define GIT_IDXENTRY_EXTENDED (0x4000)
-#define GIT_IDXENTRY_VALID (0x8000)
-#define GIT_IDXENTRY_STAGESHIFT 12
-
-/*
- * Flags are divided into two parts: in-memory flags and
- * on-disk ones. Flags in GIT_IDXENTRY_EXTENDED_FLAGS
- * will get saved on-disk.
- *
- * In-memory only flags:
- */
-#define GIT_IDXENTRY_UPDATE (1 << 0)
-#define GIT_IDXENTRY_REMOVE (1 << 1)
-#define GIT_IDXENTRY_UPTODATE (1 << 2)
-#define GIT_IDXENTRY_ADDED (1 << 3)
-
-#define GIT_IDXENTRY_HASHED (1 << 4)
-#define GIT_IDXENTRY_UNHASHED (1 << 5)
-#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */
-#define GIT_IDXENTRY_CONFLICTED (1 << 7)
-
-#define GIT_IDXENTRY_UNPACKED (1 << 8)
-#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
-
-/*
- * Extended on-disk flags:
- */
-#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
-#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
-/* GIT_IDXENTRY_EXTENDED2 is for future extension */
-#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
-
-#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
-
-/** Time used in a git index entry */
+/** Time structure used in a git index entry */
typedef struct {
git_time_t seconds;
/* nsec should not be stored as time_t compatible */
unsigned int nanoseconds;
} git_index_time;
-/** Memory representation of a file entry in the index. */
+/**
+ * In-memory representation of a file entry in the index.
+ *
+ * This is a public structure that represents a file entry in the index.
+ * The meaning of the fields corresponds to core Git's documentation (in
+ * "Documentation/technical/index-format.txt").
+ *
+ * The `flags` field consists of a number of bit fields which can be
+ * accessed via the first set of `GIT_IDXENTRY_...` bitmasks below. These
+ * flags are all read from and persisted to disk.
+ *
+ * The `flags_extended` field also has a number of bit fields which can be
+ * accessed via the later `GIT_IDXENTRY_...` bitmasks below. Some of
+ * these flags are read from and written to disk, but some are set aside
+ * for in-memory only reference.
+ */
typedef struct git_index_entry {
git_index_time ctime;
git_index_time mtime;
@@ -84,13 +63,67 @@ typedef struct git_index_entry {
char *path;
} git_index_entry;
+/**
+ * Bitmasks for on-disk fields of `git_index_entry`'s `flags`
+ *
+ * These bitmasks match the four fields in the `git_index_entry` `flags`
+ * value both in memory and on disk. You can use them to interpret the
+ * data in the `flags`.
+ */
+#define GIT_IDXENTRY_NAMEMASK (0x0fff)
+#define GIT_IDXENTRY_STAGEMASK (0x3000)
+#define GIT_IDXENTRY_EXTENDED (0x4000)
+#define GIT_IDXENTRY_VALID (0x8000)
+#define GIT_IDXENTRY_STAGESHIFT 12
+
+#define GIT_IDXENTRY_STAGE(E) (((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
+
+/**
+ * Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended`
+ *
+ * In memory, the `flags_extended` fields are divided into two parts: the
+ * fields that are read from and written to disk, and other fields that
+ * in-memory only and used by libgit2. Only the flags in
+ * `GIT_IDXENTRY_EXTENDED_FLAGS` will get saved on-disk.
+ *
+ * These bitmasks match the three fields in the `git_index_entry`
+ * `flags_extended` value that belong on disk. You can use them to
+ * interpret the data in the `flags_extended`.
+ */
+#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
+#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
+/* GIT_IDXENTRY_EXTENDED2 is reserved for future extension */
+#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
+
+#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
+
+/**
+ * Bitmasks for in-memory only fields of `git_index_entry`'s `flags_extended`
+ *
+ * These bitmasks match the other fields in the `git_index_entry`
+ * `flags_extended` value that are only used in-memory by libgit2. You
+ * can use them to interpret the data in the `flags_extended`.
+ */
+#define GIT_IDXENTRY_UPDATE (1 << 0)
+#define GIT_IDXENTRY_REMOVE (1 << 1)
+#define GIT_IDXENTRY_UPTODATE (1 << 2)
+#define GIT_IDXENTRY_ADDED (1 << 3)
+
+#define GIT_IDXENTRY_HASHED (1 << 4)
+#define GIT_IDXENTRY_UNHASHED (1 << 5)
+#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */
+#define GIT_IDXENTRY_CONFLICTED (1 << 7)
+
+#define GIT_IDXENTRY_UNPACKED (1 << 8)
+#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
+
/** Capabilities of system that affect index actions. */
-enum {
+typedef enum {
GIT_INDEXCAP_IGNORE_CASE = 1,
GIT_INDEXCAP_NO_FILEMODE = 2,
GIT_INDEXCAP_NO_SYMLINKS = 4,
GIT_INDEXCAP_FROM_OWNER = ~0u
-};
+} git_indexcap_t;
/** @name Index File Functions
*
@@ -265,11 +298,9 @@ GIT_EXTERN(void) git_index_clear(git_index *index);
/**
* Get a pointer to one of the entries in the index
*
- * The values of this entry can be modified (except the path)
- * and the changes will be written back to disk on the next
- * write() call.
- *
- * The entry should not be freed by the caller.
+ * The entry is not modifiable and should not be freed. Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
*
* @param index an existing index object
* @param n the position of the entry
@@ -281,11 +312,9 @@ GIT_EXTERN(const git_index_entry *) git_index_get_byindex(
/**
* Get a pointer to one of the entries in the index
*
- * The values of this entry can be modified (except the path)
- * and the changes will be written back to disk on the next
- * write() call.
- *
- * The entry should not be freed by the caller.
+ * The entry is not modifiable and should not be freed. Because the
+ * `git_index_entry` struct is a publicly defined struct, you should
+ * be able to make your own permanent copy of the data if necessary.
*
* @param index an existing index object
* @param path path to search
@@ -335,8 +364,7 @@ GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_en
/**
* Return the stage number from a git index entry
*
- * This entry is calculated from the entry's flag
- * attribute like this:
+ * This entry is calculated from the entry's flag attribute like this:
*
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
*
@@ -427,7 +455,7 @@ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *pat
* @return 0 or an error code
*/
GIT_EXTERN(int) git_index_conflict_add(
- git_index *index,
+ git_index *index,
const git_index_entry *ancestor_entry,
const git_index_entry *our_entry,
const git_index_entry *their_entry);
@@ -445,7 +473,12 @@ GIT_EXTERN(int) git_index_conflict_add(
* @param index an existing index object
* @param path path to search
*/
-GIT_EXTERN(int) git_index_conflict_get(git_index_entry **ancestor_out, git_index_entry **our_out, git_index_entry **their_out, git_index *index, const char *path);
+GIT_EXTERN(int) git_index_conflict_get(
+ git_index_entry **ancestor_out,
+ git_index_entry **our_out,
+ git_index_entry **their_out,
+ git_index *index,
+ const char *path);
/**
* Removes the index entries that represent a conflict of a single file.
diff --git a/include/git2/inttypes.h b/include/git2/inttypes.h
index 716084219..17364c7f8 100644
--- a/include/git2/inttypes.h
+++ b/include/git2/inttypes.h
@@ -283,18 +283,18 @@ _inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
- imaxdiv_t result;
+ imaxdiv_t result;
- result.quot = numer / denom;
- result.rem = numer % denom;
+ result.quot = numer / denom;
+ result.rem = numer % denom;
- if (numer < 0 && result.rem > 0) {
- // did division wrong; must fix up
- ++result.quot;
- result.rem -= denom;
- }
+ if (numer < 0 && result.rem > 0) {
+ // did division wrong; must fix up
+ ++result.quot;
+ result.rem -= denom;
+ }
- return result;
+ return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
diff --git a/include/git2/merge.h b/include/git2/merge.h
index 8ca90b95f..955840569 100644
--- a/include/git2/merge.h
+++ b/include/git2/merge.h
@@ -33,7 +33,7 @@ typedef enum {
/**
* Automerge options for `git_merge_trees_opts`.
- */
+ */
typedef enum {
GIT_MERGE_AUTOMERGE_NORMAL = 0,
GIT_MERGE_AUTOMERGE_NONE = 1,
@@ -45,18 +45,18 @@ typedef enum {
typedef struct {
unsigned int version;
git_merge_tree_flags flags;
-
+
/** Similarity to consider a file renamed (default 50) */
unsigned int rename_threshold;
-
+
/** Maximum similarity sources to examine (overrides the
* `merge.renameLimit` config) (default 200)
*/
unsigned int target_limit;
- /** Pluggable similarity metric; pass NULL to use internal metric */
+ /** Pluggable similarity metric; pass NULL to use internal metric */
git_diff_similarity_metric *metric;
-
+
/** Flags for automerging content. */
git_merge_automerge_flags automerge_flags;
} git_merge_tree_opts;
diff --git a/include/git2/pack.h b/include/git2/pack.h
index 118b8d554..5e431e62d 100644
--- a/include/git2/pack.h
+++ b/include/git2/pack.h
@@ -96,12 +96,12 @@ GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *
/**
* Insert a commit object
- *
+ *
* This will add a commit as well as the completed referenced tree.
- *
+ *
* @param pb The packbuilder
* @param id The oid of the commit
- *
+ *
* @return 0 or an error code
*/
GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id);
diff --git a/include/git2/refs.h b/include/git2/refs.h
index e1d425352..754bda785 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -55,6 +55,19 @@ GIT_EXTERN(int) git_reference_name_to_id(
git_oid *out, git_repository *repo, const char *name);
/**
+ * Lookup a reference by DWIMing its short name
+ *
+ * Apply the git precendence rules to the given shorthand to determine
+ * which reference the user is refering to.
+ *
+ * @param out pointer in which to store the reference
+ * @param repo the repository in which to look
+ * @param shrothand the short name for the reference
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, const char *shorthand);
+
+/**
* Create a new symbolic reference.
*
* A symbolic reference is a reference name that refers to another
@@ -284,12 +297,6 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
/**
* Fill a list with all the references that can be found in a repository.
*
- * Using the `list_flags` parameter, the listed references may be filtered
- * by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
- * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
- * For convenience, use the value `GIT_REF_LISTALL` to obtain all
- * references, including packed ones.
- *
* The string array will be filled with the names of all references; these
* values are owned by the user and should be free'd manually when no
* longer needed, using `git_strarray_free()`.
@@ -297,36 +304,27 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
* @param array Pointer to a git_strarray structure where
* the reference names will be stored
* @param repo Repository where to find the refs
- * @param list_flags Filtering flags for the reference listing
* @return 0 or an error code
*/
-GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
+GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo);
typedef int (*git_reference_foreach_cb)(const char *refname, void *payload);
/**
* Perform a callback on each reference in the repository.
*
- * Using the `list_flags` parameter, the references may be filtered by
- * type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
- * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
- * For convenience, use the value `GIT_REF_LISTALL` to obtain all
- * references, including packed ones.
- *
* The `callback` function will be called for each reference in the
* repository, receiving the name of the reference and the `payload` value
* passed to this method. Returning a non-zero value from the callback
* will terminate the iteration.
*
* @param repo Repository where to find the refs
- * @param list_flags Filtering flags for the reference listing.
* @param callback Function which will be called for every listed ref
* @param payload Additional data to pass to the callback
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
GIT_EXTERN(int) git_reference_foreach(
git_repository *repo,
- unsigned int list_flags,
git_reference_foreach_cb callback,
void *payload);
@@ -347,6 +345,31 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref);
GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
/**
+ * Create an iterator for the repo's references
+ *
+ * @param out pointer in which to store the iterator
+ * @param repo the repository
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_reference_iterator_new(git_reference_iterator **out, git_repository *repo);
+
+/**
+ * Get the next reference name
+ *
+ * @param out pointer in which to store the string
+ * @param iter the iterator
+ * @param 0, GIT_ITEROVER if there are no more; or an error code
+ */
+GIT_EXTERN(int) git_reference_next(const char **out, git_reference_iterator *iter);
+
+/**
+ * Free the iterator and its associated resources
+ *
+ * @param iter the iterator to free
+ */
+GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter);
+
+/**
* Perform a callback on each reference in the repository whose name
* matches the given pattern.
*
@@ -360,7 +383,6 @@ GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
*
* @param repo Repository where to find the refs
* @param glob Pattern to match (fnmatch-style) against reference name.
- * @param list_flags Filtering flags for the reference listing.
* @param callback Function which will be called for every listed ref
* @param payload Additional data to pass to the callback
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
@@ -368,7 +390,6 @@ GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
GIT_EXTERN(int) git_reference_foreach_glob(
git_repository *repo,
const char *glob,
- unsigned int list_flags,
git_reference_foreach_cb callback,
void *payload);
diff --git a/include/git2/repository.h b/include/git2/repository.h
index cd238e17c..bb2b3db83 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -460,10 +460,19 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
* Use this function to get the contents of this file. Don't forget to
* remove the file after you create the commit.
*
+ * If the repository message exists and there are no errors reading it, this
+ * returns the bytes needed to store the message in memory (i.e. message
+ * file size plus one terminating NUL byte). That value is returned even if
+ * `out` is NULL or `len` is shorter than the necessary size.
+ *
+ * The `out` buffer will *always* be NUL terminated, even if truncation
+ * occurs.
+ *
* @param out Buffer to write data into or NULL to just read required size
- * @param len Length of buffer in bytes
+ * @param len Length of `out` buffer in bytes
* @param repo Repository to read prepared message from
- * @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error
+ * @return GIT_ENOUTFOUND if no message exists, other value < 0 for other
+ * errors, or total bytes in message (may be > `len`) on success
*/
GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo);
@@ -536,11 +545,11 @@ GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo,
* applied when calculating the hash.
*/
GIT_EXTERN(int) git_repository_hashfile(
- git_oid *out,
- git_repository *repo,
- const char *path,
- git_otype type,
- const char *as_path);
+ git_oid *out,
+ git_repository *repo,
+ const char *path,
+ git_otype type,
+ const char *as_path);
/**
* Make the repository HEAD point to the specified reference.
diff --git a/include/git2/reset.h b/include/git2/reset.h
index c7c951942..c36781722 100644
--- a/include/git2/reset.h
+++ b/include/git2/reset.h
@@ -72,9 +72,9 @@ GIT_EXTERN(int) git_reset(
* @return 0 on success or an error code < 0
*/
GIT_EXTERN(int) git_reset_default(
- git_repository *repo,
- git_object *target,
- git_strarray* pathspecs);
+ git_repository *repo,
+ git_object *target,
+ git_strarray* pathspecs);
/** @} */
GIT_END_DECL
diff --git a/include/git2/strarray.h b/include/git2/strarray.h
index d338eb7ad..86fa25f3f 100644
--- a/include/git2/strarray.h
+++ b/include/git2/strarray.h
@@ -20,8 +20,8 @@ GIT_BEGIN_DECL
/** Array of strings */
typedef struct git_strarray {
- char **strings;
- size_t count;
+ char **strings;
+ size_t count;
} git_strarray;
/**
diff --git a/include/git2/sys/commit.h b/include/git2/sys/commit.h
index 096e028c5..34a12fb15 100644
--- a/include/git2/sys/commit.h
+++ b/include/git2/sys/commit.h
@@ -25,8 +25,9 @@ GIT_BEGIN_DECL
*
* See documentation for `git_commit_create()` for information about the
* parameters, as the meaning is identical excepting that `tree` and
- * `parents` now take `git_oid`. This is a dangerous API in that the
- * `parents` list of `git_oid`s in not checked for validity.
+ * `parents` now take `git_oid`. This is a dangerous API in that nor
+ * the `tree`, neither the `parents` list of `git_oid`s are checked for
+ * validity.
*/
GIT_EXTERN(int) git_commit_create_from_oids(
git_oid *oid,
diff --git a/include/git2/sys/index.h b/include/git2/sys/index.h
index f74637f84..a32e07036 100644
--- a/include/git2/sys/index.h
+++ b/include/git2/sys/index.h
@@ -177,4 +177,3 @@ GIT_EXTERN(void) git_index_reuc_clear(git_index *index);
/** @} */
GIT_END_DECL
#endif
-
diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h
index d5f599fec..548597fbc 100644
--- a/include/git2/sys/refdb_backend.h
+++ b/include/git2/sys/refdb_backend.h
@@ -20,9 +20,26 @@
*/
GIT_BEGIN_DECL
+
+/**
+ * Every backend's iterator must have a pointer to itself as the first
+ * element, so the API can talk to it. You'd define your iterator as
+ *
+ * struct my_iterator {
+ * git_reference_iterator parent;
+ * ...
+ * }
+ *
+ * and assign `iter->parent.backend` to your `git_refdb_backend`.
+ */
+struct git_reference_iterator {
+ git_refdb_backend *backend;
+ char *glob;
+};
+
/** An instance for a custom backend */
struct git_refdb_backend {
- unsigned int version;
+ unsigned int version;
/**
* Queries the refdb backend to determine if the given ref_name
@@ -43,29 +60,42 @@ struct git_refdb_backend {
const char *ref_name);
/**
- * Enumerates each reference in the refdb. A refdb implementation must
- * provide this function.
+ * Allocate an iterator object for the backend.
+ *
+ * A refdb implementation must provide this function.
*/
- int (*foreach)(
- git_refdb_backend *backend,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload);
+ int (*iterator)(
+ git_reference_iterator **iter,
+ struct git_refdb_backend *backend);
/**
- * Enumerates each reference in the refdb that matches the given
- * glob string. A refdb implementation may provide this function;
- * if it is not provided, foreach will be used and the results filtered
- * against the glob.
+ * Allocate a glob-filtering iterator object for the backend.
+ *
+ * A refdb implementation may provide this function. If it's
+ * not available, the glob matching will be done by the frontend.
*/
- int (*foreach_glob)(
- git_refdb_backend *backend,
- const char *glob,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload);
+ int (*iterator_glob)(
+ git_reference_iterator **iter,
+ struct git_refdb_backend *backend,
+ const char *glob);
+
+ /**
+ * Return the current value and advance the iterator.
+ *
+ * A refdb implementation must provide this function.
+ */
+ int (*next)(
+ const char **name,
+ git_reference_iterator *iter);
/**
+ * Free the iterator
+ *
+ * A refdb implementation must provide this function.
+ */
+ void (*iterator_free)(
+ git_reference_iterator *iter);
+ /*
* Writes the given reference to the refdb. A refdb implementation
* must provide this function.
*/
diff --git a/include/git2/trace.h b/include/git2/trace.h
index 7409b032d..f9b4d6ff6 100644
--- a/include/git2/trace.h
+++ b/include/git2/trace.h
@@ -32,7 +32,7 @@ typedef enum {
/** Errors that do not impact the program's execution */
GIT_TRACE_ERROR = 2,
-
+
/** Warnings that suggest abnormal data */
GIT_TRACE_WARN = 3,
@@ -65,4 +65,3 @@ GIT_EXTERN(int) git_trace_set(git_trace_level_t level, git_trace_callback cb);
/** @} */
GIT_END_DECL
#endif
-
diff --git a/include/git2/tree.h b/include/git2/tree.h
index 6ad722048..d673f50c4 100644
--- a/include/git2/tree.h
+++ b/include/git2/tree.h
@@ -97,7 +97,7 @@ GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree);
* @return the tree entry; NULL if not found
*/
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(
- git_tree *tree, const char *filename);
+ const git_tree *tree, const char *filename);
/**
* Lookup a tree entry by its position in the tree
@@ -110,7 +110,7 @@ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(
* @return the tree entry; NULL if not found
*/
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(
- git_tree *tree, size_t idx);
+ const git_tree *tree, size_t idx);
/**
* Lookup a tree entry by SHA value.
@@ -141,7 +141,7 @@ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid(
*/
GIT_EXTERN(int) git_tree_entry_bypath(
git_tree_entry **out,
- git_tree *root,
+ const git_tree *root,
const char *path);
/**
diff --git a/include/git2/types.h b/include/git2/types.h
index aca9ed927..43751d3b0 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -165,6 +165,10 @@ typedef struct git_signature {
/** In-memory representation of a reference. */
typedef struct git_reference git_reference;
+/** Iterator for references */
+typedef struct git_reference_iterator git_reference_iterator;
+
+
/** Basic type of any Git reference. */
typedef enum {
GIT_REF_INVALID = 0, /** Invalid reference */
diff --git a/src/attr.c b/src/attr.c
index 6dd2c7e2f..9fe4471f6 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -36,7 +36,7 @@ static int collect_attr_files(
int git_attr_get(
const char **value,
- git_repository *repo,
+ git_repository *repo,
uint32_t flags,
const char *pathname,
const char *name)
@@ -88,10 +88,10 @@ typedef struct {
int git_attr_get_many(
const char **values,
- git_repository *repo,
+ git_repository *repo,
uint32_t flags,
const char *pathname,
- size_t num_attr,
+ size_t num_attr,
const char **names)
{
int error;
@@ -151,7 +151,7 @@ cleanup:
int git_attr_foreach(
- git_repository *repo,
+ git_repository *repo,
uint32_t flags,
const char *pathname,
int (*callback)(const char *name, const char *value, void *payload),
diff --git a/src/attr_file.h b/src/attr_file.h
index d8abcda58..15bba1c6a 100644
--- a/src/attr_file.h
+++ b/src/attr_file.h
@@ -47,14 +47,14 @@ typedef struct {
typedef struct {
git_refcount unused;
const char *name;
- uint32_t name_hash;
+ uint32_t name_hash;
} git_attr_name;
typedef struct {
git_refcount rc; /* for macros */
char *name;
- uint32_t name_hash;
- const char *value;
+ uint32_t name_hash;
+ const char *value;
} git_attr_assignment;
typedef struct {
diff --git a/src/branch.c b/src/branch.c
index 88f052529..dd6dc68f4 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -124,40 +124,43 @@ on_error:
return error;
}
-typedef struct {
- git_branch_foreach_cb branch_cb;
- void *callback_payload;
- unsigned int branch_type;
-} branch_foreach_filter;
-
-static int branch_foreach_cb(const char *branch_name, void *payload)
-{
- branch_foreach_filter *filter = (branch_foreach_filter *)payload;
-
- if (filter->branch_type & GIT_BRANCH_LOCAL &&
- git__prefixcmp(branch_name, GIT_REFS_HEADS_DIR) == 0)
- return filter->branch_cb(branch_name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, filter->callback_payload);
-
- if (filter->branch_type & GIT_BRANCH_REMOTE &&
- git__prefixcmp(branch_name, GIT_REFS_REMOTES_DIR) == 0)
- return filter->branch_cb(branch_name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, filter->callback_payload);
-
- return 0;
-}
-
int git_branch_foreach(
git_repository *repo,
unsigned int list_flags,
- git_branch_foreach_cb branch_cb,
+ git_branch_foreach_cb callback,
void *payload)
{
- branch_foreach_filter filter;
+ git_reference_iterator *iter;
+ const char *name;
+ int error;
+
+ if (git_reference_iterator_new(&iter, repo) < 0)
+ return -1;
+
+ while ((error = git_reference_next(&name, iter)) == 0) {
+ if (list_flags & GIT_BRANCH_LOCAL &&
+ git__prefixcmp(name, GIT_REFS_HEADS_DIR) == 0) {
+ if (callback(name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, payload)) {
+ error = GIT_EUSER;
+ break;
+ }
+ }
- filter.branch_cb = branch_cb;
- filter.branch_type = list_flags;
- filter.callback_payload = payload;
+ if (list_flags & GIT_BRANCH_REMOTE &&
+ git__prefixcmp(name, GIT_REFS_REMOTES_DIR) == 0) {
+ if (callback(name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, payload)) {
+ error = GIT_EUSER;
+ break;
+ }
+ }
+ }
+
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+ git_reference_iterator_free(iter);
+ return error;
- return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
}
int git_branch_move(
@@ -185,7 +188,7 @@ int git_branch_move(
git_buf_cstr(&old_config_section),
git_buf_cstr(&new_config_section))) < 0)
goto done;
-
+
if ((error = git_reference_rename(out, branch, git_buf_cstr(&new_reference_name), force)) < 0)
goto done;
@@ -276,6 +279,8 @@ int git_branch_upstream__name(
goto cleanup;
if (!*remote_name || !*merge_name) {
+ giterr_set(GITERR_REFERENCE,
+ "branch '%s' does not have an upstream", canonical_branch_name);
error = GIT_ENOTFOUND;
goto cleanup;
}
@@ -342,6 +347,9 @@ static int remote_name(git_buf *buf, git_repository *repo, const char *canonical
remote_name = remote_list.strings[i];
} else {
git_remote_free(remote);
+
+ giterr_set(GITERR_REFERENCE,
+ "Reference '%s' is ambiguous", canonical_branch_name);
error = GIT_EAMBIGUOUS;
goto cleanup;
}
@@ -354,6 +362,8 @@ static int remote_name(git_buf *buf, git_repository *repo, const char *canonical
git_buf_clear(buf);
error = git_buf_puts(buf, remote_name);
} else {
+ giterr_set(GITERR_REFERENCE,
+ "Could not determine remote for '%s'", canonical_branch_name);
error = GIT_ENOTFOUND;
}
@@ -490,8 +500,11 @@ int git_branch_set_upstream(git_reference *branch, const char *upstream_name)
local = 1;
else if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_REMOTE) == 0)
local = 0;
- else
+ else {
+ giterr_set(GITERR_REFERENCE,
+ "Cannot set upstream for branch '%s'", shortname);
return GIT_ENOTFOUND;
+ }
/*
* If it's local, the remote is "." and the branch name is
@@ -511,7 +524,8 @@ int git_branch_set_upstream(git_reference *branch, const char *upstream_name)
goto on_error;
if (local) {
- if (git_buf_puts(&value, git_reference_name(branch)) < 0)
+ git_buf_clear(&value);
+ if (git_buf_puts(&value, git_reference_name(upstream)) < 0)
goto on_error;
} else {
/* Get the remoe-tracking branch's refname in its repo */
diff --git a/src/checkout.c b/src/checkout.c
index 21f32d89a..5820f626a 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -189,6 +189,10 @@ static int checkout_action_common(
action = (action & ~CHECKOUT_ACTION__UPDATE_BLOB) |
CHECKOUT_ACTION__UPDATE_SUBMODULE;
+ /* to "update" a symlink, we must remove the old one first */
+ if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL)
+ action |= CHECKOUT_ACTION__REMOVE;
+
notify = GIT_CHECKOUT_NOTIFY_UPDATED;
}
@@ -764,17 +768,24 @@ cleanup:
}
static int blob_content_to_link(
- struct stat *st, git_blob *blob, const char *path, int can_symlink)
+ struct stat *st,
+ git_blob *blob,
+ const char *path,
+ mode_t dir_mode,
+ int can_symlink)
{
git_buf linktarget = GIT_BUF_INIT;
int error;
+ if ((error = git_futils_mkpath2file(path, dir_mode)) < 0)
+ return error;
+
if ((error = git_blob__getbuf(&linktarget, blob)) < 0)
return error;
if (can_symlink) {
if ((error = p_symlink(git_buf_cstr(&linktarget), path)) < 0)
- giterr_set(GITERR_CHECKOUT, "Could not create symlink %s\n", path);
+ giterr_set(GITERR_OS, "Could not create symlink %s\n", path);
} else {
error = git_futils_fake_symlink(git_buf_cstr(&linktarget), path);
}
@@ -809,6 +820,31 @@ static int checkout_update_index(
return git_index_add(data->index, &entry);
}
+static int checkout_submodule_update_index(
+ checkout_data *data,
+ const git_diff_file *file)
+{
+ struct stat st;
+
+ /* update the index unless prevented */
+ if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) != 0)
+ return 0;
+
+ git_buf_truncate(&data->path, data->workdir_len);
+ if (git_buf_puts(&data->path, file->path) < 0)
+ return -1;
+
+ if (p_stat(git_buf_cstr(&data->path), &st) < 0) {
+ giterr_set(
+ GITERR_CHECKOUT, "Could not stat submodule %s\n", file->path);
+ return GIT_ENOTFOUND;
+ }
+
+ st.st_mode = GIT_FILEMODE_COMMIT;
+
+ return checkout_update_index(data, file, &st);
+}
+
static int checkout_submodule(
checkout_data *data,
const git_diff_file *file)
@@ -825,8 +861,17 @@ static int checkout_submodule(
data->opts.dir_mode, GIT_MKDIR_PATH)) < 0)
return error;
- if ((error = git_submodule_lookup(&sm, data->repo, file->path)) < 0)
+ if ((error = git_submodule_lookup(&sm, data->repo, file->path)) < 0) {
+ /* I've observed repos with submodules in the tree that do not
+ * have a .gitmodules - core Git just makes an empty directory
+ */
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
+ return checkout_submodule_update_index(data, file);
+ }
+
return error;
+ }
/* TODO: Support checkout_strategy options. Two circumstances:
* 1 - submodule already checked out, but we need to move the HEAD
@@ -837,26 +882,7 @@ static int checkout_submodule(
* command should probably be able to. Do we need a submodule callback?
*/
- /* update the index unless prevented */
- if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0) {
- struct stat st;
-
- git_buf_truncate(&data->path, data->workdir_len);
- if (git_buf_puts(&data->path, file->path) < 0)
- return -1;
-
- if ((error = p_stat(git_buf_cstr(&data->path), &st)) < 0) {
- giterr_set(
- GITERR_CHECKOUT, "Could not stat submodule %s\n", file->path);
- return error;
- }
-
- st.st_mode = GIT_FILEMODE_COMMIT;
-
- error = checkout_update_index(data, file, &st);
- }
-
- return error;
+ return checkout_submodule_update_index(data, file);
}
static void report_progress(
@@ -914,7 +940,7 @@ static int checkout_blob(
if (S_ISLNK(file->mode))
error = blob_content_to_link(
- &st, blob, git_buf_cstr(&data->path), data->can_symlink);
+ &st, blob, git_buf_cstr(&data->path), data->opts.dir_mode, data->can_symlink);
else
error = blob_content_to_file(
&st, blob, git_buf_cstr(&data->path), file->mode, &data->opts);
@@ -955,6 +981,9 @@ static int checkout_remove_the_old(
uint32_t flg = GIT_RMDIR_EMPTY_PARENTS |
GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS;
+ if (data->opts.checkout_strategy & GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES)
+ flg |= GIT_RMDIR_SKIP_NONEMPTY;
+
git_buf_truncate(&data->path, data->workdir_len);
git_vector_foreach(&data->diff->deltas, i, delta) {
diff --git a/src/clone.c b/src/clone.c
index aeb7bbf5c..7ebdb5765 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -243,7 +243,6 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote)
/* Not master. Check all the other refs. */
if (git_reference_foreach(
repo,
- GIT_REF_LISTALL,
reference_matches_remote_head,
&head_info) < 0)
goto cleanup;
@@ -275,7 +274,7 @@ static int update_head_to_branch(
int retcode;
git_buf remote_branch_name = GIT_BUF_INIT;
git_reference* remote_ref = NULL;
-
+
assert(options->checkout_branch);
if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s",
@@ -355,50 +354,48 @@ static int setup_remotes_and_fetch(
const git_clone_options *options)
{
int retcode = GIT_ERROR;
- git_remote *origin;
+ git_remote *origin = NULL;
/* Construct an origin remote */
- if (!create_and_configure_origin(&origin, repo, url, options)) {
- git_remote_set_update_fetchhead(origin, 0);
-
- /* Connect and download everything */
- if (!git_remote_connect(origin, GIT_DIRECTION_FETCH)) {
- if (!(retcode = git_remote_download(origin, options->fetch_progress_cb,
- options->fetch_progress_payload))) {
- /* Create "origin/foo" branches for all remote branches */
- if (!git_remote_update_tips(origin)) {
- /* Point HEAD to the requested branch */
- if (options->checkout_branch) {
- if (!update_head_to_branch(repo, options))
- retcode = 0;
- }
- /* Point HEAD to the same ref as the remote's head */
- else if (!update_head_to_remote(repo, origin)) {
- retcode = 0;
- }
- }
- }
- git_remote_disconnect(origin);
- }
- git_remote_free(origin);
- }
+ if ((retcode = create_and_configure_origin(&origin, repo, url, options)) < 0)
+ goto on_error;
- return retcode;
-}
+ git_remote_set_update_fetchhead(origin, 0);
+ /* If the download_tags value has not been specified, then make sure to
+ * download tags as well. It is set here because we want to download tags
+ * on the initial clone, but do not want to persist the value in the
+ * configuration file.
+ */
+ if (origin->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_AUTO &&
+ ((retcode = git_remote_add_fetch(origin, "refs/tags/*:refs/tags/*")) < 0))
+ goto on_error;
-static bool path_is_okay(const char *path)
-{
- /* The path must either not exist, or be an empty directory */
- if (!git_path_exists(path)) return true;
- if (!git_path_is_empty_dir(path)) {
- giterr_set(GITERR_INVALID,
- "'%s' exists and is not an empty directory", path);
- return false;
- }
- return true;
+ /* Connect and download everything */
+ if ((retcode = git_remote_connect(origin, GIT_DIRECTION_FETCH)) < 0)
+ goto on_error;
+
+ if ((retcode = git_remote_download(origin, options->fetch_progress_cb,
+ options->fetch_progress_payload)) < 0)
+ goto on_error;
+
+ /* Create "origin/foo" branches for all remote branches */
+ if ((retcode = git_remote_update_tips(origin)) < 0)
+ goto on_error;
+
+ /* Point HEAD to the requested branch */
+ if (options->checkout_branch)
+ retcode = update_head_to_branch(repo, options);
+ /* Point HEAD to the same ref as the remote's head */
+ else
+ retcode = update_head_to_remote(repo, origin);
+
+on_error:
+ git_remote_free(origin);
+ return retcode;
}
+
static bool should_checkout(
git_repository *repo,
bool is_bare,
@@ -425,7 +422,7 @@ static void normalize_options(git_clone_options *dst, const git_clone_options *s
/* Provide defaults for null pointers */
if (!dst->remote_name) dst->remote_name = "origin";
- if (!dst->remote_autotag) dst->remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
+ if (!dst->remote_autotag) dst->remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
}
int git_clone(
@@ -444,7 +441,10 @@ int git_clone(
normalize_options(&normOptions, options);
GITERR_CHECK_VERSION(&normOptions, GIT_CLONE_OPTIONS_VERSION, "git_clone_options");
- if (!path_is_okay(local_path)) {
+ /* Only clone to a new directory or an empty directory */
+ if (git_path_exists(local_path) && !git_path_is_empty_dir(local_path)) {
+ giterr_set(GITERR_INVALID,
+ "'%s' exists and is not an empty directory", local_path);
return GIT_ERROR;
}
diff --git a/src/commit.c b/src/commit.c
index 46c02c292..1ab9b34f7 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -96,7 +96,6 @@ int git_commit_create_from_oids(
git_odb *odb;
assert(oid && repo && tree && parent_count >= 0);
- assert(git_object_owner((const git_object *)tree) == repo);
git_oid__writebuf(&commit, "tree ", tree);
@@ -149,6 +148,7 @@ int git_commit_create(
const git_oid **parent_oids;
assert(parent_count >= 0);
+ assert(git_object_owner((const git_object *)tree) == repo);
parent_oids = git__malloc(parent_count * sizeof(git_oid *));
GITERR_CHECK_ALLOC(parent_oids);
@@ -266,14 +266,16 @@ int git_commit_tree(git_tree **tree_out, const git_commit *commit)
return git_tree_lookup(tree_out, commit->object.repo, &commit->tree_id);
}
-const git_oid *git_commit_parent_id(git_commit *commit, unsigned int n)
+const git_oid *git_commit_parent_id(
+ const git_commit *commit, unsigned int n)
{
assert(commit);
return git_vector_get(&commit->parent_ids, n);
}
-int git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n)
+int git_commit_parent(
+ git_commit **parent, const git_commit *commit, unsigned int n)
{
const git_oid *parent_id;
assert(commit);
@@ -292,7 +294,7 @@ int git_commit_nth_gen_ancestor(
const git_commit *commit,
unsigned int n)
{
- git_commit *current, *parent;
+ git_commit *current, *parent = NULL;
int error;
assert(ancestor && commit);
diff --git a/src/config.c b/src/config.c
index 2e1268ef3..dc8c7024e 100644
--- a/src/config.c
+++ b/src/config.c
@@ -91,13 +91,15 @@ int git_config_add_file_ondisk(
int force)
{
git_config_backend *file = NULL;
+ struct stat st;
int res;
assert(cfg && path);
- if (!git_path_isfile(path)) {
- giterr_set(GITERR_CONFIG, "Cannot find config file '%s'", path);
- return GIT_ENOTFOUND;
+ res = p_stat(path, &st);
+ if (res < 0 && errno != ENOENT) {
+ giterr_set(GITERR_CONFIG, "Error stat'ing config file '%s'", path);
+ return -1;
}
if (git_config_file__ondisk(&file, path) < 0)
@@ -225,10 +227,18 @@ static int git_config__add_internal(
return 0;
}
+int git_config_open_global(git_config **cfg_out, git_config *cfg)
+{
+ if (!git_config_open_level(cfg_out, cfg, GIT_CONFIG_LEVEL_XDG))
+ return 0;
+
+ return git_config_open_level(cfg_out, cfg, GIT_CONFIG_LEVEL_GLOBAL);
+}
+
int git_config_open_level(
- git_config **cfg_out,
- const git_config *cfg_parent,
- unsigned int level)
+ git_config **cfg_out,
+ const git_config *cfg_parent,
+ unsigned int level)
{
git_config *cfg;
file_internal *internal;
@@ -344,6 +354,13 @@ int git_config_delete_entry(git_config *cfg, const char *name)
* Setters
**************/
+static int config_error_nofiles(const char *name)
+{
+ giterr_set(GITERR_CONFIG,
+ "Cannot set value for '%s' when no config files exist", name);
+ return GIT_ENOTFOUND;
+}
+
int git_config_set_int64(git_config *cfg, const char *name, int64_t value)
{
char str_value[32]; /* All numbers should fit in here */
@@ -373,12 +390,8 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
}
internal = git_vector_get(&cfg->files, 0);
- if (!internal) {
- /* Should we auto-vivify .git/config? Tricky from this location */
- giterr_set(GITERR_CONFIG, "Cannot set value when no config files exist");
- return GIT_ENOTFOUND;
- }
-
+ if (!internal)
+ return config_error_nofiles(name);
file = internal->file;
error = file->set(file, name, value);
@@ -442,6 +455,12 @@ static int get_string_at_file(const char **out, const git_config_backend *file,
return res;
}
+static int config_error_notfound(const char *name)
+{
+ giterr_set(GITERR_CONFIG, "Config value '%s' was not found", name);
+ return GIT_ENOTFOUND;
+}
+
static int get_string(const char **out, const git_config *cfg, const char *name)
{
file_internal *internal;
@@ -454,7 +473,7 @@ static int get_string(const char **out, const git_config *cfg, const char *name)
return res;
}
- return GIT_ENOTFOUND;
+ return config_error_notfound(name);
}
int git_config_get_bool(int *out, const git_config *cfg, const char *name)
@@ -494,7 +513,7 @@ int git_config_get_entry(const git_config_entry **out, const git_config *cfg, co
return ret;
}
- return GIT_ENOTFOUND;
+ return config_error_notfound(name);
}
int git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp,
@@ -517,7 +536,7 @@ int git_config_get_multivar(const git_config *cfg, const char *name, const char
return ret;
}
- return 0;
+ return (ret == GIT_ENOTFOUND) ? config_error_notfound(name) : 0;
}
int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value)
@@ -526,6 +545,8 @@ int git_config_set_multivar(git_config *cfg, const char *name, const char *regex
file_internal *internal;
internal = git_vector_get(&cfg->files, 0);
+ if (!internal)
+ return config_error_nofiles(name);
file = internal->file;
return file->set_multivar(file, name, regexp, value);
@@ -586,6 +607,33 @@ int git_config_find_system(char *system_config_path, size_t length)
system_config_path, length, git_config_find_system_r);
}
+int git_config__global_location(git_buf *buf)
+{
+ const git_buf *paths;
+ const char *sep, *start;
+ size_t len;
+
+ if (git_futils_dirs_get(&paths, GIT_FUTILS_DIR_GLOBAL) < 0)
+ return -1;
+
+ /* no paths, so give up */
+ if (git_buf_len(paths) == 0)
+ return -1;
+
+ start = git_buf_cstr(paths);
+ sep = strchr(start, GIT_PATH_LIST_SEPARATOR);
+
+ if (sep)
+ len = sep - start;
+ else
+ len = paths->size;
+
+ if (git_buf_set(buf, start, len) < 0)
+ return -1;
+
+ return git_buf_joinpath(buf, buf->ptr, GIT_CONFIG_FILENAME_GLOBAL);
+}
+
int git_config_open_default(git_config **out)
{
int error;
@@ -594,9 +642,12 @@ int git_config_open_default(git_config **out)
error = git_config_new(&cfg);
- if (!error && !git_config_find_global_r(&buf))
+ if (!error && (!git_config_find_global_r(&buf) ||
+ !git_config__global_location(&buf))) {
error = git_config_add_file_ondisk(cfg, buf.ptr,
GIT_CONFIG_LEVEL_GLOBAL, 0);
+ } else {
+ }
if (!error && !git_config_find_xdg_r(&buf))
error = git_config_add_file_ondisk(cfg, buf.ptr,
diff --git a/src/config.h b/src/config.h
index c43e47e82..c5c11ae14 100644
--- a/src/config.h
+++ b/src/config.h
@@ -28,6 +28,9 @@ extern int git_config_find_global_r(git_buf *global_config_path);
extern int git_config_find_xdg_r(git_buf *system_config_path);
extern int git_config_find_system_r(git_buf *system_config_path);
+
+extern int git_config__global_location(git_buf *buf);
+
extern int git_config_rename_section(
git_repository *repo,
const char *old_section_name, /* eg "branch.dummy" */
diff --git a/src/config_file.c b/src/config_file.c
index a9a40c366..e57cd1e53 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -296,7 +296,7 @@ cleanup:
static int config_set(git_config_backend *cfg, const char *name, const char *value)
{
- cvar_t *var = NULL, *old_var;
+ cvar_t *var = NULL, *old_var = NULL;
diskfile_backend *b = (diskfile_backend *)cfg;
char *key, *esc_value = NULL;
khiter_t pos;
diff --git a/src/date.c b/src/date.c
index ce1721a0b..48841e4f9 100644
--- a/src/date.c
+++ b/src/date.c
@@ -823,8 +823,8 @@ static void pending_number(struct tm *tm, int *num)
}
static git_time_t approxidate_str(const char *date,
- const struct timeval *tv,
- int *error_ret)
+ const struct timeval *tv,
+ int *error_ret)
{
int number = 0;
int touched = 0;
@@ -866,7 +866,7 @@ int git__date_parse(git_time_t *out, const char *date)
int offset, error_ret=0;
if (!parse_date_basic(date, &timestamp, &offset)) {
- *out = timestamp;
+ *out = timestamp;
return 0;
}
diff --git a/src/diff.c b/src/diff.c
index a154e67e8..d93506984 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -389,6 +389,9 @@ static int diff_list_apply_options(
/* Don't set GIT_DIFFCAPS_USE_DEV - compile time option in core git */
+ /* Set GIT_DIFFCAPS_TRUST_NANOSECS on a platform basis */
+ diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_NANOSECS;
+
/* If not given explicit `opts`, check `diff.xyz` configs */
if (!opts) {
diff->opts.context_lines = config_int(cfg, "diff.context", 3);
@@ -529,6 +532,13 @@ cleanup:
return result;
}
+static bool diff_time_eq(
+ const git_index_time *a, const git_index_time *b, bool use_nanos)
+{
+ return a->seconds == b->seconds &&
+ (!use_nanos || a->nanoseconds == b->nanoseconds);
+}
+
typedef struct {
git_repository *repo;
git_iterator *old_iter;
@@ -540,11 +550,51 @@ typedef struct {
#define MODE_BITS_MASK 0000777
+static int maybe_modified_submodule(
+ git_delta_t *status,
+ git_oid *found_oid,
+ git_diff_list *diff,
+ diff_in_progress *info)
+{
+ int error = 0;
+ git_submodule *sub;
+ unsigned int sm_status = 0;
+ const git_oid *sm_oid;
+
+ *status = GIT_DELTA_UNMODIFIED;
+
+ if (!DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES) &&
+ !(error = git_submodule_lookup(
+ &sub, diff->repo, info->nitem->path)) &&
+ git_submodule_ignore(sub) != GIT_SUBMODULE_IGNORE_ALL &&
+ !(error = git_submodule_status(&sm_status, sub)))
+ {
+ /* check IS_WD_UNMODIFIED because this case is only used
+ * when the new side of the diff is the working directory
+ */
+ if (!GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(sm_status))
+ *status = GIT_DELTA_MODIFIED;
+
+ /* grab OID while we are here */
+ if (git_oid_iszero(&info->nitem->oid) &&
+ (sm_oid = git_submodule_wd_id(sub)) != NULL)
+ git_oid_cpy(found_oid, sm_oid);
+ }
+
+ /* GIT_EEXISTS means a dir with .git in it was found - ignore it */
+ if (error == GIT_EEXISTS) {
+ giterr_clear();
+ error = 0;
+ }
+
+ return error;
+}
+
static int maybe_modified(
git_diff_list *diff,
diff_in_progress *info)
{
- git_oid noid, *use_noid = NULL;
+ git_oid noid;
git_delta_t status = GIT_DELTA_MODIFIED;
const git_index_entry *oitem = info->oitem;
const git_index_entry *nitem = info->nitem;
@@ -560,6 +610,8 @@ static int maybe_modified(
&matched_pathspec))
return 0;
+ memset(&noid, 0, sizeof(noid));
+
/* on platforms with no symlinks, preserve mode of existing symlinks */
if (S_ISLNK(omode) && S_ISREG(nmode) && new_is_workdir &&
!(diff->diffcaps & GIT_DIFFCAPS_HAS_SYMLINKS))
@@ -600,55 +652,30 @@ static int maybe_modified(
* circumstances that can accelerate things or need special handling
*/
else if (git_oid_iszero(&nitem->oid) && new_is_workdir) {
- /* TODO: add check against index file st_mtime to avoid racy-git */
+ bool use_ctime = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) != 0);
+ bool use_nanos = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_NANOSECS) != 0);
- /* if the stat data looks exactly alike, then assume the same */
- if (omode == nmode &&
- oitem->file_size == nitem->file_size &&
- (!(diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) ||
- (oitem->ctime.seconds == nitem->ctime.seconds)) &&
- oitem->mtime.seconds == nitem->mtime.seconds &&
- (!(diff->diffcaps & GIT_DIFFCAPS_USE_DEV) ||
- (oitem->dev == nitem->dev)) &&
- oitem->ino == nitem->ino &&
- oitem->uid == nitem->uid &&
- oitem->gid == nitem->gid)
- status = GIT_DELTA_UNMODIFIED;
+ status = GIT_DELTA_UNMODIFIED;
- else if (S_ISGITLINK(nmode)) {
- int err;
- git_submodule *sub;
-
- if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES))
- status = GIT_DELTA_UNMODIFIED;
- else if ((err = git_submodule_lookup(&sub, diff->repo, nitem->path)) < 0) {
- if (err == GIT_EEXISTS)
- status = GIT_DELTA_UNMODIFIED;
- else
- return err;
- } else if (git_submodule_ignore(sub) == GIT_SUBMODULE_IGNORE_ALL)
- status = GIT_DELTA_UNMODIFIED;
- else {
- unsigned int sm_status = 0;
- if (git_submodule_status(&sm_status, sub) < 0)
- return -1;
-
- /* check IS_WD_UNMODIFIED because this case is only used
- * when the new side of the diff is the working directory
- */
- status = GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(sm_status)
- ? GIT_DELTA_UNMODIFIED : GIT_DELTA_MODIFIED;
-
- /* grab OID while we are here */
- if (git_oid_iszero(&nitem->oid)) {
- const git_oid *sm_oid = git_submodule_wd_id(sub);
- if (sm_oid != NULL) {
- git_oid_cpy(&noid, sm_oid);
- use_noid = &noid;
- }
- }
- }
+ /* TODO: add check against index file st_mtime to avoid racy-git */
+
+ if (S_ISGITLINK(nmode)) {
+ if (maybe_modified_submodule(&status, &noid, diff, info) < 0)
+ return -1;
}
+
+ /* if the stat data looks different, then mark modified - this just
+ * means that the OID will be recalculated below to confirm change
+ */
+ else if (omode != nmode ||
+ oitem->file_size != nitem->file_size ||
+ !diff_time_eq(&oitem->mtime, &nitem->mtime, use_nanos) ||
+ (use_ctime &&
+ !diff_time_eq(&oitem->ctime, &nitem->ctime, use_nanos)) ||
+ oitem->ino != nitem->ino ||
+ oitem->uid != nitem->uid ||
+ oitem->gid != nitem->gid)
+ status = GIT_DELTA_MODIFIED;
}
/* if mode is GITLINK and submodules are ignored, then skip */
@@ -660,11 +687,10 @@ static int maybe_modified(
* haven't calculated the OID of the new item, then calculate it now
*/
if (status != GIT_DELTA_UNMODIFIED && git_oid_iszero(&nitem->oid)) {
- if (!use_noid) {
+ if (git_oid_iszero(&noid)) {
if (git_diff__oid_for_file(diff->repo,
nitem->path, nitem->mode, nitem->file_size, &noid) < 0)
return -1;
- use_noid = &noid;
}
/* if oid matches, then mark unmodified (except submodules, where
@@ -672,12 +698,13 @@ static int maybe_modified(
* matches between the index and the workdir HEAD)
*/
if (omode == nmode && !S_ISGITLINK(omode) &&
- git_oid_equal(&oitem->oid, use_noid))
+ git_oid_equal(&oitem->oid, &noid))
status = GIT_DELTA_UNMODIFIED;
}
return diff_delta__from_two(
- diff, status, oitem, omode, nitem, nmode, use_noid, matched_pathspec);
+ diff, status, oitem, omode, nitem, nmode,
+ git_oid_iszero(&noid) ? NULL : &noid, matched_pathspec);
}
static bool entry_is_prefixed(
@@ -716,11 +743,12 @@ static int diff_scan_inside_untracked_dir(
error = git_iterator_advance(&info->nitem, info->new_iter);
}
- return error;
+ goto done;
}
/* look for actual untracked file */
- while (!diff->pfxcomp(info->nitem->path, git_buf_cstr(&base))) {
+ while (info->nitem != NULL &&
+ !diff->pfxcomp(info->nitem->path, git_buf_cstr(&base))) {
is_ignored = git_iterator_current_is_ignored(info->new_iter);
/* need to recurse into non-ignored directories */
@@ -742,11 +770,13 @@ static int diff_scan_inside_untracked_dir(
}
/* finish off scan */
- while (!diff->pfxcomp(info->nitem->path, git_buf_cstr(&base))) {
+ while (info->nitem != NULL &&
+ !diff->pfxcomp(info->nitem->path, git_buf_cstr(&base))) {
if ((error = git_iterator_advance(&info->nitem, info->new_iter)) < 0)
break;
}
+done:
git_buf_free(&base);
return error;
diff --git a/src/diff.h b/src/diff.h
index 48e20d1e3..16df431ed 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -26,6 +26,7 @@ enum {
GIT_DIFFCAPS_TRUST_MODE_BITS = (1 << 2), /* use st_mode? */
GIT_DIFFCAPS_TRUST_CTIME = (1 << 3), /* use st_ctime? */
GIT_DIFFCAPS_USE_DEV = (1 << 4), /* use st_dev? */
+ GIT_DIFFCAPS_TRUST_NANOSECS = (1 << 5), /* use stat time nanoseconds */
};
enum {
diff --git a/src/diff_output.c b/src/diff_output.c
index 64ff6b5be..be1ff56e7 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -593,6 +593,8 @@ static int diff_patch_load(
delta->new_file.flags |= GIT_DIFF_FLAG__NO_DATA;
break;
case GIT_DELTA_MODIFIED:
+ case GIT_DELTA_COPIED:
+ case GIT_DELTA_RENAMED:
break;
case GIT_DELTA_UNTRACKED:
delta->old_file.flags |= GIT_DIFF_FLAG__NO_DATA;
@@ -726,7 +728,7 @@ static int diff_patch_cb(void *priv, mmbuffer_t *bufs, int len)
char origin =
(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_DEL_EOFNL :
(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_ADD_EOFNL :
- GIT_DIFF_LINE_CONTEXT;
+ GIT_DIFF_LINE_CONTEXT_EOFNL;
if (ctxt->data_cb != NULL &&
ctxt->data_cb(patch->delta, &ctxt->range,
@@ -930,11 +932,13 @@ static int diff_patch_line_cb(
switch (line_origin) {
case GIT_DIFF_LINE_ADDITION:
+ case GIT_DIFF_LINE_DEL_EOFNL:
line->oldno = -1;
line->newno = patch->newno;
patch->newno += line->lines;
break;
case GIT_DIFF_LINE_DELETION:
+ case GIT_DIFF_LINE_ADD_EOFNL:
line->oldno = patch->oldno;
line->newno = -1;
patch->oldno += line->lines;
@@ -1611,6 +1615,12 @@ int git_diff_patch_line_stats(
return 0;
}
+static int diff_error_outofrange(const char *thing)
+{
+ giterr_set(GITERR_INVALID, "Diff patch %s index out of range", thing);
+ return GIT_ENOTFOUND;
+}
+
int git_diff_patch_get_hunk(
const git_diff_range **range,
const char **header,
@@ -1628,7 +1638,8 @@ int git_diff_patch_get_hunk(
if (header) *header = NULL;
if (header_len) *header_len = 0;
if (lines_in_hunk) *lines_in_hunk = 0;
- return GIT_ENOTFOUND;
+
+ return diff_error_outofrange("hunk");
}
hunk = &patch->hunks[hunk_idx];
@@ -1648,7 +1659,7 @@ int git_diff_patch_num_lines_in_hunk(
assert(patch);
if (hunk_idx >= patch->hunks_size)
- return GIT_ENOTFOUND;
+ return diff_error_outofrange("hunk");
else
return (int)patch->hunks[hunk_idx].line_count;
}
@@ -1665,15 +1676,20 @@ int git_diff_patch_get_line_in_hunk(
{
diff_patch_hunk *hunk;
diff_patch_line *line;
+ const char *thing;
assert(patch);
- if (hunk_idx >= patch->hunks_size)
+ if (hunk_idx >= patch->hunks_size) {
+ thing = "hunk";
goto notfound;
+ }
hunk = &patch->hunks[hunk_idx];
- if (line_of_hunk >= hunk->line_count)
+ if (line_of_hunk >= hunk->line_count) {
+ thing = "link";
goto notfound;
+ }
line = &patch->lines[hunk->line_start + line_of_hunk];
@@ -1692,16 +1708,16 @@ notfound:
if (old_lineno) *old_lineno = -1;
if (new_lineno) *new_lineno = -1;
- return GIT_ENOTFOUND;
+ return diff_error_outofrange(thing);
}
static int print_to_buffer_cb(
- const git_diff_delta *delta,
- const git_diff_range *range,
- char line_origin,
- const char *content,
- size_t content_len,
- void *payload)
+ const git_diff_delta *delta,
+ const git_diff_range *range,
+ char line_origin,
+ const char *content,
+ size_t content_len,
+ void *payload)
{
git_buf *output = payload;
GIT_UNUSED(delta); GIT_UNUSED(range); GIT_UNUSED(line_origin);
@@ -1781,16 +1797,16 @@ int git_diff__paired_foreach(
i_max = idx2head ? idx2head->deltas.length : 0;
j_max = wd2idx ? wd2idx->deltas.length : 0;
- /* Get appropriate strcmp function */
- strcomp = idx2head ? idx2head->strcomp : wd2idx ? wd2idx->strcomp : NULL;
+ /* Get appropriate strcmp function */
+ strcomp = idx2head ? idx2head->strcomp : wd2idx ? wd2idx->strcomp : NULL;
- /* Assert both iterators use matching ignore-case. If this function ever
- * supports merging diffs that are not sorted by the same function, then
- * it will need to spool and sort on one of the results before merging
- */
- if (idx2head && wd2idx) {
- assert(idx2head->strcomp == wd2idx->strcomp);
- }
+ /* Assert both iterators use matching ignore-case. If this function ever
+ * supports merging diffs that are not sorted by the same function, then
+ * it will need to spool and sort on one of the results before merging
+ */
+ if (idx2head && wd2idx) {
+ assert(idx2head->strcomp == wd2idx->strcomp);
+ }
for (i = 0, j = 0; i < i_max || j < j_max; ) {
i2h = idx2head ? GIT_VECTOR_GET(&idx2head->deltas,i) : NULL;
diff --git a/src/diff_tform.c b/src/diff_tform.c
index 201a0e896..84650a37b 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -178,7 +178,7 @@ int git_diff_find_similar__hashsig_for_file(
GIT_UNUSED(f);
error = git_hashsig_create_fromfile((git_hashsig **)out, path, opt);
-
+
if (error == GIT_EBUFS) {
error = 0;
giterr_clear();
@@ -195,7 +195,7 @@ int git_diff_find_similar__hashsig_for_buf(
GIT_UNUSED(f);
error = git_hashsig_create((git_hashsig **)out, buf, len, opt);
-
+
if (error == GIT_EBUFS) {
error = 0;
giterr_clear();
@@ -386,8 +386,12 @@ static int similarity_calc(
/* TODO: apply wd-to-odb filters to file data if necessary */
- if (!(error = git_buf_joinpath(
- &path, git_repository_workdir(diff->repo), file->path)))
+ if ((error = git_buf_joinpath(
+ &path, git_repository_workdir(diff->repo), file->path)) < 0)
+ return error;
+
+ /* if path is not a regular file, just skip this item */
+ if (git_path_isfile(path.ptr))
error = opts->metric->file_signature(
&cache[file_idx], file, path.ptr, opts->metric->payload);
@@ -398,8 +402,11 @@ static int similarity_calc(
/* TODO: add max size threshold a la diff? */
- if ((error = git_blob_lookup(&blob, diff->repo, &file->oid)) < 0)
- return error;
+ if (git_blob_lookup(&blob, diff->repo, &file->oid) < 0) {
+ /* if lookup fails, just skip this item in similarity calc */
+ giterr_clear();
+ return 0;
+ }
blobsize = git_blob_rawsize(blob);
if (!git__is_sizet(blobsize)) /* ? what to do ? */
@@ -437,7 +444,7 @@ static int similarity_measure(
return -1;
if (!cache[b_idx] && similarity_calc(diff, opts, b_idx, cache) < 0)
return -1;
-
+
/* some metrics may not wish to process this file (too big / too small) */
if (!cache[a_idx] || !cache[b_idx])
return 0;
diff --git a/src/fetch.c b/src/fetch.c
index 8ae34bddf..b5ec69777 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -34,10 +34,16 @@ static int filter_ref__cb(git_remote_head *head, void *payload)
if (!p->found_head && strcmp(head->name, GIT_HEAD_FILE) == 0)
p->found_head = 1;
- else if (git_remote__matching_refspec(p->remote, head->name))
+ else if (p->remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
+ /*
+ * If tagopt is --tags, then we only use the default
+ * tags refspec and ignore the remote's
+ */
+ if (git_refspec_src_matches(p->tagspec, head->name))
match = 1;
- else if (p->remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL &&
- git_refspec_src_matches(p->tagspec, head->name))
+ else
+ return 0;
+ } else if (git_remote__matching_refspec(p->remote, head->name))
match = 1;
if (!match)
diff --git a/src/fileops.c b/src/fileops.c
index d6244711f..98ab8efe3 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -444,7 +444,7 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
if (data->error < 0) {
if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 &&
- (errno == ENOTEMPTY || errno == EEXIST))
+ (errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY))
data->error = 0;
else
futils__error_cannot_rmdir(path->ptr, NULL);
@@ -480,7 +480,7 @@ static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
if (en == ENOENT || en == ENOTDIR) {
giterr_clear();
error = 0;
- } else if (en == ENOTEMPTY || en == EEXIST) {
+ } else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
giterr_clear();
error = GIT_ITEROVER;
} else {
@@ -988,8 +988,10 @@ int git_futils_filestamp_check(
if (stamp == NULL)
return 1;
- if (p_stat(path, &st) < 0)
+ if (p_stat(path, &st) < 0) {
+ giterr_set(GITERR_OS, "Could not stat '%s'", path);
return GIT_ENOTFOUND;
+ }
if (stamp->mtime == (git_time_t)st.st_mtime &&
stamp->size == (git_off_t)st.st_size &&
diff --git a/src/hash/hash_generic.h b/src/hash/hash_generic.h
index b731de8b3..6b60c98c4 100644
--- a/src/hash/hash_generic.h
+++ b/src/hash/hash_generic.h
@@ -11,9 +11,9 @@
#include "hash.h"
struct git_hash_ctx {
- unsigned long long size;
- unsigned int H[5];
- unsigned int W[16];
+ unsigned long long size;
+ unsigned int H[5];
+ unsigned int W[16];
};
#define git_hash_global_init() 0
diff --git a/src/hash/hash_win32.h b/src/hash/hash_win32.h
index daa769b59..2eee5ca79 100644
--- a/src/hash/hash_win32.h
+++ b/src/hash/hash_win32.h
@@ -48,10 +48,10 @@ struct hash_cryptoapi_prov {
/* Function declarations for CNG */
typedef NTSTATUS (WINAPI *hash_win32_cng_open_algorithm_provider_fn)(
- HANDLE /* BCRYPT_ALG_HANDLE */ *phAlgorithm,
- LPCWSTR pszAlgId,
- LPCWSTR pszImplementation,
- DWORD dwFlags);
+ HANDLE /* BCRYPT_ALG_HANDLE */ *phAlgorithm,
+ LPCWSTR pszAlgId,
+ LPCWSTR pszImplementation,
+ DWORD dwFlags);
typedef NTSTATUS (WINAPI *hash_win32_cng_get_property_fn)(
HANDLE /* BCRYPT_HANDLE */ hObject,
diff --git a/src/hashsig.c b/src/hashsig.c
index 3a75aaaed..ab8d8b3f0 100644
--- a/src/hashsig.c
+++ b/src/hashsig.c
@@ -365,4 +365,3 @@ int git_hashsig_compare(const git_hashsig *a, const git_hashsig *b)
return (hashsig_heap_compare(&a->mins, &b->mins) +
hashsig_heap_compare(&a->maxs, &b->maxs)) / 2;
}
-
diff --git a/src/index.c b/src/index.c
index d4aa475a9..f7f7133d6 100644
--- a/src/index.c
+++ b/src/index.c
@@ -104,11 +104,6 @@ static int index_find(size_t *at_pos, git_index *index, const char *path, int st
static void index_entry_free(git_index_entry *entry);
static void index_entry_reuc_free(git_index_reuc_entry *reuc);
-GIT_INLINE(int) index_entry_stage(const git_index_entry *entry)
-{
- return (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT;
-}
-
static int index_srch(const void *key, const void *array_member)
{
const struct entry_srch_key *srch_key = key;
@@ -118,7 +113,7 @@ static int index_srch(const void *key, const void *array_member)
ret = strcmp(srch_key->path, entry->path);
if (ret == 0)
- ret = srch_key->stage - index_entry_stage(entry);
+ ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry);
return ret;
}
@@ -132,7 +127,7 @@ static int index_isrch(const void *key, const void *array_member)
ret = strcasecmp(srch_key->path, entry->path);
if (ret == 0)
- ret = srch_key->stage - index_entry_stage(entry);
+ ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry);
return ret;
}
@@ -170,7 +165,7 @@ static int index_cmp(const void *a, const void *b)
diff = strcmp(entry_a->path, entry_b->path);
if (diff == 0)
- diff = (index_entry_stage(entry_a) - index_entry_stage(entry_b));
+ diff = (GIT_IDXENTRY_STAGE(entry_a) - GIT_IDXENTRY_STAGE(entry_b));
return diff;
}
@@ -184,7 +179,7 @@ static int index_icmp(const void *a, const void *b)
diff = strcasecmp(entry_a->path, entry_b->path);
if (diff == 0)
- diff = (index_entry_stage(entry_a) - index_entry_stage(entry_b));
+ diff = (GIT_IDXENTRY_STAGE(entry_a) - GIT_IDXENTRY_STAGE(entry_b));
return diff;
}
@@ -349,6 +344,7 @@ static void index_free(git_index *index)
{
git_index_clear(index);
git_vector_free(&index->entries);
+ git_vector_free(&index->names);
git_vector_free(&index->reuc);
git__free(index->index_file_path);
@@ -380,7 +376,7 @@ void git_index_clear(git_index *index)
git_index_reuc_clear(index);
git_index_name_clear(index);
-
+
git_futils_filestamp_set(&index->stamp, NULL);
git_tree_cache_free(index->tree);
@@ -546,8 +542,10 @@ const git_index_entry *git_index_get_bypath(
git_vector_sort(&index->entries);
- if (index_find(&pos, index, path, stage) < 0)
+ if (index_find(&pos, index, path, stage) < 0) {
+ giterr_set(GITERR_INDEX, "Index does not contain %s", path);
return NULL;
+ }
return git_index_get_byindex(index, pos);
}
@@ -718,7 +716,7 @@ static int index_insert(git_index *index, git_index_entry *entry, int replace)
entry->flags |= GIT_IDXENTRY_NAMEMASK;
/* look if an entry with this path already exists */
- if (!index_find(&position, index, entry->path, index_entry_stage(entry))) {
+ if (!index_find(&position, index, entry->path, GIT_IDXENTRY_STAGE(entry))) {
existing = (git_index_entry **)&index->entries.contents[position];
/* update filemode to existing values if stat is not trusted */
@@ -829,8 +827,11 @@ int git_index_remove(git_index *index, const char *path, int stage)
git_vector_sort(&index->entries);
- if (index_find(&position, index, path, stage) < 0)
+ if (index_find(&position, index, path, stage) < 0) {
+ giterr_set(GITERR_INDEX, "Index does not contain %s at stage %d",
+ path, stage);
return GIT_ENOTFOUND;
+ }
entry = git_vector_get(&index->entries, position);
if (entry != NULL)
@@ -863,7 +864,7 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage)
if (!entry || git__prefixcmp(entry->path, pfx.ptr) != 0)
break;
- if (index_entry_stage(entry) != stage) {
+ if (GIT_IDXENTRY_STAGE(entry) != stage) {
++pos;
continue;
}
@@ -1002,7 +1003,7 @@ int git_index_conflict_get(git_index_entry **ancestor_out,
if (index->entries_cmp_path(conflict_entry->path, path) != 0)
break;
- stage = index_entry_stage(conflict_entry);
+ stage = GIT_IDXENTRY_STAGE(conflict_entry);
switch (stage) {
case 3:
@@ -1044,7 +1045,7 @@ int git_index_conflict_remove(git_index *index, const char *path)
if (index->entries_cmp_path(conflict_entry->path, path) != 0)
break;
- if (index_entry_stage(conflict_entry) == 0) {
+ if (GIT_IDXENTRY_STAGE(conflict_entry) == 0) {
pos++;
continue;
}
@@ -1063,7 +1064,7 @@ static int index_conflicts_match(const git_vector *v, size_t idx)
{
git_index_entry *entry = git_vector_get(v, idx);
- if (index_entry_stage(entry) > 0) {
+ if (GIT_IDXENTRY_STAGE(entry) > 0) {
index_entry_free(entry);
return 1;
}
@@ -1085,7 +1086,7 @@ int git_index_has_conflicts(const git_index *index)
assert(index);
git_vector_foreach(&index->entries, i, entry) {
- if (index_entry_stage(entry) > 0)
+ if (GIT_IDXENTRY_STAGE(entry) > 0)
return 1;
}
@@ -1102,7 +1103,7 @@ const git_index_name_entry *git_index_name_get_byindex(
git_index *index, size_t n)
{
assert(index);
-
+
git_vector_sort(&index->names);
return git_vector_get(&index->names, n);
}
@@ -1116,7 +1117,7 @@ int git_index_name_add(git_index *index,
conflict_name = git__calloc(1, sizeof(git_index_name_entry));
GITERR_CHECK_ALLOC(conflict_name);
-
+
if (ancestor) {
conflict_name->ancestor = git__strdup(ancestor);
GITERR_CHECK_ALLOC(conflict_name->ancestor);
@@ -1131,7 +1132,7 @@ int git_index_name_add(git_index *index,
conflict_name->theirs = git__strdup(theirs);
GITERR_CHECK_ALLOC(conflict_name->theirs);
}
-
+
return git_vector_insert(&index->names, conflict_name);
}
@@ -1141,7 +1142,7 @@ void git_index_name_clear(git_index *index)
git_index_name_entry *conflict_name;
assert(index);
-
+
git_vector_foreach(&index->names, i, conflict_name) {
if (conflict_name->ancestor)
git__free(conflict_name->ancestor);
@@ -1154,7 +1155,7 @@ void git_index_name_clear(git_index *index)
git__free(conflict_name);
}
-
+
git_vector_clear(&index->names);
}
@@ -1282,8 +1283,9 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
size_t len;
int i;
- /* This gets called multiple times, the vector might already be initialized */
- if (index->reuc._alloc_size == 0 && git_vector_init(&index->reuc, 16, reuc_cmp) < 0)
+ /* If called multiple times, the vector might already be initialized */
+ if (index->reuc._alloc_size == 0 &&
+ git_vector_init(&index->reuc, 16, reuc_cmp) < 0)
return -1;
while (size) {
@@ -1293,12 +1295,9 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
if (size <= len)
return index_error_invalid("reading reuc entries");
- lost = git__malloc(sizeof(git_index_reuc_entry));
+ lost = git__calloc(1, sizeof(git_index_reuc_entry));
GITERR_CHECK_ALLOC(lost);
- if (git_vector_insert(&index->reuc, lost) < 0)
- return -1;
-
/* read NUL-terminated pathname for entry */
lost->path = git__strdup(buffer);
GITERR_CHECK_ALLOC(lost->path);
@@ -1336,6 +1335,10 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
size -= 20;
buffer += 20;
}
+
+ /* entry was read successfully - insert into reuc vector */
+ if (git_vector_insert(&index->reuc, lost) < 0)
+ return -1;
}
/* entries are guaranteed to be sorted on-disk */
@@ -1348,7 +1351,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
static int read_conflict_names(git_index *index, const char *buffer, size_t size)
{
size_t len;
-
+
/* This gets called multiple times, the vector might already be initialized */
if (index->names._alloc_size == 0 &&
git_vector_init(&index->names, 16, conflict_name_cmp) < 0)
@@ -1369,7 +1372,7 @@ static int read_conflict_names(git_index *index, const char *buffer, size_t size
\
buffer += len; \
size -= len;
-
+
while (size) {
git_index_name_entry *conflict_name = git__calloc(1, sizeof(git_index_name_entry));
GITERR_CHECK_ALLOC(conflict_name);
@@ -1377,17 +1380,17 @@ static int read_conflict_names(git_index *index, const char *buffer, size_t size
read_conflict_name(conflict_name->ancestor);
read_conflict_name(conflict_name->ours);
read_conflict_name(conflict_name->theirs);
-
+
if (git_vector_insert(&index->names, conflict_name) < 0)
return -1;
}
#undef read_conflict_name
-
+
/* entries are guaranteed to be sorted on-disk */
index->names.sorted = 1;
-
- return 0;
+
+ return 0;
}
static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size)
@@ -1718,7 +1721,7 @@ static int create_name_extension_data(git_buf *name_buf, git_index_name_entry *c
error = git_buf_put(name_buf, "\0", 1);
else
error = git_buf_put(name_buf, conflict_name->ancestor, strlen(conflict_name->ancestor) + 1);
-
+
if (error != 0)
goto on_error;
@@ -1747,20 +1750,20 @@ static int write_name_extension(git_index *index, git_filebuf *file)
struct index_extension extension;
size_t i;
int error = 0;
-
+
git_vector_foreach(out, i, conflict_name) {
if ((error = create_name_extension_data(&name_buf, conflict_name)) < 0)
goto done;
}
-
+
memset(&extension, 0x0, sizeof(struct index_extension));
memcpy(&extension.signature, INDEX_EXT_CONFLICT_NAME_SIG, 4);
extension.extension_size = (uint32_t)name_buf.size;
-
+
error = write_extension(file, &extension, &name_buf);
-
+
git_buf_free(&name_buf);
-
+
done:
return error;
}
@@ -1838,7 +1841,7 @@ static int write_index(git_index *index, git_filebuf *file)
/* write the rename conflict extension */
if (index->names.length > 0 && write_name_extension(index, file) < 0)
return -1;
-
+
/* write the reuc extension */
if (index->reuc.length > 0 && write_reuc_extension(index, file) < 0)
return -1;
@@ -1852,7 +1855,7 @@ static int write_index(git_index *index, git_filebuf *file)
int git_index_entry_stage(const git_index_entry *entry)
{
- return index_entry_stage(entry);
+ return GIT_IDXENTRY_STAGE(entry);
}
typedef struct read_tree_data {
diff --git a/src/indexer.c b/src/indexer.c
index 91b7ba5d9..1b5339f23 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -259,7 +259,7 @@ static int store_object(git_indexer_stream *idx)
entry = git__calloc(1, sizeof(*entry));
GITERR_CHECK_ALLOC(entry);
- pentry = git__malloc(sizeof(struct git_pack_entry));
+ pentry = git__calloc(1, sizeof(struct git_pack_entry));
GITERR_CHECK_ALLOC(pentry);
git_hash_final(&oid, ctx);
@@ -328,7 +328,7 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
return -1;
}
- pentry = git__malloc(sizeof(struct git_pack_entry));
+ pentry = git__calloc(1, sizeof(struct git_pack_entry));
GITERR_CHECK_ALLOC(pentry);
git_oid_cpy(&pentry->sha1, &oid);
diff --git a/src/merge.c b/src/merge.c
index 56290bfad..de5d65ac0 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -127,6 +127,7 @@ int git_merge_base_many(git_oid *out, git_repository *repo, const git_oid input_
goto cleanup;
if (!result) {
+ giterr_set(GITERR_MERGE, "No merge base found");
error = GIT_ENOTFOUND;
goto cleanup;
}
@@ -172,7 +173,7 @@ int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const
if (!result) {
git_revwalk_free(walk);
- giterr_clear();
+ giterr_set(GITERR_MERGE, "No merge base found");
return GIT_ENOTFOUND;
}
@@ -369,14 +370,14 @@ static int merge_conflict_resolve_trivial(
if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE ||
conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
return 0;
-
+
if (conflict->our_status == GIT_DELTA_RENAMED ||
conflict->their_status == GIT_DELTA_RENAMED)
return 0;
ours_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry);
theirs_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry);
-
+
ours_changed = (conflict->our_status != GIT_DELTA_UNMODIFIED);
theirs_changed = (conflict->their_status != GIT_DELTA_UNMODIFIED);
ours_theirs_differ = ours_changed && theirs_changed &&
@@ -432,7 +433,7 @@ static int merge_conflict_resolve_trivial(
*resolved = 1;
/* Note: trivial resolution does not update the REUC. */
-
+
return error;
}
@@ -485,9 +486,9 @@ static int merge_conflict_resolve_one_renamed(
int ours_changed, theirs_changed;
git_index_entry *merged;
int error = 0;
-
+
assert(resolved && diff_list && conflict);
-
+
*resolved = 0;
if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ||
@@ -496,7 +497,7 @@ static int merge_conflict_resolve_one_renamed(
ours_renamed = (conflict->our_status == GIT_DELTA_RENAMED);
theirs_renamed = (conflict->their_status == GIT_DELTA_RENAMED);
-
+
if (!ours_renamed && !theirs_renamed)
return 0;
@@ -508,7 +509,7 @@ static int merge_conflict_resolve_one_renamed(
ours_changed = (git_oid__cmp(&conflict->ancestor_entry.oid, &conflict->our_entry.oid) != 0);
theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.oid, &conflict->their_entry.oid) != 0);
-
+
/* if both are modified (and not to a common target) require a merge */
if (ours_changed && theirs_changed &&
git_oid__cmp(&conflict->our_entry.oid, &conflict->their_entry.oid) != 0)
@@ -516,7 +517,7 @@ static int merge_conflict_resolve_one_renamed(
if ((merged = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry))) == NULL)
return -1;
-
+
if (ours_changed)
memcpy(merged, &conflict->our_entry, sizeof(git_index_entry));
else
@@ -526,12 +527,12 @@ static int merge_conflict_resolve_one_renamed(
merged->path = conflict->our_entry.path;
else
merged->path = conflict->their_entry.path;
-
+
*resolved = 1;
-
+
git_vector_insert(&diff_list->staged, merged);
git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
-
+
return error;
}
@@ -549,11 +550,11 @@ static int merge_conflict_resolve_automerge(
git_odb *odb = NULL;
git_oid automerge_oid;
int error = 0;
-
+
assert(resolved && diff_list && conflict);
-
+
*resolved = 0;
-
+
if (automerge_flags == GIT_MERGE_AUTOMERGE_NONE)
return 0;
@@ -584,7 +585,7 @@ static int merge_conflict_resolve_automerge(
!result.automergeable ||
(error = git_odb_write(&automerge_oid, odb, result.data, result.len, GIT_OBJ_BLOB)) < 0)
goto done;
-
+
if ((index_entry = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry))) == NULL)
GITERR_CHECK_ALLOC(index_entry);
@@ -594,7 +595,7 @@ static int merge_conflict_resolve_automerge(
index_entry->file_size = result.len;
index_entry->mode = result.mode;
git_oid_cpy(&index_entry->oid, &automerge_oid);
-
+
git_vector_insert(&diff_list->staged, index_entry);
git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
@@ -606,7 +607,7 @@ done:
git_merge_file_input_free(&theirs);
git_merge_file_result_free(&result);
git_odb_free(odb);
-
+
return error;
}
@@ -618,16 +619,16 @@ static int merge_conflict_resolve(
{
int resolved = 0;
int error = 0;
-
+
*out = 0;
-
+
if ((error = merge_conflict_resolve_trivial(&resolved, diff_list, conflict)) < 0)
goto done;
if (automerge_flags != GIT_MERGE_AUTOMERGE_NONE) {
if (!resolved && (error = merge_conflict_resolve_one_removed(&resolved, diff_list, conflict)) < 0)
goto done;
-
+
if (!resolved && (error = merge_conflict_resolve_one_renamed(&resolved, diff_list, conflict)) < 0)
goto done;
@@ -636,7 +637,7 @@ static int merge_conflict_resolve(
}
*out = resolved;
-
+
done:
return error;
}
@@ -665,7 +666,7 @@ static int index_entry_similarity_exact(
if (git_oid__cmp(&a->oid, &b->oid) == 0)
return 100;
-
+
return 0;
}
@@ -679,28 +680,28 @@ static int index_entry_similarity_calc(
git_diff_file diff_file = {{{0}}};
git_off_t blobsize;
int error;
-
+
*out = NULL;
if ((error = git_blob_lookup(&blob, repo, &entry->oid)) < 0)
return error;
-
+
git_oid_cpy(&diff_file.oid, &entry->oid);
diff_file.path = entry->path;
diff_file.size = entry->file_size;
diff_file.mode = entry->mode;
diff_file.flags = 0;
-
+
blobsize = git_blob_rawsize(blob);
/* file too big for rename processing */
if (!git__is_sizet(blobsize))
return 0;
-
+
error = opts->metric->buffer_signature(out, &diff_file,
git_blob_rawcontent(blob), (size_t)blobsize,
opts->metric->payload);
-
+
git_blob_free(blob);
return error;
@@ -717,16 +718,16 @@ static int index_entry_similarity_inexact(
{
int score = 0;
int error = 0;
-
+
if (GIT_MODE_TYPE(a->mode) != GIT_MODE_TYPE(b->mode))
return 0;
-
+
/* update signature cache if needed */
if (!cache[a_idx] && (error = index_entry_similarity_calc(&cache[a_idx], repo, a, opts)) < 0)
return error;
if (!cache[b_idx] && (error = index_entry_similarity_calc(&cache[b_idx], repo, b, opts)) < 0)
return error;
-
+
/* some metrics may not wish to process this file (too big / too small) */
if (!cache[a_idx] || !cache[b_idx])
return 0;
@@ -735,13 +736,13 @@ static int index_entry_similarity_inexact(
if (opts->metric->similarity(
&score, cache[a_idx], cache[b_idx], opts->metric->payload) < 0)
return -1;
-
+
/* clip score */
if (score < 0)
score = 0;
else if (score > 100)
score = 100;
-
+
return score;
}
@@ -757,7 +758,7 @@ static int merge_diff_mark_similarity(
size_t i, j;
git_merge_diff *conflict_src, *conflict_tgt;
int similarity;
-
+
git_vector_foreach(&diff_list->conflicts, i, conflict_src) {
/* Items can be the source of a rename iff they have an item in the
* ancestor slot and lack an item in the ours or theirs slot. */
@@ -765,63 +766,63 @@ static int merge_diff_mark_similarity(
(GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry) &&
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)))
continue;
-
+
git_vector_foreach(&diff_list->conflicts, j, conflict_tgt) {
size_t our_idx = diff_list->conflicts.length + j;
size_t their_idx = (diff_list->conflicts.length * 2) + j;
-
+
if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->ancestor_entry))
continue;
-
+
if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->our_entry) &&
!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry)) {
similarity = similarity_fn(repo, &conflict_src->ancestor_entry, i, &conflict_tgt->our_entry, our_idx, cache, opts);
-
+
if (similarity == GIT_EBUFS)
- continue;
+ continue;
else if (similarity < 0)
return similarity;
-
+
if (similarity > similarity_ours[i].similarity &&
similarity > similarity_ours[j].similarity) {
/* Clear previous best similarity */
if (similarity_ours[i].similarity > 0)
similarity_ours[similarity_ours[i].other_idx].similarity = 0;
-
+
if (similarity_ours[j].similarity > 0)
similarity_ours[similarity_ours[j].other_idx].similarity = 0;
-
+
similarity_ours[i].similarity = similarity;
similarity_ours[i].other_idx = j;
-
+
similarity_ours[j].similarity = similarity;
similarity_ours[j].other_idx = i;
}
}
-
+
if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->their_entry) &&
!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)) {
similarity = similarity_fn(repo, &conflict_src->ancestor_entry, i, &conflict_tgt->their_entry, their_idx, cache, opts);
-
+
if (similarity > similarity_theirs[i].similarity &&
similarity > similarity_theirs[j].similarity) {
/* Clear previous best similarity */
if (similarity_theirs[i].similarity > 0)
similarity_theirs[similarity_theirs[i].other_idx].similarity = 0;
-
+
if (similarity_theirs[j].similarity > 0)
similarity_theirs[similarity_theirs[j].other_idx].similarity = 0;
-
+
similarity_theirs[i].similarity = similarity;
similarity_theirs[i].other_idx = j;
-
+
similarity_theirs[j].similarity = similarity;
similarity_theirs[j].other_idx = i;
}
}
}
}
-
+
return 0;
}
@@ -856,13 +857,13 @@ static void merge_diff_mark_rename_conflict(
const git_merge_tree_opts *opts)
{
git_merge_diff *ours_source = NULL, *theirs_source = NULL;
-
+
if (ours_renamed)
ours_source = diff_list->conflicts.contents[ours_source_idx];
-
+
if (theirs_renamed)
theirs_source = diff_list->conflicts.contents[theirs_source_idx];
-
+
/* Detect 2->1 conflicts */
if (ours_renamed && theirs_renamed) {
/* Both renamed to the same target name. */
@@ -876,30 +877,30 @@ static void merge_diff_mark_rename_conflict(
/* If our source was also renamed in theirs, this is a 1->2 */
if (similarity_theirs[ours_source_idx].similarity >= opts->rename_threshold)
ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2;
-
+
else if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->their_entry)) {
ours_source->type = GIT_MERGE_DIFF_RENAMED_ADDED;
target->type = GIT_MERGE_DIFF_RENAMED_ADDED;
}
-
+
else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(ours_source->their_entry))
ours_source->type = GIT_MERGE_DIFF_RENAMED_DELETED;
-
+
else if (ours_source->type == GIT_MERGE_DIFF_MODIFIED_DELETED)
ours_source->type = GIT_MERGE_DIFF_RENAMED_MODIFIED;
} else if (theirs_renamed) {
/* If their source was also renamed in ours, this is a 1->2 */
if (similarity_ours[theirs_source_idx].similarity >= opts->rename_threshold)
theirs_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2;
-
+
else if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->our_entry)) {
theirs_source->type = GIT_MERGE_DIFF_RENAMED_ADDED;
target->type = GIT_MERGE_DIFF_RENAMED_ADDED;
}
-
+
else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(theirs_source->our_entry))
theirs_source->type = GIT_MERGE_DIFF_RENAMED_DELETED;
-
+
else if (theirs_source->type == GIT_MERGE_DIFF_MODIFIED_DELETED)
theirs_source->type = GIT_MERGE_DIFF_RENAMED_MODIFIED;
}
@@ -914,7 +915,7 @@ GIT_INLINE(void) merge_diff_coalesce_rename(
/* Coalesce the rename target into the rename source. */
memcpy(source_entry, target_entry, sizeof(git_index_entry));
*source_status = GIT_DELTA_RENAMED;
-
+
memset(target_entry, 0x0, sizeof(git_index_entry));
*target_status = GIT_DELTA_UNMODIFIED;
}
@@ -929,50 +930,50 @@ static void merge_diff_list_coalesce_renames(
bool ours_renamed = 0, theirs_renamed = 0;
size_t ours_source_idx = 0, theirs_source_idx = 0;
git_merge_diff *ours_source, *theirs_source, *target;
-
+
for (i = 0; i < diff_list->conflicts.length; i++) {
target = diff_list->conflicts.contents[i];
-
+
ours_renamed = 0;
theirs_renamed = 0;
-
+
if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->our_entry) &&
similarity_ours[i].similarity >= opts->rename_threshold) {
ours_source_idx = similarity_ours[i].other_idx;
-
+
ours_source = diff_list->conflicts.contents[ours_source_idx];
-
+
merge_diff_coalesce_rename(
&ours_source->our_entry,
&ours_source->our_status,
&target->our_entry,
&target->our_status);
-
+
similarity_ours[ours_source_idx].similarity = 0;
similarity_ours[i].similarity = 0;
-
+
ours_renamed = 1;
}
-
+
/* insufficient to determine direction */
if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->their_entry) &&
similarity_theirs[i].similarity >= opts->rename_threshold) {
theirs_source_idx = similarity_theirs[i].other_idx;
-
+
theirs_source = diff_list->conflicts.contents[theirs_source_idx];
-
+
merge_diff_coalesce_rename(
&theirs_source->their_entry,
&theirs_source->their_status,
&target->their_entry,
&target->their_status);
-
+
similarity_theirs[theirs_source_idx].similarity = 0;
similarity_theirs[i].similarity = 0;
-
+
theirs_renamed = 1;
}
-
+
merge_diff_mark_rename_conflict(diff_list,
similarity_ours, ours_renamed, ours_source_idx,
similarity_theirs, theirs_renamed, theirs_source_idx,
@@ -983,7 +984,7 @@ static void merge_diff_list_coalesce_renames(
static int merge_diff_empty(const git_vector *conflicts, size_t idx)
{
git_merge_diff *conflict = conflicts->contents[idx];
-
+
return (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) &&
!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) &&
!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry));
@@ -999,7 +1000,7 @@ static void merge_diff_list_count_candidates(
*src_count = 0;
*tgt_count = 0;
-
+
git_vector_foreach(&diff_list->conflicts, i, entry) {
if (GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry) &&
(!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->our_entry) ||
@@ -1020,20 +1021,20 @@ int git_merge_diff_list__find_renames(
size_t cache_size = 0;
size_t src_count, tgt_count, i;
int error = 0;
-
+
assert(diff_list && opts);
-
+
if ((opts->flags & GIT_MERGE_TREE_FIND_RENAMES) == 0)
return 0;
-
+
similarity_ours = git__calloc(diff_list->conflicts.length,
sizeof(struct merge_diff_similarity));
GITERR_CHECK_ALLOC(similarity_ours);
-
+
similarity_theirs = git__calloc(diff_list->conflicts.length,
sizeof(struct merge_diff_similarity));
GITERR_CHECK_ALLOC(similarity_theirs);
-
+
/* Calculate similarity between items that were deleted from the ancestor
* and added in the other branch.
*/
@@ -1047,7 +1048,7 @@ int git_merge_diff_list__find_renames(
GITERR_CHECK_ALLOC(cache);
merge_diff_list_count_candidates(diff_list, &src_count, &tgt_count);
-
+
if (src_count > opts->target_limit || tgt_count > opts->target_limit) {
/* TODO: report! */
} else {
@@ -1062,7 +1063,7 @@ int git_merge_diff_list__find_renames(
* into the old name.
*/
merge_diff_list_coalesce_renames(diff_list, similarity_ours, similarity_theirs, opts);
-
+
/* And remove any entries that were merged and are now empty. */
git_vector_remove_matching(&diff_list->conflicts, merge_diff_empty);
@@ -1093,7 +1094,7 @@ GIT_INLINE(const char *) merge_diff_path(
return conflict->our_entry.path;
else if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
return conflict->their_entry.path;
-
+
return NULL;
}
@@ -1105,7 +1106,7 @@ GIT_INLINE(bool) merge_diff_any_side_added_or_modified(
conflict->their_status == GIT_DELTA_ADDED ||
conflict->their_status == GIT_DELTA_MODIFIED)
return true;
-
+
return false;
}
@@ -1113,11 +1114,11 @@ GIT_INLINE(bool) path_is_prefixed(const char *parent, const char *child)
{
size_t child_len = strlen(child);
size_t parent_len = strlen(parent);
-
+
if (child_len < parent_len ||
strncmp(parent, child, parent_len) != 0)
return 0;
-
+
return (child[parent_len] == '/');
}
@@ -1126,7 +1127,7 @@ GIT_INLINE(int) merge_diff_detect_df_conflict(
git_merge_diff *conflict)
{
const char *cur_path = merge_diff_path(conflict);
-
+
/* Determine if this is a D/F conflict or the child of one */
if (df_data->df_path &&
path_is_prefixed(df_data->df_path, cur_path))
@@ -1138,14 +1139,14 @@ GIT_INLINE(int) merge_diff_detect_df_conflict(
merge_diff_any_side_added_or_modified(conflict) &&
path_is_prefixed(df_data->prev_path, cur_path)) {
conflict->type = GIT_MERGE_DIFF_DF_CHILD;
-
+
df_data->prev_conflict->type = GIT_MERGE_DIFF_DIRECTORY_FILE;
df_data->df_path = df_data->prev_path;
}
-
+
df_data->prev_path = cur_path;
df_data->prev_conflict = conflict;
-
+
return 0;
}
@@ -1171,7 +1172,7 @@ GIT_INLINE(int) merge_diff_detect_type(
conflict->type = GIT_MERGE_DIFF_MODIFIED_DELETED;
else
conflict->type = GIT_MERGE_DIFF_NONE;
-
+
return 0;
}
@@ -1182,11 +1183,11 @@ GIT_INLINE(int) index_entry_dup(
{
if (src != NULL) {
memcpy(out, src, sizeof(git_index_entry));
-
+
if ((out->path = git_pool_strdup(pool, src->path)) == NULL)
return -1;
}
-
+
return 0;
}
@@ -1207,7 +1208,7 @@ GIT_INLINE(int) merge_delta_type_from_index_entries(
else if (git_oid__cmp(&ancestor->oid, &other->oid) ||
ancestor->mode != other->mode)
return GIT_DELTA_MODIFIED;
-
+
return GIT_DELTA_UNMODIFIED;
}
@@ -1217,20 +1218,20 @@ static git_merge_diff *merge_diff_from_index_entries(
{
git_merge_diff *conflict;
git_pool *pool = &diff_list->pool;
-
+
if ((conflict = git_pool_malloc(pool, sizeof(git_merge_diff))) == NULL)
return NULL;
-
+
if (index_entry_dup(&conflict->ancestor_entry, pool, entries[TREE_IDX_ANCESTOR]) < 0 ||
index_entry_dup(&conflict->our_entry, pool, entries[TREE_IDX_OURS]) < 0 ||
index_entry_dup(&conflict->their_entry, pool, entries[TREE_IDX_THEIRS]) < 0)
return NULL;
-
+
conflict->our_status = merge_delta_type_from_index_entries(
entries[TREE_IDX_ANCESTOR], entries[TREE_IDX_OURS]);
conflict->their_status = merge_delta_type_from_index_entries(
entries[TREE_IDX_ANCESTOR], entries[TREE_IDX_THEIRS]);
-
+
return conflict;
}
@@ -1242,13 +1243,13 @@ static int merge_index_insert_conflict(
const git_index_entry *tree_items[3])
{
git_merge_diff *conflict;
-
+
if ((conflict = merge_diff_from_index_entries(diff_list, tree_items)) == NULL ||
merge_diff_detect_type(conflict) < 0 ||
merge_diff_detect_df_conflict(merge_df_data, conflict) < 0 ||
git_vector_insert(&diff_list->conflicts, conflict) < 0)
return -1;
-
+
return 0;
}
@@ -1258,13 +1259,13 @@ static int merge_index_insert_unmodified(
{
int error = 0;
git_index_entry *entry;
-
+
entry = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry));
GITERR_CHECK_ALLOC(entry);
-
+
if ((error = index_entry_dup(entry, &diff_list->pool, tree_items[0])) >= 0)
error = git_vector_insert(&diff_list->staged, entry);
-
+
return error;
}
@@ -1281,40 +1282,40 @@ int git_merge_diff_list__find_differences(
int cur_item_modified;
size_t i, j;
int error = 0;
-
+
assert(diff_list && our_tree && their_tree);
if ((error = git_iterator_for_tree(&iterators[TREE_IDX_ANCESTOR], (git_tree *)ancestor_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
(error = git_iterator_for_tree(&iterators[TREE_IDX_OURS], (git_tree *)our_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
(error = git_iterator_for_tree(&iterators[TREE_IDX_THEIRS], (git_tree *)their_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
goto done;
-
+
/* Set up the iterators */
for (i = 0; i < 3; i++) {
if ((error = git_iterator_current(&items[i], iterators[i])) < 0)
goto done;
}
-
+
while (true) {
for (i = 0; i < 3; i++)
cur_items[i] = NULL;
best_cur_item = NULL;
cur_item_modified = 0;
-
+
/* Find the next path(s) to consume from each iterator */
for (i = 0; i < 3; i++) {
if (items[i] == NULL) {
cur_item_modified = 1;
continue;
}
-
+
if (best_cur_item == NULL) {
best_cur_item = items[i];
cur_items[i] = items[i];
} else {
int path_diff = entry_compare(items[i], best_cur_item);
-
+
if (path_diff < 0) {
/*
* Found an item that sorts before our current item, make
@@ -1331,21 +1332,21 @@ int git_merge_diff_list__find_differences(
cur_item_modified = 1;
} else if (path_diff == 0) {
cur_items[i] = items[i];
-
+
if (!cur_item_modified)
cur_item_modified = index_entry_cmp(best_cur_item, items[i]);
}
}
}
-
+
if (best_cur_item == NULL)
break;
-
+
if (cur_item_modified)
error = merge_index_insert_conflict(diff_list, &df_data, cur_items);
else
error = merge_index_insert_unmodified(diff_list, cur_items);
-
+
/* Advance each iterator that participated */
for (i = 0; i < 3; i++) {
if (cur_items[i] != NULL &&
@@ -1353,29 +1354,29 @@ int git_merge_diff_list__find_differences(
goto done;
}
}
-
+
done:
for (i = 0; i < 3; i++)
git_iterator_free(iterators[i]);
-
+
return error;
}
git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo)
{
git_merge_diff_list *diff_list = git__calloc(1, sizeof(git_merge_diff_list));
-
+
if (diff_list == NULL)
return NULL;
-
+
diff_list->repo = repo;
-
+
if (git_vector_init(&diff_list->staged, 0, NULL) < 0 ||
git_vector_init(&diff_list->conflicts, 0, NULL) < 0 ||
git_vector_init(&diff_list->resolved, 0, NULL) < 0 ||
git_pool_init(&diff_list->pool, 1, 0) < 0)
return NULL;
-
+
return diff_list;
}
@@ -1386,48 +1387,48 @@ static int merge_tree_normalize_opts(
{
git_config *cfg = NULL;
int error = 0;
-
+
assert(repo && opts);
-
+
if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
return error;
-
+
if (given != NULL)
memcpy(opts, given, sizeof(git_merge_tree_opts));
else {
git_merge_tree_opts init = GIT_MERGE_TREE_OPTS_INIT;
memcpy(opts, &init, sizeof(init));
-
+
opts->flags = GIT_MERGE_TREE_FIND_RENAMES;
opts->rename_threshold = GIT_MERGE_TREE_RENAME_THRESHOLD;
}
-
+
if (!opts->target_limit) {
int32_t limit = 0;
-
+
opts->target_limit = GIT_MERGE_TREE_TARGET_LIMIT;
-
+
if (git_config_get_int32(&limit, cfg, "merge.renameLimit") < 0) {
giterr_clear();
-
+
if (git_config_get_int32(&limit, cfg, "diff.renameLimit") < 0)
giterr_clear();
}
-
+
if (limit > 0)
opts->target_limit = limit;
}
-
+
/* assign the internal metric with whitespace flag as payload */
if (!opts->metric) {
opts->metric = git__malloc(sizeof(git_diff_similarity_metric));
GITERR_CHECK_ALLOC(opts->metric);
-
+
opts->metric->file_signature = git_diff_find_similar__hashsig_for_file;
opts->metric->buffer_signature = git_diff_find_similar__hashsig_for_buf;
opts->metric->free_signature = git_diff_find_similar__hashsig_free;
opts->metric->similarity = git_diff_find_similar__calc_similarity;
-
+
if (opts->flags & GIT_DIFF_FIND_IGNORE_WHITESPACE)
opts->metric->payload = (void *)GIT_HASHSIG_IGNORE_WHITESPACE;
else if (opts->flags & GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE)
@@ -1435,7 +1436,7 @@ static int merge_tree_normalize_opts(
else
opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
}
-
+
return 0;
}
@@ -1449,20 +1450,20 @@ static int merge_index_insert_reuc(
int mode[3] = { 0, 0, 0 };
git_oid const *oid[3] = { NULL, NULL, NULL };
size_t i;
-
+
if (!GIT_MERGE_INDEX_ENTRY_EXISTS(*entry))
return 0;
-
+
if ((reuc = git_index_reuc_get_bypath(index, entry->path)) != NULL) {
for (i = 0; i < 3; i++) {
mode[i] = reuc->mode[i];
oid[i] = &reuc->oid[i];
}
}
-
+
mode[idx] = entry->mode;
oid[idx] = &entry->oid;
-
+
return git_index_reuc_add(index, entry->path,
mode[0], oid[0], mode[1], oid[1], mode[2], oid[2]);
}
@@ -1474,58 +1475,58 @@ int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
git_index_entry *entry;
git_merge_diff *conflict;
int error = 0;
-
+
*out = NULL;
-
+
if ((error = git_index_new(&index)) < 0)
return error;
-
+
git_vector_foreach(&diff_list->staged, i, entry) {
if ((error = git_index_add(index, entry)) < 0)
goto on_error;
}
-
+
git_vector_foreach(&diff_list->conflicts, i, conflict) {
const git_index_entry *ancestor =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
&conflict->ancestor_entry : NULL;
-
+
const git_index_entry *ours =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
&conflict->our_entry : NULL;
-
+
const git_index_entry *theirs =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
&conflict->their_entry : NULL;
-
+
if ((error = git_index_conflict_add(index, ancestor, ours, theirs)) < 0)
goto on_error;
}
-
+
/* Add each rename entry to the rename portion of the index. */
git_vector_foreach(&diff_list->conflicts, i, conflict) {
const char *ancestor_path, *our_path, *their_path;
-
+
if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry))
continue;
-
+
ancestor_path = conflict->ancestor_entry.path;
-
+
our_path =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
conflict->our_entry.path : NULL;
-
+
their_path =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
conflict->their_entry.path : NULL;
-
+
if ((our_path && strcmp(ancestor_path, our_path) != 0) ||
(their_path && strcmp(ancestor_path, their_path) != 0)) {
if ((error = git_index_name_add(index, ancestor_path, our_path, their_path)) < 0)
goto on_error;
}
}
-
+
/* Add each entry in the resolved conflict to the REUC independently, since
* the paths may differ due to renames. */
git_vector_foreach(&diff_list->resolved, i, conflict) {
@@ -1536,7 +1537,7 @@ int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
const git_index_entry *ours =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
&conflict->our_entry : NULL;
-
+
const git_index_entry *theirs =
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
&conflict->their_entry : NULL;
@@ -1544,22 +1545,22 @@ int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
if (ancestor != NULL &&
(error = merge_index_insert_reuc(index, TREE_IDX_ANCESTOR, ancestor)) < 0)
goto on_error;
-
+
if (ours != NULL &&
(error = merge_index_insert_reuc(index, TREE_IDX_OURS, ours)) < 0)
goto on_error;
-
+
if (theirs != NULL &&
(error = merge_index_insert_reuc(index, TREE_IDX_THEIRS, theirs)) < 0)
goto on_error;
}
-
+
*out = index;
return 0;
-
+
on_error:
git_index_free(index);
-
+
return error;
}
@@ -1581,33 +1582,33 @@ int git_merge_trees(
assert(out && repo && our_tree && their_tree);
*out = NULL;
-
+
if ((error = merge_tree_normalize_opts(repo, &opts, given_opts)) < 0)
return error;
diff_list = git_merge_diff_list__alloc(repo);
GITERR_CHECK_ALLOC(diff_list);
-
+
if ((error = git_merge_diff_list__find_differences(diff_list, ancestor_tree, our_tree, their_tree)) < 0 ||
(error = git_merge_diff_list__find_renames(repo, diff_list, &opts)) < 0)
goto done;
-
+
memcpy(&changes, &diff_list->conflicts, sizeof(git_vector));
git_vector_clear(&diff_list->conflicts);
-
+
git_vector_foreach(&changes, i, conflict) {
int resolved = 0;
-
+
if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.automerge_flags)) < 0)
goto done;
-
+
if (!resolved)
git_vector_insert(&diff_list->conflicts, conflict);
}
-
+
if (!given_opts || !given_opts->metric)
git__free(opts.metric);
-
+
error = index_from_diff_list(out, diff_list);
done:
@@ -1620,11 +1621,10 @@ void git_merge_diff_list__free(git_merge_diff_list *diff_list)
{
if (!diff_list)
return;
-
+
git_vector_free(&diff_list->staged);
git_vector_free(&diff_list->conflicts);
git_vector_free(&diff_list->resolved);
git_pool_clear(&diff_list->pool);
git__free(diff_list);
}
-
diff --git a/src/merge.h b/src/merge.h
index 6307d1569..50538b12b 100644
--- a/src/merge.h
+++ b/src/merge.h
@@ -24,87 +24,87 @@
typedef enum {
/* No conflict - a change only occurs in one branch. */
GIT_MERGE_DIFF_NONE = 0,
-
+
/* Occurs when a file is modified in both branches. */
GIT_MERGE_DIFF_BOTH_MODIFIED = (1 << 0),
-
+
/* Occurs when a file is added in both branches. */
GIT_MERGE_DIFF_BOTH_ADDED = (1 << 1),
-
+
/* Occurs when a file is deleted in both branches. */
GIT_MERGE_DIFF_BOTH_DELETED = (1 << 2),
-
+
/* Occurs when a file is modified in one branch and deleted in the other. */
GIT_MERGE_DIFF_MODIFIED_DELETED = (1 << 3),
-
+
/* Occurs when a file is renamed in one branch and modified in the other. */
GIT_MERGE_DIFF_RENAMED_MODIFIED = (1 << 4),
-
+
/* Occurs when a file is renamed in one branch and deleted in the other. */
GIT_MERGE_DIFF_RENAMED_DELETED = (1 << 5),
-
+
/* Occurs when a file is renamed in one branch and a file with the same
* name is added in the other. Eg, A->B and new file B. Core git calls
* this a "rename/delete". */
GIT_MERGE_DIFF_RENAMED_ADDED = (1 << 6),
-
+
/* Occurs when both a file is renamed to the same name in the ours and
* theirs branches. Eg, A->B and A->B in both. Automergeable. */
GIT_MERGE_DIFF_BOTH_RENAMED = (1 << 7),
-
+
/* Occurs when a file is renamed to different names in the ours and theirs
* branches. Eg, A->B and A->C. */
GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2 = (1 << 8),
-
+
/* Occurs when two files are renamed to the same name in the ours and
* theirs branches. Eg, A->C and B->C. */
GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 = (1 << 9),
-
+
/* Occurs when an item at a path in one branch is a directory, and an
* item at the same path in a different branch is a file. */
GIT_MERGE_DIFF_DIRECTORY_FILE = (1 << 10),
-
+
/* The child of a folder that is in a directory/file conflict. */
GIT_MERGE_DIFF_DF_CHILD = (1 << 11),
} git_merge_diff_type_t;
typedef struct {
- git_repository *repo;
- git_pool pool;
-
- /* Vector of git_index_entry that represent the merged items that
+ git_repository *repo;
+ git_pool pool;
+
+ /* Vector of git_index_entry that represent the merged items that
* have been staged, either because only one side changed, or because
* the two changes were non-conflicting and mergeable. These items
* will be written as staged entries in the main index.
*/
- git_vector staged;
-
- /* Vector of git_merge_diff entries that represent the conflicts that
+ git_vector staged;
+
+ /* Vector of git_merge_diff entries that represent the conflicts that
* have not been automerged. These items will be written to high-stage
* entries in the main index.
*/
- git_vector conflicts;
-
- /* Vector of git_merge_diff that have been automerged. These items
+ git_vector conflicts;
+
+ /* Vector of git_merge_diff that have been automerged. These items
* will be written to the REUC when the index is produced.
*/
- git_vector resolved;
+ git_vector resolved;
} git_merge_diff_list;
/**
* Description of changes to one file across three trees.
*/
typedef struct {
- git_merge_diff_type_t type;
-
- git_index_entry ancestor_entry;
-
- git_index_entry our_entry;
- git_delta_t our_status;
-
- git_index_entry their_entry;
- git_delta_t their_status;
+ git_merge_diff_type_t type;
+
+ git_index_entry ancestor_entry;
+
+ git_index_entry our_entry;
+ git_delta_t our_status;
+
+ git_index_entry their_entry;
+ git_delta_t their_status;
} git_merge_diff;
int git_merge__bases_many(
diff --git a/src/merge_file.c b/src/merge_file.c
index 4b3f3730b..c3477ccb9 100644
--- a/src/merge_file.c
+++ b/src/merge_file.c
@@ -28,12 +28,12 @@ GIT_INLINE(const char *) merge_file_best_path(
return NULL;
}
-
+
if (strcmp(ancestor->path, ours->path) == 0)
return theirs->path;
else if(strcmp(ancestor->path, theirs->path) == 0)
return ours->path;
-
+
return NULL;
}
@@ -51,15 +51,15 @@ GIT_INLINE(int) merge_file_best_mode(
if (ours->mode == GIT_FILEMODE_BLOB_EXECUTABLE ||
theirs->mode == GIT_FILEMODE_BLOB_EXECUTABLE)
return GIT_FILEMODE_BLOB_EXECUTABLE;
-
+
return GIT_FILEMODE_BLOB;
}
-
+
if (ancestor->mode == ours->mode)
return theirs->mode;
else if(ancestor->mode == theirs->mode)
return ours->mode;
-
+
return 0;
}
@@ -70,27 +70,27 @@ int git_merge_file_input_from_index_entry(
{
git_odb *odb = NULL;
int error = 0;
-
+
assert(input && repo && entry);
-
+
if (entry->mode == 0)
return 0;
-
+
if ((error = git_repository_odb(&odb, repo)) < 0 ||
(error = git_odb_read(&input->odb_object, odb, &entry->oid)) < 0)
goto done;
-
+
input->mode = entry->mode;
input->path = git__strdup(entry->path);
input->mmfile.size = git_odb_object_size(input->odb_object);
input->mmfile.ptr = (char *)git_odb_object_data(input->odb_object);
-
+
if (input->label == NULL)
input->label = entry->path;
-
+
done:
git_odb_free(odb);
-
+
return error;
}
@@ -101,27 +101,27 @@ int git_merge_file_input_from_diff_file(
{
git_odb *odb = NULL;
int error = 0;
-
+
assert(input && repo && file);
-
+
if (file->mode == 0)
return 0;
-
+
if ((error = git_repository_odb(&odb, repo)) < 0 ||
(error = git_odb_read(&input->odb_object, odb, &file->oid)) < 0)
goto done;
-
+
input->mode = file->mode;
input->path = git__strdup(file->path);
input->mmfile.size = git_odb_object_size(input->odb_object);
input->mmfile.ptr = (char *)git_odb_object_data(input->odb_object);
-
+
if (input->label == NULL)
input->label = file->path;
-
+
done:
git_odb_free(odb);
-
+
return error;
}
@@ -138,12 +138,12 @@ int git_merge_files(
int error = 0;
assert(out && ancestor && ours && theirs);
-
+
memset(out, 0x0, sizeof(git_merge_file_result));
if (!GIT_MERGE_FILE_SIDE_EXISTS(ours) || !GIT_MERGE_FILE_SIDE_EXISTS(theirs))
return 0;
-
+
memset(&xmparam, 0x0, sizeof(xmparam_t));
xmparam.ancestor = ancestor->label;
xmparam.file1 = ours->label;
@@ -154,7 +154,7 @@ int git_merge_files(
if (flags == GIT_MERGE_AUTOMERGE_FAVOR_OURS)
xmparam.favor = XDL_MERGE_FAVOR_OURS;
-
+
if (flags == GIT_MERGE_AUTOMERGE_FAVOR_THEIRS)
xmparam.favor = XDL_MERGE_FAVOR_THEIRS;
@@ -164,7 +164,7 @@ int git_merge_files(
error = -1;
goto done;
}
-
+
out->automergeable = (xdl_result == 0);
out->data = (unsigned char *)mmbuffer.ptr;
out->len = mmbuffer.size;
@@ -172,4 +172,3 @@ int git_merge_files(
done:
return error;
}
-
diff --git a/src/merge_file.h b/src/merge_file.h
index 1aa34893d..0af2f0a57 100644
--- a/src/merge_file.h
+++ b/src/merge_file.h
@@ -16,7 +16,7 @@ typedef struct {
char *path;
unsigned int mode;
mmfile_t mmfile;
-
+
git_odb_object *odb_object;
} git_merge_file_input;
@@ -24,10 +24,10 @@ typedef struct {
typedef struct {
bool automergeable;
-
+
const char *path;
int mode;
-
+
unsigned char *data;
size_t len;
} git_merge_file_result;
diff --git a/src/notes.c b/src/notes.c
index ef48ac88e..3e3db58db 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -13,6 +13,12 @@
#include "iterator.h"
#include "signature.h"
+static int note_error_notfound(void)
+{
+ giterr_set(GITERR_INVALID, "Note could not be found");
+ return GIT_ENOTFOUND;
+}
+
static int find_subtree_in_current_level(
git_tree **out,
git_repository *repo,
@@ -26,7 +32,7 @@ static int find_subtree_in_current_level(
*out = NULL;
if (parent == NULL)
- return GIT_ENOTFOUND;
+ return note_error_notfound();
for (i = 0; i < git_tree_entrycount(parent); i++) {
entry = git_tree_entry_byindex(parent, i);
@@ -44,7 +50,7 @@ static int find_subtree_in_current_level(
return GIT_EEXISTS;
}
- return GIT_ENOTFOUND;
+ return note_error_notfound();
}
static int find_subtree_r(git_tree **out, git_tree *root,
@@ -56,9 +62,8 @@ static int find_subtree_r(git_tree **out, git_tree *root,
*out = NULL;
error = find_subtree_in_current_level(&subtree, repo, root, target, *fanout);
- if (error == GIT_EEXISTS) {
+ if (error == GIT_EEXISTS)
return git_tree_lookup(out, repo, git_tree_id(root));
- }
if (error < 0)
return error;
@@ -85,7 +90,8 @@ static int find_blob(git_oid *blob, git_tree *tree, const char *target)
return 0;
}
}
- return GIT_ENOTFOUND;
+
+ return note_error_notfound();
}
static int tree_write(
@@ -316,8 +322,8 @@ static int note_new(git_note **out, git_oid *note_oid, git_blob *blob)
return 0;
}
-static int note_lookup(git_note **out, git_repository *repo,
- git_tree *tree, const char *target)
+static int note_lookup(
+ git_note **out, git_repository *repo, git_tree *tree, const char *target)
{
int error, fanout = 0;
git_oid oid;
@@ -382,6 +388,7 @@ static int note_get_default_ref(const char **out, git_repository *repo)
ret = git_config_get_string(out, cfg, "core.notesRef");
if (ret == GIT_ENOTFOUND) {
+ giterr_clear();
*out = GIT_NOTES_DEFAULT_REF;
return 0;
}
@@ -432,12 +439,10 @@ int git_note_read(git_note **out, git_repository *repo,
target = git_oid_allocfmt(oid);
GITERR_CHECK_ALLOC(target);
- if ((error = retrieve_note_tree_and_commit(&tree, &commit, repo, &notes_ref)) < 0)
- goto cleanup;
-
- error = note_lookup(out, repo, tree, target);
+ if (!(error = retrieve_note_tree_and_commit(
+ &tree, &commit, repo, &notes_ref)))
+ error = note_lookup(out, repo, tree, target);
-cleanup:
git__free(target);
git_tree_free(tree);
git_commit_free(commit);
@@ -489,13 +494,11 @@ int git_note_remove(git_repository *repo, const char *notes_ref,
target = git_oid_allocfmt(oid);
GITERR_CHECK_ALLOC(target);
- if ((error = retrieve_note_tree_and_commit(&tree, &commit, repo, &notes_ref)) < 0)
- goto cleanup;
-
- error = note_remove(repo, author, committer, notes_ref,
- tree, target, &commit);
+ if (!(error = retrieve_note_tree_and_commit(
+ &tree, &commit, repo, &notes_ref)))
+ error = note_remove(
+ repo, author, committer, notes_ref, tree, target, &commit);
-cleanup:
git__free(target);
git_commit_free(commit);
git_tree_free(tree);
@@ -533,7 +536,7 @@ static int process_entry_path(
const char* entry_path,
git_oid *annotated_object_id)
{
- int error = -1;
+ int error = 0;
size_t i = 0, j = 0, len;
git_buf buf = GIT_BUF_INIT;
@@ -576,30 +579,30 @@ cleanup:
}
int git_note_foreach(
- git_repository *repo,
- const char *notes_ref,
- git_note_foreach_cb note_cb,
- void *payload)
+ git_repository *repo,
+ const char *notes_ref,
+ git_note_foreach_cb note_cb,
+ void *payload)
{
- int error;
- git_note_iterator *iter = NULL;
- git_oid note_id, annotated_id;
+ int error;
+ git_note_iterator *iter = NULL;
+ git_oid note_id, annotated_id;
- if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
- return error;
+ if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
+ return error;
- while (!(error = git_note_next(&note_id, &annotated_id, iter))) {
- if (note_cb(&note_id, &annotated_id, payload)) {
- error = GIT_EUSER;
- break;
- }
- }
+ while (!(error = git_note_next(&note_id, &annotated_id, iter))) {
+ if (note_cb(&note_id, &annotated_id, payload)) {
+ error = GIT_EUSER;
+ break;
+ }
+ }
- if (error == GIT_ITEROVER)
- error = 0;
+ if (error == GIT_ITEROVER)
+ error = 0;
- git_note_iterator_free(iter);
- return error;
+ git_note_iterator_free(iter);
+ return error;
}
diff --git a/src/object.c b/src/object.c
index b87a07404..9b8ccdd3e 100644
--- a/src/object.c
+++ b/src/object.c
@@ -117,13 +117,15 @@ int git_object_lookup_prefix(
{
git_object *object = NULL;
git_odb *odb = NULL;
- git_odb_object *odb_obj;
+ git_odb_object *odb_obj = NULL;
int error = 0;
assert(repo && object_out && id);
- if (len < GIT_OID_MINPREFIXLEN)
+ if (len < GIT_OID_MINPREFIXLEN) {
+ giterr_set(GITERR_OBJECT, "Ambiguous lookup - OID prefix is too short");
return GIT_EAMBIGUOUS;
+ }
error = git_repository_odb__weakptr(&odb, repo);
if (error < 0)
@@ -311,18 +313,17 @@ int git_object_peel(
git_object *source, *deref = NULL;
int error;
- if (target_type != GIT_OBJ_TAG &&
- target_type != GIT_OBJ_COMMIT &&
- target_type != GIT_OBJ_TREE &&
- target_type != GIT_OBJ_BLOB &&
- target_type != GIT_OBJ_ANY)
- return GIT_EINVALIDSPEC;
-
assert(object && peeled);
if (git_object_type(object) == target_type)
return git_object_dup(peeled, (git_object *)object);
+ assert(target_type == GIT_OBJ_TAG ||
+ target_type == GIT_OBJ_COMMIT ||
+ target_type == GIT_OBJ_TREE ||
+ target_type == GIT_OBJ_BLOB ||
+ target_type == GIT_OBJ_ANY);
+
source = (git_object *)object;
while (!(error = dereference_object(&deref, source))) {
diff --git a/src/odb.c b/src/odb.c
index 07e1ea6eb..9f18b5153 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -424,6 +424,14 @@ size_t git_odb_num_backends(git_odb *odb)
return odb->backends.length;
}
+static int git_odb__error_unsupported_in_backend(const char *action)
+{
+ giterr_set(GITERR_ODB,
+ "Cannot %s - unsupported in the loaded odb backends", action);
+ return -1;
+}
+
+
int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
{
backend_internal *internal;
@@ -436,6 +444,7 @@ int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
return 0;
}
+ giterr_set(GITERR_ODB, "No ODB backend loaded at index " PRIuZ, pos);
return GIT_ENOTFOUND;
}
@@ -457,6 +466,9 @@ static int add_default_backends(
inode = 0;
#else
if (p_stat(objects_dir, &st) < 0) {
+ if (as_alternates)
+ return 0;
+
giterr_set(GITERR_ODB, "Failed to load object database in '%s'", objects_dir);
return -1;
}
@@ -469,7 +481,7 @@ static int add_default_backends(
return 0;
}
#endif
-
+
/* add the loose object backend */
if (git_odb_backend_loose(&loose, objects_dir, -1, 0) < 0 ||
add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0)
@@ -492,9 +504,8 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_
int result = 0;
/* Git reports an error, we just ignore anything deeper */
- if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH) {
+ if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH)
return 0;
- }
if (git_buf_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0)
return -1;
@@ -684,7 +695,7 @@ int git_odb__read_header_or_object(
int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
{
- size_t i;
+ size_t i, reads = 0;
int error;
bool refreshed = false;
git_rawobj raw;
@@ -692,11 +703,6 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
assert(out && db && id);
- if (db->backends.length == 0) {
- giterr_set(GITERR_ODB, "Failed to lookup object: no backends loaded");
- return GIT_ENOTFOUND;
- }
-
*out = git_cache_get_raw(odb_cache(db), id);
if (*out != NULL)
return 0;
@@ -708,8 +714,10 @@ attempt_lookup:
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
- if (b->read != NULL)
+ if (b->read != NULL) {
+ ++reads;
error = b->read(&raw.data, &raw.len, &raw.type, b, id);
+ }
}
if (error == GIT_ENOTFOUND && !refreshed) {
@@ -720,8 +728,11 @@ attempt_lookup:
goto attempt_lookup;
}
- if (error && error != GIT_PASSTHROUGH)
+ if (error && error != GIT_PASSTHROUGH) {
+ if (!reads)
+ return git_odb__error_notfound("no match for id", id);
return error;
+ }
if ((object = odb_object__alloc(id, &raw)) == NULL)
return -1;
@@ -841,10 +852,10 @@ int git_odb_write(
if (!error || error == GIT_PASSTHROUGH)
return 0;
- /* if no backends were able to write the object directly, we try a streaming
- * write to the backends; just write the whole object into the stream in one
- * push */
-
+ /* if no backends were able to write the object directly, we try a
+ * streaming write to the backends; just write the whole object into the
+ * stream in one push
+ */
if ((error = git_odb_open_wstream(&stream, db, len, type)) != 0)
return error;
@@ -858,7 +869,7 @@ int git_odb_write(
int git_odb_open_wstream(
git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
{
- size_t i;
+ size_t i, writes = 0;
int error = GIT_ERROR;
assert(stream && db);
@@ -871,21 +882,26 @@ int git_odb_open_wstream(
if (internal->is_alternate)
continue;
- if (b->writestream != NULL)
+ if (b->writestream != NULL) {
+ ++writes;
error = b->writestream(stream, b, size, type);
- else if (b->write != NULL)
+ } else if (b->write != NULL) {
+ ++writes;
error = init_fake_wstream(stream, b, size, type);
+ }
}
if (error == GIT_PASSTHROUGH)
error = 0;
+ if (error < 0 && !writes)
+ error = git_odb__error_unsupported_in_backend("write object");
return error;
}
int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid)
{
- size_t i;
+ size_t i, reads = 0;
int error = GIT_ERROR;
assert(stream && db);
@@ -894,19 +910,23 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
- if (b->readstream != NULL)
+ if (b->readstream != NULL) {
+ ++reads;
error = b->readstream(stream, b, oid);
+ }
}
if (error == GIT_PASSTHROUGH)
error = 0;
+ if (error < 0 && !reads)
+ error = git_odb__error_unsupported_in_backend("read object streamed");
return error;
}
int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_callback progress_cb, void *progress_payload)
{
- size_t i;
+ size_t i, writes = 0;
int error = GIT_ERROR;
assert(out && db);
@@ -919,12 +939,16 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer
if (internal->is_alternate)
continue;
- if (b->writepack != NULL)
+ if (b->writepack != NULL) {
+ ++writes;
error = b->writepack(out, b, progress_cb, progress_payload);
+ }
}
if (error == GIT_PASSTHROUGH)
error = 0;
+ if (error < 0 && !writes)
+ error = git_odb__error_unsupported_in_backend("write pack");
return error;
}
diff --git a/src/pathspec.c b/src/pathspec.c
index d4eb12582..35c79ce82 100644
--- a/src/pathspec.c
+++ b/src/pathspec.c
@@ -141,7 +141,7 @@ bool git_pathspec_match_path(
git_vector_foreach(vspec, i, match) {
int result = (match->flags & GIT_ATTR_FNMATCH_MATCH_ALL) ? 0 : FNM_NOMATCH;
-
+
if (result == FNM_NOMATCH)
result = use_strcmp(match->pattern, path) ? FNM_NOMATCH : 0;
diff --git a/src/push.c b/src/push.c
index 9b1e78c8e..452d71789 100644
--- a/src/push.c
+++ b/src/push.c
@@ -180,7 +180,7 @@ int git_push_update_tips(git_push *push)
git_buf remote_ref_name = GIT_BUF_INIT;
size_t i, j;
git_refspec *fetch_spec;
- push_spec *push_spec;
+ push_spec *push_spec = NULL;
git_reference *remote_ref;
push_status *status;
int error = 0;
@@ -303,7 +303,7 @@ static int revwalk(git_vector *commits, git_push *push)
continue;
if (!git_odb_exists(push->repo->_odb, &spec->roid)) {
- giterr_clear();
+ giterr_set(GITERR_REFERENCE, "Cannot push missing reference");
error = GIT_ENONFASTFORWARD;
goto on_error;
}
@@ -313,7 +313,8 @@ static int revwalk(git_vector *commits, git_push *push)
if (error == GIT_ENOTFOUND ||
(!error && !git_oid_equal(&base, &spec->roid))) {
- giterr_clear();
+ giterr_set(GITERR_REFERENCE,
+ "Cannot push non-fastforwardable reference");
error = GIT_ENONFASTFORWARD;
goto on_error;
}
@@ -333,12 +334,13 @@ static int revwalk(git_vector *commits, git_push *push)
while ((error = git_revwalk_next(&oid, rw)) == 0) {
git_oid *o = git__malloc(GIT_OID_RAWSZ);
- GITERR_CHECK_ALLOC(o);
- git_oid_cpy(o, &oid);
- if (git_vector_insert(commits, o) < 0) {
+ if (!o) {
error = -1;
goto on_error;
}
+ git_oid_cpy(o, &oid);
+ if ((error = git_vector_insert(commits, o)) < 0)
+ goto on_error;
}
on_error:
@@ -519,7 +521,7 @@ static int calculate_work(git_push *push)
/* This is a create or update. Local ref must exist. */
if (git_reference_name_to_id(
&spec->loid, push->repo, spec->lref) < 0) {
- giterr_set(GIT_ENOTFOUND, "No such reference '%s'", spec->lref);
+ giterr_set(GITERR_REFERENCE, "No such reference '%s'", spec->lref);
return -1;
}
}
diff --git a/src/refdb.c b/src/refdb.c
index 33a1934d1..9f9037ce7 100644
--- a/src/refdb.c
+++ b/src/refdb.c
@@ -124,60 +124,70 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
return error;
}
-int git_refdb_foreach(
- git_refdb *db,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload)
+int git_refdb_iterator(git_reference_iterator **out, git_refdb *db)
{
- assert(db && db->backend);
+ if (!db->backend || !db->backend->iterator) {
+ giterr_set(GITERR_REFERENCE, "This backend doesn't support iterators");
+ return -1;
+ }
- return db->backend->foreach(db->backend, list_flags, callback, payload);
-}
+ if (db->backend->iterator(out, db->backend) < 0)
+ return -1;
-struct glob_cb_data {
- const char *glob;
- git_reference_foreach_cb callback;
- void *payload;
-};
+ return 0;
+}
-static int fromglob_cb(const char *reference_name, void *payload)
+int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob)
{
- struct glob_cb_data *data = (struct glob_cb_data *)payload;
+ if (!db->backend) {
+ giterr_set(GITERR_REFERENCE, "There are no backends loaded");
+ return -1;
+ }
- if (!p_fnmatch(data->glob, reference_name, 0))
- return data->callback(reference_name, data->payload);
+ if (db->backend->iterator_glob)
+ return db->backend->iterator_glob(out, db->backend, glob);
+
+ /* If the backend doesn't support glob-filtering themselves, we have to do it */
+ if (db->backend->iterator(out, db->backend) < 0)
+ return -1;
+
+ (*out)->glob = git__strdup(glob);
+ if (!(*out)->glob) {
+ db->backend->iterator_free(*out);
+ return -1;
+ }
return 0;
}
-int git_refdb_foreach_glob(
- git_refdb *db,
- const char *glob,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload)
+int git_refdb_next(const char **out, git_reference_iterator *iter)
{
int error;
- struct glob_cb_data data;
- assert(db && db->backend && glob && callback);
+ if (!iter->glob)
+ return iter->backend->next(out, iter);
- if(db->backend->foreach_glob != NULL)
- error = db->backend->foreach_glob(db->backend,
- glob, list_flags, callback, payload);
- else {
- data.glob = glob;
- data.callback = callback;
- data.payload = payload;
-
- error = db->backend->foreach(db->backend,
- list_flags, fromglob_cb, &data);
+ /* If the iterator has a glob, we need to filter */
+ while ((error = iter->backend->next(out, iter)) == 0) {
+ if (!p_fnmatch(iter->glob, *out, 0))
+ break;
}
return error;
}
+void git_refdb_iterator_free(git_reference_iterator *iter)
+{
+ git__free(iter->glob);
+ iter->backend->iterator_free(iter);
+}
+
+struct glob_cb_data {
+ const char *glob;
+ git_reference_foreach_cb callback;
+ void *payload;
+};
+
int git_refdb_write(git_refdb *db, const git_reference *ref)
{
assert(db && db->backend);
diff --git a/src/refdb.h b/src/refdb.h
index 047113ac8..2edd05d18 100644
--- a/src/refdb.h
+++ b/src/refdb.h
@@ -26,18 +26,10 @@ int git_refdb_lookup(
git_refdb *refdb,
const char *ref_name);
-int git_refdb_foreach(
- git_refdb *refdb,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload);
-
-int git_refdb_foreach_glob(
- git_refdb *refdb,
- const char *glob,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload);
+int git_refdb_iterator(git_reference_iterator **out, git_refdb *db);
+int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob);
+int git_refdb_next(const char **out, git_reference_iterator *iter);
+void git_refdb_iterator_free(git_reference_iterator *iter);
int git_refdb_write(git_refdb *refdb, const git_reference *ref);
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index c0a32bae7..f964c4182 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -13,6 +13,7 @@
#include "reflog.h"
#include "refdb.h"
#include "refdb_fs.h"
+#include "iterator.h"
#include <git2/tag.h>
#include <git2/object.h>
@@ -106,7 +107,7 @@ static int packed_parse_oid(
refname_len = refname_end - refname_begin;
- ref = git__malloc(sizeof(struct packref) + refname_len + 1);
+ ref = git__calloc(1, sizeof(struct packref) + refname_len + 1);
GITERR_CHECK_ALLOC(ref);
memcpy(ref->name, refname_begin, refname_len);
@@ -180,6 +181,9 @@ static int packed_load(refdb_fs_backend *backend)
GITERR_CHECK_ALLOC(ref_cache->packfile);
}
+ if (backend->path == NULL)
+ return 0;
+
result = reference_read(&packfile, &ref_cache->packfile_time,
backend->path, GIT_PACKEDREFS_FILE, &updated);
@@ -213,7 +217,7 @@ static int packed_load(refdb_fs_backend *backend)
backend->peeling_mode = PEELING_NONE;
if (buffer_start[0] == '#') {
- static const char *traits_header = "# pack-refs with: ";
+ static const char *traits_header = "# pack-refs with: ";
if (git__prefixcmp(buffer_start, traits_header) == 0) {
char *traits = (char *)buffer_start + strlen(traits_header);
@@ -253,8 +257,8 @@ static int packed_load(refdb_fs_backend *backend)
if (packed_parse_peel(ref, &buffer_start, buffer_end) < 0)
goto parse_failed;
} else if (backend->peeling_mode == PEELING_FULL ||
- (backend->peeling_mode == PEELING_STANDARD &&
- git__prefixcmp(ref->name, GIT_REFS_TAGS_DIR) == 0)) {
+ (backend->peeling_mode == PEELING_STANDARD &&
+ git__prefixcmp(ref->name, GIT_REFS_TAGS_DIR) == 0)) {
ref->flags |= PACKREF_CANNOT_PEEL;
}
@@ -316,7 +320,7 @@ static int loose_lookup_to_packfile(
git_buf_rtrim(&ref_file);
name_len = strlen(name);
- ref = git__malloc(sizeof(struct packref) + name_len + 1);
+ ref = git__calloc(1, sizeof(struct packref) + name_len + 1);
GITERR_CHECK_ALLOC(ref);
memcpy(ref->name, name, name_len);
@@ -558,98 +562,129 @@ struct dirent_list_data {
int callback_error;
};
-static git_ref_t loose_guess_rtype(const git_buf *full_path)
+typedef struct {
+ git_reference_iterator parent;
+ unsigned int loose;
+ /* packed */
+ git_strmap *h;
+ khiter_t k;
+ /* loose */
+ git_iterator *fsiter;
+ git_buf buf;
+} refdb_fs_iter;
+
+static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend)
{
- git_buf ref_file = GIT_BUF_INIT;
- git_ref_t type;
+ refdb_fs_iter *iter;
+ refdb_fs_backend *backend;
- type = GIT_REF_INVALID;
+ assert(_backend);
+ backend = (refdb_fs_backend *)_backend;
- if (git_futils_readbuffer(&ref_file, full_path->ptr) == 0) {
- if (git__prefixcmp((const char *)(ref_file.ptr), GIT_SYMREF) == 0)
- type = GIT_REF_SYMBOLIC;
- else
- type = GIT_REF_OID;
- }
+ if (packed_load(backend) < 0)
+ return -1;
- git_buf_free(&ref_file);
- return type;
+ iter = git__calloc(1, sizeof(refdb_fs_iter));
+ GITERR_CHECK_ALLOC(iter);
+
+ iter->parent.backend = _backend;
+ iter->h = backend->refcache.packfile;
+ iter->k = kh_begin(backend->refcache.packfile);
+
+ *out = (git_reference_iterator *)iter;
+
+ return 0;
}
-static int _dirent_loose_listall(void *_data, git_buf *full_path)
+static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter)
{
- struct dirent_list_data *data = (struct dirent_list_data *)_data;
- const char *file_path = full_path->ptr + data->repo_path_len;
-
- if (git_path_isdir(full_path->ptr) == true)
- return git_path_direach(full_path, _dirent_loose_listall, _data);
+ refdb_fs_iter *iter = (refdb_fs_iter *) _iter;
- /* do not add twice a reference that exists already in the packfile */
- if (git_strmap_exists(data->backend->refcache.packfile, file_path))
- return 0;
+ git_buf_free(&iter->buf);
+ git_iterator_free(iter->fsiter);
+ git__free(iter);
+}
- if (data->list_type != GIT_REF_LISTALL) {
- if ((data->list_type & loose_guess_rtype(full_path)) == 0)
- return 0; /* we are filtering out this reference */
+static int iter_packed(const char **out, refdb_fs_iter *iter)
+{
+ /* Move forward to the next entry */
+ while (!kh_exist(iter->h, iter->k)) {
+ iter->k++;
+ if (iter->k == kh_end(iter->h))
+ return GIT_ITEROVER;
}
- /* Locked references aren't returned */
- if (!git__suffixcmp(file_path, GIT_FILELOCK_EXTENSION))
- return 0;
+ *out = kh_key(iter->h, iter->k);
+ iter->k++;
- if (data->callback(file_path, data->callback_payload))
- data->callback_error = GIT_EUSER;
-
- return data->callback_error;
+ return 0;
}
-static int refdb_fs_backend__foreach(
- git_refdb_backend *_backend,
- unsigned int list_type,
- git_reference_foreach_cb callback,
- void *payload)
+static int iter_loose(const char **out, refdb_fs_iter *iter)
{
- refdb_fs_backend *backend;
- int result;
- struct dirent_list_data data;
- git_buf refs_path = GIT_BUF_INIT;
- const char *ref_name;
- void *ref = NULL;
+ const git_index_entry *entry;
+ int retry;
+ git_strmap *packfile_refs;
+ refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
- GIT_UNUSED(ref);
+ packfile_refs = backend->refcache.packfile;
- assert(_backend);
- backend = (refdb_fs_backend *)_backend;
+ do {
+ khiter_t pos;
+ if (git_iterator_current(&entry, iter->fsiter) < 0)
+ return -1;
- if (packed_load(backend) < 0)
- return -1;
+ git_buf_clear(&iter->buf);
+ if (!entry)
+ return GIT_ITEROVER;
- /* list all the packed references first */
- if (list_type & GIT_REF_OID) {
- git_strmap_foreach(backend->refcache.packfile, ref_name, ref, {
- if (callback(ref_name, payload))
- return GIT_EUSER;
- });
- }
+ if (git_buf_printf(&iter->buf, "refs/%s", entry->path) < 0)
+ return -1;
- /* now list the loose references, trying not to
- * duplicate the ref names already in the packed-refs file */
+ git_iterator_advance(NULL, iter->fsiter);
- data.repo_path_len = strlen(backend->path);
- data.list_type = list_type;
- data.backend = backend;
- data.callback = callback;
- data.callback_payload = payload;
- data.callback_error = 0;
+ /* Skip this one if we already listed it in packed */
+ pos = git_strmap_lookup_index(packfile_refs, git_buf_cstr(&iter->buf));
+ retry = 0;
+ if (git_strmap_valid_index(packfile_refs, pos) ||
+ !git_reference_is_valid_name(git_buf_cstr(&iter->buf)))
+ retry = 1;
- if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0)
+ *out = git_buf_cstr(&iter->buf);
+ } while (retry);
+
+ return 0;
+}
+
+static int iter_loose_setup(refdb_fs_iter *iter)
+{
+ refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
+
+ git_buf_clear(&iter->buf);
+ if (git_buf_printf(&iter->buf, "%s/refs", backend->path) < 0)
return -1;
- result = git_path_direach(&refs_path, _dirent_loose_listall, &data);
+ return git_iterator_for_filesystem(&iter->fsiter, git_buf_cstr(&iter->buf), 0, NULL, NULL);
+}
- git_buf_free(&refs_path);
+static int refdb_fs_backend__next(const char **out, git_reference_iterator *_iter)
+{
+ refdb_fs_iter *iter = (refdb_fs_iter *)_iter;
+
+ if (iter->loose)
+ return iter_loose(out, iter);
- return data.callback_error ? GIT_EUSER : result;
+ if (iter->k != kh_end(iter->h)) {
+ int error = iter_packed(out, iter);
+ if (error != GIT_ITEROVER)
+ return error;
+ }
+
+ if (iter_loose_setup(iter) < 0)
+ return -1;
+ iter->loose = 1;
+
+ return iter_loose(out, iter);
}
static int loose_write(refdb_fs_backend *backend, const git_reference *ref)
@@ -1025,7 +1060,11 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend)
static int setup_namespace(git_buf *path, git_repository *repo)
{
- char *parts, *start, *end;
+ char *parts, *start, *end;
+
+ /* Not all repositories have a path */
+ if (repo->path_repository == NULL)
+ return 0;
/* Load the path to the repo first */
git_buf_puts(path, repo->path_repository);
@@ -1052,7 +1091,7 @@ static int setup_namespace(git_buf *path, git_repository *repo)
free(parts);
/* Make sure that the folder with the namespace exists */
- if (git_futils_mkdir_r(git_buf_cstr(path), repo->path_repository, 0777) < 0)
+ if (git_futils_mkdir_r(git_buf_cstr(path), repo->path_repository, 0777) < 0)
return -1;
/* Return the root of the namespaced path, i.e. without the trailing '/refs' */
@@ -1081,7 +1120,9 @@ int git_refdb_backend_fs(
backend->parent.exists = &refdb_fs_backend__exists;
backend->parent.lookup = &refdb_fs_backend__lookup;
- backend->parent.foreach = &refdb_fs_backend__foreach;
+ backend->parent.iterator = &refdb_fs_backend__iterator;
+ backend->parent.next = &refdb_fs_backend__next;
+ backend->parent.iterator_free = &refdb_fs_backend__iterator_free;
backend->parent.write = &refdb_fs_backend__write;
backend->parent.delete = &refdb_fs_backend__delete;
backend->parent.compress = &refdb_fs_backend__compress;
diff --git a/src/reflog.c b/src/reflog.c
index 8c133fe53..4cc20d2c7 100644
--- a/src/reflog.c
+++ b/src/reflog.c
@@ -483,8 +483,10 @@ int git_reflog_drop(
entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
- if (entry == NULL)
+ if (entry == NULL) {
+ giterr_set(GITERR_REFERENCE, "No reflog entry at index "PRIuZ, idx);
return GIT_ENOTFOUND;
+ }
reflog_entry_free(entry);
diff --git a/src/refs.c b/src/refs.c
index b85a2e828..9c6c5c623 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -139,7 +139,7 @@ static int reference_path_available(
data.available = 1;
error = git_reference_foreach(
- repo, GIT_REF_LISTALL, _reference_available_cb, (void *)&data);
+ repo, _reference_available_cb, (void *)&data);
if (error < 0)
return error;
@@ -290,6 +290,67 @@ int git_reference_lookup_resolved(
return 0;
}
+int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname)
+{
+ int error = 0, i;
+ bool fallbackmode = true, foundvalid = false;
+ git_reference *ref;
+ git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;
+
+ static const char* formatters[] = {
+ "%s",
+ GIT_REFS_DIR "%s",
+ GIT_REFS_TAGS_DIR "%s",
+ GIT_REFS_HEADS_DIR "%s",
+ GIT_REFS_REMOTES_DIR "%s",
+ GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE,
+ NULL
+ };
+
+ if (*refname)
+ git_buf_puts(&name, refname);
+ else {
+ git_buf_puts(&name, GIT_HEAD_FILE);
+ fallbackmode = false;
+ }
+
+ for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {
+
+ git_buf_clear(&refnamebuf);
+
+ if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
+ goto cleanup;
+
+ if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
+ error = GIT_EINVALIDSPEC;
+ continue;
+ }
+ foundvalid = true;
+
+ error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);
+
+ if (!error) {
+ *out = ref;
+ error = 0;
+ goto cleanup;
+ }
+
+ if (error != GIT_ENOTFOUND)
+ goto cleanup;
+ }
+
+cleanup:
+ if (error && !foundvalid) {
+ /* never found a valid reference name */
+ giterr_set(GITERR_REFERENCE,
+ "Could not use '%s' as valid reference name", git_buf_cstr(&name));
+ }
+
+ git_buf_free(&name);
+ git_buf_free(&refnamebuf);
+ return error;
+}
+
/**
* Getters
*/
@@ -558,14 +619,59 @@ int git_reference_resolve(git_reference **ref_out, const git_reference *ref)
int git_reference_foreach(
git_repository *repo,
- unsigned int list_flags,
git_reference_foreach_cb callback,
void *payload)
{
+ git_reference_iterator *iter;
+ const char *name;
+ int error;
+
+ if (git_reference_iterator_new(&iter, repo) < 0)
+ return -1;
+
+ while ((error = git_reference_next(&name, iter)) == 0) {
+ if (callback(name, payload)) {
+ error = GIT_EUSER;
+ goto out;
+ }
+ }
+
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+out:
+ git_reference_iterator_free(iter);
+ return error;
+}
+
+int git_reference_iterator_new(git_reference_iterator **out, git_repository *repo)
+{
+ git_refdb *refdb;
+
+ if (git_repository_refdb__weakptr(&refdb, repo) < 0)
+ return -1;
+
+ return git_refdb_iterator(out, refdb);
+}
+
+int git_reference_iterator_glob_new(git_reference_iterator **out, git_repository *repo, const char *glob)
+{
git_refdb *refdb;
- git_repository_refdb__weakptr(&refdb, repo);
- return git_refdb_foreach(refdb, list_flags, callback, payload);
+ if (git_repository_refdb__weakptr(&refdb, repo) < 0)
+ return -1;
+
+ return git_refdb_iterator_glob(out, refdb, glob);
+}
+
+int git_reference_next(const char **out, git_reference_iterator *iter)
+{
+ return git_refdb_next(out, iter);
+}
+
+void git_reference_iterator_free(git_reference_iterator *iter)
+{
+ git_refdb_iterator_free(iter);
}
static int cb__reflist_add(const char *ref, void *data)
@@ -575,8 +681,7 @@ static int cb__reflist_add(const char *ref, void *data)
int git_reference_list(
git_strarray *array,
- git_repository *repo,
- unsigned int list_flags)
+ git_repository *repo)
{
git_vector ref_list;
@@ -589,7 +694,7 @@ int git_reference_list(
return -1;
if (git_reference_foreach(
- repo, list_flags, &cb__reflist_add, (void *)&ref_list) < 0) {
+ repo, &cb__reflist_add, (void *)&ref_list) < 0) {
git_vector_free(&ref_list);
return -1;
}
@@ -844,8 +949,10 @@ static int reference__update_terminal(
git_reference *ref;
int error = 0;
- if (nesting > MAX_NESTING_LEVEL)
+ if (nesting > MAX_NESTING_LEVEL) {
+ giterr_set(GITERR_REFERENCE, "Reference chain too deep (%d)", nesting);
return GIT_ENOTFOUND;
+ }
error = git_reference_lookup(&ref, repo, ref_name);
@@ -887,19 +994,29 @@ int git_reference__update_terminal(
int git_reference_foreach_glob(
git_repository *repo,
const char *glob,
- unsigned int list_flags,
- int (*callback)(
- const char *reference_name,
- void *payload),
+ git_reference_foreach_cb callback,
void *payload)
{
- git_refdb *refdb;
+ git_reference_iterator *iter;
+ const char *name;
+ int error;
- assert(repo && glob && callback);
+ if (git_reference_iterator_glob_new(&iter, repo, glob) < 0)
+ return -1;
- git_repository_refdb__weakptr(&refdb, repo);
+ while ((error = git_reference_next(&name, iter)) == 0) {
+ if (callback(name, payload)) {
+ error = GIT_EUSER;
+ goto out;
+ }
+ }
+
+ if (error == GIT_ITEROVER)
+ error = 0;
- return git_refdb_foreach_glob(refdb, glob, list_flags, callback, payload);
+out:
+ git_reference_iterator_free(iter);
+ return error;
}
int git_reference_has_log(
diff --git a/src/remote.c b/src/remote.c
index 6eaaf8b49..7a64622a5 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -63,8 +63,10 @@ static int download_tags_value(git_remote *remote, git_config *cfg)
else if (!error && !strcmp(val, "--tags"))
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
- if (error == GIT_ENOTFOUND)
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
error = 0;
+ }
return error;
}
@@ -210,6 +212,31 @@ static int refspec_cb(const git_config_entry *entry, void *payload)
return add_refspec(data->remote, entry->value, data->fetch);
}
+static int get_optional_config(
+ git_config *config, git_buf *buf, git_config_foreach_cb cb, void *payload)
+{
+ int error = 0;
+ const char *key = git_buf_cstr(buf);
+
+ if (git_buf_oom(buf))
+ return -1;
+
+ if (cb != NULL)
+ error = git_config_get_multivar(config, key, NULL, cb, payload);
+ else
+ error = git_config_get_string(payload, config, key);
+
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
+ error = 0;
+ }
+
+ if (error < 0)
+ error = -1;
+
+ return error;
+}
+
int git_remote_load(git_remote **out, git_repository *repo, const char *name)
{
git_remote *remote;
@@ -250,7 +277,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
if ((error = git_config_get_string(&val, config, git_buf_cstr(&buf))) < 0)
goto cleanup;
-
+
if (strlen(val) == 0) {
giterr_set(GITERR_INVALID, "Malformed remote '%s' - missing URL", name);
error = -1;
@@ -261,60 +288,32 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
remote->url = git__strdup(val);
GITERR_CHECK_ALLOC(remote->url);
+ val = NULL;
git_buf_clear(&buf);
- if (git_buf_printf(&buf, "remote.%s.pushurl", name) < 0) {
- error = -1;
- goto cleanup;
- }
+ git_buf_printf(&buf, "remote.%s.pushurl", name);
- error = git_config_get_string(&val, config, git_buf_cstr(&buf));
- if (error == GIT_ENOTFOUND) {
- val = NULL;
- error = 0;
- }
-
- if (error < 0) {
- error = -1;
+ if ((error = get_optional_config(config, &buf, NULL, (void *)&val)) < 0)
goto cleanup;
- }
if (val) {
remote->pushurl = git__strdup(val);
GITERR_CHECK_ALLOC(remote->pushurl);
}
- git_buf_clear(&buf);
- if (git_buf_printf(&buf, "remote.%s.fetch", name) < 0) {
- error = -1;
- goto cleanup;
- }
-
data.remote = remote;
data.fetch = true;
- error = git_config_get_multivar(config, git_buf_cstr(&buf), NULL, refspec_cb, &data);
- if (error == GIT_ENOTFOUND)
- error = 0;
-
- if (error < 0) {
- error = -1;
- goto cleanup;
- }
-
git_buf_clear(&buf);
- if (git_buf_printf(&buf, "remote.%s.push", name) < 0) {
- error = -1;
+ git_buf_printf(&buf, "remote.%s.fetch", name);
+
+ if ((error = get_optional_config(config, &buf, refspec_cb, &data)) < 0)
goto cleanup;
- }
data.fetch = false;
- error = git_config_get_multivar(config, git_buf_cstr(&buf), NULL, refspec_cb, &data);
- if (error == GIT_ENOTFOUND)
- error = 0;
+ git_buf_clear(&buf);
+ git_buf_printf(&buf, "remote.%s.push", name);
- if (error < 0) {
- error = -1;
+ if ((error = get_optional_config(config, &buf, refspec_cb, &data)) < 0)
goto cleanup;
- }
if (download_tags_value(remote, config) < 0)
goto cleanup;
@@ -336,7 +335,7 @@ static int update_config_refspec(const git_remote *remote, git_config *config, i
int push;
const char *dir;
size_t i;
- int error = -1;
+ int error = 0;
push = direction == GIT_DIRECTION_PUSH;
dir = push ? "push" : "fetch";
@@ -345,9 +344,8 @@ static int update_config_refspec(const git_remote *remote, git_config *config, i
return -1;
/* Clear out the existing config */
- do {
+ while (!error)
error = git_config_delete_entry(config, git_buf_cstr(&name));
- } while (!error);
if (error != GIT_ENOTFOUND)
return error;
@@ -358,7 +356,8 @@ static int update_config_refspec(const git_remote *remote, git_config *config, i
if (spec->push != push)
continue;
- if ((error = git_config_set_multivar(config, git_buf_cstr(&name), "", spec->string)) < 0) {
+ if ((error = git_config_set_multivar(
+ config, git_buf_cstr(&name), "", spec->string)) < 0) {
goto cleanup;
}
}
@@ -871,19 +870,6 @@ static int update_tips_for_spec(git_remote *remote, git_refspec *spec, git_vecto
if (git_vector_init(&update_heads, 16, NULL) < 0)
return -1;
- /* Let's go find HEAD, if it exists. Check only the first ref in the vector. */
- if (refs->length > 0) {
- head = git_vector_get(refs, 0);
-
- if (!strcmp(head->name, GIT_HEAD_FILE)) {
- if (git_reference_create(&ref, remote->repo, GIT_FETCH_HEAD_FILE, &head->oid, 1) < 0)
- goto on_error;
-
- i = 1;
- git_reference_free(ref);
- }
- }
-
for (; i < refs->length; ++i) {
head = git_vector_get(refs, i);
autotag = 0;
@@ -958,30 +944,38 @@ on_error:
int git_remote_update_tips(git_remote *remote)
{
- git_refspec *spec;
+ git_refspec *spec, tagspec;
git_vector refs;
+ int error;
size_t i;
+
+ if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
+ return -1;
+
if (git_vector_init(&refs, 16, NULL) < 0)
return -1;
- if (git_remote_ls(remote, store_refs, &refs) < 0)
- goto on_error;
+ if ((error = git_remote_ls(remote, store_refs, &refs)) < 0)
+ goto out;
+
+ if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
+ error = update_tips_for_spec(remote, &tagspec, &refs);
+ goto out;
+ }
git_vector_foreach(&remote->refspecs, i, spec) {
if (spec->push)
continue;
- if (update_tips_for_spec(remote, spec, &refs) < 0)
- goto on_error;
+ if ((error = update_tips_for_spec(remote, spec, &refs)) < 0)
+ goto out;
}
+out:
+ git_refspec__free(&tagspec);
git_vector_free(&refs);
- return 0;
-
-on_error:
- git_vector_free(&refs);
- return -1;
+ return error;
}
int git_remote_connected(git_remote *remote)
@@ -1244,14 +1238,6 @@ static int update_branch_remote_config_entry(
update_config_entries_cb, &data);
}
-static int rename_cb(const char *ref, void *data)
-{
- if (git__prefixcmp(ref, GIT_REFS_REMOTES_DIR))
- return 0;
-
- return git_vector_insert((git_vector *)data, git__strdup(ref));
-}
-
static int rename_one_remote_reference(
git_repository *repo,
const char *reference_name,
@@ -1291,16 +1277,29 @@ static int rename_remote_references(
int error = -1;
unsigned int i;
char *name;
+ const char *refname;
+ git_reference_iterator *iter;
if (git_vector_init(&refnames, 8, NULL) < 0)
+ return -1;
+
+ if (git_reference_iterator_new(&iter, repo) < 0)
goto cleanup;
- if (git_reference_foreach(
- repo,
- GIT_REF_LISTALL,
- rename_cb,
- &refnames) < 0)
- goto cleanup;
+ while ((error = git_reference_next(&refname, iter)) == 0) {
+ if (git__prefixcmp(refname, GIT_REFS_REMOTES_DIR))
+ continue;
+
+ if ((error = git_vector_insert(&refnames, git__strdup(refname))) < 0)
+ break;
+
+ }
+
+ git_reference_iterator_free(iter);
+ if (error == GIT_ITEROVER)
+ error = 0;
+ else
+ goto cleanup;
git_vector_foreach(&refnames, i, name) {
if ((error = rename_one_remote_reference(repo, name, old_name, new_name)) < 0)
diff --git a/src/repository.c b/src/repository.c
index e6eaf753c..9957f32b7 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -594,6 +594,10 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
git_config_find_xdg_r(&xdg_buf);
git_config_find_system_r(&system_buf);
+ /* If there is no global file, open a backend for it anyway */
+ if (git_buf_len(&global_buf) == 0)
+ git_config__global_location(&global_buf);
+
error = load_config(
&config, repo,
path_unless_empty(&global_buf),
@@ -1469,7 +1473,7 @@ static int at_least_one_cb(const char *refname, void *payload)
static int repo_contains_no_reference(git_repository *repo)
{
- int error = git_reference_foreach(repo, GIT_REF_LISTALL, at_least_one_cb, NULL);
+ int error = git_reference_foreach(repo, at_least_one_cb, NULL);
if (error == GIT_EUSER)
return 0;
@@ -1592,12 +1596,16 @@ int git_repository_message(char *buffer, size_t len, git_repository *repo)
struct stat st;
int error;
+ if (buffer != NULL)
+ *buffer = '\0';
+
if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
return -1;
if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
if (errno == ENOENT)
error = GIT_ENOTFOUND;
+ giterr_set(GITERR_OS, "Could not access message file");
}
else if (buffer != NULL) {
error = git_futils_readbuffer(&buf, git_buf_cstr(&path));
@@ -1628,11 +1636,11 @@ int git_repository_message_remove(git_repository *repo)
}
int git_repository_hashfile(
- git_oid *out,
- git_repository *repo,
- const char *path,
- git_otype type,
- const char *as_path)
+ git_oid *out,
+ git_repository *repo,
+ const char *path,
+ git_otype type,
+ const char *as_path)
{
int error;
git_vector filters = GIT_VECTOR_INIT;
diff --git a/src/reset.c b/src/reset.c
index c1e1f865e..cea212a93 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -32,7 +32,7 @@ int git_reset_default(
int error;
git_index *index = NULL;
- assert(pathspecs != NULL && pathspecs->count > 0);
+ assert(pathspecs != NULL && pathspecs->count > 0);
memset(&entry, 0, sizeof(git_index_entry));
diff --git a/src/revparse.c b/src/revparse.c
index 8a22a04f3..97fc91b54 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -14,60 +14,6 @@
#include "git2.h"
-static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname)
-{
- int error = 0, i;
- bool fallbackmode = true;
- git_reference *ref;
- git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;
-
- static const char* formatters[] = {
- "%s",
- GIT_REFS_DIR "%s",
- GIT_REFS_TAGS_DIR "%s",
- GIT_REFS_HEADS_DIR "%s",
- GIT_REFS_REMOTES_DIR "%s",
- GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE,
- NULL
- };
-
- if (*refname)
- git_buf_puts(&name, refname);
- else {
- git_buf_puts(&name, GIT_HEAD_FILE);
- fallbackmode = false;
- }
-
- for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {
-
- git_buf_clear(&refnamebuf);
-
- if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
- goto cleanup;
-
- if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
- error = GIT_EINVALIDSPEC;
- continue;
- }
-
- error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);
-
- if (!error) {
- *out = ref;
- error = 0;
- goto cleanup;
- }
-
- if (error != GIT_ENOTFOUND)
- goto cleanup;
- }
-
-cleanup:
- git_buf_free(&name);
- git_buf_free(&refnamebuf);
- return error;
-}
-
static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen)
{
git_oid oid;
@@ -150,7 +96,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
if (error < 0 && error != GIT_ENOTFOUND)
return error;
- error = disambiguate_refname(&ref, repo, spec);
+ error = git_reference_dwim(&ref, repo, spec);
if (!error) {
error = git_object_lookup(out, repo, git_reference_target(ref), GIT_OBJ_ANY);
git_reference_free(ref);
@@ -235,7 +181,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so);
- if ((error = disambiguate_refname(base_ref, repo, git_buf_cstr(&buf))) == 0)
+ if ((error = git_reference_dwim(base_ref, repo, git_buf_cstr(&buf))) == 0)
goto cleanup;
if (error < 0 && error != GIT_ENOTFOUND)
@@ -316,7 +262,7 @@ static int retrieve_revobject_from_reflog(git_object **out, git_reference **base
int error = -1;
if (*base_ref == NULL) {
- if ((error = disambiguate_refname(&ref, repo, identifier)) < 0)
+ if ((error = git_reference_dwim(&ref, repo, identifier)) < 0)
return error;
} else {
ref = *base_ref;
@@ -344,7 +290,7 @@ static int retrieve_remote_tracking_reference(git_reference **base_ref, const ch
int error = -1;
if (*base_ref == NULL) {
- if ((error = disambiguate_refname(&ref, repo, identifier)) < 0)
+ if ((error = git_reference_dwim(&ref, repo, identifier)) < 0)
return error;
} else {
ref = *base_ref;
@@ -909,4 +855,3 @@ int git_revparse(
return error;
}
-
diff --git a/src/revwalk.c b/src/revwalk.c
index 16f06624d..528d02b20 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -186,7 +186,7 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
data.hide = hide;
if (git_reference_foreach_glob(
- walk->repo, git_buf_cstr(&buf), GIT_REF_LISTALL, push_glob_cb, &data) < 0)
+ walk->repo, git_buf_cstr(&buf), push_glob_cb, &data) < 0)
goto on_error;
regfree(&preg);
diff --git a/src/signature.c b/src/signature.c
index 649dbcd3d..1131fb789 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -66,10 +66,12 @@ int git_signature_new(git_signature **sig_out, const char *name, const char *ema
p->name = extract_trimmed(name, strlen(name));
p->email = extract_trimmed(email, strlen(email));
- if (p->name == NULL || p->email == NULL ||
- p->name[0] == '\0' || p->email[0] == '\0') {
+ if (p->name == NULL || p->email == NULL)
+ return -1; /* oom */
+
+ if (p->name[0] == '\0') {
git_signature_free(p);
- return signature_error("Empty name or email");
+ return signature_error("Signature cannot have an empty name");
}
p->when.time = time;
@@ -81,9 +83,16 @@ int git_signature_new(git_signature **sig_out, const char *name, const char *ema
git_signature *git_signature_dup(const git_signature *sig)
{
- git_signature *new;
- if (git_signature_new(&new, sig->name, sig->email, sig->when.time, sig->when.offset) < 0)
+ git_signature *new = git__calloc(1, sizeof(git_signature));
+
+ if (new == NULL)
return NULL;
+
+ new->name = git__strdup(sig->name);
+ new->email = git__strdup(sig->email);
+ new->when.time = sig->when.time;
+ new->when.offset = sig->when.offset;
+
return new;
}
@@ -164,7 +173,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
tz_start = time_end + 1;
- if ((tz_start[0] != '-' && tz_start[0] != '+') ||
+ if ((tz_start[0] != '-' && tz_start[0] != '+') ||
git__strtol32(&offset, tz_start + 1, &tz_end, 10) < 0)
return signature_error("malformed timezone");
diff --git a/src/stash.c b/src/stash.c
index 355c5dc9c..19b29be77 100644
--- a/src/stash.c
+++ b/src/stash.c
@@ -587,8 +587,10 @@ int git_stash_foreach(
const git_reflog_entry *entry;
error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE);
- if (error == GIT_ENOTFOUND)
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
return 0;
+ }
if (error < 0)
goto cleanup;
@@ -651,7 +653,7 @@ int git_stash_drop(
const git_reflog_entry *entry;
entry = git_reflog_entry_byindex(reflog, 0);
-
+
git_reference_free(stash);
error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, &entry->oid_cur, 1);
}
diff --git a/src/status.c b/src/status.c
index ac6b4379b..89f3eedb5 100644
--- a/src/status.c
+++ b/src/status.c
@@ -141,7 +141,7 @@ int git_status_foreach_ext(
/* if there is no HEAD, that's okay - we'll make an empty iterator */
if (((err = git_repository_head_tree(&head, repo)) < 0) &&
!(err == GIT_ENOTFOUND || err == GIT_EORPHANEDHEAD))
- return err;
+ return err;
memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
@@ -238,7 +238,7 @@ static int get_one_status(const char *path, unsigned int status, void *data)
p_fnmatch(sfi->expected, path, sfi->fnm_flags) != 0))
{
sfi->ambiguous = true;
- return GIT_EAMBIGUOUS;
+ return GIT_EAMBIGUOUS; /* giterr_set will be done by caller */
}
return 0;
@@ -266,6 +266,7 @@ int git_status_file(
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
+ GIT_STATUS_OPT_RECURSE_IGNORED_DIRS |
GIT_STATUS_OPT_INCLUDE_UNTRACKED |
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
GIT_STATUS_OPT_INCLUDE_UNMODIFIED;
@@ -281,22 +282,9 @@ int git_status_file(
}
if (!error && !sfi.count) {
- git_buf full = GIT_BUF_INIT;
-
- /* if the file actually exists and we still did not get a callback
- * for it, then it must be contained inside an ignored directory, so
- * mark it as such instead of generating an error.
- */
- if (!git_buf_joinpath(&full, git_repository_workdir(repo), path) &&
- git_path_exists(full.ptr))
- sfi.status = GIT_STATUS_IGNORED;
- else {
- giterr_set(GITERR_INVALID,
- "Attempt to get status of nonexistent file '%s'", path);
- error = GIT_ENOTFOUND;
- }
-
- git_buf_free(&full);
+ giterr_set(GITERR_INVALID,
+ "Attempt to get status of nonexistent file '%s'", path);
+ error = GIT_ENOTFOUND;
}
*status_flags = sfi.status;
diff --git a/src/submodule.c b/src/submodule.c
index 0a22e3b13..f4fbcd35a 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -128,6 +128,10 @@ int git_submodule_lookup(
git_buf_free(&path);
}
+ giterr_set(GITERR_SUBMODULE, (error == GIT_ENOTFOUND) ?
+ "No submodule named '%s'" :
+ "Submodule '%s' has not been added yet", name);
+
return error;
}
diff --git a/src/tag.c b/src/tag.c
index a4f2e2581..f81956de7 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -427,7 +427,7 @@ int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data)
data.cb_data = cb_data;
data.repo = repo;
- return git_reference_foreach(repo, GIT_REF_OID, &tags_cb, &data);
+ return git_reference_foreach(repo, &tags_cb, &data);
}
typedef struct {
diff --git a/src/trace.c b/src/trace.c
index 159ac91cc..ee5039f56 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -25,7 +25,7 @@ int git_trace_set(git_trace_level_t level, git_trace_callback callback)
git_trace__data.level = level;
git_trace__data.callback = callback;
GIT_MEMORY_BARRIER;
-
+
return 0;
#else
GIT_UNUSED(level);
@@ -36,4 +36,3 @@ int git_trace_set(git_trace_level_t level, git_trace_callback callback)
return -1;
#endif
}
-
diff --git a/src/trace.h b/src/trace.h
index f4bdff88a..77b1e03ef 100644
--- a/src/trace.h
+++ b/src/trace.h
@@ -25,14 +25,14 @@ GIT_INLINE(void) git_trace__write_fmt(
git_trace_level_t level,
const char *fmt, ...)
{
- git_trace_callback callback = git_trace__data.callback;
+ git_trace_callback callback = git_trace__data.callback;
git_buf message = GIT_BUF_INIT;
va_list ap;
-
+
va_start(ap, fmt);
git_buf_vprintf(&message, fmt, ap);
va_end(ap);
-
+
callback(level, git_buf_cstr(&message));
git_buf_free(&message);
diff --git a/src/transports/local.c b/src/transports/local.c
index 8b4d50c14..4bf1c876a 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -124,7 +124,7 @@ static int store_refs(transport_local *t)
assert(t);
- if (git_reference_list(&ref_names, t->repo, GIT_REF_LISTALL) < 0 ||
+ if (git_reference_list(&ref_names, t->repo) < 0 ||
git_vector_init(&t->refs, ref_names.count, NULL) < 0)
goto on_error;
@@ -348,7 +348,7 @@ static int local_push(
if ((error = git_repository_open(&remote_repo, push->remote->url)) < 0)
return error;
- /* We don't currently support pushing locally to non-bare repos. Proper
+ /* We don't currently support pushing locally to non-bare repos. Proper
non-bare repo push support would require checking configs to see if
we should override the default 'don't let this happen' behavior */
if (!remote_repo->is_bare) {
@@ -495,7 +495,7 @@ static int local_download_pack(
/* Tag or some other wanted object. Add it on its own */
error = git_packbuilder_insert(pack, &rhead->oid, rhead->name);
}
- git_object_free(obj);
+ git_object_free(obj);
}
/* Walk the objects, building a packfile */
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index a5ad1e422..636616717 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -21,12 +21,18 @@ int git_smart__store_refs(transport_smart *t, int flushes)
gitno_buffer *buf = &t->buffer;
git_vector *refs = &t->refs;
int error, flush = 0, recvd;
- const char *line_end;
- git_pkt *pkt;
+ const char *line_end = NULL;
+ git_pkt *pkt = NULL;
+ git_pkt_ref *ref;
+ size_t i;
/* Clear existing refs in case git_remote_connect() is called again
* after git_remote_disconnect().
*/
+ git_vector_foreach(refs, i, ref) {
+ git__free(ref->head.name);
+ git__free(ref);
+ }
git_vector_clear(refs);
do {
@@ -129,7 +135,7 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps)
static int recv_pkt(git_pkt **out, gitno_buffer *buf)
{
const char *ptr = buf->data, *line_end = ptr;
- git_pkt *pkt;
+ git_pkt *pkt = NULL;
int pkt_type, error = 0, ret;
do {
@@ -187,7 +193,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
unsigned int i;
git_reference *ref;
- if (git_reference_list(&refs, repo, GIT_REF_LISTALL) < 0)
+ if (git_reference_list(&refs, repo) < 0)
return -1;
if (git_revwalk_new(&walk, repo) < 0)
@@ -570,7 +576,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
switch (pkt->type) {
case GIT_PKT_OK:
- status = git__malloc(sizeof(push_status));
+ status = git__calloc(1, sizeof(push_status));
GITERR_CHECK_ALLOC(status);
status->msg = NULL;
status->ref = git__strdup(((git_pkt_ok *)pkt)->ref);
@@ -634,8 +640,8 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
static int parse_report(gitno_buffer *buf, git_push *push)
{
- git_pkt *pkt;
- const char *line_end;
+ git_pkt *pkt = NULL;
+ const char *line_end = NULL;
int error, recvd;
for (;;) {
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index e502001cb..d803c812c 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -893,7 +893,7 @@ static int winhttp_connect(
wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
wchar_t host[GIT_WIN_PATH];
int32_t port;
- const char *default_port;
+ const char *default_port = "80";
int ret;
if (!git__prefixcmp(url, prefix_http)) {
diff --git a/src/tree.c b/src/tree.c
index 79cbcffcb..10d131438 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -149,7 +149,7 @@ static int tree_key_search(
/* Initial homing search; find an entry on the tree with
* the same prefix as the filename we're looking for */
if (git_vector_bsearch2(&homing, entries, &homing_search_cmp, &ksearch) < 0)
- return GIT_ENOTFOUND;
+ return GIT_ENOTFOUND; /* just a signal error; not passed back to user */
/* We found a common prefix. Look forward as long as
* there are entries that share the common prefix */
@@ -271,25 +271,27 @@ int git_tree_entry_to_object(
}
static const git_tree_entry *entry_fromname(
- git_tree *tree, const char *name, size_t name_len)
+ const git_tree *tree, const char *name, size_t name_len)
{
size_t idx;
- if (tree_key_search(&idx, &tree->entries, name, name_len) < 0)
+ assert(tree->entries.sorted); /* be safe when we cast away constness */
+
+ if (tree_key_search(&idx, (git_vector *)&tree->entries, name, name_len) < 0)
return NULL;
return git_vector_get(&tree->entries, idx);
}
const git_tree_entry *git_tree_entry_byname(
- git_tree *tree, const char *filename)
+ const git_tree *tree, const char *filename)
{
assert(tree && filename);
return entry_fromname(tree, filename, strlen(filename));
}
const git_tree_entry *git_tree_entry_byindex(
- git_tree *tree, size_t idx)
+ const git_tree *tree, size_t idx)
{
assert(tree);
return git_vector_get(&tree->entries, idx);
@@ -311,9 +313,9 @@ const git_tree_entry *git_tree_entry_byoid(
return NULL;
}
-int git_tree__prefix_position(git_tree *tree, const char *path)
+int git_tree__prefix_position(const git_tree *tree, const char *path)
{
- git_vector *entries = &tree->entries;
+ const git_vector *entries = &tree->entries;
struct tree_key_search ksearch;
size_t at_pos;
@@ -323,8 +325,11 @@ int git_tree__prefix_position(git_tree *tree, const char *path)
ksearch.filename = path;
ksearch.filename_len = strlen(path);
+ assert(tree->entries.sorted); /* be safe when we cast away constness */
+
/* Find tree entry with appropriate prefix */
- git_vector_bsearch2(&at_pos, entries, &homing_search_cmp, &ksearch);
+ git_vector_bsearch2(
+ &at_pos, (git_vector *)entries, &homing_search_cmp, &ksearch);
for (; at_pos < entries->length; ++at_pos) {
const git_tree_entry *entry = entries->contents[at_pos];
@@ -408,6 +413,8 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
buffer += GIT_OID_RAWSZ;
}
+ git_vector_sort(&tree->entries);
+
return 0;
}
@@ -796,7 +803,7 @@ static size_t subpath_len(const char *path)
int git_tree_entry_bypath(
git_tree_entry **entry_out,
- git_tree *root,
+ const git_tree *root,
const char *path)
{
int error = 0;
diff --git a/src/tree.h b/src/tree.h
index 7cb2dd36c..f07039a07 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -47,7 +47,7 @@ int git_tree__parse(void *tree, git_odb_object *obj);
* @param prefix the beginning of a path to find in the tree.
* @return index of the first item at or after the given prefix.
*/
-int git_tree__prefix_position(git_tree *tree, const char *prefix);
+int git_tree__prefix_position(const git_tree *tree, const char *prefix);
/**
diff --git a/src/util.c b/src/util.c
index 8c8bc1a6c..49530f8c8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -685,7 +685,7 @@ static int GIT_STDLIB_CALL git__qsort_r_glue_cmp(
void git__qsort_r(
void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload)
{
-#if defined(__MINGW32__) || defined(__OpenBSD__)
+#if defined(__MINGW32__) || defined(__OpenBSD__) || defined(AMIGA)
git__insertsort_r(els, nel, elsize, NULL, cmp, payload);
#elif defined(GIT_WIN32)
git__qsort_r_glue glue = { cmp, payload };
diff --git a/src/util.h b/src/util.h
index 687afe084..6f876d012 100644
--- a/src/util.h
+++ b/src/util.h
@@ -262,22 +262,22 @@ GIT_INLINE(size_t) git__size_t_powerof2(size_t v)
GIT_INLINE(bool) git__isupper(int c)
{
- return (c >= 'A' && c <= 'Z');
+ return (c >= 'A' && c <= 'Z');
}
GIT_INLINE(bool) git__isalpha(int c)
{
- return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+ return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
}
GIT_INLINE(bool) git__isdigit(int c)
{
- return (c >= '0' && c <= '9');
+ return (c >= '0' && c <= '9');
}
GIT_INLINE(bool) git__isspace(int c)
{
- return (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r' || c == '\v' || c == 0x85 /* Unicode CR+LF */);
+ return (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r' || c == '\v' || c == 0x85 /* Unicode CR+LF */);
}
GIT_INLINE(bool) git__iswildcard(int c)
diff --git a/src/win32/dir.c b/src/win32/dir.c
index 95ae5060e..8c51d8378 100644
--- a/src/win32/dir.c
+++ b/src/win32/dir.c
@@ -32,7 +32,7 @@ git__DIR *git__opendir(const char *dir)
if (!dir || !init_filter(filter, sizeof(filter), dir))
return NULL;
- new = git__malloc(sizeof(*new));
+ new = git__calloc(1, sizeof(*new));
if (!new)
return NULL;
diff --git a/src/win32/findfile.c b/src/win32/findfile.c
index bc36b6b45..5dd3de13d 100644
--- a/src/win32/findfile.c
+++ b/src/win32/findfile.c
@@ -235,4 +235,3 @@ int git_win32__find_xdg_dirs(git_buf *out)
return win32_find_existing_dirs(out, global_tmpls, temp);
}
-
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 4d56299f7..f9967e04a 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -295,7 +295,18 @@ int p_getcwd(char *buffer_out, size_t size)
int p_stat(const char* path, struct stat* buf)
{
- return do_lstat(path, buf, 0);
+ char target[GIT_WIN_PATH];
+ int error = 0;
+
+ error = do_lstat(path, buf, 0);
+
+ /* We need not do this in a loop to unwind chains of symlinks since
+ * p_readlink calls GetFinalPathNameByHandle which does it for us. */
+ if (error >= 0 && S_ISLNK(buf->st_mode) &&
+ (error = p_readlink(path, target, GIT_WIN_PATH)) >= 0)
+ error = do_lstat(target, buf, 0);
+
+ return error;
}
int p_chdir(const char* path)
@@ -314,9 +325,20 @@ int p_chmod(const char* path, mode_t mode)
int p_rmdir(const char* path)
{
+ int error;
wchar_t buf[GIT_WIN_PATH];
git__utf8_to_16(buf, GIT_WIN_PATH, path);
- return _wrmdir(buf);
+
+ error = _wrmdir(buf);
+
+ /* _wrmdir() is documented to return EACCES if "A program has an open
+ * handle to the directory." This sounds like what everybody else calls
+ * EBUSY. Let's convert appropriate error codes.
+ */
+ if (GetLastError() == ERROR_SHARING_VIOLATION)
+ errno = EBUSY;
+
+ return error;
}
int p_hide_directory__w32(const char *path)
@@ -457,29 +479,29 @@ int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags)
* Borrowed from http://old.nabble.com/Porting-localtime_r-and-gmtime_r-td15282276.html
* On Win32, `gmtime_r` doesn't exist but `gmtime` is threadsafe, so we can use that
*/
-struct tm *
-p_localtime_r (const time_t *timer, struct tm *result)
-{
- struct tm *local_result;
- local_result = localtime (timer);
-
- if (local_result == NULL || result == NULL)
- return NULL;
-
- memcpy (result, local_result, sizeof (struct tm));
- return result;
-}
-struct tm *
-p_gmtime_r (const time_t *timer, struct tm *result)
-{
- struct tm *local_result;
- local_result = gmtime (timer);
-
- if (local_result == NULL || result == NULL)
- return NULL;
-
- memcpy (result, local_result, sizeof (struct tm));
- return result;
+struct tm *
+p_localtime_r (const time_t *timer, struct tm *result)
+{
+ struct tm *local_result;
+ local_result = localtime (timer);
+
+ if (local_result == NULL || result == NULL)
+ return NULL;
+
+ memcpy (result, local_result, sizeof (struct tm));
+ return result;
+}
+struct tm *
+p_gmtime_r (const time_t *timer, struct tm *result)
+{
+ struct tm *local_result;
+ local_result = gmtime (timer);
+
+ if (local_result == NULL || result == NULL)
+ return NULL;
+
+ memcpy (result, local_result, sizeof (struct tm));
+ return result;
}
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
@@ -492,44 +514,44 @@ p_gmtime_r (const time_t *timer, struct tm *result)
#define _TIMEZONE_DEFINED
struct timezone
{
- int tz_minuteswest; /* minutes W of Greenwich */
- int tz_dsttime; /* type of dst correction */
+ int tz_minuteswest; /* minutes W of Greenwich */
+ int tz_dsttime; /* type of dst correction */
};
#endif
-
+
int p_gettimeofday(struct timeval *tv, struct timezone *tz)
{
- FILETIME ft;
- unsigned __int64 tmpres = 0;
- static int tzflag;
-
- if (NULL != tv)
- {
- GetSystemTimeAsFileTime(&ft);
-
- tmpres |= ft.dwHighDateTime;
- tmpres <<= 32;
- tmpres |= ft.dwLowDateTime;
-
- /*converting file time to unix epoch*/
- tmpres /= 10; /*convert into microseconds*/
- tmpres -= DELTA_EPOCH_IN_MICROSECS;
- tv->tv_sec = (long)(tmpres / 1000000UL);
- tv->tv_usec = (long)(tmpres % 1000000UL);
- }
-
- if (NULL != tz)
- {
- if (!tzflag)
- {
- _tzset();
- tzflag++;
- }
- tz->tz_minuteswest = _timezone / 60;
- tz->tz_dsttime = _daylight;
- }
-
- return 0;
+ FILETIME ft;
+ unsigned __int64 tmpres = 0;
+ static int tzflag;
+
+ if (NULL != tv)
+ {
+ GetSystemTimeAsFileTime(&ft);
+
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+
+ /*converting file time to unix epoch*/
+ tmpres /= 10; /*convert into microseconds*/
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+ tv->tv_sec = (long)(tmpres / 1000000UL);
+ tv->tv_usec = (long)(tmpres % 1000000UL);
+ }
+
+ if (NULL != tz)
+ {
+ if (!tzflag)
+ {
+ _tzset();
+ tzflag++;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+
+ return 0;
}
int p_inet_pton(int af, const char* src, void* dst)
diff --git a/tests-clar/checkout/tree.c b/tests-clar/checkout/tree.c
index eb129f34e..462a46c83 100644
--- a/tests-clar/checkout/tree.c
+++ b/tests-clar/checkout/tree.c
@@ -363,7 +363,7 @@ void assert_conflict(
git_index *index;
git_object *hack_tree;
git_reference *branch, *head;
- git_buf file_path = GIT_BUF_INIT;
+ git_buf file_path = GIT_BUF_INIT;
cl_git_pass(git_repository_index(&index, g_repo));
@@ -526,3 +526,66 @@ void test_checkout_tree__can_write_to_empty_dirs(void)
git_object_free(obj);
}
+
+void test_checkout_tree__fails_when_dir_in_use(void)
+{
+#ifdef GIT_WIN32
+ git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
+ git_oid oid;
+ git_object *obj = NULL;
+
+ opts.checkout_strategy = GIT_CHECKOUT_FORCE;
+
+ cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+ cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+ cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+ cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+ git_object_free(obj);
+
+ cl_git_pass(p_chdir("testrepo/a"));
+
+ cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/master"));
+ cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+ cl_git_fail(git_checkout_tree(g_repo, obj, &opts));
+
+ cl_git_pass(p_chdir("../.."));
+
+ cl_assert(git_path_is_empty_dir("testrepo/a"));
+#endif
+}
+
+void test_checkout_tree__can_continue_when_dir_in_use(void)
+{
+#ifdef GIT_WIN32
+ git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
+ git_oid oid;
+ git_object *obj = NULL;
+
+ opts.checkout_strategy = GIT_CHECKOUT_FORCE |
+ GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES;
+
+ cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
+ cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+ cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+ cl_assert(git_path_isfile("testrepo/a/b.txt"));
+
+ git_object_free(obj);
+
+ cl_git_pass(p_chdir("testrepo/a"));
+
+ cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/master"));
+ cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+ cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+ cl_git_pass(p_chdir("../.."));
+
+ cl_assert(git_path_is_empty_dir("testrepo/a"));
+#endif
+}
diff --git a/tests-clar/clar_libgit2.c b/tests-clar/clar_libgit2.c
index 68d17162b..de0e41bf7 100644
--- a/tests-clar/clar_libgit2.c
+++ b/tests-clar/clar_libgit2.c
@@ -190,6 +190,18 @@ git_repository *cl_git_sandbox_init(const char *sandbox)
return _cl_repo;
}
+git_repository *cl_git_sandbox_reopen(void)
+{
+ if (_cl_repo) {
+ git_repository_free(_cl_repo);
+ _cl_repo = NULL;
+
+ cl_git_pass(git_repository_open(&_cl_repo, _cl_sandbox));
+ }
+
+ return _cl_repo;
+}
+
void cl_git_sandbox_cleanup(void)
{
if (_cl_repo) {
diff --git a/tests-clar/clar_libgit2.h b/tests-clar/clar_libgit2.h
index 93909d8a5..3fcf45a37 100644
--- a/tests-clar/clar_libgit2.h
+++ b/tests-clar/clar_libgit2.h
@@ -60,6 +60,7 @@ int cl_rename(const char *source, const char *dest);
git_repository *cl_git_sandbox_init(const char *sandbox);
void cl_git_sandbox_cleanup(void);
+git_repository *cl_git_sandbox_reopen(void);
/* Local-repo url helpers */
const char* cl_git_fixture_url(const char *fixturename);
diff --git a/tests-clar/clone/empty.c b/tests-clar/clone/empty.c
index f190523b6..f92fa6cbb 100644
--- a/tests-clar/clone/empty.c
+++ b/tests-clar/clone/empty.c
@@ -48,13 +48,13 @@ void test_clone_empty__can_clone_an_empty_local_repo_barely(void)
cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&ref, g_repo_cloned, local_name));
/* ...one can still retrieve the name of the remote tracking reference */
- cl_assert_equal_i((int)strlen(expected_tracked_branch_name) + 1,
+ cl_assert_equal_i((int)strlen(expected_tracked_branch_name) + 1,
git_branch_upstream_name(buffer, 1024, g_repo_cloned, local_name));
cl_assert_equal_s(expected_tracked_branch_name, buffer);
/* ...and the name of the remote... */
- cl_assert_equal_i((int)strlen(expected_remote_name) + 1,
+ cl_assert_equal_i((int)strlen(expected_remote_name) + 1,
git_branch_remote_name(buffer, 1024, g_repo_cloned, expected_tracked_branch_name));
cl_assert_equal_s(expected_remote_name, buffer);
diff --git a/tests-clar/clone/nonetwork.c b/tests-clar/clone/nonetwork.c
index 545fe3a06..8aae1fb52 100644
--- a/tests-clar/clone/nonetwork.c
+++ b/tests-clar/clone/nonetwork.c
@@ -172,6 +172,7 @@ void test_clone_nonetwork__custom_push_spec(void)
void test_clone_nonetwork__custom_autotag(void)
{
+ git_remote *origin;
git_strarray tags = {0};
g_options.remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
@@ -180,7 +181,26 @@ void test_clone_nonetwork__custom_autotag(void)
cl_git_pass(git_tag_list(&tags, g_repo));
cl_assert_equal_sz(0, tags.count);
+ cl_git_pass(git_remote_load(&origin, g_repo, "origin"));
+ cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_NONE, origin->download_tags);
+
+ git_strarray_free(&tags);
+ git_remote_free(origin);
+}
+
+void test_clone_nonetwork__custom_autotag_tags_all(void)
+{
+ git_strarray tags = {0};
+ git_remote *origin;
+
+ g_options.remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
+ cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+ cl_git_pass(git_remote_load(&origin, g_repo, "origin"));
+ cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_ALL, origin->download_tags);
+
git_strarray_free(&tags);
+ git_remote_free(origin);
}
void test_clone_nonetwork__cope_with_already_existing_directory(void)
diff --git a/tests-clar/commit/parse.c b/tests-clar/commit/parse.c
index 8de4401dc..415860a6e 100644
--- a/tests-clar/commit/parse.c
+++ b/tests-clar/commit/parse.c
@@ -386,10 +386,6 @@ This commit has a few LF at the start of the commit message";
\n\
This commit has a few LF at the start of the commit message";
- commit = (git_commit*)git__malloc(sizeof(git_commit));
- memset(commit, 0x0, sizeof(git_commit));
- commit->object.repo = g_repo;
-
cl_git_pass(parse_commit(&commit, buffer));
cl_assert_equal_s(message, git_commit_message(commit));
git_commit__free(commit);
diff --git a/tests-clar/commit/signature.c b/tests-clar/commit/signature.c
index 9364efb10..aef72a80d 100644
--- a/tests-clar/commit/signature.c
+++ b/tests-clar/commit/signature.c
@@ -54,8 +54,8 @@ void test_commit_signature__create_empties(void)
cl_git_fail(try_build_signature("", "emeric.fermas@gmail.com", 1234567890, 60));
cl_git_fail(try_build_signature(" ", "emeric.fermas@gmail.com", 1234567890, 60));
- cl_git_fail(try_build_signature("nulltoken", "", 1234567890, 60));
- cl_git_fail(try_build_signature("nulltoken", " ", 1234567890, 60));
+ cl_git_pass(try_build_signature("nulltoken", "", 1234567890, 60));
+ cl_git_pass(try_build_signature("nulltoken", " ", 1234567890, 60));
}
void test_commit_signature__create_one_char(void)
diff --git a/tests-clar/commit/write.c b/tests-clar/commit/write.c
index e9946af89..73436b74b 100644
--- a/tests-clar/commit/write.c
+++ b/tests-clar/commit/write.c
@@ -115,7 +115,7 @@ void test_commit_write__root(void)
head_old = git__strdup(git_reference_symbolic_target(head));
cl_assert(head_old != NULL);
git_reference_free(head);
-
+
cl_git_pass(git_reference_symbolic_create(&head, g_repo, "HEAD", branch_name, 1));
cl_git_pass(git_commit_create_v(
diff --git a/tests-clar/config/global.c b/tests-clar/config/global.c
new file mode 100644
index 000000000..2ecdf97d8
--- /dev/null
+++ b/tests-clar/config/global.c
@@ -0,0 +1,67 @@
+#include "clar_libgit2.h"
+#include "buffer.h"
+#include "fileops.h"
+
+void test_config_global__initialize(void)
+{
+ git_buf path = GIT_BUF_INIT;
+
+ cl_must_pass(p_mkdir("home", 0777));
+ cl_git_pass(git_path_prettify(&path, "home", NULL));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+
+ cl_must_pass(p_mkdir("xdg", 0777));
+ cl_git_pass(git_path_prettify(&path, "xdg", NULL));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, NULL));
+
+ git_buf_free(&path);
+}
+
+void test_config_global__cleanup(void)
+{
+ cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
+ cl_git_pass(git_futils_rmdir_r("xdg", NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
+void test_config_global__open_global(void)
+{
+ git_config *cfg, *global, *selected, *dummy;
+
+ cl_git_pass(git_config_open_default(&cfg));
+ cl_git_pass(git_config_open_level(&global, cfg, GIT_CONFIG_LEVEL_GLOBAL));
+ cl_git_fail(git_config_open_level(&dummy, cfg, GIT_CONFIG_LEVEL_XDG));
+ cl_git_pass(git_config_open_global(&selected, cfg));
+
+ git_config_free(selected);
+ git_config_free(global);
+ git_config_free(cfg);
+}
+
+void test_config_global__open_xdg(void)
+{
+ git_config *cfg, *xdg, *selected;
+ const char *val, *str = "teststring";
+ const char *key = "this.variable";
+
+ p_setenv("XDG_CONFIG_HOME", "xdg", 1);
+
+ cl_must_pass(p_mkdir("xdg/git/", 0777));
+ cl_git_mkfile("xdg/git/config", "");
+
+ cl_git_pass(git_config_open_default(&cfg));
+ cl_git_pass(git_config_open_level(&xdg, cfg, GIT_CONFIG_LEVEL_XDG));
+ cl_git_pass(git_config_open_global(&selected, cfg));
+
+ cl_git_pass(git_config_set_string(xdg, key, str));
+ cl_git_pass(git_config_get_string(&val, selected, key));
+ cl_assert_equal_s(str, val);
+
+ git_config_free(selected);
+ git_config_free(xdg);
+ git_config_free(cfg);
+}
diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c
index c85826886..9f943d0f6 100644
--- a/tests-clar/config/read.c
+++ b/tests-clar/config/read.c
@@ -449,10 +449,3 @@ void test_config_read__can_load_and_parse_an_empty_config_file(void)
git_config_free(cfg);
}
-
-void test_config_read__cannot_load_a_non_existing_config_file(void)
-{
- git_config *cfg;
-
- cl_assert_equal_i(GIT_ENOTFOUND, git_config_open_ondisk(&cfg, "./no.config"));
-}
diff --git a/tests-clar/diff/diff_helpers.c b/tests-clar/diff/diff_helpers.c
index e7f97c034..75eda0520 100644
--- a/tests-clar/diff/diff_helpers.c
+++ b/tests-clar/diff/diff_helpers.c
@@ -97,20 +97,15 @@ int diff_line_cb(
e->lines++;
switch (line_origin) {
case GIT_DIFF_LINE_CONTEXT:
+ case GIT_DIFF_LINE_CONTEXT_EOFNL: /* techically not a line */
e->line_ctxt++;
break;
case GIT_DIFF_LINE_ADDITION:
- e->line_adds++;
- break;
- case GIT_DIFF_LINE_ADD_EOFNL:
- /* technically not a line add, but we'll count it as such */
+ case GIT_DIFF_LINE_ADD_EOFNL: /* technically not a line add */
e->line_adds++;
break;
case GIT_DIFF_LINE_DELETION:
- e->line_dels++;
- break;
- case GIT_DIFF_LINE_DEL_EOFNL:
- /* technically not a line delete, but we'll count it as such */
+ case GIT_DIFF_LINE_DEL_EOFNL: /* technically not a line delete */
e->line_dels++;
break;
default:
diff --git a/tests-clar/diff/patch.c b/tests-clar/diff/patch.c
index 40b191dd5..f9e913a74 100644
--- a/tests-clar/diff/patch.c
+++ b/tests-clar/diff/patch.c
@@ -226,6 +226,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
size_t hdrlen, hunklen, textlen;
char origin;
int oldno, newno;
+ git_buf old_content = GIT_BUF_INIT, actual = GIT_BUF_INIT;
const char *new_content = "The Song of Seven Cities\n------------------------\n\nI WAS Lord of Cities very sumptuously builded.\nSeven roaring Cities paid me tribute from afar.\nIvory their outposts were--the guardrooms of them gilded,\nAnd garrisoned with Amazons invincible in war.\n\nThis is some new text;\nNot as good as the old text;\nBut here it is.\n\nSo they warred and trafficked only yesterday, my Cities.\nTo-day there is no mark or mound of where my Cities stood.\nFor the River rose at midnight and it washed away my Cities.\nThey are evened with Atlantis and the towns before the Flood.\n\nRain on rain-gorged channels raised the water-levels round them,\nFreshet backed on freshet swelled and swept their world from sight,\nTill the emboldened floods linked arms and, flashing forward, drowned them--\nDrowned my Seven Cities and their peoples in one night!\n\nLow among the alders lie their derelict foundations,\nThe beams wherein they trusted and the plinths whereon they built--\nMy rulers and their treasure and their unborn populations,\nDead, destroyed, aborted, and defiled with mud and silt!\n\nAnother replacement;\nBreaking up the poem;\nGenerating some hunks.\n\nTo the sound of trumpets shall their seed restore my Cities\nWealthy and well-weaponed, that once more may I behold\nAll the world go softly when it walks before my Cities,\nAnd the horses and the chariots fleeing from them as of old!\n\n -- Rudyard Kipling\n";
g_repo = cl_git_sandbox_init("renames");
@@ -233,6 +234,9 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_git_pass(git_config_new(&cfg));
git_repository_set_config(g_repo, cfg);
+ cl_git_pass(
+ git_futils_readbuffer(&old_content, "renames/songof7cities.txt"));
+
cl_git_rewritefile("renames/songof7cities.txt", new_content);
cl_git_pass(git_repository_head_tree(&head, g_repo));
@@ -263,21 +267,24 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_git_pass(git_diff_patch_get_line_in_hunk(
&origin, &text, &textlen, &oldno, &newno, patch, 0, 0));
cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
- cl_assert(strncmp("Ivory their outposts were--the guardrooms of them gilded,\n", text, textlen) == 0);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("Ivory their outposts were--the guardrooms of them gilded,\n", actual.ptr);
cl_assert_equal_i(6, oldno);
cl_assert_equal_i(6, newno);
cl_git_pass(git_diff_patch_get_line_in_hunk(
&origin, &text, &textlen, &oldno, &newno, patch, 0, 3));
cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
- cl_assert(strncmp("All the world went softly when it walked before my Cities--\n", text, textlen) == 0);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("All the world went softly when it walked before my Cities--\n", actual.ptr);
cl_assert_equal_i(9, oldno);
cl_assert_equal_i(-1, newno);
cl_git_pass(git_diff_patch_get_line_in_hunk(
&origin, &text, &textlen, &oldno, &newno, patch, 0, 12));
cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
- cl_assert(strncmp("This is some new text;\n", text, textlen) == 0);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("This is some new text;\n", actual.ptr);
cl_assert_equal_i(-1, oldno);
cl_assert_equal_i(9, newno);
@@ -298,37 +305,116 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
cl_git_pass(git_diff_patch_get_line_in_hunk(
&origin, &text, &textlen, &oldno, &newno, patch, 1, 0));
cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
- cl_assert(strncmp("My rulers and their treasure and their unborn populations,\n", text, textlen) == 0);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("My rulers and their treasure and their unborn populations,\n", actual.ptr);
cl_assert_equal_i(31, oldno);
cl_assert_equal_i(25, newno);
cl_git_pass(git_diff_patch_get_line_in_hunk(
&origin, &text, &textlen, &oldno, &newno, patch, 1, 3));
cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
- cl_assert(strncmp("The Daughters of the Palace whom they cherished in my Cities,\n", text, textlen) == 0);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("The Daughters of the Palace whom they cherished in my Cities,\n", actual.ptr);
cl_assert_equal_i(34, oldno);
cl_assert_equal_i(-1, newno);
cl_git_pass(git_diff_patch_get_line_in_hunk(
&origin, &text, &textlen, &oldno, &newno, patch, 1, 12));
cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
- cl_assert(strncmp("Another replacement;\n", text, textlen) == 0);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("Another replacement;\n", actual.ptr);
cl_assert_equal_i(-1, oldno);
cl_assert_equal_i(28, newno);
git_diff_patch_free(patch);
git_diff_list_free(diff);
+
+ /* Let's check line numbers when there is no newline */
+
+ git_buf_rtrim(&old_content);
+ cl_git_rewritefile("renames/songof7cities.txt", old_content.ptr);
+
+ cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, head, &opt));
+
+ cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
+
+ cl_git_pass(git_diff_get_patch(&patch, &delta, diff, 0));
+
+ cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+ cl_assert_equal_i(1, (int)git_diff_patch_num_hunks(patch));
+
+ /* check hunk 0 */
+
+ cl_git_pass(
+ git_diff_patch_get_hunk(&range, &hdr, &hdrlen, &hunklen, patch, 0));
+
+ cl_assert_equal_i(6, (int)hunklen);
+
+ cl_assert_equal_i(46, (int)range->old_start);
+ cl_assert_equal_i(4, (int)range->old_lines);
+ cl_assert_equal_i(46, (int)range->new_start);
+ cl_assert_equal_i(4, (int)range->new_lines);
+
+ cl_assert_equal_i(6, (int)git_diff_patch_num_lines_in_hunk(patch, 0));
+
+ cl_git_pass(git_diff_patch_get_line_in_hunk(
+ &origin, &text, &textlen, &oldno, &newno, patch, 0, 1));
+ cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("And the horses and the chariots fleeing from them as of old!\n", actual.ptr);
+ cl_assert_equal_i(47, oldno);
+ cl_assert_equal_i(47, newno);
+
+ cl_git_pass(git_diff_patch_get_line_in_hunk(
+ &origin, &text, &textlen, &oldno, &newno, patch, 0, 2));
+ cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("\n", actual.ptr);
+ cl_assert_equal_i(48, oldno);
+ cl_assert_equal_i(48, newno);
+
+ cl_git_pass(git_diff_patch_get_line_in_hunk(
+ &origin, &text, &textlen, &oldno, &newno, patch, 0, 3));
+ cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s(" -- Rudyard Kipling\n", actual.ptr);
+ cl_assert_equal_i(49, oldno);
+ cl_assert_equal_i(-1, newno);
+
+ cl_git_pass(git_diff_patch_get_line_in_hunk(
+ &origin, &text, &textlen, &oldno, &newno, patch, 0, 4));
+ cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s(" -- Rudyard Kipling", actual.ptr);
+ cl_assert_equal_i(-1, oldno);
+ cl_assert_equal_i(49, newno);
+
+ cl_git_pass(git_diff_patch_get_line_in_hunk(
+ &origin, &text, &textlen, &oldno, &newno, patch, 0, 5));
+ cl_assert_equal_i(GIT_DIFF_LINE_DEL_EOFNL, (int)origin);
+ cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_assert_equal_s("\n\\ No newline at end of file\n", actual.ptr);
+ cl_assert_equal_i(-1, oldno);
+ cl_assert_equal_i(49, newno);
+
+ git_diff_patch_free(patch);
+ git_diff_list_free(diff);
+
+ git_buf_free(&actual);
+ git_buf_free(&old_content);
git_tree_free(head);
git_config_free(cfg);
}
static void check_single_patch_stats(
- git_repository *repo, size_t hunks, size_t adds, size_t dels)
+ git_repository *repo, size_t hunks,
+ size_t adds, size_t dels, size_t ctxt,
+ const char *expected)
{
git_diff_list *diff;
git_diff_patch *patch;
const git_diff_delta *delta;
- size_t actual_adds, actual_dels;
+ size_t actual_ctxt, actual_adds, actual_dels;
cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, NULL));
@@ -339,12 +425,52 @@ static void check_single_patch_stats(
cl_assert_equal_i((int)hunks, (int)git_diff_patch_num_hunks(patch));
- cl_git_pass(
- git_diff_patch_line_stats(NULL, &actual_adds, &actual_dels, patch));
+ cl_git_pass( git_diff_patch_line_stats(
+ &actual_ctxt, &actual_adds, &actual_dels, patch) );
+ cl_assert_equal_sz(ctxt, actual_ctxt);
cl_assert_equal_sz(adds, actual_adds);
cl_assert_equal_sz(dels, actual_dels);
+ if (expected != NULL) {
+ char *text;
+ cl_git_pass(git_diff_patch_to_str(&text, patch));
+ cl_assert_equal_s(expected, text);
+ git__free(text);
+ }
+
+ /* walk lines in hunk with basic sanity checks */
+ for (; hunks > 0; --hunks) {
+ size_t i, max_i;
+ int lastoldno = -1, oldno, lastnewno = -1, newno;
+ char origin;
+
+ max_i = git_diff_patch_num_lines_in_hunk(patch, hunks - 1);
+
+ for (i = 0; i < max_i; ++i) {
+ int expected = 1;
+
+ cl_git_pass(git_diff_patch_get_line_in_hunk(
+ &origin, NULL, NULL, &oldno, &newno, patch, hunks - 1, i));
+
+ if (origin == GIT_DIFF_LINE_ADD_EOFNL ||
+ origin == GIT_DIFF_LINE_DEL_EOFNL ||
+ origin == GIT_DIFF_LINE_CONTEXT_EOFNL)
+ expected = 0;
+
+ if (oldno >= 0) {
+ if (lastoldno >= 0)
+ cl_assert_equal_i(expected, oldno - lastoldno);
+ lastoldno = oldno;
+ }
+ if (newno >= 0) {
+ if (lastnewno >= 0)
+ cl_assert_equal_i(expected, newno - lastnewno);
+ lastnewno = newno;
+ }
+ }
+ }
+
git_diff_patch_free(patch);
git_diff_list_free(diff);
}
@@ -369,14 +495,14 @@ void test_diff_patch__line_counts_with_eofnl(void)
git_buf_consume(&content, end);
cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
- check_single_patch_stats(g_repo, 1, 0, 1);
+ check_single_patch_stats(g_repo, 1, 0, 1, 3, NULL);
/* remove trailing whitespace */
git_buf_rtrim(&content);
cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
- check_single_patch_stats(g_repo, 2, 1, 2);
+ check_single_patch_stats(g_repo, 2, 1, 2, 6, NULL);
/* add trailing whitespace */
@@ -388,7 +514,45 @@ void test_diff_patch__line_counts_with_eofnl(void)
cl_git_pass(git_buf_putc(&content, '\n'));
cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
- check_single_patch_stats(g_repo, 1, 1, 1);
+ check_single_patch_stats(g_repo, 1, 1, 1, 3, NULL);
+
+ /* no trailing whitespace as context line */
+
+ {
+ /* walk back a couple lines, make space and insert char */
+ char *scan = content.ptr + content.size;
+ int i;
+
+ for (i = 0; i < 5; ++i) {
+ for (--scan; scan > content.ptr && *scan != '\n'; --scan)
+ /* seek to prev \n */;
+ }
+ cl_assert(scan > content.ptr);
+
+ /* overwrite trailing \n with right-shifted content */
+ memmove(scan + 1, scan, content.size - (scan - content.ptr) - 1);
+ /* insert '#' char into space we created */
+ scan[1] = '#';
+ }
+ cl_git_rewritefile("renames/songof7cities.txt", content.ptr);
+
+ check_single_patch_stats(
+ g_repo, 1, 1, 1, 6,
+ /* below is pasted output of 'git diff' with fn context removed */
+ "diff --git a/songof7cities.txt b/songof7cities.txt\n"
+ "index 378a7d9..3d0154e 100644\n"
+ "--- a/songof7cities.txt\n"
+ "+++ b/songof7cities.txt\n"
+ "@@ -42,7 +42,7 @@\n"
+ " \n"
+ " To the sound of trumpets shall their seed restore my Cities\n"
+ " Wealthy and well-weaponed, that once more may I behold\n"
+ "-All the world go softly when it walks before my Cities,\n"
+ "+#All the world go softly when it walks before my Cities,\n"
+ " And the horses and the chariots fleeing from them as of old!\n"
+ " \n"
+ " -- Rudyard Kipling\n"
+ "\\ No newline at end of file\n");
git_buf_free(&content);
git_config_free(cfg);
diff --git a/tests-clar/diff/rename.c b/tests-clar/diff/rename.c
index 5a8af93bb..1349d4013 100644
--- a/tests-clar/diff/rename.c
+++ b/tests-clar/diff/rename.c
@@ -364,7 +364,7 @@ void test_diff_rename__handles_small_files(void)
cl_git_pass(git_repository_index(&index, g_repo));
tree = resolve_commit_oid_to_tree(g_repo, tree_sha);
-
+
cl_git_rewritefile("renames/songof7cities.txt", "single line\n");
cl_git_pass(git_index_add_bypath(index, "songof7cities.txt"));
@@ -391,3 +391,58 @@ void test_diff_rename__working_directory_changes(void)
/* and with / without CRLF changes */
}
+
+void test_diff_rename__patch(void)
+{
+ const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+ const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
+ git_tree *old_tree, *new_tree;
+ git_diff_list *diff;
+ git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+ git_diff_patch *patch;
+ const git_diff_delta *delta;
+ char *text;
+ const char *expected = "diff --git a/sixserving.txt b/ikeepsix.txt\nindex ad0a8e5..36020db 100644\n--- a/sixserving.txt\n+++ b/ikeepsix.txt\n@@ -1,3 +1,6 @@\n+I Keep Six Honest Serving-Men\n+=============================\n+\n I KEEP six honest serving-men\n (They taught me all I knew);\n Their names are What and Why and When\n@@ -21,4 +24,4 @@\n One million Hows, two million Wheres,\n And seven million Whys!\n \n- -- Rudyard Kipling\n+ -- Rudyard Kipling\n";
+
+ old_tree = resolve_commit_oid_to_tree(g_repo, sha0);
+ new_tree = resolve_commit_oid_to_tree(g_repo, sha1);
+
+ diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+ cl_git_pass(git_diff_tree_to_tree(
+ &diff, g_repo, old_tree, new_tree, &diffopts));
+
+ opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
+ cl_git_pass(git_diff_find_similar(diff, &opts));
+
+ /* == Changes =====================================================
+ * sixserving.txt -> ikeepsix.txt (copy, add title, >80% match)
+ * sevencities.txt (no change)
+ * sixserving.txt -> sixserving.txt (indentation change)
+ * songofseven.txt -> songofseven.txt (major rewrite, <20% match - split)
+ */
+
+ cl_assert_equal_i(4, (int)git_diff_num_deltas(diff));
+
+ cl_git_pass(git_diff_get_patch(&patch, &delta, diff, 0));
+ cl_assert_equal_i(GIT_DELTA_COPIED, (int)delta->status);
+
+ cl_git_pass(git_diff_patch_to_str(&text, patch));
+ cl_assert_equal_s(expected, text);
+ git__free(text);
+
+ git_diff_patch_free(patch);
+
+ cl_git_pass(git_diff_get_patch(NULL, &delta, diff, 1));
+ cl_assert_equal_i(GIT_DELTA_UNMODIFIED, (int)delta->status);
+
+ cl_git_pass(git_diff_get_patch(NULL, &delta, diff, 2));
+ cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+
+ cl_git_pass(git_diff_get_patch(NULL, &delta, diff, 3));
+ cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
+
+ git_diff_list_free(diff);
+ git_tree_free(old_tree);
+ git_tree_free(new_tree);
+}
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index 94fd7165d..18182ea96 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -1220,3 +1220,28 @@ void test_diff_workdir__untracked_directory_scenarios(void)
git_diff_list_free(diff);
}
+
+
+void test_diff_workdir__untracked_directory_comes_last(void)
+{
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff = NULL;
+
+ g_repo = cl_git_sandbox_init("renames");
+
+ cl_git_mkfile("renames/.gitignore", "*.ign\n");
+ cl_git_pass(p_mkdir("renames/zzz_untracked", 0777));
+ cl_git_mkfile("renames/zzz_untracked/an.ign", "ignore me please");
+ cl_git_mkfile("renames/zzz_untracked/skip.ign", "ignore me really");
+ cl_git_mkfile("renames/zzz_untracked/test.ign", "ignore me now");
+
+ opts.context_lines = 3;
+ opts.interhunk_lines = 1;
+ opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+ cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
+
+ cl_assert(diff != NULL);
+
+ git_diff_list_free(diff);
+}
diff --git a/tests-clar/index/names.c b/tests-clar/index/names.c
index 68615531a..95a560ee4 100644
--- a/tests-clar/index/names.c
+++ b/tests-clar/index/names.c
@@ -21,7 +21,7 @@ void test_index_names__cleanup(void)
{
git_index_free(repo_index);
repo_index = NULL;
-
+
cl_git_sandbox_cleanup();
}
@@ -32,14 +32,14 @@ void test_index_names__add(void)
cl_git_pass(git_index_name_add(repo_index, "ancestor", "ours", "theirs"));
cl_git_pass(git_index_name_add(repo_index, "ancestor2", "ours2", NULL));
cl_git_pass(git_index_name_add(repo_index, "ancestor3", NULL, "theirs3"));
-
+
cl_assert(git_index_name_entrycount(repo_index) == 3);
-
+
conflict_name = git_index_name_get_byindex(repo_index, 0);
cl_assert(strcmp(conflict_name->ancestor, "ancestor") == 0);
cl_assert(strcmp(conflict_name->ours, "ours") == 0);
cl_assert(strcmp(conflict_name->theirs, "theirs") == 0);
-
+
conflict_name = git_index_name_get_byindex(repo_index, 1);
cl_assert(strcmp(conflict_name->ancestor, "ancestor2") == 0);
cl_assert(strcmp(conflict_name->ours, "ours2") == 0);
@@ -54,31 +54,31 @@ void test_index_names__add(void)
void test_index_names__roundtrip(void)
{
const git_index_name_entry *conflict_name;
-
+
cl_git_pass(git_index_name_add(repo_index, "ancestor", "ours", "theirs"));
cl_git_pass(git_index_name_add(repo_index, "ancestor2", "ours2", NULL));
cl_git_pass(git_index_name_add(repo_index, "ancestor3", NULL, "theirs3"));
-
+
cl_git_pass(git_index_write(repo_index));
git_index_clear(repo_index);
cl_assert(git_index_name_entrycount(repo_index) == 0);
-
+
cl_git_pass(git_index_read(repo_index));
cl_assert(git_index_name_entrycount(repo_index) == 3);
-
+
conflict_name = git_index_name_get_byindex(repo_index, 0);
cl_assert(strcmp(conflict_name->ancestor, "ancestor") == 0);
cl_assert(strcmp(conflict_name->ours, "ours") == 0);
cl_assert(strcmp(conflict_name->theirs, "theirs") == 0);
-
+
conflict_name = git_index_name_get_byindex(repo_index, 1);
cl_assert(strcmp(conflict_name->ancestor, "ancestor2") == 0);
cl_assert(strcmp(conflict_name->ours, "ours2") == 0);
cl_assert(conflict_name->theirs == NULL);
-
+
conflict_name = git_index_name_get_byindex(repo_index, 2);
cl_assert(strcmp(conflict_name->ancestor, "ancestor3") == 0);
cl_assert(conflict_name->ours == NULL);
cl_assert(strcmp(conflict_name->theirs, "theirs3") == 0);
-
+
}
diff --git a/tests-clar/index/reuc.c b/tests-clar/index/reuc.c
index 0e38a92f3..69ed4a933 100644
--- a/tests-clar/index/reuc.c
+++ b/tests-clar/index/reuc.c
@@ -232,7 +232,7 @@ void test_index_reuc__remove(void)
cl_git_pass(git_index_reuc_remove(repo_index, 0));
cl_git_fail(git_index_reuc_remove(repo_index, 1));
-
+
cl_assert_equal_i(1, git_index_reuc_entrycount(repo_index));
cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0));
@@ -283,7 +283,7 @@ void test_index_reuc__write(void)
/* ensure sort order was round-tripped correct */
cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 0));
cl_assert_equal_s("one.txt", reuc->path);
-
+
cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 1));
cl_assert_equal_s("two.txt", reuc->path);
}
@@ -296,41 +296,41 @@ static int reuc_entry_exists(void)
void test_index_reuc__cleaned_on_reset_hard(void)
{
git_object *target;
-
+
retrieve_target_from_oid(&target, repo, "3a34580a35add43a4cf361e8e9a30060a905c876");
-
+
test_index_reuc__add();
cl_git_pass(git_reset(repo, target, GIT_RESET_HARD));
cl_assert(reuc_entry_exists() == false);
-
+
git_object_free(target);
}
void test_index_reuc__cleaned_on_reset_mixed(void)
{
git_object *target;
-
+
retrieve_target_from_oid(&target, repo, "3a34580a35add43a4cf361e8e9a30060a905c876");
- test_index_reuc__add();
+ test_index_reuc__add();
cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED));
cl_assert(reuc_entry_exists() == false);
-
+
git_object_free(target);
}
void test_index_reuc__retained_on_reset_soft(void)
{
git_object *target;
-
+
retrieve_target_from_oid(&target, repo, "3a34580a35add43a4cf361e8e9a30060a905c876");
-
+
git_reset(repo, target, GIT_RESET_HARD);
test_index_reuc__add();
cl_git_pass(git_reset(repo, target, GIT_RESET_SOFT));
cl_assert(reuc_entry_exists() == true);
-
+
git_object_free(target);
}
@@ -339,7 +339,7 @@ void test_index_reuc__cleaned_on_checkout_tree(void)
git_oid oid;
git_object *obj;
git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
-
+
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
test_index_reuc__add();
@@ -347,16 +347,16 @@ void test_index_reuc__cleaned_on_checkout_tree(void)
git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY);
git_checkout_tree(repo, obj, &opts);
cl_assert(reuc_entry_exists() == false);
-
+
git_object_free(obj);
}
void test_index_reuc__cleaned_on_checkout_head(void)
{
git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
-
+
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
-
+
test_index_reuc__add();
git_checkout_head(repo, &opts);
cl_assert(reuc_entry_exists() == false);
@@ -365,9 +365,9 @@ void test_index_reuc__cleaned_on_checkout_head(void)
void test_index_reuc__retained_on_checkout_index(void)
{
git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
-
+
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
-
+
test_index_reuc__add();
git_checkout_index(repo, repo_index, &opts);
cl_assert(reuc_entry_exists() == true);
diff --git a/tests-clar/merge/merge_helpers.c b/tests-clar/merge/merge_helpers.c
index 71bb96781..bc31b1f44 100644
--- a/tests-clar/merge/merge_helpers.c
+++ b/tests-clar/merge/merge_helpers.c
@@ -56,11 +56,11 @@ void merge__dump_index_entries(git_vector *index_entries)
{
size_t i;
const git_index_entry *index_entry;
-
+
printf ("\nINDEX [%d]:\n", (int)index_entries->length);
for (i = 0; i < index_entries->length; i++) {
index_entry = index_entries->contents[i];
-
+
printf("%o ", index_entry->mode);
printf("%s ", git_oid_allocfmt(&index_entry->oid));
printf("%d ", git_index_entry_stage(index_entry));
@@ -77,7 +77,7 @@ void merge__dump_names(git_index *index)
for (i = 0; i < git_index_name_entrycount(index); i++) {
conflict_name = git_index_name_get_byindex(index, i);
-
+
printf("%s %s %s\n", conflict_name->ancestor, conflict_name->ours, conflict_name->theirs);
}
printf("\n");
@@ -91,7 +91,7 @@ void merge__dump_reuc(git_index *index)
printf ("\nREUC:\n");
for (i = 0; i < git_index_reuc_entrycount(index); i++) {
reuc = git_index_reuc_get_byindex(index, i);
-
+
printf("%s ", reuc->path);
printf("%o ", reuc->mode[0]);
printf("%s\n", git_oid_allocfmt(&reuc->oid[0]));
@@ -114,18 +114,18 @@ static int index_entry_eq_merge_index_entry(const struct merge_index_entry *expe
test_oid = 1;
} else
test_oid = 0;
-
+
if (actual->mode != expected->mode ||
(test_oid && git_oid_cmp(&actual->oid, &expected_oid) != 0) ||
git_index_entry_stage(actual) != expected->stage)
return 0;
-
+
if (actual->mode == 0 && (actual->path != NULL || strlen(expected->path) > 0))
return 0;
if (actual->mode != 0 && (strcmp(actual->path, expected->path) != 0))
return 0;
-
+
return 1;
}
@@ -133,7 +133,7 @@ static int name_entry_eq(const char *expected, const char *actual)
{
if (strlen(expected) == 0)
return (actual == NULL) ? 1 : 0;
-
+
return (strcmp(expected, actual) == 0) ? 1 : 0;
}
@@ -153,11 +153,11 @@ static int index_conflict_data_eq_merge_diff(const struct merge_index_conflict_d
!index_entry_eq_merge_index_entry(&expected->ours.entry, &actual->our_entry) ||
!index_entry_eq_merge_index_entry(&expected->theirs.entry, &actual->their_entry))
return 0;
-
+
if (expected->ours.status != actual->our_status ||
expected->theirs.status != actual->their_status)
return 0;
-
+
return 1;
}
@@ -165,48 +165,48 @@ int merge_test_merge_conflicts(git_vector *conflicts, const struct merge_index_c
{
git_merge_diff *actual;
size_t i;
-
+
if (conflicts->length != expected_len)
return 0;
for (i = 0; i < expected_len; i++) {
actual = conflicts->contents[i];
-
+
if (!index_conflict_data_eq_merge_diff(&expected[i], actual))
return 0;
}
- return 1;
+ return 1;
}
int merge_test_index(git_index *index, const struct merge_index_entry expected[], size_t expected_len)
{
- size_t i;
- const git_index_entry *index_entry;
-
+ size_t i;
+ const git_index_entry *index_entry;
+
/*
dump_index_entries(&index->entries);
*/
- if (git_index_entrycount(index) != expected_len)
- return 0;
-
- for (i = 0; i < expected_len; i++) {
- if ((index_entry = git_index_get_byindex(index, i)) == NULL)
- return 0;
-
+ if (git_index_entrycount(index) != expected_len)
+ return 0;
+
+ for (i = 0; i < expected_len; i++) {
+ if ((index_entry = git_index_get_byindex(index, i)) == NULL)
+ return 0;
+
if (!index_entry_eq_merge_index_entry(&expected[i], index_entry))
return 0;
- }
-
- return 1;
+ }
+
+ return 1;
}
int merge_test_names(git_index *index, const struct merge_name_entry expected[], size_t expected_len)
{
size_t i;
const git_index_name_entry *name_entry;
-
+
/*
dump_names(index);
*/
@@ -221,26 +221,26 @@ int merge_test_names(git_index *index, const struct merge_name_entry expected[],
if (! name_entry_eq_merge_name_entry(&expected[i], name_entry))
return 0;
}
-
+
return 1;
}
int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], size_t expected_len)
{
- size_t i;
+ size_t i;
const git_index_reuc_entry *reuc_entry;
- git_oid expected_oid;
-
+ git_oid expected_oid;
+
/*
dump_reuc(index);
*/
-
- if (git_index_reuc_entrycount(index) != expected_len)
- return 0;
-
- for (i = 0; i < expected_len; i++) {
- if ((reuc_entry = git_index_reuc_get_byindex(index, i)) == NULL)
- return 0;
+
+ if (git_index_reuc_entrycount(index) != expected_len)
+ return 0;
+
+ for (i = 0; i < expected_len; i++) {
+ if ((reuc_entry = git_index_reuc_get_byindex(index, i)) == NULL)
+ return 0;
if (strcmp(reuc_entry->path, expected[i].path) != 0 ||
reuc_entry->mode[0] != expected[i].ancestor_mode ||
@@ -268,19 +268,19 @@ int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[],
if (git_oid_cmp(&reuc_entry->oid[2], &expected_oid) != 0)
return 0;
}
- }
-
- return 1;
+ }
+
+ return 1;
}
int dircount(void *payload, git_buf *pathbuf)
{
int *entries = payload;
size_t len = git_buf_len(pathbuf);
-
+
if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0)
(*entries)++;
-
+
return 0;
}
@@ -289,22 +289,22 @@ int merge_test_workdir(git_repository *repo, const struct merge_index_entry expe
size_t actual_len = 0, i;
git_oid actual_oid, expected_oid;
git_buf wd = GIT_BUF_INIT;
-
- git_buf_puts(&wd, repo->workdir);
+
+ git_buf_puts(&wd, repo->workdir);
git_path_direach(&wd, dircount, &actual_len);
-
+
if (actual_len != expected_len)
return 0;
-
+
for (i = 0; i < expected_len; i++) {
git_blob_create_fromworkdir(&actual_oid, repo, expected[i].path);
git_oid_fromstr(&expected_oid, expected[i].oid_str);
-
+
if (git_oid_cmp(&actual_oid, &expected_oid) != 0)
return 0;
}
-
+
git_buf_free(&wd);
-
+
return 1;
}
diff --git a/tests-clar/merge/trees/automerge.c b/tests-clar/merge/trees/automerge.c
index 7592a926e..04a7beff6 100644
--- a/tests-clar/merge/trees/automerge.c
+++ b/tests-clar/merge/trees/automerge.c
@@ -93,7 +93,7 @@ void test_merge_trees_automerge__automerge(void)
const git_index_entry *entry;
git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT;
git_blob *blob;
-
+
struct merge_index_entry merge_index_entries[] = {
ADDED_IN_MASTER_INDEX_ENTRY,
AUTOMERGEABLE_INDEX_ENTRY,
@@ -105,7 +105,7 @@ void test_merge_trees_automerge__automerge(void)
{ 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
UNCHANGED_INDEX_ENTRY,
- };
+ };
struct merge_reuc_entry merge_reuc_entries[] = {
AUTOMERGEABLE_REUC_ENTRY,
@@ -120,10 +120,10 @@ void test_merge_trees_automerge__automerge(void)
cl_assert((entry = git_index_get_bypath(index, "automergeable.txt", 0)) != NULL);
cl_assert(entry->file_size == strlen(AUTOMERGEABLE_MERGED_FILE));
-
+
cl_git_pass(git_object_lookup((git_object **)&blob, repo, &entry->oid, GIT_OBJ_BLOB));
cl_assert(memcmp(git_blob_rawcontent(blob), AUTOMERGEABLE_MERGED_FILE, entry->file_size) == 0);
-
+
git_index_free(index);
git_blob_free(blob);
}
@@ -132,7 +132,7 @@ void test_merge_trees_automerge__favor_ours(void)
{
git_index *index;
git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT;
-
+
struct merge_index_entry merge_index_entries[] = {
ADDED_IN_MASTER_INDEX_ENTRY,
AUTOMERGEABLE_INDEX_ENTRY,
@@ -148,9 +148,9 @@ void test_merge_trees_automerge__favor_ours(void)
REMOVED_IN_BRANCH_REUC_ENTRY,
REMOVED_IN_MASTER_REUC_ENTRY,
};
-
+
opts.automerge_flags = GIT_MERGE_AUTOMERGE_FAVOR_OURS;
-
+
cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts));
cl_assert(merge_test_index(index, merge_index_entries, 6));
@@ -163,7 +163,7 @@ void test_merge_trees_automerge__favor_theirs(void)
{
git_index *index;
git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT;
-
+
struct merge_index_entry merge_index_entries[] = {
ADDED_IN_MASTER_INDEX_ENTRY,
AUTOMERGEABLE_INDEX_ENTRY,
@@ -181,12 +181,12 @@ void test_merge_trees_automerge__favor_theirs(void)
};
opts.automerge_flags = GIT_MERGE_AUTOMERGE_FAVOR_THEIRS;
-
+
cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts));
cl_assert(merge_test_index(index, merge_index_entries, 6));
cl_assert(merge_test_reuc(index, merge_reuc_entries, 4));
-
+
git_index_free(index);
}
@@ -194,7 +194,7 @@ void test_merge_trees_automerge__unrelated(void)
{
git_index *index;
git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT;
-
+
struct merge_index_entry merge_index_entries[] = {
{ 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" },
{ 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 2, "automergeable.txt" },
@@ -208,10 +208,10 @@ void test_merge_trees_automerge__unrelated(void)
{ 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" },
{ 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" },
};
-
+
cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_UNRELATED_BRANCH, &opts));
-
+
cl_assert(merge_test_index(index, merge_index_entries, 11));
-
+
git_index_free(index);
}
diff --git a/tests-clar/merge/trees/modeconflict.c b/tests-clar/merge/trees/modeconflict.c
index 0661ce5b3..d858b8f66 100644
--- a/tests-clar/merge/trees/modeconflict.c
+++ b/tests-clar/merge/trees/modeconflict.c
@@ -27,7 +27,7 @@ void test_merge_trees_modeconflict__cleanup(void)
void test_merge_trees_modeconflict__df_conflict(void)
{
git_index *index;
-
+
struct merge_index_entry merge_index_entries[] = {
{ 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 2, "dir-10" },
{ 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 3, "dir-10" },
@@ -49,7 +49,7 @@ void test_merge_trees_modeconflict__df_conflict(void)
{ 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new" },
{ 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 2, "file-5/new" },
{ 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 3, "file-5/new" },
- };
+ };
cl_git_pass(merge_trees_from_branches(&index, repo, DF_SIDE1_BRANCH, DF_SIDE2_BRANCH, NULL));
diff --git a/tests-clar/merge/trees/renames.c b/tests-clar/merge/trees/renames.c
index dc0564bc4..427b6bd8f 100644
--- a/tests-clar/merge/trees/renames.c
+++ b/tests-clar/merge/trees/renames.c
@@ -72,14 +72,14 @@ void test_merge_trees_renames__index(void)
{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" },
};
-
+
struct merge_name_entry merge_name_entries[] = {
{
"3a-renamed-in-ours-deleted-in-theirs.txt",
"3a-newname-in-ours-deleted-in-theirs.txt",
""
},
-
+
{
"3b-renamed-in-theirs-deleted-in-ours.txt",
"",
@@ -97,7 +97,7 @@ void test_merge_trees_renames__index(void)
"",
"4b-newname-in-theirs-added-in-ours.txt",
},
-
+
{
"5a-renamed-in-ours-added-in-theirs.txt",
"5a-newname-in-ours-added-in-theirs.txt",
@@ -115,13 +115,13 @@ void test_merge_trees_renames__index(void)
"6-both-renamed-1-to-2-ours.txt",
"6-both-renamed-1-to-2-theirs.txt",
},
-
+
{
"7-both-renamed-side-1.txt",
"7-both-renamed.txt",
"7-both-renamed-side-1.txt",
},
-
+
{
"7-both-renamed-side-2.txt",
"7-both-renamed-side-2.txt",
@@ -159,7 +159,7 @@ void test_merge_trees_renames__index(void)
"",
"",
"241a1005cd9b980732741b74385b891142bcba28" },
-
+
{ "1b-newname-in-theirs.txt",
0, 0, 0100644,
"",
@@ -194,11 +194,11 @@ void test_merge_trees_renames__index(void)
cl_git_pass(merge_trees_from_branches(&index, repo,
BRANCH_RENAME_OURS, BRANCH_RENAME_THEIRS,
opts));
-
+
cl_assert(merge_test_index(index, merge_index_entries, 41));
cl_assert(merge_test_names(index, merge_name_entries, 9));
cl_assert(merge_test_reuc(index, merge_reuc_entries, 10));
-
+
git_index_free(index);
}
@@ -206,7 +206,7 @@ void test_merge_trees_renames__no_rename_index(void)
{
git_index *index;
git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT;
-
+
struct merge_index_entry merge_index_entries[] = {
{ 0100644, "68c6c84b091926c7d90aa6a79b2bc3bb6adccd8e", 0, "0a-no-change.txt" },
{ 0100644, "f0ce2b8e4986084d9b308fb72709e414c23eb5e6", 0, "0b-duplicated-in-ours.txt" },
@@ -241,13 +241,12 @@ void test_merge_trees_renames__no_rename_index(void)
{ 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 2, "7-both-renamed.txt" },
{ 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 3, "7-both-renamed.txt" },
};
-
+
cl_git_pass(merge_trees_from_branches(&index, repo,
BRANCH_RENAME_OURS, BRANCH_RENAME_THEIRS,
&opts));
-
+
cl_assert(merge_test_index(index, merge_index_entries, 32));
-
+
git_index_free(index);
}
-
diff --git a/tests-clar/merge/trees/treediff.c b/tests-clar/merge/trees/treediff.c
index 06ea94e0d..357859df3 100644
--- a/tests-clar/merge/trees/treediff.c
+++ b/tests-clar/merge/trees/treediff.c
@@ -58,37 +58,37 @@ static void test_find_differences(
opts.metric->similarity = git_diff_find_similar__calc_similarity;
opts.metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
- cl_git_pass(git_oid_fromstr(&ancestor_oid, ancestor_oidstr));
- cl_git_pass(git_oid_fromstr(&ours_oid, ours_oidstr));
- cl_git_pass(git_oid_fromstr(&theirs_oid, theirs_oidstr));
-
- cl_git_pass(git_tree_lookup(&ancestor_tree, repo, &ancestor_oid));
- cl_git_pass(git_tree_lookup(&ours_tree, repo, &ours_oid));
- cl_git_pass(git_tree_lookup(&theirs_tree, repo, &theirs_oid));
-
+ cl_git_pass(git_oid_fromstr(&ancestor_oid, ancestor_oidstr));
+ cl_git_pass(git_oid_fromstr(&ours_oid, ours_oidstr));
+ cl_git_pass(git_oid_fromstr(&theirs_oid, theirs_oidstr));
+
+ cl_git_pass(git_tree_lookup(&ancestor_tree, repo, &ancestor_oid));
+ cl_git_pass(git_tree_lookup(&ours_tree, repo, &ours_oid));
+ cl_git_pass(git_tree_lookup(&theirs_tree, repo, &theirs_oid));
+
cl_git_pass(git_merge_diff_list__find_differences(merge_diff_list, ancestor_tree, ours_tree, theirs_tree));
cl_git_pass(git_merge_diff_list__find_renames(repo, merge_diff_list, &opts));
/*
dump_merge_index(merge_index);
*/
-
- cl_assert(treediff_conflict_data_len == merge_diff_list->conflicts.length);
+
+ cl_assert(treediff_conflict_data_len == merge_diff_list->conflicts.length);
cl_assert(merge_test_merge_conflicts(&merge_diff_list->conflicts, treediff_conflict_data, treediff_conflict_data_len));
- git_tree_free(ancestor_tree);
- git_tree_free(ours_tree);
- git_tree_free(theirs_tree);
-
+ git_tree_free(ancestor_tree);
+ git_tree_free(ours_tree);
+ git_tree_free(theirs_tree);
+
git_merge_diff_list__free(merge_diff_list);
-
+
git__free(opts.metric);
}
void test_merge_trees_treediff__simple(void)
{
- struct merge_index_conflict_data treediff_conflict_data[] = {
+ struct merge_index_conflict_data treediff_conflict_data[] = {
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" }, GIT_DELTA_ADDED },
@@ -96,41 +96,41 @@ void test_merge_trees_treediff__simple(void)
GIT_MERGE_DIFF_NONE
},
- {
+ {
{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
{ { 0100644, "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
GIT_MERGE_DIFF_BOTH_MODIFIED
},
-
+
{
{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0, "changed-in-branch.txt" }, GIT_DELTA_MODIFIED },
GIT_MERGE_DIFF_NONE
},
-
+
{
{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" }, GIT_DELTA_MODIFIED },
{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_NONE
},
-
+
{
{ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt" }, GIT_DELTA_MODIFIED },
{ { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 0, "conflicting.txt" }, GIT_DELTA_MODIFIED },
GIT_MERGE_DIFF_BOTH_MODIFIED
},
-
+
{
{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_NONE
},
-
+
{
{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
@@ -138,13 +138,13 @@ void test_merge_trees_treediff__simple(void)
GIT_MERGE_DIFF_NONE
},
};
-
+
test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_BRANCH, treediff_conflict_data, 7);
}
void test_merge_trees_treediff__df_conflicts(void)
{
- struct merge_index_conflict_data treediff_conflict_data[] = {
+ struct merge_index_conflict_data treediff_conflict_data[] = {
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 0, "dir-10" }, GIT_DELTA_ADDED },
@@ -158,7 +158,7 @@ void test_merge_trees_treediff__df_conflicts(void)
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_BOTH_DELETED,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
@@ -172,7 +172,7 @@ void test_merge_trees_treediff__df_conflicts(void)
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_NONE,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
@@ -186,7 +186,7 @@ void test_merge_trees_treediff__df_conflicts(void)
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_DF_CHILD,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8" }, GIT_DELTA_ADDED },
@@ -200,7 +200,7 @@ void test_merge_trees_treediff__df_conflicts(void)
{ { 0100644, "f20c9063fa0bda9a397c96947a7b687305c49753", 0, "dir-8/file.txt" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_NONE,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 0, "dir-9" }, GIT_DELTA_ADDED },
@@ -235,7 +235,7 @@ void test_merge_trees_treediff__df_conflicts(void)
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_DIRECTORY_FILE,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
@@ -277,7 +277,7 @@ void test_merge_trees_treediff__df_conflicts(void)
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_BOTH_DELETED,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 0, "file-5/new" }, GIT_DELTA_ADDED },
@@ -285,7 +285,7 @@ void test_merge_trees_treediff__df_conflicts(void)
GIT_MERGE_DIFF_BOTH_ADDED,
},
};
-
+
test_find_differences(TREE_OID_DF_ANCESTOR, TREE_OID_DF_SIDE1, TREE_OID_DF_SIDE2, treediff_conflict_data, 20);
}
@@ -298,7 +298,7 @@ void test_merge_trees_treediff__strict_renames(void)
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_NONE,
},
-
+
{
{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt" }, GIT_DELTA_MODIFIED },
@@ -348,8 +348,8 @@ void test_merge_trees_treediff__strict_renames(void)
GIT_MERGE_DIFF_NONE,
},
};
-
- test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_RENAMES1, treediff_conflict_data, 8);
+
+ test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_RENAMES1, treediff_conflict_data, 8);
}
void test_merge_trees_treediff__rename_conflicts(void)
@@ -375,7 +375,7 @@ void test_merge_trees_treediff__rename_conflicts(void)
{ { 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-duplicated-in-theirs.txt" }, GIT_DELTA_ADDED },
GIT_MERGE_DIFF_NONE,
},
-
+
{
{ { 0100644, "2f56120107d680129a5d9791b521cb1e73a2ed31", 0, "0c-rewritten-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "efc9121fdedaf08ba180b53ebfbcf71bd488ed09", 0, "0c-rewritten-in-theirs.txt" }, GIT_DELTA_MODIFIED },
@@ -389,21 +389,21 @@ void test_merge_trees_treediff__rename_conflicts(void)
{ { 0100644, "0d872f8e871a30208305978ecbf9e66d864f1638", 0, "1a-renamed-in-ours-edited-in-theirs.txt" }, GIT_DELTA_MODIFIED },
GIT_MERGE_DIFF_RENAMED_MODIFIED,
},
-
+
{
{ { 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-renamed-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-newname-in-ours.txt" }, GIT_DELTA_RENAMED },
{ { 0100644, "d0d4594e16f2e19107e3fa7ea63e7aaaff305ffb", 0, "1a-renamed-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_NONE,
},
-
+
{
{ { 0100644, "241a1005cd9b980732741b74385b891142bcba28", 0, "1b-renamed-in-theirs-edited-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "ed9523e62e453e50dd9be1606af19399b96e397a", 0, "1b-renamed-in-theirs-edited-in-ours.txt" }, GIT_DELTA_MODIFIED },
{ { 0100644, "241a1005cd9b980732741b74385b891142bcba28", 0, "1b-newname-in-theirs-edited-in-ours.txt" }, GIT_DELTA_RENAMED },
GIT_MERGE_DIFF_RENAMED_MODIFIED,
},
-
+
{
{ { 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-renamed-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "2b5f1f181ee3b58ea751f5dd5d8f9b445520a136", 0, "1b-renamed-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
@@ -417,28 +417,28 @@ void test_merge_trees_treediff__rename_conflicts(void)
{ { 0100644, "178940b450f238a56c0d75b7955cb57b38191982", 0, "2-newname-in-both.txt" }, GIT_DELTA_RENAMED },
GIT_MERGE_DIFF_BOTH_RENAMED,
},
-
+
{
{ { 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-renamed-in-ours-deleted-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "18cb316b1cefa0f8a6946f0e201a8e1a6f845ab9", 0, "3a-newname-in-ours-deleted-in-theirs.txt" }, GIT_DELTA_RENAMED },
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
GIT_MERGE_DIFF_RENAMED_DELETED,
},
-
+
{
{ { 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-renamed-in-theirs-deleted-in-ours.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_DELETED },
{ { 0100644, "36219b49367146cb2e6a1555b5a9ebd4d0328495", 0, "3b-newname-in-theirs-deleted-in-ours.txt" }, GIT_DELTA_RENAMED },
GIT_MERGE_DIFF_RENAMED_DELETED,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "8b5b53cb2aa9ceb1139f5312fcfa3cc3c5a47c9a", 0, "4a-newname-in-ours-added-in-theirs.txt" }, GIT_DELTA_ADDED },
GIT_MERGE_DIFF_RENAMED_ADDED,
- },
-
+ },
+
{
{ { 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-renamed-in-ours-added-in-theirs.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "227792b52aaa0b238bea00ec7e509b02623f168c", 0, "4a-newname-in-ours-added-in-theirs.txt" }, GIT_DELTA_RENAMED },
@@ -459,21 +459,21 @@ void test_merge_trees_treediff__rename_conflicts(void)
{ { 0100644, "98d52d07c0b0bbf2b46548f6aa521295c2cb55db", 0, "4b-newname-in-theirs-added-in-ours.txt" }, GIT_DELTA_RENAMED },
GIT_MERGE_DIFF_RENAMED_ADDED,
},
-
+
{
{ { 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "5-both-renamed-1-to-2.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "5-both-renamed-1-to-2-ours.txt" }, GIT_DELTA_RENAMED },
{ { 0100644, "d8fa77b6833082c1ea36b7828a582d4c43882450", 0, "5-both-renamed-1-to-2-theirs.txt" }, GIT_DELTA_RENAMED },
GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2,
},
-
+
{
{ { 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "6-both-renamed-side-1.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "6-both-renamed.txt" }, GIT_DELTA_RENAMED },
{ { 0100644, "b42712cfe99a1a500b2a51fe984e0b8a7702ba11", 0, "6-both-renamed-side-1.txt" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1,
},
-
+
{
{ { 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "6-both-renamed-side-2.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "b69fe837e4cecfd4c9a40cdca7c138468687df07", 0, "6-both-renamed-side-2.txt" }, GIT_DELTA_UNMODIFIED },
@@ -481,8 +481,7 @@ void test_merge_trees_treediff__rename_conflicts(void)
GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1,
},
};
-
- test_find_differences(TREE_OID_RENAME_CONFLICT_ANCESTOR,
+ test_find_differences(TREE_OID_RENAME_CONFLICT_ANCESTOR,
TREE_OID_RENAME_CONFLICT_OURS, TREE_OID_RENAME_CONFLICT_THEIRS, treediff_conflict_data, 18);
}
@@ -494,7 +493,7 @@ void test_merge_trees_treediff__best_renames(void)
{ { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" }, GIT_DELTA_ADDED },
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_NONE,
- },
+ },
{
{ { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt" }, GIT_DELTA_UNMODIFIED },
@@ -502,7 +501,7 @@ void test_merge_trees_treediff__best_renames(void)
{ { 0100644, "45299c1ca5e07bba1fd90843056fb559f96b1f5a", 0, "renamed-90.txt" }, GIT_DELTA_RENAMED },
GIT_MERGE_DIFF_RENAMED_MODIFIED,
},
-
+
{
{ { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
{ { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" }, GIT_DELTA_MODIFIED },
@@ -523,7 +522,7 @@ void test_merge_trees_treediff__best_renames(void)
{ { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt" }, GIT_DELTA_UNMODIFIED },
GIT_MERGE_DIFF_MODIFIED_DELETED,
},
-
+
{
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
{ { 0, "", 0, "" }, GIT_DELTA_UNMODIFIED },
@@ -538,6 +537,6 @@ void test_merge_trees_treediff__best_renames(void)
GIT_MERGE_DIFF_NONE,
},
};
-
- test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_RENAMES2, treediff_conflict_data, 7);
+
+ test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_RENAMES2, treediff_conflict_data, 7);
}
diff --git a/tests-clar/merge/trees/trivial.c b/tests-clar/merge/trees/trivial.c
index 7d8d2cbf5..bfd5dfed3 100644
--- a/tests-clar/merge/trees/trivial.c
+++ b/tests-clar/merge/trees/trivial.c
@@ -34,7 +34,7 @@ static int merge_trivial(git_index **index, const char *ours, const char *theirs
git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT;
opts.automerge_flags |= automerge ? 0 : GIT_MERGE_AUTOMERGE_NONE;
-
+
git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours);
cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid));
@@ -46,7 +46,7 @@ static int merge_trivial(git_index **index, const char *ours, const char *theirs
cl_git_pass(git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit)));
cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid));
-
+
cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit));
cl_git_pass(git_commit_tree(&our_tree, our_commit));
cl_git_pass(git_commit_tree(&their_tree, their_commit));
@@ -67,7 +67,7 @@ static int merge_trivial(git_index **index, const char *ours, const char *theirs
static int merge_trivial_conflict_entrycount(git_index *index)
{
const git_index_entry *entry;
- size_t count = 0;
+ int count = 0;
size_t i;
for (i = 0; i < git_index_entrycount(index); i++) {
@@ -106,7 +106,7 @@ void test_merge_trees_trivial__3alt(void)
cl_assert(entry = git_index_get_bypath(result, "new-in-3alt.txt", 0));
cl_assert(git_index_reuc_entrycount(result) == 0);
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -124,7 +124,7 @@ void test_merge_trees_trivial__4(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "new-and-different.txt", 2));
cl_assert(entry = git_index_get_bypath(result, "new-and-different.txt", 3));
-
+
git_index_free(result);
}
@@ -139,7 +139,7 @@ void test_merge_trees_trivial__5alt_1(void)
cl_assert(entry = git_index_get_bypath(result, "new-and-same.txt", 0));
cl_assert(git_index_reuc_entrycount(result) == 0);
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -154,7 +154,7 @@ void test_merge_trees_trivial__5alt_2(void)
cl_assert(entry = git_index_get_bypath(result, "modified-to-same.txt", 0));
cl_assert(git_index_reuc_entrycount(result) == 0);
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -171,7 +171,7 @@ void test_merge_trees_trivial__6(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 1);
cl_assert(entry = git_index_get_bypath(result, "removed-in-both.txt", 1));
-
+
git_index_free(result);
}
@@ -189,7 +189,7 @@ void test_merge_trees_trivial__6_automerge(void)
cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-both.txt"));
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -207,7 +207,7 @@ void test_merge_trees_trivial__8(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "removed-in-8.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "removed-in-8.txt", 3));
-
+
git_index_free(result);
}
@@ -226,7 +226,7 @@ void test_merge_trees_trivial__8_automerge(void)
cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-8.txt"));
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -244,7 +244,7 @@ void test_merge_trees_trivial__7(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 3));
-
+
git_index_free(result);
}
@@ -262,7 +262,7 @@ void test_merge_trees_trivial__7_automerge(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 3));
-
+
git_index_free(result);
}
@@ -280,7 +280,7 @@ void test_merge_trees_trivial__10(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 2));
-
+
git_index_free(result);
}
@@ -299,7 +299,7 @@ void test_merge_trees_trivial__10_automerge(void)
cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-10-branch.txt"));
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -317,7 +317,7 @@ void test_merge_trees_trivial__9(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 2));
-
+
git_index_free(result);
}
@@ -335,7 +335,7 @@ void test_merge_trees_trivial__9_automerge(void)
cl_assert(merge_trivial_conflict_entrycount(result) == 2);
cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 2));
-
+
git_index_free(result);
}
@@ -354,7 +354,7 @@ void test_merge_trees_trivial__13(void)
cl_assert(git_index_reuc_entrycount(result) == 0);
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -373,7 +373,7 @@ void test_merge_trees_trivial__14(void)
cl_assert(git_index_reuc_entrycount(result) == 0);
cl_assert(merge_trivial_conflict_entrycount(result) == 0);
-
+
git_index_free(result);
}
@@ -392,6 +392,6 @@ void test_merge_trees_trivial__11(void)
cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 1));
cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 2));
cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 3));
-
+
git_index_free(result);
}
diff --git a/tests-clar/network/fetchlocal.c b/tests-clar/network/fetchlocal.c
index bcf298cde..09335b3df 100644
--- a/tests-clar/network/fetchlocal.c
+++ b/tests-clar/network/fetchlocal.c
@@ -34,7 +34,7 @@ void test_network_fetchlocal__complete(void)
cl_git_pass(git_remote_download(origin, transfer_cb, &callcount));
cl_git_pass(git_remote_update_tips(origin));
- cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count);
cl_assert(callcount > 0);
@@ -58,7 +58,7 @@ void test_network_fetchlocal__partial(void)
const char *url;
cl_set_cleanup(&cleanup_sandbox, NULL);
- cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(1, (int)refnames.count);
url = cl_git_fixture_url("testrepo.git");
@@ -69,7 +69,7 @@ void test_network_fetchlocal__partial(void)
git_strarray_free(&refnames);
- cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */
cl_assert(callcount > 0);
diff --git a/tests-clar/network/remote/local.c b/tests-clar/network/remote/local.c
index 74ef63dc9..3cb8a25d6 100644
--- a/tests-clar/network/remote/local.c
+++ b/tests-clar/network/remote/local.c
@@ -141,3 +141,20 @@ void test_network_remote_local__shorthand_fetch_refspec1(void)
cl_git_fail(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
}
+
+void test_network_remote_local__tagopt(void)
+{
+ git_reference *ref;
+
+ connect_to_local_repository(cl_fixture("testrepo.git"));
+ git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_ALL);
+
+ cl_git_pass(git_remote_download(remote, NULL, NULL));
+ cl_git_pass(git_remote_update_tips(remote));
+
+
+ cl_git_fail(git_reference_lookup(&ref, repo, "refs/remotes/master"));
+
+ cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
+ git_reference_free(ref);
+}
diff --git a/tests-clar/network/remote/remotes.c b/tests-clar/network/remote/remotes.c
index 4c24db8eb..21f27bcc6 100644
--- a/tests-clar/network/remote/remotes.c
+++ b/tests-clar/network/remote/remotes.c
@@ -118,13 +118,13 @@ void test_network_remote_remotes__add_fetchspec(void)
cl_git_pass(git_remote_add_fetch(_remote, "refs/*:refs/*"));
size++;
- cl_assert_equal_i(size, git_remote_refspec_count(_remote));
+ cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));
_refspec = git_remote_get_refspec(_remote, size - 1);
cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
- cl_assert_equal_i(_refspec->push, false);
+ cl_assert_equal_b(_refspec->push, false);
}
void test_network_remote_remotes__add_pushspec(void)
@@ -135,14 +135,14 @@ void test_network_remote_remotes__add_pushspec(void)
cl_git_pass(git_remote_add_push(_remote, "refs/*:refs/*"));
size++;
- cl_assert_equal_i(size, git_remote_refspec_count(_remote));
+ cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));
_refspec = git_remote_get_refspec(_remote, size - 1);
cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
- cl_assert_equal_i(_refspec->push, true);
+ cl_assert_equal_b(_refspec->push, true);
}
void test_network_remote_remotes__save(void)
@@ -169,12 +169,12 @@ void test_network_remote_remotes__save(void)
cl_git_pass(git_remote_load(&_remote, _repo, "upstream"));
cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote));
- cl_assert_equal_i(1, array.count);
+ cl_assert_equal_i(1, (int)array.count);
cl_assert_equal_s(fetch_refspec, array.strings[0]);
git_strarray_free(&array);
cl_git_pass(git_remote_get_push_refspecs(&array, _remote));
- cl_assert_equal_i(1, array.count);
+ cl_assert_equal_i(1, (int)array.count);
cl_assert_equal_s(push_refspec, array.strings[0]);
cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
cl_assert_equal_s(git_remote_pushurl(_remote), "git://github.com/libgit2/libgit2_push");
diff --git a/tests-clar/object/cache.c b/tests-clar/object/cache.c
index e06760e2a..b927b2514 100644
--- a/tests-clar/object/cache.c
+++ b/tests-clar/object/cache.c
@@ -80,7 +80,7 @@ void test_object_cache__cache_everything(void)
cl_assert_equal_i(count + 1, (int)git_cache_size(&g_repo->objects));
}
- cl_assert_equal_i(i, git_cache_size(&g_repo->objects) - start);
+ cl_assert_equal_i(i, (int)git_cache_size(&g_repo->objects) - start);
git_odb_free(odb);
@@ -135,7 +135,7 @@ void test_object_cache__cache_no_blobs(void)
}
}
- cl_assert_equal_i(nonblobs, git_cache_size(&g_repo->objects) - start);
+ cl_assert_equal_i(nonblobs, (int)git_cache_size(&g_repo->objects) - start);
git_odb_free(odb);
}
diff --git a/tests-clar/object/peel.c b/tests-clar/object/peel.c
index bb0bbd096..b6c9c7a3b 100644
--- a/tests-clar/object/peel.c
+++ b/tests-clar/object/peel.c
@@ -103,8 +103,3 @@ void test_object_peel__target_any_object_for_type_change(void)
/* fail to peel blob */
assert_peel_error(GIT_ENOTFOUND, "0266163a49e280c4f5ed1e08facd36a2bd716bcf", GIT_OBJ_ANY);
}
-
-void test_object_peel__should_use_a_well_known_type(void)
-{
- assert_peel_error(GIT_EINVALIDSPEC, "7b4384978d2493e851f9cca7858815fac9b10980", GIT_OBJ__EXT2);
-}
diff --git a/tests-clar/online/clone.c b/tests-clar/online/clone.c
index c1a9a9a88..aa12e47c9 100644
--- a/tests-clar/online/clone.c
+++ b/tests-clar/online/clone.c
@@ -3,6 +3,7 @@
#include "git2/clone.h"
#include "git2/cred_helpers.h"
#include "repository.h"
+#include "remote.h"
#define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository"
#define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
@@ -42,6 +43,8 @@ void test_online_clone__network_full(void)
cl_assert(!git_repository_is_bare(g_repo));
cl_git_pass(git_remote_load(&origin, g_repo, "origin"));
+ cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, origin->download_tags);
+
git_remote_free(origin);
}
diff --git a/tests-clar/refdb/inmemory.c b/tests-clar/refdb/inmemory.c
index 243b5bb37..d2594cd6d 100644
--- a/tests-clar/refdb/inmemory.c
+++ b/tests-clar/refdb/inmemory.c
@@ -163,7 +163,7 @@ void test_refdb_inmemory__foreach(void)
cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af"));
cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0));
- cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, foreach_test, &i));
+ cl_git_pass(git_reference_foreach(repo,foreach_test, &i));
cl_assert_equal_i(3, (int)i);
git_reference_free(write1);
@@ -210,7 +210,7 @@ void test_refdb_inmemory__delete(void)
git_reference_delete(write3);
git_reference_free(write3);
- cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, delete_test, &i));
+ cl_git_pass(git_reference_foreach(repo, delete_test, &i));
cl_assert_equal_i(1, (int)i);
git_reference_free(write2);
diff --git a/tests-clar/refdb/testdb.c b/tests-clar/refdb/testdb.c
index 627254e44..961e18d44 100644
--- a/tests-clar/refdb/testdb.c
+++ b/tests-clar/refdb/testdb.c
@@ -112,33 +112,49 @@ static int refdb_test_backend__lookup(
return GIT_ENOTFOUND;
}
-static int refdb_test_backend__foreach(
- git_refdb_backend *_backend,
- unsigned int list_flags,
- git_reference_foreach_cb callback,
- void *payload)
-{
- refdb_test_backend *backend;
- refdb_test_entry *entry;
+typedef struct {
+ git_reference_iterator parent;
size_t i;
+} refdb_test_iter;
- assert(_backend);
- backend = (refdb_test_backend *)_backend;
+static int refdb_test_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend)
+{
+ refdb_test_iter *iter;
- git_vector_foreach(&backend->refs, i, entry) {
- if (entry->type == GIT_REF_OID && (list_flags & GIT_REF_OID) == 0)
- continue;
+ GIT_UNUSED(_backend);
- if (entry->type == GIT_REF_SYMBOLIC && (list_flags & GIT_REF_SYMBOLIC) == 0)
- continue;
+ iter = git__calloc(1, sizeof(refdb_test_iter));
+ GITERR_CHECK_ALLOC(iter);
- if (callback(entry->name, payload) != 0)
- return GIT_EUSER;
- }
+ iter->parent.backend = _backend;
+ iter->i = 0;
+
+ *out = (git_reference_iterator *) iter;
return 0;
}
+static int refdb_test_backend__next(const char **name, git_reference_iterator *_iter)
+{
+ refdb_test_entry *entry;
+ refdb_test_backend *backend = (refdb_test_backend *) _iter->backend;
+ refdb_test_iter *iter = (refdb_test_iter *) _iter;
+
+ entry = git_vector_get(&backend->refs, iter->i);
+ if (!entry)
+ return GIT_ITEROVER;
+
+ *name = entry->name;
+ iter->i++;
+
+ return 0;
+}
+
+static void refdb_test_backend__iterator_free(git_reference_iterator *iter)
+{
+ git__free(iter);
+}
+
static void refdb_test_entry_free(refdb_test_entry *entry)
{
if (entry->type == GIT_REF_SYMBOLIC)
@@ -200,7 +216,9 @@ int refdb_backend_test(
backend->parent.exists = &refdb_test_backend__exists;
backend->parent.lookup = &refdb_test_backend__lookup;
- backend->parent.foreach = &refdb_test_backend__foreach;
+ backend->parent.iterator = &refdb_test_backend__iterator;
+ backend->parent.next = &refdb_test_backend__next;
+ backend->parent.iterator_free = &refdb_test_backend__iterator_free;
backend->parent.write = &refdb_test_backend__write;
backend->parent.delete = &refdb_test_backend__delete;
backend->parent.free = &refdb_test_backend__free;
diff --git a/tests-clar/refs/branches/foreach.c b/tests-clar/refs/branches/foreach.c
index 96a5bc2b9..57f9c0e39 100644
--- a/tests-clar/refs/branches/foreach.c
+++ b/tests-clar/refs/branches/foreach.c
@@ -24,6 +24,8 @@ void test_refs_branches_foreach__cleanup(void)
repo = NULL;
cl_fixture_cleanup("testrepo.git");
+
+ cl_git_sandbox_cleanup();
}
static int count_branch_list_cb(const char *branch_name, git_branch_t branch_type, void *payload)
@@ -72,14 +74,11 @@ static void assert_branch_has_been_found(struct expectations *findings, const ch
{
int pos = 0;
- while (findings[pos].branch_name)
- {
+ for (pos = 0; findings[pos].branch_name; ++pos) {
if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) {
cl_assert_equal_i(1, findings[pos].encounters);
return;
}
-
- pos++;
}
cl_fail("expected branch not found in list.");
@@ -94,12 +93,9 @@ static int contains_branch_list_cb(const char *branch_name, git_branch_t branch_
exp = (struct expectations *)payload;
- while (exp[pos].branch_name)
- {
+ for (pos = 0; exp[pos].branch_name; ++pos) {
if (strcmp(branch_name, exp[pos].branch_name) == 0)
exp[pos].encounters++;
-
- pos++;
}
return 0;
@@ -153,3 +149,25 @@ void test_refs_branches_foreach__can_cancel(void)
cl_assert_equal_i(5, count);
}
+
+void test_refs_branches_foreach__mix_of_packed_and_loose(void)
+{
+ struct expectations exp[] = {
+ { "master", 0 },
+ { "origin/HEAD", 0 },
+ { "origin/master", 0 },
+ { "origin/packed", 0 },
+ { NULL, 0 }
+ };
+ git_repository *r2;
+
+ r2 = cl_git_sandbox_init("testrepo2");
+
+ cl_git_pass(git_branch_foreach(r2, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
+ contains_branch_list_cb, &exp));
+
+ assert_branch_has_been_found(exp, "master");
+ assert_branch_has_been_found(exp, "origin/HEAD");
+ assert_branch_has_been_found(exp, "origin/master");
+ assert_branch_has_been_found(exp, "origin/packed");
+}
diff --git a/tests-clar/refs/branches/move.c b/tests-clar/refs/branches/move.c
index 7267f941d..ecf14e006 100644
--- a/tests-clar/refs/branches/move.c
+++ b/tests-clar/refs/branches/move.c
@@ -24,7 +24,7 @@ void test_refs_branches_move__can_move_a_local_branch(void)
cl_git_pass(git_branch_move(&new_ref, original_ref, NEW_BRANCH_NAME, 0));
cl_assert_equal_s(GIT_REFS_HEADS_DIR NEW_BRANCH_NAME, git_reference_name(new_ref));
-
+
git_reference_free(original_ref);
git_reference_free(new_ref);
}
@@ -32,7 +32,7 @@ void test_refs_branches_move__can_move_a_local_branch(void)
void test_refs_branches_move__can_move_a_local_branch_to_a_different_namespace(void)
{
git_reference *original_ref, *new_ref, *newer_ref;
-
+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
/* Downward */
@@ -42,14 +42,14 @@ void test_refs_branches_move__can_move_a_local_branch_to_a_different_namespace(v
/* Upward */
cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0));
git_reference_free(new_ref);
-
+
git_reference_free(newer_ref);
}
void test_refs_branches_move__can_move_a_local_branch_to_a_partially_colliding_namespace(void)
{
git_reference *original_ref, *new_ref, *newer_ref;
-
+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
/* Downward */
@@ -59,29 +59,29 @@ void test_refs_branches_move__can_move_a_local_branch_to_a_partially_colliding_n
/* Upward */
cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0));
git_reference_free(new_ref);
-
+
git_reference_free(newer_ref);
}
void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_collide_with_an_existing_one(void)
{
git_reference *original_ref, *new_ref;
-
+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
cl_assert_equal_i(GIT_EEXISTS, git_branch_move(&new_ref, original_ref, "master", 0));
-
+
git_reference_free(original_ref);
}
void test_refs_branches_move__moving_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void)
{
git_reference *original_ref, *new_ref;
-
+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
cl_assert_equal_i(GIT_EINVALIDSPEC, git_branch_move(&new_ref, original_ref, "Inv@{id", 0));
-
+
git_reference_free(original_ref);
}
@@ -98,11 +98,11 @@ void test_refs_branches_move__can_not_move_a_non_branch(void)
void test_refs_branches_move__can_force_move_over_an_existing_branch(void)
{
git_reference *original_ref, *new_ref;
-
+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
cl_git_pass(git_branch_move(&new_ref, original_ref, "master", 1));
-
+
git_reference_free(original_ref);
git_reference_free(new_ref);
}
diff --git a/tests-clar/refs/branches/remote.c b/tests-clar/refs/branches/remote.c
index 6043828b3..c110adb33 100644
--- a/tests-clar/refs/branches/remote.c
+++ b/tests-clar/refs/branches/remote.c
@@ -49,16 +49,20 @@ void test_refs_branches_remote__no_matching_remote_returns_error(void)
{
const char *unknown = "refs/remotes/nonexistent/master";
+ giterr_clear();
cl_git_fail_with(git_branch_remote_name(
NULL, 0, g_repo, unknown), GIT_ENOTFOUND);
+ cl_assert(giterr_last() != NULL);
}
void test_refs_branches_remote__local_remote_returns_error(void)
{
const char *local = "refs/heads/master";
+ giterr_clear();
cl_git_fail_with(git_branch_remote_name(
NULL, 0, g_repo, local), GIT_ERROR);
+ cl_assert(giterr_last() != NULL);
}
void test_refs_branches_remote__ambiguous_remote_returns_error(void)
@@ -75,6 +79,8 @@ void test_refs_branches_remote__ambiguous_remote_returns_error(void)
git_remote_free(remote);
+ giterr_clear();
cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo,
remote_tracking_branch_name), GIT_EAMBIGUOUS);
+ cl_assert(giterr_last() != NULL);
}
diff --git a/tests-clar/refs/branches/upstream.c b/tests-clar/refs/branches/upstream.c
index 2d0ebd240..69e55a0c5 100644
--- a/tests-clar/refs/branches/upstream.c
+++ b/tests-clar/refs/branches/upstream.c
@@ -103,6 +103,7 @@ void test_refs_branches_upstream__set_unset_upstream(void)
repository = cl_git_sandbox_init("testrepo.git");
+ /* remote */
cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
cl_git_pass(git_branch_set_upstream(branch, "test/master"));
@@ -112,6 +113,18 @@ void test_refs_branches_upstream__set_unset_upstream(void)
cl_git_pass(git_config_get_string(&value, config, "branch.test.merge"));
cl_assert_equal_s(value, "refs/heads/master");
+ git_reference_free(branch);
+
+ /* local */
+ cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
+ cl_git_pass(git_branch_set_upstream(branch, "master"));
+
+ cl_git_pass(git_config_get_string(&value, config, "branch.test.remote"));
+ cl_assert_equal_s(value, ".");
+ cl_git_pass(git_config_get_string(&value, config, "branch.test.merge"));
+ cl_assert_equal_s(value, "refs/heads/master");
+
+ /* unset */
cl_git_pass(git_branch_set_upstream(branch, NULL));
cl_git_fail_with(git_config_get_string(&value, config, "branch.test.merge"), GIT_ENOTFOUND);
cl_git_fail_with(git_config_get_string(&value, config, "branch.test.remote"), GIT_ENOTFOUND);
diff --git a/tests-clar/refs/foreachglob.c b/tests-clar/refs/foreachglob.c
index 4da1a15dd..2c458082f 100644
--- a/tests-clar/refs/foreachglob.c
+++ b/tests-clar/refs/foreachglob.c
@@ -37,11 +37,11 @@ static int count_cb(const char *reference_name, void *payload)
return 0;
}
-static void assert_retrieval(const char *glob, unsigned int flags, int expected_count)
+static void assert_retrieval(const char *glob, int expected_count)
{
int count = 0;
- cl_git_pass(git_reference_foreach_glob(repo, glob, flags, count_cb, &count));
+ cl_git_pass(git_reference_foreach_glob(repo, glob, count_cb, &count));
cl_assert_equal_i(expected_count, count);
}
@@ -49,17 +49,17 @@ static void assert_retrieval(const char *glob, unsigned int flags, int expected_
void test_refs_foreachglob__retrieve_all_refs(void)
{
/* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags */
- assert_retrieval("*", GIT_REF_LISTALL, 22);
+ assert_retrieval("*", 22);
}
void test_refs_foreachglob__retrieve_remote_branches(void)
{
- assert_retrieval("refs/remotes/*", GIT_REF_LISTALL, 2);
+ assert_retrieval("refs/remotes/*", 2);
}
void test_refs_foreachglob__retrieve_local_branches(void)
{
- assert_retrieval("refs/heads/*", GIT_REF_LISTALL, 12);
+ assert_retrieval("refs/heads/*", 12);
}
void test_refs_foreachglob__retrieve_partially_named_references(void)
@@ -69,7 +69,7 @@ void test_refs_foreachglob__retrieve_partially_named_references(void)
* refs/remotes/test/master, refs/tags/test
*/
- assert_retrieval("*test*", GIT_REF_LISTALL, 4);
+ assert_retrieval("*test*", 4);
}
@@ -89,7 +89,7 @@ void test_refs_foreachglob__can_cancel(void)
int count = 0;
cl_assert_equal_i(GIT_EUSER, git_reference_foreach_glob(
- repo, "*", GIT_REF_LISTALL, interrupt_cb, &count) );
+ repo, "*", interrupt_cb, &count) );
cl_assert_equal_i(11, count);
}
diff --git a/tests-clar/refs/iterator.c b/tests-clar/refs/iterator.c
new file mode 100644
index 000000000..d5555c657
--- /dev/null
+++ b/tests-clar/refs/iterator.c
@@ -0,0 +1,94 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+#include "vector.h"
+
+static git_repository *repo;
+
+void test_refs_iterator__initialize(void)
+{
+ cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
+}
+
+void test_refs_iterator__cleanup(void)
+{
+ git_repository_free(repo);
+}
+
+static const char *refnames[] = {
+ "refs/heads/br2",
+ "refs/heads/cannot-fetch",
+ "refs/heads/chomped",
+ "refs/heads/haacked",
+ "refs/heads/master",
+ "refs/heads/not-good",
+ "refs/heads/packed",
+ "refs/heads/packed-test",
+ "refs/heads/subtrees",
+ "refs/heads/test",
+ "refs/heads/track-local",
+ "refs/heads/trailing",
+ "refs/notes/fanout",
+ "refs/remotes/test/master",
+ "refs/tags/annotated_tag_to_blob",
+ "refs/tags/e90810b",
+ "refs/tags/hard_tag",
+ "refs/tags/point_to_blob",
+ "refs/tags/taggerless",
+ "refs/tags/test",
+ "refs/tags/wrapped_tag",
+};
+
+void test_refs_iterator__list(void)
+{
+ git_reference_iterator *iter;
+ git_vector output;
+ char *refname;
+ int error;
+ size_t i;
+
+ cl_git_pass(git_vector_init(&output, 32, git__strcmp_cb));
+ cl_git_pass(git_reference_iterator_new(&iter, repo));
+
+ do {
+ const char *name;
+ error = git_reference_next(&name, iter);
+ cl_assert(error == 0 || error == GIT_ITEROVER);
+ if (error != GIT_ITEROVER) {
+ char *dup = git__strdup(name);
+ cl_assert(dup != NULL);
+ cl_git_pass(git_vector_insert(&output, dup));
+ }
+ } while (!error);
+
+ cl_assert_equal_i(output.length, ARRAY_SIZE(refnames));
+
+ git_vector_sort(&output);
+ git_vector_foreach(&output, i, refname) {
+ cl_assert_equal_s(refname, refnames[i]);
+ }
+
+ git_reference_iterator_free(iter);
+
+ git_vector_foreach(&output, i, refname) {
+ git__free(refname);
+ }
+ git_vector_free(&output);
+}
+
+void test_refs_iterator__empty(void)
+{
+ git_reference_iterator *iter;
+ git_odb *odb;
+ const char *name;
+ git_repository *empty;
+
+ cl_git_pass(git_odb_new(&odb));
+ cl_git_pass(git_repository_wrap_odb(&empty, odb));
+
+ cl_git_pass(git_reference_iterator_new(&iter, empty));
+ cl_assert_equal_i(GIT_ITEROVER, git_reference_next(&name, iter));
+
+ git_reference_iterator_free(iter);
+ git_odb_free(odb);
+ git_repository_free(empty);
+}
diff --git a/tests-clar/refs/list.c b/tests-clar/refs/list.c
index 3948b2b7a..c9c2af4a7 100644
--- a/tests-clar/refs/list.c
+++ b/tests-clar/refs/list.c
@@ -25,7 +25,7 @@ void test_refs_list__all(void)
// try to list all the references in our test repo
git_strarray ref_list;
- cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&ref_list, g_repo));
/*{
unsigned short i;
@@ -41,17 +41,6 @@ void test_refs_list__all(void)
git_strarray_free(&ref_list);
}
-void test_refs_list__symbolic_only(void)
-{
- // try to list only the symbolic references
- git_strarray ref_list;
-
- cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_SYMBOLIC));
- cl_assert(ref_list.count == 0); /* no symrefs in the test repo */
-
- git_strarray_free(&ref_list);
-}
-
void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_extension(void)
{
git_strarray ref_list;
@@ -61,7 +50,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten
"./testrepo/.git/refs/heads/hanwen.lock",
"144344043ba4d4a405da03de3844aa829ae8be0e\n");
- cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&ref_list, g_repo));
cl_assert_equal_i((int)ref_list.count, 13);
git_strarray_free(&ref_list);
diff --git a/tests-clar/refs/listall.c b/tests-clar/refs/listall.c
index 8f4c3746b..c696fbb2e 100644
--- a/tests-clar/refs/listall.c
+++ b/tests-clar/refs/listall.c
@@ -9,7 +9,7 @@ static void ensure_no_refname_starts_with_a_forward_slash(const char *path)
size_t i;
cl_git_pass(git_repository_open(&repo, path));
- cl_git_pass(git_reference_list(&ref_list, repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&ref_list, repo));
cl_assert(ref_list.count > 0);
@@ -38,7 +38,7 @@ void test_refs_listall__from_repository_opened_through_gitdir_path(void)
void test_refs_listall__from_repository_with_no_trailing_newline(void)
{
cl_git_pass(git_repository_open(&repo, cl_fixture("bad_tag.git")));
- cl_git_pass(git_reference_list(&ref_list, repo, GIT_REF_LISTALL));
+ cl_git_pass(git_reference_list(&ref_list, repo));
cl_assert(ref_list.count > 0);
diff --git a/tests-clar/refs/ref_helpers.c b/tests-clar/refs/ref_helpers.c
index 16ab9e6ef..7676e65a7 100644
--- a/tests-clar/refs/ref_helpers.c
+++ b/tests-clar/refs/ref_helpers.c
@@ -11,15 +11,15 @@ int reference_is_packed(git_reference *ref)
int packed;
assert(ref);
-
+
if (git_buf_joinpath(&ref_path,
git_repository_path(git_reference_owner(ref)),
git_reference_name(ref)) < 0)
return -1;
packed = !git_path_isfile(ref_path.ptr);
-
+
git_buf_free(&ref_path);
-
+
return packed;
}
diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c
index 74472b175..43406e239 100644
--- a/tests-clar/refs/revparse.c
+++ b/tests-clar/refs/revparse.c
@@ -557,12 +557,12 @@ void test_refs_revparse__issue_994(void)
/**
* $ git rev-parse blah-7-gc47800c
* c47800c7266a2be04c571c04d5a6614691ea99bd
- *
+ *
* $ git rev-parse HEAD~3
* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
- *
+ *
* $ git branch blah-7-gc47800c HEAD~3
- *
+ *
* $ git rev-parse blah-7-gc47800c
* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
*/
@@ -592,15 +592,15 @@ void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void)
/**
* $ git rev-parse a65fedf39aefe402d3bb6e24df4d4f5fe4547750
* a65fedf39aefe402d3bb6e24df4d4f5fe4547750
- *
+ *
* $ git rev-parse HEAD~3
* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
- *
+ *
* $ git branch a65fedf39aefe402d3bb6e24df4d4f5fe4547750 HEAD~3
- *
+ *
* $ git rev-parse a65fedf39aefe402d3bb6e24df4d4f5fe4547750
* a65fedf39aefe402d3bb6e24df4d4f5fe4547750
- *
+ *
* $ git rev-parse heads/a65fedf39aefe402d3bb6e24df4d4f5fe4547750
* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
*/
@@ -631,12 +631,12 @@ void test_refs_revparse__try_to_retrieve_sha_before_branch(void)
/**
* $ git rev-parse c47800
* c47800c7266a2be04c571c04d5a6614691ea99bd
- *
+ *
* $ git rev-parse HEAD~3
* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
- *
+ *
* $ git branch c47800 HEAD~3
- *
+ *
* $ git rev-parse c47800
* 4a202b346bb0fb0db7eff3cffeb3c70babbd2045
*/
@@ -694,4 +694,3 @@ void test_refs_revparse__parses_range_operator(void)
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE);
}
-
diff --git a/tests-clar/refs/setter.c b/tests-clar/refs/setter.c
index 713af814f..6d875f9b6 100644
--- a/tests-clar/refs/setter.c
+++ b/tests-clar/refs/setter.c
@@ -25,7 +25,7 @@ void test_refs_setter__update_direct(void)
{
git_reference *ref, *test_ref, *new_ref;
git_oid id;
-
+
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
cl_assert(git_reference_type(ref) == GIT_REF_OID);
git_oid_cpy(&id, git_reference_target(ref));
@@ -48,7 +48,7 @@ void test_refs_setter__update_direct(void)
void test_refs_setter__update_symbolic(void)
{
git_reference *head, *new_head;
-
+
cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC);
cl_assert(strcmp(git_reference_symbolic_target(head), ref_master_name) == 0);
@@ -56,7 +56,7 @@ void test_refs_setter__update_symbolic(void)
cl_git_pass(git_reference_symbolic_set_target(&new_head, head, ref_test_name));
git_reference_free(new_head);
git_reference_free(head);
-
+
cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC);
cl_assert(strcmp(git_reference_symbolic_target(head), ref_test_name) == 0);
@@ -68,13 +68,13 @@ void test_refs_setter__cant_update_direct_with_symbolic(void)
// Overwrite an existing object id reference with a symbolic one
git_reference *ref, *new;
git_oid id;
-
+
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
cl_assert(git_reference_type(ref) == GIT_REF_OID);
git_oid_cpy(&id, git_reference_target(ref));
-
+
cl_git_fail(git_reference_symbolic_set_target(&new, ref, ref_name));
-
+
git_reference_free(ref);
}
@@ -83,7 +83,7 @@ void test_refs_setter__cant_update_symbolic_with_direct(void)
// Overwrite an existing symbolic reference with an object id one
git_reference *ref, *new;
git_oid id;
-
+
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
cl_assert(git_reference_type(ref) == GIT_REF_OID);
git_oid_cpy(&id, git_reference_target(ref));
@@ -94,6 +94,6 @@ void test_refs_setter__cant_update_symbolic_with_direct(void)
/* Can't set an OID on a direct ref */
cl_git_fail(git_reference_set_target(&new, ref, &id));
-
+
git_reference_free(ref);
}
diff --git a/tests-clar/repo/config.c b/tests-clar/repo/config.c
new file mode 100644
index 000000000..086fb5e4f
--- /dev/null
+++ b/tests-clar/repo/config.c
@@ -0,0 +1,75 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include <ctype.h>
+
+git_buf path = GIT_BUF_INIT;
+
+void test_repo_config__initialize(void)
+{
+ cl_fixture_sandbox("empty_standard_repo");
+ cl_git_pass(cl_rename("empty_standard_repo/.gitted", "empty_standard_repo/.git"));
+
+ git_buf_clear(&path);
+
+ cl_must_pass(p_mkdir("alternate", 0777));
+ cl_git_pass(git_path_prettify(&path, "alternate", NULL));
+
+}
+
+void test_repo_config__cleanup(void)
+{
+ cl_git_pass(git_futils_rmdir_r(path.ptr, NULL, GIT_RMDIR_REMOVE_FILES));
+
+ git_buf_free(&path);
+ cl_fixture_cleanup("empty_standard_repo");
+}
+
+void test_repo_config__open_missing_global(void)
+{
+ git_repository *repo;
+ git_config *config, *global;
+
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+ cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+ cl_git_pass(git_repository_config(&config, repo));
+ cl_git_pass(git_config_open_level(&global, config, GIT_CONFIG_LEVEL_GLOBAL));
+
+ cl_git_pass(git_config_set_string(global, "test.set", "42"));
+
+ git_config_free(global);
+ git_config_free(config);
+ git_repository_free(repo);
+}
+
+void test_repo_config__open_missing_global_with_separators(void)
+{
+ git_repository *repo;
+ git_config *config, *global;
+
+ cl_git_pass(git_buf_printf(&path, "%c%s", GIT_PATH_LIST_SEPARATOR, "dummy"));
+
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
+
+ git_buf_free(&path);
+
+ cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
+ cl_git_pass(git_repository_config(&config, repo));
+ cl_git_pass(git_config_open_level(&global, config, GIT_CONFIG_LEVEL_GLOBAL));
+
+ cl_git_pass(git_config_set_string(global, "test.set", "42"));
+
+ git_config_free(global);
+ git_config_free(config);
+ git_repository_free(repo);
+}
diff --git a/tests-clar/repo/message.c b/tests-clar/repo/message.c
index 59487d51b..629d40c12 100644
--- a/tests-clar/repo/message.c
+++ b/tests-clar/repo/message.c
@@ -35,13 +35,18 @@ void test_repo_message__message(void)
len = git_repository_message(NULL, 0, _repo);
cl_assert(len > 0);
+
_actual = git__malloc(len + 1);
cl_assert(_actual != NULL);
+ /* Test non truncation */
cl_assert(git_repository_message(_actual, len, _repo) > 0);
- _actual[len] = '\0';
cl_assert_equal_s(expected, _actual);
+ /* Test truncation and that trailing NUL is inserted */
+ cl_assert(git_repository_message(_actual, 6, _repo) > 0);
+ cl_assert_equal_s("Test\n", _actual);
+
cl_git_pass(p_unlink(git_buf_cstr(&_path)));
cl_assert_equal_i(GIT_ENOTFOUND, git_repository_message(NULL, 0, _repo));
}
diff --git a/tests-clar/repo/open.c b/tests-clar/repo/open.c
index 6b5253797..840858586 100644
--- a/tests-clar/repo/open.c
+++ b/tests-clar/repo/open.c
@@ -309,7 +309,7 @@ void test_repo_open__no_config(void)
cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
cl_git_pass(git_repository_config(&config, repo));
- cl_git_fail(git_config_set_string(config, "test.set", "42"));
+ cl_git_pass(git_config_set_string(config, "test.set", "42"));
git_config_free(config);
git_repository_free(repo);
diff --git a/tests-clar/reset/hard.c b/tests-clar/reset/hard.c
index 62371f83f..1c0c84135 100644
--- a/tests-clar/reset/hard.c
+++ b/tests-clar/reset/hard.c
@@ -105,14 +105,14 @@ void test_reset_hard__cannot_reset_in_a_bare_repository(void)
static void index_entry_init(git_index *index, int side, git_oid *oid)
{
git_index_entry entry;
-
+
memset(&entry, 0x0, sizeof(git_index_entry));
-
+
entry.path = "conflicting_file";
entry.flags = (side << GIT_IDXENTRY_STAGESHIFT);
entry.mode = 0100644;
git_oid_cpy(&entry.oid, oid);
-
+
cl_git_pass(git_index_add(index, &entry));
}
@@ -122,19 +122,19 @@ static void unmerged_index_init(git_index *index, int entries)
int write_ours = 2;
int write_theirs = 4;
git_oid ancestor, ours, theirs;
-
+
git_oid_fromstr(&ancestor, "6bb0d9f700543ba3d318ba7075fc3bd696b4287b");
git_oid_fromstr(&ours, "b19a1e93bec1317dc6097229e12afaffbfa74dc2");
git_oid_fromstr(&theirs, "950b81b7eee953d050aa05a641f8e056c85dd1bd");
-
+
cl_git_rewritefile("status/conflicting_file", "conflicting file\n");
-
+
if (entries & write_ancestor)
index_entry_init(index, 1, &ancestor);
-
+
if (entries & write_ours)
index_entry_init(index, 2, &ours);
-
+
if (entries & write_theirs)
index_entry_init(index, 3, &theirs);
}
@@ -143,24 +143,24 @@ void test_reset_hard__resetting_reverts_unmerged(void)
{
git_index *index;
int entries;
-
+
/* Ensure every permutation of non-zero stage entries results in the
* path being cleaned up. */
for (entries = 1; entries < 8; entries++) {
cl_git_pass(git_repository_index(&index, repo));
-
+
unmerged_index_init(index, entries);
cl_git_pass(git_index_write(index));
-
+
retrieve_target_from_oid(&target, repo, "26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f");
cl_git_pass(git_reset(repo, target, GIT_RESET_HARD));
-
+
cl_assert(git_path_exists("status/conflicting_file") == 0);
-
+
git_object_free(target);
target = NULL;
-
- git_index_free(index);
+
+ git_index_free(index);
}
}
diff --git a/tests-clar/resources/testrepo2/.gitted/HEAD b/tests-clar/resources/testrepo2/.gitted/HEAD
new file mode 100644
index 000000000..cb089cd89
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests-clar/resources/testrepo2/.gitted/config b/tests-clar/resources/testrepo2/.gitted/config
new file mode 100644
index 000000000..fc2433caf
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/config
@@ -0,0 +1,14 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+ precomposeunicode = false
+[remote "origin"]
+ url = https://github.com/libgit2/false.git
+ fetch = +refs/heads/*:refs/remotes/origin/*
+[branch "master"]
+ remote = origin
+ merge = refs/heads/master
+ rebase = true
diff --git a/tests-clar/resources/testrepo2/.gitted/description b/tests-clar/resources/testrepo2/.gitted/description
new file mode 100644
index 000000000..498b267a8
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/tests-clar/resources/testrepo2/.gitted/index b/tests-clar/resources/testrepo2/.gitted/index
new file mode 100644
index 000000000..b614d0727
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/index
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/info/exclude b/tests-clar/resources/testrepo2/.gitted/info/exclude
new file mode 100644
index 000000000..a5196d1be
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/tests-clar/resources/testrepo2/.gitted/logs/HEAD b/tests-clar/resources/testrepo2/.gitted/logs/HEAD
new file mode 100644
index 000000000..4e80c69fa
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/logs/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git
diff --git a/tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master b/tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master
new file mode 100644
index 000000000..4e80c69fa
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/logs/refs/heads/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git
diff --git a/tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD b/tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD
new file mode 100644
index 000000000..4e80c69fa
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/logs/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 36060c58702ed4c2a40832c51758d5344201d89a Russell Belfer <rb@github.com> 1368278260 -0700 clone: from /Users/rb/src/libgit2/tests-clar/resources/../../../rugged/test/fixtures/testrepo.git
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d b/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d
new file mode 100644
index 000000000..bfe146a5a
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 b/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
new file mode 100644
index 000000000..cedb2a22e
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 b/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
new file mode 100644
index 000000000..93a16f146
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/18/1037049a54a1eb5fab404658a3a250b44335d7
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd b/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
new file mode 100644
index 000000000..ba0bfb30c
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/18/10dff58d8a660512d4832e740f692884338ccd
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 b/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2
new file mode 100644
index 000000000..3cd240db5
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a b/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a
new file mode 100644
index 000000000..0c6246061
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/36/060c58702ed4c2a40832c51758d5344201d89a
@@ -0,0 +1,2 @@
+xQ
+0)reݴ $ۭ-F-00𸖲?iL#HSS#q2D據jC|HSL8$)a#2i׹6js?JZftΞUiͶqiZ"_/H6 \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 b/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
new file mode 100644
index 000000000..7ca4ceed5
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 b/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
new file mode 100644
index 000000000..8953b6cef
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045
@@ -0,0 +1,2 @@
+xQ
+0D)6ͦ "xO-FbEo0 Ǥ,ske[Pn8R,EpD?g}^3 <GhYK8ЖDA);gݧjp4-r;sGA4ۺ=(in7IKFE \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 b/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
new file mode 100644
index 000000000..c1f22c54f
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644
@@ -0,0 +1,2 @@
+x 1ENi@k2 "X$YW0YcÅszMD08!s Xgd::@X0Pw"F/RUzmZZV}|/o5I!1z:vUim}/>
+F- \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 b/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96
new file mode 100644
index 000000000..1fd79b477
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a b/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
new file mode 100644
index 000000000..2ef4faa0f
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 b/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0
new file mode 100644
index 000000000..3d1016daa
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d b/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
new file mode 100644
index 000000000..2f9b6b6e3
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/81/4889a078c031f61ed08ab5fa863aea9314344d
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479 b/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
new file mode 100644
index 000000000..5df58dda5
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/84/96071c1b46c854b31185ea97743be6a8774479
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a b/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
new file mode 100644
index 000000000..a79612435
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a
@@ -0,0 +1,3 @@
+x[
+0E*fդ "W0-Ft݁pS[Yx^
+Db CLhut}8X*4ZsYUA X3RM) s6輢Mរ&Jm;}<\@ޏpĀv?jۺL?H \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f b/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
new file mode 100644
index 000000000..f8588696b
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f
@@ -0,0 +1,2 @@
+x;j1Dmdǎ|M3`V{ >QvL0I?!4Z=!צ8F!rsQy9]$D&l6A>jFWҵ IKNiZ%S
+ U~̽>' w [ DGڡQ-M>dO}\8g_ШoYr \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd b/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
new file mode 100644
index 000000000..d0d7e736e
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 b/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
new file mode 100644
index 000000000..18a7f61c2
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 b/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
new file mode 100644
index 000000000..0817229bc
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644
@@ -0,0 +1,3 @@
+xKj1D)zUB-0uV9<#+W<J&8/seȕKJS
+Rv{QrYQN$H\E=6X5K Fr)(dCΆjs}9c-w8o\rI:
+l}FW$DsǣٚOWe]V8-Ý"U \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd b/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
new file mode 100644
index 000000000..75f541f10
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd
@@ -0,0 +1,3 @@
+xQ
+0D)ʦI<'lR+FjEo0<xha ]șXUlPF)z4y,\r 'S-mI4
+Xh&F}n+\Y-p|鷜oUz;-alt{?I,:oRcHK \ No newline at end of file
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b b/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b
new file mode 100644
index 000000000..599e16084
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
new file mode 100644
index 000000000..711223894
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 b/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
new file mode 100644
index 000000000..03770969a
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92 b/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
new file mode 100644
index 000000000..112998d42
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/fa/49b077972391ad58037050f2a75f74e3671e92
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765 b/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
new file mode 100644
index 000000000..12bf5f3e3
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/fd/093bff70906175335656e6ce6ae05783708765
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
new file mode 100644
index 000000000..94c3c71da
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
new file mode 100644
index 000000000..74c7fe4f3
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack
Binary files differ
diff --git a/tests-clar/resources/testrepo2/.gitted/packed-refs b/tests-clar/resources/testrepo2/.gitted/packed-refs
new file mode 100644
index 000000000..97ea6a848
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/packed-refs
@@ -0,0 +1,6 @@
+# pack-refs with: peeled fully-peeled
+36060c58702ed4c2a40832c51758d5344201d89a refs/remotes/origin/master
+41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed
+5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/tags/v0.9
+0c37a5391bbff43c37f0d0371823a5509eed5b1d refs/tags/v1.0
+^5b5b025afb0b4c913b4c338a42934a3863bf3644
diff --git a/tests-clar/resources/testrepo2/.gitted/refs/heads/master b/tests-clar/resources/testrepo2/.gitted/refs/heads/master
new file mode 100644
index 000000000..a7eafce3c
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/refs/heads/master
@@ -0,0 +1 @@
+36060c58702ed4c2a40832c51758d5344201d89a
diff --git a/tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD b/tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD
new file mode 100644
index 000000000..6efe28fff
--- /dev/null
+++ b/tests-clar/resources/testrepo2/.gitted/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/tests-clar/resources/testrepo2/README b/tests-clar/resources/testrepo2/README
new file mode 100644
index 000000000..1385f264a
--- /dev/null
+++ b/tests-clar/resources/testrepo2/README
@@ -0,0 +1 @@
+hey
diff --git a/tests-clar/resources/testrepo2/new.txt b/tests-clar/resources/testrepo2/new.txt
new file mode 100644
index 000000000..fa49b0779
--- /dev/null
+++ b/tests-clar/resources/testrepo2/new.txt
@@ -0,0 +1 @@
+new file
diff --git a/tests-clar/resources/testrepo2/subdir/README b/tests-clar/resources/testrepo2/subdir/README
new file mode 100644
index 000000000..1385f264a
--- /dev/null
+++ b/tests-clar/resources/testrepo2/subdir/README
@@ -0,0 +1 @@
+hey
diff --git a/tests-clar/resources/testrepo2/subdir/new.txt b/tests-clar/resources/testrepo2/subdir/new.txt
new file mode 100644
index 000000000..fa49b0779
--- /dev/null
+++ b/tests-clar/resources/testrepo2/subdir/new.txt
@@ -0,0 +1 @@
+new file
diff --git a/tests-clar/resources/testrepo2/subdir/subdir2/README b/tests-clar/resources/testrepo2/subdir/subdir2/README
new file mode 100644
index 000000000..1385f264a
--- /dev/null
+++ b/tests-clar/resources/testrepo2/subdir/subdir2/README
@@ -0,0 +1 @@
+hey
diff --git a/tests-clar/resources/testrepo2/subdir/subdir2/new.txt b/tests-clar/resources/testrepo2/subdir/subdir2/new.txt
new file mode 100644
index 000000000..fa49b0779
--- /dev/null
+++ b/tests-clar/resources/testrepo2/subdir/subdir2/new.txt
@@ -0,0 +1 @@
+new file
diff --git a/tests-clar/status/submodules.c b/tests-clar/status/submodules.c
index 8365a7f5a..af8707721 100644
--- a/tests-clar/status/submodules.c
+++ b/tests-clar/status/submodules.c
@@ -219,4 +219,3 @@ void test_status_submodules__dirty_workdir_only(void)
git_status_foreach_ext(g_repo, &opts, cb_status__match, &counts));
cl_assert_equal_i(6, counts.entry_count);
}
-
diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c
index 0138b1712..062a09aeb 100644
--- a/tests-clar/status/worktree.c
+++ b/tests-clar/status/worktree.c
@@ -672,3 +672,26 @@ void test_status_worktree__file_status_honors_core_ignorecase_false(void)
{
assert_ignore_case(false, GIT_STATUS_WT_DELETED, GIT_STATUS_WT_NEW);
}
+
+void test_status_worktree__file_status_honors_case_ignorecase_regarding_untracked_files(void)
+{
+ git_repository *repo = cl_git_sandbox_init("status");
+ unsigned int status;
+ git_index *index;
+
+ cl_repo_set_bool(repo, "core.ignorecase", false);
+
+ repo = cl_git_sandbox_reopen();
+
+ /* Actually returns GIT_STATUS_IGNORED on Windows */
+ cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND);
+
+ cl_git_pass(git_repository_index(&index, repo));
+
+ cl_git_pass(git_index_add_bypath(index, "new_file"));
+ cl_git_pass(git_index_write(index));
+ git_index_free(index);
+
+ /* Actually returns GIT_STATUS_IGNORED on Windows */
+ cl_git_fail_with(git_status_file(&status, repo, "NEW_FILE"), GIT_ENOTFOUND);
+}
diff --git a/tests-clar/submodule/status.c b/tests-clar/submodule/status.c
index fca84af63..88f388052 100644
--- a/tests-clar/submodule/status.c
+++ b/tests-clar/submodule/status.c
@@ -409,4 +409,6 @@ void test_submodule_status__untracked_dirs_containing_ignored_files(void)
GIT_SUBMODULE_STATUS_IN_WD;
cl_assert(status == expected);
+
+ git_buf_free(&path);
}
diff --git a/tests-clar/trace/trace.c b/tests-clar/trace/trace.c
index cc99cd187..87b325378 100644
--- a/tests-clar/trace/trace.c
+++ b/tests-clar/trace/trace.c
@@ -85,4 +85,3 @@ void test_trace_trace__writes_lower_level(void)
cl_assert(written == 1);
#endif
}
-
diff --git a/tests-clar/valgrind-supp-mac.txt b/tests-clar/valgrind-supp-mac.txt
index 03e60dcd7..297b11e62 100644
--- a/tests-clar/valgrind-supp-mac.txt
+++ b/tests-clar/valgrind-supp-mac.txt
@@ -80,3 +80,75 @@
...
fun:puts
}
+{
+ mac-ssl-uninitialized-1
+ Memcheck:Cond
+ obj:/usr/lib/libcrypto.0.9.8.dylib
+ ...
+ fun:ssl23_connect
+}
+{
+ mac-ssl-uninitialized-2
+ Memcheck:Cond
+ ...
+ obj:/usr/lib/libssl.0.9.8.dylib
+ ...
+ fun:ssl23_connect
+}
+{
+ mac-ssl-uninitialized-3
+ Memcheck:Value8
+ obj:/usr/lib/libcrypto.0.9.8.dylib
+ ...
+ fun:ssl23_connect
+}
+{
+ mac-ssl-uninitialized-4
+ Memcheck:Param
+ ...
+ obj:/usr/lib/libcrypto.0.9.8.dylib
+ ...
+ fun:ssl23_connect
+}
+{
+ mac-ssl-leak-1
+ Memcheck:Leak
+ fun:malloc
+ fun:CRYPTO_malloc
+ ...
+ fun:ERR_load_strings
+}
+{
+ mac-ssl-leak-2
+ Memcheck:Leak
+ fun:malloc
+ fun:CRYPTO_malloc
+ ...
+ fun:SSL_library_init
+}
+{
+ mac-ssl-leak-3
+ Memcheck:Leak
+ fun:malloc
+ fun:strdup
+ ...
+ fun:si_module_with_name
+ fun:getaddrinfo
+}
+{
+ mac-ssl-leak-4
+ Memcheck:Leak
+ fun:malloc
+ fun:CRYPTO_malloc
+ ...
+ fun:ssl3_get_server_certificate
+}
+{
+ clar-printf-buf
+ Memcheck:Leak
+ fun:malloc
+ fun:__smakebuf
+ ...
+ fun:printf
+ fun:clar_print_init
+}