Update upstream source from tag 'upstream/1.0.0+dfsg.1'

Update to upstream version '1.0.0+dfsg.1'
with Debian dir 8c465e4156
This commit is contained in:
Utkarsh Gupta 2020-04-09 21:11:29 +05:30
commit a40c71fb9f
61 changed files with 690 additions and 302 deletions

View File

@ -36,6 +36,7 @@ INCLUDE(AddCFlagIfSupported)
INCLUDE(FindPkgLibraries)
INCLUDE(FindThreads)
INCLUDE(FindStatNsec)
INCLUDE(GNUInstallDirs)
INCLUDE(IdeSplitSources)
INCLUDE(FeatureSummary)
INCLUDE(EnableWarnings)

View File

@ -4,9 +4,8 @@ libgit2 - the Git linkable library
| Build Status | |
| ------------ | - |
| **master** branch CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=master)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=master) |
| **v0.99 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.99)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.99) |
| **v0.28 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.28)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.28) |
| **v0.27 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.27)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.27) |
| **v0.26 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.26)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.26) |
| **Nightly** builds | [![Azure Pipelines Build Status](https://libgit2.visualstudio.com/libgit2/_apis/build/status/nightly?branchName=master&label=Full+Build)](https://libgit2.visualstudio.com/libgit2/_build/latest?definitionId=9&branchName=master) [![Coverity Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/coverity?branchName=master&label=Coverity+Build)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=21?branchName=master) [![Coverity Scan Build Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) |
`libgit2` is a portable, pure C implementation of the Git core methods
@ -248,9 +247,9 @@ For more advanced use or questions about CMake please read <https://cmake.org/Wi
The following CMake variables are declared:
- `BIN_INSTALL_DIR`: Where to install binaries to.
- `LIB_INSTALL_DIR`: Where to install libraries to.
- `INCLUDE_INSTALL_DIR`: Where to install headers to.
- `CMAKE_INSTALL_BINDIR`: Where to install binaries to.
- `CMAKE_INSTALL_LIBDIR`: Where to install libraries to.
- `CMAKE_INSTALL_INCLUDEDIR`: Where to install headers to.
- `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON)
- `BUILD_CLAR`: Build [Clar](https://github.com/vmg/clar)-based test suite (defaults to ON)
- `THREADSAFE`: Build libgit2 with threading support (defaults to ON)
@ -330,6 +329,8 @@ Here are the bindings to libgit2 that are currently available:
* hgit2 <https://github.com/jwiegley/gitlib>
* Java
* Jagged <https://github.com/ethomson/jagged>
* Javascript / WebAssembly ( browser and nodejs )
* WASM-git <https://github.com/petersalomonsen/wasm-git>
* Julia
* LibGit2.jl <https://github.com/JuliaLang/julia/tree/master/stdlib/LibGit2>
* Lua

View File

@ -9,7 +9,7 @@ jobs:
- job: linux_amd64_xenial_gcc_openssl
displayName: 'Linux (amd64; Xenial; GCC; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: azure-pipelines/docker.yml
parameters:
@ -25,7 +25,7 @@ jobs:
- job: linux_amd64_xenial_gcc_mbedtls
displayName: 'Linux (amd64; Xenial; GCC; mbedTLS)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: azure-pipelines/docker.yml
parameters:
@ -41,7 +41,7 @@ jobs:
- job: linux_amd64_xenial_clang_openssl
displayName: 'Linux (amd64; Xenial; Clang; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: azure-pipelines/docker.yml
parameters:
@ -57,7 +57,7 @@ jobs:
- job: linux_amd64_xenial_clang_mbedtls
displayName: 'Linux (amd64; Xenial; Clang; mbedTLS)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: azure-pipelines/docker.yml
parameters:
@ -71,9 +71,9 @@ jobs:
GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }}
- job: macos
displayName: 'macOS'
displayName: 'macOS (amd64; 10.15)'
pool:
vmImage: 'macOS 10.13'
vmImage: 'macOS-10.15'
steps:
- bash: . '$(Build.SourcesDirectory)/azure-pipelines/setup-osx.sh'
displayName: Setup
@ -89,31 +89,34 @@ jobs:
- job: windows_vs_amd64
displayName: 'Windows (amd64; Visual Studio)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- template: azure-pipelines/bash.yml
parameters:
environmentVariables:
CMAKE_GENERATOR: Visual Studio 12 2013 Win64
CMAKE_OPTIONS: -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- job: windows_vs_x86
displayName: 'Windows (x86; Visual Studio)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- template: azure-pipelines/bash.yml
parameters:
environmentVariables:
CMAKE_GENERATOR: Visual Studio 12 2013
CMAKE_OPTIONS: -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- job: windows_mingw_amd64
displayName: 'Windows (amd64; MinGW)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh'
displayName: Setup
@ -131,7 +134,8 @@ jobs:
- job: windows_mingw_x86
displayName: 'Windows (x86; MinGW)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh'
displayName: Setup
@ -151,7 +155,7 @@ jobs:
- job: documentation
displayName: 'Generate Documentation'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- script: |
cd $(Build.SourcesDirectory)/azure-pipelines/docker

View File

@ -25,7 +25,7 @@ TOOL_DIR=${BUILD_DIR}/coverity-tools
if ! test -d "$TOOL_DIR"
then
mkdir -p "$TOOL_DIR"
curl --silent --location --data "project=libgit2&token=$COVERITY_TOKEN" "$SCAN_TOOL" |
curl --silent --show-error --location --data "project=libgit2&token=$COVERITY_TOKEN" "$SCAN_TOOL" |
tar -xzC "$TOOL_DIR"
ln -s "$(find "$TOOL_DIR" -type d -name 'cov-analysis*')" "$TOOL_DIR"/cov-analysis
fi
@ -44,7 +44,7 @@ COVERITY_UNSUPPORTED=1 \
tar -czf libgit2.tgz cov-int
REVISION=$(cd ${SOURCE_DIR} && git rev-parse --short HEAD)
HTML="$(curl \
--silent \
--silent --show-error \
--write-out "\n%{http_code}" \
--form token="$COVERITY_TOKEN" \
--form email=libgit2@gmail.com \

View File

@ -5,7 +5,7 @@ jobs:
- job: coverity
displayName: 'Coverity'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- script: |
cd $(Build.SourcesDirectory)/azure-pipelines/docker

View File

@ -25,7 +25,7 @@ RUN apt-get update && \
FROM apt AS mbedtls
RUN cd /tmp && \
curl --location --silent https://tls.mbed.org/download/mbedtls-2.16.2-apache.tgz | \
curl --location --silent --show-error https://tls.mbed.org/download/mbedtls-2.16.2-apache.tgz | \
tar -xz && \
cd mbedtls-2.16.2 && \
scripts/config.pl set MBEDTLS_MD4_C 1 && \

View File

@ -1,6 +1,3 @@
FROM debian:jessie-slim
ARG CACHEBUST=1
RUN apt-get update
RUN apt install -y cmake pkg-config ruby ruby-dev llvm libclang-3.5-dev libssl-dev python-pygments
ARG CACHEBUST=1
FROM ubuntu:bionic
RUN apt update && apt install -y cmake pkg-config ruby ruby-dev llvm libclang-dev libssl-dev python-pygments
RUN gem install docurium

View File

@ -1,4 +1,4 @@
#!/bin/bash -e
useradd --shell /bin/bash libgit2
chown --recursive libgit2:libgit2 /home/libgit2
exec sudo --preserve-env --user=libgit2 "$@"
exec sudo --preserve-env --set-home --user=libgit2 "$@"

View File

@ -29,7 +29,7 @@ RUN apt-get update && \
FROM apt AS mbedtls
RUN cd /tmp && \
curl --location --silent https://tls.mbed.org/download/mbedtls-2.16.2-apache.tgz | \
curl --location --silent --show-error https://tls.mbed.org/download/mbedtls-2.16.2-apache.tgz | \
tar -xz && \
cd mbedtls-2.16.2 && \
scripts/config.pl set MBEDTLS_MD4_C 1 && \
@ -40,7 +40,7 @@ RUN cd /tmp && \
FROM mbedtls AS libssh2
RUN cd /tmp && \
curl --location --silent https://www.libssh2.org/download/libssh2-1.8.2.tar.gz | \
curl --insecure --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.2.tar.gz | \
tar -xz && \
cd libssh2-1.8.2 && \
CFLAGS=-fPIC cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=Libgcrypt . && \
@ -50,7 +50,7 @@ RUN cd /tmp && \
FROM libssh2 AS valgrind
RUN cd /tmp && \
curl --location --silent https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2 | \
curl --insecure --location --silent --show-error https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2 | \
tar -xj && \
cd valgrind-3.15.0 && \
./configure && \

View File

@ -5,7 +5,7 @@ jobs:
- job: linux_amd64_xenial_gcc_openssl
displayName: 'Linux (amd64; Xenial; GCC; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -21,7 +21,7 @@ jobs:
- job: linux_amd64_xenial_gcc_mbedtls
displayName: 'Linux (amd64; Xenial; GCC; mbedTLS)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -37,7 +37,7 @@ jobs:
- job: linux_amd64_xenial_clang_openssl
displayName: 'Linux (amd64; Xenial; Clang; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -53,7 +53,7 @@ jobs:
- job: linux_amd64_xenial_clang_mbedtls
displayName: 'Linux (amd64; Xenial; Clang; mbedTLS)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -67,9 +67,9 @@ jobs:
RUN_INVASIVE_TESTS=true
- job: macos
displayName: 'macOS'
displayName: 'macOS (amd64; 10.15)'
pool:
vmImage: 'macOS 10.13'
vmImage: 'macOS-10.15'
steps:
- bash: . '$(Build.SourcesDirectory)/azure-pipelines/setup-osx.sh'
displayName: Setup
@ -85,31 +85,34 @@ jobs:
- job: windows_vs_amd64
displayName: 'Windows (amd64; Visual Studio)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- template: bash.yml
parameters:
environmentVariables:
CMAKE_GENERATOR: Visual Studio 12 2013 Win64
CMAKE_OPTIONS: -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON
RUN_INVASIVE_TESTS: true
SKIP_SSH_TESTS: true
- job: windows_vs_x86
displayName: 'Windows (x86; Visual Studio)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- template: bash.yml
parameters:
environmentVariables:
CMAKE_GENERATOR: Visual Studio 12 2013
CMAKE_OPTIONS: -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS
RUN_INVASIVE_TESTS: true
SKIP_SSH_TESTS: true
- job: windows_mingw_amd64
displayName: 'Windows (amd64; MinGW)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh'
displayName: Setup
@ -127,7 +130,8 @@ jobs:
- job: windows_mingw_x86
displayName: 'Windows (x86; MinGW)'
pool: Hosted
pool:
vmImage: 'vs2017-win2016'
steps:
- bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh'
displayName: Setup
@ -147,7 +151,7 @@ jobs:
- job: linux_x86_bionic_gcc_openssl
displayName: 'Linux (x86; Bionic; GCC; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -164,7 +168,7 @@ jobs:
- job: linux_x86_bionic_clang_openssl
displayName: 'Linux (x86; Bionic; Clang; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -181,7 +185,7 @@ jobs:
- job: linux_arm32_bionic_gcc_openssl
displayName: 'Linux (arm32; Bionic; GCC; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:
@ -199,7 +203,7 @@ jobs:
- job: linux_arm64_bionic_gcc_openssl
displayName: 'Linux (arm64; Bionic; GCC; OpenSSL)'
pool:
vmImage: 'Ubuntu 16.04'
vmImage: 'ubuntu-18.04'
steps:
- template: docker.yml
parameters:

View File

@ -85,7 +85,7 @@ if [ -z "$SKIP_GITDAEMON_TESTS" ]; then
fi
if [ -z "$SKIP_PROXY_TESTS" ]; then
curl --location --silent https://github.com/ethomson/poxyproxy/releases/download/v0.7.0/poxyproxy-0.7.0.jar >poxyproxy.jar
curl --location --silent --show-error https://github.com/ethomson/poxyproxy/releases/download/v0.7.0/poxyproxy-0.7.0.jar >poxyproxy.jar
echo ""
echo "Starting HTTP proxy (Basic)..."
@ -97,7 +97,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
fi
if [ -z "$SKIP_NTLM_TESTS" ]; then
curl --location --silent https://github.com/ethomson/poxygit/releases/download/v0.4.0/poxygit-0.4.0.jar >poxygit.jar
curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.4.0/poxygit-0.4.0.jar >poxygit.jar
echo ""
echo "Starting HTTP server..."

View File

@ -1,10 +1,5 @@
# pkg-config file generation
#
# Uses the following globals:
# - PKG_BUILD_PREFIX: the build location (aka prefix). Defaults to CMAKE_INSTALL_PREFIX
# - PKG_BUILD_LIBDIR: the libdir location. Defaults to ${prefix}/lib.
# - PKG_BUILD_INCLUDEDIR: the includedir location. Defaults to ${prefix}/include.
#
function(pkg_build_config)
set(options)
@ -29,37 +24,11 @@ function(pkg_build_config)
message(FATAL_ERROR "Missing VERSION argument")
endif()
if (DEFINED PKG_BUILD_PREFIX)
set(PKGCONFIG_PREFIX "${PKG_BUILD_PREFIX}")
else()
set(PKGCONFIG_PREFIX "${CMAKE_INSTALL_PREFIX}")
endif()
if(DEFINED PKG_BUILD_LIBDIR)
if (IS_ABSOLUTE ${PKG_BUILD_LIBDIR})
set(PKGCONFIG_LIBDIR ${PKG_BUILD_LIBDIR})
else()
set(PKGCONFIG_LIBDIR "\${prefix}/${PKG_BUILD_LIBDIR}")
endif()
else()
set(PKGCONFIG_LIBDIR "\${prefix}/lib")
endif()
if(DEFINED PKG_BUILD_INCLUDEDIR)
if (IS_ABSOLUTE ${PKG_BUILD_INCLUDEDIR})
set(PKGCONFIG_INCLUDEDIR ${PKG_BUILD_INCLUDEDIR})
else()
set(PKGCONFIG_INCLUDEDIR "\${prefix}/${PKG_BUILD_INCLUDEDIR}")
endif()
else()
set(PKGCONFIG_INCLUDEDIR "\${prefix}/include")
endif()
# Write .pc "header"
file(WRITE "${PKGCONFIG_FILE}"
"prefix=\"${PKGCONFIG_PREFIX}\"\n"
"libdir=\"${PKGCONFIG_LIBDIR}\"\n"
"includedir=\"${PKGCONFIG_INCLUDEDIR}\"\n"
"prefix=\"${CMAKE_INSTALL_PREFIX}\"\n"
"libdir=\"${CMAKE_INSTALL_FULL_LIBDIR}\"\n"
"includedir=\"${CMAKE_INSTALL_FULL_INCLUDEDIR}\"\n"
"\n"
"Name: ${PKGCONFIG_NAME}\n"
"Description: ${PKGCONFIG_DESCRIPTION}\n"
@ -104,7 +73,5 @@ function(pkg_build_config)
file(APPEND "${PKGCONFIG_FILE}" "Cflags: -I\${includedir} ${PKGCONFIG_CFLAGS}\n")
# Install .pc file
install(FILES "${PKGCONFIG_FILE}"
DESTINATION "${PKGCONFIG_PREFIX}/${PKGCONFIG_LIBDIR}/pkgconfig"
)
install(FILES "${PKGCONFIG_FILE}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endfunction()

View File

@ -0,0 +1,20 @@
FUNCTION(SanitizeBool VAR)
STRING(TOLOWER "${${VAR}}" VALUE)
IF(VALUE STREQUAL "on")
SET(${VAR} "ON" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "yes")
SET(${VAR} "ON" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "true")
SET(${VAR} "ON" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "1")
SET(${VAR} "ON" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "off")
SET(${VAR} "OFF" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "no")
SET(${VAR} "OFF" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "false")
SET(${VAR} "OFF" PARENT_SCOPE)
ELSEIF(VALUE STREQUAL "0")
SET(${VAR} "OFF" PARENT_SCOPE)
ENDIF()
ENDFUNCTION()

View File

@ -2,12 +2,15 @@
# We try to find any packages our backends might use
INCLUDE(SanitizeBool)
FIND_PACKAGE(GSSAPI)
IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
INCLUDE(FindGSSFramework)
ENDIF()
# Auto-select GSS backend
SanitizeBool(USE_GSSAPI)
IF (USE_GSSAPI STREQUAL ON)
IF (GSSFRAMEWORK_FOUND)
SET(GSS_BACKEND "GSS.framework")

View File

@ -1,5 +1,7 @@
# Select the backend to use
INCLUDE(SanitizeBool)
# We try to find any packages our backends might use
FIND_PACKAGE(OpenSSL)
FIND_PACKAGE(mbedTLS)
@ -9,6 +11,7 @@ IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF()
# Auto-select TLS backend
SanitizeBool(USE_HTTPS)
IF (USE_HTTPS STREQUAL ON)
IF (SECURITY_FOUND)
IF (SECURITY_HAS_SSLCREATECONTEXT)

View File

@ -1,7 +1,10 @@
# Select a hash backend
INCLUDE(SanitizeBool)
# USE_SHA1=CollisionDetection(ON)/HTTPS/Generic/OFF
SanitizeBool(USE_SHA1)
IF(USE_SHA1 STREQUAL ON OR USE_SHA1 STREQUAL "CollisionDetection")
SET(SHA1_BACKEND "CollisionDetection")
ELSEIF(USE_SHA1 STREQUAL "HTTPS")

View File

@ -1,3 +1,54 @@
v1.0
----
This is release v1.0 "Luftschloss", which is the first stabe release of
libgit2. The API will stay compatible across all releases of the same major
version. This release includes bugfixes only and supersedes v0.99, which will
stop being maintained. Both v0.27 and v0.28 stay supported in accordance with
our release policy.
### Changes or improvements
- CMake was converted to make use of the GNUInstallDirs module for both our
pkgconfig and install targets in favor of our custom build options
`BIN_INSTALL_DIR`, `LIB_INSTALL_DIR` and `INCLUDE_INSTALL_DIR`. Instead, you
can now use CMakes standard variables `CMAKE_INSTALL_BINDIR`,
`CMAKE_INSTALL_LIBDIR` and `CMAKE_INSTALL_INCLUDEDIR`.
- Some CMake build options accepted either a specific value or a boolean value
to disable the option altogether or use automatic detection. We only accepted
"ON" or "OFF", but none of the other values CMake recognizes as boolean. This
was aligned with CMake's understanding of booleans.
- The installed pkgconfig file contained incorrect values for both `libdir` and
`includedir` variables.
- If using pcre2 for regular expressions, then we incorrectly added "pcre2"
instead of "pcre2-8" to our pkgconfig dependencies, which was corrected.
- Fixed building the bundled ntlmclient dependency on FreeBSD, OpenBSD and
SunOS.
- When writing symlinks on Windows, we incorrectly handled relative symlink
targets, which was corrected.
- When using the HTTP protocol via macOS' SecureTransport implementation, reads
could stall at the end of the session and only continue after a timeout of 60
seconds was reached.
- The filesystem-based reference callback didn't corectly initialize the backend
version.
- A segmentation fault was fixed when calling `git_blame_buffer()` for files
that were modified and added to the index.
- A backwards-incompatible change was introduced when we moved some structures
from "git2/credentials.h" into "git2/sys/credentials.h". This was fixed in the
case where you do not use hard deprecation.
- Improved error handling in various places.
v0.99
-----

View File

@ -41,6 +41,13 @@
*/
#ifndef GIT_DEPRECATE_HARD
/*
* The credential structures are now opaque by default, and their
* definition has moved into the `sys/credential.h` header; include
* them here for backward compatibility.
*/
#include "sys/credential.h"
/**
* @file git2/deprecated.h
* @brief libgit2 deprecated functions and values

View File

@ -481,10 +481,11 @@ GIT_EXTERN(const char *) git_repository_path(const git_repository *repo);
GIT_EXTERN(const char *) git_repository_workdir(const 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.
* Get the path of the shared common directory for this repository.
*
* If the repository is bare, it is the root directory for the repository.
* If the repository is a worktree, it is the parent repo's gitdir.
* Otherwise, it is the gitdir.
*
* @param repo A repository object
* @return the path to the common dir

View File

@ -64,6 +64,12 @@ struct git_refdb_backend {
* Queries the refdb backend for the existence of a reference.
*
* A refdb implementation must provide this function.
*
* @arg exists The implementation shall set this to `0` if a ref does
* not exist, otherwise to `1`.
* @arg ref_name The reference's name that should be checked for
* existence.
* @return `0` on success, a negative error value code.
*/
int GIT_CALLBACK(exists)(
int *exists,
@ -74,6 +80,13 @@ struct git_refdb_backend {
* Queries the refdb backend for a given reference.
*
* A refdb implementation must provide this function.
*
* @arg out The implementation shall set this to the allocated
* reference, if it could be found, otherwise to `NULL`.
* @arg ref_name The reference's name that should be checked for
* existence.
* @return `0` on success, `GIT_ENOTFOUND` if the reference does
* exist, otherwise a negative error code.
*/
int GIT_CALLBACK(lookup)(
git_reference **out,
@ -84,6 +97,16 @@ struct git_refdb_backend {
* Allocate an iterator object for the backend.
*
* A refdb implementation must provide this function.
*
* @arg out The implementation shall set this to the allocated
* reference iterator. A custom structure may be used with an
* embedded `git_reference_iterator` structure. Both `next`
* and `next_name` functions of `git_reference_iterator` need
* to be populated.
* @arg glob A pattern to filter references by. If given, the iterator
* shall only return references that match the glob when
* passed to `wildmatch`.
* @return `0` on success, otherwise a negative error code.
*/
int GIT_CALLBACK(iterator)(
git_reference_iterator **iter,
@ -94,6 +117,27 @@ struct git_refdb_backend {
* Writes the given reference to the refdb.
*
* A refdb implementation must provide this function.
*
* @arg ref The reference to persist. May either be a symbolic or
* direct reference.
* @arg force Whether to write the reference if a reference with the
* same name already exists.
* @arg who The person updating the reference. Shall be used to create
* a reflog entry.
* @arg message The message detailing what kind of reference update is
* performed. Shall be used to create a reflog entry.
* @arg old If not `NULL` and `force` is not set, then the
* implementation needs to ensure that the reference is currently at
* the given OID before writing the new value. If both `old`
* and `old_target` are `NULL`, then the reference should not
* exist at the point of writing.
* @arg old_target If not `NULL` and `force` is not set, then the
* implementation needs to ensure that the symbolic
* reference is currently at the given target before
* writing the new value. If both `old` and
* `old_target` are `NULL`, then the reference should
* not exist at the point of writing.
* @return `0` on success, otherwise a negative error code.
*/
int GIT_CALLBACK(write)(git_refdb_backend *backend,
const git_reference *ref, int force,
@ -104,6 +148,18 @@ struct git_refdb_backend {
* Rename a reference in the refdb.
*
* A refdb implementation must provide this function.
*
* @arg out The implementation shall set this to the newly created
* reference or `NULL` on error.
* @arg old_name The current name of the reference that is to be renamed.
* @arg new_name The new name that the old reference shall be renamed to.
* @arg force Whether to write the reference if a reference with the
* target name already exists.
* @arg who The person updating the reference. Shall be used to create
* a reflog entry.
* @arg message The message detailing what kind of reference update is
* performed. Shall be used to create a reflog entry.
* @return `0` on success, otherwise a negative error code.
*/
int GIT_CALLBACK(rename)(
git_reference **out, git_refdb_backend *backend,
@ -116,6 +172,16 @@ struct git_refdb_backend {
* If it exists, its reflog should be deleted as well.
*
* A refdb implementation must provide this function.
*
* @arg ref_name The name of the reference name that shall be deleted.
* @arg old_id If not `NULL` and `force` is not set, then the
* implementation needs to ensure that the reference is currently at
* the given OID before writing the new value.
* @arg old_target If not `NULL` and `force` is not set, then the
* implementation needs to ensure that the symbolic
* reference is currently at the given target before
* writing the new value.
* @return `0` on success, otherwise a negative error code.
*/
int GIT_CALLBACK(del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
@ -127,13 +193,21 @@ struct git_refdb_backend {
*
* A refdb implementation may provide this function; if it is not
* provided, nothing will be done.
*
* @return `0` on success a negative error code otherwise
*/
int GIT_CALLBACK(compress)(git_refdb_backend *backend);
/**
* Query whether a particular reference has a log (may be empty)
*
* Shall return 1 if it has a reflog, 0 it it doesn't and negative in
* case an error occurred.
*
* A refdb implementation must provide this function.
*
* @return `0` on success, `1` if the reflog for the given reference
* exists, a negative error code otherwise
*/
int GIT_CALLBACK(has_log)(git_refdb_backend *backend, const char *refname);
@ -142,6 +216,8 @@ struct git_refdb_backend {
* will be appended to on writes.
*
* A refdb implementation must provide this function.
*
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(ensure_log)(git_refdb_backend *backend, const char *refname);
@ -157,6 +233,8 @@ struct git_refdb_backend {
* Read the reflog for the given reference name.
*
* A refdb implementation must provide this function.
*
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(reflog_read)(git_reflog **out, git_refdb_backend *backend, const char *name);
@ -164,6 +242,11 @@ struct git_refdb_backend {
* Write a reflog to disk.
*
* A refdb implementation must provide this function.
*
* @arg reflog The complete reference log for a given reference. Note
* that this may contain entries that have already been
* written to disk.
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(reflog_write)(git_refdb_backend *backend, git_reflog *reflog);
@ -171,6 +254,10 @@ struct git_refdb_backend {
* Rename a reflog.
*
* A refdb implementation must provide this function.
*
* @arg old_name The name of old reference whose reflog shall be renamed from.
* @arg new_name The name of new reference whose reflog shall be renamed to.
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(reflog_rename)(git_refdb_backend *_backend, const char *old_name, const char *new_name);
@ -178,16 +265,22 @@ struct git_refdb_backend {
* Remove a reflog.
*
* A refdb implementation must provide this function.
*
* @arg name The name of the reference whose reflog shall be deleted.
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(reflog_delete)(git_refdb_backend *backend, const char *name);
/**
* Lock a reference.
*
* The opaque parameter will be passed to the unlock function.
*
* A refdb implementation may provide this function; if it is not
* provided, the transaction API will fail to work.
*
* @arg payload_out Opaque parameter that will be passed verbosely to
* `unlock`.
* @arg refname Reference that shall be locked.
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(lock)(void **payload_out, git_refdb_backend *backend, const char *refname);
@ -200,6 +293,20 @@ struct git_refdb_backend {
*
* A refdb implementation must provide this function if a `lock`
* implementation is provided.
*
* @arg payload The payload returned by `lock`.
* @arg success `1` if a reference should be updated, `2` if
* a reference should be deleted, `0` if the lock must be
* discarded.
* @arg update_reflog `1` in case the reflog should be updated, `0`
* otherwise.
* @arg ref The reference which should be unlocked.
* @arg who The person updating the reference. Shall be used to create
* a reflog entry in case `update_reflog` is set.
* @arg message The message detailing what kind of reference update is
* performed. Shall be used to create a reflog entry in
* case `update_reflog` is set.
* @return `0` on success, a negative error code otherwise
*/
int GIT_CALLBACK(unlock)(git_refdb_backend *backend, void *payload, int success, int update_reflog,
const git_reference *ref, const git_signature *sig, const char *message);

View File

@ -7,12 +7,12 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
#define LIBGIT2_VERSION "0.99.0"
#define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 99
#define LIBGIT2_VERSION "1.0.0"
#define LIBGIT2_VER_MAJOR 1
#define LIBGIT2_VER_MINOR 0
#define LIBGIT2_VER_REVISION 0
#define LIBGIT2_VER_PATCH 0
#define LIBGIT2_SOVERSION "0.99"
#define LIBGIT2_SOVERSION "1.0"
#endif

View File

@ -21,14 +21,8 @@ SET(LIBGIT2_INCLUDES
SET(LIBGIT2_SYSTEM_INCLUDES "")
SET(LIBGIT2_LIBS "")
# Installation paths
#
SET(BIN_INSTALL_DIR bin CACHE PATH "Where to install binaries to.")
SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.")
SET(INCLUDE_INSTALL_DIR include CACHE PATH "Where to install headers to.")
# Enable tracing
IF (ENABLE_TRACE STREQUAL "ON")
IF(ENABLE_TRACE)
SET(GIT_TRACE 1)
ENDIF()
ADD_FEATURE_INFO(tracing GIT_TRACE "tracing support")
@ -140,7 +134,7 @@ ELSEIF(REGEX_BACKEND STREQUAL "pcre2")
LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS})
LIST(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES})
LIST(APPEND LIBGIT2_PC_REQUIRES "libpcre2")
LIST(APPEND LIBGIT2_PC_REQUIRES "libpcre2-8")
ELSEIF(REGEX_BACKEND STREQUAL "pcre")
ADD_FEATURE_INFO(regex ON "using system PCRE")
SET(GIT_REGEX_PCRE 1)
@ -300,6 +294,10 @@ FILE(GLOB SRC_GIT2 *.c *.h
streams/*.c streams/*.h
transports/*.c transports/*.h
xdiff/*.c xdiff/*.h)
IF(APPLE)
# The old Secure Transport API has been deprecated in macOS 10.15.
SET_SOURCE_FILES_PROPERTIES(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated)
ENDIF()
# the xdiff dependency is not (yet) warning-free, disable warnings as
# errors for the xdiff sources until we've sorted them out
@ -387,9 +385,9 @@ ENDIF ()
# Install
INSTALL(TARGETS git2
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
INSTALL(DIRECTORY ${libgit2_SOURCE_DIR}/include/git2 DESTINATION ${INCLUDE_INSTALL_DIR} )
INSTALL(FILES ${libgit2_SOURCE_DIR}/include/git2.h DESTINATION ${INCLUDE_INSTALL_DIR} )
INSTALL(DIRECTORY ${libgit2_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
INSTALL(FILES ${libgit2_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

View File

@ -415,7 +415,7 @@ on_error:
static bool hunk_is_bufferblame(git_blame_hunk *hunk)
{
return git_oid_is_zero(&hunk->final_commit_id);
return hunk && git_oid_is_zero(&hunk->final_commit_id);
}
static int buffer_hunk_cb(

View File

@ -208,10 +208,14 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
entry = stored_entry;
} else if (stored_entry->flags == GIT_CACHE_STORE_RAW &&
entry->flags == GIT_CACHE_STORE_PARSED) {
git_cached_obj_decref(stored_entry);
git_cached_obj_incref(entry);
git_oidmap_set(cache->map, &entry->oid, entry);
if (git_oidmap_set(cache->map, &entry->oid, entry) == 0) {
git_cached_obj_decref(stored_entry);
git_cached_obj_incref(entry);
} else {
git_cached_obj_decref(entry);
git_cached_obj_incref(stored_entry);
entry = stored_entry;
}
} else {
/* NO OP */
}

View File

@ -150,11 +150,11 @@ int git_indexer_new(
idx->progress_cb = opts.progress_cb;
idx->progress_payload = opts.progress_cb_payload;
idx->mode = mode ? mode : GIT_PACK_FILE_MODE;
git_hash_ctx_init(&idx->hash_ctx);
git_hash_ctx_init(&idx->trailer);
git_buf_init(&idx->entry_data, 0);
if ((error = git_oidmap_new(&idx->expected_oids)) < 0)
if ((error = git_hash_ctx_init(&idx->hash_ctx)) < 0 ||
(error = git_hash_ctx_init(&idx->trailer)) < 0 ||
(error = git_oidmap_new(&idx->expected_oids)) < 0)
goto cleanup;
idx->do_verify = opts.verify;

View File

@ -808,8 +808,11 @@ int git_note_next(
git_oid_cpy(note_id, &item->id);
if (!(error = process_entry_path(item->path, annotated_id)))
git_iterator_advance(NULL, it);
if ((error = process_entry_path(item->path, annotated_id)) < 0)
return error;
return error;
if ((error = git_iterator_advance(NULL, it)) < 0 && error != GIT_ITEROVER)
return error;
return 0;
}

View File

@ -15,7 +15,6 @@
#include "hash.h"
#include "odb.h"
#include "delta.h"
#include "sha1_lookup.h"
#include "mwindow.h"
#include "pack.h"

View File

@ -374,7 +374,9 @@ static int write_object(
GIT_ERROR_CHECK_ALLOC(zbuf);
git_zstream_reset(&pb->zstream);
git_zstream_set_input(&pb->zstream, data, data_len);
if ((error = git_zstream_set_input(&pb->zstream, data, data_len)) < 0)
goto done;
while (!git_zstream_done(&pb->zstream)) {
if ((error = git_zstream_get_output(zbuf, &zbuf_len, &pb->zstream)) < 0 ||

View File

@ -12,7 +12,6 @@
#include "mwindow.h"
#include "odb.h"
#include "oid.h"
#include "sha1_lookup.h"
/* Option to bypass checking existence of '.keep' files */
bool git_disable_pack_keep_file_checks = false;
@ -1239,6 +1238,27 @@ int git_pack_foreach_entry(
return error;
}
static int sha1_position(const void *table, size_t stride, unsigned lo,
unsigned hi, const unsigned char *key)
{
const unsigned char *base = table;
while (lo < hi) {
unsigned mi = (lo + hi) / 2;
int cmp = git_oid__hashcmp(base + mi * stride, key);
if (!cmp)
return mi;
if (cmp > 0)
hi = mi;
else
lo = mi+1;
}
return -((int)lo)-1;
}
static int pack_entry_find_offset(
off64_t *offset_out,
git_oid *found_oid,

View File

@ -349,8 +349,9 @@ static int queue_objects(git_push *push)
if (git_oid_is_zero(&head->oid))
continue;
/* TODO */
git_revwalk_hide(rw, &head->oid);
if ((error = git_revwalk_hide(rw, &head->oid)) < 0 &&
error != GIT_ENOTFOUND && error != GIT_EINVALIDSPEC && error != GIT_EPEEL)
goto on_error;
}
error = git_packbuilder_insert_walk(push->pb, rw);

View File

@ -2129,6 +2129,9 @@ int git_refdb_backend_fs(
backend = git__calloc(1, sizeof(refdb_fs_backend));
GIT_ERROR_CHECK_ALLOC(backend);
if (git_refdb_init_backend(&backend->parent, GIT_REFDB_BACKEND_VERSION) < 0)
goto fail;
backend->repo = repository;
if (repository->gitdir) {

View File

@ -189,19 +189,25 @@ void git_repository_free(git_repository *repo)
*
* Open a repository object from its path
*/
static bool valid_repository_path(git_buf *repository_path, git_buf *common_path)
static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf *common_path)
{
int error;
*out = false;
/* Check if we have a separate commondir (e.g. we have a
* worktree) */
if (git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
git_buf common_link = GIT_BUF_INIT;
git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE);
git_futils_readbuffer(&common_link, common_link.ptr);
if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 ||
(error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0)
return error;
git_buf_rtrim(&common_link);
if (git_path_is_relative(common_link.ptr)) {
git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr);
if ((error = git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr)) < 0)
return error;
} else {
git_buf_swap(common_path, &common_link);
}
@ -209,24 +215,26 @@ static bool valid_repository_path(git_buf *repository_path, git_buf *common_path
git_buf_dispose(&common_link);
}
else {
git_buf_set(common_path, repository_path->ptr, repository_path->size);
if ((error = git_buf_set(common_path, repository_path->ptr, repository_path->size)) < 0)
return error;
}
/* Make sure the commondir path always has a trailing * slash */
if (git_buf_rfind(common_path, '/') != (ssize_t)common_path->size - 1)
git_buf_putc(common_path, '/');
if ((error = git_buf_putc(common_path, '/')) < 0)
return error;
/* Ensure HEAD file exists */
if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
return false;
return 0;
/* Check files in common dir */
if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
return false;
return 0;
if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false)
return false;
return 0;
return true;
*out = true;
return 0;
}
static git_repository *repository_alloc(void)
@ -441,15 +449,15 @@ static int find_repo(
uint32_t flags,
const char *ceiling_dirs)
{
int error;
git_buf path = GIT_BUF_INIT;
git_buf repo_link = GIT_BUF_INIT;
git_buf common_link = GIT_BUF_INIT;
struct stat st;
dev_t initial_device = 0;
int min_iterations;
bool in_dot_git;
bool in_dot_git, is_valid;
size_t ceiling_offset = 0;
int error;
git_buf_clear(gitdir_path);
@ -475,9 +483,8 @@ static int find_repo(
for (;;) {
if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
if (!in_dot_git) {
error = git_buf_joinpath(&path, path.ptr, DOT_GIT);
if (error < 0)
break;
if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0)
goto out;
}
in_dot_git = !in_dot_git;
}
@ -491,28 +498,33 @@ static int find_repo(
break;
if (S_ISDIR(st.st_mode)) {
if (valid_repository_path(&path, &common_link)) {
git_path_to_dir(&path);
git_buf_set(gitdir_path, path.ptr, path.size);
if ((error = is_valid_repository_path(&is_valid, &path, &common_link)) < 0)
goto out;
if (is_valid) {
if ((error = git_path_to_dir(&path)) < 0 ||
(error = git_buf_set(gitdir_path, path.ptr, path.size)) < 0)
goto out;
if (gitlink_path)
git_buf_attach(gitlink_path,
git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0);
if ((error = git_buf_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
goto out;
if (commondir_path)
git_buf_swap(&common_link, commondir_path);
break;
}
}
else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
error = read_gitfile(&repo_link, path.ptr);
if (error < 0)
break;
if (valid_repository_path(&repo_link, &common_link)) {
} else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
if ((error = read_gitfile(&repo_link, path.ptr)) < 0 ||
(error = is_valid_repository_path(&is_valid, &repo_link, &common_link)) < 0)
goto out;
if (is_valid) {
git_buf_swap(gitdir_path, &repo_link);
if (gitlink_path)
error = git_buf_put(gitlink_path, path.ptr, path.size);
if ((error = git_buf_put(gitlink_path, path.ptr, path.size)) < 0)
goto out;
if (commondir_path)
git_buf_swap(&common_link, commondir_path);
}
@ -523,10 +535,8 @@ static int find_repo(
/* Move up one directory. If we're in_dot_git, we'll search the
* parent itself next. If we're !in_dot_git, we'll search .git
* in the parent directory next (added at the top of the loop). */
if (git_path_dirname_r(&path, path.ptr) < 0) {
error = -1;
break;
}
if ((error = git_path_dirname_r(&path, path.ptr)) < 0)
goto out;
/* Once we've checked the directory (and .git if applicable),
* find the ceiling for a search. */
@ -534,31 +544,28 @@ static int find_repo(
ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
/* Check if we should stop searching here. */
if (min_iterations == 0
&& (path.ptr[ceiling_offset] == 0
|| (flags & GIT_REPOSITORY_OPEN_NO_SEARCH)))
if (min_iterations == 0 &&
(path.ptr[ceiling_offset] == 0 || (flags & GIT_REPOSITORY_OPEN_NO_SEARCH)))
break;
}
if (!error && workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
if (!git_buf_len(gitdir_path))
git_buf_clear(workdir_path);
else {
git_path_dirname_r(workdir_path, path.ptr);
git_path_to_dir(workdir_path);
}
if (git_buf_oom(workdir_path))
return -1;
else if ((error = git_path_dirname_r(workdir_path, path.ptr)) < 0 ||
(error = git_path_to_dir(workdir_path)) < 0)
goto out;
}
/* If we didn't find the repository, and we don't have any other error
* to report, report that. */
if (!git_buf_len(gitdir_path) && !error) {
git_error_set(GIT_ERROR_REPOSITORY,
"could not find repository from '%s'", start_path);
if (!git_buf_len(gitdir_path)) {
git_error_set(GIT_ERROR_REPOSITORY, "could not find repository from '%s'", start_path);
error = GIT_ENOTFOUND;
goto out;
}
out:
git_buf_dispose(&path);
git_buf_dispose(&repo_link);
git_buf_dispose(&common_link);
@ -569,14 +576,16 @@ int git_repository_open_bare(
git_repository **repo_ptr,
const char *bare_path)
{
int error;
git_buf path = GIT_BUF_INIT, common_path = GIT_BUF_INIT;
git_repository *repo = NULL;
bool is_valid;
int error;
if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0)
if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
(error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
return error;
if (!valid_repository_path(&path, &common_path)) {
if (!is_valid) {
git_buf_dispose(&path);
git_buf_dispose(&common_path);
git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path);
@ -2055,6 +2064,7 @@ int git_repository_init_ext(
git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT,
common_path = GIT_BUF_INIT, head_path = GIT_BUF_INIT;
const char *wd;
bool is_valid;
int error;
assert(out && given_repo && opts);
@ -2066,7 +2076,10 @@ int git_repository_init_ext(
wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path);
if (valid_repository_path(&repo_path, &common_path)) {
if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0)
goto out;
if (is_valid) {
if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) {
git_error_set(GIT_ERROR_REPOSITORY,
"attempt to reinitialize '%s'", given_repo);

View File

@ -58,7 +58,7 @@ int git_revwalk__push_commit(git_revwalk *walk, const git_oid *oid, const git_re
return 0;
git_error_set(GIT_ERROR_INVALID, "object is not a committish");
return -1;
return error;
}
if (error < 0)
return error;

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "sha1_lookup.h"
#include <stdio.h>
#include "oid.h"
int sha1_position(const void *table,
size_t stride,
unsigned lo, unsigned hi,
const unsigned char *key)
{
const unsigned char *base = table;
while (lo < hi) {
unsigned mi = (lo + hi) / 2;
int cmp = git_oid__hashcmp(base + mi * stride, key);
if (!cmp)
return mi;
if (cmp > 0)
hi = mi;
else
lo = mi+1;
}
return -((int)lo)-1;
}

View File

@ -1,19 +0,0 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_sha1_lookup_h__
#define INCLUDE_sha1_lookup_h__
#include "common.h"
#include <stdlib.h>
int sha1_position(const void *table,
size_t stride,
unsigned lo, unsigned hi,
const unsigned char *key);
#endif

View File

@ -156,7 +156,7 @@ static void openssl_locking_function(
lock = mode & CRYPTO_LOCK;
if (lock) {
git_mutex_lock(&openssl_locks[n]);
(void)git_mutex_lock(&openssl_locks[n]);
} else {
git_mutex_unlock(&openssl_locks[n]);
}

View File

@ -50,10 +50,10 @@ static int ntlm_set_credentials(http_auth_ntlm_context *ctx, git_credential *_cr
cred = (git_credential_userpass_plaintext *)_cred;
if ((sep = strchr(cred->username, '\\')) != NULL) {
domain = strndup(cred->username, (sep - cred->username));
domain = git__strndup(cred->username, (sep - cred->username));
GIT_ERROR_CHECK_ALLOC(domain);
domainuser = strdup(sep + 1);
domainuser = git__strdup(sep + 1);
GIT_ERROR_CHECK_ALLOC(domainuser);
username = domainuser;

View File

@ -29,7 +29,18 @@ static git_http_auth_scheme auth_schemes[] = {
{ GIT_HTTP_AUTH_BASIC, "Basic", GIT_CREDENTIAL_USERPASS_PLAINTEXT, git_http_auth_basic },
};
#define GIT_READ_BUFFER_SIZE 8192
/*
* Use a 16kb read buffer to match the maximum size of a TLS packet. This
* is critical for compatibility with SecureTransport, which will always do
* a network read on every call, even if it has data buffered to return to
* you. That buffered data may be the _end_ of a keep-alive response, so
* if SecureTransport performs another network read, it will wait until the
* server ultimately times out before it returns that buffered data to you.
* Since SecureTransport only reads a single TLS packet at a time, by
* calling it with a read buffer that is the maximum size of a TLS packet,
* we ensure that it will never buffer.
*/
#define GIT_READ_BUFFER_SIZE (16 * 1024)
typedef struct {
git_net_url url;
@ -585,7 +596,7 @@ static int apply_credentials(
if (auth->connection_affinity)
free_auth_context(server);
} else if (!token.size) {
git_error_set(GIT_ERROR_HTTP, "failed to respond to authentication challange");
git_error_set(GIT_ERROR_HTTP, "failed to respond to authentication challenge");
error = -1;
goto done;
}

View File

@ -33,7 +33,7 @@ typedef int GIT_SOCKET;
# define st_atime_nsec st_atim.tv_nsec
# define st_mtime_nsec st_mtim.tv_nsec
# define st_ctime_nsec st_ctim.tv_nsec
#elif !defined(GIT_USE_STAT_MTIME_NSEC) && defined(GIT_USE_NEC)
#elif !defined(GIT_USE_STAT_MTIME_NSEC) && defined(GIT_USE_NSEC)
# error GIT_USE_NSEC defined but unknown struct stat nanosecond type
#endif

View File

@ -25,6 +25,9 @@
#define path__is_unc(p) \
(((p)[0] == '\\' && (p)[1] == '\\') || ((p)[0] == '/' && (p)[1] == '/'))
#define path__startswith_slash(p) \
((p)[0] == '\\' || (p)[0] == '/')
GIT_INLINE(int) path__cwd(wchar_t *path, int size)
{
int len;
@ -221,7 +224,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src)
goto on_error;
}
/* Absolute paths omitting the drive letter */
else if (src[0] == '\\' || src[0] == '/') {
else if (path__startswith_slash(src)) {
if (path__cwd(dest, MAX_PATH) < 0)
goto on_error;
@ -257,6 +260,30 @@ on_error:
return -1;
}
int git_win32_path_relative_from_utf8(git_win32_path out, const char *src)
{
wchar_t *dest = out, *p;
int len;
/* Handle absolute paths */
if (git_path_is_absolute(src) ||
path__is_nt_namespace(src) ||
path__is_unc(src) ||
path__startswith_slash(src)) {
return git_win32_path_from_utf8(out, src);
}
if ((len = git__utf8_to_16(dest, MAX_PATH, src)) < 0)
return -1;
for (p = dest; p < (dest + len); p++) {
if (*p == L'/')
*p = L'\\';
}
return len;
}
int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src)
{
char *out = dest;

View File

@ -11,7 +11,9 @@
#include "vector.h"
/**
* Create a Win32 path (in UCS-2 format) from a UTF-8 string.
* Create a Win32 path (in UCS-2 format) from a UTF-8 string. If the given
* path is relative, then it will be turned into an absolute path by having
* the current working directory prepended.
*
* @param dest The buffer to receive the wide string.
* @param src The UTF-8 string to convert.
@ -19,6 +21,16 @@
*/
extern int git_win32_path_from_utf8(git_win32_path dest, const char *src);
/**
* Create a Win32 path (in UCS-2 format) from a UTF-8 string. If the given
* path is relative, then it will not be turned into an absolute path.
*
* @param dest The buffer to receive the wide string.
* @param src The UTF-8 string to convert.
* @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
*/
extern int git_win32_path_relative_from_utf8(git_win32_path dest, const char *src);
/**
* Canonicalize a Win32 UCS-2 path so that it is suitable for delivery to the
* Win32 APIs: remove multiple directory separators, squashing to a single one,
@ -26,6 +38,9 @@ extern int git_win32_path_from_utf8(git_win32_path dest, const char *src);
* canonical (always backslashes, never forward slashes) and process any
* directory entries of '.' or '..'.
*
* Note that this is intended to be used on absolute Windows paths, those
* that start with `C:\`, `\\server\share`, `\\?\`, etc.
*
* This processes the buffer in place.
*
* @param path The buffer to process

View File

@ -447,8 +447,7 @@ int p_symlink(const char *target, const char *path)
* relative symlinks, this is not someting we want.
*/
if (git_win32_path_from_utf8(path_w, path) < 0 ||
git__utf8_to_16(target_w, MAX_PATH, target) < 0 ||
git_win32_path_canonicalize(target_w) < 0)
git_win32_path_relative_from_utf8(target_w, target) < 0)
return -1;
dwFlags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;

View File

@ -136,11 +136,11 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
goto out;
}
if ((wt->name = git__strdup(name)) == NULL
|| (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL
|| (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL
|| (parent && (wt->parent_path = git__strdup(parent)) == NULL)
|| (wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) {
if ((wt->name = git__strdup(name)) == NULL ||
(wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL ||
(wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL ||
(parent && (wt->parent_path = git__strdup(parent)) == NULL) ||
(wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) {
error = -1;
goto out;
}
@ -149,7 +149,10 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
goto out;
wt->gitdir_path = git_buf_detach(&gitdir);
wt->locked = !!git_worktree_is_locked(NULL, wt);
if ((error = git_worktree_is_locked(NULL, wt)) < 0)
goto out;
wt->locked = !!error;
error = 0;
*out = wt;
@ -403,20 +406,24 @@ out:
int git_worktree_lock(git_worktree *wt, const char *reason)
{
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
int err;
int error;
assert(wt);
if ((err = git_worktree_is_locked(NULL, wt)) < 0)
if ((error = git_worktree_is_locked(NULL, wt)) < 0)
goto out;
if (error) {
error = GIT_ELOCKED;
goto out;
}
if ((err = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
if ((error = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
goto out;
if (reason)
git_buf_attach_notowned(&buf, reason, strlen(reason));
if ((err = git_futils_writebuffer(&buf, path.ptr, O_CREAT|O_EXCL|O_WRONLY, 0644)) < 0)
if ((error = git_futils_writebuffer(&buf, path.ptr, O_CREAT|O_EXCL|O_WRONLY, 0644)) < 0)
goto out;
wt->locked = 1;
@ -424,16 +431,19 @@ int git_worktree_lock(git_worktree *wt, const char *reason)
out:
git_buf_dispose(&path);
return err;
return error;
}
int git_worktree_unlock(git_worktree *wt)
{
git_buf path = GIT_BUF_INIT;
int error;
assert(wt);
if (!git_worktree_is_locked(NULL, wt))
if ((error = git_worktree_is_locked(NULL, wt)) < 0)
return error;
if (!error)
return 1;
if (git_buf_joinpath(&path, wt->gitdir_path, "locked") < 0)
@ -454,22 +464,25 @@ int git_worktree_unlock(git_worktree *wt)
int git_worktree_is_locked(git_buf *reason, const git_worktree *wt)
{
git_buf path = GIT_BUF_INIT;
int ret;
int error, locked;
assert(wt);
if (reason)
git_buf_clear(reason);
if ((ret = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
if ((error = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
goto out;
locked = git_path_exists(path.ptr);
if (locked && reason &&
(error = git_futils_readbuffer(reason, path.ptr)) < 0)
goto out;
if ((ret = git_path_exists(path.ptr)) && reason)
git_futils_readbuffer(reason, path.ptr);
error = locked;
out:
git_buf_dispose(&path);
return ret;
return error;
}
const char *git_worktree_name(const git_worktree *wt)
@ -502,7 +515,6 @@ int git_worktree_pruneinit_options(git_worktree_prune_options *opts,
int git_worktree_is_prunable(git_worktree *wt,
git_worktree_prune_options *opts)
{
git_buf reason = GIT_BUF_INIT;
git_worktree_prune_options popts = GIT_WORKTREE_PRUNE_OPTIONS_INIT;
GIT_ERROR_CHECK_VERSION(
@ -512,20 +524,24 @@ int git_worktree_is_prunable(git_worktree *wt,
if (opts)
memcpy(&popts, opts, sizeof(popts));
if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0 &&
git_worktree_is_locked(&reason, wt))
{
if (!reason.size)
git_buf_attach_notowned(&reason, "no reason given", 15);
git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr);
git_buf_dispose(&reason);
if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0) {
git_buf reason = GIT_BUF_INIT;
int error;
return 0;
if ((error = git_worktree_is_locked(&reason, wt)) < 0)
return error;
if (error) {
if (!reason.size)
git_buf_attach_notowned(&reason, "no reason given", 15);
git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr);
git_buf_dispose(&reason);
return 0;
}
}
if ((popts.flags & GIT_WORKTREE_PRUNE_VALID) == 0 &&
git_worktree_validate(wt) == 0)
{
git_worktree_validate(wt) == 0) {
git_error_set(GIT_ERROR_WORKTREE, "not pruning valid working tree");
return 0;
}

View File

@ -31,13 +31,13 @@ void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx,
}
if (hunk->final_start_line_number != start_line) {
hunk_message(idx, hunk, "mismatched start line number: expected %d, got %d",
hunk_message(idx, hunk, "mismatched start line number: expected %"PRIuZ", got %"PRIuZ,
start_line, hunk->final_start_line_number);
}
cl_assert_equal_i(hunk->final_start_line_number, start_line);
if (hunk->lines_in_hunk != len) {
hunk_message(idx, hunk, "mismatched line count: expected %d, got %d",
hunk_message(idx, hunk, "mismatched line count: expected %"PRIuZ", got %"PRIuZ,
len, hunk->lines_in_hunk);
}
cl_assert_equal_i(hunk->lines_in_hunk, len);

View File

@ -1,7 +1,7 @@
#include "clar_libgit2.h"
#include "blame.h"
void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...);
void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...) GIT_FORMAT_PRINTF(3, 4);
void check_blame_hunk_index(
git_repository *repo,

View File

@ -17,6 +17,32 @@ void test_blame_buffer__cleanup(void)
git_repository_free(g_repo);
}
void test_blame_buffer__index(void)
{
const git_blame_hunk *hunk;
const char *buffer = "Hello\nWorld!";
/*
* We need to open a different file from the ones used in other tests. Close
* the one opened in test_blame_buffer__initialize() to avoid a leak.
*/
git_blame_free(g_fileblame);
g_fileblame = NULL;
cl_git_pass(git_blame_file(&g_fileblame, g_repo, "file.txt", NULL));
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(2, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 1, 0, "836bc00b", "file.txt");
hunk = git_blame_get_hunk_byline(g_bufferblame, 1);
cl_assert(hunk);
cl_assert_equal_s("lhchavez", hunk->final_signature->name);
check_blame_hunk_index(g_repo, g_bufferblame, 1, 2, 1, 0, "00000000", "file.txt");
hunk = git_blame_get_hunk_byline(g_bufferblame, 2);
cl_assert(hunk);
cl_assert(hunk->final_signature == NULL);
}
void test_blame_buffer__added_line(void)
{
const git_blame_hunk *hunk;

View File

@ -81,7 +81,7 @@ void test_config_global__lock_missing_global_config(void)
git_config_entry *entry;
git_transaction *transaction;
p_unlink("home/.gitconfig"); /* No global config */
(void)p_unlink("home/.gitconfig"); /* No global config */
cl_git_pass(git_config_open_default(&cfg));
cl_git_pass(git_config_lock(&transaction, cfg));

View File

@ -30,5 +30,5 @@ void test_config_new__write_new_config(void)
git_buf_dispose(&buf);
git_config_free(config);
p_unlink(TEST_CONFIG);
cl_must_pass(p_unlink(TEST_CONFIG));
}

View File

@ -190,6 +190,26 @@ void test_core_posix__symlink_resolves_to_correct_type(void)
git_buf_dispose(&contents);
}
void test_core_posix__relative_symlink(void)
{
git_buf contents = GIT_BUF_INIT;
if (!git_path_supports_symlinks(clar_sandbox_path()))
clar__skip();
cl_must_pass(git_futils_mkdir("dir", 0777, 0));
cl_git_mkfile("file", "contents");
cl_git_pass(p_symlink("../file", "dir/link"));
cl_git_pass(git_futils_readbuffer(&contents, "dir/link"));
cl_assert_equal_s(contents.ptr, "contents");
cl_must_pass(p_unlink("file"));
cl_must_pass(p_unlink("dir/link"));
cl_must_pass(p_rmdir("dir"));
git_buf_dispose(&contents);
}
void test_core_posix__symlink_to_file_across_dirs(void)
{
git_buf contents = GIT_BUF_INIT;

View File

@ -524,3 +524,52 @@ void test_diff_tree__diff_configs(void)
cl_assert_equal_i(7, expect.line_adds);
cl_assert_equal_i(15, expect.line_dels);
}
void test_diff_tree__diff_tree_with_empty_dir_entry_succeeds(void)
{
const char *content = "This is a blob\n";
const git_diff_delta *delta;
git_oid empty_tree, invalid_tree, blob;
git_buf patch = GIT_BUF_INIT;
git_treebuilder *builder;
g_repo = cl_git_sandbox_init("empty_standard_repo");
cl_git_pass(git_blob_create_from_buffer(&blob, g_repo, content, strlen(content)));
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
cl_git_pass(git_treebuilder_write(&empty_tree, builder));
cl_git_pass(git_treebuilder_insert(NULL, builder, "empty_tree", &empty_tree, GIT_FILEMODE_TREE));
cl_git_pass(git_treebuilder_insert(NULL, builder, "blob", &blob, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_write(&invalid_tree, builder));
cl_git_pass(git_tree_lookup(&a, g_repo, &empty_tree));
cl_git_pass(git_tree_lookup(&b, g_repo, &invalid_tree));
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, NULL));
cl_git_pass(git_diff_foreach(diff,
diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));
cl_assert_equal_i(1, expect.files);
cl_assert_equal_i(0, expect.file_status[GIT_DELTA_MODIFIED]);
cl_assert_equal_i(1, expect.hunks);
cl_assert_equal_i(1, expect.lines);
cl_assert_equal_i(0, expect.line_ctxt);
cl_assert_equal_i(1, expect.line_adds);
cl_assert_equal_i(0, expect.line_dels);
cl_git_pass(git_diff_to_buf(&patch, diff, GIT_DIFF_FORMAT_PATCH));
cl_assert_equal_s(patch.ptr,
"diff --git a/blob b/blob\n"
"new file mode 100644\n"
"index 0000000..bbf2e80\n"
"--- /dev/null\n"
"+++ b/blob\n"
"@@ -0,0 +1 @@\n"
"+This is a blob\n");
cl_assert_equal_i(git_diff_num_deltas(diff), 1);
delta = git_diff_get_delta(diff, 0);
cl_assert_equal_s(delta->new_file.path, "blob");
git_treebuilder_free(builder);
git_buf_dispose(&patch);
}

View File

@ -2160,3 +2160,46 @@ void test_diff_workdir__symlink_changed_on_non_symlink_platform(void)
git_tree_free(tree);
git_vector_free(&pathlist);
}
void test_diff_workdir__order(void)
{
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_buf patch = GIT_BUF_INIT;
git_oid tree_oid, blob_oid;
git_treebuilder *builder;
git_tree *tree;
git_diff *diff;
g_repo = cl_git_sandbox_init("empty_standard_repo");
/* Build tree with a single file "abc.txt" */
cl_git_pass(git_blob_create_from_buffer(&blob_oid, g_repo, "foo\n", 4));
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
cl_git_pass(git_treebuilder_insert(NULL, builder, "abc.txt", &blob_oid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_write(&tree_oid, builder));
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
/* Create a directory that sorts before and one that sorts after "abc.txt" */
cl_git_mkfile("empty_standard_repo/abc.txt", "bar\n");
cl_must_pass(p_mkdir("empty_standard_repo/abb", 0777));
cl_must_pass(p_mkdir("empty_standard_repo/abd", 0777));
opts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
cl_assert_equal_i(1, git_diff_num_deltas(diff));
cl_git_pass(git_diff_to_buf(&patch, diff, GIT_DIFF_FORMAT_PATCH));
cl_assert_equal_s(patch.ptr,
"diff --git a/abc.txt b/abc.txt\n"
"index 257cc56..5716ca5 100644\n"
"--- a/abc.txt\n"
"+++ b/abc.txt\n"
"@@ -1 +1 @@\n"
"-foo\n"
"+bar\n");
git_treebuilder_free(builder);
git_buf_dispose(&patch);
git_diff_free(diff);
git_tree_free(tree);
}

View File

@ -255,7 +255,7 @@ void test_ignore_path__globs_without_star(void)
void test_ignore_path__skip_gitignore_directory(void)
{
cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder");
p_unlink("attr/.gitignore");
cl_must_pass(p_unlink("attr/.gitignore"));
cl_assert(!git_path_exists("attr/.gitignore"));
p_mkdir("attr/.gitignore", 0777);
cl_git_mkfile("attr/.gitignore/garbage.txt", "new_file\n");
@ -268,12 +268,11 @@ void test_ignore_path__skip_gitignore_directory(void)
void test_ignore_path__subdirectory_gitignore(void)
{
p_unlink("attr/.gitignore");
cl_must_pass(p_unlink("attr/.gitignore"));
cl_assert(!git_path_exists("attr/.gitignore"));
cl_git_mkfile(
"attr/.gitignore",
"file1\n");
p_mkdir("attr/dir", 0777);
cl_git_mkfile(
"attr/dir/.gitignore",
"file2/\n");

View File

@ -54,7 +54,7 @@ static bool should_expect_nsecs(void)
expect = try_create_file_with_nsec_timestamp(nsec_path.ptr);
p_unlink(nsec_path.ptr);
cl_must_pass(p_unlink(nsec_path.ptr));
git_buf_dispose(&nsec_path);

View File

@ -566,8 +566,7 @@ void test_index_tests__cannot_add_invalid_filename(void)
{
git_repository *repo;
p_mkdir("invalid", 0700);
cl_must_pass(p_mkdir("invalid", 0700));
cl_git_pass(git_repository_init(&repo, "./invalid", 0));
cl_must_pass(p_mkdir("./invalid/subdir", 0777));

View File

@ -153,7 +153,7 @@ static void assert_invalid_rtransform(const char *refspec, const char *name)
git_refspec spec;
git_buf buf = GIT_BUF_INIT;
git_refspec__parse(&spec, refspec, true);
cl_git_pass(git_refspec__parse(&spec, refspec, true));
cl_git_fail(git_refspec_rtransform(&buf, &spec, name));
git_buf_dispose(&buf);

View File

@ -400,15 +400,11 @@ void test_notes_notes__can_read_a_note_from_a_commit(void)
git_note *note;
cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
cl_git_pass(git_note_commit_create(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1));
git_commit_lookup(&notes_commit, _repo, &notes_commit_oid);
cl_git_pass(git_commit_lookup(&notes_commit, _repo, &notes_commit_oid));
cl_assert(notes_commit);
cl_git_pass(git_note_commit_read(&note, _repo, notes_commit, &oid));
cl_assert_equal_s(git_note_message(note), "I decorate 4a20\n");
git_commit_free(notes_commit);
@ -457,7 +453,7 @@ void test_notes_notes__can_insert_a_note_in_an_existing_fanout(void)
git_note *_note;
cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
for (i = 0; i < MESSAGES_COUNT; i++) {
cl_git_pass(git_note_create(&note_oid, _repo, "refs/notes/fanout", _sig, _sig, &target_oid, messages[i], 0));
cl_git_pass(git_note_read(&_note, _repo, "refs/notes/fanout", &target_oid));
@ -511,7 +507,7 @@ void test_notes_notes__can_remove_a_note_from_commit(void)
cl_git_pass(git_note_commit_create(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0));
git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_oid);
cl_git_pass(git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_oid));
cl_assert(existing_notes_commit);
@ -547,7 +543,7 @@ void test_notes_notes__removing_a_note_which_doesnt_exists_returns_ENOTFOUND(voi
cl_git_pass(git_oid_fromstr(&target_oid, "8496071c1b46c854b31185ea97743be6a8774479"));
cl_git_pass(git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid));
error = git_note_remove(_repo, "refs/notes/fanout", _sig, _sig, &target_oid);
cl_git_fail(error);
cl_assert_equal_i(GIT_ENOTFOUND, error);

View File

@ -21,6 +21,21 @@ void test_utf8_to_utf16(const char *utf8_in, const wchar_t *utf16_expected)
#endif
}
void test_utf8_to_utf16_relative(const char* utf8_in, const wchar_t* utf16_expected)
{
#ifdef GIT_WIN32
git_win32_path path_utf16;
int path_utf16len;
cl_assert((path_utf16len = git_win32_path_relative_from_utf8(path_utf16, utf8_in)) >= 0);
cl_assert_equal_wcs(utf16_expected, path_utf16);
cl_assert_equal_i(wcslen(utf16_expected), path_utf16len);
#else
GIT_UNUSED(utf8_in);
GIT_UNUSED(utf16_expected);
#endif
}
void test_path_win32__utf8_to_utf16(void)
{
#ifdef GIT_WIN32
@ -129,6 +144,31 @@ void test_path_win32__absolute_from_relative(void)
#endif
}
void test_path_win32__keeps_relative(void)
{
#ifdef GIT_WIN32
/* Relative paths stay relative */
test_utf8_to_utf16_relative("Foo", L"Foo");
test_utf8_to_utf16_relative("..\\..\\Foo", L"..\\..\\Foo");
test_utf8_to_utf16_relative("Foo\\..", L"Foo\\..");
test_utf8_to_utf16_relative("Foo\\..\\..", L"Foo\\..\\..");
test_utf8_to_utf16_relative("Foo\\Bar", L"Foo\\Bar");
test_utf8_to_utf16_relative("Foo\\..\\Bar", L"Foo\\..\\Bar");
test_utf8_to_utf16_relative("../../Foo", L"..\\..\\Foo");
test_utf8_to_utf16_relative("Foo/..", L"Foo\\..");
test_utf8_to_utf16_relative("Foo/../..", L"Foo\\..\\..");
test_utf8_to_utf16_relative("Foo/Bar", L"Foo\\Bar");
test_utf8_to_utf16_relative("Foo/../Bar", L"Foo\\..\\Bar");
test_utf8_to_utf16_relative("Foo/../Bar/", L"Foo\\..\\Bar\\");
test_utf8_to_utf16_relative("", L"");
/* Absolute paths are canonicalized */
test_utf8_to_utf16_relative("\\Foo", L"\\\\?\\C:\\Foo");
test_utf8_to_utf16_relative("/Foo/Bar/", L"\\\\?\\C:\\Foo\\Bar");
test_utf8_to_utf16_relative("\\\\server\\c$\\unc\\path", L"\\\\?\\UNC\\server\\c$\\unc\\path");
#endif
}
#ifdef GIT_WIN32
static void test_canonicalize(const wchar_t *in, const wchar_t *expected)
{
@ -203,16 +243,6 @@ void test_path_win32__canonicalize(void)
test_canonicalize(L"C:/Foo/Bar", L"C:\\Foo\\Bar");
test_canonicalize(L"C:/", L"C:\\");
test_canonicalize(L"Foo\\\\Bar\\\\Asdf\\\\", L"Foo\\Bar\\Asdf");
test_canonicalize(L"Foo\\\\Bar\\\\..\\\\Asdf\\", L"Foo\\Asdf");
test_canonicalize(L"Foo\\\\Bar\\\\.\\\\Asdf\\", L"Foo\\Bar\\Asdf");
test_canonicalize(L"Foo\\\\..\\Bar\\\\.\\\\Asdf\\", L"Bar\\Asdf");
test_canonicalize(L"\\", L"");
test_canonicalize(L"", L"");
test_canonicalize(L"Foo\\..\\..\\..\\..", L"");
test_canonicalize(L"..\\..\\..\\..", L"");
test_canonicalize(L"\\..\\..\\..\\..", L"");
test_canonicalize(L"\\\\?\\C:\\Foo\\Bar", L"\\\\?\\C:\\Foo\\Bar");
test_canonicalize(L"\\\\?\\C:\\Foo\\Bar\\", L"\\\\?\\C:\\Foo\\Bar");
test_canonicalize(L"\\\\?\\C:\\\\Foo\\.\\Bar\\\\..\\", L"\\\\?\\C:\\Foo");