summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--cmake/FindLibSSH2.cmake13
-rw-r--r--include/git2/clone.h2
-rw-r--r--include/git2/common.h20
-rw-r--r--include/git2/notes.h4
-rw-r--r--include/git2/remote.h6
-rw-r--r--include/git2/repository.h10
-rw-r--r--include/git2/stash.h2
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/blame.c8
-rw-r--r--src/blame_git.c2
-rw-r--r--src/blob.c7
-rw-r--r--src/buffer.c4
-rw-r--r--src/cc-compat.h8
-rw-r--r--src/clone.c2
-rw-r--r--src/commit_graph.c2
-rw-r--r--src/config.c2
-rw-r--r--src/config_file.c4
-rw-r--r--src/config_parse.c2
-rw-r--r--src/describe.c2
-rw-r--r--src/hash/sha1/sha1dc/sha1.c16
-rw-r--r--src/indexer.c40
-rw-r--r--src/libgit2.c23
-rw-r--r--src/merge.c9
-rw-r--r--src/notes.c62
-rw-r--r--src/path.c2
-rw-r--r--src/path.h2
-rw-r--r--src/refdb_fs.c2
-rw-r--r--src/refs.c4
-rw-r--r--src/refspec.c2
-rw-r--r--src/remote.c17
-rw-r--r--src/repository.c125
-rw-r--r--src/repository.h4
-rw-r--r--src/reset.c2
-rw-r--r--src/revparse.c8
-rw-r--r--src/stash.c2
-rw-r--r--src/streams/openssl_legacy.c2
-rw-r--r--src/streams/openssl_legacy.h2
-rw-r--r--src/trailer.c2
-rw-r--r--src/transports/ssh.c8
-rw-r--r--src/transports/winhttp.c2
-rw-r--r--src/util.h2
-rw-r--r--src/win32/findfile.c2
-rw-r--r--src/win32/posix.h12
-rw-r--r--src/win32/posix_w32.c12
-rw-r--r--tests/config/read.c7
-rw-r--r--tests/core/opts.c46
-rw-r--r--tests/remote/httpproxy.c42
-rw-r--r--tests/repo/extensions.c72
-rw-r--r--tests/repo/open.c42
-rw-r--r--tests/resources/config/config215
-rw-r--r--tests/resources/revert-rename.git/HEAD1
-rw-r--r--tests/resources/revert-rename.git/config5
-rw-r--r--tests/resources/revert-rename.git/indexbin0 -> 209 bytes
-rw-r--r--tests/resources/revert-rename.git/objects/info/packs2
-rw-r--r--tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idxbin0 -> 1296 bytes
-rw-r--r--tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.packbin0 -> 783 bytes
-rw-r--r--tests/resources/revert-rename.git/packed-refs2
-rw-r--r--tests/resources/revert-rename.git/refs/heads/master1
-rw-r--r--tests/revert/rename.c49
-rw-r--r--tests/win32/longpath.c49
61 files changed, 618 insertions, 177 deletions
diff --git a/README.md b/README.md
index 9ecb706bd..0cbde525b 100644
--- a/README.md
+++ b/README.md
@@ -371,6 +371,7 @@ Here are the bindings to libgit2 that are currently available:
* hgit2 <https://github.com/jwiegley/gitlib>
* Java
* Jagged <https://github.com/ethomson/jagged>
+ * Git24j <https://github.com/git24j/git24j>
* Javascript / WebAssembly ( browser and nodejs )
* WASM-git <https://github.com/petersalomonsen/wasm-git>
* Julia
diff --git a/cmake/FindLibSSH2.cmake b/cmake/FindLibSSH2.cmake
new file mode 100644
index 000000000..ff5893525
--- /dev/null
+++ b/cmake/FindLibSSH2.cmake
@@ -0,0 +1,13 @@
+# LIBSSH2_FOUND - system has the libssh2 library
+# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
+# LIBSSH2_LIBRARY - the libssh2 library name
+
+FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h)
+
+FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2 libssh2)
+
+INCLUDE(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibSSH2
+ REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
diff --git a/include/git2/clone.h b/include/git2/clone.h
index 2d6f68705..3c3ea260e 100644
--- a/include/git2/clone.h
+++ b/include/git2/clone.h
@@ -133,7 +133,7 @@ typedef struct git_clone_options {
* The name of the branch to checkout. NULL means use the
* remote's default branch.
*/
- const char* checkout_branch;
+ const char *checkout_branch;
/**
* A callback used to create the new repository into which to
diff --git a/include/git2/common.h b/include/git2/common.h
index d278c01b6..2ee829025 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -209,7 +209,9 @@ typedef enum {
GIT_OPT_GET_MWINDOW_FILE_LIMIT,
GIT_OPT_SET_MWINDOW_FILE_LIMIT,
GIT_OPT_SET_ODB_PACKED_PRIORITY,
- GIT_OPT_SET_ODB_LOOSE_PRIORITY
+ GIT_OPT_SET_ODB_LOOSE_PRIORITY,
+ GIT_OPT_GET_EXTENSIONS,
+ GIT_OPT_SET_EXTENSIONS
} git_libgit2_opt_t;
/**
@@ -431,6 +433,22 @@ typedef enum {
* > Override the default priority of the loose ODB backend which
* > is added when default backends are assigned to a repository
*
+ * opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out)
+ * > Returns the list of git extensions that are supported. This
+ * > is the list of built-in extensions supported by libgit2 and
+ * > custom extensions that have been added with
+ * > `GIT_OPT_SET_EXTENSIONS`. Extensions that have been negated
+ * > will not be returned. The returned list should be released
+ * > with `git_strarray_dispose`.
+ *
+ * opts(GIT_OPT_SET_EXTENSIONS, const char **extensions, size_t len)
+ * > Set that the given git extensions are supported by the caller.
+ * > Extensions supported by libgit2 may be negated by prefixing
+ * > them with a `!`. For example: setting extensions to
+ * > { "!noop", "newext" } indicates that the caller does not want
+ * > to support repositories with the `noop` extension but does want
+ * > to support repositories with the `newext` extension.
+ *
* @param option Option key
* @param ... value to set the option
* @return 0 on success, <0 on failure
diff --git a/include/git2/notes.h b/include/git2/notes.h
index c36149e5b..c135881a7 100644
--- a/include/git2/notes.h
+++ b/include/git2/notes.h
@@ -84,8 +84,8 @@ GIT_EXTERN(void) git_note_iterator_free(git_note_iterator *it);
* (negative value)
*/
GIT_EXTERN(int) git_note_next(
- git_oid* note_id,
- git_oid* annotated_id,
+ git_oid *note_id,
+ git_oid *annotated_id,
git_note_iterator *it);
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 51a7d1cdc..4d57eaaf7 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -243,7 +243,7 @@ GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote);
* @param url the url to set
* @return 0 or an error value
*/
-GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char* url);
+GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char *url);
/**
* Set the remote's url for pushing in the configuration.
@@ -257,7 +257,7 @@ GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, con
* @param url the url to set
* @return 0, or an error code
*/
-GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url);
+GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char *url);
/**
* Set the url for this particular url instance. The URL in the
@@ -451,7 +451,7 @@ typedef int GIT_CALLBACK(git_push_transfer_progress_cb)(
unsigned int current,
unsigned int total,
size_t bytes,
- void* payload);
+ void *payload);
/**
* Represents an update which will be performed on the remote during push
diff --git a/include/git2/repository.h b/include/git2/repository.h
index 45becc73d..e69901644 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -797,8 +797,8 @@ GIT_EXTERN(int) git_repository_hashfile(
* @return 0 on success, or an error code
*/
GIT_EXTERN(int) git_repository_set_head(
- git_repository* repo,
- const char* refname);
+ git_repository *repo,
+ const char *refname);
/**
* Make the repository HEAD directly point to the Commit.
@@ -817,8 +817,8 @@ GIT_EXTERN(int) git_repository_set_head(
* @return 0 on success, or an error code
*/
GIT_EXTERN(int) git_repository_set_head_detached(
- git_repository* repo,
- const git_oid* commitish);
+ git_repository *repo,
+ const git_oid *commitish);
/**
* Make the repository HEAD directly point to the Commit.
@@ -854,7 +854,7 @@ GIT_EXTERN(int) git_repository_set_head_detached_from_annotated(
* branch or an error code
*/
GIT_EXTERN(int) git_repository_detach_head(
- git_repository* repo);
+ git_repository *repo);
/**
* Repository state
diff --git a/include/git2/stash.h b/include/git2/stash.h
index 625e51b4b..795920ebc 100644
--- a/include/git2/stash.h
+++ b/include/git2/stash.h
@@ -200,7 +200,7 @@ GIT_EXTERN(int) git_stash_apply(
*/
typedef int GIT_CALLBACK(git_stash_cb)(
size_t index,
- const char* message,
+ const char *message,
const git_oid *stash_id,
void *payload);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 45dec2796..fdb367335 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -232,6 +232,13 @@ ENDIF()
# Optional external dependency: libssh2
IF (USE_SSH)
FIND_PKGLIBRARIES(LIBSSH2 libssh2)
+ IF (NOT LIBSSH2_FOUND)
+ FIND_PACKAGE(LibSSH2)
+ SET(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR})
+ GET_FILENAME_COMPONENT(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY)
+ SET(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY})
+ SET(LIBSSH2_LDFLAGS "-lssh2")
+ ENDIF()
ENDIF()
IF (LIBSSH2_FOUND)
SET(GIT_SSH 1)
diff --git a/src/blame.c b/src/blame.c
index 10e311aee..a6ab43efd 100644
--- a/src/blame.c
+++ b/src/blame.c
@@ -59,7 +59,7 @@ static bool hunk_starts_at_or_after_line(git_blame_hunk *hunk, size_t line)
return line <= hunk->final_start_line_number;
}
-static git_blame_hunk* new_hunk(
+static git_blame_hunk *new_hunk(
size_t start,
size_t lines,
size_t orig_start,
@@ -84,7 +84,7 @@ static void free_hunk(git_blame_hunk *hunk)
git__free(hunk);
}
-static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
+static git_blame_hunk *dup_hunk(git_blame_hunk *hunk)
{
git_blame_hunk *newhunk = new_hunk(
hunk->final_start_line_number,
@@ -122,7 +122,7 @@ static void shift_hunks_by(git_vector *v, size_t start_line, int shift_by)
}
}
-git_blame* git_blame__alloc(
+git_blame *git_blame__alloc(
git_repository *repo,
git_blame_options opts,
const char *path)
@@ -299,7 +299,7 @@ static int index_blob_lines(git_blame *blame)
return blame->num_lines;
}
-static git_blame_hunk* hunk_from_entry(git_blame__entry *e, git_blame *blame)
+static git_blame_hunk *hunk_from_entry(git_blame__entry *e, git_blame *blame)
{
git_blame_hunk *h = new_hunk(
e->lno+1, e->num_lines, e->s_lno+1, e->suspect->path);
diff --git a/src/blame_git.c b/src/blame_git.c
index 073137a68..3d514a1bc 100644
--- a/src/blame_git.c
+++ b/src/blame_git.c
@@ -429,7 +429,7 @@ static int paths_on_dup(void **old, void *new)
return -1;
}
-static git_blame__origin* find_origin(
+static git_blame__origin *find_origin(
git_blame *blame,
git_commit *parent,
git_blame__origin *origin)
diff --git a/src/blob.c b/src/blob.c
index 01ebf075e..79096ee95 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -138,12 +138,13 @@ static int write_file_filtered(
git_object_size_t *size,
git_odb *odb,
const char *full_path,
- git_filter_list *fl)
+ git_filter_list *fl,
+ git_repository* repo)
{
int error;
git_buf tgt = GIT_BUF_INIT;
- error = git_filter_list_apply_to_file(&tgt, fl, NULL, full_path);
+ error = git_filter_list_apply_to_file(&tgt, fl, repo, full_path);
/* Write the file to disk if it was properly filtered */
if (!error) {
@@ -238,7 +239,7 @@ int git_blob__create_from_paths(
error = write_file_stream(id, odb, content_path, size);
else {
/* We need to apply one or more filters */
- error = write_file_filtered(id, &size, odb, content_path, fl);
+ error = write_file_filtered(id, &size, odb, content_path, fl, repo);
git_filter_list_free(fl);
}
diff --git a/src/buffer.c b/src/buffer.c
index 794e1f1ab..ab2a6139a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -670,7 +670,7 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
va_start(ap, nbuf);
for (i = 0; i < nbuf; ++i) {
- const char* segment;
+ const char *segment;
size_t segment_len;
segment = va_arg(ap, const char *);
@@ -702,7 +702,7 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
va_start(ap, nbuf);
for (i = 0; i < nbuf; ++i) {
- const char* segment;
+ const char *segment;
size_t segment_len;
segment = va_arg(ap, const char *);
diff --git a/src/cc-compat.h b/src/cc-compat.h
index 6bdc65145..f701b2d93 100644
--- a/src/cc-compat.h
+++ b/src/cc-compat.h
@@ -29,12 +29,6 @@
# endif
#endif
-#ifdef __GNUC__
-# define GIT_TYPEOF(x) (__typeof__(x))
-#else
-# define GIT_TYPEOF(x)
-#endif
-
#if defined(__GNUC__)
# define GIT_ALIGN(x,size) x __attribute__ ((aligned(size)))
#elif defined(_MSC_VER)
@@ -46,7 +40,7 @@
#if defined(__GNUC__)
# define GIT_UNUSED(x) \
do { \
- typeof(x) _unused __attribute__((unused)); \
+ __typeof__(x) _unused __attribute__((unused)); \
_unused = (x); \
} while (0)
#else
diff --git a/src/clone.c b/src/clone.c
index e29a4aab3..752df3b92 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -265,7 +265,7 @@ static int update_head_to_branch(
{
int retcode;
git_buf remote_branch_name = GIT_BUF_INIT;
- git_reference* remote_ref = NULL;
+ git_reference *remote_ref = NULL;
git_buf default_branch = GIT_BUF_INIT;
GIT_ASSERT_ARG(remote);
diff --git a/src/commit_graph.c b/src/commit_graph.c
index 71e415e99..f663fc5d3 100644
--- a/src/commit_graph.c
+++ b/src/commit_graph.c
@@ -728,7 +728,7 @@ int git_commit_graph_writer_add_revwalk(git_commit_graph_writer *w, git_revwalk
git_oid id;
git_repository *repo = git_revwalk_repository(walk);
git_commit *commit;
- struct packed_commit* packed_commit;
+ struct packed_commit *packed_commit;
while ((git_revwalk_next(&id, walk)) == 0) {
error = git_commit_lookup(&commit, repo, &id);
diff --git a/src/config.c b/src/config.c
index 7a5dadd87..3251cd51f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -511,7 +511,7 @@ int git_config_backend_foreach_match(
void *payload)
{
git_config_entry *entry;
- git_config_iterator* iter;
+ git_config_iterator *iter;
git_regexp regex;
int error = 0;
diff --git a/src/config_file.c b/src/config_file.c
index 5267beb94..3588e6be6 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -164,7 +164,7 @@ out:
return error;
}
-static void config_file_clear_includes(config_file_backend* cfg)
+static void config_file_clear_includes(config_file_backend *cfg)
{
config_file *include;
uint32_t i;
@@ -1104,7 +1104,7 @@ static int write_on_eof(
/*
* This is pretty much the parsing, except we write out anything we don't have
*/
-static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char* value)
+static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char *value)
{
char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot;
diff --git a/src/config_parse.c b/src/config_parse.c
index a2d779bfa..9f95e67d7 100644
--- a/src/config_parse.c
+++ b/src/config_parse.c
@@ -349,7 +349,7 @@ static int parse_multiline_variable(git_config_parser *reader, git_buf *value, i
}
/* If it was just a comment, pretend it didn't exist */
- quote_count = strip_comments(line, !!in_quotes);
+ quote_count = strip_comments(line, in_quotes);
if (line[0] == '\0')
goto next;
diff --git a/src/describe.c b/src/describe.c
index 3648ccef6..103d0da5c 100644
--- a/src/describe.c
+++ b/src/describe.c
@@ -391,7 +391,7 @@ static int show_suffix(
git_buf *buf,
int depth,
git_repository *repo,
- const git_oid* id,
+ const git_oid *id,
unsigned int abbrev_size)
{
int error, size = 0;
diff --git a/src/hash/sha1/sha1dc/sha1.c b/src/hash/sha1/sha1dc/sha1.c
index 86b8cc075..4d03c75d8 100644
--- a/src/hash/sha1/sha1dc/sha1.c
+++ b/src/hash/sha1/sha1dc/sha1.c
@@ -1710,7 +1710,7 @@ static void sha1_recompression_step(uint32_t step, uint32_t ihvin[5], uint32_t i
-static void sha1_process(SHA1_CTX* ctx, const uint32_t block[16])
+static void sha1_process(SHA1_CTX *ctx, const uint32_t block[16])
{
unsigned i, j;
uint32_t ubc_dv_mask[DVMASKSIZE] = { 0xFFFFFFFF };
@@ -1762,7 +1762,7 @@ static void sha1_process(SHA1_CTX* ctx, const uint32_t block[16])
}
}
-void SHA1DCInit(SHA1_CTX* ctx)
+void SHA1DCInit(SHA1_CTX *ctx)
{
ctx->total = 0;
ctx->ihv[0] = 0x67452301;
@@ -1778,7 +1778,7 @@ void SHA1DCInit(SHA1_CTX* ctx)
ctx->callback = NULL;
}
-void SHA1DCSetSafeHash(SHA1_CTX* ctx, int safehash)
+void SHA1DCSetSafeHash(SHA1_CTX *ctx, int safehash)
{
if (safehash)
ctx->safe_hash = 1;
@@ -1787,7 +1787,7 @@ void SHA1DCSetSafeHash(SHA1_CTX* ctx, int safehash)
}
-void SHA1DCSetUseUBC(SHA1_CTX* ctx, int ubc_check)
+void SHA1DCSetUseUBC(SHA1_CTX *ctx, int ubc_check)
{
if (ubc_check)
ctx->ubc_check = 1;
@@ -1795,7 +1795,7 @@ void SHA1DCSetUseUBC(SHA1_CTX* ctx, int ubc_check)
ctx->ubc_check = 0;
}
-void SHA1DCSetUseDetectColl(SHA1_CTX* ctx, int detect_coll)
+void SHA1DCSetUseDetectColl(SHA1_CTX *ctx, int detect_coll)
{
if (detect_coll)
ctx->detect_coll = 1;
@@ -1803,7 +1803,7 @@ void SHA1DCSetUseDetectColl(SHA1_CTX* ctx, int detect_coll)
ctx->detect_coll = 0;
}
-void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX* ctx, int reduced_round_coll)
+void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX *ctx, int reduced_round_coll)
{
if (reduced_round_coll)
ctx->reduced_round_coll = 1;
@@ -1811,12 +1811,12 @@ void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX* ctx, int reduced_round_coll)
ctx->reduced_round_coll = 0;
}
-void SHA1DCSetCallback(SHA1_CTX* ctx, collision_block_callback callback)
+void SHA1DCSetCallback(SHA1_CTX *ctx, collision_block_callback callback)
{
ctx->callback = callback;
}
-void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
+void SHA1DCUpdate(SHA1_CTX *ctx, const char *buf, size_t len)
{
unsigned left, fill;
diff --git a/src/indexer.c b/src/indexer.c
index d546888cc..ce7737500 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -601,9 +601,10 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
idx->inbuf_len += size - to_expell;
}
+#if defined(NO_MMAP) || !defined(GIT_WIN32)
+
static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
{
-#ifdef NO_MMAP
size_t remaining_size = size;
const char *ptr = (const char *)data;
@@ -619,7 +620,31 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
offset += nb;
remaining_size -= nb;
}
+
+ return 0;
+}
+
+static int append_to_pack(git_indexer *idx, const void *data, size_t size)
+{
+ if (write_at(idx, data, idx->pack->mwf.size, size) < 0) {
+ git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
+ return -1;
+ }
+
+ return 0;
+}
+
#else
+
+/*
+ * Windows may keep different views to a networked file for the mmap- and
+ * open-accessed versions of a file, so any writes done through
+ * `write(2)`/`pwrite(2)` may not be reflected on the data that `mmap(2)` is
+ * able to read.
+ */
+
+static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
+{
git_file fd = idx->pack->mwf.fd;
size_t mmap_alignment;
size_t page_offset;
@@ -644,7 +669,6 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
map_data = (unsigned char *)map.data;
memcpy(map_data + page_offset, data, size);
p_munmap(&map);
-#endif
return 0;
}
@@ -680,6 +704,8 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
return write_at(idx, data, idx->pack->mwf.size, size);
}
+#endif
+
static int read_stream_object(git_indexer *idx, git_indexer_progress *stats)
{
git_packfile_stream *stream = &idx->stream;
@@ -1279,11 +1305,19 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
if (git_mwindow_free_all(&idx->pack->mwf) < 0)
goto on_error;
- /* Truncate file to undo rounding up to next page_size in append_to_pack */
+#if !defined(NO_MMAP) && defined(GIT_WIN32)
+ /*
+ * Some non-Windows remote filesystems fail when truncating files if the
+ * file permissions change after opening the file (done by p_mkstemp).
+ *
+ * Truncation is only needed when mmap is used to undo rounding up to next
+ * page_size in append_to_pack.
+ */
if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
return -1;
}
+#endif
if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
git_error_set(GIT_ERROR_OS, "failed to fsync packfile");
diff --git a/src/libgit2.c b/src/libgit2.c
index 09f7ab533..cc793b458 100644
--- a/src/libgit2.c
+++ b/src/libgit2.c
@@ -52,6 +52,7 @@ static void libgit2_settings_global_shutdown(void)
{
git__free(git__user_agent);
git__free(git__ssl_ciphers);
+ git_repository__free_extensions();
}
static int git_libgit2_settings_global_init(void)
@@ -367,6 +368,28 @@ int git_libgit2_opts(int key, ...)
git_odb__loose_priority = va_arg(ap, int);
break;
+ case GIT_OPT_SET_EXTENSIONS:
+ {
+ const char **extensions = va_arg(ap, const char **);
+ size_t len = va_arg(ap, size_t);
+ error = git_repository__set_extensions(extensions, len);
+ }
+ break;
+
+ case GIT_OPT_GET_EXTENSIONS:
+ {
+ git_strarray *out = va_arg(ap, git_strarray *);
+ char **extensions;
+ size_t len;
+
+ if ((error = git_repository__extensions(&extensions, &len)) < 0)
+ break;
+
+ out->strings = extensions;
+ out->count = len;
+ }
+ break;
+
default:
git_error_set(GIT_ERROR_INVALID, "invalid option key");
error = -1;
diff --git a/src/merge.c b/src/merge.c
index 0e4bb582a..1c841bdfb 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -816,8 +816,11 @@ static int merge_conflict_resolve_one_renamed(
conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
return 0;
- ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0);
- theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0);
+ ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0) ||
+ (conflict->ancestor_entry.mode != conflict->our_entry.mode);
+
+ theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0) ||
+ (conflict->ancestor_entry.mode != conflict->their_entry.mode);
/* if both are modified (and not to a common target) require a merge */
if (ours_changed && theirs_changed &&
@@ -1151,7 +1154,7 @@ static void deletes_by_oid_free(git_oidmap *map) {
git_oidmap_free(map);
}
-static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid *id, size_t idx)
+static int deletes_by_oid_enqueue(git_oidmap *map, git_pool *pool, const git_oid *id, size_t idx)
{
deletes_by_oid_queue *queue;
size_t *array_entry;
diff --git a/src/notes.c b/src/notes.c
index b9e198599..95db334fb 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -407,31 +407,33 @@ cleanup:
return error;
}
-static int note_get_default_ref(char **out, git_repository *repo)
+static int note_get_default_ref(git_buf *out, git_repository *repo)
{
git_config *cfg;
- int ret = git_repository_config__weakptr(&cfg, repo);
+ int error;
+
+ if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
+ return error;
- *out = (ret != 0) ? NULL : git_config__get_string_force(
- cfg, "core.notesref", GIT_NOTES_DEFAULT_REF);
+ error = git_config_get_string_buf(out, cfg, "core.notesref");
- return ret;
+ if (error == GIT_ENOTFOUND)
+ error = git_buf_puts(out, GIT_NOTES_DEFAULT_REF);
+
+ return error;
}
-static int normalize_namespace(char **out, git_repository *repo, const char *notes_ref)
+static int normalize_namespace(git_buf *out, git_repository *repo, const char *notes_ref)
{
- if (notes_ref) {
- *out = git__strdup(notes_ref);
- GIT_ERROR_CHECK_ALLOC(*out);
- return 0;
- }
+ if (notes_ref)
+ return git_buf_puts(out, notes_ref);
return note_get_default_ref(out, repo);
}
static int retrieve_note_commit(
git_commit **commit_out,
- char **notes_ref_out,
+ git_buf *notes_ref_out,
git_repository *repo,
const char *notes_ref)
{
@@ -441,7 +443,7 @@ static int retrieve_note_commit(
if ((error = normalize_namespace(notes_ref_out, repo, notes_ref)) < 0)
return error;
- if ((error = git_reference_name_to_id(&oid, repo, *notes_ref_out)) < 0)
+ if ((error = git_reference_name_to_id(&oid, repo, notes_ref_out->ptr)) < 0)
return error;
if (git_commit_lookup(commit_out, repo, &oid) < 0)
@@ -476,7 +478,7 @@ int git_note_read(git_note **out, git_repository *repo,
const char *notes_ref_in, const git_oid *oid)
{
int error;
- char *notes_ref = NULL;
+ git_buf notes_ref = GIT_BUF_INIT;
git_commit *commit = NULL;
error = retrieve_note_commit(&commit, &notes_ref, repo, notes_ref_in);
@@ -487,7 +489,7 @@ int git_note_read(git_note **out, git_repository *repo,
error = git_note_commit_read(out, repo, commit, oid);
cleanup:
- git__free(notes_ref);
+ git_buf_dispose(&notes_ref);
git_commit_free(commit);
return error;
}
@@ -534,7 +536,7 @@ int git_note_create(
int allow_note_overwrite)
{
int error;
- char *notes_ref = NULL;
+ git_buf notes_ref = GIT_BUF_INIT;
git_commit *existing_notes_commit = NULL;
git_reference *ref = NULL;
git_oid notes_blob_oid, notes_commit_oid;
@@ -553,14 +555,14 @@ int git_note_create(
if (error < 0)
goto cleanup;
- error = git_reference_create(&ref, repo, notes_ref,
+ error = git_reference_create(&ref, repo, notes_ref.ptr,
&notes_commit_oid, 1, NULL);
if (out != NULL)
git_oid_cpy(out, &notes_blob_oid);
cleanup:
- git__free(notes_ref);
+ git_buf_dispose(&notes_ref);
git_commit_free(existing_notes_commit);
git_reference_free(ref);
return error;
@@ -596,7 +598,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in,
const git_oid *oid)
{
int error;
- char *notes_ref_target = NULL;
+ git_buf notes_ref_target = GIT_BUF_INIT;
git_commit *existing_notes_commit = NULL;
git_oid new_notes_commit;
git_reference *notes_ref = NULL;
@@ -612,11 +614,11 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in,
if (error < 0)
goto cleanup;
- error = git_reference_create(&notes_ref, repo, notes_ref_target,
+ error = git_reference_create(&notes_ref, repo, notes_ref_target.ptr,
&new_notes_commit, 1, NULL);
cleanup:
- git__free(notes_ref_target);
+ git_buf_dispose(&notes_ref_target);
git_reference_free(notes_ref);
git_commit_free(existing_notes_commit);
return error;
@@ -624,18 +626,16 @@ cleanup:
int git_note_default_ref(git_buf *out, git_repository *repo)
{
- char *default_ref;
int error;
GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG(repo);
if ((error = git_buf_sanitize(out)) < 0 ||
- (error = note_get_default_ref(&default_ref, repo)) < 0)
- return error;
+ (error = note_get_default_ref(out, repo)) < 0)
+ git_buf_dispose(out);
- git_buf_attach(out, default_ref, strlen(default_ref));
- return 0;
+ return error;
}
const git_signature *git_note_committer(const git_note *note)
@@ -674,7 +674,7 @@ void git_note_free(git_note *note)
}
static int process_entry_path(
- const char* entry_path,
+ const char *entry_path,
git_oid *annotated_object_id)
{
int error = 0;
@@ -780,7 +780,7 @@ int git_note_iterator_new(
{
int error;
git_commit *commit = NULL;
- char *notes_ref;
+ git_buf notes_ref = GIT_BUF_INIT;
error = retrieve_note_commit(&commit, &notes_ref, repo, notes_ref_in);
if (error < 0)
@@ -789,15 +789,15 @@ int git_note_iterator_new(
error = git_note_commit_iterator_new(it, commit);
cleanup:
- git__free(notes_ref);
+ git_buf_dispose(&notes_ref);
git_commit_free(commit);
return error;
}
int git_note_next(
- git_oid* note_id,
- git_oid* annotated_id,
+ git_oid *note_id,
+ git_oid *annotated_id,
git_note_iterator *it)
{
int error;
diff --git a/src/path.c b/src/path.c
index ec573220e..c444b31a7 100644
--- a/src/path.c
+++ b/src/path.c
@@ -413,7 +413,7 @@ int git_path_to_dir(git_buf *path)
return git_buf_oom(path) ? -1 : 0;
}
-void git_path_string_to_dir(char* path, size_t size)
+void git_path_string_to_dir(char *path, size_t size)
{
size_t end = strlen(path);
diff --git a/src/path.h b/src/path.h
index dcf5652df..de6ec8ff2 100644
--- a/src/path.h
+++ b/src/path.h
@@ -85,7 +85,7 @@ extern int git_path_to_dir(git_buf *path);
/**
* Ensure string has a trailing '/' if there is space for it.
*/
-extern void git_path_string_to_dir(char* path, size_t size);
+extern void git_path_string_to_dir(char *path, size_t size);
/**
* Taken from git.git; returns nonzero if the given path is "." or "..".
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 0cb925516..24cb22fb0 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -764,7 +764,7 @@ static bool ref_is_available(
static int reference_path_available(
refdb_fs_backend *backend,
const char *new_ref,
- const char* old_ref,
+ const char *old_ref,
int force)
{
size_t i;
diff --git a/src/refs.c b/src/refs.c
index 4900afabf..8acfa84a5 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -249,7 +249,7 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re
git_reference *ref;
git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;
- static const char* formatters[] = {
+ static const char *formatters[] = {
"%s",
GIT_REFS_DIR "%s",
GIT_REFS_TAGS_DIR "%s",
@@ -1246,7 +1246,7 @@ int git_reference_is_note(const git_reference *ref)
return git_reference__is_note(ref->name);
}
-static int peel_error(int error, const git_reference *ref, const char* msg)
+static int peel_error(int error, const git_reference *ref, const char *msg)
{
git_error_set(
GIT_ERROR_INVALID,
diff --git a/src/refspec.c b/src/refspec.c
index d0be29bf6..c72721a43 100644
--- a/src/refspec.c
+++ b/src/refspec.c
@@ -359,7 +359,7 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs)
git_remote_head key;
git_refspec *cur;
- const char* formatters[] = {
+ const char *formatters[] = {
GIT_REFS_DIR "%s",
GIT_REFS_TAGS_DIR "%s",
GIT_REFS_HEADS_DIR "%s",
diff --git a/src/remote.c b/src/remote.c
index 7dddea93a..56d7e42db 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -677,7 +677,7 @@ int git_remote_set_instance_pushurl(git_remote *remote, const char *url)
return 0;
}
-int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url)
+int git_remote_set_pushurl(git_repository *repo, const char *remote, const char *url)
{
return set_url(repo, remote, CONFIG_PUSHURL_FMT, url);
}
@@ -884,15 +884,22 @@ static void url_config_trim(git_net_url *url)
static int http_proxy_config(char **out, git_remote *remote, git_net_url *url)
{
- git_config *cfg;
+ git_config *cfg = NULL;
git_buf buf = GIT_BUF_INIT;
git_net_url lookup_url = GIT_NET_URL_INIT;
int error;
- if ((error = git_net_url_dup(&lookup_url, url)) < 0 ||
- (error = git_repository_config__weakptr(&cfg, remote->repo)) < 0)
+ if ((error = git_net_url_dup(&lookup_url, url)) < 0)
goto done;
+ if (remote->repo) {
+ if ((error = git_repository_config(&cfg, remote->repo)) < 0)
+ goto done;
+ } else {
+ if ((error = git_config_open_default(&cfg)) < 0)
+ goto done;
+ }
+
/* remote.<name>.proxy config setting */
if (remote->name && remote->name[0]) {
git_buf_clear(&buf);
@@ -922,6 +929,7 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url)
error = lookup_config(out, cfg, "http.proxy");
done:
+ git_config_free(cfg);
git_buf_dispose(&buf);
git_net_url_dispose(&lookup_url);
return error;
@@ -971,7 +979,6 @@ int git_remote__http_proxy(char **out, git_remote *remote, git_net_url *url)
GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG(remote);
- GIT_ASSERT_ARG(remote->repo);
*out = NULL;
diff --git a/src/repository.c b/src/repository.c
index aae0c910b..8f0f477c4 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1427,15 +1427,60 @@ static int check_repositoryformatversion(int *version, git_config *config)
return 0;
}
+static const char *builtin_extensions[] = {
+ "noop"
+};
+
+static git_vector user_extensions = GIT_VECTOR_INIT;
+
static int check_valid_extension(const git_config_entry *entry, void *payload)
{
+ git_buf cfg = GIT_BUF_INIT;
+ bool reject;
+ const char *extension;
+ size_t i;
+ int error = 0;
+
GIT_UNUSED(payload);
- if (!strcmp(entry->name, "extensions.noop"))
- return 0;
+ git_vector_foreach (&user_extensions, i, extension) {
+ git_buf_clear(&cfg);
+
+ /*
+ * Users can specify that they don't want to support an
+ * extension with a '!' prefix.
+ */
+ if ((reject = (extension[0] == '!')) == true)
+ extension = &extension[1];
+
+ if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0)
+ goto done;
+
+ if (strcmp(entry->name, cfg.ptr) == 0) {
+ if (reject)
+ goto fail;
+
+ goto done;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
+ extension = builtin_extensions[i];
+
+ if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0)
+ goto done;
+ if (strcmp(entry->name, cfg.ptr) == 0)
+ goto done;
+ }
+
+fail:
git_error_set(GIT_ERROR_REPOSITORY, "unsupported extension name %s", entry->name);
- return -1;
+ error = -1;
+
+done:
+ git_buf_dispose(&cfg);
+ return error;
}
static int check_extensions(git_config *config, int version)
@@ -1446,6 +1491,70 @@ static int check_extensions(git_config *config, int version)
return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL);
}
+int git_repository__extensions(char ***out, size_t *out_len)
+{
+ git_vector extensions;
+ const char *builtin, *user;
+ char *extension;
+ size_t i, j;
+
+ if (git_vector_init(&extensions, 8, NULL) < 0)
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
+ bool match = false;
+
+ builtin = builtin_extensions[i];
+
+ git_vector_foreach (&user_extensions, j, user) {
+ if (user[0] == '!' && strcmp(builtin, &user[1]) == 0) {
+ match = true;
+ break;
+ }
+ }
+
+ if (match)
+ continue;
+
+ if ((extension = git__strdup(builtin)) == NULL ||
+ git_vector_insert(&extensions, extension) < 0)
+ return -1;
+ }
+
+ git_vector_foreach (&user_extensions, i, user) {
+ if (user[0] == '!')
+ continue;
+
+ if ((extension = git__strdup(user)) == NULL ||
+ git_vector_insert(&extensions, extension) < 0)
+ return -1;
+ }
+
+ *out = (char **)git_vector_detach(out_len, NULL, &extensions);
+ return 0;
+}
+
+int git_repository__set_extensions(const char **extensions, size_t len)
+{
+ char *extension;
+ size_t i;
+
+ git_repository__free_extensions();
+
+ for (i = 0; i < len; i++) {
+ if ((extension = git__strdup(extensions[i])) == NULL ||
+ git_vector_insert(&user_extensions, extension) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+void git_repository__free_extensions(void)
+{
+ git_vector_free_deep(&user_extensions);
+}
+
int git_repository_create_head(const char *git_dir, const char *ref_name)
{
git_buf ref_path = GIT_BUF_INIT;
@@ -2850,8 +2959,8 @@ cleanup:
}
int git_repository_set_head(
- git_repository* repo,
- const char* refname)
+ git_repository *repo,
+ const char *refname)
{
git_reference *ref = NULL, *current = NULL, *new_head = NULL;
git_buf log_message = GIT_BUF_INIT;
@@ -2900,8 +3009,8 @@ cleanup:
}
int git_repository_set_head_detached(
- git_repository* repo,
- const git_oid* commitish)
+ git_repository *repo,
+ const git_oid *commitish)
{
return detach(repo, commitish, NULL);
}
@@ -2916,7 +3025,7 @@ int git_repository_set_head_detached_from_annotated(
return detach(repo, git_annotated_commit_id(commitish), commitish->description);
}
-int git_repository_detach_head(git_repository* repo)
+int git_repository_detach_head(git_repository *repo)
{
git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
git_object *object = NULL;
diff --git a/src/repository.h b/src/repository.h
index f48dd9edf..cbc160140 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -249,4 +249,8 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo);
*/
int git_repository_workdir_path(git_buf *out, git_repository *repo, const char *path);
+int git_repository__extensions(char ***out, size_t *out_len);
+int git_repository__set_extensions(const char **extensions, size_t len);
+void git_repository__free_extensions(void);
+
#endif
diff --git a/src/reset.c b/src/reset.c
index dfae91d6f..f21a620c6 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -22,7 +22,7 @@
int git_reset_default(
git_repository *repo,
const git_object *target,
- const git_strarray* pathspecs)
+ const git_strarray *pathspecs)
{
git_object *commit = NULL;
git_tree *tree = NULL;
diff --git a/src/revparse.c b/src/revparse.c
index b0c312d72..b4d5d4759 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -14,7 +14,7 @@
#include "git2.h"
-static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen)
+static int maybe_sha_or_abbrev(git_object **out, git_repository *repo, const char *spec, size_t speclen)
{
git_oid oid;
@@ -24,7 +24,7 @@ static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const cha
return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJECT_ANY);
}
-static int maybe_sha(git_object** out, git_repository *repo, const char *spec)
+static int maybe_sha(git_object **out, git_repository *repo, const char *spec)
{
size_t speclen = strlen(spec);
@@ -34,7 +34,7 @@ static int maybe_sha(git_object** out, git_repository *repo, const char *spec)
return maybe_sha_or_abbrev(out, repo, spec, speclen);
}
-static int maybe_abbrev(git_object** out, git_repository *repo, const char *spec)
+static int maybe_abbrev(git_object **out, git_repository *repo, const char *spec)
{
size_t speclen = strlen(spec);
@@ -310,7 +310,7 @@ cleanup:
return error;
}
-static int handle_at_syntax(git_object **out, git_reference **ref, const char *spec, size_t identifier_len, git_repository* repo, const char *curly_braces_content)
+static int handle_at_syntax(git_object **out, git_reference **ref, const char *spec, size_t identifier_len, git_repository *repo, const char *curly_braces_content)
{
bool is_numeric;
int parsed = 0, error = -1;
diff --git a/src/stash.c b/src/stash.c
index 8ee127322..49ea26fdd 100644
--- a/src/stash.c
+++ b/src/stash.c
@@ -56,7 +56,7 @@ static int append_abbreviated_oid(git_buf *out, const git_oid *b_commit)
return git_buf_oom(out) ? -1 : 0;
}
-static int append_commit_description(git_buf *out, git_commit* commit)
+static int append_commit_description(git_buf *out, git_commit *commit)
{
const char *summary = git_commit_summary(commit);
GIT_ERROR_CHECK_ALLOC(summary);
diff --git a/src/streams/openssl_legacy.c b/src/streams/openssl_legacy.c
index 1c1ff60c0..e61e6efbb 100644
--- a/src/streams/openssl_legacy.c
+++ b/src/streams/openssl_legacy.c
@@ -36,7 +36,7 @@ int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings)
return 0;
}
-BIO_METHOD* BIO_meth_new__legacy(int type, const char *name)
+BIO_METHOD *BIO_meth_new__legacy(int type, const char *name)
{
BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
if (!meth) {
diff --git a/src/streams/openssl_legacy.h b/src/streams/openssl_legacy.h
index 1f74fd95a..e6dae9572 100644
--- a/src/streams/openssl_legacy.h
+++ b/src/streams/openssl_legacy.h
@@ -42,7 +42,7 @@
#if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC)
extern int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings);
-extern BIO_METHOD* BIO_meth_new__legacy(int type, const char *name);
+extern BIO_METHOD *BIO_meth_new__legacy(int type, const char *name);
extern void BIO_meth_free__legacy(BIO_METHOD *biom);
extern int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int));
extern int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int));
diff --git a/src/trailer.c b/src/trailer.c
index ca81fd020..61cdd1ba1 100644
--- a/src/trailer.c
+++ b/src/trailer.c
@@ -258,7 +258,7 @@ static size_t find_trailer_end(const char *buf, size_t len)
return len - ignore_non_trailer(buf, len);
}
-static char *extract_trailer_block(const char *message, size_t* len)
+static char *extract_trailer_block(const char *message, size_t *len)
{
size_t patch_start = find_patch_start(message);
size_t trailer_end = find_trailer_end(message, patch_start);
diff --git a/src/transports/ssh.c b/src/transports/ssh.c
index efa77a798..1b00be79c 100644
--- a/src/transports/ssh.c
+++ b/src/transports/ssh.c
@@ -476,11 +476,11 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char *
}
static int _git_ssh_session_create(
- LIBSSH2_SESSION** session,
+ LIBSSH2_SESSION **session,
git_stream *io)
{
int rc = 0;
- LIBSSH2_SESSION* s;
+ LIBSSH2_SESSION *s;
git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent);
GIT_ASSERT_ARG(session);
@@ -521,8 +521,8 @@ static int _git_ssh_setup_conn(
size_t i;
ssh_stream *s;
git_credential *cred = NULL;
- LIBSSH2_SESSION* session=NULL;
- LIBSSH2_CHANNEL* channel=NULL;
+ LIBSSH2_SESSION *session=NULL;
+ LIBSSH2_CHANNEL *channel=NULL;
t->current_stream = NULL;
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 178773a41..f4801a451 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -250,7 +250,7 @@ static int acquire_fallback_cred(
hCoInitResult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(hCoInitResult) || hCoInitResult == RPC_E_CHANGED_MODE) {
- IInternetSecurityManager* pISM;
+ IInternetSecurityManager *pISM;
/* And if the target URI is in the My Computer, Intranet, or Trusted zones */
if (SUCCEEDED(CoCreateInstance(&CLSID_InternetSecurityManager, NULL,
diff --git a/src/util.h b/src/util.h
index 68c2b1804..e8074fcb9 100644
--- a/src/util.h
+++ b/src/util.h
@@ -34,7 +34,7 @@
# define GIT_CONTAINER_OF(ptr, type, member) \
__builtin_choose_expr( \
__builtin_offsetof(type, member) == 0 && \
- __builtin_types_compatible_p(typeof(&((type *) 0)->member), typeof(ptr)), \
+ __builtin_types_compatible_p(__typeof__(&((type *) 0)->member), __typeof__(ptr)), \
((type *) (ptr)), \
(void)0)
#else
diff --git a/src/win32/findfile.c b/src/win32/findfile.c
index f541a03d4..40d2d518a 100644
--- a/src/win32/findfile.c
+++ b/src/win32/findfile.c
@@ -49,7 +49,7 @@ static int win32_path_to_8(git_buf *dest, const wchar_t *src)
return git_buf_sets(dest, utf8_path);
}
-static wchar_t* win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen)
+static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen)
{
wchar_t term, *base = path;
diff --git a/src/win32/posix.h b/src/win32/posix.h
index f115088b4..87c6b436a 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -23,7 +23,7 @@ typedef SOCKET GIT_SOCKET;
extern int p_fstat(int fd, struct stat *buf);
extern int p_lstat(const char *file_name, struct stat *buf);
-extern int p_stat(const char* path, struct stat *buf);
+extern int p_stat(const char *path, struct stat *buf);
extern int p_utimes(const char *filename, const struct p_timeval times[2]);
extern int p_futimes(int fd, const struct p_timeval times[2]);
@@ -38,15 +38,15 @@ extern char *p_realpath(const char *orig_path, char *buffer);
extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags);
extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags);
-extern int p_inet_pton(int af, const char* src, void* dst);
+extern int p_inet_pton(int af, const char *src, void* dst);
extern int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr);
extern int p_snprintf(char *buffer, size_t count, const char *format, ...) GIT_FORMAT_PRINTF(3, 4);
extern int p_mkstemp(char *tmp_path);
-extern int p_chdir(const char* path);
-extern int p_chmod(const char* path, mode_t mode);
-extern int p_rmdir(const char* path);
-extern int p_access(const char* path, mode_t mode);
+extern int p_chdir(const char *path);
+extern int p_chmod(const char *path, mode_t mode);
+extern int p_rmdir(const char *path);
+extern int p_access(const char *path, mode_t mode);
extern int p_ftruncate(int fd, off64_t size);
/* p_lstat is almost but not quite POSIX correct. Specifically, the use of
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 7fcc472e9..66d12cfcf 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -690,7 +690,7 @@ static int getfinalpath_w(
return (int)git_win32_path_remove_namespace(dest, dwChars);
}
-static int follow_and_lstat_link(git_win32_path path, struct stat* buf)
+static int follow_and_lstat_link(git_win32_path path, struct stat *buf)
{
git_win32_path target_w;
@@ -716,7 +716,7 @@ int p_fstat(int fd, struct stat *buf)
return 0;
}
-int p_stat(const char* path, struct stat* buf)
+int p_stat(const char *path, struct stat *buf)
{
git_win32_path path_w;
int len;
@@ -733,7 +733,7 @@ int p_stat(const char* path, struct stat* buf)
return 0;
}
-int p_chdir(const char* path)
+int p_chdir(const char *path)
{
git_win32_path buf;
@@ -743,7 +743,7 @@ int p_chdir(const char* path)
return _wchdir(buf);
}
-int p_chmod(const char* path, mode_t mode)
+int p_chmod(const char *path, mode_t mode)
{
git_win32_path buf;
@@ -753,7 +753,7 @@ int p_chmod(const char* path, mode_t mode)
return _wchmod(buf, mode);
}
-int p_rmdir(const char* path)
+int p_rmdir(const char *path)
{
git_win32_path buf;
int error;
@@ -873,7 +873,7 @@ int p_mkstemp(char *tmp_path)
return p_open(tmp_path, O_RDWR | O_CREAT | O_EXCL, 0744); /* -V536 */
}
-int p_access(const char* path, mode_t mode)
+int p_access(const char *path, mode_t mode)
{
git_win32_path buf;
diff --git a/tests/config/read.c b/tests/config/read.c
index badf5118e..8d1bb8b0a 100644
--- a/tests/config/read.c
+++ b/tests/config/read.c
@@ -213,6 +213,13 @@ void test_config_read__symbol_headers(void)
git_config_free(cfg);
}
+void test_config_read__multiline_multiple_quoted_comment_chars(void)
+{
+ git_config *cfg;
+ cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config21")));
+ git_config_free(cfg);
+}
+
void test_config_read__header_in_last_line(void)
{
git_config *cfg;
diff --git a/tests/core/opts.c b/tests/core/opts.c
index 72408cbe8..e8f65d510 100644
--- a/tests/core/opts.c
+++ b/tests/core/opts.c
@@ -1,6 +1,11 @@
#include "clar_libgit2.h"
#include "cache.h"
+void test_core_opts__cleanup(void)
+{
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, NULL, 0));
+}
+
void test_core_opts__readwrite(void)
{
size_t old_val = 0;
@@ -23,3 +28,44 @@ void test_core_opts__invalid_option(void)
cl_git_fail(git_libgit2_opts(-1, "foobar"));
}
+void test_core_opts__extensions_query(void)
+{
+ git_strarray out = { 0 };
+
+ cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
+
+ cl_assert_equal_sz(out.count, 1);
+ cl_assert_equal_s("noop", out.strings[0]);
+
+ git_strarray_dispose(&out);
+}
+
+void test_core_opts__extensions_add(void)
+{
+ const char *in[] = { "foo" };
+ git_strarray out = { 0 };
+
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
+ cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
+
+ cl_assert_equal_sz(out.count, 2);
+ cl_assert_equal_s("noop", out.strings[0]);
+ cl_assert_equal_s("foo", out.strings[1]);
+
+ git_strarray_dispose(&out);
+}
+
+void test_core_opts__extensions_remove(void)
+{
+ const char *in[] = { "bar", "!negate", "!noop", "baz" };
+ git_strarray out = { 0 };
+
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
+ cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
+
+ cl_assert_equal_sz(out.count, 2);
+ cl_assert_equal_s("bar", out.strings[0]);
+ cl_assert_equal_s("baz", out.strings[1]);
+
+ git_strarray_dispose(&out);
+}
diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c
index 0985c8cd5..8cd4371f5 100644
--- a/tests/remote/httpproxy.c
+++ b/tests/remote/httpproxy.c
@@ -1,6 +1,7 @@
#include "clar_libgit2.h"
-#include "remote.h"
+#include "futils.h"
#include "net.h"
+#include "remote.h"
static git_repository *repo;
static git_net_url url = GIT_NET_URL_INIT;
@@ -105,6 +106,45 @@ void test_remote_httpproxy__config_empty_overrides(void)
assert_config_match("remote.lg2.proxy", "");
}
+void assert_global_config_match(const char *config, const char *expected)
+{
+ git_remote *remote;
+ char *proxy;
+ git_config* cfg;
+
+ if (config) {
+ cl_git_pass(git_config_open_default(&cfg));
+ git_config_set_string(cfg, config, expected);
+ git_config_free(cfg);
+ }
+
+ cl_git_pass(git_remote_create_detached(&remote, "https://github.com/libgit2/libgit2"));
+ cl_git_pass(git_remote__http_proxy(&proxy, remote, &url));
+
+ if (expected)
+ cl_assert_equal_s(proxy, expected);
+ else
+ cl_assert_equal_p(proxy, expected);
+
+ git_remote_free(remote);
+ git__free(proxy);
+}
+
+void test_remote_httpproxy__config_overrides_detached_remote(void)
+{
+ cl_fake_home();
+
+ assert_global_config_match(NULL, NULL);
+ assert_global_config_match("http.proxy", "http://localhost:1/");
+ assert_global_config_match("http.https://github.com.proxy", "http://localhost:2/");
+ assert_global_config_match("http.https://github.com/.proxy", "http://localhost:3/");
+ assert_global_config_match("http.https://github.com/libgit2.proxy", "http://localhost:4/");
+ assert_global_config_match("http.https://github.com/libgit2/.proxy", "http://localhost:5/");
+ assert_global_config_match("http.https://github.com/libgit2/libgit2.proxy", "http://localhost:6/");
+
+ cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
+}
+
void test_remote_httpproxy__env(void)
{
orig_http_proxy = cl_getenv("HTTP_PROXY");
diff --git a/tests/repo/extensions.c b/tests/repo/extensions.c
new file mode 100644
index 000000000..e7772acd5
--- /dev/null
+++ b/tests/repo/extensions.c
@@ -0,0 +1,72 @@
+#include "clar_libgit2.h"
+#include "futils.h"
+#include "sysdir.h"
+#include <ctype.h>
+
+git_repository *repo;
+
+void test_repo_extensions__initialize(void)
+{
+ git_config *config;
+
+ repo = cl_git_sandbox_init("empty_bare.git");
+
+ cl_git_pass(git_repository_config(&config, repo));
+ cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
+ git_config_free(config);
+}
+
+void test_repo_extensions__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, NULL, 0));
+}
+
+void test_repo_extensions__builtin(void)
+{
+ git_repository *extended;
+
+ cl_repo_set_string(repo, "extensions.noop", "foobar");
+
+ cl_git_pass(git_repository_open(&extended, "empty_bare.git"));
+ cl_assert(git_repository_path(extended) != NULL);
+ cl_assert(git__suffixcmp(git_repository_path(extended), "/") == 0);
+ git_repository_free(extended);
+}
+
+void test_repo_extensions__negate_builtin(void)
+{
+ const char *in[] = { "foo", "!noop", "baz" };
+ git_repository *extended;
+
+ cl_repo_set_string(repo, "extensions.noop", "foobar");
+
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
+
+ cl_git_fail(git_repository_open(&extended, "empty_bare.git"));
+ git_repository_free(extended);
+}
+
+void test_repo_extensions__unsupported(void)
+{
+ git_repository *extended = NULL;
+
+ cl_repo_set_string(repo, "extensions.unknown", "foobar");
+
+ cl_git_fail(git_repository_open(&extended, "empty_bare.git"));
+ git_repository_free(extended);
+}
+
+void test_repo_extensions__adds_extension(void)
+{
+ const char *in[] = { "foo", "!noop", "newextension", "baz" };
+ git_repository *extended;
+
+ cl_repo_set_string(repo, "extensions.newextension", "foobar");
+ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
+
+ cl_git_pass(git_repository_open(&extended, "empty_bare.git"));
+ cl_assert(git_repository_path(extended) != NULL);
+ cl_assert(git__suffixcmp(git_repository_path(extended), "/") == 0);
+ git_repository_free(extended);
+}
diff --git a/tests/repo/open.c b/tests/repo/open.c
index 881a23d34..bd60c12c2 100644
--- a/tests/repo/open.c
+++ b/tests/repo/open.c
@@ -42,48 +42,6 @@ void test_repo_open__format_version_1(void)
git_repository_free(repo);
}
-void test_repo_open__format_version_1_with_valid_extension(void)
-{
- git_repository *repo;
- git_config *config;
-
- repo = cl_git_sandbox_init("empty_bare.git");
-
- cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
- cl_git_pass(git_repository_config(&config, repo));
-
- cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
- cl_git_pass(git_config_set_int32(config, "extensions.noop", 1));
-
- git_config_free(config);
- git_repository_free(repo);
-
- cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
- cl_assert(git_repository_path(repo) != NULL);
- cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0);
- git_repository_free(repo);
-}
-
-void test_repo_open__format_version_1_with_invalid_extension(void)
-{
- git_repository *repo;
- git_config *config;
-
- repo = cl_git_sandbox_init("empty_bare.git");
-
- cl_git_pass(git_repository_open(&repo, "empty_bare.git"));
- cl_git_pass(git_repository_config(&config, repo));
-
- cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1));
- cl_git_pass(git_config_set_int32(config, "extensions.invalid", 1));
-
- git_config_free(config);
- git_repository_free(repo);
-
- cl_git_fail(git_repository_open(&repo, "empty_bare.git"));
- git_repository_free(repo);
-}
-
void test_repo_open__standard_empty_repo_through_gitdir(void)
{
git_repository *repo;
diff --git a/tests/resources/config/config21 b/tests/resources/config/config21
new file mode 100644
index 000000000..aa5eb4115
--- /dev/null
+++ b/tests/resources/config/config21
@@ -0,0 +1,5 @@
+[alias]
+ m = '\
+ ";" \
+ ";" \
+ '
diff --git a/tests/resources/revert-rename.git/HEAD b/tests/resources/revert-rename.git/HEAD
new file mode 100644
index 000000000..cb089cd89
--- /dev/null
+++ b/tests/resources/revert-rename.git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests/resources/revert-rename.git/config b/tests/resources/revert-rename.git/config
new file mode 100644
index 000000000..a4ef456cb
--- /dev/null
+++ b/tests/resources/revert-rename.git/config
@@ -0,0 +1,5 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = true
+ logallrefupdates = true
diff --git a/tests/resources/revert-rename.git/index b/tests/resources/revert-rename.git/index
new file mode 100644
index 000000000..232325dfb
--- /dev/null
+++ b/tests/resources/revert-rename.git/index
Binary files differ
diff --git a/tests/resources/revert-rename.git/objects/info/packs b/tests/resources/revert-rename.git/objects/info/packs
new file mode 100644
index 000000000..5d971426e
--- /dev/null
+++ b/tests/resources/revert-rename.git/objects/info/packs
@@ -0,0 +1,2 @@
+P pack-4363774fb90141e8aa7a326ace0566366114e869.pack
+
diff --git a/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idx b/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idx
new file mode 100644
index 000000000..3fb48ea94
--- /dev/null
+++ b/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idx
Binary files differ
diff --git a/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.pack b/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.pack
new file mode 100644
index 000000000..e078ec2aa
--- /dev/null
+++ b/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.pack
Binary files differ
diff --git a/tests/resources/revert-rename.git/packed-refs b/tests/resources/revert-rename.git/packed-refs
new file mode 100644
index 000000000..e062909d4
--- /dev/null
+++ b/tests/resources/revert-rename.git/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled fully-peeled sorted
+ecef6a85173b6f446873a13f7b5a7b54a85cd912 refs/heads/master
diff --git a/tests/resources/revert-rename.git/refs/heads/master b/tests/resources/revert-rename.git/refs/heads/master
new file mode 100644
index 000000000..3771102fb
--- /dev/null
+++ b/tests/resources/revert-rename.git/refs/heads/master
@@ -0,0 +1 @@
+ecef6a85173b6f446873a13f7b5a7b54a85cd912
diff --git a/tests/revert/rename.c b/tests/revert/rename.c
new file mode 100644
index 000000000..0d713c60f
--- /dev/null
+++ b/tests/revert/rename.c
@@ -0,0 +1,49 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "git2/revert.h"
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "revert-rename.git"
+
+static git_repository *repo;
+
+/* Fixture setup and teardown */
+void test_revert_rename__initialize(void)
+{
+ repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_revert_rename__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+/* Attempt a revert when there is a file rename AND change of file mode,
+ * but the file contents remain the same. Check that the file mode doesn't
+ * change following the revert.
+ */
+void test_revert_rename__automerge(void)
+{
+ git_commit *head_commit, *revert_commit;
+ git_oid revert_oid;
+ git_index *index;
+ git_reference *head_ref;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "f0f64c618e1646d2948a456ed7c4bcfad5536d68", 0, "goodmode" }};
+
+ cl_git_pass(git_repository_head(&head_ref, repo));
+ cl_git_pass(git_reference_peel((git_object **)&head_commit, head_ref, GIT_OBJECT_COMMIT));
+
+ cl_git_pass(git_oid_fromstr(&revert_oid, "7b4d7c3789b3581973c04087cb774c3c3576de2f"));
+ cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid));
+
+ cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL));
+ cl_assert(merge_test_index(index, merge_index_entries, 1));
+
+ git_commit_free(revert_commit);
+ git_commit_free(head_commit);
+ git_index_free(index);
+ git_reference_free(head_ref);
+}
diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c
index ebfcc4d0d..f8b8c4b0a 100644
--- a/tests/win32/longpath.c
+++ b/tests/win32/longpath.c
@@ -64,18 +64,17 @@ void test_win32_longpath__workdir_path_validated(void)
#endif
}
-void test_win32_longpath__status_and_add(void)
-{
#ifdef GIT_WIN32
- git_repository *repo = cl_git_sandbox_init("testrepo");
+static void assert_longpath_status_and_add(git_repository *repo, const char *wddata, const char *repodata) {
git_index *index;
+ git_blob *blob;
git_buf out = GIT_BUF_INIT;
+ const git_index_entry *entry;
unsigned int status_flags;
- cl_repo_set_bool(repo, "core.longpaths", true);
cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME));
- cl_git_rewritefile(out.ptr, "This is a long path.\r\n");
+ cl_git_rewritefile(out.ptr, wddata);
cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME));
cl_assert_equal_i(GIT_STATUS_WT_NEW, status_flags);
@@ -86,7 +85,47 @@ void test_win32_longpath__status_and_add(void)
cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME));
cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status_flags);
+ cl_assert((entry = git_index_get_bypath(index, LONG_FILENAME, 0)) != NULL);
+ cl_git_pass(git_blob_lookup(&blob, repo, &entry->id));
+ cl_assert_equal_s(repodata, git_blob_rawcontent(blob));
+
+ git_blob_free(blob);
git_index_free(index);
git_buf_dispose(&out);
+}
+#endif
+
+void test_win32_longpath__status_and_add(void)
+{
+#ifdef GIT_WIN32
+ git_repository *repo = cl_git_sandbox_init("testrepo");
+
+ cl_repo_set_bool(repo, "core.longpaths", true);
+
+ /*
+ * Doing no content filtering, we expect the data we add
+ * to be the data in the repository.
+ */
+ assert_longpath_status_and_add(repo,
+ "This is a long path.\r\n",
+ "This is a long path.\r\n");
+#endif
+}
+
+void test_win32_longpath__status_and_add_with_filter(void)
+{
+#ifdef GIT_WIN32
+ git_repository *repo = cl_git_sandbox_init("testrepo");
+
+ cl_repo_set_bool(repo, "core.longpaths", true);
+ cl_repo_set_bool(repo, "core.autocrlf", true);
+
+ /*
+ * With `core.autocrlf`, we expect the data we add to have
+ * newline conversion performed.
+ */
+ assert_longpath_status_and_add(repo,
+ "This is a long path.\r\n",
+ "This is a long path.\n");
#endif
}