Imported Upstream version 0.26.0

This commit is contained in:
Russell Sim 2017-07-29 15:51:23 +02:00
commit 4f895057f3
352 changed files with 10780 additions and 2153 deletions

View File

@ -1,5 +1,5 @@
v0.25 + 1
-------
v0.26 + 1
---------
### Changes or improvements
@ -9,6 +9,102 @@ v0.25 + 1
### Breaking API changes
v0.26
-----
### Changes or improvements
* Support for opening, creating and modifying worktrees.
* We can now detect SHA1 collisions resulting from the SHAttered attack. These
checks can be enabled at build time via `-DUSE_SHA1DC`.
* Fix for missing implementation of `git_merge_driver_source` getters.
* Fix for installed pkg-config file being broken when the prefix contains
spaces.
* We now detect when the hashsum of on-disk objects does not match their
expected hashsum.
* We now support open-ended ranges (e.g. "master..", "...master") in our
revision range parsing code.
* We now correctly compute ignores with leading "/" in subdirectories.
* We now optionally call `fsync` on loose objects, packfiles and their indexes,
loose references and packed reference files.
* We can now build against OpenSSL v1.1 and against LibreSSL.
* `GIT_MERGE_OPTIONS_INIT` now includes a setting to perform rename detection.
This aligns this structure with the default by `git_merge` and
`git_merge_trees` when `NULL` was provided for the options.
* Improvements for reading index v4 files.
* Perform additional retries for filesystem operations on Windows when files
are temporarily locked by other processes.
### API additions
* New family of functions to handle worktrees:
* `git_worktree_list()` lets you look up worktrees for a repository.
* `git_worktree_lookup()` lets you get a specific worktree.
* `git_worktree_open_from_repository()` lets you get the associated worktree
of a repository.
a worktree.
* `git_worktree_add` lets you create new worktrees.
* `git_worktree_prune` lets you remove worktrees from disk.
* `git_worktree_lock()` and `git_worktree_unlock()` let you lock
respectively unlock a worktree.
* `git_repository_open_from_worktree()` lets you open a repository via
* `git_repository_head_for_worktree()` lets you get the current `HEAD` for a
linked worktree.
* `git_repository_head_detached_for_worktree()` lets you check whether a
linked worktree is in detached HEAD mode.
* `git_repository_item_path()` lets you retrieve paths for various repository
files.
* `git_repository_commondir()` lets you retrieve the common directory of a
repository.
* `git_branch_is_checked_out()` allows you to check whether a branch is checked
out in a repository or any of its worktrees.
* `git_repository_submodule_cache_all()` and
`git_repository_submodule_cache_clear()` functions allow you to prime or clear
the submodule cache of a repository.
* You can disable strict hash verifications via the
`GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION` option with `git_libgit2_opts()`.
* You can enable us calling `fsync` for various files inside the ".git"
directory by setting the `GIT_OPT_ENABLE_FSYNC_GITDIR` option with
`git_libgit2_opts()`.
* You can now enable "offset deltas" when creating packfiles and negotiating
packfiles with a remote server by setting `GIT_OPT_ENABLE_OFS_DELTA` option
with `GIT_libgit2_opts()`.
* You can now set the default share mode on Windows for opening files using
`GIT_OPT_SET_WINDOWS_SHAREMODE` option with `git_libgit2_opts()`.
You can query the current share mode with `GIT_OPT_GET_WINDOWS_SHAREMODE`.
* `git_transport_smart_proxy_options()' enables you to get the proxy options for
smart transports.
* The `GIT_FILTER_INIT` macro and the `git_filter_init` function are provided
to initialize a `git_filter` structure.
### Breaking API changes
* `clone_checkout_strategy` has been removed from
`git_submodule_update_option`. The checkout strategy used to clone will
be the same strategy specified in `checkout_opts`.
v0.25
-------
@ -150,7 +246,12 @@ v0.25
If this is `NULL`, then it will not be called and the `exists` function
will be used instead.
* `git_remote_connect()` now accepts proxy options.
* `git_remote_connect()` now accepts `git_proxy_options` argument, and
`git_fetch_options` and `git_push_options` each have a `proxy_opts` field.
* `git_merge_options` now provides a `default_driver` that can be used
to provide the name of a merge driver to be used to handle files changed
during a merge.
v0.24
-------
@ -227,10 +328,6 @@ v0.24
### Breaking API changes
* `git_merge_options` now provides a `default_driver` that can be used
to provide the name of a merge driver to be used to handle files changed
during a merge.
* The `git_merge_tree_flag_t` is now `git_merge_flag_t`. Subsequently,
its members are no longer prefixed with `GIT_MERGE_TREE_FLAG` but are
now prefixed with `GIT_MERGE_FLAG`, and the `tree_flags` field of the

View File

@ -37,6 +37,7 @@ OPTION( PROFILE "Generate profiling information" OFF )
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF )
OPTION( USE_SHA1DC "Use SHA-1 with collision detection" OFF )
OPTION( USE_ICONV "Link with and use iconv library" OFF )
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
OPTION( USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF )
@ -237,8 +238,7 @@ ENDIF()
IF (WIN32 AND WINHTTP)
ADD_DEFINITIONS(-DGIT_WINHTTP)
INCLUDE_DIRECTORIES(deps/http-parser)
FILE(GLOB SRC_HTTP deps/http-parser/*.c deps/http-parser/*.h)
ADD_DEFINITIONS(-DGIT_HTTPS)
# Since MinGW does not come with headers or an import library for winhttp,
# we have to include a private header and generate our own import library
@ -291,27 +291,22 @@ ELSE ()
LINK_LIBRARIES(${CURL_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
ENDIF()
FIND_PACKAGE(HTTP_Parser)
IF (HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
INCLUDE_DIRECTORIES(${HTTP_PARSER_INCLUDE_DIRS})
LINK_LIBRARIES(${HTTP_PARSER_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS "-lhttp_parser")
ELSE()
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()
ENDIF()
# Specify sha1 implementation
IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin")
ADD_DEFINITIONS(-DWIN32_SHA1)
IF (USE_SHA1DC)
ADD_DEFINITIONS(-DGIT_SHA1_COLLISIONDETECT)
ADD_DEFINITIONS(-DSHA1DC_NO_STANDARD_INCLUDES=1)
ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\")
ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\")
FILE(GLOB SRC_SHA1 src/hash/hash_collisiondetect.c src/hash/sha1dc/*)
ELSEIF (WIN32 AND NOT MINGW)
ADD_DEFINITIONS(-DGIT_SHA1_WIN32)
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
ADD_DEFINITIONS(-DGIT_COMMON_CRYPTO)
ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin")
ADD_DEFINITIONS(-DOPENSSL_SHA1)
ADD_DEFINITIONS(-DGIT_SHA1_COMMON_CRYPTO)
ELSEIF (OPENSSL_FOUND)
ADD_DEFINITIONS(-DGIT_SHA1_OPENSSL)
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
LIST(APPEND LIBGIT2_PC_LIBS "-lssl")
ELSE()
@ -332,6 +327,18 @@ IF(WIN32 OR AMIGA OR CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
SET(SRC_REGEX deps/regex/regex.c)
ENDIF()
# Optional external dependency: http-parser
FIND_PACKAGE(HTTP_Parser)
IF (HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
INCLUDE_DIRECTORIES(${HTTP_PARSER_INCLUDE_DIRS})
LINK_LIBRARIES(${HTTP_PARSER_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS "-lhttp_parser")
ELSE()
MESSAGE(STATUS "http-parser version 2 was not found; using bundled 3rd-party sources.")
INCLUDE_DIRECTORIES(deps/http-parser)
FILE(GLOB SRC_HTTP deps/http-parser/*.c deps/http-parser/*.h)
ENDIF()
# Optional external dependency: zlib
FIND_PACKAGE(ZLIB)
IF (ZLIB_FOUND)
@ -461,19 +468,17 @@ IF (MSVC)
SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}")
SET(WIN_RC "src/win32/git2.rc")
# Precompiled headers
ELSE ()
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -Wall -Wextra ${CMAKE_C_FLAGS}")
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}")
ADD_C_FLAG_IF_SUPPORTED(-Wall)
ADD_C_FLAG_IF_SUPPORTED(-Wextra)
IF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
SET(CMAKE_C_FLAGS "-std=c99 -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}")
ENDIF()
IF (WIN32 AND NOT CYGWIN)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
ENDIF ()
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -O0")
IF (MINGW OR MSYS) # MinGW and MSYS always do PIC and complain if we tell them to
STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
@ -540,11 +545,13 @@ ENDIF()
IF (SECURITY_FOUND)
ADD_DEFINITIONS(-DGIT_SECURE_TRANSPORT)
ADD_DEFINITIONS(-DGIT_HTTPS)
INCLUDE_DIRECTORIES(${SECURITY_INCLUDE_DIR})
ENDIF ()
IF (OPENSSL_FOUND)
ADD_DEFINITIONS(-DGIT_OPENSSL)
ADD_DEFINITIONS(-DGIT_HTTPS)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
ENDIF()
@ -697,9 +704,9 @@ IF (BUILD_CLAR)
ENABLE_TESTING()
IF (WINHTTP OR OPENSSL_FOUND OR SECURITY_FOUND)
ADD_TEST(libgit2_clar libgit2_clar -ionline)
ADD_TEST(libgit2_clar libgit2_clar -ionline -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
ELSE ()
ADD_TEST(libgit2_clar libgit2_clar -v)
ADD_TEST(libgit2_clar libgit2_clar -v -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
ENDIF ()
# Add a test target which runs the cred callback tests, to be

View File

@ -18,11 +18,11 @@ other's toes.
- If a function returns an object as a return value, that function is
a getter and the object's lifetime is tied to the parent
object. Objects which are returned as the first argument as a
pointer-to-pointer are owned by the caller and it is repsponsible
pointer-to-pointer are owned by the caller and it is responsible
for freeing it. Strings are returned via `git_buf` in order to
allow for re-use and safe freeing.
- Most of what libgit2 does relates to I/O so you as a general rule
- Most of what libgit2 does relates to I/O so as a general rule
you should assume that any function can fail due to errors as even
getting data from the filesystem can result in all sorts of errors
and complex failure cases.

33
COPYING
View File

@ -958,3 +958,36 @@ necessary. Here is a sample; alter the names:
That's all there is to it!
----------------------------------------------------------------------
The bundled SHA1 collision detection code is licensed under the MIT license:
MIT License
Copyright (c) 2017:
Marc Stevens
Cryptology Group
Centrum Wiskunde & Informatica
P.O. Box 94079, 1090 GB Amsterdam, Netherlands
marc@marc-stevens.nl
Dan Shumow
Microsoft Research
danshu@microsoft.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -43,10 +43,9 @@ We ask that you not open a GitHub Issue for help, only for bug reports.
What It Can Do
==============
The goal of this library is to allow its users the ability to handle Git data in
their applications from their programming language of choice, as is used in
production for many applications including the GitHub.com site, in Plastic SCM
and also powering Microsoft's Visual Studio tools for Git.
libgit2 provides you with the ability to manage Git repositories in the
programming language of your choice. It's used in production to power many
applications including GitHub.com, Plastic SCM and Visual Studio Team Services.
It does not aim to replace the git tool or its user-facing commands. Some APIs
resemble the plumbing commands as those align closely with the concepts of the
@ -68,6 +67,16 @@ The library provides:
* descriptive and detailed error messages
* ...and more (over 175 different API calls)
As libgit2 is purely a consumer of the Git system, we have to
adjust to changes made upstream. This has two major consequences:
* Some changes may require us to change provided interfaces. While we try to
implement functions in a generic way so that no future changes are required,
we cannot promise a completely stable API.
* As we have to keep up with changes in behavior made upstream, we may lag
behind in some areas. We usually to document these incompatibilities in our
issue tracker with the label "git change".
Optional dependencies
=====================
@ -124,6 +133,14 @@ On most systems you can build the library using the following commands
Alternatively you can point the CMake GUI tool to the CMakeLists.txt file and generate platform specific build project or IDE workspace.
Once built, you can run the tests from the `build` directory with the command
$ make test
Alternatively you can run the test suite directly using,
$ ./libgit2_clar
To install the library you can specify the install prefix by setting:
$ cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix

View File

@ -2,6 +2,7 @@ version: '{build}'
branches:
only:
- master
- appveyor
- /^maint.*/
environment:
GITTEST_INVASIVE_FS_STRUCTURE: 1

View File

@ -57,7 +57,7 @@ static void blob_parsing(git_repository *repo);
static void revwalking(git_repository *repo);
static void index_walking(git_repository *repo);
static void reference_listing(git_repository *repo);
static void config_files(const char *repo_path);
static void config_files(const char *repo_path, git_repository *repo);
/**
* Almost all libgit2 functions return 0 on success or negative on error.
@ -115,7 +115,7 @@ int main (int argc, char** argv)
revwalking(repo);
index_walking(repo);
reference_listing(repo);
config_files(repo_path);
config_files(repo_path, repo);
/**
* Finally, when you're done with the repository, you can free it as well.
@ -247,6 +247,11 @@ static void object_database(git_repository *repo, git_oid *oid)
*/
git_oid_fmt(oid_hex, oid);
printf("Written Object: %s\n", oid_hex);
/**
* Free the object database after usage.
*/
git_odb_free(odb);
}
/**
@ -264,7 +269,7 @@ static void commit_writing(git_repository *repo)
git_oid tree_id, parent_id, commit_id;
git_tree *tree;
git_commit *parent;
const git_signature *author, *cmtter;
git_signature *author, *committer;
char oid_hex[GIT_OID_HEXSZ+1] = { 0 };
printf("\n*Commit Writing*\n");
@ -276,9 +281,9 @@ static void commit_writing(git_repository *repo)
* `user.email` configuration options. See the `config` section of this
* example file to see how to access config values.
*/
git_signature_new((git_signature **)&author,
git_signature_new(&author,
"Scott Chacon", "schacon@gmail.com", 123456789, 60);
git_signature_new((git_signature **)&cmtter,
git_signature_new(&committer,
"Scott A Chacon", "scott@github.com", 987654321, 90);
/**
@ -301,7 +306,7 @@ static void commit_writing(git_repository *repo)
repo,
NULL, /* do not update the HEAD */
author,
cmtter,
committer,
NULL, /* use default message encoding */
"example commit",
tree,
@ -312,6 +317,14 @@ static void commit_writing(git_repository *repo)
*/
git_oid_fmt(oid_hex, &commit_id);
printf("New Commit: %s\n", oid_hex);
/**
* Free all objects used in the meanwhile.
*/
git_tree_free(tree);
git_commit_free(parent);
git_signature_free(author);
git_signature_free(committer);
}
/**
@ -431,7 +444,11 @@ static void tag_parsing(git_repository *repo)
printf("Tag Name: %s\nTag Type: %s\nTag Message: %s\n",
name, git_object_type2string(type), message);
/**
* Free both the commit and tag after usage.
*/
git_commit_free(commit);
git_tag_free(tag);
}
/**
@ -485,9 +502,10 @@ static void tree_parsing(git_repository *repo)
git_tree_entry_to_object(&obj, repo, entry); /* blob */
/**
* Remember to close the looked-up object once you are done using it
* Remember to close the looked-up object and tree once you are done using it
*/
git_object_free(obj);
git_tree_free(tree);
}
/**
@ -522,6 +540,11 @@ static void blob_parsing(git_repository *repo)
* */
printf("Blob Size: %ld\n", (long)git_blob_rawsize(blob)); /* 8 */
git_blob_rawcontent(blob); /* "content" */
/**
* Free the blob after usage.
*/
git_blob_free(blob);
}
/**
@ -644,10 +667,7 @@ static void index_walking(git_repository *repo)
static void reference_listing(git_repository *repo)
{
git_strarray ref_list;
const char *refname;
git_reference *ref;
unsigned i;
char oid_hex[GIT_OID_HEXSZ+1];
printf("\n*Reference Listing*\n");
@ -662,7 +682,10 @@ static void reference_listing(git_repository *repo)
git_reference_list(&ref_list, repo);
for (i = 0; i < ref_list.count; ++i) {
memset(oid_hex, 0, sizeof(oid_hex));
git_reference *ref;
char oid_hex[GIT_OID_HEXSZ+1] = GIT_OID_HEX_ZERO;
const char *refname;
refname = ref_list.strings[i];
git_reference_lookup(&ref, repo, refname);
@ -679,6 +702,8 @@ static void reference_listing(git_repository *repo)
fprintf(stderr, "Unexpected reference type\n");
exit(1);
}
git_reference_free(ref);
}
git_strarray_free(&ref_list);
@ -692,12 +717,13 @@ static void reference_listing(git_repository *repo)
*
* [config]: http://libgit2.github.com/libgit2/#HEAD/group/config
*/
static void config_files(const char *repo_path)
static void config_files(const char *repo_path, git_repository* repo)
{
const char *email;
char config_path[256];
int32_t j;
int32_t autocorrect;
git_config *cfg;
git_config *snap_cfg;
printf("\n*Config Listing*\n");
@ -707,9 +733,16 @@ static void config_files(const char *repo_path)
sprintf(config_path, "%s/config", repo_path);
check_error(git_config_open_ondisk(&cfg, config_path), "opening config");
git_config_get_int32(&j, cfg, "help.autocorrect");
printf("Autocorrect: %d\n", j);
if (git_config_get_int32(&autocorrect, cfg, "help.autocorrect") == 0)
printf("Autocorrect: %d\n", autocorrect);
git_config_get_string(&email, cfg, "user.email");
check_error(git_repository_config_snapshot(&snap_cfg, repo), "config snapshot");
git_config_get_string(&email, snap_cfg, "user.email");
printf("Email: %s\n", email);
/**
* Remember to free the configurations after usage.
*/
git_config_free(cfg);
git_config_free(snap_cfg);
}

View File

@ -50,7 +50,7 @@ static int sideband_progress(const char *str, int len, void *payload)
{
(void)payload; // unused
printf("remote: %*s", len, str);
printf("remote: %.*s", len, str);
fflush(stdout);
return 0;
}

View File

@ -1,5 +1,7 @@
#include "common.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* Shamelessly borrowed from http://stackoverflow.com/questions/3417837/
* with permission of the original author, Martin Pool.
@ -20,15 +22,27 @@ int cred_acquire_cb(git_cred **out,
unsigned int UNUSED(allowed_types),
void * UNUSED(payload))
{
char username[128] = {0};
char password[128] = {0};
char *username = NULL, *password = NULL;
int error;
printf("Username: ");
scanf("%s", username);
if (getline(&username, NULL, stdin) < 0) {
fprintf(stderr, "Unable to read username: %s", strerror(errno));
return -1;
}
/* Yup. Right there on your terminal. Careful where you copy/paste output. */
printf("Password: ");
scanf("%s", password);
if (getline(&password, NULL, stdin) < 0) {
fprintf(stderr, "Unable to read password: %s", strerror(errno));
free(username);
return -1;
}
return git_cred_userpass_plaintext_new(out, username, password);
error = git_cred_userpass_plaintext_new(out, username, password);
free(username);
free(password);
return error;
}

View File

@ -245,6 +245,18 @@ GIT_EXTERN(int) git_branch_upstream_name(
GIT_EXTERN(int) git_branch_is_head(
const git_reference *branch);
/**
* Determine if the current branch is checked out in any linked
* repository.
*
* @param branch Reference to the branch.
*
* @return 1 if branch is checked out, 0 if it isn't,
* error code otherwise.
*/
GIT_EXTERN(int) git_branch_is_checked_out(
const git_reference *branch);
/**
* Return the name of remote that the remote tracking branch belongs to.
*

View File

@ -255,7 +255,8 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
/**
* Get an arbitrary header field
*
* @param out the buffer to fill
* @param out the buffer to fill; existing content will be
* overwritten
* @param commit the commit to look in
* @param field the header field to return
* @return 0 on succeess, GIT_ENOTFOUND if the field does not exist,
@ -270,8 +271,10 @@ GIT_EXTERN(int) git_commit_header_field(git_buf *out, const git_commit *commit,
* `GITERR_INVALID`. If the commit does not have a signature, the
* error class will be `GITERR_OBJECT`.
*
* @param signature the signature block
* @param signed_data signed data; this is the commit contents minus the signature block
* @param signature the signature block; existing content will be
* overwritten
* @param signed_data signed data; this is the commit contents minus the signature block;
* existing content will be overwritten
* @param repo the repository in which the commit exists
* @param commit_id the commit from which to extract the data
* @param field the name of the header field containing the signature

View File

@ -175,8 +175,14 @@ typedef enum {
GIT_OPT_SET_SSL_CERT_LOCATIONS,
GIT_OPT_SET_USER_AGENT,
GIT_OPT_ENABLE_STRICT_OBJECT_CREATION,
GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION,
GIT_OPT_SET_SSL_CIPHERS,
GIT_OPT_GET_USER_AGENT,
GIT_OPT_ENABLE_OFS_DELTA,
GIT_OPT_ENABLE_FSYNC_GITDIR,
GIT_OPT_GET_WINDOWS_SHAREMODE,
GIT_OPT_SET_WINDOWS_SHAREMODE,
GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION,
} git_libgit2_opt_t;
/**
@ -281,6 +287,17 @@ typedef enum {
* > - `user_agent` is the value that will be delivered as the
* > User-Agent header on HTTP requests.
*
* * opts(GIT_OPT_SET_WINDOWS_SHAREMODE, unsigned long value)
*
* > Set the share mode used when opening files on Windows.
* > For more information, see the documentation for CreateFile.
* > The default is: FILE_SHARE_READ | FILE_SHARE_WRITE. This is
* > ignored and unused on non-Windows platforms.
*
* * opts(GIT_OPT_GET_WINDOWS_SHAREMODE, unsigned long *value)
*
* > Get the share mode used when opening files on Windows.
*
* * opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, int enabled)
*
* > Enable strict input validation when creating new objects
@ -289,12 +306,45 @@ typedef enum {
* > will be validated when creating a new commit. This defaults
* > to enabled.
*
* * opts(GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION, int enabled)
*
* > Validate the target of a symbolic ref when creating it. For
* > example, `foobar` is not a valid ref, therefore `foobar` is
* > not a valid target for a symbolic ref by default, whereas
* > `refs/heads/foobar` is. Disabling this bypasses validation
* > so that an arbitrary strings such as `foobar` can be used
* > for a symbolic ref target. This defaults to enabled.
*
* * opts(GIT_OPT_SET_SSL_CIPHERS, const char *ciphers)
*
* > Set the SSL ciphers use for HTTPS connections.
* >
* > - `ciphers` is the list of ciphers that are eanbled.
*
* * opts(GIT_OPT_ENABLE_OFS_DELTA, int enabled)
*
* > Enable or disable the use of "offset deltas" when creating packfiles,
* > and the negotiation of them when talking to a remote server.
* > Offset deltas store a delta base location as an offset into the
* > packfile from the current location, which provides a shorter encoding
* > and thus smaller resultant packfiles.
* > Packfiles containing offset deltas can still be read.
* > This defaults to enabled.
*
* * opts(GIT_OPT_ENABLE_FSYNC_GITDIR, int enabled)
*
* > Enable synchronized writes of files in the gitdir using `fsync`
* > (or the platform equivalent) to ensure that new object data
* > is written to permanent storage, not simply cached. This
* > defaults to disabled.
*
* opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, int enabled)
*
* > Enable strict verification of object hashsums when reading
* > objects from disk. This may impact performance due to an
* > additional checksum calculation on each object. This defaults
* > to enabled.
*
* @param option Option key
* @param ... value to set the option
* @return 0 on success, <0 on failure

View File

@ -53,6 +53,8 @@ typedef enum {
GIT_PASSTHROUGH = -30, /**< Internal only */
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
GIT_RETRY = -32, /**< Internal only */
GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */
} git_error_code;
/**
@ -100,6 +102,8 @@ typedef enum {
GITERR_REBASE,
GITERR_FILESYSTEM,
GITERR_PATCH,
GITERR_WORKTREE,
GITERR_SHA1
} git_error_t;
/**

View File

@ -14,7 +14,7 @@ GIT_BEGIN_DECL
/**
* Init the global state
*
* This function must the called before any other libgit2 function in
* This function must be called before any other libgit2 function in
* order to set up global state and threading.
*
* This function may be called multiple times - it will return the number

View File

@ -575,15 +575,16 @@ GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
* This method will fail in bare index instances.
*
* The `pathspec` is a list of file names or shell glob patterns that will
* matched against files in the repository's working directory. Each file
* that matches will be added to the index (either updating an existing
* entry or adding a new entry). You can disable glob expansion and force
* exact matching with the `GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH` flag.
* be matched against files in the repository's working directory. Each
* file that matches will be added to the index (either updating an
* existing entry or adding a new entry). You can disable glob expansion
* and force exact matching with the `GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH`
* flag.
*
* Files that are ignored will be skipped (unlike `git_index_add_bypath`).
* If a file is already tracked in the index, then it *will* be updated
* even if it is ignored. Pass the `GIT_INDEX_ADD_FORCE` flag to
* skip the checking of ignore rules.
* even if it is ignored. Pass the `GIT_INDEX_ADD_FORCE` flag to skip
* the checking of ignore rules.
*
* To emulate `git add -A` and generate an error if the pathspec contains
* the exact path of an ignored file (when not using FORCE), add the

View File

@ -290,7 +290,8 @@ typedef struct {
} git_merge_options;
#define GIT_MERGE_OPTIONS_VERSION 1
#define GIT_MERGE_OPTIONS_INIT {GIT_MERGE_OPTIONS_VERSION}
#define GIT_MERGE_OPTIONS_INIT { \
GIT_MERGE_OPTIONS_VERSION, GIT_MERGE_FIND_RENAMES }
/**
* Initializes a `git_merge_options` with default values. Equivalent to

View File

@ -488,7 +488,7 @@ GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object);
* The backends are checked in relative ordering, based on the
* value of the `priority` parameter.
*
* Read <odb_backends.h> for more information.
* Read <sys/odb_backend.h> for more information.
*
* @param odb database to add the backend to
* @param backend pointer to a git_odb_backend instance
@ -509,7 +509,7 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int
*
* Writing is disabled on alternate backends.
*
* Read <odb_backends.h> for more information.
* Read <sys/odb_backend.h> for more information.
*
* @param odb database to add the backend to
* @param backend pointer to a git_odb_backend instance

View File

@ -39,7 +39,7 @@ GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_
* @param out location to store the odb backend pointer
* @param objects_dir the Git repository's objects directory
* @param compression_level zlib compression level to use
* @param do_fsync whether to do an fsync() after writing (currently ignored)
* @param do_fsync whether to do an fsync() after writing
* @param dir_mode permissions to use creating a directory or 0 for defaults
* @param file_mode permissions to use creating a file or 0 for defaults
*

View File

@ -50,17 +50,16 @@ GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
* Parse a hex formatted null-terminated string into a git_oid.
*
* @param out oid structure the result is written into.
* @param str input hex string; must be at least 4 characters
* long and null-terminated.
* @param str input hex string; must be null-terminated.
* @return 0 or an error code
*/
GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str);
/**
* Parse N characters of a hex formatted object id into a git_oid
* Parse N characters of a hex formatted object id into a git_oid.
*
* If N is odd, N-1 characters will be parsed instead.
* The remaining space in the git_oid will be set to zero.
* If N is odd, the last byte's high nibble will be read in and the
* low nibble set to zero.
*
* @param out oid structure the result is written into.
* @param str input hex string of at least size `length`

View File

@ -715,8 +715,8 @@ GIT_EXTERN(int) git_remote_prune(git_remote *remote, const git_remote_callbacks
* Peform all the steps from a push.
*
* @param remote the remote to push to
* @param refspecs the refspecs to use for pushing. If none are
* passed, the configured refspecs will be used
* @param refspecs the refspecs to use for pushing. If NULL or an empty
* array, the configured refspecs will be used
* @param opts options to use for this push
*/
GIT_EXTERN(int) git_remote_push(git_remote *remote,
@ -796,7 +796,7 @@ GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
* for the remote will be removed.
*
* @param repo the repository in which to act
* @param name the name of the remove to delete
* @param name the name of the remote to delete
* @return 0 on success, or an error code.
*/
GIT_EXTERN(int) git_remote_delete(git_repository *repo, const char *name);

View File

@ -35,6 +35,17 @@ GIT_BEGIN_DECL
* @return 0 or an error code
*/
GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
/**
* Open working tree as a repository
*
* Open the working directory of the working tree as a normal
* repository that can then be worked on.
*
* @param out Output pointer containing opened repository
* @param wt Working tree to open
* @return 0 or an error code
*/
GIT_EXTERN(int) git_repository_open_from_worktree(git_repository **out, git_worktree *wt);
/**
* Create a "fake" repository to wrap an object database
@ -334,6 +345,17 @@ GIT_EXTERN(int) git_repository_init_ext(
*/
GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
/**
* Retrieve the referenced HEAD for the worktree
*
* @param out pointer to the reference which will be retrieved
* @param repo a repository object
* @param name name of the worktree to retrieve HEAD for
* @return 0 when successful, error-code otherwise
*/
GIT_EXTERN(int) git_repository_head_for_worktree(git_reference **out, git_repository *repo,
const char *name);
/**
* Check if a repository's HEAD is detached
*
@ -346,6 +368,20 @@ GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
*/
GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
/*
* Check if a worktree's HEAD is detached
*
* A worktree's HEAD is detached when it points directly to a
* commit instead of a branch.
*
* @param repo a repository object
* @param name name of the worktree to retrieve HEAD for
* @return 1 if HEAD is detached, 0 if its not; error code if
* there was an error
*/
GIT_EXTERN(int) git_repository_head_detached_for_worktree(git_repository *repo,
const char *name);
/**
* Check if the current branch is unborn
*
@ -370,6 +406,42 @@ GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo);
*/
GIT_EXTERN(int) git_repository_is_empty(git_repository *repo);
/**
* List of items which belong to the git repository layout
*/
typedef enum {
GIT_REPOSITORY_ITEM_GITDIR,
GIT_REPOSITORY_ITEM_WORKDIR,
GIT_REPOSITORY_ITEM_COMMONDIR,
GIT_REPOSITORY_ITEM_INDEX,
GIT_REPOSITORY_ITEM_OBJECTS,
GIT_REPOSITORY_ITEM_REFS,
GIT_REPOSITORY_ITEM_PACKED_REFS,
GIT_REPOSITORY_ITEM_REMOTES,
GIT_REPOSITORY_ITEM_CONFIG,
GIT_REPOSITORY_ITEM_INFO,
GIT_REPOSITORY_ITEM_HOOKS,
GIT_REPOSITORY_ITEM_LOGS,
GIT_REPOSITORY_ITEM_MODULES,
GIT_REPOSITORY_ITEM_WORKTREES
} git_repository_item_t;
/**
* Get the location of a specific repository file or directory
*
* This function will retrieve the path of a specific repository
* item. It will thereby honor things like the repository's
* common directory, gitdir, etc. In case a file path cannot
* exist for a given item (e.g. the working directory of a bare
* repository), GIT_ENOTFOUND is returned.
*
* @param out Buffer to store the path at
* @param repo Repository to get path for
* @param item The repository item for which to retrieve the path
* @return 0, GIT_ENOTFOUND if the path cannot exist or an error code
*/
GIT_EXTERN(int) git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item);
/**
* Get the path of this repository
*
@ -392,6 +464,17 @@ GIT_EXTERN(const char *) git_repository_path(git_repository *repo);
*/
GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
/**
* Get the path of the shared common directory for this repository
*
* If the repository is bare is not a worktree, the git directory
* path is returned.
*
* @param repo A repository object
* @return the path to the common dir
*/
GIT_EXTERN(const char *) git_repository_commondir(git_repository *repo);
/**
* Set the path to the working directory for this repository
*
@ -420,6 +503,14 @@ GIT_EXTERN(int) git_repository_set_workdir(
*/
GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
/**
* Check if a repository is a linked work tree
*
* @param repo Repo to test
* @return 1 if the repository is a linked work tree, 0 otherwise.
*/
GIT_EXTERN(int) git_repository_is_worktree(git_repository *repo);
/**
* Get the configuration file for this repository.
*

View File

@ -53,7 +53,7 @@ typedef enum {
*
* @param reset_type Kind of reset operation to perform.
*
* @param checkout_opts Checkout options to be used for a HARD reset.
* @param checkout_opts Optional checkout options to be used for a HARD reset.
* The checkout_strategy field will be overridden (based on reset_type).
* This parameter can be used to propagate notify and progress callbacks.
*

View File

@ -75,7 +75,7 @@ GIT_EXTERN(int) git_revert_commit(
*
* @param repo the repository to revert
* @param commit the commit to revert
* @param given_opts merge flags
* @param given_opts the revert options (or null for defaults)
* @return zero on success, -1 on failure.
*/
GIT_EXTERN(int) git_revert(

View File

@ -173,7 +173,7 @@ GIT_EXTERN(int) git_stash_apply_init_options(
* @param repo The owning repository.
* @param index The position within the stash list. 0 points to the
* most recent stashed state.
* @param options Options to control how stashes are applied.
* @param options Optional options to control how stashes are applied.
*
* @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the
* given index, GIT_EMERGECONFLICT if changes exist in the working
@ -242,7 +242,7 @@ GIT_EXTERN(int) git_stash_drop(
* @param repo The owning repository.
* @param index The position within the stash list. 0 points to the
* most recent stashed state.
* @param options Options to control how stashes are applied.
* @param options Optional options to control how stashes are applied.
*
* @return 0 on success, GIT_ENOTFOUND if there's no stashed state for the given
* index, or error code. (see git_stash_apply() above for details)

View File

@ -134,9 +134,7 @@ typedef struct git_submodule_update_options {
* checkout, set the `checkout_strategy` to
* `GIT_CHECKOUT_NONE`. Generally you will want the use
* GIT_CHECKOUT_SAFE to update files in the working
* directory. Use the `clone_checkout_strategy` field
* to set the checkout strategy that will be used in
* the case where update needs to clone the repository.
* directory.
*/
git_checkout_options checkout_opts;
@ -148,13 +146,6 @@ typedef struct git_submodule_update_options {
*/
git_fetch_options fetch_opts;
/**
* The checkout strategy to use when the sub repository needs to
* be cloned. Use GIT_CHECKOUT_SAFE to create all files
* in the working directory for the newly cloned repository.
*/
unsigned int clone_checkout_strategy;
/**
* Allow fetching from the submodule's default remote if the target
* commit isn't found. Enabled by default.
@ -166,7 +157,7 @@ typedef struct git_submodule_update_options {
#define GIT_SUBMODULE_UPDATE_OPTIONS_INIT \
{ GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, \
{ GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE }, \
GIT_FETCH_OPTIONS_INIT, GIT_CHECKOUT_SAFE, 1 }
GIT_FETCH_OPTIONS_INIT, 1 }
/**
* Initializes a `git_submodule_update_options` with default values.

View File

@ -271,6 +271,17 @@ struct git_filter {
};
#define GIT_FILTER_VERSION 1
#define GIT_FILTER_INIT {GIT_FILTER_VERSION}
/**
* Initializes a `git_filter` with default values. Equivalent to
* creating an instance with GIT_FILTER_INIT.
*
* @param filter the `git_filter` struct to initialize.
* @param version Version the struct; pass `GIT_FILTER_VERSION`
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN(int) git_filter_init(git_filter *filter, unsigned int version);
/**
* Register a filter under a given name with a given priority.

View File

@ -36,23 +36,23 @@ GIT_EXTERN(git_merge_driver *) git_merge_driver_lookup(const char *name);
typedef struct git_merge_driver_source git_merge_driver_source;
/** Get the repository that the source data is coming from. */
GIT_EXTERN(git_repository *) git_merge_driver_source_repo(
GIT_EXTERN(const git_repository *) git_merge_driver_source_repo(
const git_merge_driver_source *src);
/** Gets the ancestor of the file to merge. */
GIT_EXTERN(git_index_entry *) git_merge_driver_source_ancestor(
GIT_EXTERN(const git_index_entry *) git_merge_driver_source_ancestor(
const git_merge_driver_source *src);
/** Gets the ours side of the file to merge. */
GIT_EXTERN(git_index_entry *) git_merge_driver_source_ours(
GIT_EXTERN(const git_index_entry *) git_merge_driver_source_ours(
const git_merge_driver_source *src);
/** Gets the theirs side of the file to merge. */
GIT_EXTERN(git_index_entry *) git_merge_driver_source_theirs(
GIT_EXTERN(const git_index_entry *) git_merge_driver_source_theirs(
const git_merge_driver_source *src);
/** Gets the merge file options that the merge was invoked with */
GIT_EXTERN(git_merge_file_options *) git_merge_driver_source_file_options(
GIT_EXTERN(const git_merge_file_options *) git_merge_driver_source_file_options(
const git_merge_driver_source *src);

View File

@ -135,6 +135,35 @@ GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index
*/
GIT_EXTERN(int) git_repository_set_bare(git_repository *repo);
/**
* Load and cache all submodules.
*
* Because the `.gitmodules` file is unstructured, loading submodules is an
* O(N) operation. Any operation (such as `git_rebase_init`) that requires
* accessing all submodules is O(N^2) in the number of submodules, if it
* has to look each one up individually. This function loads all submodules
* and caches them so that subsequent calls to `git_submodule_lookup` are O(1).
*
* @param repo the repository whose submodules will be cached.
*/
GIT_EXTERN(int) git_repository_submodule_cache_all(
git_repository *repo);
/**
* Clear the submodule cache.
*
* Clear the submodule cache populated by `git_repository_submodule_cache_all`.
* If there is no cache, do nothing.
*
* The cache incorporates data from the repository's configuration, as well
* as the state of the working tree, the index, and HEAD. So any time any
* of these has changed, the cache might become invalid.
*
* @param repo the repository whose submodule cache will be cleared
*/
GIT_EXTERN(int) git_repository_submodule_cache_clear(
git_repository *repo);
/** @} */
GIT_END_DECL
#endif

View File

@ -241,6 +241,16 @@ GIT_EXTERN(int) git_transport_smart_certificate_check(git_transport *transport,
*/
GIT_EXTERN(int) git_transport_smart_credentials(git_cred **out, git_transport *transport, const char *user, int methods);
/**
* Get a copy of the proxy options
*
* The url is copied and must be freed by the caller.
*
* @param out options struct to fill
* @param transport the transport to extract the data from.
*/
GIT_EXTERN(int) git_transport_smart_proxy_options(git_proxy_options *out, git_transport *transport);
/*
*** End of base transport interface ***
*** Begin interface for subtransports for the smart transport ***

View File

@ -321,13 +321,13 @@ GIT_EXTERN(void) git_cred_free(git_cred *cred);
/**
* Signature of a function which acquires a credential object.
*
* - cred: The newly created credential object.
* - url: The resource for which we are demanding a credential.
* - username_from_url: The username that was embedded in a "user\@host"
* @param cred The newly created credential object.
* @param url The resource for which we are demanding a credential.
* @param username_from_url The username that was embedded in a "user\@host"
* remote url, or NULL if not included.
* - allowed_types: A bitmask stating which cred types are OK to return.
* - payload: The payload provided when specifying this callback.
* - returns 0 for success, < 0 to indicate an error, > 0 to indicate
* @param allowed_types A bitmask stating which cred types are OK to return.
* @param payload The payload provided when specifying this callback.
* @return 0 for success, < 0 to indicate an error, > 0 to indicate
* no credential was acquired
*/
typedef int (*git_cred_acquire_cb)(

View File

@ -375,6 +375,19 @@ GIT_EXTERN(void) git_treebuilder_filter(
GIT_EXTERN(int) git_treebuilder_write(
git_oid *id, git_treebuilder *bld);
/**
* Write the contents of the tree builder as a tree object
* using a shared git_buf.
*
* @see git_treebuilder_write
*
* @param oid Pointer to store the OID of the newly written tree
* @param bld Tree builder to write
* @param tree Shared buffer for writing the tree. Will be grown as necessary.
* @return 0 or an error code
*/
GIT_EXTERN(int) git_treebuilder_write_with_buffer(
git_oid *oid, git_treebuilder *bld, git_buf *tree);
/** Callback for the tree traversal method */
typedef int (*git_treewalk_cb)(

View File

@ -104,6 +104,9 @@ typedef struct git_refdb_backend git_refdb_backend;
*/
typedef struct git_repository git_repository;
/** Representation of a working tree */
typedef struct git_worktree git_worktree;
/** Representation of a generic object in a repository */
typedef struct git_object git_object;

View File

@ -7,12 +7,12 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
#define LIBGIT2_VERSION "0.25.1"
#define LIBGIT2_VERSION "0.26.0"
#define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 25
#define LIBGIT2_VER_REVISION 1
#define LIBGIT2_VER_MINOR 26
#define LIBGIT2_VER_REVISION 0
#define LIBGIT2_VER_PATCH 0
#define LIBGIT2_SOVERSION 25
#define LIBGIT2_SOVERSION 26
#endif

220
include/git2/worktree.h Normal file
View File

@ -0,0 +1,220 @@
/*
* 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_git_worktree_h__
#define INCLUDE_git_worktree_h__
#include "common.h"
#include "buffer.h"
#include "types.h"
#include "strarray.h"
/**
* @file git2/worktrees.h
* @brief Git worktree related functions
* @defgroup git_commit Git worktree related functions
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/**
* List names of linked working trees
*
* The returned list should be released with `git_strarray_free`
* when no longer needed.
*
* @param out pointer to the array of working tree names
* @param repo the repo to use when listing working trees
* @return 0 or an error code
*/
GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo);
/**
* Lookup a working tree by its name for a given repository
*
* @param out Output pointer to looked up worktree or `NULL`
* @param repo The repository containing worktrees
* @param name Name of the working tree to look up
* @return 0 or an error code
*/
GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name);
/**
* Open a worktree of a given repository
*
* If a repository is not the main tree but a worktree, this
* function will look up the worktree inside the parent
* repository and create a new `git_worktree` structure.
*
* @param out Out-pointer for the newly allocated worktree
* @param repo Repository to look up worktree for
*/
GIT_EXTERN(int) git_worktree_open_from_repository(git_worktree **out, git_repository *repo);
/**
* Free a previously allocated worktree
*
* @param wt worktree handle to close. If NULL nothing occurs.
*/
GIT_EXTERN(void) git_worktree_free(git_worktree *wt);
/**
* Check if worktree is valid
*
* A valid worktree requires both the git data structures inside
* the linked parent repository and the linked working copy to be
* present.
*
* @param wt Worktree to check
* @return 0 when worktree is valid, error-code otherwise
*/
GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt);
typedef struct git_worktree_add_options {
unsigned int version;
int lock; /**< lock newly created worktree */
} git_worktree_add_options;
#define GIT_WORKTREE_ADD_OPTIONS_VERSION 1
#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0}
/**
* Initializes a `git_worktree_add_options` with default vaules.
* Equivalent to creating an instance with
* GIT_WORKTREE_ADD_OPTIONS_INIT.
*
* @param opts the struct to initialize
* @param version Verison of struct; pass `GIT_WORKTREE_ADD_OPTIONS_VERSION`
* @return Zero on success; -1 on failure.
*/
int git_worktree_add_init_options(git_worktree_add_options *opts,
unsigned int version);
/**
* Add a new working tree
*
* Add a new working tree for the repository, that is create the
* required data structures inside the repository and check out
* the current HEAD at `path`
*
* @param out Output pointer containing new working tree
* @param repo Repository to create working tree for
* @param name Name of the working tree
* @param path Path to create working tree at
* @param opts Options to modify default behavior. May be NULL
* @return 0 or an error code
*/
GIT_EXTERN(int) git_worktree_add(git_worktree **out, git_repository *repo,
const char *name, const char *path,
const git_worktree_add_options *opts);
/**
* Lock worktree if not already locked
*
* Lock a worktree, optionally specifying a reason why the linked
* working tree is being locked.
*
* @param wt Worktree to lock
* @param reason Reason why the working tree is being locked
* @return 0 on success, non-zero otherwise
*/
GIT_EXTERN(int) git_worktree_lock(git_worktree *wt, char *reason);
/**
* Unlock a locked worktree
*
* @param wt Worktree to unlock
* @return 0 on success, 1 if worktree was not locked, error-code
* otherwise
*/
GIT_EXTERN(int) git_worktree_unlock(git_worktree *wt);
/**
* Check if worktree is locked
*
* A worktree may be locked if the linked working tree is stored
* on a portable device which is not available.
*
* @param reason Buffer to store reason in. If NULL no reason is stored.
* @param wt Worktree to check
* @return 0 when the working tree not locked, a value greater
* than zero if it is locked, less than zero if there was an
* error
*/
GIT_EXTERN(int) git_worktree_is_locked(git_buf *reason, const git_worktree *wt);
/**
* Flags which can be passed to git_worktree_prune to alter its
* behavior.
*/
typedef enum {
/* Prune working tree even if working tree is valid */
GIT_WORKTREE_PRUNE_VALID = 1u << 0,
/* Prune working tree even if it is locked */
GIT_WORKTREE_PRUNE_LOCKED = 1u << 1,
/* Prune checked out working tree */
GIT_WORKTREE_PRUNE_WORKING_TREE = 1u << 2,
} git_worktree_prune_t;
typedef struct git_worktree_prune_options {
unsigned int version;
uint32_t flags;
} git_worktree_prune_options;
#define GIT_WORKTREE_PRUNE_OPTIONS_VERSION 1
#define GIT_WORKTREE_PRUNE_OPTIONS_INIT {GIT_WORKTREE_PRUNE_OPTIONS_VERSION,0}
/**
* Initializes a `git_worktree_prune_options` with default vaules.
* Equivalent to creating an instance with
* GIT_WORKTREE_PRUNE_OPTIONS_INIT.
*
* @param opts the struct to initialize
* @param version Verison of struct; pass `GIT_WORKTREE_PRUNE_OPTIONS_VERSION`
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN(int) git_worktree_prune_init_options(
git_worktree_prune_options *opts,
unsigned int version);
/**
* Is the worktree prunable with the given options?
*
* A worktree is not prunable in the following scenarios:
*
* - the worktree is linking to a valid on-disk worktree. The
* `valid` member will cause this check to be ignored.
* - the worktree is locked. The `locked` flag will cause this
* check to be ignored.
*
* If the worktree is not valid and not locked or if the above
* flags have been passed in, this function will return a
* positive value.
*/
GIT_EXTERN(int) git_worktree_is_prunable(git_worktree *wt,
git_worktree_prune_options *opts);
/**
* Prune working tree
*
* Prune the working tree, that is remove the git data
* structures on disk. The repository will only be pruned of
* `git_worktree_is_prunable` succeeds.
*
* @param wt Worktree to prune
* @param opts Specifies which checks to override. See
* `git_worktree_is_prunable`. May be NULL
* @return 0 or an error code
*/
GIT_EXTERN(int) git_worktree_prune(git_worktree *wt,
git_worktree_prune_options *opts);
/** @} */
GIT_END_DECL
#endif

View File

@ -1,4 +1,4 @@
prefix=@PKGCONFIG_PREFIX@
prefix="@PKGCONFIG_PREFIX@"
libdir=@PKGCONFIG_LIBDIR@
includedir=@PKGCONFIG_INCLUDEDIR@
@ -6,7 +6,7 @@ Name: libgit2
Description: The git library, take 2
Version: @LIBGIT2_VERSION_STRING@
Libs: -L"${libdir}" -lgit2
Libs: -L${libdir} -lgit2
Libs.private: @LIBGIT2_PC_LIBS@
Requires.private: @LIBGIT2_PC_REQUIRES@

View File

@ -7,15 +7,17 @@ if [ "$ARCH" = "i686" ]; then
curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/$f
fi
7z x $f > /dev/null
mv mingw32 /MinGW
export PATH=`pwd`/mingw32/bin:$PATH
else
f=x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z
if ! [ -e $f ]; then
curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/$f
fi
7z x $f > /dev/null
mv mingw64 /MinGW
export PATH=`pwd`/mingw64/bin:$PATH
fi
cd build
gcc --version
cmake --version
cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON .. -G"$GENERATOR"
cmake --build . --config RelWithDebInfo

View File

@ -3,6 +3,7 @@
set -x
brew update
brew install homebrew/dupes/zlib
brew install zlib
brew install curl
brew install openssl
brew install libssh2

View File

@ -173,7 +173,7 @@ static int apply_hunk(
git_diff_line *line = git_array_get(patch->lines, linenum);
if (!line) {
error = apply_err("Preimage does not contain line %"PRIuZ, linenum);
error = apply_err("preimage does not contain line %"PRIuZ, linenum);
goto done;
}
@ -193,7 +193,7 @@ static int apply_hunk(
line_num = hunk->hunk.new_start ? hunk->hunk.new_start - 1 : 0;
if (!find_hunk_linenum(&line_num, image, &preimage, line_num)) {
error = apply_err("Hunk at line %d did not apply",
error = apply_err("hunk at line %d did not apply",
hunk->hunk.new_start);
goto done;
}

View File

@ -7,8 +7,6 @@
#include "git2/oid.h"
#include <ctype.h>
GIT__USE_STRMAP
const char *git_attr__true = "[internal]__TRUE__";
const char *git_attr__false = "[internal]__FALSE__";
const char *git_attr__unset = "[internal]__UNSET__";
@ -209,7 +207,7 @@ int git_attr_foreach(
if (git_strmap_exists(seen, assign->name))
continue;
git_strmap_insert(seen, assign->name, assign, error);
git_strmap_insert(seen, assign->name, assign, &error);
if (error < 0)
goto cleanup;
@ -292,7 +290,7 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
int error = 0;
const char *workdir = git_repository_workdir(repo);
git_index *idx = NULL;
git_buf sys = GIT_BUF_INIT;
git_buf path = GIT_BUF_INIT;
if (attr_session && attr_session->init_setup)
return 0;
@ -304,40 +302,45 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
* definitions will be available for later file parsing
*/
error = system_attr_file(&sys, attr_session);
error = system_attr_file(&path, attr_session);
if (error == 0)
error = preload_attr_file(
repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr);
repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, path.ptr);
if (error != GIT_ENOTFOUND)
return error;
git_buf_free(&sys);
goto out;
if ((error = preload_attr_file(
repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
NULL, git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
return error;
goto out;
if ((error = git_repository_item_path(&path,
repo, GIT_REPOSITORY_ITEM_INFO)) < 0)
goto out;
if ((error = preload_attr_file(
repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
git_repository_path(repo), GIT_ATTR_FILE_INREPO)) < 0)
return error;
path.ptr, GIT_ATTR_FILE_INREPO)) < 0)
goto out;
if (workdir != NULL &&
(error = preload_attr_file(
repo, attr_session, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
return error;
goto out;
if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
(error = preload_attr_file(
repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
return error;
goto out;
if (attr_session)
attr_session->init_setup = 1;
out:
git_buf_free(&path);
return error;
}
@ -472,7 +475,7 @@ static int collect_attr_files(
git_vector *files)
{
int error = 0;
git_buf dir = GIT_BUF_INIT;
git_buf dir = GIT_BUF_INIT, attrfile = GIT_BUF_INIT;
const char *workdir = git_repository_workdir(repo);
attr_walk_up_info info = { NULL };
@ -494,9 +497,13 @@ static int collect_attr_files(
* - $GIT_PREFIX/etc/gitattributes
*/
error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO);
if (error < 0)
goto cleanup;
error = push_attr_file(
repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
git_repository_path(repo), GIT_ATTR_FILE_INREPO);
attrfile.ptr, GIT_ATTR_FILE_INREPO);
if (error < 0)
goto cleanup;
@ -538,6 +545,7 @@ static int collect_attr_files(
cleanup:
if (error < 0)
release_attr_files(files);
git_buf_free(&attrfile);
git_buf_free(&dir);
return error;

View File

@ -30,7 +30,7 @@ int git_attr_file__new(
GITERR_CHECK_ALLOC(attrs);
if (git_mutex_init(&attrs->lock) < 0) {
giterr_set(GITERR_OS, "Failed to initialize lock");
giterr_set(GITERR_OS, "failed to initialize lock");
git__free(attrs);
return -1;
}
@ -49,7 +49,7 @@ int git_attr_file__clear_rules(git_attr_file *file, bool need_lock)
git_attr_rule *rule;
if (need_lock && git_mutex_lock(&file->lock) < 0) {
giterr_set(GITERR_OS, "Failed to lock attribute file");
giterr_set(GITERR_OS, "failed to lock attribute file");
return -1;
}
@ -140,7 +140,7 @@ int git_attr_file__load(
break;
}
default:
giterr_set(GITERR_INVALID, "Unknown file source %d", source);
giterr_set(GITERR_INVALID, "unknown file source %d", source);
return -1;
}
@ -212,7 +212,7 @@ int git_attr_file__out_of_date(
}
default:
giterr_set(GITERR_INVALID, "Invalid file type %d", file->source);
giterr_set(GITERR_INVALID, "invalid file type %d", file->source);
return -1;
}
}
@ -238,7 +238,7 @@ int git_attr_file__parse_buffer(
context = attrs->entry->path;
if (git_mutex_lock(&attrs->lock) < 0) {
giterr_set(GITERR_OS, "Failed to lock attribute file");
giterr_set(GITERR_OS, "failed to lock attribute file");
return -1;
}
@ -395,9 +395,13 @@ bool git_attr_fnmatch__match(
if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) {
bool samename;
/* for attribute checks or root ignore checks, fail match */
/*
* for attribute checks or checks at the root of this match's
* containing_dir (or root of the repository if no containing_dir),
* do not match.
*/
if (!(match->flags & GIT_ATTR_FNMATCH_IGNORE) ||
path->basename == path->path)
path->basename == relpath)
return false;
flags |= FNM_LEADING_DIR;

View File

@ -15,7 +15,7 @@
#include "fileops.h"
#define GIT_ATTR_FILE ".gitattributes"
#define GIT_ATTR_FILE_INREPO "info/attributes"
#define GIT_ATTR_FILE_INREPO "attributes"
#define GIT_ATTR_FILE_SYSTEM "gitattributes"
#define GIT_ATTR_FILE_XDG "attributes"

View File

@ -5,14 +5,12 @@
#include "sysdir.h"
#include "ignore.h"
GIT__USE_STRMAP
GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache)
{
GIT_UNUSED(cache); /* avoid warning if threading is off */
if (git_mutex_lock(&cache->lock) < 0) {
giterr_set(GITERR_OS, "Unable to get attr cache lock");
giterr_set(GITERR_OS, "unable to get attr cache lock");
return -1;
}
return 0;
@ -82,7 +80,7 @@ static int attr_cache_make_entry(
&entry, git_repository_workdir(repo), path, &cache->pool);
if (!error) {
git_strmap_insert(cache->files, entry->path, entry, error);
git_strmap_insert(cache->files, entry->path, entry, &error);
if (error > 0)
error = 0;
}
@ -105,8 +103,11 @@ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file)
GIT_REFCOUNT_OWN(file, entry);
GIT_REFCOUNT_INC(file);
old = git__compare_and_swap(
&entry->file[file->source], entry->file[file->source], file);
/*
* Replace the existing value if another thread has
* created it in the meantime.
*/
old = git__swap(entry->file[file->source], file);
if (old) {
GIT_REFCOUNT_OWN(old, NULL);
@ -121,20 +122,22 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file)
{
int error = 0;
git_attr_file_entry *entry;
git_attr_file *old = NULL;
if (!file)
return 0;
if ((error = attr_cache_lock(cache)) < 0)
return error;
if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL)
file = git__compare_and_swap(&entry->file[file->source], file, NULL);
old = git__compare_and_swap(&entry->file[file->source], file, NULL);
attr_cache_unlock(cache);
if (file) {
GIT_REFCOUNT_OWN(file, NULL);
git_attr_file__free(file);
if (old) {
GIT_REFCOUNT_OWN(old, NULL);
git_attr_file__free(old);
}
return error;
@ -287,14 +290,16 @@ static int attr_cache__lookup_path(
const char *cfgval = entry->value;
/* expand leading ~/ as needed */
if (cfgval && cfgval[0] == '~' && cfgval[1] == '/' &&
!git_sysdir_find_global_file(&buf, &cfgval[2]))
*out = git_buf_detach(&buf);
else if (cfgval)
if (cfgval && cfgval[0] == '~' && cfgval[1] == '/') {
if (! (error = git_sysdir_expand_global_file(&buf, &cfgval[2])))
*out = git_buf_detach(&buf);
} else if (cfgval) {
*out = git__strdup(cfgval);
}
}
else if (!git_sysdir_find_xdg_file(&buf, fallback))
else if (!git_sysdir_find_xdg_file(&buf, fallback)) {
*out = git_buf_detach(&buf);
}
git_config_entry_free(entry);
git_buf_free(&buf);
@ -309,7 +314,7 @@ static void attr_cache__free(git_attr_cache *cache)
if (!cache)
return;
unlock = (git_mutex_lock(&cache->lock) == 0);
unlock = (attr_cache_lock(cache) == 0);
if (cache->files != NULL) {
git_attr_file_entry *entry;
@ -345,13 +350,13 @@ static void attr_cache__free(git_attr_cache *cache)
cache->cfg_excl_file = NULL;
if (unlock)
git_mutex_unlock(&cache->lock);
attr_cache_unlock(cache);
git_mutex_free(&cache->lock);
git__free(cache);
}
int git_attr_cache__do_init(git_repository *repo)
int git_attr_cache__init(git_repository *repo)
{
int ret = 0;
git_attr_cache *cache = git_repository_attr_cache(repo);
@ -365,7 +370,7 @@ int git_attr_cache__do_init(git_repository *repo)
/* set up lock */
if (git_mutex_init(&cache->lock) < 0) {
giterr_set(GITERR_OS, "Unable to initialize lock for attr cache");
giterr_set(GITERR_OS, "unable to initialize lock for attr cache");
git__free(cache);
return -1;
}
@ -429,11 +434,11 @@ int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
if (macro->assigns.length == 0)
return 0;
if (git_mutex_lock(&cache->lock) < 0) {
giterr_set(GITERR_OS, "Unable to get attr cache lock");
if (attr_cache_lock(cache) < 0) {
giterr_set(GITERR_OS, "unable to get attr cache lock");
error = -1;
} else {
git_strmap_insert(macros, macro->match.pattern, macro, error);
git_strmap_insert(macros, macro->match.pattern, macro, &error);
git_mutex_unlock(&cache->lock);
}

View File

@ -22,10 +22,7 @@ typedef struct {
git_pool pool;
} git_attr_cache;
extern int git_attr_cache__do_init(git_repository *repo);
#define git_attr_cache__init(REPO) \
(git_repository_attr_cache(REPO) ? 0 : git_attr_cache__do_init(REPO))
extern int git_attr_cache__init(git_repository *repo);
/* get file - loading and reload as needed */
extern int git_attr_cache__get(

View File

@ -478,14 +478,15 @@ cleanup:
* The blobs of origin and porigin exactly match, so everything origin is
* suspected for can be blamed on the parent.
*/
static void pass_whole_blame(git_blame *blame,
static int pass_whole_blame(git_blame *blame,
git_blame__origin *origin, git_blame__origin *porigin)
{
git_blame__entry *e;
if (!porigin->blob)
git_object_lookup((git_object**)&porigin->blob, blame->repository,
git_blob_id(origin->blob), GIT_OBJ_BLOB);
if (!porigin->blob &&
git_object_lookup((git_object**)&porigin->blob, blame->repository,
git_blob_id(origin->blob), GIT_OBJ_BLOB) < 0)
return -1;
for (e=blame->ent; e; e=e->next) {
if (!same_suspect(e->suspect, origin))
continue;
@ -493,6 +494,8 @@ static void pass_whole_blame(git_blame *blame,
origin_decref(e->suspect);
e->suspect = porigin;
}
return 0;
}
static int pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt)
@ -514,11 +517,12 @@ static int pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt)
if (!num_parents) {
git_oid_cpy(&blame->options.oldest_commit, git_commit_id(commit));
goto finish;
}
else if (num_parents < (int)ARRAY_SIZE(sg_buf))
} else if (num_parents < (int)ARRAY_SIZE(sg_buf))
memset(sg_buf, 0, sizeof(sg_buf));
else
else {
sg_origin = git__calloc(num_parents, sizeof(*sg_origin));
GITERR_CHECK_ALLOC(sg_origin);
}
for (i=0; i<num_parents; i++) {
git_commit *p;
@ -543,7 +547,7 @@ static int pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt)
}
if (porigin->blob && origin->blob &&
!git_oid_cmp(git_blob_id(porigin->blob), git_blob_id(origin->blob))) {
pass_whole_blame(blame, origin, porigin);
error = pass_whole_blame(blame, origin, porigin);
origin_decref(porigin);
goto finish;
}

View File

@ -96,7 +96,7 @@ static int write_file_stream(
p_close(fd);
if (written != file_size || read_len < 0) {
giterr_set(GITERR_OS, "Failed to read file into stream");
giterr_set(GITERR_OS, "failed to read file into stream");
error = -1;
}
@ -142,7 +142,7 @@ static int write_symlink(
read_len = p_readlink(path, link_data, link_size);
if (read_len != (ssize_t)link_size) {
giterr_set(GITERR_OS, "Failed to create blob. Can't read symlink '%s'", path);
giterr_set(GITERR_OS, "failed to create blob: cannot read symlink '%s'", path);
git__free(link_data);
return -1;
}
@ -186,7 +186,7 @@ int git_blob__create_from_paths(
goto done;
if (S_ISDIR(st.st_mode)) {
giterr_set(GITERR_ODB, "cannot create blob from '%s'; it is a directory", content_path);
giterr_set(GITERR_ODB, "cannot create blob from '%s': it is a directory", content_path);
error = GIT_EDIRECTORY;
goto done;
}
@ -326,8 +326,8 @@ int git_blob_create_fromstream(git_writestream **out, git_repository *repo, cons
stream->parent.close = blob_writestream_close;
stream->parent.free = blob_writestream_free;
if ((error = git_buf_joinpath(&path,
git_repository_path(repo), GIT_OBJECTS_DIR "streamed")) < 0)
if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0
|| (error = git_buf_joinpath(&path, path.ptr, "streamed")) < 0)
goto cleanup;
if ((error = git_filebuf_open_withsize(&stream->fbuf, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY,

View File

@ -13,6 +13,7 @@
#include "refs.h"
#include "remote.h"
#include "annotated_commit.h"
#include "worktree.h"
#include "git2/branch.h"
@ -33,7 +34,7 @@ static int retrieve_branch_reference(
/* OOM */;
else if ((error = git_reference_lookup(&branch, repo, ref_name.ptr)) < 0)
giterr_set(
GITERR_REFERENCE, "Cannot locate %s branch '%s'",
GITERR_REFERENCE, "cannot locate %s branch '%s'",
is_remote ? "remote-tracking" : "local", branch_name);
*branch_reference_out = branch; /* will be NULL on error */
@ -46,7 +47,7 @@ static int not_a_local_branch(const char *reference_name)
{
giterr_set(
GITERR_INVALID,
"Reference '%s' is not a local branch.", reference_name);
"reference '%s' is not a local branch.", reference_name);
return -1;
}
@ -80,7 +81,7 @@ static int create_branch(
}
if (is_unmovable_head && force) {
giterr_set(GITERR_REFERENCE, "Cannot force update branch '%s' as it is "
giterr_set(GITERR_REFERENCE, "cannot force update branch '%s' as it is "
"the current HEAD of the repository.", branch_name);
error = -1;
goto cleanup;
@ -126,6 +127,31 @@ int git_branch_create_from_annotated(
repository, branch_name, commit->commit, commit->description, force);
}
static int branch_equals(git_repository *repo, const char *path, void *payload)
{
git_reference *branch = (git_reference *) payload;
git_reference *head = NULL;
int equal = 0;
if (git_reference__read_head(&head, repo, path) < 0 ||
git_reference_type(head) != GIT_REF_SYMBOLIC)
goto done;
equal = !git__strcmp(head->target.symbolic, branch->name);
done:
git_reference_free(head);
return equal;
}
int git_branch_is_checked_out(const git_reference *branch)
{
assert(branch && git_reference_is_branch(branch));
return git_repository_foreach_head(git_reference_owner(branch),
branch_equals, (void *) branch) == 1;
}
int git_branch_delete(git_reference *branch)
{
int is_head;
@ -135,7 +161,7 @@ int git_branch_delete(git_reference *branch)
assert(branch);
if (!git_reference_is_branch(branch) && !git_reference_is_remote(branch)) {
giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.",
giterr_set(GITERR_INVALID, "reference '%s' is not a valid branch.",
git_reference_name(branch));
return GIT_ENOTFOUND;
}
@ -144,11 +170,17 @@ int git_branch_delete(git_reference *branch)
return is_head;
if (is_head) {
giterr_set(GITERR_REFERENCE, "Cannot delete branch '%s' as it is "
giterr_set(GITERR_REFERENCE, "cannot delete branch '%s' as it is "
"the current HEAD of the repository.", git_reference_name(branch));
return -1;
}
if (git_reference_is_branch(branch) && git_branch_is_checked_out(branch)) {
giterr_set(GITERR_REFERENCE, "Cannot delete branch '%s' as it is "
"the current HEAD of a linked repository.", git_reference_name(branch));
return -1;
}
if (git_buf_join(&config_section, '.', "branch",
git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
goto on_error;
@ -306,7 +338,7 @@ int git_branch_name(
branch_name += strlen(GIT_REFS_REMOTES_DIR);
} else {
giterr_set(GITERR_INVALID,
"Reference '%s' is neither a local nor a remote branch.", ref->name);
"reference '%s' is neither a local nor a remote branch.", ref->name);
return -1;
}
*out = branch_name;
@ -436,7 +468,7 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna
/* Verify that this is a remote branch */
if (!git_reference__is_remote(refname)) {
giterr_set(GITERR_INVALID, "Reference '%s' is not a remote branch.",
giterr_set(GITERR_INVALID, "reference '%s' is not a remote branch.",
refname);
error = GIT_ERROR;
goto cleanup;
@ -463,7 +495,7 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna
git_remote_free(remote);
giterr_set(GITERR_REFERENCE,
"Reference '%s' is ambiguous", refname);
"reference '%s' is ambiguous", refname);
error = GIT_EAMBIGUOUS;
goto cleanup;
}
@ -477,7 +509,7 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna
error = git_buf_puts(buf, remote_name);
} else {
giterr_set(GITERR_REFERENCE,
"Could not determine remote for '%s'", refname);
"could not determine remote for '%s'", refname);
error = GIT_ENOTFOUND;
}
@ -566,7 +598,7 @@ int git_branch_set_upstream(git_reference *branch, const char *upstream_name)
local = 0;
else {
giterr_set(GITERR_REFERENCE,
"Cannot set upstream for branch '%s'", shortname);
"cannot set upstream for branch '%s'", shortname);
return GIT_ENOTFOUND;
}

View File

@ -18,18 +18,19 @@ char git_buf__initbuf[1];
char git_buf__oom[1];
#define ENSURE_SIZE(b, d) \
if ((d) > buf->asize && git_buf_grow(b, (d)) < 0)\
if ((d) > (b)->asize && git_buf_grow((b), (d)) < 0)\
return -1;
void git_buf_init(git_buf *buf, size_t initial_size)
int git_buf_init(git_buf *buf, size_t initial_size)
{
buf->asize = 0;
buf->size = 0;
buf->ptr = git_buf__initbuf;
if (initial_size)
git_buf_grow(buf, initial_size);
ENSURE_SIZE(buf, initial_size);
return 0;
}
int git_buf_try_grow(
@ -577,7 +578,7 @@ char *git_buf_detach(git_buf *buf)
return data;
}
void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
int git_buf_attach(git_buf *buf, char *ptr, size_t asize)
{
git_buf_free(buf);
@ -588,9 +589,10 @@ void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
buf->asize = (asize < buf->size) ? buf->size + 1 : asize;
else /* pass 0 to fall back on strlen + 1 */
buf->asize = buf->size + 1;
} else {
git_buf_grow(buf, asize);
}
ENSURE_SIZE(buf, asize);
return 0;
}
void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size)
@ -724,9 +726,7 @@ int git_buf_join(
GITERR_CHECK_ALLOC_ADD(&alloc_len, strlen_a, strlen_b);
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, need_sep);
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
if (git_buf_grow(buf, alloc_len) < 0)
return -1;
assert(buf->ptr);
ENSURE_SIZE(buf, alloc_len);
/* fix up internal pointers */
if (offset_a >= 0)
@ -780,8 +780,7 @@ int git_buf_join3(
GITERR_CHECK_ALLOC_ADD(&len_total, len_total, sep_b);
GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_c);
GITERR_CHECK_ALLOC_ADD(&len_total, len_total, 1);
if (git_buf_grow(buf, len_total) < 0)
return -1;
ENSURE_SIZE(buf, len_total);
tgt = buf->ptr;
@ -962,14 +961,14 @@ int git_buf_unquote(git_buf *buf)
case '0': case '1': case '2': case '3':
if (j == buf->size-3) {
giterr_set(GITERR_INVALID,
"Truncated quoted character \\%c", ch);
"truncated quoted character \\%c", ch);
return -1;
}
if (buf->ptr[j+1] < '0' || buf->ptr[j+1] > '7' ||
buf->ptr[j+2] < '0' || buf->ptr[j+2] > '7') {
giterr_set(GITERR_INVALID,
"Truncated quoted character \\%c%c%c",
"truncated quoted character \\%c%c%c",
buf->ptr[j], buf->ptr[j+1], buf->ptr[j+2]);
return -1;
}
@ -981,7 +980,7 @@ int git_buf_unquote(git_buf *buf)
break;
default:
giterr_set(GITERR_INVALID, "Invalid quoted character \\%c", ch);
giterr_set(GITERR_INVALID, "invalid quoted character \\%c", ch);
return -1;
}
}
@ -995,6 +994,6 @@ int git_buf_unquote(git_buf *buf)
return 0;
invalid:
giterr_set(GITERR_INVALID, "Invalid quoted line");
giterr_set(GITERR_INVALID, "invalid quoted line");
return -1;
}

View File

@ -34,7 +34,7 @@ GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf)
* For the cases where GIT_BUF_INIT cannot be used to do static
* initialization.
*/
extern void git_buf_init(git_buf *buf, size_t initial_size);
extern int git_buf_init(git_buf *buf, size_t initial_size);
/**
* Resize the buffer allocation to make more space.
@ -66,13 +66,14 @@ extern int git_buf_try_grow(
* 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.
* git_buf__initbuf. If a buffer with a non-NULL ptr is passed in, this method
* assures that the buffer is '\0'-terminated.
*/
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);
extern int git_buf_attach(git_buf *buf, char *ptr, size_t asize);
/* Populates a `git_buf` where the contents are not "owned" by the
* buffer, and calls to `git_buf_free` will not free the given buf.

View File

@ -15,8 +15,6 @@
#include "object.h"
#include "git2/oid.h"
GIT__USE_OIDMAP
bool git_cache__enabled = true;
ssize_t git_cache__max_storage = (256 * 1024 * 1024);
git_atomic_ssize git_cache__current_storage = {0};
@ -47,13 +45,13 @@ void git_cache_dump_stats(git_cache *cache)
{
git_cached_obj *object;
if (kh_size(cache->map) == 0)
if (git_cache_size(cache) == 0)
return;
printf("Cache %p: %d items cached, %"PRIdZ" bytes\n",
cache, kh_size(cache->map), cache->used_memory);
printf("Cache %p: %"PRIuZ" items cached, %"PRIdZ" bytes\n",
cache, git_cache_size(cache), cache->used_memory);
kh_foreach_value(cache->map, object, {
git_oidmap_foreach_value(cache->map, object, {
char oid_str[9];
printf(" %s%c %s (%"PRIuZ")\n",
git_object_type2string(object->type),
@ -70,7 +68,7 @@ int git_cache_init(git_cache *cache)
cache->map = git_oidmap_alloc();
GITERR_CHECK_ALLOC(cache->map);
if (git_rwlock_init(&cache->lock)) {
giterr_set(GITERR_OS, "Failed to initialize cache rwlock");
giterr_set(GITERR_OS, "failed to initialize cache rwlock");
return -1;
}
return 0;
@ -81,14 +79,14 @@ static void clear_cache(git_cache *cache)
{
git_cached_obj *evict = NULL;
if (kh_size(cache->map) == 0)
if (git_cache_size(cache) == 0)
return;
kh_foreach_value(cache->map, evict, {
git_oidmap_foreach_value(cache->map, evict, {
git_cached_obj_decref(evict);
});
kh_clear(oid, cache->map);
git_oidmap_clear(cache->map);
git_atomic_ssize_add(&git_cache__current_storage, -cache->used_memory);
cache->used_memory = 0;
}
@ -119,22 +117,22 @@ static void cache_evict_entries(git_cache *cache)
ssize_t evicted_memory = 0;
/* do not infinite loop if there's not enough entries to evict */
if (evict_count > kh_size(cache->map)) {
if (evict_count > git_cache_size(cache)) {
clear_cache(cache);
return;
}
while (evict_count > 0) {
khiter_t pos = seed++ % kh_end(cache->map);
khiter_t pos = seed++ % git_oidmap_end(cache->map);
if (kh_exist(cache->map, pos)) {
git_cached_obj *evict = kh_val(cache->map, pos);
if (git_oidmap_has_data(cache->map, pos)) {
git_cached_obj *evict = git_oidmap_value_at(cache->map, pos);
evict_count--;
evicted_memory += evict->size;
git_cached_obj_decref(evict);
kh_del(oid, cache->map, pos);
git_oidmap_delete_at(cache->map, pos);
}
}
@ -156,9 +154,9 @@ static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags)
if (!git_cache__enabled || git_rwlock_rdlock(&cache->lock) < 0)
return NULL;
pos = kh_get(oid, cache->map, oid);
if (pos != kh_end(cache->map)) {
entry = kh_val(cache->map, pos);
pos = git_oidmap_lookup_index(cache->map, oid);
if (git_oidmap_valid_index(cache->map, pos)) {
entry = git_oidmap_value_at(cache->map, pos);
if (flags && entry->flags != flags) {
entry = NULL;
@ -193,16 +191,14 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
if (git_cache__current_storage.val > git_cache__max_storage)
cache_evict_entries(cache);
pos = kh_get(oid, cache->map, &entry->oid);
pos = git_oidmap_lookup_index(cache->map, &entry->oid);
/* not found */
if (pos == kh_end(cache->map)) {
if (!git_oidmap_valid_index(cache->map, pos)) {
int rval;
pos = kh_put(oid, cache->map, &entry->oid, &rval);
git_oidmap_insert(cache->map, &entry->oid, entry, &rval);
if (rval >= 0) {
kh_key(cache->map, pos) = &entry->oid;
kh_val(cache->map, pos) = entry;
git_cached_obj_incref(entry);
cache->used_memory += entry->size;
git_atomic_ssize_add(&git_cache__current_storage, (ssize_t)entry->size);
@ -210,7 +206,7 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
}
/* found */
else {
git_cached_obj *stored_entry = kh_val(cache->map, pos);
git_cached_obj *stored_entry = git_oidmap_value_at(cache->map, pos);
if (stored_entry->flags == entry->flags) {
git_cached_obj_decref(entry);
@ -221,8 +217,8 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
git_cached_obj_decref(stored_entry);
git_cached_obj_incref(entry);
kh_key(cache->map, pos) = &entry->oid;
kh_val(cache->map, pos) = entry;
git_oidmap_set_key_at(cache->map, pos, &entry->oid);
git_oidmap_set_value_at(cache->map, pos, entry);
} else {
/* NO OP */
}

View File

@ -53,7 +53,7 @@ void *git_cache_get_any(git_cache *cache, const git_oid *oid);
GIT_INLINE(size_t) git_cache_size(git_cache *cache)
{
return (size_t)kh_size(cache->map);
return (size_t)git_oidmap_size(cache->map);
}
GIT_INLINE(void) git_cached_obj_incref(void *_obj)

View File

@ -35,8 +35,6 @@
#include "pool.h"
#include "strmap.h"
GIT__USE_STRMAP
/* See docs/checkout-internals.md for more information */
enum {
@ -372,10 +370,8 @@ static int checkout_action_wd_only(
*/
const git_index_entry *e = git_index_get_byindex(data->index, pos);
if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0) {
notify = GIT_CHECKOUT_NOTIFY_DIRTY;
remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
}
if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0)
return git_iterator_advance_into(wditem, workdir);
}
}
@ -1021,13 +1017,13 @@ static int checkout_conflicts_load_byname_entry(
*theirs_out = NULL;
if (!name_entry->ancestor) {
giterr_set(GITERR_INDEX, "A NAME entry exists without an ancestor");
giterr_set(GITERR_INDEX, "a NAME entry exists without an ancestor");
error = -1;
goto done;
}
if (!name_entry->ours && !name_entry->theirs) {
giterr_set(GITERR_INDEX, "A NAME entry exists without an ours or theirs");
giterr_set(GITERR_INDEX, "a NAME entry exists without an ours or theirs");
error = -1;
goto done;
}
@ -1035,7 +1031,7 @@ static int checkout_conflicts_load_byname_entry(
if ((ancestor = checkout_conflicts_search_ancestor(data,
name_entry->ancestor)) == NULL) {
giterr_set(GITERR_INDEX,
"A NAME entry referenced ancestor entry '%s' which does not exist in the main index",
"a NAME entry referenced ancestor entry '%s' which does not exist in the main index",
name_entry->ancestor);
error = -1;
goto done;
@ -1047,7 +1043,7 @@ static int checkout_conflicts_load_byname_entry(
else if ((ours = checkout_conflicts_search_branch(data, name_entry->ours)) == NULL ||
ours->ours == NULL) {
giterr_set(GITERR_INDEX,
"A NAME entry referenced our entry '%s' which does not exist in the main index",
"a NAME entry referenced our entry '%s' which does not exist in the main index",
name_entry->ours);
error = -1;
goto done;
@ -1062,7 +1058,7 @@ static int checkout_conflicts_load_byname_entry(
else if ((theirs = checkout_conflicts_search_branch(data, name_entry->theirs)) == NULL ||
theirs->theirs == NULL) {
giterr_set(GITERR_INDEX,
"A NAME entry referenced their entry '%s' which does not exist in the main index",
"a NAME entry referenced their entry '%s' which does not exist in the main index",
name_entry->theirs);
error = -1;
goto done;
@ -1161,7 +1157,7 @@ static int checkout_conflicts_mark_directoryfile(
if ((error = git_index_find(&j, index, path)) < 0) {
if (error == GIT_ENOTFOUND)
giterr_set(GITERR_INDEX,
"Index inconsistency, could not find entry for expected conflict '%s'", path);
"index inconsistency, could not find entry for expected conflict '%s'", path);
goto done;
}
@ -1169,7 +1165,7 @@ static int checkout_conflicts_mark_directoryfile(
for (; j < len; j++) {
if ((entry = git_index_get_byindex(index, j)) == NULL) {
giterr_set(GITERR_INDEX,
"Index inconsistency, truncated index while loading expected conflict '%s'", path);
"index inconsistency, truncated index while loading expected conflict '%s'", path);
error = -1;
goto done;
}
@ -1254,14 +1250,14 @@ static int checkout_verify_paths(
if (action & CHECKOUT_ACTION__REMOVE) {
if (!git_path_isvalid(repo, delta->old_file.path, flags)) {
giterr_set(GITERR_CHECKOUT, "Cannot remove invalid path '%s'", delta->old_file.path);
giterr_set(GITERR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path);
return -1;
}
}
if (action & ~CHECKOUT_ACTION__REMOVE) {
if (!git_path_isvalid(repo, delta->new_file.path, flags)) {
giterr_set(GITERR_CHECKOUT, "Cannot checkout to invalid path '%s'", delta->new_file.path);
giterr_set(GITERR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path);
return -1;
}
}
@ -1430,7 +1426,7 @@ static int mkpath2file(
*/
error = git_futils_rmdir_r(path, NULL, GIT_RMDIR_REMOVE_FILES);
} else if (errno != ENOENT) {
giterr_set(GITERR_OS, "Failed to stat file '%s'", path);
giterr_set(GITERR_OS, "failed to stat '%s'", path);
return GIT_EEXISTS;
} else {
giterr_clear();
@ -1454,7 +1450,7 @@ static int checkout_stream_write(
int ret;
if ((ret = p_write(stream->fd, buffer, len)) < 0)
giterr_set(GITERR_OS, "Could not write to '%s'", stream->path);
giterr_set(GITERR_OS, "could not write to '%s'", stream->path);
return ret;
}
@ -1503,7 +1499,7 @@ static int blob_content_to_file(
mode = GIT_FILEMODE_BLOB;
if ((fd = p_open(path, flags, mode)) < 0) {
giterr_set(GITERR_OS, "Could not open '%s' for writing", path);
giterr_set(GITERR_OS, "could not open '%s' for writing", path);
return fd;
}
@ -1540,7 +1536,7 @@ static int blob_content_to_file(
data->perfdata.stat_calls++;
if ((error = p_stat(path, st)) < 0) {
giterr_set(GITERR_OS, "Error statting '%s'", path);
giterr_set(GITERR_OS, "failed to stat '%s'", path);
return error;
}
@ -1567,7 +1563,7 @@ static int blob_content_to_link(
if (data->can_symlink) {
if ((error = p_symlink(git_buf_cstr(&linktarget), path)) < 0)
giterr_set(GITERR_OS, "Could not create symlink %s", path);
giterr_set(GITERR_OS, "could not create symlink %s", path);
} else {
error = git_futils_fake_symlink(git_buf_cstr(&linktarget), path);
}
@ -1576,7 +1572,7 @@ static int blob_content_to_link(
data->perfdata.stat_calls++;
if ((error = p_lstat(path, st)) < 0)
giterr_set(GITERR_CHECKOUT, "Could not stat symlink %s", path);
giterr_set(GITERR_CHECKOUT, "could not stat symlink %s", path);
st->st_mode = GIT_FILEMODE_LINK;
}
@ -1621,7 +1617,7 @@ static int checkout_submodule_update_index(
data->perfdata.stat_calls++;
if (p_stat(fullpath->ptr, &st) < 0) {
giterr_set(
GITERR_CHECKOUT, "Could not stat submodule %s\n", file->path);
GITERR_CHECKOUT, "could not stat submodule %s\n", file->path);
return GIT_ENOTFOUND;
}
@ -1694,7 +1690,7 @@ static int checkout_safe_for_update_only(
return 0;
/* otherwise, stat error and no update */
giterr_set(GITERR_OS, "Failed to stat file '%s'", path);
giterr_set(GITERR_OS, "failed to stat '%s'", path);
return -1;
}
@ -1966,7 +1962,7 @@ static int checkout_path_suffixed(git_buf *path, const char *suffix)
if (i == INT_MAX) {
git_buf_truncate(path, path_len);
giterr_set(GITERR_CHECKOUT, "Could not write '%s': working directory file exists", path->ptr);
giterr_set(GITERR_CHECKOUT, "could not write '%s': working directory file exists", path->ptr);
return GIT_EEXISTS;
}
@ -2097,7 +2093,7 @@ static int checkout_write_merge(
goto done;
if (result.path == NULL || result.mode == 0) {
giterr_set(GITERR_CHECKOUT, "Could not merge contents of file");
giterr_set(GITERR_CHECKOUT, "could not merge contents of file");
error = GIT_ECONFLICT;
goto done;
}
@ -2321,8 +2317,6 @@ static void checkout_data_clear(checkout_data *data)
git__free(data->pfx);
data->pfx = NULL;
git_strmap_free(data->mkdir_map);
git_buf_free(&data->target_path);
git_buf_free(&data->tmp);
@ -2330,6 +2324,7 @@ static void checkout_data_clear(checkout_data *data)
data->index = NULL;
git_strmap_free(data->mkdir_map);
data->mkdir_map = NULL;
git_attr_session__free(&data->attr_session);
}
@ -2345,7 +2340,7 @@ static int checkout_data_init(
memset(data, 0, sizeof(*data));
if (!repo) {
giterr_set(GITERR_CHECKOUT, "Cannot checkout nothing");
giterr_set(GITERR_CHECKOUT, "cannot checkout nothing");
return -1;
}
@ -2553,6 +2548,10 @@ int git_checkout_iterator(
GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
baseline_opts.start = data.pfx;
baseline_opts.end = data.pfx;
if (opts && (opts->checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)) {
baseline_opts.pathlist.count = opts->paths.count;
baseline_opts.pathlist.strings = opts->paths.strings;
}
if (data.opts.baseline_index) {
if ((error = git_iterator_for_index(
@ -2647,7 +2646,7 @@ int git_checkout_index(
if (!index && !repo) {
giterr_set(GITERR_CHECKOUT,
"Must provide either repository or index to checkout");
"must provide either repository or index to checkout");
return -1;
}
@ -2655,7 +2654,7 @@ int git_checkout_index(
git_index_owner(index) &&
git_index_owner(index) != repo) {
giterr_set(GITERR_CHECKOUT,
"Index to checkout does not match repository");
"index to checkout does not match repository");
return -1;
} else if(index && repo && !git_index_owner(index)) {
GIT_REFCOUNT_OWN(index, repo);
@ -2694,12 +2693,12 @@ int git_checkout_tree(
if (!treeish && !repo) {
giterr_set(GITERR_CHECKOUT,
"Must provide either repository or tree to checkout");
"must provide either repository or tree to checkout");
return -1;
}
if (treeish && repo && git_object_owner(treeish) != repo) {
giterr_set(GITERR_CHECKOUT,
"Object to checkout does not match repository");
"object to checkout does not match repository");
return -1;
}
@ -2709,7 +2708,7 @@ int git_checkout_tree(
if (treeish) {
if (git_object_peel((git_object **)&tree, treeish, GIT_OBJ_TREE) < 0) {
giterr_set(
GITERR_CHECKOUT, "Provided object cannot be peeled to a tree");
GITERR_CHECKOUT, "provided object cannot be peeled to a tree");
return -1;
}
}

View File

@ -28,7 +28,7 @@ static int write_cherrypick_head(
git_buf file_path = GIT_BUF_INIT;
int error = 0;
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_CHERRYPICK_HEAD_FILE)) >= 0 &&
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_CHERRYPICK_HEAD_FILE)) >= 0 &&
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) >= 0 &&
(error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
error = git_filebuf_commit(&file);
@ -49,7 +49,7 @@ static int write_merge_msg(
git_buf file_path = GIT_BUF_INIT;
int error = 0;
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) < 0 ||
(error = git_filebuf_printf(&file, "%s", commit_msg)) < 0)
goto cleanup;
@ -130,13 +130,13 @@ int git_cherrypick_commit(
if (git_commit_parentcount(cherrypick_commit) > 1) {
if (!mainline)
return cherrypick_seterr(cherrypick_commit,
"Mainline branch is not specified but %s is a merge commit");
"mainline branch is not specified but %s is a merge commit");
parent = mainline;
} else {
if (mainline)
return cherrypick_seterr(cherrypick_commit,
"Mainline branch specified but %s is not a merge commit");
"mainline branch specified but %s is not a merge commit");
parent = git_commit_parentcount(cherrypick_commit);
}

View File

@ -513,9 +513,8 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_
return error;
}
git_buf_joinpath(&src_odb, git_repository_path(src), GIT_OBJECTS_DIR);
git_buf_joinpath(&dst_odb, git_repository_path(repo), GIT_OBJECTS_DIR);
if (git_buf_oom(&src_odb) || git_buf_oom(&dst_odb)) {
if (git_repository_item_path(&src_odb, src, GIT_REPOSITORY_ITEM_OBJECTS) < 0
|| git_repository_item_path(&dst_odb, repo, GIT_REPOSITORY_ITEM_OBJECTS) < 0) {
error = -1;
goto cleanup;
}

View File

@ -159,6 +159,9 @@ static int git_commit__create_internal(
if (git_repository_odb__weakptr(&odb, repo) < 0)
goto cleanup;
if (git_odb__freshen(odb, tree) < 0)
goto cleanup;
if (git_odb_write(id, odb, buf.ptr, buf.size, GIT_OBJ_COMMIT) < 0)
goto cleanup;
@ -468,7 +471,7 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
return 0;
bad_buffer:
giterr_set(GITERR_OBJECT, "Failed to parse bad commit object");
giterr_set(GITERR_OBJECT, "failed to parse bad commit object");
return -1;
}
@ -598,7 +601,7 @@ int git_commit_parent(
parent_id = git_commit_parent_id(commit, n);
if (parent_id == NULL) {
giterr_set(GITERR_INVALID, "Parent %u does not exist", n);
giterr_set(GITERR_INVALID, "parent %u does not exist", n);
return GIT_ENOTFOUND;
}
@ -642,7 +645,7 @@ int git_commit_header_field(git_buf *out, const git_commit *commit, const char *
{
const char *eol, *buf = commit->raw_header;
git_buf_sanitize(out);
git_buf_clear(out);
while ((eol = strchr(buf, '\n'))) {
/* We can skip continuations here */
@ -706,8 +709,8 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r
const char *h, *eol;
int error;
git_buf_sanitize(signature);
git_buf_sanitize(signed_data);
git_buf_clear(signature);
git_buf_clear(signed_data);
if (!field)
field = "gpgsig";
@ -766,8 +769,9 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r
if (git_buf_oom(signature))
goto oom;
error = git_buf_puts(signed_data, eol+1);
git_odb_object_free(obj);
return git_buf_puts(signed_data, eol+1);
return error;
}
giterr_set(GITERR_OBJECT, "this commit is not signed");

View File

@ -61,7 +61,7 @@ static int commit_error(git_commit_list_node *commit, const char *msg)
git_oid_fmt(commit_oid, &commit->oid);
commit_oid[GIT_OID_HEXSZ] = '\0';
giterr_set(GITERR_ODB, "Failed to parse commit %s - %s", commit_oid, msg);
giterr_set(GITERR_ODB, "failed to parse commit %s - %s", commit_oid, msg);
return -1;
}
@ -191,7 +191,7 @@ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
return error;
if (obj->cached.type != GIT_OBJ_COMMIT) {
giterr_set(GITERR_INVALID, "Object is no commit object");
giterr_set(GITERR_INVALID, "object is no commit object");
error = -1;
} else
error = commit_quick_parse(

View File

@ -188,7 +188,7 @@ GIT_INLINE(int) giterr__check_version(const void *structure, unsigned int expect
if (actual > 0 && actual <= expected_max)
return 0;
giterr_set(GITERR_INVALID, "Invalid version %d on %s", actual, name);
giterr_set(GITERR_INVALID, "invalid version %d on %s", actual, name);
return -1;
}
#define GITERR_CHECK_VERSION(S,V,N) if (giterr__check_version(S,V,N) < 0) return -1

View File

@ -109,7 +109,7 @@ int git_config_add_file_ondisk(
res = p_stat(path, &st);
if (res < 0 && errno != ENOENT) {
giterr_set(GITERR_CONFIG, "Error stat'ing config file '%s'", path);
giterr_set(GITERR_CONFIG, "failed to stat '%s'", path);
return -1;
}
@ -203,7 +203,7 @@ static int find_internal_file_by_level(
if (pos == -1) {
giterr_set(GITERR_CONFIG,
"No config file exists for the given level '%i'", (int)level);
"no config file exists for the given level '%i'", (int)level);
return GIT_ENOTFOUND;
}
@ -218,7 +218,7 @@ static int duplicate_level(void **old_raw, void *new_raw)
GIT_UNUSED(new_raw);
giterr_set(GITERR_CONFIG, "A file with the same level (%i) has already been added to the config", (int)(*old)->level);
giterr_set(GITERR_CONFIG, "a file with the same level (%i) has already been added to the config", (int)(*old)->level);
return GIT_EEXISTS;
}
@ -576,22 +576,50 @@ int git_config_foreach_match(
* Setters
**************/
static int config_error_nofiles(const char *name)
typedef enum {
BACKEND_USE_SET,
BACKEND_USE_DELETE
} backend_use;
static const char *uses[] = {
"set",
"delete"
};
static int get_backend_for_use(git_config_backend **out,
git_config *cfg, const char *name, backend_use use)
{
size_t i;
file_internal *f;
*out = NULL;
if (git_vector_length(&cfg->files) == 0) {
giterr_set(GITERR_CONFIG,
"cannot %s value for '%s' when no config files exist",
uses[use], name);
return GIT_ENOTFOUND;
}
git_vector_foreach(&cfg->files, i, f) {
if (!f->file->readonly) {
*out = f->file;
return 0;
}
}
giterr_set(GITERR_CONFIG,
"Cannot set value for '%s' when no config files exist", name);
"cannot %s value for '%s' when all config files are readonly",
uses[use], name);
return GIT_ENOTFOUND;
}
int git_config_delete_entry(git_config *cfg, const char *name)
{
git_config_backend *file;
file_internal *internal;
internal = git_vector_get(&cfg->files, 0);
if (!internal || !internal->file)
return config_error_nofiles(name);
file = internal->file;
if (get_backend_for_use(&file, cfg, name, BACKEND_USE_DELETE) < 0)
return GIT_ENOTFOUND;
return file->del(file, name);
}
@ -617,17 +645,14 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
{
int error;
git_config_backend *file;
file_internal *internal;
if (!value) {
giterr_set(GITERR_CONFIG, "The value to set cannot be NULL");
giterr_set(GITERR_CONFIG, "the value to set cannot be NULL");
return -1;
}
internal = git_vector_get(&cfg->files, 0);
if (!internal || !internal->file)
return config_error_nofiles(name);
file = internal->file;
if (get_backend_for_use(&file, cfg, name, BACKEND_USE_SET) < 0)
return GIT_ENOTFOUND;
error = file->set(file, name, value);
@ -674,7 +699,7 @@ int git_config__update_entry(
static int config_error_notfound(const char *name)
{
giterr_set(GITERR_CONFIG, "Config value '%s' was not found", name);
giterr_set(GITERR_CONFIG, "config value '%s' was not found", name);
return GIT_ENOTFOUND;
}
@ -1032,12 +1057,9 @@ on_error:
int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value)
{
git_config_backend *file;
file_internal *internal;
internal = git_vector_get(&cfg->files, 0);
if (!internal || !internal->file)
return config_error_nofiles(name);
file = internal->file;
if (get_backend_for_use(&file, cfg, name, BACKEND_USE_DELETE) < 0)
return GIT_ENOTFOUND;
return file->set_multivar(file, name, regexp, value);
}
@ -1045,12 +1067,9 @@ int git_config_set_multivar(git_config *cfg, const char *name, const char *regex
int git_config_delete_multivar(git_config *cfg, const char *name, const char *regexp)
{
git_config_backend *file;
file_internal *internal;
internal = git_vector_get(&cfg->files, 0);
if (!internal || !internal->file)
return config_error_nofiles(name);
file = internal->file;
if (get_backend_for_use(&file, cfg, name, BACKEND_USE_DELETE) < 0)
return GIT_ENOTFOUND;
return file->del_multivar(file, name, regexp);
}
@ -1236,7 +1255,7 @@ int git_config_lookup_map_value(
}
fail_parse:
giterr_set(GITERR_CONFIG, "Failed to map '%s'", value);
giterr_set(GITERR_CONFIG, "failed to map '%s'", value);
return -1;
}
@ -1270,7 +1289,7 @@ int git_config_parse_bool(int *out, const char *value)
return 0;
}
giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a boolean value", value);
giterr_set(GITERR_CONFIG, "failed to parse '%s' as a boolean value", value);
return -1;
}
@ -1313,7 +1332,7 @@ int git_config_parse_int64(int64_t *out, const char *value)
}
fail_parse:
giterr_set(GITERR_CONFIG, "Failed to parse '%s' as an integer", value ? value : "(null)");
giterr_set(GITERR_CONFIG, "failed to parse '%s' as an integer", value ? value : "(null)");
return -1;
}
@ -1333,15 +1352,12 @@ int git_config_parse_int32(int32_t *out, const char *value)
return 0;
fail_parse:
giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a 32-bit integer", value ? value : "(null)");
giterr_set(GITERR_CONFIG, "failed to parse '%s' as a 32-bit integer", value ? value : "(null)");
return -1;
}
int git_config_parse_path(git_buf *out, const char *value)
{
int error = 0;
const git_buf *home;
assert(out && value);
git_buf_sanitize(out);
@ -1352,16 +1368,7 @@ int git_config_parse_path(git_buf *out, const char *value)
return -1;
}
if ((error = git_sysdir_get(&home, GIT_SYSDIR_GLOBAL)) < 0)
return error;
git_buf_sets(out, home->ptr);
git_buf_puts(out, value + 1);
if (git_buf_oom(out))
return -1;
return 0;
return git_sysdir_expand_global_file(out, value[1] ? &value[2] : NULL);
}
return git_buf_sets(out, value);
@ -1398,7 +1405,7 @@ int git_config__normalize_name(const char *in, char **out)
invalid:
git__free(name);
giterr_set(GITERR_CONFIG, "Invalid config item name '%s'", in);
giterr_set(GITERR_CONFIG, "invalid config item name '%s'", in);
return GIT_EINVALIDSPEC;
}
@ -1461,7 +1468,7 @@ int git_config_rename_section(
replace.ptr, strchr(replace.ptr, '.'))) < 0)
{
giterr_set(
GITERR_CONFIG, "Invalid config section '%s'", new_section_name);
GITERR_CONFIG, "invalid config section '%s'", new_section_name);
goto cleanup;
}

View File

@ -78,6 +78,7 @@ static struct map_data _cvar_maps[] = {
{"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
{"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
{"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
{"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },
};
int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)

View File

@ -21,8 +21,6 @@
#include <sys/types.h>
#include <regex.h>
GIT__USE_STRMAP
typedef struct cvar_t {
struct cvar_t *next;
git_config_entry *entry;
@ -126,7 +124,7 @@ static int config_snapshot(git_config_backend **out, git_config_backend *in);
static void set_parse_error(struct reader *reader, int col, const char *error_str)
{
giterr_set(GITERR_CONFIG, "Failed to parse config file: %s (in %s:%d, column %d)",
giterr_set(GITERR_CONFIG, "failed to parse config file: %s (in %s:%d, column %d)",
error_str, reader->file_path, reader->line_number, col);
}
@ -179,7 +177,7 @@ static int append_entry(git_strmap *values, cvar_t *var)
pos = git_strmap_lookup_index(values, var->entry->name);
if (!git_strmap_valid_index(values, pos)) {
git_strmap_insert(values, var->entry->name, var, error);
git_strmap_insert(values, var->entry->name, var, &error);
} else {
existing = git_strmap_value_at(values, pos);
while (existing->next != NULL) {
@ -233,7 +231,7 @@ static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
refcounted_strmap *map;
if (git_mutex_lock(&h->values_mutex) < 0) {
giterr_set(GITERR_OS, "Failed to lock config backend");
giterr_set(GITERR_OS, "failed to lock config backend");
return NULL;
}
@ -322,7 +320,7 @@ static int config__refresh(git_config_backend *cfg)
goto out;
if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
giterr_set(GITERR_OS, "Failed to lock config backend");
giterr_set(GITERR_OS, "failed to lock config backend");
goto out;
}
@ -479,7 +477,7 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
cvar_t *existing = git_strmap_value_at(values, pos);
if (existing->next != NULL) {
giterr_set(GITERR_CONFIG, "Multivar incompatible with simple set");
giterr_set(GITERR_CONFIG, "multivar incompatible with simple set");
ret = -1;
goto out;
}
@ -611,7 +609,7 @@ static int config_delete(git_config_backend *cfg, const char *name)
if (!git_strmap_valid_index(values, pos)) {
refcounted_strmap_free(map);
giterr_set(GITERR_CONFIG, "Could not find key '%s' to delete", name);
giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
return GIT_ENOTFOUND;
}
@ -619,7 +617,7 @@ static int config_delete(git_config_backend *cfg, const char *name)
refcounted_strmap_free(map);
if (var->next != NULL) {
giterr_set(GITERR_CONFIG, "Cannot delete multivar with a single delete");
giterr_set(GITERR_CONFIG, "cannot delete multivar with a single delete");
return -1;
}
@ -651,7 +649,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
if (!git_strmap_valid_index(values, pos)) {
refcounted_strmap_free(map);
git__free(key);
giterr_set(GITERR_CONFIG, "Could not find key '%s' to delete", name);
giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
return GIT_ENOTFOUND;
}
@ -1029,7 +1027,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
first_quote = strchr(line, '"');
if (first_quote == NULL) {
set_parse_error(reader, 0, "Missing quotation marks in section header");
return -1;
goto end_error;
}
last_quote = strrchr(line, '"');
@ -1037,14 +1035,15 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
if (quoted_len == 0) {
set_parse_error(reader, 0, "Missing closing quotation mark in section header");
return -1;
goto end_error;
}
GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
git_buf_grow(&buf, alloc_len);
git_buf_printf(&buf, "%s.", base_name);
if (git_buf_grow(&buf, alloc_len) < 0 ||
git_buf_printf(&buf, "%s.", base_name) < 0)
goto end_error;
rpos = 0;
@ -1060,8 +1059,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
switch (c) {
case 0:
set_parse_error(reader, 0, "Unexpected end-of-line in section header");
git_buf_free(&buf);
return -1;
goto end_error;
case '"':
goto end_parse;
@ -1071,8 +1069,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
if (c == 0) {
set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
git_buf_free(&buf);
return -1;
goto end_error;
}
default:
@ -1084,6 +1081,9 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
} while (line + rpos < last_quote);
end_parse:
if (git_buf_oom(&buf))
goto end_error;
if (line[rpos] != '"' || line[rpos + 1] != ']') {
set_parse_error(reader, rpos, "Unexpected text after closing quotes");
git_buf_free(&buf);
@ -1092,6 +1092,11 @@ end_parse:
*section_name = git_buf_detach(&buf);
return 0;
end_error:
git_buf_free(&buf);
return -1;
}
static int parse_section_header(struct reader *reader, char **section_out)
@ -1251,7 +1256,7 @@ static int included_path(git_buf *out, const char *dir, const char *path)
{
/* From the user's home */
if (path[0] == '~' && path[1] == '/')
return git_sysdir_find_global_file(out, &path[1]);
return git_sysdir_expand_global_file(out, &path[1]);
return git_path_join_unrooted(out, path, dir, NULL);
}
@ -1262,7 +1267,7 @@ static const char *escaped = "\n\t\b\"\\";
/* Escape the values to write them to the file */
static char *escape_value(const char *ptr)
{
git_buf buf = GIT_BUF_INIT;
git_buf buf;
size_t len;
const char *esc;
@ -1272,7 +1277,8 @@ static char *escape_value(const char *ptr)
if (!len)
return git__calloc(1, sizeof(char));
git_buf_grow(&buf, len);
if (git_buf_init(&buf, len) < 0)
return NULL;
while (*ptr != '\0') {
if ((esc = strchr(escaped, *ptr)) != NULL) {
@ -1325,7 +1331,7 @@ static int unescape_line(
*fixed++ = escaped[esc - escapes];
} else {
git__free(str);
giterr_set(GITERR_CONFIG, "Invalid escape at %s", ptr);
giterr_set(GITERR_CONFIG, "invalid escape at %s", ptr);
return -1;
}
}
@ -1639,7 +1645,7 @@ static int config_read(git_strmap *values, diskfile_backend *cfg_file, struct re
struct parse_data parse_data;
if (depth >= MAX_INCLUDE_DEPTH) {
giterr_set(GITERR_CONFIG, "Maximum config include depth reached");
giterr_set(GITERR_CONFIG, "maximum config include depth reached");
return -1;
}

View File

@ -7,6 +7,7 @@
#ifndef INCLUDE_config_file_h__
#define INCLUDE_config_file_h__
#include "git2/sys/config.h"
#include "git2/config.h"
GIT_INLINE(int) git_config_file_open(git_config_backend *cfg, unsigned int level)

View File

@ -218,7 +218,7 @@ static const char *line_ending(struct crlf_attrs *ca)
return "\r\n";
line_ending_error:
giterr_set(GITERR_INVALID, "Invalid input to line ending filter");
giterr_set(GITERR_INVALID, "invalid input to line ending filter");
return NULL;
}

View File

@ -131,7 +131,7 @@ static int lookup_index_alloc(
GITERR_CHECK_ALLOC_ADD(&index_len, index_len, hash_len);
if (!git__is_ulong(index_len)) {
giterr_set(GITERR_NOMEMORY, "Overly large delta");
giterr_set(GITERR_NOMEMORY, "overly large delta");
return -1;
}
@ -544,12 +544,12 @@ int git_delta_apply(
* base object, resulting in data corruption or segfault.
*/
if ((hdr_sz(&base_sz, &delta, delta_end) < 0) || (base_sz != base_len)) {
giterr_set(GITERR_INVALID, "Failed to apply delta. Base size does not match given data");
giterr_set(GITERR_INVALID, "failed to apply delta: base size does not match given data");
return -1;
}
if (hdr_sz(&res_sz, &delta, delta_end) < 0) {
giterr_set(GITERR_INVALID, "Failed to apply delta. Base size does not match given data");
giterr_set(GITERR_INVALID, "failed to apply delta: base size does not match given data");
return -1;
}
@ -614,6 +614,6 @@ fail:
*out = NULL;
*out_len = 0;
giterr_set(GITERR_INVALID, "Failed to apply delta");
giterr_set(GITERR_INVALID, "failed to apply delta");
return -1;
}

View File

@ -19,8 +19,6 @@
#include "vector.h"
#include "repository.h"
GIT__USE_OIDMAP
/* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */
struct commit_name {
@ -127,7 +125,7 @@ static int add_to_known_names(
if (!found) {
int ret;
git_oidmap_insert(names, &e->peeled, e, ret);
git_oidmap_insert(names, &e->peeled, e, &ret);
if (ret < 0)
return -1;
}
@ -335,14 +333,14 @@ static int display_name(git_buf *buf, git_repository *repo, struct commit_name *
{
if (n->prio == 2 && !n->tag) {
if (git_tag_lookup(&n->tag, repo, &n->sha1) < 0) {
giterr_set(GITERR_TAG, "Annotated tag '%s' not available", n->path);
giterr_set(GITERR_TAG, "annotated tag '%s' not available", n->path);
return -1;
}
}
if (n->tag && !n->name_checked) {
if (!git_tag_name(n->tag)) {
giterr_set(GITERR_TAG, "Annotated tag '%s' has no embedded name", n->path);
giterr_set(GITERR_TAG, "annotated tag '%s' has no embedded name", n->path);
return -1;
}
@ -471,7 +469,7 @@ static int describe(
if (!data->opts->max_candidates_tags) {
error = describe_not_found(
git_commit_id(commit),
"Cannot describe - no tag exactly matches '%s'");
"cannot describe - no tag exactly matches '%s'");
goto cleanup;
}
@ -564,15 +562,15 @@ static int describe(
}
if (unannotated_cnt) {
error = describe_not_found(git_commit_id(commit),
"Cannot describe - "
"No annotated tags can describe '%s'."
"However, there were unannotated tags.");
"cannot describe - "
"no annotated tags can describe '%s'; "
"however, there were unannotated tags.");
goto cleanup;
}
else {
error = describe_not_found(git_commit_id(commit),
"Cannot describe - "
"No tags can describe '%s'.");
"cannot describe - "
"no tags can describe '%s'.");
goto cleanup;
}
}
@ -695,8 +693,8 @@ int git_describe_commit(
goto cleanup;
if (git_oidmap_size(data.names) == 0 && !opts->show_commit_oid_as_fallback) {
giterr_set(GITERR_DESCRIBE, "Cannot describe - "
"No reference found, cannot describe anything.");
giterr_set(GITERR_DESCRIBE, "cannot describe - "
"no reference found, cannot describe anything.");
error = -1;
goto cleanup;
}
@ -793,7 +791,7 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g
if (opts.always_use_long_format && opts.abbreviated_size == 0) {
giterr_set(GITERR_DESCRIBE, "Cannot describe - "
giterr_set(GITERR_DESCRIBE, "cannot describe - "
"'always_use_long_format' is incompatible with a zero"
"'abbreviated_size'");
return -1;

View File

@ -120,6 +120,41 @@ int git_diff_get_perfdata(git_diff_perfdata *out, const git_diff *diff)
return 0;
}
int git_diff_foreach(
git_diff *diff,
git_diff_file_cb file_cb,
git_diff_binary_cb binary_cb,
git_diff_hunk_cb hunk_cb,
git_diff_line_cb data_cb,
void *payload)
{
int error = 0;
git_diff_delta *delta;
size_t idx;
assert(diff);
git_vector_foreach(&diff->deltas, idx, delta) {
git_patch *patch;
/* check flags against patch status */
if (git_diff_delta__should_skip(&diff->opts, delta))
continue;
if ((error = git_patch_from_diff(&patch, diff, idx)) != 0)
break;
error = git_patch__invoke_callbacks(patch, file_cb, binary_cb,
hunk_cb, data_cb, payload);
git_patch_free(patch);
if (error)
break;
}
return error;
}
int git_diff_format_email__append_header_tobuf(
git_buf *out,
const git_oid *id,

View File

@ -16,8 +16,6 @@
#include "config.h"
#include "repository.h"
GIT__USE_STRMAP
typedef enum {
DIFF_DRIVER_AUTO = 0,
DIFF_DRIVER_BINARY = 1,
@ -151,7 +149,7 @@ static git_diff_driver_registry *git_repository_driver_registry(
}
if (!repo->diff_drivers)
giterr_set(GITERR_REPOSITORY, "Unable to create diff driver registry");
giterr_set(GITERR_REPOSITORY, "unable to create diff driver registry");
return repo->diff_drivers;
}
@ -217,7 +215,7 @@ static int git_diff_driver_builtin(
goto done;
}
git_strmap_insert(reg->drivers, drv->name, drv, error);
git_strmap_insert(reg->drivers, drv->name, drv, &error);
if (error > 0)
error = 0;
@ -331,7 +329,7 @@ static int git_diff_driver_load(
goto done;
/* store driver in registry */
git_strmap_insert(reg->drivers, drv->name, drv, error);
git_strmap_insert(reg->drivers, drv->name, drv, &error);
if (error < 0)
goto done;
error = 0;

View File

@ -304,7 +304,7 @@ static int diff_file_content_load_workdir_symlink(
read_len = p_readlink(git_buf_cstr(path), fc->map.data, alloc_len);
if (read_len < 0) {
giterr_set(GITERR_OS, "Failed to read symlink '%s'", fc->file->path);
giterr_set(GITERR_OS, "failed to read symlink '%s'", fc->file->path);
return -1;
}

View File

@ -624,7 +624,7 @@ int git_diff__oid_for_entry(
error = git_odb__hashlink(out, full_path.ptr);
diff->base.perf.oid_calculations++;
} else if (!git__is_sizet(entry.file_size)) {
giterr_set(GITERR_OS, "File size overflow (for 32-bits) on '%s'",
giterr_set(GITERR_OS, "file size overflow (for 32-bits) on '%s'",
entry.path);
error = -1;
} else if (!(error = git_filter_list_load(&fl,
@ -1587,7 +1587,7 @@ int git_diff__commit(
char commit_oidstr[GIT_OID_HEXSZ + 1];
error = -1;
giterr_set(GITERR_INVALID, "Commit %s is a merge commit",
giterr_set(GITERR_INVALID, "commit %s is a merge commit",
git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit)));
goto on_error;
}

View File

@ -37,7 +37,6 @@ static git_diff_parsed *diff_parsed_alloc(void)
GIT_REFCOUNT_INC(diff);
diff->base.type = GIT_DIFF_TYPE_PARSED;
diff->base.opts.flags &= ~GIT_DIFF_IGNORE_CASE;
diff->base.strcomp = git__strcmp;
diff->base.strncomp = git__strncmp;
diff->base.pfxcomp = git__prefixcmp;
@ -45,6 +44,13 @@ static git_diff_parsed *diff_parsed_alloc(void)
diff->base.patch_fn = git_patch_parsed_from_diff;
diff->base.free_fn = diff_parsed_free;
if (git_diff_init_options(&diff->base.opts, GIT_DIFF_OPTIONS_VERSION) < 0) {
git__free(diff);
return NULL;
}
diff->base.opts.flags &= ~GIT_DIFF_IGNORE_CASE;
git_pool_init(&diff->base.pool, 1);
if (git_vector_init(&diff->patches, 0, NULL) < 0 ||

View File

@ -222,7 +222,7 @@ static int diff_print_one_raw(
if (pi->id_strlen > id_abbrev) {
giterr_set(GITERR_PATCH,
"The patch input contains %d id characters (cannot print %d)",
"the patch input contains %d id characters (cannot print %d)",
id_abbrev, pi->id_strlen);
return -1;
}
@ -273,7 +273,7 @@ static int diff_print_oid_range(
if (delta->old_file.mode &&
id_strlen > delta->old_file.id_abbrev) {
giterr_set(GITERR_PATCH,
"The patch input contains %d id characters (cannot print %d)",
"the patch input contains %d id characters (cannot print %d)",
delta->old_file.id_abbrev, id_strlen);
return -1;
}
@ -281,7 +281,7 @@ static int diff_print_oid_range(
if ((delta->new_file.mode &&
id_strlen > delta->new_file.id_abbrev)) {
giterr_set(GITERR_PATCH,
"The patch input contains %d id characters (cannot print %d)",
"the patch input contains %d id characters (cannot print %d)",
delta->new_file.id_abbrev, id_strlen);
return -1;
}
@ -680,7 +680,7 @@ int git_diff_print(
print_file = diff_print_one_name_status;
break;
default:
giterr_set(GITERR_INVALID, "Unknown diff output format (%d)", format);
giterr_set(GITERR_INVALID, "unknown diff output format (%d)", format);
return -1;
}
@ -708,7 +708,7 @@ int git_diff_print_callback__to_buf(
GIT_UNUSED(delta); GIT_UNUSED(hunk);
if (!output) {
giterr_set(GITERR_INVALID, "Buffer pointer must be provided");
giterr_set(GITERR_INVALID, "buffer pointer must be provided");
return -1;
}

View File

@ -131,7 +131,7 @@ int git_diff__merge(
if (ignore_case != ((from->opts.flags & GIT_DIFF_IGNORE_CASE) != 0) ||
reversed != ((from->opts.flags & GIT_DIFF_REVERSE) != 0)) {
giterr_set(GITERR_INVALID,
"Attempt to merge diffs created with conflicting options");
"attempt to merge diffs created with conflicting options");
return -1;
}
@ -553,8 +553,8 @@ static int similarity_measure(
*score = -1;
/* don't try to compare files of different types */
if (GIT_MODE_TYPE(a_file->mode) != GIT_MODE_TYPE(b_file->mode))
/* don't try to compare things that aren't files */
if (!GIT_MODE_ISBLOB(a_file->mode) || !GIT_MODE_ISBLOB(b_file->mode))
return 0;
/* if exact match is requested, force calculation of missing OIDs now */

View File

@ -50,7 +50,7 @@ static int git_xdiff_parse_hunk(git_diff_hunk *hunk, const char *header)
return 0;
fail:
giterr_set(GITERR_INVALID, "Malformed hunk header from xdiff");
giterr_set(GITERR_INVALID, "malformed hunk header from xdiff");
return -1;
}
@ -99,7 +99,7 @@ static int diff_update_lines(
info->new_lineno += (int)line->num_lines;
break;
default:
giterr_set(GITERR_INVALID, "Unknown diff line origin %02x",
giterr_set(GITERR_INVALID, "unknown diff line origin %02x",
(unsigned int)line->origin);
return -1;
}

View File

@ -113,7 +113,7 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
remote->need_pack = 0;
if (filter_wants(remote, opts) < 0) {
giterr_set(GITERR_NET, "Failed to filter the reference list for wants");
giterr_set(GITERR_NET, "failed to filter the reference list for wants");
return -1;
}

View File

@ -115,7 +115,7 @@ int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs)
assert(repo && fetchhead_refs);
if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
if (git_buf_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0)
return -1;
if (git_filebuf_open(&file, path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE) < 0) {
@ -149,7 +149,7 @@ static int fetchhead_ref_parse(
if (!*line) {
giterr_set(GITERR_FETCHHEAD,
"Empty line in FETCH_HEAD line %"PRIuZ, line_num);
"empty line in FETCH_HEAD line %"PRIuZ, line_num);
return -1;
}
@ -163,13 +163,13 @@ static int fetchhead_ref_parse(
if (strlen(oid_str) != GIT_OID_HEXSZ) {
giterr_set(GITERR_FETCHHEAD,
"Invalid object ID in FETCH_HEAD line %"PRIuZ, line_num);
"invalid object ID in FETCH_HEAD line %"PRIuZ, line_num);
return -1;
}
if (git_oid_fromstr(oid, oid_str) < 0) {
const git_error *oid_err = giterr_last();
const char *err_msg = oid_err ? oid_err->message : "Invalid object ID";
const char *err_msg = oid_err ? oid_err->message : "invalid object ID";
giterr_set(GITERR_FETCHHEAD, "%s in FETCH_HEAD line %"PRIuZ,
err_msg, line_num);
@ -180,7 +180,7 @@ static int fetchhead_ref_parse(
if (*line) {
if ((is_merge_str = git__strsep(&line, "\t")) == NULL) {
giterr_set(GITERR_FETCHHEAD,
"Invalid description data in FETCH_HEAD line %"PRIuZ, line_num);
"invalid description data in FETCH_HEAD line %"PRIuZ, line_num);
return -1;
}
@ -190,13 +190,13 @@ static int fetchhead_ref_parse(
*is_merge = 0;
else {
giterr_set(GITERR_FETCHHEAD,
"Invalid for-merge entry in FETCH_HEAD line %"PRIuZ, line_num);
"invalid for-merge entry in FETCH_HEAD line %"PRIuZ, line_num);
return -1;
}
if ((desc = line) == NULL) {
giterr_set(GITERR_FETCHHEAD,
"Invalid description in FETCH_HEAD line %"PRIuZ, line_num);
"invalid description in FETCH_HEAD line %"PRIuZ, line_num);
return -1;
}
@ -213,7 +213,7 @@ static int fetchhead_ref_parse(
if ((desc = strstr(name, "' ")) == NULL ||
git__prefixcmp(desc, "' of ") != 0) {
giterr_set(GITERR_FETCHHEAD,
"Invalid description in FETCH_HEAD line %"PRIuZ, line_num);
"invalid description in FETCH_HEAD line %"PRIuZ, line_num);
return -1;
}
@ -249,7 +249,7 @@ int git_repository_fetchhead_foreach(git_repository *repo,
assert(repo && cb);
if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
if (git_buf_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0)
return -1;
if ((error = git_futils_readbuffer(&file, git_buf_cstr(&path))) < 0)
@ -277,7 +277,7 @@ int git_repository_fetchhead_foreach(git_repository *repo,
}
if (*buffer) {
giterr_set(GITERR_FETCHHEAD, "No EOL at line %"PRIuZ, line_num+1);
giterr_set(GITERR_FETCHHEAD, "no EOL at line %"PRIuZ, line_num+1);
error = -1;
goto done;
}

View File

@ -23,7 +23,7 @@ static int verify_last_error(git_filebuf *file)
{
switch (file->last_error) {
case BUFERR_WRITE:
giterr_set(GITERR_OS, "Failed to write out file");
giterr_set(GITERR_OS, "failed to write out file");
return -1;
case BUFERR_MEM:
@ -48,7 +48,7 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode)
else {
giterr_clear(); /* actual OS error code just confuses */
giterr_set(GITERR_OS,
"Failed to lock file '%s' for writing", file->path_lock);
"failed to lock file '%s' for writing", file->path_lock);
return GIT_ELOCKED;
}
}
@ -75,7 +75,7 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode)
source = p_open(file->path_original, O_RDONLY);
if (source < 0) {
giterr_set(GITERR_OS,
"Failed to open file '%s' for reading",
"failed to open file '%s' for reading",
file->path_original);
return -1;
}
@ -90,10 +90,10 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode)
p_close(source);
if (read_bytes < 0) {
giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original);
giterr_set(GITERR_OS, "failed to read file '%s'", file->path_original);
return -1;
} else if (error < 0) {
giterr_set(GITERR_OS, "Failed to write file '%s'", file->path_lock);
giterr_set(GITERR_OS, "failed to write file '%s'", file->path_lock);
return -1;
}
}
@ -246,7 +246,7 @@ static int resolve_symlink(git_buf *out, const char *path)
root = git_path_root(target.ptr);
if (root >= 0) {
if ((error = git_buf_puts(&curpath, target.ptr)) < 0)
if ((error = git_buf_sets(&curpath, target.ptr)) < 0)
goto cleanup;
} else {
git_buf dir = GIT_BUF_INIT;
@ -291,6 +291,9 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo
if (flags & GIT_FILEBUF_DO_NOT_BUFFER)
file->do_not_buffer = true;
if (flags & GIT_FILEBUF_FSYNC)
file->do_fsync = true;
file->buf_size = size;
file->buf_pos = 0;
file->fd = -1;
@ -316,7 +319,7 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo
if (compression != 0) {
/* Initialize the ZLib stream */
if (deflateInit(&file->zs, compression) != Z_OK) {
giterr_set(GITERR_ZLIB, "Failed to initialize zlib");
giterr_set(GITERR_ZLIB, "failed to initialize zlib");
goto cleanup;
}
@ -425,18 +428,26 @@ int git_filebuf_commit(git_filebuf *file)
file->fd_is_open = false;
if (file->do_fsync && p_fsync(file->fd) < 0) {
giterr_set(GITERR_OS, "failed to fsync '%s'", file->path_lock);
goto on_error;
}
if (p_close(file->fd) < 0) {
giterr_set(GITERR_OS, "Failed to close file at '%s'", file->path_lock);
giterr_set(GITERR_OS, "failed to close file at '%s'", file->path_lock);
goto on_error;
}
file->fd = -1;
if (p_rename(file->path_lock, file->path_original) < 0) {
giterr_set(GITERR_OS, "Failed to rename lockfile to '%s'", file->path_original);
giterr_set(GITERR_OS, "failed to rename lockfile to '%s'", file->path_original);
goto on_error;
}
if (file->do_fsync && git_futils_fsync_parent(file->path_original) < 0)
goto on_error;
file->did_rename = true;
git_filebuf_cleanup(file);
@ -571,7 +582,7 @@ int git_filebuf_stats(time_t *mtime, size_t *size, git_filebuf *file)
res = p_stat(file->path_original, &st);
if (res < 0) {
giterr_set(GITERR_OS, "Could not get stat info for '%s'",
giterr_set(GITERR_OS, "could not get stat info for '%s'",
file->path_original);
return res;
}

View File

@ -20,7 +20,8 @@
#define GIT_FILEBUF_FORCE (1 << 3)
#define GIT_FILEBUF_TEMPORARY (1 << 4)
#define GIT_FILEBUF_DO_NOT_BUFFER (1 << 5)
#define GIT_FILEBUF_DEFLATE_SHIFT (6)
#define GIT_FILEBUF_FSYNC (1 << 6)
#define GIT_FILEBUF_DEFLATE_SHIFT (7)
#define GIT_FILELOCK_EXTENSION ".lock\0"
#define GIT_FILELOCK_EXTLENGTH 6
@ -47,6 +48,7 @@ struct git_filebuf {
bool created_lock;
bool did_rename;
bool do_not_buffer;
bool do_fsync;
int last_error;
};

View File

@ -13,8 +13,6 @@
#include "win32/findfile.h"
#endif
GIT__USE_STRMAP
int git_futils_mkpath2file(const char *file_path, const mode_t mode)
{
return git_futils_mkdir(
@ -37,13 +35,13 @@ int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode)
if ((fd = p_mkstemp(path_out->ptr)) < 0) {
giterr_set(GITERR_OS,
"Failed to create temporary file '%s'", path_out->ptr);
"failed to create temporary file '%s'", path_out->ptr);
return -1;
}
if (p_chmod(path_out->ptr, (mode & ~mask))) {
giterr_set(GITERR_OS,
"Failed to set permissions on file '%s'", path_out->ptr);
"failed to set permissions on file '%s'", path_out->ptr);
return -1;
}
@ -59,7 +57,7 @@ int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode
fd = p_creat(path, mode);
if (fd < 0) {
giterr_set(GITERR_OS, "Failed to create file '%s'", path);
giterr_set(GITERR_OS, "failed to create file '%s'", path);
return -1;
}
@ -68,12 +66,12 @@ int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode
int git_futils_creat_locked(const char *path, const mode_t mode)
{
int fd = p_open(path, O_WRONLY | O_CREAT | O_TRUNC |
O_EXCL | O_BINARY | O_CLOEXEC, mode);
int fd = p_open(path, O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC,
mode);
if (fd < 0) {
int error = errno;
giterr_set(GITERR_OS, "Failed to create locked file '%s'", path);
giterr_set(GITERR_OS, "failed to create locked file '%s'", path);
switch (error) {
case EEXIST:
return GIT_ELOCKED;
@ -108,7 +106,7 @@ git_off_t git_futils_filesize(git_file fd)
struct stat sb;
if (p_fstat(fd, &sb)) {
giterr_set(GITERR_OS, "Failed to stat file descriptor");
giterr_set(GITERR_OS, "failed to stat file descriptor");
return -1;
}
@ -137,7 +135,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
git_buf_clear(buf);
if (!git__is_ssizet(len)) {
giterr_set(GITERR_INVALID, "Read too large.");
giterr_set(GITERR_INVALID, "read too large");
return -1;
}
@ -149,7 +147,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
read_size = p_read(fd, buf->ptr, len);
if (read_size != (ssize_t)len) {
giterr_set(GITERR_OS, "Failed to read descriptor");
giterr_set(GITERR_OS, "failed to read descriptor");
git_buf_free(buf);
return -1;
}
@ -184,7 +182,7 @@ int git_futils_readbuffer_updated(
}
if (!git__is_sizet(st.st_size+1)) {
giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path);
giterr_set(GITERR_OS, "invalid regular file stat for '%s'", path);
return -1;
}
@ -198,28 +196,29 @@ int git_futils_readbuffer_updated(
p_close(fd);
if ((error = git_hash_buf(&checksum_new, buf.ptr, buf.size)) < 0) {
git_buf_free(&buf);
return error;
}
if (checksum) {
if ((error = git_hash_buf(&checksum_new, buf.ptr, buf.size)) < 0) {
git_buf_free(&buf);
return error;
}
/*
* If we were given a checksum, we only want to use it if it's different
*/
if (checksum && !git_oid__cmp(checksum, &checksum_new)) {
git_buf_free(&buf);
if (updated)
*updated = 0;
/*
* If we were given a checksum, we only want to use it if it's different
*/
if (!git_oid__cmp(checksum, &checksum_new)) {
git_buf_free(&buf);
if (updated)
*updated = 0;
return 0;
return 0;
}
git_oid_cpy(checksum, &checksum_new);
}
/*
* If we're here, the file did change, or the user didn't have an old version
*/
if (checksum)
git_oid_cpy(checksum, &checksum_new);
if (updated != NULL)
*updated = 1;
@ -237,26 +236,43 @@ int git_futils_readbuffer(git_buf *buf, const char *path)
int git_futils_writebuffer(
const git_buf *buf, const char *path, int flags, mode_t mode)
{
int fd, error = 0;
int fd, do_fsync = 0, error = 0;
if (flags <= 0)
if (!flags)
flags = O_CREAT | O_TRUNC | O_WRONLY;
if ((flags & O_FSYNC) != 0)
do_fsync = 1;
flags &= ~O_FSYNC;
if (!mode)
mode = GIT_FILEMODE_BLOB;
if ((fd = p_open(path, flags, mode)) < 0) {
giterr_set(GITERR_OS, "Could not open '%s' for writing", path);
giterr_set(GITERR_OS, "could not open '%s' for writing", path);
return fd;
}
if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) {
giterr_set(GITERR_OS, "Could not write to '%s'", path);
giterr_set(GITERR_OS, "could not write to '%s'", path);
(void)p_close(fd);
return error;
}
if ((error = p_close(fd)) < 0)
giterr_set(GITERR_OS, "Error while closing '%s'", path);
if (do_fsync && (error = p_fsync(fd)) < 0) {
giterr_set(GITERR_OS, "could not fsync '%s'", path);
p_close(fd);
return error;
}
if ((error = p_close(fd)) < 0) {
giterr_set(GITERR_OS, "error while closing '%s'", path);
return error;
}
if (do_fsync && (flags & O_CREAT))
error = git_futils_fsync_parent(path);
return error;
}
@ -267,7 +283,7 @@ int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmod
return -1;
if (p_rename(from, to) < 0) {
giterr_set(GITERR_OS, "Failed to rename '%s' to '%s'", from, to);
giterr_set(GITERR_OS, "failed to rename '%s' to '%s'", from, to);
return -1;
}
@ -288,13 +304,19 @@ int git_futils_mmap_ro_file(git_map *out, const char *path)
if (fd < 0)
return fd;
len = git_futils_filesize(fd);
if ((len = git_futils_filesize(fd)) < 0) {
result = -1;
goto out;
}
if (!git__is_sizet(len)) {
giterr_set(GITERR_OS, "File `%s` too large to mmap", path);
return -1;
giterr_set(GITERR_OS, "file `%s` too large to mmap", path);
result = -1;
goto out;
}
result = git_futils_mmap_ro(out, fd, 0, (size_t)len);
out:
p_close(fd);
return result;
}
@ -314,14 +336,14 @@ GIT_INLINE(int) mkdir_validate_dir(
/* with exclusive create, existing dir is an error */
if ((flags & GIT_MKDIR_EXCL) != 0) {
giterr_set(GITERR_FILESYSTEM,
"Failed to make directory '%s': directory exists", path);
"failed to make directory '%s': directory exists", path);
return GIT_EEXISTS;
}
if ((S_ISREG(st->st_mode) && (flags & GIT_MKDIR_REMOVE_FILES)) ||
(S_ISLNK(st->st_mode) && (flags & GIT_MKDIR_REMOVE_SYMLINKS))) {
if (p_unlink(path) < 0) {
giterr_set(GITERR_OS, "Failed to remove %s '%s'",
giterr_set(GITERR_OS, "failed to remove %s '%s'",
S_ISLNK(st->st_mode) ? "symlink" : "file", path);
return GIT_EEXISTS;
}
@ -329,7 +351,7 @@ GIT_INLINE(int) mkdir_validate_dir(
opts->perfdata.mkdir_calls++;
if (p_mkdir(path, mode) < 0) {
giterr_set(GITERR_OS, "Failed to make directory '%s'", path);
giterr_set(GITERR_OS, "failed to make directory '%s'", path);
return GIT_EEXISTS;
}
}
@ -339,14 +361,14 @@ GIT_INLINE(int) mkdir_validate_dir(
opts->perfdata.stat_calls++;
if (p_stat(path, st) < 0) {
giterr_set(GITERR_OS, "Failed to make directory '%s'", path);
giterr_set(GITERR_OS, "failed to make directory '%s'", path);
return GIT_EEXISTS;
}
}
else if (!S_ISDIR(st->st_mode)) {
giterr_set(GITERR_FILESYSTEM,
"Failed to make directory '%s': directory exists", path);
"failed to make directory '%s': directory exists", path);
return GIT_EEXISTS;
}
@ -569,7 +591,7 @@ int git_futils_mkdir_relative(
retry_lstat:
if (p_lstat(make_path.ptr, &st) < 0) {
if (mkdir_attempted || errno != ENOENT) {
giterr_set(GITERR_OS, "Cannot access component in path '%s'", make_path.ptr);
giterr_set(GITERR_OS, "cannot access component in path '%s'", make_path.ptr);
error = -1;
goto done;
}
@ -580,7 +602,7 @@ retry_lstat:
if (p_mkdir(make_path.ptr, mode) < 0) {
if (errno == EEXIST)
goto retry_lstat;
giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
giterr_set(GITERR_OS, "failed to make directory '%s'", make_path.ptr);
error = -1;
goto done;
}
@ -607,7 +629,7 @@ retry_lstat:
memcpy(cache_path, make_path.ptr, make_path.size + 1);
git_strmap_insert(opts->dir_map, cache_path, cache_path, error);
git_strmap_insert(opts->dir_map, cache_path, cache_path, &error);
if (error < 0)
goto done;
}
@ -621,7 +643,7 @@ retry_lstat:
opts->perfdata.stat_calls++;
if (p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode)) {
giterr_set(GITERR_OS, "Path is not a directory '%s'",
giterr_set(GITERR_OS, "path is not a directory '%s'",
make_path.ptr);
error = GIT_ENOTFOUND;
}
@ -644,10 +666,10 @@ typedef struct {
static int futils__error_cannot_rmdir(const char *path, const char *filemsg)
{
if (filemsg)
giterr_set(GITERR_OS, "Could not remove directory. File '%s' %s",
giterr_set(GITERR_OS, "could not remove directory '%s': %s",
path, filemsg);
else
giterr_set(GITERR_OS, "Could not remove directory '%s'", path);
giterr_set(GITERR_OS, "could not remove directory '%s'", path);
return -1;
}
@ -748,6 +770,9 @@ static int futils__rmdir_empty_parent(void *opaque, const char *path)
if (en == ENOENT || en == ENOTDIR) {
/* do nothing */
} else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0 &&
en == EBUSY) {
error = git_path_set_error(errno, path, "rmdir");
} else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
error = GIT_ITEROVER;
} else {
@ -815,7 +840,7 @@ static int cp_by_fd(int ifd, int ofd, bool close_fd_when_done)
error = p_write(ofd, buffer, len);
if (len < 0) {
giterr_set(GITERR_OS, "Read error while copying file");
giterr_set(GITERR_OS, "read error while copying file");
error = (int)len;
}
@ -871,14 +896,14 @@ static int cp_link(const char *from, const char *to, size_t link_size)
read_len = p_readlink(from, link_data, link_size);
if (read_len != (ssize_t)link_size) {
giterr_set(GITERR_OS, "Failed to read symlink data for '%s'", from);
giterr_set(GITERR_OS, "failed to read symlink data for '%s'", from);
error = -1;
}
else {
link_data[read_len] = '\0';
if (p_symlink(link_data, to) < 0) {
giterr_set(GITERR_OS, "Could not symlink '%s' as '%s'",
giterr_set(GITERR_OS, "could not symlink '%s' as '%s'",
link_data, to);
error = -1;
}
@ -974,7 +999,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
return 0;
if (p_unlink(info->to.ptr) < 0) {
giterr_set(GITERR_OS, "Cannot overwrite existing file '%s'",
giterr_set(GITERR_OS, "cannot overwrite existing file '%s'",
info->to.ptr);
return GIT_EEXISTS;
}
@ -1109,3 +1134,37 @@ void git_futils_filestamp_set_from_stat(
memset(stamp, 0, sizeof(*stamp));
}
}
int git_futils_fsync_dir(const char *path)
{
#ifdef GIT_WIN32
GIT_UNUSED(path);
return 0;
#else
int fd, error = -1;
if ((fd = p_open(path, O_RDONLY)) < 0) {
giterr_set(GITERR_OS, "failed to open directory '%s' for fsync", path);
return -1;
}
if ((error = p_fsync(fd)) < 0)
giterr_set(GITERR_OS, "failed to fsync directory '%s'", path);
p_close(fd);
return error;
#endif
}
int git_futils_fsync_parent(const char *path)
{
char *parent;
int error;
if ((parent = git_path_dirname(path)) == NULL)
return -1;
error = git_futils_fsync_dir(parent);
git__free(parent);
return error;
}

View File

@ -25,6 +25,13 @@ extern int git_futils_readbuffer_updated(
git_buf *obj, const char *path, git_oid *checksum, int *updated);
extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len);
/* Additional constants for `git_futils_writebuffer`'s `open_flags`. We
* support these internally and they will be removed before the `open` call.
*/
#ifndef O_FSYNC
# define O_FSYNC (1 << 31)
#endif
extern int git_futils_writebuffer(
const git_buf *buf, const char *path, int open_flags, mode_t mode);
@ -356,4 +363,22 @@ extern void git_futils_filestamp_set(
extern void git_futils_filestamp_set_from_stat(
git_futils_filestamp *stamp, struct stat *st);
/**
* `fsync` the parent directory of the given path, if `fsync` is
* supported for directories on this platform.
*
* @param path Path of the directory to sync.
* @return 0 on success, -1 on error
*/
extern int git_futils_fsync_dir(const char *path);
/**
* `fsync` the parent directory of the given path, if `fsync` is
* supported for directories on this platform.
*
* @param path Path of the file whose parent directory should be synced.
* @return 0 on success, -1 on error
*/
extern int git_futils_fsync_parent(const char *path);
#endif /* INCLUDE_fileops_h__ */

View File

@ -296,7 +296,7 @@ int git_filter_unregister(const char *name)
/* cannot unregister default filters */
if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) {
giterr_set(GITERR_FILTER, "Cannot unregister filter '%s'", name);
giterr_set(GITERR_FILTER, "cannot unregister filter '%s'", name);
return -1;
}
@ -306,7 +306,7 @@ int git_filter_unregister(const char *name)
}
if ((fdef = filter_registry_lookup(&pos, name)) == NULL) {
giterr_set(GITERR_FILTER, "Cannot find filter '%s' to unregister", name);
giterr_set(GITERR_FILTER, "cannot find filter '%s' to unregister", name);
error = GIT_ENOTFOUND;
goto done;
}
@ -645,7 +645,7 @@ int git_filter_list_push(
git_rwlock_rdunlock(&filter_registry.lock);
if (fdef == NULL) {
giterr_set(GITERR_FILTER, "Cannot use an unregistered filter");
giterr_set(GITERR_FILTER, "cannot use an unregistered filter");
return -1;
}
@ -758,7 +758,7 @@ static int buf_from_blob(git_buf *out, git_blob *blob)
git_off_t rawsize = git_blob_rawsize(blob);
if (!git__is_sizet(rawsize)) {
giterr_set(GITERR_OS, "Blob is too large to filter");
giterr_set(GITERR_OS, "blob is too large to filter");
return -1;
}
@ -911,14 +911,19 @@ static int stream_list_init(
last_stream);
if (error < 0)
return error;
goto out;
git_vector_insert(streams, filter_stream);
last_stream = filter_stream;
}
*out = last_stream;
return 0;
out:
if (error)
last_stream->close(last_stream);
else
*out = last_stream;
return error;
}
void stream_list_free(git_vector *streams)
@ -943,12 +948,13 @@ int git_filter_list_stream_file(
git_vector filter_streams = GIT_VECTOR_INIT;
git_writestream *stream_start;
ssize_t readlen;
int fd = -1, error;
int fd = -1, error, initialized = 0;
if ((error = stream_list_init(
&stream_start, &filter_streams, filters, target)) < 0 ||
(error = git_path_join_unrooted(&abspath, path, base, NULL)) < 0)
goto done;
initialized = 1;
if ((fd = git_futils_open_ro(abspath.ptr)) < 0) {
error = fd;
@ -960,13 +966,13 @@ int git_filter_list_stream_file(
goto done;
}
if (!readlen)
error = stream_start->close(stream_start);
else if (readlen < 0)
if (readlen < 0)
error = readlen;
done:
if (initialized)
error |= stream_start->close(stream_start);
if (fd >= 0)
p_close(fd);
stream_list_free(&filter_streams);
@ -981,20 +987,24 @@ int git_filter_list_stream_data(
{
git_vector filter_streams = GIT_VECTOR_INIT;
git_writestream *stream_start;
int error = 0, close_error;
int error, initialized = 0;
git_buf_sanitize(data);
if ((error = stream_list_init(&stream_start, &filter_streams, filters, target)) < 0)
goto out;
initialized = 1;
error = stream_start->write(stream_start, data->ptr, data->size);
if ((error = stream_start->write(
stream_start, data->ptr, data->size)) < 0)
goto out;
out:
close_error = stream_start->close(stream_start);
if (initialized)
error |= stream_start->close(stream_start);
stream_list_free(&filter_streams);
/* propagate the stream init or write error */
return error < 0 ? error : close_error;
return error;
}
int git_filter_list_stream_blob(
@ -1012,3 +1022,9 @@ int git_filter_list_stream_blob(
return git_filter_list_stream_data(filters, &in, target);
}
int git_filter_init(git_filter *filter, unsigned int version)
{
GIT_INIT_STRUCTURE_FROM_TEMPLATE(filter, version, git_filter, GIT_FILTER_INIT);
return 0;
}

View File

@ -22,7 +22,7 @@
git_mutex git__mwindow_mutex;
#define MAX_SHUTDOWN_CB 8
#define MAX_SHUTDOWN_CB 9
static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
static git_atomic git__n_shutdown_callbacks;

View File

@ -16,11 +16,13 @@ int git_hash_global_init(void);
int git_hash_ctx_init(git_hash_ctx *ctx);
void git_hash_ctx_cleanup(git_hash_ctx *ctx);
#if defined(GIT_COMMON_CRYPTO)
#if defined(GIT_SHA1_COLLISIONDETECT)
# include "hash/hash_collisiondetect.h"
#elif defined(GIT_SHA1_COMMON_CRYPTO)
# include "hash/hash_common_crypto.h"
#elif defined(OPENSSL_SHA1)
#elif defined(GIT_SHA1_OPENSSL)
# include "hash/hash_openssl.h"
#elif defined(WIN32_SHA1)
#elif defined(GIT_SHA1_WIN32)
# include "hash/hash_win32.h"
#else
# include "hash/hash_generic.h"

View File

@ -0,0 +1,47 @@
/*
* 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_hash_collisiondetect_h__
#define INCLUDE_hash_collisiondetect_h__
#include "hash.h"
#include "sha1dc/sha1.h"
struct git_hash_ctx {
SHA1_CTX c;
};
#define git_hash_global_init() 0
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
#define git_hash_ctx_cleanup(ctx)
GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx)
{
assert(ctx);
SHA1DCInit(&ctx->c);
return 0;
}
GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
{
assert(ctx);
SHA1DCUpdate(&ctx->c, data, len);
return 0;
}
GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx)
{
assert(ctx);
if (SHA1DCFinal(out->id, &ctx->c)) {
giterr_set(GITERR_SHA1, "SHA1 collision attack detected");
return -1;
}
return 0;
}
#endif /* INCLUDE_hash_collisiondetect_h__ */

1856
src/hash/sha1dc/sha1.c Normal file

File diff suppressed because it is too large Load Diff

110
src/hash/sha1dc/sha1.h Normal file
View File

@ -0,0 +1,110 @@
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/
#ifndef SHA1DC_SHA1_H
#define SHA1DC_SHA1_H
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef SHA1DC_NO_STANDARD_INCLUDES
#include <stdint.h>
#endif
/* sha-1 compression function that takes an already expanded message, and additionally store intermediate states */
/* only stores states ii (the state between step ii-1 and step ii) when DOSTORESTATEii is defined in ubc_check.h */
void sha1_compression_states(uint32_t[5], const uint32_t[16], uint32_t[80], uint32_t[80][5]);
/*
// Function type for sha1_recompression_step_T (uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5]).
// Where 0 <= T < 80
// me2 is an expanded message (the expansion of an original message block XOR'ed with a disturbance vector's message block difference.)
// state is the internal state (a,b,c,d,e) before step T of the SHA-1 compression function while processing the original message block.
// The function will return:
// ihvin: The reconstructed input chaining value.
// ihvout: The reconstructed output chaining value.
*/
typedef void(*sha1_recompression_type)(uint32_t*, uint32_t*, const uint32_t*, const uint32_t*);
/* A callback function type that can be set to be called when a collision block has been found: */
/* void collision_block_callback(uint64_t byteoffset, const uint32_t ihvin1[5], const uint32_t ihvin2[5], const uint32_t m1[80], const uint32_t m2[80]) */
typedef void(*collision_block_callback)(uint64_t, const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
/* The SHA-1 context. */
typedef struct {
uint64_t total;
uint32_t ihv[5];
unsigned char buffer[64];
int found_collision;
int safe_hash;
int detect_coll;
int ubc_check;
int reduced_round_coll;
collision_block_callback callback;
uint32_t ihv1[5];
uint32_t ihv2[5];
uint32_t m1[80];
uint32_t m2[80];
uint32_t states[80][5];
} SHA1_CTX;
/* Initialize SHA-1 context. */
void SHA1DCInit(SHA1_CTX*);
/*
Function to enable safe SHA-1 hashing:
Collision attacks are thwarted by hashing a detected near-collision block 3 times.
Think of it as extending SHA-1 from 80-steps to 240-steps for such blocks:
The best collision attacks against SHA-1 have complexity about 2^60,
thus for 240-steps an immediate lower-bound for the best cryptanalytic attacks would be 2^180.
An attacker would be better off using a generic birthday search of complexity 2^80.
Enabling safe SHA-1 hashing will result in the correct SHA-1 hash for messages where no collision attack was detected,
but it will result in a different SHA-1 hash for messages where a collision attack was detected.
This will automatically invalidate SHA-1 based digital signature forgeries.
Enabled by default.
*/
void SHA1DCSetSafeHash(SHA1_CTX*, int);
/*
Function to disable or enable the use of Unavoidable Bitconditions (provides a significant speed up).
Enabled by default
*/
void SHA1DCSetUseUBC(SHA1_CTX*, int);
/*
Function to disable or enable the use of Collision Detection.
Enabled by default.
*/
void SHA1DCSetUseDetectColl(SHA1_CTX*, int);
/* function to disable or enable the detection of reduced-round SHA-1 collisions */
/* disabled by default */
void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX*, int);
/* function to set a callback function, pass NULL to disable */
/* by default no callback set */
void SHA1DCSetCallback(SHA1_CTX*, collision_block_callback);
/* update SHA-1 context with buffer contents */
void SHA1DCUpdate(SHA1_CTX*, const char*, size_t);
/* obtain SHA-1 hash from SHA-1 context */
/* returns: 0 = no collision detected, otherwise = collision found => warn user for active attack */
int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
#if defined(__cplusplus)
}
#endif
#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
#include SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
#endif
#endif

372
src/hash/sha1dc/ubc_check.c Normal file
View File

@ -0,0 +1,372 @@
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/
/*
// this file was generated by the 'parse_bitrel' program in the tools section
// using the data files from directory 'tools/data/3565'
//
// sha1_dvs contains a list of SHA-1 Disturbance Vectors (DV) to check
// dvType, dvK and dvB define the DV: I(K,B) or II(K,B) (see the paper)
// dm[80] is the expanded message block XOR-difference defined by the DV
// testt is the step to do the recompression from for collision detection
// maski and maskb define the bit to check for each DV in the dvmask returned by ubc_check
//
// ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs
// it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met
// thus one needs to do the recompression check for each DV that has its bit set
//
// ubc_check is programmatically generated and the unavoidable bitconditions have been hardcoded
// a directly verifiable version named ubc_check_verify can be found in ubc_check_verify.c
// ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section
*/
#ifndef SHA1DC_NO_STANDARD_INCLUDES
#include <stdint.h>
#endif
#ifdef SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
#include SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
#endif
#include "ubc_check.h"
static const uint32_t DV_I_43_0_bit = (uint32_t)(1) << 0;
static const uint32_t DV_I_44_0_bit = (uint32_t)(1) << 1;
static const uint32_t DV_I_45_0_bit = (uint32_t)(1) << 2;
static const uint32_t DV_I_46_0_bit = (uint32_t)(1) << 3;
static const uint32_t DV_I_46_2_bit = (uint32_t)(1) << 4;
static const uint32_t DV_I_47_0_bit = (uint32_t)(1) << 5;
static const uint32_t DV_I_47_2_bit = (uint32_t)(1) << 6;
static const uint32_t DV_I_48_0_bit = (uint32_t)(1) << 7;
static const uint32_t DV_I_48_2_bit = (uint32_t)(1) << 8;
static const uint32_t DV_I_49_0_bit = (uint32_t)(1) << 9;
static const uint32_t DV_I_49_2_bit = (uint32_t)(1) << 10;
static const uint32_t DV_I_50_0_bit = (uint32_t)(1) << 11;
static const uint32_t DV_I_50_2_bit = (uint32_t)(1) << 12;
static const uint32_t DV_I_51_0_bit = (uint32_t)(1) << 13;
static const uint32_t DV_I_51_2_bit = (uint32_t)(1) << 14;
static const uint32_t DV_I_52_0_bit = (uint32_t)(1) << 15;
static const uint32_t DV_II_45_0_bit = (uint32_t)(1) << 16;
static const uint32_t DV_II_46_0_bit = (uint32_t)(1) << 17;
static const uint32_t DV_II_46_2_bit = (uint32_t)(1) << 18;
static const uint32_t DV_II_47_0_bit = (uint32_t)(1) << 19;
static const uint32_t DV_II_48_0_bit = (uint32_t)(1) << 20;
static const uint32_t DV_II_49_0_bit = (uint32_t)(1) << 21;
static const uint32_t DV_II_49_2_bit = (uint32_t)(1) << 22;
static const uint32_t DV_II_50_0_bit = (uint32_t)(1) << 23;
static const uint32_t DV_II_50_2_bit = (uint32_t)(1) << 24;
static const uint32_t DV_II_51_0_bit = (uint32_t)(1) << 25;
static const uint32_t DV_II_51_2_bit = (uint32_t)(1) << 26;
static const uint32_t DV_II_52_0_bit = (uint32_t)(1) << 27;
static const uint32_t DV_II_53_0_bit = (uint32_t)(1) << 28;
static const uint32_t DV_II_54_0_bit = (uint32_t)(1) << 29;
static const uint32_t DV_II_55_0_bit = (uint32_t)(1) << 30;
static const uint32_t DV_II_56_0_bit = (uint32_t)(1) << 31;
dv_info_t sha1_dvs[] =
{
{1,43,0,58,0,0, { 0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803,0x80000161,0x80000599 } }
, {1,44,0,58,0,1, { 0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803,0x80000161 } }
, {1,45,0,58,0,2, { 0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803 } }
, {1,46,0,58,0,3, { 0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c } }
, {1,46,2,58,0,4, { 0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590,0x00001020,0x0000039a,0x00000132 } }
, {1,47,0,58,0,5, { 0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6 } }
, {1,47,2,58,0,6, { 0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590,0x00001020,0x0000039a } }
, {1,48,0,58,0,7, { 0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408 } }
, {1,48,2,58,0,8, { 0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590,0x00001020 } }
, {1,49,0,58,0,9, { 0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164 } }
, {1,49,2,58,0,10, { 0x60000000,0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060,0x00000590 } }
, {1,50,0,65,0,11, { 0x0800000c,0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018 } }
, {1,50,2,65,0,12, { 0x20000030,0x60000000,0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a,0x00000060 } }
, {1,51,0,65,0,13, { 0xe8000000,0x0800000c,0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202 } }
, {1,51,2,65,0,14, { 0xa0000003,0x20000030,0x60000000,0xe000002a,0x20000043,0xb0000040,0xd0000053,0xd0000022,0x20000000,0x60000032,0x60000043,0x20000040,0xe0000042,0x60000002,0x80000001,0x00000020,0x00000003,0x40000052,0x40000040,0xe0000052,0xa0000000,0x80000040,0x20000001,0x20000060,0x80000001,0x40000042,0xc0000043,0x40000022,0x00000003,0x40000042,0xc0000043,0xc0000022,0x00000001,0x40000002,0xc0000043,0x40000062,0x80000001,0x40000042,0x40000042,0x40000002,0x00000002,0x00000040,0x80000002,0x80000000,0x80000002,0x80000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000000,0x00000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000101,0x00000009,0x00000012,0x00000202,0x0000001a,0x00000124,0x0000040c,0x00000026,0x0000004a,0x0000080a } }
, {1,52,0,65,0,15, { 0x04000010,0xe8000000,0x0800000c,0x18000000,0xb800000a,0xc8000010,0x2c000010,0xf4000014,0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012 } }
, {2,45,0,58,0,16, { 0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a,0x000002e4,0x80000054,0x00000967 } }
, {2,46,0,58,0,17, { 0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a,0x000002e4,0x80000054 } }
, {2,46,2,58,0,18, { 0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e,0x0000046c,0x000005b6,0x0000106a,0x00000b90,0x00000152 } }
, {2,47,0,58,0,19, { 0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a,0x000002e4 } }
, {2,48,0,58,0,20, { 0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d,0x8000041a } }
, {2,49,0,58,0,21, { 0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b,0x8000016d } }
, {2,49,2,58,0,22, { 0xf0000010,0xf000006a,0x80000040,0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e,0x0000046c,0x000005b6 } }
, {2,50,0,65,0,23, { 0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b,0x0000011b } }
, {2,50,2,65,0,24, { 0xd0000072,0xf0000010,0xf000006a,0x80000040,0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e,0x0000046c } }
, {2,51,0,65,0,25, { 0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014,0x8000024b } }
, {2,51,2,65,0,26, { 0x00000043,0xd0000072,0xf0000010,0xf000006a,0x80000040,0x90000070,0xb0000053,0x30000008,0x00000043,0xd0000072,0xb0000010,0xf0000062,0xc0000042,0x00000030,0xe0000042,0x20000060,0xe0000041,0x20000050,0xc0000041,0xe0000072,0xa0000003,0xc0000012,0x60000041,0xc0000032,0x20000001,0xc0000002,0xe0000042,0x60000042,0x80000002,0x00000000,0x00000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000000,0x00000040,0x80000001,0x00000060,0x80000003,0x40000002,0xc0000040,0xc0000002,0x80000000,0x80000000,0x80000002,0x00000040,0x00000002,0x80000000,0x80000000,0x80000000,0x00000002,0x00000040,0x00000000,0x80000040,0x80000002,0x00000000,0x80000000,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000004,0x00000080,0x00000004,0x00000009,0x00000105,0x00000089,0x00000016,0x0000020b,0x0000011b,0x0000012d,0x0000041e,0x00000224,0x00000050,0x0000092e } }
, {2,52,0,65,0,27, { 0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089,0x00000014 } }
, {2,53,0,65,0,28, { 0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107,0x00000089 } }
, {2,54,0,65,0,29, { 0x0400001c,0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b,0x80000107 } }
, {2,55,0,65,0,30, { 0x00000010,0x0400001c,0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046,0x4000004b } }
, {2,56,0,65,0,31, { 0x2600001a,0x00000010,0x0400001c,0xcc000014,0x0c000002,0xc0000010,0xb400001c,0x3c000004,0xbc00001a,0x20000010,0x2400001c,0xec000014,0x0c000002,0xc0000010,0xb400001c,0x2c000004,0xbc000018,0xb0000010,0x0000000c,0xb8000010,0x08000018,0x78000010,0x08000014,0x70000010,0xb800001c,0xe8000000,0xb0000004,0x58000010,0xb000000c,0x48000000,0xb0000000,0xb8000010,0x98000010,0xa0000000,0x00000000,0x00000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0x20000000,0x00000010,0x60000000,0x00000018,0xe0000000,0x90000000,0x30000010,0xb0000000,0x20000000,0x20000000,0xa0000000,0x00000010,0x80000000,0x20000000,0x20000000,0x20000000,0x80000000,0x00000010,0x00000000,0x20000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000041,0x40000022,0x80000005,0xc0000082,0xc0000046 } }
, {0,0,0,0,0,0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
};
void ubc_check(const uint32_t W[80], uint32_t dvmask[1])
{
uint32_t mask = ~((uint32_t)(0));
mask &= (((((W[44]^W[45])>>29)&1)-1) | ~(DV_I_48_0_bit|DV_I_51_0_bit|DV_I_52_0_bit|DV_II_45_0_bit|DV_II_46_0_bit|DV_II_50_0_bit|DV_II_51_0_bit));
mask &= (((((W[49]^W[50])>>29)&1)-1) | ~(DV_I_46_0_bit|DV_II_45_0_bit|DV_II_50_0_bit|DV_II_51_0_bit|DV_II_55_0_bit|DV_II_56_0_bit));
mask &= (((((W[48]^W[49])>>29)&1)-1) | ~(DV_I_45_0_bit|DV_I_52_0_bit|DV_II_49_0_bit|DV_II_50_0_bit|DV_II_54_0_bit|DV_II_55_0_bit));
mask &= ((((W[47]^(W[50]>>25))&(1<<4))-(1<<4)) | ~(DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_51_0_bit|DV_II_56_0_bit));
mask &= (((((W[47]^W[48])>>29)&1)-1) | ~(DV_I_44_0_bit|DV_I_51_0_bit|DV_II_48_0_bit|DV_II_49_0_bit|DV_II_53_0_bit|DV_II_54_0_bit));
mask &= (((((W[46]>>4)^(W[49]>>29))&1)-1) | ~(DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit|DV_II_50_0_bit|DV_II_55_0_bit));
mask &= (((((W[46]^W[47])>>29)&1)-1) | ~(DV_I_43_0_bit|DV_I_50_0_bit|DV_II_47_0_bit|DV_II_48_0_bit|DV_II_52_0_bit|DV_II_53_0_bit));
mask &= (((((W[45]>>4)^(W[48]>>29))&1)-1) | ~(DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit|DV_II_49_0_bit|DV_II_54_0_bit));
mask &= (((((W[45]^W[46])>>29)&1)-1) | ~(DV_I_49_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_47_0_bit|DV_II_51_0_bit|DV_II_52_0_bit));
mask &= (((((W[44]>>4)^(W[47]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit|DV_II_48_0_bit|DV_II_53_0_bit));
mask &= (((((W[43]>>4)^(W[46]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit|DV_II_47_0_bit|DV_II_52_0_bit));
mask &= (((((W[43]^W[44])>>29)&1)-1) | ~(DV_I_47_0_bit|DV_I_50_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_49_0_bit|DV_II_50_0_bit));
mask &= (((((W[42]>>4)^(W[45]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_51_0_bit));
mask &= (((((W[41]>>4)^(W[44]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_50_0_bit));
mask &= (((((W[40]^W[41])>>29)&1)-1) | ~(DV_I_44_0_bit|DV_I_47_0_bit|DV_I_48_0_bit|DV_II_46_0_bit|DV_II_47_0_bit|DV_II_56_0_bit));
mask &= (((((W[54]^W[55])>>29)&1)-1) | ~(DV_I_51_0_bit|DV_II_47_0_bit|DV_II_50_0_bit|DV_II_55_0_bit|DV_II_56_0_bit));
mask &= (((((W[53]^W[54])>>29)&1)-1) | ~(DV_I_50_0_bit|DV_II_46_0_bit|DV_II_49_0_bit|DV_II_54_0_bit|DV_II_55_0_bit));
mask &= (((((W[52]^W[53])>>29)&1)-1) | ~(DV_I_49_0_bit|DV_II_45_0_bit|DV_II_48_0_bit|DV_II_53_0_bit|DV_II_54_0_bit));
mask &= ((((W[50]^(W[53]>>25))&(1<<4))-(1<<4)) | ~(DV_I_50_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_48_0_bit|DV_II_54_0_bit));
mask &= (((((W[50]^W[51])>>29)&1)-1) | ~(DV_I_47_0_bit|DV_II_46_0_bit|DV_II_51_0_bit|DV_II_52_0_bit|DV_II_56_0_bit));
mask &= ((((W[49]^(W[52]>>25))&(1<<4))-(1<<4)) | ~(DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit|DV_II_47_0_bit|DV_II_53_0_bit));
mask &= ((((W[48]^(W[51]>>25))&(1<<4))-(1<<4)) | ~(DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit|DV_II_46_0_bit|DV_II_52_0_bit));
mask &= (((((W[42]^W[43])>>29)&1)-1) | ~(DV_I_46_0_bit|DV_I_49_0_bit|DV_I_50_0_bit|DV_II_48_0_bit|DV_II_49_0_bit));
mask &= (((((W[41]^W[42])>>29)&1)-1) | ~(DV_I_45_0_bit|DV_I_48_0_bit|DV_I_49_0_bit|DV_II_47_0_bit|DV_II_48_0_bit));
mask &= (((((W[40]>>4)^(W[43]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_50_0_bit|DV_II_49_0_bit|DV_II_56_0_bit));
mask &= (((((W[39]>>4)^(W[42]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_49_0_bit|DV_II_48_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_44_0_bit|DV_I_48_0_bit|DV_II_47_0_bit|DV_II_54_0_bit|DV_II_56_0_bit))
mask &= (((((W[38]>>4)^(W[41]>>29))&1)-1) | ~(DV_I_44_0_bit|DV_I_48_0_bit|DV_II_47_0_bit|DV_II_54_0_bit|DV_II_56_0_bit));
mask &= (((((W[37]>>4)^(W[40]>>29))&1)-1) | ~(DV_I_43_0_bit|DV_I_47_0_bit|DV_II_46_0_bit|DV_II_53_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_52_0_bit|DV_II_48_0_bit|DV_II_51_0_bit|DV_II_56_0_bit))
mask &= (((((W[55]^W[56])>>29)&1)-1) | ~(DV_I_52_0_bit|DV_II_48_0_bit|DV_II_51_0_bit|DV_II_56_0_bit));
if (mask & (DV_I_52_0_bit|DV_II_48_0_bit|DV_II_50_0_bit|DV_II_56_0_bit))
mask &= ((((W[52]^(W[55]>>25))&(1<<4))-(1<<4)) | ~(DV_I_52_0_bit|DV_II_48_0_bit|DV_II_50_0_bit|DV_II_56_0_bit));
if (mask & (DV_I_51_0_bit|DV_II_47_0_bit|DV_II_49_0_bit|DV_II_55_0_bit))
mask &= ((((W[51]^(W[54]>>25))&(1<<4))-(1<<4)) | ~(DV_I_51_0_bit|DV_II_47_0_bit|DV_II_49_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_48_0_bit|DV_II_47_0_bit|DV_II_52_0_bit|DV_II_53_0_bit))
mask &= (((((W[51]^W[52])>>29)&1)-1) | ~(DV_I_48_0_bit|DV_II_47_0_bit|DV_II_52_0_bit|DV_II_53_0_bit));
if (mask & (DV_I_46_0_bit|DV_I_49_0_bit|DV_II_45_0_bit|DV_II_48_0_bit))
mask &= (((((W[36]>>4)^(W[40]>>29))&1)-1) | ~(DV_I_46_0_bit|DV_I_49_0_bit|DV_II_45_0_bit|DV_II_48_0_bit));
if (mask & (DV_I_52_0_bit|DV_II_48_0_bit|DV_II_49_0_bit))
mask &= ((0-(((W[53]^W[56])>>29)&1)) | ~(DV_I_52_0_bit|DV_II_48_0_bit|DV_II_49_0_bit));
if (mask & (DV_I_50_0_bit|DV_II_46_0_bit|DV_II_47_0_bit))
mask &= ((0-(((W[51]^W[54])>>29)&1)) | ~(DV_I_50_0_bit|DV_II_46_0_bit|DV_II_47_0_bit));
if (mask & (DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit))
mask &= ((0-(((W[50]^W[52])>>29)&1)) | ~(DV_I_49_0_bit|DV_I_51_0_bit|DV_II_45_0_bit));
if (mask & (DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit))
mask &= ((0-(((W[49]^W[51])>>29)&1)) | ~(DV_I_48_0_bit|DV_I_50_0_bit|DV_I_52_0_bit));
if (mask & (DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit))
mask &= ((0-(((W[48]^W[50])>>29)&1)) | ~(DV_I_47_0_bit|DV_I_49_0_bit|DV_I_51_0_bit));
if (mask & (DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit))
mask &= ((0-(((W[47]^W[49])>>29)&1)) | ~(DV_I_46_0_bit|DV_I_48_0_bit|DV_I_50_0_bit));
if (mask & (DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit))
mask &= ((0-(((W[46]^W[48])>>29)&1)) | ~(DV_I_45_0_bit|DV_I_47_0_bit|DV_I_49_0_bit));
mask &= ((((W[45]^W[47])&(1<<6))-(1<<6)) | ~(DV_I_47_2_bit|DV_I_49_2_bit|DV_I_51_2_bit));
if (mask & (DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit))
mask &= ((0-(((W[45]^W[47])>>29)&1)) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_I_48_0_bit));
mask &= (((((W[44]^W[46])>>6)&1)-1) | ~(DV_I_46_2_bit|DV_I_48_2_bit|DV_I_50_2_bit));
if (mask & (DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit))
mask &= ((0-(((W[44]^W[46])>>29)&1)) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_I_47_0_bit));
mask &= ((0-((W[41]^(W[42]>>5))&(1<<1))) | ~(DV_I_48_2_bit|DV_II_46_2_bit|DV_II_51_2_bit));
mask &= ((0-((W[40]^(W[41]>>5))&(1<<1))) | ~(DV_I_47_2_bit|DV_I_51_2_bit|DV_II_50_2_bit));
if (mask & (DV_I_44_0_bit|DV_I_46_0_bit|DV_II_56_0_bit))
mask &= ((0-(((W[40]^W[42])>>4)&1)) | ~(DV_I_44_0_bit|DV_I_46_0_bit|DV_II_56_0_bit));
mask &= ((0-((W[39]^(W[40]>>5))&(1<<1))) | ~(DV_I_46_2_bit|DV_I_50_2_bit|DV_II_49_2_bit));
if (mask & (DV_I_43_0_bit|DV_I_45_0_bit|DV_II_55_0_bit))
mask &= ((0-(((W[39]^W[41])>>4)&1)) | ~(DV_I_43_0_bit|DV_I_45_0_bit|DV_II_55_0_bit));
if (mask & (DV_I_44_0_bit|DV_II_54_0_bit|DV_II_56_0_bit))
mask &= ((0-(((W[38]^W[40])>>4)&1)) | ~(DV_I_44_0_bit|DV_II_54_0_bit|DV_II_56_0_bit));
if (mask & (DV_I_43_0_bit|DV_II_53_0_bit|DV_II_55_0_bit))
mask &= ((0-(((W[37]^W[39])>>4)&1)) | ~(DV_I_43_0_bit|DV_II_53_0_bit|DV_II_55_0_bit));
mask &= ((0-((W[36]^(W[37]>>5))&(1<<1))) | ~(DV_I_47_2_bit|DV_I_50_2_bit|DV_II_46_2_bit));
if (mask & (DV_I_45_0_bit|DV_I_48_0_bit|DV_II_47_0_bit))
mask &= (((((W[35]>>4)^(W[39]>>29))&1)-1) | ~(DV_I_45_0_bit|DV_I_48_0_bit|DV_II_47_0_bit));
if (mask & (DV_I_48_0_bit|DV_II_48_0_bit))
mask &= ((0-((W[63]^(W[64]>>5))&(1<<0))) | ~(DV_I_48_0_bit|DV_II_48_0_bit));
if (mask & (DV_I_45_0_bit|DV_II_45_0_bit))
mask &= ((0-((W[63]^(W[64]>>5))&(1<<1))) | ~(DV_I_45_0_bit|DV_II_45_0_bit));
if (mask & (DV_I_47_0_bit|DV_II_47_0_bit))
mask &= ((0-((W[62]^(W[63]>>5))&(1<<0))) | ~(DV_I_47_0_bit|DV_II_47_0_bit));
if (mask & (DV_I_46_0_bit|DV_II_46_0_bit))
mask &= ((0-((W[61]^(W[62]>>5))&(1<<0))) | ~(DV_I_46_0_bit|DV_II_46_0_bit));
mask &= ((0-((W[61]^(W[62]>>5))&(1<<2))) | ~(DV_I_46_2_bit|DV_II_46_2_bit));
if (mask & (DV_I_45_0_bit|DV_II_45_0_bit))
mask &= ((0-((W[60]^(W[61]>>5))&(1<<0))) | ~(DV_I_45_0_bit|DV_II_45_0_bit));
if (mask & (DV_II_51_0_bit|DV_II_54_0_bit))
mask &= (((((W[58]^W[59])>>29)&1)-1) | ~(DV_II_51_0_bit|DV_II_54_0_bit));
if (mask & (DV_II_50_0_bit|DV_II_53_0_bit))
mask &= (((((W[57]^W[58])>>29)&1)-1) | ~(DV_II_50_0_bit|DV_II_53_0_bit));
if (mask & (DV_II_52_0_bit|DV_II_54_0_bit))
mask &= ((((W[56]^(W[59]>>25))&(1<<4))-(1<<4)) | ~(DV_II_52_0_bit|DV_II_54_0_bit));
if (mask & (DV_II_51_0_bit|DV_II_52_0_bit))
mask &= ((0-(((W[56]^W[59])>>29)&1)) | ~(DV_II_51_0_bit|DV_II_52_0_bit));
if (mask & (DV_II_49_0_bit|DV_II_52_0_bit))
mask &= (((((W[56]^W[57])>>29)&1)-1) | ~(DV_II_49_0_bit|DV_II_52_0_bit));
if (mask & (DV_II_51_0_bit|DV_II_53_0_bit))
mask &= ((((W[55]^(W[58]>>25))&(1<<4))-(1<<4)) | ~(DV_II_51_0_bit|DV_II_53_0_bit));
if (mask & (DV_II_50_0_bit|DV_II_52_0_bit))
mask &= ((((W[54]^(W[57]>>25))&(1<<4))-(1<<4)) | ~(DV_II_50_0_bit|DV_II_52_0_bit));
if (mask & (DV_II_49_0_bit|DV_II_51_0_bit))
mask &= ((((W[53]^(W[56]>>25))&(1<<4))-(1<<4)) | ~(DV_II_49_0_bit|DV_II_51_0_bit));
mask &= ((((W[51]^(W[50]>>5))&(1<<1))-(1<<1)) | ~(DV_I_50_2_bit|DV_II_46_2_bit));
mask &= ((((W[48]^W[50])&(1<<6))-(1<<6)) | ~(DV_I_50_2_bit|DV_II_46_2_bit));
if (mask & (DV_I_51_0_bit|DV_I_52_0_bit))
mask &= ((0-(((W[48]^W[55])>>29)&1)) | ~(DV_I_51_0_bit|DV_I_52_0_bit));
mask &= ((((W[47]^W[49])&(1<<6))-(1<<6)) | ~(DV_I_49_2_bit|DV_I_51_2_bit));
mask &= ((((W[48]^(W[47]>>5))&(1<<1))-(1<<1)) | ~(DV_I_47_2_bit|DV_II_51_2_bit));
mask &= ((((W[46]^W[48])&(1<<6))-(1<<6)) | ~(DV_I_48_2_bit|DV_I_50_2_bit));
mask &= ((((W[47]^(W[46]>>5))&(1<<1))-(1<<1)) | ~(DV_I_46_2_bit|DV_II_50_2_bit));
mask &= ((0-((W[44]^(W[45]>>5))&(1<<1))) | ~(DV_I_51_2_bit|DV_II_49_2_bit));
mask &= ((((W[43]^W[45])&(1<<6))-(1<<6)) | ~(DV_I_47_2_bit|DV_I_49_2_bit));
mask &= (((((W[42]^W[44])>>6)&1)-1) | ~(DV_I_46_2_bit|DV_I_48_2_bit));
mask &= ((((W[43]^(W[42]>>5))&(1<<1))-(1<<1)) | ~(DV_II_46_2_bit|DV_II_51_2_bit));
mask &= ((((W[42]^(W[41]>>5))&(1<<1))-(1<<1)) | ~(DV_I_51_2_bit|DV_II_50_2_bit));
mask &= ((((W[41]^(W[40]>>5))&(1<<1))-(1<<1)) | ~(DV_I_50_2_bit|DV_II_49_2_bit));
if (mask & (DV_I_52_0_bit|DV_II_51_0_bit))
mask &= ((((W[39]^(W[43]>>25))&(1<<4))-(1<<4)) | ~(DV_I_52_0_bit|DV_II_51_0_bit));
if (mask & (DV_I_51_0_bit|DV_II_50_0_bit))
mask &= ((((W[38]^(W[42]>>25))&(1<<4))-(1<<4)) | ~(DV_I_51_0_bit|DV_II_50_0_bit));
if (mask & (DV_I_48_2_bit|DV_I_51_2_bit))
mask &= ((0-((W[37]^(W[38]>>5))&(1<<1))) | ~(DV_I_48_2_bit|DV_I_51_2_bit));
if (mask & (DV_I_50_0_bit|DV_II_49_0_bit))
mask &= ((((W[37]^(W[41]>>25))&(1<<4))-(1<<4)) | ~(DV_I_50_0_bit|DV_II_49_0_bit));
if (mask & (DV_II_52_0_bit|DV_II_54_0_bit))
mask &= ((0-((W[36]^W[38])&(1<<4))) | ~(DV_II_52_0_bit|DV_II_54_0_bit));
mask &= ((0-((W[35]^(W[36]>>5))&(1<<1))) | ~(DV_I_46_2_bit|DV_I_49_2_bit));
if (mask & (DV_I_51_0_bit|DV_II_47_0_bit))
mask &= ((((W[35]^(W[39]>>25))&(1<<3))-(1<<3)) | ~(DV_I_51_0_bit|DV_II_47_0_bit));
if (mask) {
if (mask & DV_I_43_0_bit)
if (
!((W[61]^(W[62]>>5)) & (1<<1))
|| !(!((W[59]^(W[63]>>25)) & (1<<5)))
|| !((W[58]^(W[63]>>30)) & (1<<0))
) mask &= ~DV_I_43_0_bit;
if (mask & DV_I_44_0_bit)
if (
!((W[62]^(W[63]>>5)) & (1<<1))
|| !(!((W[60]^(W[64]>>25)) & (1<<5)))
|| !((W[59]^(W[64]>>30)) & (1<<0))
) mask &= ~DV_I_44_0_bit;
if (mask & DV_I_46_2_bit)
mask &= ((~((W[40]^W[42])>>2)) | ~DV_I_46_2_bit);
if (mask & DV_I_47_2_bit)
if (
!((W[62]^(W[63]>>5)) & (1<<2))
|| !(!((W[41]^W[43]) & (1<<6)))
) mask &= ~DV_I_47_2_bit;
if (mask & DV_I_48_2_bit)
if (
!((W[63]^(W[64]>>5)) & (1<<2))
|| !(!((W[48]^(W[49]<<5)) & (1<<6)))
) mask &= ~DV_I_48_2_bit;
if (mask & DV_I_49_2_bit)
if (
!(!((W[49]^(W[50]<<5)) & (1<<6)))
|| !((W[42]^W[50]) & (1<<1))
|| !(!((W[39]^(W[40]<<5)) & (1<<6)))
|| !((W[38]^W[40]) & (1<<1))
) mask &= ~DV_I_49_2_bit;
if (mask & DV_I_50_0_bit)
mask &= ((((W[36]^W[37])<<7)) | ~DV_I_50_0_bit);
if (mask & DV_I_50_2_bit)
mask &= ((((W[43]^W[51])<<11)) | ~DV_I_50_2_bit);
if (mask & DV_I_51_0_bit)
mask &= ((((W[37]^W[38])<<9)) | ~DV_I_51_0_bit);
if (mask & DV_I_51_2_bit)
if (
!(!((W[51]^(W[52]<<5)) & (1<<6)))
|| !(!((W[49]^W[51]) & (1<<6)))
|| !(!((W[37]^(W[37]>>5)) & (1<<1)))
|| !(!((W[35]^(W[39]>>25)) & (1<<5)))
) mask &= ~DV_I_51_2_bit;
if (mask & DV_I_52_0_bit)
mask &= ((((W[38]^W[39])<<11)) | ~DV_I_52_0_bit);
if (mask & DV_II_46_2_bit)
mask &= ((((W[47]^W[51])<<17)) | ~DV_II_46_2_bit);
if (mask & DV_II_48_0_bit)
if (
!(!((W[36]^(W[40]>>25)) & (1<<3)))
|| !((W[35]^(W[40]<<2)) & (1<<30))
) mask &= ~DV_II_48_0_bit;
if (mask & DV_II_49_0_bit)
if (
!(!((W[37]^(W[41]>>25)) & (1<<3)))
|| !((W[36]^(W[41]<<2)) & (1<<30))
) mask &= ~DV_II_49_0_bit;
if (mask & DV_II_49_2_bit)
if (
!(!((W[53]^(W[54]<<5)) & (1<<6)))
|| !(!((W[51]^W[53]) & (1<<6)))
|| !((W[50]^W[54]) & (1<<1))
|| !(!((W[45]^(W[46]<<5)) & (1<<6)))
|| !(!((W[37]^(W[41]>>25)) & (1<<5)))
|| !((W[36]^(W[41]>>30)) & (1<<0))
) mask &= ~DV_II_49_2_bit;
if (mask & DV_II_50_0_bit)
if (
!((W[55]^W[58]) & (1<<29))
|| !(!((W[38]^(W[42]>>25)) & (1<<3)))
|| !((W[37]^(W[42]<<2)) & (1<<30))
) mask &= ~DV_II_50_0_bit;
if (mask & DV_II_50_2_bit)
if (
!(!((W[54]^(W[55]<<5)) & (1<<6)))
|| !(!((W[52]^W[54]) & (1<<6)))
|| !((W[51]^W[55]) & (1<<1))
|| !((W[45]^W[47]) & (1<<1))
|| !(!((W[38]^(W[42]>>25)) & (1<<5)))
|| !((W[37]^(W[42]>>30)) & (1<<0))
) mask &= ~DV_II_50_2_bit;
if (mask & DV_II_51_0_bit)
if (
!(!((W[39]^(W[43]>>25)) & (1<<3)))
|| !((W[38]^(W[43]<<2)) & (1<<30))
) mask &= ~DV_II_51_0_bit;
if (mask & DV_II_51_2_bit)
if (
!(!((W[55]^(W[56]<<5)) & (1<<6)))
|| !(!((W[53]^W[55]) & (1<<6)))
|| !((W[52]^W[56]) & (1<<1))
|| !((W[46]^W[48]) & (1<<1))
|| !(!((W[39]^(W[43]>>25)) & (1<<5)))
|| !((W[38]^(W[43]>>30)) & (1<<0))
) mask &= ~DV_II_51_2_bit;
if (mask & DV_II_52_0_bit)
if (
!(!((W[59]^W[60]) & (1<<29)))
|| !(!((W[40]^(W[44]>>25)) & (1<<3)))
|| !(!((W[40]^(W[44]>>25)) & (1<<4)))
|| !((W[39]^(W[44]<<2)) & (1<<30))
) mask &= ~DV_II_52_0_bit;
if (mask & DV_II_53_0_bit)
if (
!((W[58]^W[61]) & (1<<29))
|| !(!((W[57]^(W[61]>>25)) & (1<<4)))
|| !(!((W[41]^(W[45]>>25)) & (1<<3)))
|| !(!((W[41]^(W[45]>>25)) & (1<<4)))
) mask &= ~DV_II_53_0_bit;
if (mask & DV_II_54_0_bit)
if (
!(!((W[58]^(W[62]>>25)) & (1<<4)))
|| !(!((W[42]^(W[46]>>25)) & (1<<3)))
|| !(!((W[42]^(W[46]>>25)) & (1<<4)))
) mask &= ~DV_II_54_0_bit;
if (mask & DV_II_55_0_bit)
if (
!(!((W[59]^(W[63]>>25)) & (1<<4)))
|| !(!((W[57]^(W[59]>>25)) & (1<<4)))
|| !(!((W[43]^(W[47]>>25)) & (1<<3)))
|| !(!((W[43]^(W[47]>>25)) & (1<<4)))
) mask &= ~DV_II_55_0_bit;
if (mask & DV_II_56_0_bit)
if (
!(!((W[60]^(W[64]>>25)) & (1<<4)))
|| !(!((W[44]^(W[48]>>25)) & (1<<3)))
|| !(!((W[44]^(W[48]>>25)) & (1<<4)))
) mask &= ~DV_II_56_0_bit;
}
dvmask[0]=mask;
}
#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_C
#include SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_C
#endif

View File

@ -0,0 +1,52 @@
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/
/*
// this file was generated by the 'parse_bitrel' program in the tools section
// using the data files from directory 'tools/data/3565'
//
// sha1_dvs contains a list of SHA-1 Disturbance Vectors (DV) to check
// dvType, dvK and dvB define the DV: I(K,B) or II(K,B) (see the paper)
// dm[80] is the expanded message block XOR-difference defined by the DV
// testt is the step to do the recompression from for collision detection
// maski and maskb define the bit to check for each DV in the dvmask returned by ubc_check
//
// ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs
// it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met
// thus one needs to do the recompression check for each DV that has its bit set
*/
#ifndef SHA1DC_UBC_CHECK_H
#define SHA1DC_UBC_CHECK_H
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef SHA1DC_NO_STANDARD_INCLUDES
#include <stdint.h>
#endif
#define DVMASKSIZE 1
typedef struct { int dvType; int dvK; int dvB; int testt; int maski; int maskb; uint32_t dm[80]; } dv_info_t;
extern dv_info_t sha1_dvs[];
void ubc_check(const uint32_t W[80], uint32_t dvmask[DVMASKSIZE]);
#define DOSTORESTATE58
#define DOSTORESTATE65
#define CHECK_DVMASK(_DVMASK) (0 != _DVMASK[0])
#if defined(__cplusplus)
}
#endif
#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_H
#include SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_H
#endif
#endif

View File

@ -214,7 +214,7 @@ static int hashsig_finalize_hashes(git_hashsig *sig)
if (sig->mins.size < HASHSIG_HEAP_MIN_SIZE &&
!(sig->opt & GIT_HASHSIG_ALLOW_SMALL_FILES)) {
giterr_set(GITERR_INVALID,
"File too small for similarity signature calculation");
"file too small for similarity signature calculation");
return GIT_EBUFS;
}
@ -286,7 +286,7 @@ int git_hashsig_create_fromfile(
if ((buflen = p_read(fd, buf, sizeof(buf))) <= 0) {
if ((error = (int)buflen) < 0)
giterr_set(GITERR_OS,
"Read error on '%s' calculating similarity hashes", path);
"read error on '%s' calculating similarity hashes", path);
break;
}

133
src/idxmap.c Normal file
View File

@ -0,0 +1,133 @@
/*
* 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 "idxmap.h"
/* This is __ac_X31_hash_string but with tolower and it takes the entry's stage into account */
static kh_inline khint_t idxentry_hash(const git_index_entry *e)
{
const char *s = e->path;
khint_t h = (khint_t)git__tolower(*s);
if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)git__tolower(*s);
return h + GIT_IDXENTRY_STAGE(e);
}
#define idxentry_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcmp(a->path, b->path) == 0)
#define idxentry_icase_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcasecmp(a->path, b->path) == 0)
__KHASH_IMPL(idx, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_equal)
__KHASH_IMPL(idxicase, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_icase_equal)
int git_idxmap_alloc(git_idxmap **map)
{
if ((*map = kh_init(idx)) == NULL) {
giterr_set_oom();
return -1;
}
return 0;
}
int git_idxmap_icase_alloc(git_idxmap_icase **map)
{
if ((*map = kh_init(idxicase)) == NULL) {
giterr_set_oom();
return -1;
}
return 0;
}
void git_idxmap_insert(git_idxmap *map, const git_index_entry *key, void *value, int *rval)
{
khiter_t idx = kh_put(idx, map, key, rval);
if ((*rval) >= 0) {
if ((*rval) == 0)
kh_key(map, idx) = key;
kh_val(map, idx) = value;
}
}
void git_idxmap_icase_insert(git_idxmap_icase *map, const git_index_entry *key, void *value, int *rval)
{
khiter_t idx = kh_put(idxicase, map, key, rval);
if ((*rval) >= 0) {
if ((*rval) == 0)
kh_key(map, idx) = key;
kh_val(map, idx) = value;
}
}
size_t git_idxmap_lookup_index(git_idxmap *map, const git_index_entry *key)
{
return kh_get(idx, map, key);
}
size_t git_idxmap_icase_lookup_index(git_idxmap_icase *map, const git_index_entry *key)
{
return kh_get(idxicase, map, key);
}
void *git_idxmap_value_at(git_idxmap *map, size_t idx)
{
return kh_val(map, idx);
}
int git_idxmap_valid_index(git_idxmap *map, size_t idx)
{
return idx != kh_end(map);
}
int git_idxmap_has_data(git_idxmap *map, size_t idx)
{
return kh_exist(map, idx);
}
void git_idxmap_resize(git_idxmap *map, size_t size)
{
kh_resize(idx, map, size);
}
void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size)
{
kh_resize(idxicase, map, size);
}
void git_idxmap_free(git_idxmap *map)
{
kh_destroy(idx, map);
}
void git_idxmap_clear(git_idxmap *map)
{
kh_clear(idx, map);
}
void git_idxmap_delete_at(git_idxmap *map, size_t idx)
{
kh_del(idx, map, idx);
}
void git_idxmap_icase_delete_at(git_idxmap_icase *map, size_t idx)
{
kh_del(idxicase, map, idx);
}
void git_idxmap_delete(git_idxmap *map, const git_index_entry *key)
{
khiter_t idx = git_idxmap_lookup_index(map, key);
if (git_idxmap_valid_index(map, idx))
git_idxmap_delete_at(map, idx);
}
void git_idxmap_icase_delete(git_idxmap_icase *map, const git_index_entry *key)
{
khiter_t idx = git_idxmap_icase_lookup_index(map, key);
if (git_idxmap_valid_index((git_idxmap *)map, idx))
git_idxmap_icase_delete_at(map, idx);
}

View File

@ -26,66 +26,27 @@ typedef khash_t(idxicase) git_idxmap_icase;
typedef khiter_t git_idxmap_iter;
/* This is __ac_X31_hash_string but with tolower and it takes the entry's stage into account */
static kh_inline khint_t idxentry_hash(const git_index_entry *e)
{
const char *s = e->path;
khint_t h = (khint_t)git__tolower(*s);
if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)git__tolower(*s);
return h + GIT_IDXENTRY_STAGE(e);
}
int git_idxmap_alloc(git_idxmap **map);
int git_idxmap_icase_alloc(git_idxmap_icase **map);
void git_idxmap_insert(git_idxmap *map, const git_index_entry *key, void *value, int *rval);
void git_idxmap_icase_insert(git_idxmap_icase *map, const git_index_entry *key, void *value, int *rval);
#define idxentry_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcmp(a->path, b->path) == 0)
#define idxentry_icase_equal(a, b) (GIT_IDXENTRY_STAGE(a) == GIT_IDXENTRY_STAGE(b) && strcasecmp(a->path, b->path) == 0)
size_t git_idxmap_lookup_index(git_idxmap *map, const git_index_entry *key);
size_t git_idxmap_icase_lookup_index(git_idxmap_icase *map, const git_index_entry *key);
void *git_idxmap_value_at(git_idxmap *map, size_t idx);
int git_idxmap_valid_index(git_idxmap *map, size_t idx);
int git_idxmap_has_data(git_idxmap *map, size_t idx);
#define GIT__USE_IDXMAP \
__KHASH_IMPL(idx, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_equal)
void git_idxmap_resize(git_idxmap *map, size_t size);
void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size);
void git_idxmap_free(git_idxmap *map);
void git_idxmap_clear(git_idxmap *map);
#define GIT__USE_IDXMAP_ICASE \
__KHASH_IMPL(idxicase, static kh_inline, const git_index_entry *, git_index_entry *, 1, idxentry_hash, idxentry_icase_equal)
void git_idxmap_delete_at(git_idxmap *map, size_t idx);
void git_idxmap_icase_delete_at(git_idxmap_icase *map, size_t idx);
#define git_idxmap_alloc(hp) \
((*(hp) = kh_init(idx)) == NULL) ? giterr_set_oom(), -1 : 0
#define git_idxmap_icase_alloc(hp) \
((*(hp) = kh_init(idxicase)) == NULL) ? giterr_set_oom(), -1 : 0
#define git_idxmap_insert(h, key, val, rval) do { \
khiter_t __pos = kh_put(idx, h, key, &rval); \
if (rval >= 0) { \
if (rval == 0) kh_key(h, __pos) = key; \
kh_val(h, __pos) = val; \
} } while (0)
#define git_idxmap_icase_insert(h, key, val, rval) do { \
khiter_t __pos = kh_put(idxicase, h, key, &rval); \
if (rval >= 0) { \
if (rval == 0) kh_key(h, __pos) = key; \
kh_val(h, __pos) = val; \
} } while (0)
#define git_idxmap_lookup_index(h, k) kh_get(idx, h, k)
#define git_idxmap_icase_lookup_index(h, k) kh_get(idxicase, h, k)
#define git_idxmap_value_at(h, idx) kh_val(h, idx)
#define git_idxmap_valid_index(h, idx) (idx != kh_end(h))
#define git_idxmap_has_data(h, idx) kh_exist(h, idx)
#define git_idxmap_resize(h,s) kh_resize(idx, h, s)
#define git_idxmap_free(h) kh_destroy(idx, h), h = NULL
#define git_idxmap_clear(h) kh_clear(idx, h)
#define git_idxmap_delete_at(h, id) kh_del(idx, h, id)
#define git_idxmap_icase_delete_at(h, id) kh_del(idxicase, h, id)
#define git_idxmap_delete(h, key) do { \
khiter_t __pos = git_idxmap_lookup_index(h, key); \
if (git_idxmap_valid_index(h, __pos)) \
git_idxmap_delete_at(h, __pos); } while (0)
#define git_idxmap_icase_delete(h, key) do { \
khiter_t __pos = git_idxmap_icase_lookup_index(h, key); \
if (git_idxmap_valid_index(h, __pos)) \
git_idxmap_icase_delete_at(h, __pos); } while (0)
void git_idxmap_delete(git_idxmap *map, const git_index_entry *key);
void git_idxmap_icase_delete(git_idxmap_icase *map, const git_index_entry *key);
#define git_idxmap_begin kh_begin
#define git_idxmap_end kh_end

View File

@ -175,7 +175,7 @@ static int parse_ignore_file(
context = attrs->entry->path;
if (git_mutex_lock(&attrs->lock) < 0) {
giterr_set(GITERR_OS, "Failed to lock ignore file");
giterr_set(GITERR_OS, "failed to lock ignore file");
return -1;
}
@ -277,8 +277,9 @@ int git_ignore__for_path(
{
int error = 0;
const char *workdir = git_repository_workdir(repo);
git_buf infopath = GIT_BUF_INIT;
assert(ignores && path);
assert(repo && ignores && path);
memset(ignores, 0, sizeof(*ignores));
ignores->repo = repo;
@ -322,10 +323,14 @@ int git_ignore__for_path(
goto cleanup;
}
if ((error = git_repository_item_path(&infopath,
repo, GIT_REPOSITORY_ITEM_INFO)) < 0)
goto cleanup;
/* load .git/info/exclude */
error = push_ignore_file(
ignores, &ignores->ign_global,
git_repository_path(repo), GIT_IGNORE_FILE_INREPO);
infopath.ptr, GIT_IGNORE_FILE_INREPO);
if (error < 0)
goto cleanup;
@ -336,6 +341,7 @@ int git_ignore__for_path(
git_repository_attr_cache(repo)->cfg_excl_file);
cleanup:
git_buf_free(&infopath);
if (error < 0)
git_ignore__free(ignores);
@ -503,9 +509,9 @@ int git_ignore_path_is_ignored(
unsigned int i;
git_attr_file *file;
assert(ignored && pathname);
assert(repo && ignored && pathname);
workdir = repo ? git_repository_workdir(repo) : NULL;
workdir = git_repository_workdir(repo);
memset(&path, 0, sizeof(path));
memset(&ignores, 0, sizeof(ignores));

View File

@ -12,7 +12,7 @@
#include "attr_file.h"
#define GIT_IGNORE_FILE ".gitignore"
#define GIT_IGNORE_FILE_INREPO "info/exclude"
#define GIT_IGNORE_FILE_INREPO "exclude"
#define GIT_IGNORE_FILE_XDG "ignore"
/* The git_ignores structure maintains three sets of ignores:

View File

@ -27,9 +27,6 @@
#include "git2/config.h"
#include "git2/sys/index.h"
GIT__USE_IDXMAP
GIT__USE_IDXMAP_ICASE
#define INSERT_IN_MAP_EX(idx, map, e, err) do { \
if ((idx)->ignore_case) \
git_idxmap_icase_insert((khash_t(idxicase) *) (map), (e), (e), (err)); \
@ -57,10 +54,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr
unsigned int flags,
git_index_matched_path_cb cb, void *payload);
#define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
#define short_entry_size(len) entry_size(struct entry_short, len)
#define long_entry_size(len) entry_size(struct entry_long, len)
#define minimal_entry_size (offsetof(struct entry_short, path))
static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ;
@ -570,7 +563,7 @@ int git_index_set_caps(git_index *index, int caps)
if (!repo)
return create_index_error(
-1, "Cannot access repository to set index caps");
-1, "cannot access repository to set index caps");
if (!git_repository__cvar(&val, repo, GIT_CVAR_IGNORECASE))
index->ignore_case = (val != 0);
@ -639,7 +632,7 @@ int git_index_read(git_index *index, int force)
if (!index->index_file_path)
return create_index_error(-1,
"Failed to read index: The index is in-memory only");
"failed to read index: The index is in-memory only");
index->on_disk = git_path_exists(index->index_file_path);
@ -653,7 +646,7 @@ int git_index_read(git_index *index, int force)
((updated = compare_checksum(index)) < 0)) {
giterr_set(
GITERR_INDEX,
"Failed to read index: '%s' no longer exists",
"failed to read index: '%s' no longer exists",
index->index_file_path);
return updated;
}
@ -765,7 +758,7 @@ int git_index_set_version(git_index *index, unsigned int version)
if (version < INDEX_VERSION_NUMBER_LB ||
version > INDEX_VERSION_NUMBER_UB) {
giterr_set(GITERR_INDEX, "Invalid version number");
giterr_set(GITERR_INDEX, "invalid version number");
return -1;
}
@ -805,7 +798,7 @@ int git_index_write_tree(git_oid *oid, git_index *index)
if (repo == NULL)
return create_index_error(-1, "Failed to write tree. "
"The index file is not backed up by an existing repository");
"the index file is not backed up by an existing repository");
return git_tree__write_index(oid, index, repo);
}
@ -847,7 +840,7 @@ const git_index_entry *git_index_get_bypath(
if (git_idxmap_valid_index(index->entries_map, pos))
return git_idxmap_value_at(index->entries_map, pos);
giterr_set(GITERR_INDEX, "Index does not contain %s", path);
giterr_set(GITERR_INDEX, "index does not contain '%s'", path);
return NULL;
}
@ -934,7 +927,7 @@ static int index_entry_init(
if (INDEX_OWNER(index) == NULL)
return create_index_error(-1,
"Could not initialize index entry. "
"could not initialize index entry. "
"Index is not backed up by an existing repository.");
if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, true) < 0)
@ -1365,7 +1358,7 @@ static int index_insert(
error = git_vector_insert_sorted(&index->entries, entry, index_no_dups);
if (error == 0) {
INSERT_IN_MAP(index, entry, error);
INSERT_IN_MAP(index, entry, &error);
}
}
@ -1423,7 +1416,7 @@ int git_index_add_frombuffer(
if (INDEX_OWNER(index) == NULL)
return create_index_error(-1,
"Could not initialize index entry. "
"could not initialize index entry. "
"Index is not backed up by an existing repository.");
if (!valid_filemode(source_entry->mode)) {
@ -1592,7 +1585,7 @@ int git_index__fill(git_index *index, const git_vector *source_entries)
if ((ret = git_vector_insert(&index->entries, entry)) < 0)
break;
INSERT_IN_MAP(index, entry, ret);
INSERT_IN_MAP(index, entry, &ret);
if (ret < 0)
break;
}
@ -1637,7 +1630,7 @@ int git_index_remove(git_index *index, const char *path, int stage)
if (index_find(&position, index, path, 0, stage) < 0) {
giterr_set(
GITERR_INDEX, "Index does not contain %s at stage %d", path, stage);
GITERR_INDEX, "index does not contain %s at stage %d", path, stage);
error = GIT_ENOTFOUND;
} else {
error = index_remove_entry(index, position);
@ -1709,7 +1702,7 @@ int git_index_find(size_t *at_pos, git_index *index, const char *path)
if (git_vector_bsearch2(
&pos, &index->entries, index->entries_search_path, path) < 0) {
giterr_set(GITERR_INDEX, "Index does not contain %s", path);
giterr_set(GITERR_INDEX, "index does not contain %s", path);
return GIT_ENOTFOUND;
}
@ -2153,7 +2146,7 @@ void git_index_reuc_clear(git_index *index)
static int index_error_invalid(const char *message)
{
giterr_set(GITERR_INDEX, "Invalid data in index - %s", message);
giterr_set(GITERR_INDEX, "invalid data in index - %s", message);
return -1;
}
@ -2285,12 +2278,29 @@ out_err:
return 0;
}
static size_t index_entry_size(size_t path_len, size_t varint_len, uint32_t flags)
{
if (varint_len) {
if (flags & GIT_IDXENTRY_EXTENDED)
return offsetof(struct entry_long, path) + path_len + 1 + varint_len;
else
return offsetof(struct entry_short, path) + path_len + 1 + varint_len;
} else {
#define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
if (flags & GIT_IDXENTRY_EXTENDED)
return entry_size(struct entry_long, path_len);
else
return entry_size(struct entry_short, path_len);
#undef entry_size
}
}
static size_t read_entry(
git_index_entry **out,
git_index *index,
const void *buffer,
size_t buffer_size,
const char **last)
const char *last)
{
size_t path_length, entry_size;
const char *path_ptr;
@ -2347,35 +2357,34 @@ static size_t read_entry(
path_length = path_end - path_ptr;
}
if (entry.flags & GIT_IDXENTRY_EXTENDED)
entry_size = long_entry_size(path_length);
else
entry_size = short_entry_size(path_length);
if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
return 0;
entry_size = index_entry_size(path_length, 0, entry.flags);
entry.path = (char *)path_ptr;
} else {
size_t varint_len;
size_t shared = git_decode_varint((const unsigned char *)path_ptr,
&varint_len);
size_t len = strlen(path_ptr + varint_len);
size_t last_len = strlen(*last);
size_t tmp_path_len;
size_t strip_len = git_decode_varint((const unsigned char *)path_ptr,
&varint_len);
size_t last_len = strlen(last);
size_t prefix_len = last_len - strip_len;
size_t suffix_len = strlen(path_ptr + varint_len);
size_t path_len;
if (varint_len == 0)
return index_error_invalid("incorrect prefix length");
GITERR_CHECK_ALLOC_ADD(&tmp_path_len, shared, len + 1);
tmp_path = git__malloc(tmp_path_len);
GITERR_CHECK_ALLOC_ADD(&path_len, prefix_len, suffix_len);
GITERR_CHECK_ALLOC_ADD(&path_len, path_len, 1);
tmp_path = git__malloc(path_len);
GITERR_CHECK_ALLOC(tmp_path);
memcpy(tmp_path, last, last_len);
memcpy(tmp_path + last_len, path_ptr + varint_len, len);
entry_size = long_entry_size(shared + len);
memcpy(tmp_path, last, prefix_len);
memcpy(tmp_path + prefix_len, path_ptr + varint_len, suffix_len + 1);
entry_size = index_entry_size(suffix_len, varint_len, entry.flags);
entry.path = tmp_path;
}
if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
return 0;
if (index_entry_dup(out, index, &entry) < 0) {
git__free(tmp_path);
return 0;
@ -2448,7 +2457,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
unsigned int i;
struct index_header header = { 0 };
git_oid checksum_calculated, checksum_expected;
const char **last = NULL;
const char *last = NULL;
const char *empty = "";
#define seek_forward(_increase) { \
@ -2472,16 +2481,16 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
index->version = header.version;
if (index->version >= INDEX_VERSION_NUMBER_COMP)
last = &empty;
last = empty;
seek_forward(INDEX_HEADER_SIZE);
assert(!index->entries.length);
if (index->ignore_case)
kh_resize(idxicase, (khash_t(idxicase) *) index->entries_map, header.entry_count);
git_idxmap_icase_resize((khash_t(idxicase) *) index->entries_map, header.entry_count);
else
kh_resize(idx, index->entries_map, header.entry_count);
git_idxmap_resize(index->entries_map, header.entry_count);
/* Parse all the entries */
for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
@ -2499,7 +2508,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
goto done;
}
INSERT_IN_MAP(index, entry, error);
INSERT_IN_MAP(index, entry, &error);
if (error < 0) {
index_entry_free(entry);
@ -2507,6 +2516,9 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
}
error = 0;
if (index->version >= INDEX_VERSION_NUMBER_COMP)
last = entry->path;
seek_forward(entry_size);
}
@ -2577,11 +2589,12 @@ static bool is_index_extended(git_index *index)
return (extended > 0);
}
static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char **last)
static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char *last)
{
void *mem = NULL;
struct entry_short *ondisk;
size_t path_len, disk_size;
int varint_len = 0;
char *path;
const char *path_start = entry->path;
size_t same_len = 0;
@ -2589,7 +2602,7 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
path_len = ((struct entry_internal *)entry)->pathlen;
if (last) {
const char *last_c = *last;
const char *last_c = last;
while (*path_start == *last_c) {
if (!*path_start || !*last_c)
@ -2599,13 +2612,10 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
++same_len;
}
path_len -= same_len;
*last = entry->path;
varint_len = git_encode_varint(NULL, 0, same_len);
}
if (entry->flags & GIT_IDXENTRY_EXTENDED)
disk_size = long_entry_size(path_len);
else
disk_size = short_entry_size(path_len);
disk_size = index_entry_size(path_len, varint_len, entry->flags);
if (git_filebuf_reserve(file, &mem, disk_size) < 0)
return -1;
@ -2645,16 +2655,34 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
ondisk_ext->flags_extended = htons(entry->flags_extended &
GIT_IDXENTRY_EXTENDED_FLAGS);
path = ondisk_ext->path;
}
else
disk_size -= offsetof(struct entry_long, path);
} else {
path = ondisk->path;
disk_size -= offsetof(struct entry_short, path);
}
if (last) {
path += git_encode_varint((unsigned char *) path,
disk_size,
path_len - same_len);
varint_len = git_encode_varint((unsigned char *) path,
disk_size, same_len);
assert(varint_len > 0);
path += varint_len;
disk_size -= varint_len;
/*
* If using path compression, we are not allowed
* to have additional trailing NULs.
*/
assert(disk_size == path_len + 1);
} else {
/*
* If no path compression is used, we do have
* NULs as padding. As such, simply assert that
* we have enough space left to write the path.
*/
assert(disk_size > path_len);
}
memcpy(path, path_start, path_len);
memcpy(path, path_start, path_len + 1);
return 0;
}
@ -2665,8 +2693,7 @@ static int write_entries(git_index *index, git_filebuf *file)
size_t i;
git_vector case_sorted, *entries;
git_index_entry *entry;
const char **last = NULL;
const char *empty = "";
const char *last = NULL;
/* If index->entries is sorted case-insensitively, then we need
* to re-sort it case-sensitively before writing */
@ -2679,11 +2706,14 @@ static int write_entries(git_index *index, git_filebuf *file)
}
if (index->version >= INDEX_VERSION_NUMBER_COMP)
last = &empty;
last = "";
git_vector_foreach(entries, i, entry)
git_vector_foreach(entries, i, entry) {
if ((error = write_disk_entry(file, entry, last)) < 0)
break;
if (index->version >= INDEX_VERSION_NUMBER_COMP)
last = entry->path;
}
if (index->ignore_case)
git_vector_free(&case_sorted);
@ -2979,12 +3009,12 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
goto cleanup;
if (index->ignore_case)
kh_resize(idxicase, (khash_t(idxicase) *) entries_map, entries.length);
git_idxmap_icase_resize((khash_t(idxicase) *) entries_map, entries.length);
else
kh_resize(idx, entries_map, entries.length);
git_idxmap_resize(entries_map, entries.length);
git_vector_foreach(&entries, i, e) {
INSERT_IN_MAP_EX(index, entries_map, e, error);
INSERT_IN_MAP_EX(index, entries_map, e, &error);
if (error < 0) {
giterr_set(GITERR_INDEX, "failed to insert entry into map");
@ -3037,9 +3067,9 @@ static int git_index_read_iterator(
goto done;
if (index->ignore_case && new_length_hint)
kh_resize(idxicase, (khash_t(idxicase) *) new_entries_map, new_length_hint);
git_idxmap_icase_resize((khash_t(idxicase) *) new_entries_map, new_length_hint);
else if (new_length_hint)
kh_resize(idx, new_entries_map, new_length_hint);
git_idxmap_resize(new_entries_map, new_length_hint);
opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE |
GIT_ITERATOR_INCLUDE_CONFLICTS;
@ -3103,7 +3133,7 @@ static int git_index_read_iterator(
if (add_entry) {
if ((error = git_vector_insert(&new_entries, add_entry)) == 0)
INSERT_IN_MAP_EX(index, new_entries_map, add_entry, error);
INSERT_IN_MAP_EX(index, new_entries_map, add_entry, &error);
}
if (remove_entry && error >= 0)
@ -3390,7 +3420,7 @@ static int index_apply_to_all(
i--; /* back up foreach if we removed this */
break;
default:
giterr_set(GITERR_INVALID, "Unknown index action %d", action);
giterr_set(GITERR_INVALID, "unknown index action %d", action);
error = -1;
break;
}
@ -3475,13 +3505,13 @@ int git_indexwriter_init(
if (!index->index_file_path)
return create_index_error(-1,
"Failed to write index: The index is in-memory only");
"failed to write index: The index is in-memory only");
if ((error = git_filebuf_open(
&writer->file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) {
if (error == GIT_ELOCKED)
giterr_set(GITERR_INDEX, "The index is locked. This might be due to a concurrent or crashed process");
giterr_set(GITERR_INDEX, "the index is locked; this might be due to a concurrent or crashed process");
return error;
}
@ -3530,7 +3560,7 @@ int git_indexwriter_commit(git_indexwriter *writer)
if ((error = git_futils_filestamp_check(
&writer->index->stamp, writer->index->index_file_path)) < 0) {
giterr_set(GITERR_OS, "Could not read index timestamp");
giterr_set(GITERR_OS, "could not read index timestamp");
return -1;
}

View File

@ -17,8 +17,7 @@
#include "oid.h"
#include "oidmap.h"
#include "zstream.h"
GIT__USE_OIDMAP
#include "object.h"
extern git_mutex git__mwindow_mutex;
@ -33,9 +32,10 @@ struct entry {
struct git_indexer {
unsigned int parsed_header :1,
opened_pack :1,
pack_committed :1,
have_stream :1,
have_delta :1;
have_delta :1,
do_fsync :1;
struct git_pack_header hdr;
struct git_pack_file *pack;
unsigned int mode;
@ -83,12 +83,12 @@ static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack)
/* Verify we recognize this pack file format. */
if (hdr->hdr_signature != ntohl(PACK_SIGNATURE)) {
giterr_set(GITERR_INDEXER, "Wrong pack signature");
giterr_set(GITERR_INDEXER, "wrong pack signature");
return -1;
}
if (!pack_version_ok(hdr->hdr_version)) {
giterr_set(GITERR_INDEXER, "Wrong pack version");
giterr_set(GITERR_INDEXER, "wrong pack version");
return -1;
}
@ -125,6 +125,9 @@ int git_indexer_new(
git_hash_ctx_init(&idx->hash_ctx);
git_hash_ctx_init(&idx->trailer);
if (git_repository__fsync_gitdir)
idx->do_fsync = 1;
error = git_buf_joinpath(&path, prefix, suff);
if (error < 0)
goto cleanup;
@ -151,12 +154,23 @@ cleanup:
if (fd != -1)
p_close(fd);
if (git_buf_len(&tmp_path) > 0)
p_unlink(git_buf_cstr(&tmp_path));
if (idx->pack != NULL)
p_unlink(idx->pack->pack_name);
git_buf_free(&path);
git_buf_free(&tmp_path);
git__free(idx);
return -1;
}
void git_indexer__set_fsync(git_indexer *idx, int do_fsync)
{
idx->do_fsync = !!do_fsync;
}
/* Try to store the delta so we can try to resolve it later */
static int store_delta(git_indexer *idx)
{
@ -288,7 +302,7 @@ static int store_object(git_indexer *idx)
git_oid_cpy(&pentry->sha1, &oid);
pentry->offset = entry_start;
k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error);
if (error == -1) {
git__free(pentry);
giterr_set_oom();
@ -302,7 +316,7 @@ static int store_object(git_indexer *idx)
}
kh_value(idx->pack->idx_cache, k) = pentry;
git_oidmap_set_value_at(idx->pack->idx_cache, k, pentry);
git_oid_cpy(&entry->oid, &oid);
@ -327,9 +341,7 @@ on_error:
GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id)
{
khiter_t k;
k = kh_get(oid, idx->pack->idx_cache, id);
return (k != kh_end(idx->pack->idx_cache));
return git_oidmap_exists(idx->pack->idx_cache, id);
}
static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start)
@ -345,14 +357,14 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent
}
pentry->offset = entry_start;
k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
k = git_oidmap_put(idx->pack->idx_cache, &pentry->sha1, &error);
if (error <= 0) {
giterr_set(GITERR_INDEXER, "cannot insert object into pack");
return -1;
}
kh_value(idx->pack->idx_cache, k) = pentry;
git_oidmap_set_value_at(idx->pack->idx_cache, k, pentry);
/* Add the object to the list */
if (git_vector_insert(&idx->objects, entry) < 0)
@ -376,7 +388,7 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, git_off_t entry_star
GITERR_CHECK_ALLOC(entry);
if (git_odb__hashobj(&oid, obj) < 0) {
giterr_set(GITERR_INDEXER, "Failed to hash object");
giterr_set(GITERR_INDEXER, "failed to hash object");
goto on_error;
}
@ -477,13 +489,29 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t
static int append_to_pack(git_indexer *idx, const void *data, size_t size)
{
git_off_t new_size;
size_t mmap_alignment;
size_t page_offset;
git_off_t page_start;
git_off_t current_size = idx->pack->mwf.size;
int fd = idx->pack->mwf.fd;
int error;
if (!size)
return 0;
if (p_lseek(fd, current_size + size - 1, SEEK_SET) < 0 ||
if ((error = git__mmap_alignment(&mmap_alignment)) < 0)
return error;
/* Write a single byte to force the file system to allocate space now or
* report an error, since we can't report errors when writing using mmap.
* Round the size up to the nearest page so that we only need to perform file
* I/O when we add a page, instead of whenever we write even a single byte. */
new_size = current_size + size;
page_offset = new_size % mmap_alignment;
page_start = new_size - page_offset;
if (p_lseek(fd, page_start + mmap_alignment - 1, SEEK_SET) < 0 ||
p_write(idx->pack->mwf.fd, data, 1) < 0) {
giterr_set(GITERR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
return -1;
@ -909,7 +937,6 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
git_buf filename = GIT_BUF_INIT;
struct entry *entry;
git_oid trailer_hash, file_hash;
git_hash_ctx ctx;
git_filebuf index_file = {0};
void *packfile_trailer;
@ -918,9 +945,6 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
return -1;
}
if (git_hash_ctx_init(&ctx) < 0)
return -1;
/* Test for this before resolve_deltas(), as it plays with idx->off */
if (idx->off + 20 < idx->pack->mwf.size) {
giterr_set(GITERR_INDEXER, "unexpected data at the end of the pack");
@ -964,6 +988,10 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
git_vector_sort(&idx->objects);
/* Use the trailer hash as the pack file name to ensure
* files with different contents have different names */
git_oid_cpy(&idx->hash, &trailer_hash);
git_buf_sets(&filename, idx->pack->pack_name);
git_buf_shorten(&filename, strlen("pack"));
git_buf_puts(&filename, "idx");
@ -971,7 +999,9 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
return -1;
if (git_filebuf_open(&index_file, filename.ptr,
GIT_FILEBUF_HASH_CONTENTS, idx->mode) < 0)
GIT_FILEBUF_HASH_CONTENTS |
(idx->do_fsync ? GIT_FILEBUF_FSYNC : 0),
idx->mode) < 0)
goto on_error;
/* Write out the header */
@ -988,9 +1018,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
/* Write out the object names (SHA-1 hashes) */
git_vector_foreach(&idx->objects, i, entry) {
git_filebuf_write(&index_file, &entry->oid, sizeof(git_oid));
git_hash_update(&ctx, &entry->oid, GIT_OID_RAWSZ);
}
git_hash_final(&idx->hash, &ctx);
/* Write out the CRC32 values */
git_vector_foreach(&idx->objects, i, entry) {
@ -1041,6 +1069,18 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
goto on_error;
git_mwindow_free_all(&idx->pack->mwf);
/* Truncate file to undo rounding up to next page_size in append_to_pack */
if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
giterr_set(GITERR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
return -1;
}
if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
giterr_set(GITERR_OS, "failed to fsync packfile");
goto on_error;
}
/* We need to close the descriptor here so Windows doesn't choke on commit_at */
if (p_close(idx->pack->mwf.fd) < 0) {
giterr_set(GITERR_OS, "failed to close packfile");
@ -1053,17 +1093,23 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
goto on_error;
/* And don't forget to rename the packfile to its new place. */
p_rename(idx->pack->pack_name, git_buf_cstr(&filename));
if (p_rename(idx->pack->pack_name, git_buf_cstr(&filename)) < 0)
goto on_error;
/* And fsync the parent directory if we're asked to. */
if (idx->do_fsync &&
git_futils_fsync_parent(git_buf_cstr(&filename)) < 0)
goto on_error;
idx->pack_committed = 1;
git_buf_free(&filename);
git_hash_ctx_cleanup(&ctx);
return 0;
on_error:
git_mwindow_free_all(&idx->pack->mwf);
git_filebuf_cleanup(&index_file);
git_buf_free(&filename);
git_hash_ctx_cleanup(&ctx);
return -1;
}
@ -1074,10 +1120,11 @@ void git_indexer_free(git_indexer *idx)
git_vector_free_deep(&idx->objects);
if (idx->pack && idx->pack->idx_cache) {
if (idx->pack->idx_cache) {
struct git_pack_entry *pentry;
kh_foreach_value(
idx->pack->idx_cache, pentry, { git__free(pentry); });
git_oidmap_foreach_value(idx->pack->idx_cache, pentry, {
git__free(pentry);
});
git_oidmap_free(idx->pack->idx_cache);
}
@ -1085,6 +1132,9 @@ void git_indexer_free(git_indexer *idx)
git_vector_free_deep(&idx->deltas);
if (!git_mutex_lock(&git__mwindow_mutex)) {
if (!idx->pack_committed)
git_packfile_close(idx->pack, true);
git_packfile_free(idx->pack);
git_mutex_unlock(&git__mwindow_mutex);
}

12
src/indexer.h Normal file
View File

@ -0,0 +1,12 @@
/*
* 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_indexer_h__
#define INCLUDE_indexer_h__
extern int git_indexer__set_fsync(git_indexer *idx, int do_fsync);
#endif

View File

@ -55,16 +55,16 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t
}
/* Use clang/gcc compiler intrinsics whenever possible */
#if (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow)
# define git__add_sizet_overflow(out, one, two) \
__builtin_uadd_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \
__builtin_umul_overflow(one, two, out)
#elif (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow)
#if (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow)
# define git__add_sizet_overflow(out, one, two) \
__builtin_uaddl_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \
__builtin_umull_overflow(one, two, out)
#elif (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow)
# define git__add_sizet_overflow(out, one, two) \
__builtin_uadd_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \
__builtin_umul_overflow(one, two, out)
#else
/**

View File

@ -78,7 +78,7 @@ int merge_bases_many(git_commit_list **out, git_revwalk **walk_out, git_reposito
unsigned int i;
if (length < 2) {
giterr_set(GITERR_INVALID, "At least two commits are required to find an ancestor. Provided 'length' was %" PRIuZ ".", length);
giterr_set(GITERR_INVALID, "at least two commits are required to find an ancestor");
return -1;
}
@ -104,7 +104,7 @@ int merge_bases_many(git_commit_list **out, git_revwalk **walk_out, git_reposito
goto on_error;
if (!result) {
giterr_set(GITERR_MERGE, "No merge base found");
giterr_set(GITERR_MERGE, "no merge base found");
error = GIT_ENOTFOUND;
goto on_error;
}
@ -184,7 +184,7 @@ int git_merge_base_octopus(git_oid *out, git_repository *repo, size_t length, co
assert(out && repo && input_array);
if (length < 2) {
giterr_set(GITERR_INVALID, "At least two commits are required to find an ancestor. Provided 'length' was %" PRIuZ ".", length);
giterr_set(GITERR_INVALID, "at least two commits are required to find an ancestor");
return -1;
}
@ -230,7 +230,7 @@ static int merge_bases(git_commit_list **out, git_revwalk **walk_out, git_reposi
if (!result) {
git_revwalk_free(walk);
giterr_set(GITERR_MERGE, "No merge base found");
giterr_set(GITERR_MERGE, "no merge base found");
return GIT_ENOTFOUND;
}
@ -562,7 +562,7 @@ int git_repository_mergehead_foreach(
assert(repo && cb);
if ((error = git_buf_joinpath(&merge_head_path, repo->path_repository,
if ((error = git_buf_joinpath(&merge_head_path, repo->gitdir,
GIT_MERGE_HEAD_FILE)) < 0)
return error;
@ -574,7 +574,7 @@ int git_repository_mergehead_foreach(
while ((line = git__strsep(&buffer, "\n")) != NULL) {
if (strlen(line) != GIT_OID_HEXSZ) {
giterr_set(GITERR_INVALID, "Unable to parse OID - invalid length");
giterr_set(GITERR_INVALID, "unable to parse OID - invalid length");
error = -1;
goto cleanup;
}
@ -591,7 +591,7 @@ int git_repository_mergehead_foreach(
}
if (*buffer) {
giterr_set(GITERR_MERGE, "No EOL at line %"PRIuZ, line_num);
giterr_set(GITERR_MERGE, "no EOL at line %"PRIuZ, line_num);
error = -1;
goto cleanup;
}
@ -1075,7 +1075,7 @@ static int index_entry_similarity_inexact(
int score = 0;
int error = 0;
if (GIT_MODE_TYPE(a->mode) != GIT_MODE_TYPE(b->mode))
if (!GIT_MODE_ISBLOB(a->mode) || !GIT_MODE_ISBLOB(b->mode))
return 0;
/* update signature cache if needed */
@ -1713,16 +1713,16 @@ static int merge_normalize_opts(
if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
return error;
if (given != NULL)
if (given != NULL) {
memcpy(opts, given, sizeof(git_merge_options));
else {
} else {
git_merge_options init = GIT_MERGE_OPTIONS_INIT;
memcpy(opts, &init, sizeof(init));
opts->flags = GIT_MERGE_FIND_RENAMES;
opts->rename_threshold = GIT_MERGE_DEFAULT_RENAME_THRESHOLD;
}
if ((opts->flags & GIT_MERGE_FIND_RENAMES) && !opts->rename_threshold)
opts->rename_threshold = GIT_MERGE_DEFAULT_RENAME_THRESHOLD;
if (given && given->default_driver) {
opts->default_driver = git__strdup(given->default_driver);
GITERR_CHECK_ALLOC(opts->default_driver);
@ -2018,6 +2018,26 @@ int git_merge_trees(
git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
int error;
assert(out && repo);
/* if one side is treesame to the ancestor, take the other side */
if (ancestor_tree && merge_opts && (merge_opts->flags & GIT_MERGE_SKIP_REUC)) {
const git_tree *result = NULL;
const git_oid *ancestor_tree_id = git_tree_id(ancestor_tree);
if (our_tree && !git_oid_cmp(ancestor_tree_id, git_tree_id(our_tree)))
result = their_tree;
else if (their_tree && !git_oid_cmp(ancestor_tree_id, git_tree_id(their_tree)))
result = our_tree;
if (result) {
if ((error = git_index_new(out)) == 0)
error = git_index_read_tree(*out, result);
return error;
}
}
iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
if ((error = git_iterator_for_tree(
@ -2277,7 +2297,7 @@ static int write_merge_head(
assert(repo && heads);
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_HEAD_FILE)) < 0 ||
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 ||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0)
goto cleanup;
@ -2305,7 +2325,7 @@ static int write_merge_mode(git_repository *repo)
assert(repo);
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MODE_FILE)) < 0 ||
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 ||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0)
goto cleanup;
@ -2536,7 +2556,7 @@ static int write_merge_msg(
for (i = 0; i < heads_len; i++)
entries[i].merge_head = heads[i];
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0 ||
(error = git_filebuf_write(&file, "Merge ", 6)) < 0)
goto cleanup;
@ -2914,7 +2934,7 @@ int git_merge__append_conflicts_to_merge_msg(
if (!git_index_has_conflicts(index))
return 0;
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0)
goto cleanup;
@ -3043,7 +3063,7 @@ int git_merge_analysis(
assert(analysis_out && preference_out && repo && their_heads);
if (their_heads_len != 1) {
giterr_set(GITERR_MERGE, "Can only merge a single branch");
giterr_set(GITERR_MERGE, "can only merge a single branch");
error = -1;
goto done;
}
@ -3099,7 +3119,7 @@ int git_merge(
assert(repo && their_heads);
if (their_heads_len != 1) {
giterr_set(GITERR_MERGE, "Can only merge a single branch");
giterr_set(GITERR_MERGE, "can only merge a single branch");
return -1;
}

View File

@ -32,6 +32,35 @@ static struct merge_driver_registry merge_driver_registry;
static void git_merge_driver_global_shutdown(void);
const git_repository* git_merge_driver_source_repo(const git_merge_driver_source *src)
{
assert(src);
return src->repo;
}
const git_index_entry* git_merge_driver_source_ancestor(const git_merge_driver_source *src)
{
assert(src);
return src->ancestor;
}
const git_index_entry* git_merge_driver_source_ours(const git_merge_driver_source *src)
{
assert(src);
return src->ours;
}
const git_index_entry* git_merge_driver_source_theirs(const git_merge_driver_source *src)
{
assert(src);
return src->theirs;
}
const git_merge_file_options* git_merge_driver_source_file_options(const git_merge_driver_source *src)
{
assert(src);
return src->file_opts;
}
int git_merge_driver__builtin_apply(
git_merge_driver *self,

View File

@ -127,7 +127,7 @@ static int merge_file__xdiff(
if ((xdl_result = xdl_merge(&ancestor_mmfile, &our_mmfile,
&their_mmfile, &xmparam, &mmbuffer)) < 0) {
giterr_set(GITERR_MERGE, "Failed to merge files.");
giterr_set(GITERR_MERGE, "failed to merge files");
error = -1;
goto done;
}

View File

@ -14,8 +14,6 @@
#include "strmap.h"
#include "pack.h"
GIT__USE_STRMAP
#define DEFAULT_WINDOW_SIZE \
(sizeof(void*) >= 8 \
? 1 * 1024 * 1024 * 1024 \
@ -84,7 +82,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
git_atomic_inc(&pack->refcount);
git_strmap_insert(git__pack_cache, pack->pack_name, pack, error);
git_strmap_insert(git__pack_cache, pack->pack_name, pack, &error);
git_mutex_unlock(&git__mwindow_mutex);
if (error < 0) {
@ -231,7 +229,7 @@ static int git_mwindow_close_lru(git_mwindow_file *mwf)
}
if (!lru_w) {
giterr_set(GITERR_OS, "Failed to close memory window. Couldn't find LRU");
giterr_set(GITERR_OS, "failed to close memory window; couldn't find LRU");
return -1;
}

View File

@ -144,7 +144,7 @@ int gitno_connection_data_from_url(
default_port = "80";
if (data->use_ssl) {
giterr_set(GITERR_NET, "Redirect from HTTPS to HTTP is not allowed");
giterr_set(GITERR_NET, "redirect from HTTPS to HTTP is not allowed");
goto cleanup;
}
} else if (!git__prefixcmp(url, prefix_https)) {
@ -155,7 +155,7 @@ int gitno_connection_data_from_url(
default_port = data->use_ssl ? "443" : "80";
if (!default_port) {
giterr_set(GITERR_NET, "Unrecognized URL prefix");
giterr_set(GITERR_NET, "unrecognized URL prefix");
goto cleanup;
}
@ -187,7 +187,7 @@ int gitno_connection_data_from_url(
/* Check for errors in the resulting data */
if (original_host && url[0] != '/' && strcmp(original_host, data->host)) {
giterr_set(GITERR_NET, "Cross host redirect not allowed");
giterr_set(GITERR_NET, "cross host redirect not allowed");
error = -1;
}
}
@ -237,7 +237,7 @@ int gitno_extract_url_parts(
const char *_host, *_port, *_path, *_userinfo;
if (http_parser_parse_url(url, strlen(url), false, &u)) {
giterr_set(GITERR_NET, "Malformed URL '%s'", url);
giterr_set(GITERR_NET, "malformed URL '%s'", url);
return GIT_EINVALIDSPEC;
}

View File

@ -15,7 +15,7 @@
static int note_error_notfound(void)
{
giterr_set(GITERR_INVALID, "Note could not be found");
giterr_set(GITERR_INVALID, "note could not be found");
return GIT_ENOTFOUND;
}
@ -226,7 +226,7 @@ static int remove_note_in_tree_enotfound_cb(
GIT_UNUSED(note_oid);
GIT_UNUSED(fanout);
giterr_set(GITERR_REPOSITORY, "Object '%s' has no note", annotated_object_sha);
giterr_set(GITERR_REPOSITORY, "object '%s' has no note", annotated_object_sha);
return current_error;
}
@ -244,7 +244,7 @@ static int insert_note_in_tree_eexists_cb(git_tree **out,
GIT_UNUSED(note_oid);
GIT_UNUSED(fanout);
giterr_set(GITERR_REPOSITORY, "Note for '%s' exists already", annotated_object_sha);
giterr_set(GITERR_REPOSITORY, "note for '%s' exists already", annotated_object_sha);
return current_error;
}

Some files were not shown because too many files have changed in this diff Show More