diff options
83 files changed, 844 insertions, 585 deletions
diff --git a/.travis.yml b/.travis.yml index 151060fb4..f25ff7681 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,13 +9,21 @@ compiler: # Settings to try env: + global: + - secure: "YnhS+8n6B+uoyaYfaJ3Lei7cSJqHDPiKJCKFIF2c87YDfmCvAJke8QtE7IzjYDs7UFkTCM4ox+ph2bERUrxZbSCyEkHdjIZpKuMJfYWja/jgMqTMxdyOH9y8JLFbZsSXDIXDwqBlC6vVyl1fP90M35wuWcNTs6tctfVWVofEFbs=" + matrix: - OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release" - OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=ON" matrix: + fast_finish: true include: - compiler: i586-mingw32msvc-gcc env: OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON" + - compiler: gcc + env: COVERITY=1 + allow_failures: + - env: COVERITY=1 install: - sudo apt-get -qq update diff --git a/CMakeLists.txt b/CMakeLists.txt index 48cbccb4e..f1c81eb6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,7 +136,7 @@ ELSE () LINK_LIBRARIES(${HTTP_PARSER_LIBRARIES}) SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} -lhttp_parser") ELSE() - MESSAGE("http-parser was not found or is too old; using bundled 3rd-party sources.") + MESSAGE(STATUS "http-parser was not found or is too old; using bundled 3rd-party sources.") INCLUDE_DIRECTORIES(deps/http-parser) FILE(GLOB SRC_HTTP deps/http-parser/*.c deps/http-parser/*.h) ENDIF() @@ -177,9 +177,9 @@ IF (ZLIB_FOUND) SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} zlib") ENDIF() # Fake the message CMake would have shown - MESSAGE("-- Found zlib: ${ZLIB_LIBRARY}") + MESSAGE(STATUS "Found zlib: ${ZLIB_LIBRARY}") ELSE() - MESSAGE( "zlib was not found; using bundled 3rd-party sources." ) + MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." ) INCLUDE_DIRECTORIES(deps/zlib) ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP) FILE(GLOB SRC_ZLIB deps/zlib/*.c deps/zlib/*.h) @@ -2,6 +2,7 @@ libgit2 - the Git linkable library ================================== [](http://travis-ci.org/libgit2/libgit2) +[](https://scan.coverity.com/projects/639) `libgit2` is a portable, pure C implementation of the Git core methods provided as a re-entrant linkable library with a solid API, allowing you to write native @@ -164,6 +165,8 @@ Here are the bindings to libgit2 that are currently available: * libgit2-glib <https://live.gnome.org/Libgit2-glib> * Haskell * hgit2 <https://github.com/fpco/gitlib> +* Java + * Jagged <https://github.com/ethomson/jagged> * Lua * luagit2 <https://github.com/libgit2/luagit2> * .NET @@ -181,6 +184,8 @@ Here are the bindings to libgit2 that are currently available: * Git-Raw <https://github.com/ghedo/p5-Git-Raw> * PHP * php-git <https://github.com/libgit2/php-git> +* PowerShell + * GitPowerShell <https://github.com/ethomson/gitpowershell> * Python * pygit2 <https://github.com/libgit2/pygit2> * Ruby diff --git a/include/git2/blob.h b/include/git2/blob.h index 19ad4d949..6ba5e9f9c 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -84,7 +84,7 @@ GIT_EXTERN(git_repository *) git_blob_owner(const git_blob *blob); * time. * * @param blob pointer to the blob - * @return the pointer; NULL if the blob has no contents + * @return the pointer */ GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob); diff --git a/include/git2/refs.h b/include/git2/refs.h index 1df42fead..b203f242b 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -27,7 +27,7 @@ GIT_BEGIN_DECL * The returned reference must be freed by the user. * * The name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. + * See `git_reference_symbolic_create()` for rules about valid names. * * @param out pointer to the looked-up reference * @param repo the repository to look up the reference @@ -89,37 +89,9 @@ GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, co * This function will return an error if a reference already exists with the * given name unless `force` is true, in which case it will be overwritten. * - * @param out Pointer to the newly created reference - * @param repo Repository where that reference will live - * @param name The name of the reference - * @param target The target of the reference - * @param force Overwrite existing references - * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force); - -/** - * Create a new symbolic reference and update the reflog with a given - * message. - * - * A symbolic reference is a reference name that refers to another - * reference name. If the other name moves, the symbolic name will move, - * too. As a simple example, the "HEAD" reference might refer to - * "refs/heads/master" while on the "master" branch of a repository. - * - * The symbolic reference will be created in the repository and written to - * the disk. The generated reference object must be freed by the user. - * - * Valid reference names must follow one of two patterns: - * - * 1. Top-level names must contain only capital letters and underscores, - * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - * 2. Names prefixed with "refs/" can be almost anything. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * This function will return an error if a reference already exists with the - * given name unless `force` is true, in which case it will be overwritten. + * The signature and message for the reflog will be ignored if the + * reference does not belong in the standard set (HEAD, branches and + * remote-tracking branches) and it does not have a reflog. * * @param out Pointer to the newly created reference * @param repo Repository where that reference will live @@ -127,18 +99,10 @@ GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repositor * @param target The target of the reference * @param force Overwrite existing references * @param signature The identity that will used to populate the reflog entry - * @param log_message The one line long message that has to be appended - * to the reflog - * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code + * @param log_message The one line long message to be appended to the reflog + * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reference_symbolic_create_with_log( - git_reference **out, - git_repository *repo, - const char *name, - const char *target, - int force, - const git_signature *signature, - const char *log_message); +GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force, const git_signature *signature, const char *log_message); /** * Create a new direct reference. @@ -163,57 +127,21 @@ GIT_EXTERN(int) git_reference_symbolic_create_with_log( * This function will return an error if a reference already exists with the * given name unless `force` is true, in which case it will be overwritten. * - * @param out Pointer to the newly created reference - * @param repo Repository where that reference will live - * @param name The name of the reference - * @param id The object id pointed to by the reference. - * @param force Overwrite existing references - * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force); - -/** - * Create a new direct reference and update the reflog with a given - * message. - * - * A direct reference (also called an object id reference) refers directly - * to a specific object id (a.k.a. OID or SHA) in the repository. The id - * permanently refers to the object (although the reference itself can be - * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0" - * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977. - * - * The direct reference will be created in the repository and written to - * the disk. The generated reference object must be freed by the user. - * - * Valid reference names must follow one of two patterns: - * - * 1. Top-level names must contain only capital letters and underscores, - * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - * 2. Names prefixed with "refs/" can be almost anything. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * This function will return an error if a reference already exists with the - * given name unless `force` is true, in which case it will be overwritten. + * The signature and message for the reflog will be ignored if the + * reference does not belong in the standard set (HEAD, branches and + * remote-tracking branches) and and it does not have a reflog. * * @param out Pointer to the newly created reference * @param repo Repository where that reference will live * @param name The name of the reference * @param id The object id pointed to by the reference. * @param force Overwrite existing references + * @param force Overwrite existing references * @param signature The identity that will used to populate the reflog entry - * @param log_message The one line long message that has to be appended - * to the reflog - * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code + * @param log_message The one line long message to be appended to the reflog + * @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reference_create_with_log( - git_reference **out, - git_repository *repo, - const char *name, - const git_oid *id, - int force, - const git_signature *signature, - const char *log_message); +GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_signature *signature, const char *log_message); /** * Get the OID pointed to by a direct reference. @@ -264,7 +192,7 @@ GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref); /** * Get the full name of a reference. * - * See `git_reference_create_symbolic()` for rules about valid names. + * See `git_reference_symbolic_create()` for rules about valid names. * * @param ref The reference * @return the full name for the ref @@ -305,37 +233,20 @@ GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref); * The new reference will be written to disk, overwriting the given reference. * * The target name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param out Pointer to the newly created reference - * @param ref The reference - * @param target The new target for the reference - * @return 0 on success, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reference_symbolic_set_target( - git_reference **out, - git_reference *ref, - const char *target); - -/** - * Create a new reference with the same name as the given reference but a - * different symbolic target and update the reflog with a given message. - * - * The reference must be a symbolic reference, otherwise this will fail. - * - * The new reference will be written to disk, overwriting the given reference. + * See `git_reference_symbolic_create()` for rules about valid names. * - * The target name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. + * The signature and message for the reflog will be ignored if the + * reference does not belong in the standard set (HEAD, branches and + * remote-tracking branches) and and it does not have a reflog. * * @param out Pointer to the newly created reference * @param ref The reference * @param target The new target for the reference * @param signature The identity that will used to populate the reflog entry - * @param log_message The one line long message that has to be appended - * @return 0 on success, EINVALIDSPEC or an error code + * @param log_message The one line long message to be appended to the reflog + * @return 0 on success, GIT_EINVALIDSPEC or an error code */ -GIT_EXTERN(int) git_reference_symbolic_set_target_with_log( +GIT_EXTERN(int) git_reference_symbolic_set_target( git_reference **out, git_reference *ref, const char *target, @@ -349,33 +260,18 @@ GIT_EXTERN(int) git_reference_symbolic_set_target_with_log( * * The new reference will be written to disk, overwriting the given reference. * - * @param out Pointer to the newly created reference - * @param ref The reference - * @param id The new target OID for the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_set_target( - git_reference **out, - git_reference *ref, - const git_oid *id); - -/** - * Create a new reference with the same name as the given reference but a - * different OID target and update the reflog with a given message. - * - * The reference must be a direct reference, otherwise this will fail. - * - * The new reference will be written to disk, overwriting the given reference. + * The signature and message for the reflog will be ignored if the + * reference does not belong in the standard set (HEAD, branches and + * remote-tracking branches) and and it does not have a reflog. * * @param out Pointer to the newly created reference * @param ref The reference * @param id The new target OID for the reference * @param signature The identity that will used to populate the reflog entry - * @param log_message The one line long message that has to be appended - * to the reflog + * @param log_message The one line long message to be appended to the reflog * @return 0 or an error code */ -GIT_EXTERN(int) git_reference_set_target_with_log( +GIT_EXTERN(int) git_reference_set_target( git_reference **out, git_reference *ref, const git_oid *id, @@ -388,7 +284,7 @@ GIT_EXTERN(int) git_reference_set_target_with_log( * This method works for both direct and symbolic references. * * The new name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. + * See `git_reference_symbolic_create()` for rules about valid names. * * If the `force` flag is not enabled, and there's already * a reference with the given name, the renaming will fail. @@ -648,7 +544,7 @@ typedef enum { * Once normalized, if the reference name is valid, it will be returned in * the user allocated buffer. * - * See `git_reference_create_symbolic()` for rules about valid names. + * See `git_reference_symbolic_create()` for rules about valid names. * * @param buffer_out User allocated buffer to store normalized name * @param buffer_size Size of buffer_out diff --git a/include/git2/remote.h b/include/git2/remote.h index 7410909dc..d3e6caa48 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -108,6 +108,18 @@ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const ch GIT_EXTERN(int) git_remote_save(const git_remote *remote); /** + * Create a copy of an existing remote. All internal strings are also + * duplicated. Callbacks are not duplicated. + * + * Call `git_remote_free` to free the data. + * + * @param dest pointer where to store the copy + * @param source object to copy + * @return 0 or an error code + */ +GIT_EXTERN(int) git_remote_dup(git_remote **dest, const git_remote *source); + +/** * Get the remote's repository * * @param remote the remote diff --git a/include/git2/signature.h b/include/git2/signature.h index 2fa46d032..a1dd1ec7a 100644 --- a/include/git2/signature.h +++ b/include/git2/signature.h @@ -68,10 +68,11 @@ GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo) * * Call `git_signature_free()` to free the data. * - * @param sig signature to duplicated - * @return a copy of sig, NULL on out of memory + * @param dest pointer where to store the copy + * @param entry signature to duplicate + * @return 0 or an error code */ -GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig); +GIT_EXTERN(int) git_signature_dup(git_signature **dest, const git_signature *sig); /** * Free an existing signature. diff --git a/include/git2/submodule.h b/include/git2/submodule.h index a1507593c..907e5a15f 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -284,6 +284,14 @@ GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule); GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule); /** +* Get the branch for the submodule. +* +* @param submodule Pointer to submodule object +* @return Pointer to the submodule branch +*/ +GIT_EXTERN(const char *) git_submodule_branch(git_submodule *submodule); + +/** * Set the URL for the submodule. * * This sets the URL in memory for the submodule. This will be used for @@ -437,7 +445,7 @@ GIT_EXTERN(git_submodule_recurse_t) git_submodule_fetch_recurse_submodules( * @param fetch_recurse_submodules Boolean value * @return old value for fetchRecurseSubmodules */ -GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules( +GIT_EXTERN(git_submodule_recurse_t) git_submodule_set_fetch_recurse_submodules( git_submodule *submodule, git_submodule_recurse_t fetch_recurse_submodules); diff --git a/include/git2/tree.h b/include/git2/tree.h index 422365674..6350ada9b 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -150,10 +150,11 @@ GIT_EXTERN(int) git_tree_entry_bypath( * Create a copy of a tree entry. The returned copy is owned by the user, * and must be freed explicitly with `git_tree_entry_free()`. * - * @param entry A tree entry to duplicate - * @return a copy of the original entry or NULL on error (alloc failure) + * @param dest pointer where to store the copy + * @param entry tree entry to duplicate + * @return 0 or an error code */ -GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry); +GIT_EXTERN(int) git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source); /** * Free a user-owned tree entry diff --git a/include/git2/types.h b/include/git2/types.h index 55505b110..d88815d80 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -131,7 +131,7 @@ typedef struct git_treebuilder git_treebuilder; /** Memory representation of an index file. */ typedef struct git_index git_index; -/** An interator for conflicts in the index. */ +/** An iterator for conflicts in the index. */ typedef struct git_index_conflict_iterator git_index_conflict_iterator; /** Memory representation of a set of config files */ diff --git a/script/cibuild.sh b/script/cibuild.sh index aa4fa47aa..5c0584a80 100755 --- a/script/cibuild.sh +++ b/script/cibuild.sh @@ -1,5 +1,11 @@ #!/bin/sh +if [ "$COVERITY" -eq 1 ]; +then + ./script/coverity.sh; + exit $?; +fi + # Create a test repo which we can use for the online::push tests mkdir $HOME/_temp git init --bare $HOME/_temp/test.git diff --git a/script/coverity.sh b/script/coverity.sh new file mode 100755 index 000000000..e72008883 --- /dev/null +++ b/script/coverity.sh @@ -0,0 +1,57 @@ +#!/bin/bash +set -e + +# Environment check +[ -z "$COVERITY_TOKEN" ] && echo "Need to set a coverity token" && exit 1 + +# Only run this on our branches +echo "Pull request: $TRAVIS_PULL_REQUEST | Slug: $TRAVIS_REPO_SLUG" +if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_REPO_SLUG" != "libgit2/libgit2" ]; +then + echo "Only analyzing 'development' on the main repo." + exit 0 +fi + +COV_VERSION=6.6.1 +case `uname -m` in + i?86) BITS=32 ;; + amd64|x86_64) BITS=64 ;; +esac +SCAN_TOOL=https://scan.coverity.com/download/linux-${BITS} +TOOL_BASE=`pwd`/_coverity-scan + +# Install coverity tools +if [ ! -d $TOOL_BASE ]; then + echo "Downloading coverity..." + mkdir -p $TOOL_BASE + cd $TOOL_BASE + wget -O coverity_tool.tgz $SCAN_TOOL \ + --post-data "project=libgit2&token=$COVERITY_TOKEN" + tar xzf coverity_tool.tgz + cd .. + TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'` + ln -s $TOOL_DIR $TOOL_BASE/cov-analysis +fi + +COV_BUILD="$TOOL_BASE/cov-analysis/bin/cov-build" + +# Configure and build +rm -rf _build +mkdir _build +cd _build +cmake .. -DTHREADSAFE=ON +COVERITY_UNSUPPORTED=1 \ + $COV_BUILD --dir cov-int \ + cmake --build . + +# Upload results +tar czf libgit2.tgz cov-int +SHA=`git rev-parse --short HEAD` +curl \ + --form project=libgit2 \ + --form token=$COVERITY_TOKEN \ + --form email=bs@github.com \ + --form file=@libgit2.tgz \ + --form version=$SHA \ + --form description="Travis build" \ + http://scan5.coverity.com/cgi-bin/upload.py diff --git a/src/blame.c b/src/blame.c index a1357415a..0f2d906d2 100644 --- a/src/blame.c +++ b/src/blame.c @@ -76,8 +76,8 @@ static git_blame_hunk* dup_hunk(git_blame_hunk *hunk) git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id); git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id); newhunk->boundary = hunk->boundary; - newhunk->final_signature = git_signature_dup(hunk->final_signature); - newhunk->orig_signature = git_signature_dup(hunk->orig_signature); + git_signature_dup(&newhunk->final_signature, hunk->final_signature); + git_signature_dup(&newhunk->orig_signature, hunk->orig_signature); return newhunk; } @@ -121,7 +121,6 @@ git_blame* git_blame__alloc( git_vector_insert(&gbr->paths, git__strdup(path)) < 0) { git_blame_free(gbr); - git__free(gbr); return NULL; } @@ -242,7 +241,7 @@ static int index_blob_lines(git_blame *blame) git_off_t len = blame->final_buf_size; int num = 0, incomplete = 0, bol = 1; size_t *i; - + if (len && buf[len-1] != '\n') incomplete++; /* incomplete line at the end */ while (len--) { @@ -263,13 +262,15 @@ static int index_blob_lines(git_blame *blame) blame->num_lines = num + incomplete; return blame->num_lines; } - + static git_blame_hunk* hunk_from_entry(git_blame__entry *e) { git_blame_hunk *h = new_hunk( e->lno+1, e->num_lines, e->s_lno+1, e->suspect->path); git_oid_cpy(&h->final_commit_id, git_commit_id(e->suspect->commit)); - h->final_signature = git_signature_dup(git_commit_author(e->suspect->commit)); + git_oid_cpy(&h->orig_commit_id, git_commit_id(e->suspect->commit)); + git_signature_dup(&h->final_signature, git_commit_author(e->suspect->commit)); + git_signature_dup(&h->orig_signature, git_commit_author(e->suspect->commit)); h->boundary = e->is_boundary ? 1 : 0; return h; } diff --git a/src/blob.c b/src/blob.c index ab344ae98..2e924f37f 100644 --- a/src/blob.c +++ b/src/blob.c @@ -347,6 +347,8 @@ int git_blob_filtered_content( assert(blob && path && out); + git_buf_sanitize(out); + if (check_for_binary_data && git_blob_is_binary(blob)) return 0; diff --git a/src/branch.c b/src/branch.c index ef71c2cd1..3b9aa0d20 100644 --- a/src/branch.c +++ b/src/branch.c @@ -72,7 +72,7 @@ int git_branch_create( goto cleanup; error = git_reference_create(&branch, repository, - git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force); + git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force, NULL, NULL); if (!error) *ref_out = branch; @@ -181,6 +181,9 @@ void git_branch_iterator_free(git_branch_iterator *_iter) { branch_iter *iter = (branch_iter *) _iter; + if (iter == NULL) + return; + git_reference_iterator_free(iter->iter); git__free(iter); } diff --git a/src/buffer.c b/src/buffer.c index 20682322e..3283c2d4f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -100,6 +100,14 @@ void git_buf_free(git_buf *buf) git_buf_init(buf, 0); } +void git_buf_sanitize(git_buf *buf) +{ + if (buf->ptr == NULL) { + assert (buf->size == 0 && buf->asize == 0); + buf->ptr = git_buf__initbuf; + } +} + void git_buf_clear(git_buf *buf) { buf->size = 0; diff --git a/src/buffer.h b/src/buffer.h index c88af6fef..564a4f561 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -51,6 +51,15 @@ extern void git_buf_init(git_buf *buf, size_t initial_size); extern int git_buf_try_grow( git_buf *buf, size_t target_size, bool mark_oom, bool preserve_external); +/** + * Sanitizes git_buf structures provided from user input. Users of the + * library, when providing git_buf's, may wish to provide a NULL ptr for + * ease of handling. The buffer routines, however, expect a non-NULL ptr + * always. This helper method simply handles NULL input, converting to a + * git_buf__initbuf. + */ +extern void git_buf_sanitize(git_buf *buf); + extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b); extern char *git_buf_detach(git_buf *buf); extern void git_buf_attach(git_buf *buf, char *ptr, size_t asize); diff --git a/src/commit.c b/src/commit.c index 4ddfafb41..f0e304a84 100644 --- a/src/commit.c +++ b/src/commit.c @@ -112,7 +112,7 @@ int git_commit_create_from_oids( git_buf_free(&commit); if (update_ref != NULL) - return git_reference__update_terminal(repo, update_ref, oid); + return git_reference__update_terminal(repo, update_ref, oid, NULL, NULL); return 0; diff --git a/src/compress.c b/src/compress.c deleted file mode 100644 index 14b79404c..000000000 --- a/src/compress.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#include "compress.h" - -#include <zlib.h> - -#define BUFFER_SIZE (1024 * 1024) - -int git__compress(git_buf *buf, const void *buff, size_t len) -{ - z_stream zs; - char *zb; - size_t have; - - memset(&zs, 0, sizeof(zs)); - if (deflateInit(&zs, Z_DEFAULT_COMPRESSION) != Z_OK) - return -1; - - zb = git__malloc(BUFFER_SIZE); - GITERR_CHECK_ALLOC(zb); - - zs.next_in = (void *)buff; - zs.avail_in = (uInt)len; - - do { - zs.next_out = (unsigned char *)zb; - zs.avail_out = BUFFER_SIZE; - - if (deflate(&zs, Z_FINISH) == Z_STREAM_ERROR) { - git__free(zb); - return -1; - } - - have = BUFFER_SIZE - (size_t)zs.avail_out; - - if (git_buf_put(buf, zb, have) < 0) { - git__free(zb); - return -1; - } - - } while (zs.avail_out == 0); - - assert(zs.avail_in == 0); - - deflateEnd(&zs); - git__free(zb); - return 0; -} diff --git a/src/compress.h b/src/compress.h deleted file mode 100644 index 49e6f4749..000000000 --- a/src/compress.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_compress_h__ -#define INCLUDE_compress_h__ - -#include "common.h" - -#include "buffer.h" - -int git__compress(git_buf *buf, const void *buff, size_t len); - -#endif /* INCLUDE_compress_h__ */ diff --git a/src/config.c b/src/config.c index 6dcaba5fd..fa1dd8182 100644 --- a/src/config.c +++ b/src/config.c @@ -458,6 +458,7 @@ int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cf if ((result = regcomp(&iter->regex, regexp, REG_EXTENDED)) < 0) { giterr_set_regex(&iter->regex, result); regfree(&iter->regex); + git__free(iter); return -1; } @@ -928,6 +929,9 @@ int git_config_next(git_config_entry **entry, git_config_iterator *iter) void git_config_iterator_free(git_config_iterator *iter) { + if (iter == NULL) + return; + iter->free(iter); } diff --git a/src/config_file.c b/src/config_file.c index 0971aa7b0..c7727c029 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -213,7 +213,7 @@ static int config_refresh(git_config_backend *cfg) int res = 0, updated = 0, any_updated = 0; diskfile_backend *b = (diskfile_backend *)cfg; git_strmap *old_values; - struct reader *reader; + struct reader *reader = NULL; uint32_t i; for (i = 0; i < git_array_size(b->readers); i++) { @@ -1072,8 +1072,10 @@ static int config_parse(diskfile_backend *cfg_file, struct reader *reader, git_c git_buf_printf(&buf, "%s.%s", current_section, var_name); git__free(var_name); - if (git_buf_oom(&buf)) + if (git_buf_oom(&buf)) { + git__free(var_value); return -1; + } var->entry->name = git_buf_detach(&buf); var->entry->value = var_value; diff --git a/src/indexer.c b/src/indexer.c index 6132571cc..9b60ef413 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -5,8 +5,6 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include <zlib.h> - #include "git2/indexer.h" #include "git2/object.h" @@ -18,7 +16,7 @@ #include "filebuf.h" #include "oid.h" #include "oidmap.h" -#include "compress.h" +#include "zstream.h" #define UINT31_MAX (0x7FFFFFFF) @@ -355,7 +353,7 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, git_off_t entry_star git_oid oid; size_t entry_size; struct entry *entry; - struct git_pack_entry *pentry; + struct git_pack_entry *pentry = NULL; entry = git__calloc(1, sizeof(*entry)); GITERR_CHECK_ALLOC(entry); @@ -379,6 +377,7 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, git_off_t entry_star return save_entry(idx, entry, pentry, entry_start); on_error: + git__free(pentry); git__free(entry); git__free(obj->data); return -1; @@ -634,7 +633,7 @@ static int inject_object(git_indexer *idx, git_oid *id) { git_odb_object *obj; struct entry *entry; - struct git_pack_entry *pentry; + struct git_pack_entry *pentry = NULL; git_oid foo = {{0}}; unsigned char hdr[64]; git_buf buf = GIT_BUF_INIT; @@ -643,9 +642,6 @@ static int inject_object(git_indexer *idx, git_oid *id) size_t len, hdr_len; int error; - entry = git__calloc(1, sizeof(*entry)); - GITERR_CHECK_ALLOC(entry); - entry_start = seek_back_trailer(idx); if (git_odb_read(&obj, idx->odb, id) < 0) @@ -654,6 +650,9 @@ static int inject_object(git_indexer *idx, git_oid *id) data = git_odb_object_data(obj); len = git_odb_object_size(obj); + entry = git__calloc(1, sizeof(*entry)); + GITERR_CHECK_ALLOC(entry); + entry->crc = crc32(0L, Z_NULL, 0); /* Write out the object header */ @@ -662,7 +661,7 @@ static int inject_object(git_indexer *idx, git_oid *id) idx->pack->mwf.size += hdr_len; entry->crc = crc32(entry->crc, hdr, hdr_len); - if ((error = git__compress(&buf, data, len)) < 0) + if ((error = git_zstream_deflatebuf(&buf, data, len)) < 0) goto cleanup; /* And then the compressed object */ @@ -684,10 +683,14 @@ static int inject_object(git_indexer *idx, git_oid *id) git_oid_cpy(&entry->oid, id); idx->off = entry_start + hdr_len + len; - if ((error = save_entry(idx, entry, pentry, entry_start)) < 0) - git__free(pentry); + error = save_entry(idx, entry, pentry, entry_start); cleanup: + if (error) { + git__free(entry); + git__free(pentry); + } + git_odb_object_free(obj); return error; } @@ -949,6 +949,9 @@ int git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len) void git_odb_stream_free(git_odb_stream *stream) { + if (stream == NULL) + return; + git__free(stream->hash_ctx); stream->free(stream); } @@ -314,6 +314,9 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length) void git_oid_shorten_free(git_oid_shorten *os) { + if (os == NULL) + return; + git__free(os->nodes); git__free(os); } diff --git a/src/pack-objects.c b/src/pack-objects.c index 335944c0c..c4ed4dce3 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -7,7 +7,7 @@ #include "pack-objects.h" -#include "compress.h" +#include "zstream.h" #include "delta.h" #include "iterator.h" #include "netops.h" @@ -61,6 +61,9 @@ struct pack_write_context { /* The minimal interval between progress updates (in seconds). */ #define MIN_PROGRESS_UPDATE_INTERVAL 0.5 +/* Size of the buffer to feed to zlib */ +#define COMPRESS_BUFLEN (1024 * 1024) + static unsigned name_hash(const char *name) { unsigned c, hash = 0; @@ -127,6 +130,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) pb->nr_threads = 1; /* do not spawn any thread by default */ if (git_hash_ctx_init(&pb->ctx) < 0 || + git_zstream_init(&pb->zstream) < 0 || git_repository_odb(&pb->odb, repo) < 0 || packbuilder_config(pb) < 0) goto on_error; @@ -275,78 +279,92 @@ on_error: return -1; } -static int write_object(git_buf *buf, git_packbuilder *pb, git_pobject *po) +static int write_object( + git_packbuilder *pb, + git_pobject *po, + int (*write_cb)(void *buf, size_t size, void *cb_data), + void *cb_data) { git_odb_object *obj = NULL; - git_buf zbuf = GIT_BUF_INIT; git_otype type; - unsigned char hdr[10]; - size_t hdr_len; - unsigned long size; + unsigned char hdr[10], *zbuf = NULL; void *data; + size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len; + ssize_t written; + int error; if (po->delta) { if (po->delta_data) data = po->delta_data; - else if (get_delta(&data, pb->odb, po) < 0) - goto on_error; - size = po->delta_size; + else if ((error = get_delta(&data, pb->odb, po)) < 0) + goto done; + + data_len = po->delta_size; type = GIT_OBJ_REF_DELTA; } else { - if (git_odb_read(&obj, pb->odb, &po->id)) - goto on_error; + if ((error = git_odb_read(&obj, pb->odb, &po->id)) < 0) + goto done; data = (void *)git_odb_object_data(obj); - size = (unsigned long)git_odb_object_size(obj); + data_len = git_odb_object_size(obj); type = git_odb_object_type(obj); } /* Write header */ - hdr_len = git_packfile__object_header(hdr, size, type); - - if (git_buf_put(buf, (char *)hdr, hdr_len) < 0) - goto on_error; + hdr_len = git_packfile__object_header(hdr, data_len, type); - if (git_hash_update(&pb->ctx, hdr, hdr_len) < 0) - goto on_error; + if ((error = write_cb(hdr, hdr_len, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0) + goto done; if (type == GIT_OBJ_REF_DELTA) { - if (git_buf_put(buf, (char *)po->delta->id.id, GIT_OID_RAWSZ) < 0 || - git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_RAWSZ) < 0) - goto on_error; + if ((error = write_cb(po->delta->id.id, GIT_OID_RAWSZ, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_RAWSZ)) < 0) + goto done; } /* Write data */ - if (po->z_delta_size) - size = po->z_delta_size; - else if (git__compress(&zbuf, data, size) < 0) - goto on_error; - else { + if (po->z_delta_size) { + data_len = po->z_delta_size; + + if ((error = write_cb(data, data_len, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, data, data_len)) < 0) + goto done; + } else { + zbuf = git__malloc(zbuf_len); + GITERR_CHECK_ALLOC(zbuf); + + git_zstream_reset(&pb->zstream); + + while ((written = git_zstream_deflate(zbuf, zbuf_len, &pb->zstream, data, data_len)) > 0) { + if ((error = write_cb(zbuf, written, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, zbuf, written)) < 0) + goto done; + + data = (char *)data + written; + data_len -= written; + } + + if (written < 0) { + error = written; + goto done; + } + if (po->delta) git__free(data); - data = zbuf.ptr; - size = (unsigned long)zbuf.size; } - if (git_buf_put(buf, data, size) < 0 || - git_hash_update(&pb->ctx, data, size) < 0) - goto on_error; - if (po->delta_data) { git__free(po->delta_data); po->delta_data = NULL; } - git_odb_object_free(obj); - git_buf_free(&zbuf); - pb->nr_written++; - return 0; -on_error: +done: + git__free(zbuf); git_odb_object_free(obj); - git_buf_free(&zbuf); - return -1; + return error; } enum write_one_status { @@ -356,9 +374,15 @@ enum write_one_status { WRITE_ONE_RECURSIVE = 2 /* already scheduled to be written */ }; -static int write_one(git_buf *buf, git_packbuilder *pb, git_pobject *po, - enum write_one_status *status) +static int write_one( + enum write_one_status *status, + git_packbuilder *pb, + git_pobject *po, + int (*write_cb)(void *buf, size_t size, void *cb_data), + void *cb_data) { + int error; + if (po->recursing) { *status = WRITE_ONE_RECURSIVE; return 0; @@ -369,21 +393,19 @@ static int write_one(git_buf *buf, git_packbuilder *pb, git_pobject *po, if (po->delta) { po->recursing = 1; - if (write_one(buf, pb, po->delta, status) < 0) - return -1; - switch (*status) { - case WRITE_ONE_RECURSIVE: - /* we cannot depend on this one */ + + if ((error = write_one(status, pb, po->delta, write_cb, cb_data)) < 0) + return error; + + /* we cannot depend on this one */ + if (*status == WRITE_ONE_RECURSIVE) po->delta = NULL; - break; - default: - break; - } } po->written = 1; po->recursing = 0; - return write_object(buf, pb, po); + + return write_object(pb, po, write_cb, cb_data); } GIT_INLINE(void) add_to_write_order(git_pobject **wo, unsigned int *endp, @@ -563,12 +585,11 @@ static git_pobject **compute_write_order(git_packbuilder *pb) } static int write_pack(git_packbuilder *pb, - int (*cb)(void *buf, size_t size, void *data), - void *data) + int (*write_cb)(void *buf, size_t size, void *cb_data), + void *cb_data) { git_pobject **write_order; git_pobject *po; - git_buf buf = GIT_BUF_INIT; enum write_one_status status; struct git_pack_header ph; git_oid entry_oid; @@ -586,10 +607,8 @@ static int write_pack(git_packbuilder *pb, ph.hdr_version = htonl(PACK_VERSION); ph.hdr_entries = htonl(pb->nr_objects); - if ((error = cb(&ph, sizeof(ph), data)) < 0) - goto done; - - if ((error = git_hash_update(&pb->ctx, &ph, sizeof(ph))) < 0) + if ((error = write_cb(&ph, sizeof(ph), cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, &ph, sizeof(ph))) < 0) goto done; pb->nr_remaining = pb->nr_objects; @@ -597,21 +616,18 @@ static int write_pack(git_packbuilder *pb, pb->nr_written = 0; for ( ; i < pb->nr_objects; ++i) { po = write_order[i]; - if ((error = write_one(&buf, pb, po, &status)) < 0) - goto done; - if ((error = cb(buf.ptr, buf.size, data)) < 0) + + if ((error = write_one(&status, pb, po, write_cb, cb_data)) < 0) goto done; - git_buf_clear(&buf); } pb->nr_remaining -= pb->nr_written; } while (pb->nr_remaining && i < pb->nr_objects); - if ((error = git_hash_final(&entry_oid, &pb->ctx)) < 0) goto done; - error = cb(entry_oid.id, GIT_OID_RAWSZ, data); + error = write_cb(entry_oid.id, GIT_OID_RAWSZ, cb_data); done: /* if callback cancelled writing, we must still free delta_data */ @@ -624,7 +640,6 @@ done: } git__free(write_order); - git_buf_free(&buf); return error; } @@ -931,7 +946,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, * between writes at that moment. */ if (po->delta_data) { - if (git__compress(&zbuf, po->delta_data, po->delta_size) < 0) + if (git_zstream_deflatebuf(&zbuf, po->delta_data, po->delta_size) < 0) goto on_error; git__free(po->delta_data); @@ -1396,6 +1411,7 @@ void git_packbuilder_free(git_packbuilder *pb) git__free(pb->object_list); git_hash_ctx_cleanup(&pb->ctx); + git_zstream_free(&pb->zstream); git__free(pb); } diff --git a/src/pack-objects.h b/src/pack-objects.h index 0c94a5a7a..4647df75a 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -14,6 +14,7 @@ #include "hash.h" #include "oidmap.h" #include "netops.h" +#include "zstream.h" #include "git2/oid.h" #include "git2/pack.h" @@ -54,6 +55,7 @@ struct git_packbuilder { git_odb *odb; /* associated object database */ git_hash_ctx ctx; + git_zstream zstream; uint32_t nr_objects, nr_alloc, diff --git a/src/pathspec.c b/src/pathspec.c index bad8dacdb..d6ce09c02 100644 --- a/src/pathspec.c +++ b/src/pathspec.c @@ -89,8 +89,10 @@ int git_pathspec__vinit( if (ret == GIT_ENOTFOUND) { git__free(match); continue; - } else if (ret < 0) + } else if (ret < 0) { + git__free(match); return ret; + } if (git_vector_insert(vspec, match) < 0) return -1; diff --git a/src/posix.h b/src/posix.h index f529914fe..0d9be49a9 100644 --- a/src/posix.h +++ b/src/posix.h @@ -89,13 +89,17 @@ extern struct tm * p_gmtime_r (const time_t *timer, struct tm *result); # include "unix/posix.h" #endif -#if defined(__MINGW32__) || defined(__sun) +#if defined(__MINGW32__) || defined(__sun) || defined(__APPLE__) +# define NO_STRNLEN +#endif + +#ifdef NO_STRNLEN GIT_INLINE(size_t) p_strnlen(const char *s, size_t maxlen) { const char *end = memchr(s, 0, maxlen); return end ? (size_t)(end - s) : maxlen; } #else -# define p_strnlen strnlen +# define p_strnlen strnlen #endif #ifdef NO_READDIR_R diff --git a/src/push.c b/src/push.c index dd77864a5..0be82f3b2 100644 --- a/src/push.c +++ b/src/push.c @@ -241,7 +241,7 @@ int git_push_update_tips(git_push *push) giterr_clear(); else goto on_error; - } else if ((error = git_reference_create(NULL, push->remote->repo, git_buf_cstr(&remote_ref_name), &push_spec->loid, 1)) < 0) + } else if ((error = git_reference_create(NULL, push->remote->repo, git_buf_cstr(&remote_ref_name), &push_spec->loid, 1, NULL, NULL)) < 0) goto on_error; } diff --git a/src/reflog.c b/src/reflog.c index 9b2b201bf..8e41621ea 100644 --- a/src/reflog.c +++ b/src/reflog.c @@ -82,7 +82,7 @@ int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_sign entry = git__calloc(1, sizeof(git_reflog_entry)); GITERR_CHECK_ALLOC(entry); - if ((entry->committer = git_signature_dup(committer)) == NULL) + if ((git_signature_dup(&entry->committer, committer)) < 0) goto cleanup; if (msg != NULL) { diff --git a/src/refs.c b/src/refs.c index 83343f41b..0f0a380ea 100644 --- a/src/refs.c +++ b/src/refs.c @@ -393,32 +393,20 @@ static int reference__create( return 0; } -int git_reference_create( - git_reference **ref_out, - git_repository *repo, - const char *name, - const git_oid *oid, - int force) +static int log_signature(git_signature **out, git_repository *repo) { - git_signature *who; int error; + git_signature *who; - assert(oid); - - /* Should we return an error if there is no default? */ - if (((error = git_signature_default(&who, repo)) < 0) && - ((error = git_signature_now(&who, "unknown", "unknown")) < 0)) { + if(((error = git_signature_default(&who, repo)) < 0) && + ((error = git_signature_now(&who, "unknown", "unknown")) < 0)) return error; - } - - error = reference__create(ref_out, repo, name, oid, NULL, force, who, NULL); - - git_signature_free(who); - return error; + *out = who; + return 0; } -int git_reference_create_with_log( +int git_reference_create( git_reference **ref_out, git_repository *repo, const char *name, @@ -427,10 +415,23 @@ int git_reference_create_with_log( const git_signature *signature, const char *log_message) { - assert(oid && signature && log_message); + int error; + git_signature *who = NULL; + + assert(oid); + + if (!signature) { + if ((error = log_signature(&who, repo)) < 0) + return error; + else + signature = who; + } - return reference__create( + error = reference__create( ref_out, repo, name, oid, NULL, force, signature, log_message); + + git_signature_free(who); + return error; } int git_reference_symbolic_create( @@ -438,10 +439,27 @@ int git_reference_symbolic_create( git_repository *repo, const char *name, const char *target, - int force) + int force, + const git_signature *signature, + const char *log_message) { + int error; + git_signature *who = NULL; + assert(target); - return reference__create(ref_out, repo, name, NULL, target, force, NULL, NULL); + + if (!signature) { + if ((error = log_signature(&who, repo)) < 0) + return error; + else + signature = who; + } + + error = reference__create( + ref_out, repo, name, NULL, target, force, signature, log_message); + + git_signature_free(who); + return error; } static int ensure_is_an_updatable_direct_reference(git_reference *ref) @@ -456,21 +474,6 @@ static int ensure_is_an_updatable_direct_reference(git_reference *ref) int git_reference_set_target( git_reference **out, git_reference *ref, - const git_oid *id) -{ - int error; - - assert(out && ref && id); - - if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0) - return error; - - return git_reference_create(out, ref->db->repo, ref->name, id, 1); -} - -int git_reference_set_target_with_log( - git_reference **out, - git_reference *ref, const git_oid *id, const git_signature *signature, const char *log_message) @@ -478,12 +481,11 @@ int git_reference_set_target_with_log( int error; assert(out && ref && id); - assert(signature && log_message); if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0) return error; - return git_reference_create_with_log( + return git_reference_create( out, ref->db->repo, ref->name, id, 1, signature, log_message); } @@ -499,7 +501,9 @@ static int ensure_is_an_updatable_symbolic_reference(git_reference *ref) int git_reference_symbolic_set_target( git_reference **out, git_reference *ref, - const char *target) + const char *target, + const git_signature *signature, + const char *log_message) { int error; @@ -508,7 +512,8 @@ int git_reference_symbolic_set_target( if ((error = ensure_is_an_updatable_symbolic_reference(ref)) < 0) return error; - return git_reference_symbolic_create(out, ref->db->repo, ref->name, target, 1); + return git_reference_symbolic_create( + out, ref->db->repo, ref->name, target, 1, signature, log_message); } static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force, @@ -709,6 +714,9 @@ int git_reference_next_name(const char **out, git_reference_iterator *iter) void git_reference_iterator_free(git_reference_iterator *iter) { + if (iter == NULL) + return; + git_refdb_iterator_free(iter); } @@ -1002,7 +1010,9 @@ static int reference__update_terminal( git_repository *repo, const char *ref_name, const git_oid *oid, - int nesting) + int nesting, + const git_signature *signature, + const char *log_message) { git_reference *ref; int error = 0; @@ -1017,7 +1027,7 @@ static int reference__update_terminal( /* If we haven't found the reference at all, create a new reference. */ if (error == GIT_ENOTFOUND) { giterr_clear(); - return git_reference_create(NULL, repo, ref_name, oid, 0); + return git_reference_create(NULL, repo, ref_name, oid, 0, signature, log_message); } if (error < 0) @@ -1026,11 +1036,11 @@ static int reference__update_terminal( /* If the ref is a symbolic reference, follow its target. */ if (git_reference_type(ref) == GIT_REF_SYMBOLIC) { error = reference__update_terminal(repo, git_reference_symbolic_target(ref), oid, - nesting+1); + nesting+1, signature, log_message); git_reference_free(ref); } else { git_reference_free(ref); - error = git_reference_create(NULL, repo, ref_name, oid, 1); + error = git_reference_create(NULL, repo, ref_name, oid, 1, signature, log_message); } return error; @@ -1044,9 +1054,11 @@ static int reference__update_terminal( int git_reference__update_terminal( git_repository *repo, const char *ref_name, - const git_oid *oid) + const git_oid *oid, + const git_signature *signature, + const char *log_message) { - return reference__update_terminal(repo, ref_name, oid, 0); + return reference__update_terminal(repo, ref_name, oid, 0, signature, log_message); } int git_reference_has_log(git_repository *repo, const char *refname) diff --git a/src/refs.h b/src/refs.h index 4d5b6dacb..d57d67026 100644 --- a/src/refs.h +++ b/src/refs.h @@ -68,7 +68,7 @@ git_reference *git_reference__set_name(git_reference *ref, const char *name); int git_reference__normalize_name_lax(char *buffer_out, size_t out_size, const char *name); int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags); -int git_reference__update_terminal(git_repository *repo, const char *ref_name, const git_oid *oid); +int git_reference__update_terminal(git_repository *repo, const char *ref_name, const git_oid *oid, const git_signature *signature, const char *log_message); int git_reference__is_valid_name(const char *refname, unsigned int flags); int git_reference__is_branch(const char *ref_name); int git_reference__is_remote(const char *ref_name); diff --git a/src/remote.c b/src/remote.c index 294a8709d..306cb0b9a 100644 --- a/src/remote.c +++ b/src/remote.c @@ -248,6 +248,44 @@ int git_remote_create_inmemory(git_remote **out, git_repository *repo, const cha return 0; } +int git_remote_dup(git_remote **dest, const git_remote *source) +{ + int error; + git_remote *remote = git__calloc(1, sizeof(git_remote)); + GITERR_CHECK_ALLOC(remote); + + if (source->name != NULL) { + remote->name = git__strdup(source->name); + GITERR_CHECK_ALLOC(remote->name); + } + + if (source->url != NULL) { + remote->url = git__strdup(source->url); + GITERR_CHECK_ALLOC(remote->url); + } + + if (source->pushurl != NULL) { + remote->pushurl = git__strdup(source->pushurl); + GITERR_CHECK_ALLOC(remote->pushurl); + } + + remote->repo = source->repo; + remote->download_tags = source->download_tags; + remote->check_cert = source->check_cert; + remote->update_fetchhead = source->update_fetchhead; + + if ((error = git_vector_dup(&remote->refs, &source->refs, NULL)) < 0 || + (error = git_vector_dup(&remote->refspecs, &source->refspecs, NULL)) < 0 || + (error = git_vector_dup(&remote->active_refspecs, &source->active_refspecs, NULL))) { + git__free(remote); + return error; + } + + *dest = remote; + + return 0; +} + struct refspec_cb_data { git_remote *remote; int fetch; @@ -989,7 +1027,7 @@ static int update_tips_for_spec(git_remote *remote, git_refspec *spec, git_vecto continue; /* In autotag mode, don't overwrite any locally-existing tags */ - error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag); + error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag, NULL, NULL); if (error < 0 && error != GIT_EEXISTS) goto on_error; diff --git a/src/repository.c b/src/repository.c index 94f6603aa..8645357b8 100644 --- a/src/repository.c +++ b/src/repository.c @@ -289,16 +289,20 @@ static int read_gitfile(git_buf *path_out, const char *file_path) return -1; git_buf_rtrim(&file); + /* apparently on Windows, some people use backslashes in paths */ + git_path_mkposix(file.ptr); if (git_buf_len(&file) <= prefix_len || memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0) { - giterr_set(GITERR_REPOSITORY, "The `.git` file at '%s' is malformed", file_path); + giterr_set(GITERR_REPOSITORY, + "The `.git` file at '%s' is malformed", file_path); error = -1; } else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) { const char *gitlink = git_buf_cstr(&file) + prefix_len; while (*gitlink && git__isspace(*gitlink)) gitlink++; + error = git_path_prettify_dir( path_out, gitlink, git_buf_cstr(path_out)); } @@ -1863,11 +1867,11 @@ int git_repository_set_head( if (!error) { if (git_reference_is_branch(ref)) - error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1); + error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1, NULL, NULL); else error = git_repository_set_head_detached(repo, git_reference_target(ref)); } else if (looks_like_a_branch(refname)) - error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, 1); + error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, 1, NULL, NULL); git_reference_free(ref); git_reference_free(new_head); @@ -1891,7 +1895,7 @@ int git_repository_set_head_detached( if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0) goto cleanup; - error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1); + error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1, NULL, NULL); cleanup: git_object_free(object); @@ -1916,7 +1920,7 @@ int git_repository_detach_head( if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJ_COMMIT)) < 0) goto cleanup; - error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head), 1); + error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head), 1, NULL, NULL); cleanup: git_object_free(object); diff --git a/src/reset.c b/src/reset.c index 261a36576..32e101357 100644 --- a/src/reset.c +++ b/src/reset.c @@ -131,7 +131,7 @@ int git_reset( /* move HEAD to the new target */ if ((error = git_reference__update_terminal(repo, GIT_HEAD_FILE, - git_object_id(commit))) < 0) + git_object_id(commit), NULL, NULL)) < 0) goto cleanup; if (reset_type == GIT_RESET_HARD) { diff --git a/src/settings.c b/src/settings.c new file mode 100644 index 000000000..748f76560 --- /dev/null +++ b/src/settings.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include <stdarg.h> + +#include <git2.h> +#include "common.h" +#include "fileops.h" +#include "cache.h" + +void git_libgit2_version(int *major, int *minor, int *rev) +{ + *major = LIBGIT2_VER_MAJOR; + *minor = LIBGIT2_VER_MINOR; + *rev = LIBGIT2_VER_REVISION; +} + +int git_libgit2_capabilities() +{ + return 0 +#ifdef GIT_THREADS + | GIT_CAP_THREADS +#endif +#if defined(GIT_SSL) || defined(GIT_WINHTTP) + | GIT_CAP_HTTPS +#endif +#if defined(GIT_SSH) + | GIT_CAP_SSH +#endif + ; +} + +/* Declarations for tuneable settings */ +extern size_t git_mwindow__window_size; +extern size_t git_mwindow__mapped_limit; + +static int config_level_to_futils_dir(int config_level) +{ + int val = -1; + + switch (config_level) { + case GIT_CONFIG_LEVEL_SYSTEM: val = GIT_FUTILS_DIR_SYSTEM; break; + case GIT_CONFIG_LEVEL_XDG: val = GIT_FUTILS_DIR_XDG; break; + case GIT_CONFIG_LEVEL_GLOBAL: val = GIT_FUTILS_DIR_GLOBAL; break; + default: + giterr_set( + GITERR_INVALID, "Invalid config path selector %d", config_level); + } + + return val; +} + +int git_libgit2_opts(int key, ...) +{ + int error = 0; + va_list ap; + + va_start(ap, key); + + switch (key) { + case GIT_OPT_SET_MWINDOW_SIZE: + git_mwindow__window_size = va_arg(ap, size_t); + break; + + case GIT_OPT_GET_MWINDOW_SIZE: + *(va_arg(ap, size_t *)) = git_mwindow__window_size; + break; + + case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT: + git_mwindow__mapped_limit = va_arg(ap, size_t); + break; + + case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT: + *(va_arg(ap, size_t *)) = git_mwindow__mapped_limit; + break; + + case GIT_OPT_GET_SEARCH_PATH: + if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) { + char *out = va_arg(ap, char *); + size_t outlen = va_arg(ap, size_t); + + error = git_futils_dirs_get_str(out, outlen, error); + } + break; + + case GIT_OPT_SET_SEARCH_PATH: + if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) + error = git_futils_dirs_set(error, va_arg(ap, const char *)); + break; + + case GIT_OPT_SET_CACHE_OBJECT_LIMIT: + { + git_otype type = (git_otype)va_arg(ap, int); + size_t size = va_arg(ap, size_t); + error = git_cache_set_max_object_size(type, size); + break; + } + + case GIT_OPT_SET_CACHE_MAX_SIZE: + git_cache__max_storage = va_arg(ap, ssize_t); + break; + + case GIT_OPT_ENABLE_CACHING: + git_cache__enabled = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_GET_CACHED_MEMORY: + *(va_arg(ap, ssize_t *)) = git_cache__current_storage.val; + *(va_arg(ap, ssize_t *)) = git_cache__max_storage; + break; + + case GIT_OPT_GET_TEMPLATE_PATH: + { + char *out = va_arg(ap, char *); + size_t outlen = va_arg(ap, size_t); + + error = git_futils_dirs_get_str(out, outlen, GIT_FUTILS_DIR_TEMPLATE); + } + break; + + case GIT_OPT_SET_TEMPLATE_PATH: + error = git_futils_dirs_set(GIT_FUTILS_DIR_TEMPLATE, va_arg(ap, const char *)); + break; + } + + va_end(ap); + + return error; +} + diff --git a/src/signature.c b/src/signature.c index ec51a42e9..f658d6035 100644 --- a/src/signature.c +++ b/src/signature.c @@ -82,23 +82,28 @@ int git_signature_new(git_signature **sig_out, const char *name, const char *ema return 0; } -git_signature *git_signature_dup(const git_signature *sig) +int git_signature_dup(git_signature **dest, const git_signature *source) { - git_signature *new; + git_signature *signature; - if (sig == NULL) - return NULL; + if (source == NULL) + return 0; + + signature = git__calloc(1, sizeof(git_signature)); + GITERR_CHECK_ALLOC(signature); + + signature->name = git__strdup(source->name); + GITERR_CHECK_ALLOC(signature->name); - new = git__calloc(1, sizeof(git_signature)); - if (new == NULL) - return NULL; + signature->email = git__strdup(source->email); + GITERR_CHECK_ALLOC(signature->email); - new->name = git__strdup(sig->name); - new->email = git__strdup(sig->email); - new->when.time = sig->when.time; - new->when.offset = sig->when.offset; + signature->when.time = source->when.time; + signature->when.offset = source->when.offset; - return new; + *dest = signature; + + return 0; } int git_signature_now(git_signature **sig_out, const char *name, const char *email) diff --git a/src/stash.c b/src/stash.c index 3019816ff..b1dd87b22 100644 --- a/src/stash.c +++ b/src/stash.c @@ -417,7 +417,7 @@ static int update_reflog( if ((error = git_reference_ensure_log(repo, GIT_REFS_STASH_FILE)) < 0) return error; - error = git_reference_create_with_log(&stash, repo, GIT_REFS_STASH_FILE, w_commit_oid, 1, stasher, message); + error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, w_commit_oid, 1, stasher, message); git_reference_free(stash); @@ -628,7 +628,7 @@ int git_stash_drop( entry = git_reflog_entry_byindex(reflog, 0); git_reference_free(stash); - if ((error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, &entry->oid_cur, 1) < 0)) + if ((error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, &entry->oid_cur, 1, NULL, NULL) < 0)) goto cleanup; /* We need to undo the writing that we just did */ diff --git a/src/submodule.c b/src/submodule.c index 5548e4553..3ffbfdba4 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -472,6 +472,10 @@ int git_submodule_save(git_submodule *submodule) (error = git_config_file_set_string(mods, key.ptr, submodule->url)) < 0) goto cleanup; + if ((error = submodule_config_key_trunc_puts(&key, "branch")) < 0 || + (error = git_config_file_set_string(mods, key.ptr, submodule->branch)) < 0) + goto cleanup; + if (!(error = submodule_config_key_trunc_puts(&key, "update")) && (val = git_submodule_update_to_str(submodule->update)) != NULL) error = git_config_file_set_string(mods, key.ptr, val); @@ -528,6 +532,12 @@ const char *git_submodule_url(git_submodule *submodule) return submodule->url; } +const char *git_submodule_branch(git_submodule *submodule) +{ + assert(submodule); + return submodule->branch; +} + int git_submodule_set_url(git_submodule *submodule, const char *url) { assert(submodule && url); @@ -632,11 +642,11 @@ git_submodule_recurse_t git_submodule_fetch_recurse_submodules( return submodule->fetch_recurse; } -int git_submodule_set_fetch_recurse_submodules( +git_submodule_recurse_t git_submodule_set_fetch_recurse_submodules( git_submodule *submodule, git_submodule_recurse_t fetch_recurse_submodules) { - int old; + git_submodule_recurse_t old; assert(submodule); @@ -990,8 +1000,9 @@ static git_submodule *submodule_alloc(git_repository *repo, const char *name) GIT_REFCOUNT_INC(sm); sm->ignore = sm->ignore_default = GIT_SUBMODULE_IGNORE_NONE; sm->update = sm->update_default = GIT_SUBMODULE_UPDATE_CHECKOUT; - sm->fetch_recurse = sm->update_default = GIT_SUBMODULE_RECURSE_YES; + sm->fetch_recurse = GIT_SUBMODULE_RECURSE_YES; sm->repo = repo; + sm->branch = NULL; return sm; } @@ -1190,6 +1201,15 @@ static int submodule_load_from_config( goto done; } } + else if (strcasecmp(property, "branch") == 0) { + git__free(sm->branch); + sm->branch = NULL; + + if (value != NULL && (sm->branch = git__strdup(value)) == NULL) { + error = -1; + goto done; + } + } else if (strcasecmp(property, "update") == 0) { if ((error = git_submodule_parse_update(&sm->update, value)) < 0) goto done; diff --git a/src/submodule.h b/src/submodule.h index 2a610e112..94748aca0 100644 --- a/src/submodule.h +++ b/src/submodule.h @@ -81,6 +81,7 @@ struct git_submodule { char *name; char *path; /* important: may just point to "name" string */ char *url; + char *branch; git_submodule_update_t update; git_submodule_update_t update_default; git_submodule_ignore_t ignore; @@ -271,7 +271,7 @@ static int git_tag_create__internal( } else git_oid_cpy(oid, git_object_id(target)); - error = git_reference_create(&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite); + error = git_reference_create(&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite, NULL, NULL); cleanup: git_reference_free(new_ref); @@ -376,7 +376,7 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu return -1; } - error = git_reference_create(&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite); + error = git_reference_create(&new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite, NULL, NULL); git_reference_free(new_ref); git_buf_free(&ref_name); diff --git a/src/transports/local.c b/src/transports/local.c index 4635d5dd3..253aca30a 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -315,7 +315,7 @@ static int local_push_update_remote_ref( if (lref) { /* Create or update a ref */ if ((error = git_reference_create(NULL, remote_repo, rref, loid, - !git_oid_iszero(roid))) < 0) + !git_oid_iszero(roid), NULL, NULL)) < 0) return error; } else { /* Delete a ref */ diff --git a/src/tree.c b/src/tree.c index 4d77ff778..fc105ed5e 100644 --- a/src/tree.c +++ b/src/tree.c @@ -204,22 +204,22 @@ void git_tree_entry_free(git_tree_entry *entry) git__free(entry); } -git_tree_entry *git_tree_entry_dup(const git_tree_entry *entry) +int git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source) { size_t total_size; git_tree_entry *copy; - assert(entry); + assert(source); - total_size = sizeof(git_tree_entry) + entry->filename_len + 1; + total_size = sizeof(git_tree_entry) + source->filename_len + 1; copy = git__malloc(total_size); - if (!copy) - return NULL; + GITERR_CHECK_ALLOC(copy); - memcpy(copy, entry, total_size); + memcpy(copy, source, total_size); - return copy; + *dest = copy; + return 0; } void git_tree__free(void *_tree) @@ -853,8 +853,7 @@ int git_tree_entry_bypath( case '\0': /* If there are no more components in the path, return * this entry */ - *entry_out = git_tree_entry_dup(entry); - return 0; + return git_tree_entry_dup(entry_out, entry); } if (git_tree_lookup(&subtree, root->object.repo, &entry->oid) < 0) diff --git a/src/util.c b/src/util.c index 47516a8f7..3767b890c 100644 --- a/src/util.c +++ b/src/util.c @@ -6,140 +6,21 @@ */ #include <git2.h> #include "common.h" -#include <stdarg.h> #include <stdio.h> #include <ctype.h> #include "posix.h" -#include "fileops.h" -#include "cache.h" #ifdef _MSC_VER # include <Shlwapi.h> #endif -void git_libgit2_version(int *major, int *minor, int *rev) -{ - *major = LIBGIT2_VER_MAJOR; - *minor = LIBGIT2_VER_MINOR; - *rev = LIBGIT2_VER_REVISION; -} - -int git_libgit2_capabilities() -{ - return 0 -#ifdef GIT_THREADS - | GIT_CAP_THREADS -#endif -#if defined(GIT_SSL) || defined(GIT_WINHTTP) - | GIT_CAP_HTTPS -#endif -#if defined(GIT_SSH) - | GIT_CAP_SSH -#endif - ; -} - -/* Declarations for tuneable settings */ -extern size_t git_mwindow__window_size; -extern size_t git_mwindow__mapped_limit; - -static int config_level_to_futils_dir(int config_level) -{ - int val = -1; - - switch (config_level) { - case GIT_CONFIG_LEVEL_SYSTEM: val = GIT_FUTILS_DIR_SYSTEM; break; - case GIT_CONFIG_LEVEL_XDG: val = GIT_FUTILS_DIR_XDG; break; - case GIT_CONFIG_LEVEL_GLOBAL: val = GIT_FUTILS_DIR_GLOBAL; break; - default: - giterr_set( - GITERR_INVALID, "Invalid config path selector %d", config_level); - } - - return val; -} - -int git_libgit2_opts(int key, ...) -{ - int error = 0; - va_list ap; - - va_start(ap, key); - - switch (key) { - case GIT_OPT_SET_MWINDOW_SIZE: - git_mwindow__window_size = va_arg(ap, size_t); - break; - - case GIT_OPT_GET_MWINDOW_SIZE: - *(va_arg(ap, size_t *)) = git_mwindow__window_size; - break; - - case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT: - git_mwindow__mapped_limit = va_arg(ap, size_t); - break; - - case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT: - *(va_arg(ap, size_t *)) = git_mwindow__mapped_limit; - break; - - case GIT_OPT_GET_SEARCH_PATH: - if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) { - char *out = va_arg(ap, char *); - size_t outlen = va_arg(ap, size_t); - - error = git_futils_dirs_get_str(out, outlen, error); - } - break; - - case GIT_OPT_SET_SEARCH_PATH: - if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) - error = git_futils_dirs_set(error, va_arg(ap, const char *)); - break; - - case GIT_OPT_SET_CACHE_OBJECT_LIMIT: - { - git_otype type = (git_otype)va_arg(ap, int); - size_t size = va_arg(ap, size_t); - error = git_cache_set_max_object_size(type, size); - break; - } - - case GIT_OPT_SET_CACHE_MAX_SIZE: - git_cache__max_storage = va_arg(ap, ssize_t); - break; - - case GIT_OPT_ENABLE_CACHING: - git_cache__enabled = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_GET_CACHED_MEMORY: - *(va_arg(ap, ssize_t *)) = git_cache__current_storage.val; - *(va_arg(ap, ssize_t *)) = git_cache__max_storage; - break; - - case GIT_OPT_GET_TEMPLATE_PATH: - { - char *out = va_arg(ap, char *); - size_t outlen = va_arg(ap, size_t); - - error = git_futils_dirs_get_str(out, outlen, GIT_FUTILS_DIR_TEMPLATE); - } - break; - - case GIT_OPT_SET_TEMPLATE_PATH: - error = git_futils_dirs_set(GIT_FUTILS_DIR_TEMPLATE, va_arg(ap, const char *)); - break; - } - - va_end(ap); - - return error; -} - void git_strarray_free(git_strarray *array) { size_t i; + + if (array == NULL) + return; + for (i = 0; i < array->count; ++i) git__free(array->strings[i]); @@ -729,6 +610,7 @@ void git__qsort_r( #if defined(__MINGW32__) || defined(AMIGA) || \ defined(__OpenBSD__) || defined(__NetBSD__) || \ defined(__gnu_hurd__) || defined(__ANDROID_API__) || \ + defined(__sun) || \ (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8) git__insertsort_r(els, nel, elsize, NULL, cmp, payload); #elif defined(GIT_WIN32) diff --git a/src/vector.c b/src/vector.c index 050e032a0..f0c2f06c2 100644 --- a/src/vector.c +++ b/src/vector.c @@ -6,7 +6,6 @@ */ #include "common.h" -#include "repository.h" #include "vector.h" /* In elements, not bytes */ diff --git a/src/zstream.c b/src/zstream.c new file mode 100644 index 000000000..7def0440b --- /dev/null +++ b/src/zstream.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include <zlib.h> + +#include "zstream.h" +#include "buffer.h" + +#define BUFFER_SIZE (1024 * 1024) + +static int zstream_seterr(int zerr, git_zstream *zstream) +{ + if (zerr == Z_MEM_ERROR) + giterr_set_oom(); + else if (zstream->msg) + giterr_set(GITERR_ZLIB, zstream->msg); + else + giterr_set(GITERR_ZLIB, "Unknown compression error"); + + return -1; +} + +int git_zstream_init(git_zstream *zstream) +{ + int zerr; + + if ((zerr = deflateInit(zstream, Z_DEFAULT_COMPRESSION)) != Z_OK) + return zstream_seterr(zerr, zstream); + + return 0; +} + +ssize_t git_zstream_deflate(void *out, size_t out_len, git_zstream *zstream, const void *in, size_t in_len) +{ + int zerr; + + if ((ssize_t)out_len < 0) + out_len = INT_MAX; + + zstream->next_in = (Bytef *)in; + zstream->avail_in = in_len; + zstream->next_out = out; + zstream->avail_out = out_len; + + if ((zerr = deflate(zstream, Z_FINISH)) == Z_STREAM_ERROR) + return zstream_seterr(zerr, zstream); + + return (out_len - zstream->avail_out); +} + +void git_zstream_reset(git_zstream *zstream) +{ + deflateReset(zstream); +} + +void git_zstream_free(git_zstream *zstream) +{ + deflateEnd(zstream); +} + +int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len) +{ + git_zstream zstream = GIT_ZSTREAM_INIT; + size_t out_len; + ssize_t written; + int error = 0; + + if ((error = git_zstream_init(&zstream)) < 0) + goto done; + + do { + if (out->asize - out->size < BUFFER_SIZE) + git_buf_grow(out, out->asize + BUFFER_SIZE); + + out_len = out->asize - out->size; + + if ((written = git_zstream_deflate(out->ptr + out->size, out_len, &zstream, in, in_len)) <= 0) + break; + + in = (char *)in + written; + in_len -= written; + out->size += written; + } while (written > 0); + + if (written < 0) + error = written; + +done: + git_zstream_free(&zstream); + return error; +} diff --git a/src/zstream.h b/src/zstream.h new file mode 100644 index 000000000..9672903c0 --- /dev/null +++ b/src/zstream.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_zstream_h__ +#define INCLUDE_zstream_h__ + +#include <zlib.h> + +#include "common.h" +#include "buffer.h" + +#define git_zstream z_stream + +#define GIT_ZSTREAM_INIT {0} + +int git_zstream_init(git_zstream *zstream); +ssize_t git_zstream_deflate(void *out, size_t out_len, git_zstream *zstream, const void *in, size_t in_len); +void git_zstream_reset(git_zstream *zstream); +void git_zstream_free(git_zstream *zstream); + +int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len); + +#endif /* INCLUDE_zstream_h__ */ diff --git a/tests/blame/blame_helpers.c b/tests/blame/blame_helpers.c index d64bb5c4c..56240dbde 100644 --- a/tests/blame/blame_helpers.c +++ b/tests/blame/blame_helpers.c @@ -48,6 +48,9 @@ void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx, actual, expected); } cl_assert_equal_s(actual, expected); + cl_assert_equal_i(git_oid_cmp(&hunk->final_commit_id, &hunk->orig_commit_id), 0); + + if (strcmp(hunk->orig_path, orig_path)) { hunk_message(idx, hunk, "has mismatched original path (got '%s', expected '%s')\n", hunk->orig_path, orig_path); diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 06aa6a594..f0699fdb7 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -484,7 +484,7 @@ void assert_conflict( /* Make HEAD point to this branch */ cl_git_pass(git_reference_symbolic_create( - &head, g_repo, "HEAD", git_reference_name(branch), 1)); + &head, g_repo, "HEAD", git_reference_name(branch), 1, NULL, NULL)); git_reference_free(head); git_reference_free(branch); diff --git a/tests/commit/write.c b/tests/commit/write.c index 73436b74b..8e5b67f2f 100644 --- a/tests/commit/write.c +++ b/tests/commit/write.c @@ -116,7 +116,7 @@ void test_commit_write__root(void) 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_reference_symbolic_create(&head, g_repo, "HEAD", branch_name, 1, NULL, NULL)); cl_git_pass(git_commit_create_v( &commit_id, /* out id */ diff --git a/tests/diff/rename.c b/tests/diff/rename.c index 93e69f479..4d1f7646e 100644 --- a/tests/diff/rename.c +++ b/tests/diff/rename.c @@ -945,7 +945,7 @@ void test_diff_rename__rejected_match_can_match_others(void) cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_git_pass(git_reference_symbolic_set_target( - &selfsimilar, head, "refs/heads/renames_similar")); + &selfsimilar, head, "refs/heads/renames_similar", NULL, NULL)); cl_git_pass(git_checkout_head(g_repo, &opts)); cl_git_pass(git_repository_index(&index, g_repo)); @@ -1030,7 +1030,7 @@ void test_diff_rename__rejected_match_can_match_others_two(void) cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_git_pass(git_reference_symbolic_set_target( - &selfsimilar, head, "refs/heads/renames_similar_two")); + &selfsimilar, head, "refs/heads/renames_similar_two", NULL, NULL)); cl_git_pass(git_checkout_head(g_repo, &opts)); cl_git_pass(git_repository_index(&index, g_repo)); @@ -1088,7 +1088,7 @@ void test_diff_rename__rejected_match_can_match_others_three(void) cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_git_pass(git_reference_symbolic_set_target( - &selfsimilar, head, "refs/heads/renames_similar_two")); + &selfsimilar, head, "refs/heads/renames_similar_two", NULL, NULL)); cl_git_pass(git_checkout_head(g_repo, &opts)); cl_git_pass(git_repository_index(&index, g_repo)); diff --git a/tests/filter/blob.c b/tests/filter/blob.c index 9600a9779..8dce6470a 100644 --- a/tests/filter/blob.c +++ b/tests/filter/blob.c @@ -47,6 +47,38 @@ void test_filter_blob__all_crlf(void) git_blob_free(blob); } +void test_filter_blob__sanitizes(void) +{ + git_blob *blob; + git_buf buf; + + cl_git_pass(git_revparse_single( + (git_object **)&blob, g_repo, "e69de29")); /* zero-byte */ + + cl_assert_equal_i(0, git_blob_rawsize(blob)); + cl_assert_equal_s("", git_blob_rawcontent(blob)); + + memset(&buf, 0, sizeof(git_buf)); + cl_git_pass(git_blob_filtered_content(&buf, blob, "file.bin", 1)); + cl_assert_equal_sz(0, buf.size); + cl_assert_equal_s("", buf.ptr); + git_buf_free(&buf); + + memset(&buf, 0, sizeof(git_buf)); + cl_git_pass(git_blob_filtered_content(&buf, blob, "file.crlf", 1)); + cl_assert_equal_sz(0, buf.size); + cl_assert_equal_s("", buf.ptr); + git_buf_free(&buf); + + memset(&buf, 0, sizeof(git_buf)); + cl_git_pass(git_blob_filtered_content(&buf, blob, "file.lf", 1)); + cl_assert_equal_sz(0, buf.size); + cl_assert_equal_s("", buf.ptr); + git_buf_free(&buf); + + git_blob_free(blob); +} + void test_filter_blob__ident(void) { git_oid id; diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c index 5660179a7..7ce5e28ff 100644 --- a/tests/merge/merge_helpers.c +++ b/tests/merge/merge_helpers.c @@ -87,7 +87,7 @@ int merge_branches(git_merge_result **result, git_repository *repo, const char * head_checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE; - cl_git_pass(git_reference_symbolic_create(&head_ref, repo, "HEAD", ours_branch, 1)); + cl_git_pass(git_reference_symbolic_create(&head_ref, repo, "HEAD", ours_branch, 1, NULL, NULL)); cl_git_pass(git_checkout_head(repo, &head_checkout_opts)); cl_git_pass(git_reference_lookup(&theirs_ref, repo, theirs_branch)); diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index 4a3b86ee4..98dca53ef 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -406,7 +406,7 @@ void test_merge_workdir_simple__directory_file(void) { 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 3, "file-5/new" }, }; - cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_DIR OURS_DIRECTORY_FILE, 1)); + cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_DIR OURS_DIRECTORY_FILE, 1, NULL, NULL)); cl_git_pass(git_reference_name_to_id(&head_commit_id, repo, GIT_HEAD_FILE)); cl_git_pass(git_commit_lookup(&head_commit, repo, &head_commit_id)); cl_git_pass(git_reset(repo, (git_object *)head_commit, GIT_RESET_HARD)); diff --git a/tests/merge/workdir/trivial.c b/tests/merge/workdir/trivial.c index 9f9566243..df18b0e0b 100644 --- a/tests/merge/workdir/trivial.c +++ b/tests/merge/workdir/trivial.c @@ -42,7 +42,7 @@ static int merge_trivial(const char *ours, const char *theirs, bool automerge) opts.merge_tree_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_symbolic_create(&our_ref, repo, "HEAD", branch_buf.ptr, 1)); + cl_git_pass(git_reference_symbolic_create(&our_ref, repo, "HEAD", branch_buf.ptr, 1, NULL, NULL)); cl_git_pass(git_checkout_head(repo, &checkout_opts)); diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index 954ded82c..235a1022d 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -129,6 +129,27 @@ void test_network_remote_remotes__add_fetchspec(void) cl_assert_equal_b(_refspec->push, false); } +void test_network_remote_remotes__dup(void) +{ + git_strarray array; + git_remote *dup; + + cl_git_pass(git_remote_dup(&dup, _remote)); + + cl_assert_equal_s(git_remote_name(dup), git_remote_name(_remote)); + cl_assert_equal_s(git_remote_url(dup), git_remote_url(_remote)); + cl_assert_equal_s(git_remote_pushurl(dup), git_remote_pushurl(_remote)); + + cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote)); + cl_assert_equal_i(1, (int)array.count); + cl_assert_equal_s("+refs/heads/*:refs/remotes/test/*", array.strings[0]); + git_strarray_free(&array); + + cl_git_pass(git_remote_get_push_refspecs(&array, _remote)); + cl_assert_equal_i(0, (int)array.count); + git_strarray_free(&array); +} + void test_network_remote_remotes__add_pushspec(void) { size_t size; diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index de90cb734..a642f8704 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -14,7 +14,7 @@ void test_refs_branches_delete__initialize(void) cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0)); + cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL, NULL)); } void test_refs_branches_delete__cleanup(void) diff --git a/tests/refs/branches/ishead.c b/tests/refs/branches/ishead.c index b1ad09c3e..12a8c4449 100644 --- a/tests/refs/branches/ishead.c +++ b/tests/refs/branches/ishead.c @@ -98,9 +98,9 @@ void test_refs_branches_ishead__only_direct_references_are_considered(void) git_repository_free(repo); repo = cl_git_sandbox_init("testrepo.git"); - cl_git_pass(git_reference_symbolic_create(&linked, repo, "refs/heads/linked", "refs/heads/master", 0)); - cl_git_pass(git_reference_symbolic_create(&super, repo, "refs/heads/super", "refs/heads/linked", 0)); - cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/heads/super", 1)); + cl_git_pass(git_reference_symbolic_create(&linked, repo, "refs/heads/linked", "refs/heads/master", 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&super, repo, "refs/heads/super", "refs/heads/linked", 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/heads/super", 1, NULL, NULL)); cl_assert_equal_i(false, git_branch_is_head(linked)); cl_assert_equal_i(false, git_branch_is_head(super)); diff --git a/tests/refs/branches/iterator.c b/tests/refs/branches/iterator.c index 904c6a146..29ca59aca 100644 --- a/tests/refs/branches/iterator.c +++ b/tests/refs/branches/iterator.c @@ -12,7 +12,7 @@ void test_refs_branches_iterator__initialize(void) cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0)); + cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL, NULL)); } void test_refs_branches_iterator__cleanup(void) @@ -113,7 +113,7 @@ void test_refs_branches_iterator__retrieve_remote_symbolic_HEAD_when_present(voi }; git_reference_free(fake_remote); - cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0)); + cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0, NULL, NULL)); assert_retrieval(GIT_BRANCH_REMOTE, 3); diff --git a/tests/refs/crashes.c b/tests/refs/crashes.c index 5a1885a7a..03082d71e 100644 --- a/tests/refs/crashes.c +++ b/tests/refs/crashes.c @@ -7,7 +7,7 @@ void test_refs_crashes__double_free(void) const char *REFNAME = "refs/heads/xxx"; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_reference_symbolic_create(&ref, repo, REFNAME, "refs/heads/master", 0)); + cl_git_pass(git_reference_symbolic_create(&ref, repo, REFNAME, "refs/heads/master", 0, NULL, NULL)); cl_git_pass(git_reference_lookup(&ref2, repo, REFNAME)); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); diff --git a/tests/refs/create.c b/tests/refs/create.c index 85ff05aa9..50b8e84f8 100644 --- a/tests/refs/create.c +++ b/tests/refs/create.c @@ -32,7 +32,7 @@ void test_refs_create__symbolic(void) git_oid_fromstr(&id, current_master_tip); /* Create and write the new symbolic reference */ - cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0)); + cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); @@ -73,7 +73,7 @@ void test_refs_create__deep_symbolic(void) git_oid_fromstr(&id, current_master_tip); - cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0)); + cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL, NULL)); cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref)); cl_assert(git_oid_cmp(&id, git_reference_target(resolved_ref)) == 0); @@ -95,7 +95,7 @@ void test_refs_create__oid(void) git_oid_fromstr(&id, current_master_tip); /* Create and write the new object id reference */ - cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0)); + cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head)); @@ -130,7 +130,7 @@ void test_refs_create__oid_unknown(void) git_oid_fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644"); /* Create and write the new object id reference */ - cl_git_fail(git_reference_create(&new_reference, g_repo, new_head, &id, 0)); + cl_git_fail(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL, NULL)); /* Ensure the reference can't be looked-up... */ cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, new_head)); @@ -144,10 +144,10 @@ void test_refs_create__propagate_eexists(void) /* Make sure it works for oid and for symbolic both */ git_oid_fromstr(&oid, current_master_tip); - error = git_reference_create(&ref, g_repo, current_head_target, &oid, false); + error = git_reference_create(&ref, g_repo, current_head_target, &oid, false, NULL, NULL); cl_assert(error == GIT_EEXISTS); - error = git_reference_symbolic_create(&ref, g_repo, "HEAD", current_head_target, false); + error = git_reference_symbolic_create(&ref, g_repo, "HEAD", current_head_target, false, NULL, NULL); cl_assert(error == GIT_EEXISTS); } @@ -161,8 +161,8 @@ void test_refs_create__creating_a_reference_with_an_invalid_name_returns_EINVALI git_oid_fromstr(&id, current_master_tip); cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_create( - &new_reference, g_repo, name, &id, 0)); + &new_reference, g_repo, name, &id, 0, NULL, NULL)); cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create( - &new_reference, g_repo, name, current_head_target, 0)); + &new_reference, g_repo, name, current_head_target, 0, NULL, NULL)); } diff --git a/tests/refs/createwithlog.c b/tests/refs/createwithlog.c index 0fe81df91..026ff6d6a 100644 --- a/tests/refs/createwithlog.c +++ b/tests/refs/createwithlog.c @@ -35,7 +35,7 @@ void test_refs_createwithlog__creating_a_direct_reference_adds_a_reflog_entry(vo cl_git_pass(git_signature_now(&signature, "foo", "foo@bar")); cl_git_pass( - git_reference_create_with_log(&reference, g_repo, name, &id, 0, signature, message)); + git_reference_create(&reference, g_repo, name, &id, 0, signature, message)); cl_git_pass(git_reflog_read(&reflog, g_repo, name)); cl_assert_equal_sz(1, git_reflog_entrycount(reflog)); diff --git a/tests/refs/delete.c b/tests/refs/delete.c index 973768aeb..5e4afb138 100644 --- a/tests/refs/delete.c +++ b/tests/refs/delete.c @@ -66,7 +66,7 @@ void test_refs_delete__packed_only(void) git_oid_fromstr(&id, current_master_tip); /* Create and write the new object id reference */ - cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0, NULL, NULL)); git_reference_free(ref); /* Lookup the reference */ diff --git a/tests/refs/foreachglob.c b/tests/refs/foreachglob.c index c0f6ce763..b992b07b8 100644 --- a/tests/refs/foreachglob.c +++ b/tests/refs/foreachglob.c @@ -12,7 +12,7 @@ void test_refs_foreachglob__initialize(void) cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0)); + cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL, NULL)); } void test_refs_foreachglob__cleanup(void) diff --git a/tests/refs/overwrite.c b/tests/refs/overwrite.c index ebe72069c..78ce4ace7 100644 --- a/tests/refs/overwrite.c +++ b/tests/refs/overwrite.c @@ -27,8 +27,8 @@ void test_refs_overwrite__symbolic(void) git_reference *ref, *branch_ref; /* The target needds to exist and we need to check the name has changed */ - cl_git_pass(git_reference_symbolic_create(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0)); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_branch_name, 0)); + cl_git_pass(git_reference_symbolic_create(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_branch_name, 0, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place*/ @@ -38,8 +38,8 @@ void test_refs_overwrite__symbolic(void) git_reference_free(ref); /* Ensure we can't create it unless we force it to */ - cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1)); + cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place */ @@ -63,7 +63,7 @@ void test_refs_overwrite__object_id(void) git_reference_free(ref); /* Create it */ - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); git_reference_free(ref); cl_git_pass(git_reference_lookup(&ref, g_repo, ref_test_name)); @@ -72,8 +72,8 @@ void test_refs_overwrite__object_id(void) git_reference_free(ref); /* Ensure we can't overwrite unless we force it */ - cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0)); - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1)); + cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it has been overwritten */ @@ -94,10 +94,10 @@ void test_refs_overwrite__object_id_with_symbolic(void) git_oid_cpy(&id, git_reference_target(ref)); git_reference_free(ref); - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); git_reference_free(ref); - cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1)); + cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place */ @@ -120,11 +120,11 @@ void test_refs_overwrite__symbolic_with_object_id(void) git_reference_free(ref); /* Create the symbolic ref */ - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); git_reference_free(ref); /* It shouldn't overwrite unless we tell it to */ - cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0)); - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1)); + cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place */ diff --git a/tests/refs/pack.c b/tests/refs/pack.c index 849a052aa..7f5c611a7 100644 --- a/tests/refs/pack.c +++ b/tests/refs/pack.c @@ -93,11 +93,11 @@ void test_refs_pack__symbolic(void) for (i = 0; i < 100; ++i) { snprintf(name, sizeof(name), "refs/heads/symbolic-%03d", i); cl_git_pass(git_reference_symbolic_create( - &ref, g_repo, name, "refs/heads/master", 0)); + &ref, g_repo, name, "refs/heads/master", 0, NULL, NULL)); git_reference_free(ref); snprintf(name, sizeof(name), "refs/heads/direct-%03d", i); - cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL, NULL)); git_reference_free(ref); } diff --git a/tests/refs/reflog/reflog.c b/tests/refs/reflog/reflog.c index a1c5adaf4..82b28de15 100644 --- a/tests/refs/reflog/reflog.c +++ b/tests/refs/reflog/reflog.c @@ -82,7 +82,7 @@ void test_refs_reflog_reflog__append_then_read(void) /* Create a new branch pointing at the HEAD */ git_oid_fromstr(&oid, current_master_tip); - cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0, NULL, NULL)); git_reference_free(ref); cl_git_pass(git_signature_now(&committer, "foo", "foo@bar")); @@ -189,11 +189,11 @@ void test_refs_reflog_reflog__write_only_std_locations(void) git_oid_fromstr(&id, current_master_tip); - cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/foo", &id, 1)); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/foo", &id, 1, NULL, NULL)); git_reference_free(ref); - cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1)); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL, NULL)); git_reference_free(ref); - cl_git_pass(git_reference_create(&ref, g_repo, "refs/notes/foo", &id, 1)); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/notes/foo", &id, 1, NULL, NULL)); git_reference_free(ref); assert_has_reflog(true, "refs/heads/foo"); @@ -210,7 +210,7 @@ void test_refs_reflog_reflog__write_when_explicitly_active(void) git_oid_fromstr(&id, current_master_tip); git_reference_ensure_log(g_repo, "refs/tags/foo"); - cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1)); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL, NULL)); git_reference_free(ref); assert_has_reflog(true, "refs/tags/foo"); } diff --git a/tests/refs/rename.c b/tests/refs/rename.c index 543bc4d62..120967892 100644 --- a/tests/refs/rename.c +++ b/tests/refs/rename.c @@ -268,15 +268,15 @@ void test_refs_rename__overwrite(void) git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ - cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0)); - cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0)); + cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0, NULL, NULL)); + cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL, NULL)); /* Pack everything */ cl_git_pass(git_repository_refdb(&refdb, g_repo)); cl_git_pass(git_refdb_compress(refdb)); /* Attempt to create illegal reference */ - cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0)); + cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0, NULL, NULL)); /* Illegal reference couldn't be created so this is supposed to fail */ cl_git_fail(git_reference_lookup(&ref_one_new, g_repo, ref_one_name_new)); @@ -301,7 +301,7 @@ void test_refs_rename__prefix(void) git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ - cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0)); + cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL, NULL)); /* An existing reference... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name)); @@ -334,7 +334,7 @@ void test_refs_rename__move_up(void) git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ - cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0)); + cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL, NULL)); git_reference_free(ref_two); /* An existing reference... */ diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 37d3981bb..522a44c82 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -596,7 +596,8 @@ void test_refs_revparse__issue_994(void) repo, "refs/remotes/origin/bim_with_3d@11296", git_reference_target(head), - 0)); + 0, + NULL, NULL)); cl_git_pass(git_revparse_single(&target, repo, "origin/bim_with_3d@11296")); git_object_free(target); diff --git a/tests/refs/settargetwithlog.c b/tests/refs/settargetwithlog.c index cfa1c99d5..524ce771c 100644 --- a/tests/refs/settargetwithlog.c +++ b/tests/refs/settargetwithlog.c @@ -38,7 +38,7 @@ void test_refs_settargetwithlog__updating_a_direct_reference_adds_a_reflog_entry cl_git_pass(git_signature_now(&signature, "foo", "foo@bar")); - cl_git_pass(git_reference_set_target_with_log( + cl_git_pass(git_reference_set_target( &reference_out, reference, &target_id, signature, message)); cl_git_pass(git_reflog_read(&reflog, g_repo, br2_name)); diff --git a/tests/refs/setter.c b/tests/refs/setter.c index 6d875f9b6..9a945db00 100644 --- a/tests/refs/setter.c +++ b/tests/refs/setter.c @@ -34,7 +34,7 @@ void test_refs_setter__update_direct(void) cl_git_pass(git_reference_lookup(&test_ref, g_repo, ref_test_name)); cl_assert(git_reference_type(test_ref) == GIT_REF_OID); - cl_git_pass(git_reference_set_target(&new_ref, test_ref, &id)); + cl_git_pass(git_reference_set_target(&new_ref, test_ref, &id, NULL, NULL)); git_reference_free(test_ref); git_reference_free(new_ref); @@ -53,7 +53,7 @@ void test_refs_setter__update_symbolic(void) cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC); cl_assert(strcmp(git_reference_symbolic_target(head), ref_master_name) == 0); - cl_git_pass(git_reference_symbolic_set_target(&new_head, head, ref_test_name)); + cl_git_pass(git_reference_symbolic_set_target(&new_head, head, ref_test_name, NULL, NULL)); git_reference_free(new_head); git_reference_free(head); @@ -73,7 +73,7 @@ void test_refs_setter__cant_update_direct_with_symbolic(void) 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)); + cl_git_fail(git_reference_symbolic_set_target(&new, ref, ref_name, NULL, NULL)); git_reference_free(ref); } @@ -90,10 +90,10 @@ void test_refs_setter__cant_update_symbolic_with_direct(void) git_reference_free(ref); /* Create the symbolic ref */ - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); /* Can't set an OID on a direct ref */ - cl_git_fail(git_reference_set_target(&new, ref, &id)); + cl_git_fail(git_reference_set_target(&new, ref, &id, NULL, NULL)); git_reference_free(ref); } diff --git a/tests/refs/unicode.c b/tests/refs/unicode.c index b56012869..471b0b8d3 100644 --- a/tests/refs/unicode.c +++ b/tests/refs/unicode.c @@ -24,7 +24,7 @@ void test_refs_unicode__create_and_lookup(void) /* Create the reference */ cl_git_pass(git_reference_lookup(&ref0, repo, master)); cl_git_pass(git_reference_create( - &ref1, repo, REFNAME, git_reference_target(ref0), 0)); + &ref1, repo, REFNAME, git_reference_target(ref0), 0, NULL, NULL)); cl_assert_equal_s(REFNAME, git_reference_name(ref1)); git_reference_free(ref0); diff --git a/tests/refs/update.c b/tests/refs/update.c index 205b526a2..873fc4ebe 100644 --- a/tests/refs/update.c +++ b/tests/refs/update.c @@ -22,5 +22,5 @@ void test_refs_update__updating_the_target_of_a_symref_with_an_invalid_name_retu cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); git_reference_free(head); - cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(&head, g_repo, GIT_HEAD_FILE, "refs/heads/inv@{id", 1)); + cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(&head, g_repo, GIT_HEAD_FILE, "refs/heads/inv@{id", 1, NULL, NULL)); } diff --git a/tests/repo/head.c b/tests/repo/head.c index 5a55984bd..101e30f10 100644 --- a/tests/repo/head.c +++ b/tests/repo/head.c @@ -26,7 +26,7 @@ void test_repo_head__head_detached(void) cl_assert_equal_i(true, git_repository_head_detached(repo)); /* take the reop back to it's original state */ - cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master", 1)); + cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master", 1, NULL, NULL)); git_reference_free(ref); cl_assert_equal_i(false, git_repository_head_detached(repo)); @@ -44,7 +44,7 @@ void test_repo_head__unborn_head(void) /* take the repo back to it's original state */ - cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master", 1)); + cl_git_pass(git_reference_symbolic_create(&ref, repo, "HEAD", "refs/heads/master", 1, NULL, NULL)); cl_assert(git_repository_head_unborn(repo) == 0); git_reference_free(ref); @@ -156,7 +156,7 @@ void test_repo_head__detach_head_Fails_if_HEAD_and_point_to_a_non_commitish(void { git_reference *head; - cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/tags/point_to_blob", 1)); + cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/tags/point_to_blob", 1, NULL, NULL)); cl_git_fail(git_repository_detach_head(repo)); diff --git a/tests/repo/repo_helpers.c b/tests/repo/repo_helpers.c index 3d477ff42..7c5db4a81 100644 --- a/tests/repo/repo_helpers.c +++ b/tests/repo/repo_helpers.c @@ -7,7 +7,7 @@ void make_head_unborn(git_repository* repo, const char *target) { git_reference *head; - cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, target, 1)); + cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, target, 1, NULL, NULL)); git_reference_free(head); } diff --git a/tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789 b/tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789 Binary files differnew file mode 100644 index 000000000..218e9d192 --- /dev/null +++ b/tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789 diff --git a/tests/resources/crlf/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/tests/resources/crlf/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 Binary files differnew file mode 100644 index 000000000..711223894 --- /dev/null +++ b/tests/resources/crlf/.gitted/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/resources/crlf/.gitted/objects/ef/0dcd356d77221e9c27f4f3928ad28e80b87ceb b/tests/resources/crlf/.gitted/objects/ef/0dcd356d77221e9c27f4f3928ad28e80b87ceb Binary files differnew file mode 100644 index 000000000..33aceda12 --- /dev/null +++ b/tests/resources/crlf/.gitted/objects/ef/0dcd356d77221e9c27f4f3928ad28e80b87ceb diff --git a/tests/resources/crlf/.gitted/refs/heads/master b/tests/resources/crlf/.gitted/refs/heads/master index a2dbe0c2d..cfdaaf37b 100644 --- a/tests/resources/crlf/.gitted/refs/heads/master +++ b/tests/resources/crlf/.gitted/refs/heads/master @@ -1 +1 @@ -12faf3c1ea55f572473cec9052fca468c3584ccb +2c9a868cfdf8e270d0ec68164433376c68fb1789 diff --git a/tests/stash/save.c b/tests/stash/save.c index 3d92b26bd..293a89a97 100644 --- a/tests/stash/save.c +++ b/tests/stash/save.c @@ -174,7 +174,7 @@ void test_stash_save__cannot_stash_against_an_unborn_branch(void) { git_reference *head; - cl_git_pass(git_reference_symbolic_create(&head, repo, "HEAD", "refs/heads/unborn", 1)); + cl_git_pass(git_reference_symbolic_create(&head, repo, "HEAD", "refs/heads/unborn", 1, NULL, NULL)); cl_assert_equal_i(GIT_EUNBORNBRANCH, git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT)); diff --git a/tests/submodule/lookup.c b/tests/submodule/lookup.c index 5f320e702..ac3fa0415 100644 --- a/tests/submodule/lookup.c +++ b/tests/submodule/lookup.c @@ -108,7 +108,7 @@ void test_submodule_lookup__lookup_even_with_unborn_head(void) /* put us on an unborn branch */ cl_git_pass(git_reference_symbolic_create( - &head, g_repo, "HEAD", "refs/heads/garbage", 1)); + &head, g_repo, "HEAD", "refs/heads/garbage", 1, NULL, NULL)); git_reference_free(head); /* lookup existing */ diff --git a/tests/threads/refdb.c b/tests/threads/refdb.c index 3c651e341..fbf6ac09b 100644 --- a/tests/threads/refdb.c +++ b/tests/threads/refdb.c @@ -58,7 +58,7 @@ void test_threads_refdb__iterator(void) for (r = 0; r < 200; ++r) { snprintf(name, sizeof(name), "refs/heads/direct-%03d", r); - cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL, NULL)); git_reference_free(ref); } @@ -102,7 +102,7 @@ static void *create_refs(void *arg) for (i = 0; i < 10; ++i) { snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", *id, i); - cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0)); + cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0, NULL, NULL)); if (i == 5) { git_refdb *refdb; @@ -165,7 +165,7 @@ void test_threads_refdb__edit_while_iterate(void) for (r = 0; r < 50; ++r) { snprintf(name, sizeof(name), "refs/heads/starter-%03d", r); - cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL, NULL)); git_reference_free(ref); } |
