summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig4
-rw-r--r--.gitignore30
-rw-r--r--CMakeLists.txt6
-rw-r--r--README.md11
-rw-r--r--azure-pipelines.yml42
-rwxr-xr-xazure-pipelines/coverity.sh4
-rw-r--r--azure-pipelines/coverity.yml2
-rw-r--r--azure-pipelines/docker.yml6
-rw-r--r--azure-pipelines/docker/bionic12
-rw-r--r--azure-pipelines/docker/docurium7
-rw-r--r--azure-pipelines/docker/entrypoint.sh4
-rw-r--r--azure-pipelines/docker/xenial12
-rw-r--r--azure-pipelines/nightly.yml40
-rwxr-xr-xazure-pipelines/setup-linux.sh27
-rwxr-xr-xazure-pipelines/test.sh4
-rw-r--r--cmake/Modules/PkgBuildConfig.cmake41
-rw-r--r--cmake/Modules/SanitizeBool.cmake20
-rw-r--r--cmake/Modules/SelectGSSAPI.cmake41
-rw-r--r--cmake/Modules/SelectHTTPSBackend.cmake56
-rw-r--r--cmake/Modules/SelectHashes.cmake49
-rw-r--r--deps/ntlmclient/CMakeLists.txt12
-rw-r--r--deps/ntlmclient/compat.h22
-rw-r--r--docs/changelog.md411
-rw-r--r--docs/fuzzing.md13
-rw-r--r--include/git2/deprecated.h7
-rw-r--r--include/git2/repository.h9
-rw-r--r--include/git2/sys/refdb_backend.h111
-rw-r--r--include/git2/version.h8
-rwxr-xr-xscript/release.py171
-rw-r--r--src/CMakeLists.txt33
-rw-r--r--src/blame.c2
-rw-r--r--src/cache.c12
-rw-r--r--src/diff_print.c14
-rw-r--r--src/indexer.c6
-rw-r--r--src/notes.c9
-rw-r--r--src/odb_pack.c1
-rw-r--r--src/pack-objects.c4
-rw-r--r--src/pack.c22
-rw-r--r--src/patch_parse.c1
-rw-r--r--src/push.c5
-rw-r--r--src/refdb_fs.c5
-rw-r--r--src/refdb_fs.h19
-rw-r--r--src/repository.c113
-rw-r--r--src/revwalk.c2
-rw-r--r--src/sha1_lookup.c35
-rw-r--r--src/sha1_lookup.h19
-rw-r--r--src/streams/openssl.c76
-rw-r--r--src/transports/auth_ntlm.c4
-rw-r--r--src/transports/httpclient.c15
-rw-r--r--src/unix/posix.h2
-rw-r--r--src/win32/path_w32.c29
-rw-r--r--src/win32/path_w32.h17
-rw-r--r--src/win32/posix_w32.c3
-rw-r--r--src/worktree.c72
-rw-r--r--tests/blame/blame_helpers.c4
-rw-r--r--tests/blame/blame_helpers.h2
-rw-r--r--tests/blame/buffer.c26
-rw-r--r--tests/config/global.c2
-rw-r--r--tests/config/new.c2
-rw-r--r--tests/core/posix.c20
-rw-r--r--tests/diff/tree.c49
-rw-r--r--tests/diff/workdir.c43
-rw-r--r--tests/ignore/path.c5
-rw-r--r--tests/index/nsec.c2
-rw-r--r--tests/index/tests.c3
-rw-r--r--tests/network/refspecs.c2
-rw-r--r--tests/notes/notes.c12
-rw-r--r--tests/object/cache.c8
-rw-r--r--tests/patch/patch_common.h8
-rw-r--r--tests/patch/print.c6
-rw-r--r--tests/path/win32.c50
-rw-r--r--tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e3
-rw-r--r--tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f1
-rw-r--r--tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3bin0 -> 28 bytes
-rw-r--r--tests/resources/blametest.git/refs/heads/master2
75 files changed, 1407 insertions, 545 deletions
diff --git a/.editorconfig b/.editorconfig
index 34c5e9234..2230fd860 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,3 +15,7 @@ indent_size = 2
indent_style = space
indent_size = 4
trim_trailing_whitespace = false
+
+[*.py]
+indent_style = space
+indent_size = 4
diff --git a/.gitignore b/.gitignore
index dec3dca06..b38b7e16e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,37 +1,7 @@
-/tests/clar.suite
-/tests/clar.suite.rule
-/tests/.clarcache
-/apidocs
-/trash-*.exe
-/libgit2.pc
-/config.mak
-*.o
-*.a
-*.exe
-*.gcda
-*.gcno
-*.gcov
-.lock-wafbuild
-.waf*
build/
-build-amiga/
-tests/tmp/
-msvc/Debug/
-msvc/Release/
-*.sln
-*.suo
-*.vc*proj*
-*.sdf
-*.opensdf
-*.aps
-*.cmake
-!cmake/Modules/*.cmake
.DS_Store
*~
.*.swp
tags
-mkmf.log
-*.profdata
-*.profraw
CMakeSettings.json
.vs
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8765a97b5..826415893 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,7 @@ INCLUDE(AddCFlagIfSupported)
INCLUDE(FindPkgLibraries)
INCLUDE(FindThreads)
INCLUDE(FindStatNsec)
+INCLUDE(GNUInstallDirs)
INCLUDE(IdeSplitSources)
INCLUDE(FeatureSummary)
INCLUDE(EnableWarnings)
@@ -58,7 +59,6 @@ OPTION(USE_SHA1 "Enable SHA1. Can be set to CollisionDetection(ON)/HTTPS/Gene
OPTION(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF)
OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF)
OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF)
-OPTION(VALGRIND "Configure build for valgrind" OFF)
OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib" OFF)
@@ -111,8 +111,8 @@ STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_V
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}")
SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
-FILE(STRINGS "${libgit2_SOURCE_DIR}/include/git2/version.h" GIT2_HEADER_SOVERSION REGEX "^#define LIBGIT2_SOVERSION [0-9]+$")
-STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION ([0-9]+)$" "\\1" LIBGIT2_SOVERSION "${GIT2_HEADER_SOVERSION}")
+FILE(STRINGS "${libgit2_SOURCE_DIR}/include/git2/version.h" GIT2_HEADER_SOVERSION REGEX "^#define LIBGIT2_SOVERSION \"([0-9.]+)\"$")
+STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION \"([0-9.]+)\"$" "\\1" LIBGIT2_SOVERSION "${GIT2_HEADER_SOVERSION}")
IF (DEPRECATE_HARD)
ADD_DEFINITIONS(-DGIT_DEPRECATE_HARD)
diff --git a/README.md b/README.md
index 9dafffec0..516077a5f 100644
--- a/README.md
+++ b/README.md
@@ -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) |
+| **v1.0 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v1.0)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v1.0) |
| **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
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 2b593dd2c..20335b33a 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -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:
@@ -19,13 +19,13 @@ jobs:
environmentVariables: |
CC=gcc
CMAKE_GENERATOR=Ninja
- CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DVALGRIND=on -DUSE_GSSAPI=ON
+ CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }}
- 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:
@@ -35,13 +35,13 @@ jobs:
environmentVariables: |
CC=gcc
CMAKE_GENERATOR=Ninja
- CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DVALGRIND=on -DUSE_GSSAPI=ON
+ CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }}
- 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:
@@ -51,13 +51,13 @@ jobs:
environmentVariables: |
CC=clang
CMAKE_GENERATOR=Ninja
- CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DVALGRIND=on -DUSE_GSSAPI=ON
+ CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }}
- 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:
@@ -67,13 +67,13 @@ jobs:
environmentVariables: |
CC=clang
CMAKE_GENERATOR=Ninja
- CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DVALGRIND=on -DUSE_GSSAPI=ON
+ CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
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
diff --git a/azure-pipelines/coverity.sh b/azure-pipelines/coverity.sh
index 14faadc49..c68b6f8cc 100755
--- a/azure-pipelines/coverity.sh
+++ b/azure-pipelines/coverity.sh
@@ -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 \
diff --git a/azure-pipelines/coverity.yml b/azure-pipelines/coverity.yml
index 10450af5d..a8747db73 100644
--- a/azure-pipelines/coverity.yml
+++ b/azure-pipelines/coverity.yml
@@ -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
diff --git a/azure-pipelines/docker.yml b/azure-pipelines/docker.yml
index 0e1988c8a..0f0885770 100644
--- a/azure-pipelines/docker.yml
+++ b/azure-pipelines/docker.yml
@@ -13,9 +13,9 @@ steps:
if [ -f /tmp/dockercache/${{parameters.docker.image}}.tar ]; then docker load < /tmp/dockercache/${{parameters.docker.image}}.tar; fi
displayName: 'Load Docker cache'
- script: |
- cd $(Build.SourcesDirectory)/azure-pipelines/docker
- docker build -t libgit2/${{parameters.docker.image}} --build-arg BASE=${{parameters.docker.base}} -f ${{parameters.docker.image}} .
- if [ ! -d /tmp/dockercache ]; then mkdir /tmp/dockercache; fi
+ cd $(Build.SourcesDirectory)/azure-pipelines/docker &&
+ docker build -t libgit2/${{parameters.docker.image}} --build-arg BASE=${{parameters.docker.base}} -f ${{parameters.docker.image}} . &&
+ if [ ! -d /tmp/dockercache ]; then mkdir /tmp/dockercache; fi &&
docker save libgit2/${{parameters.docker.image}} $(docker history -q libgit2/${{parameters.docker.image}} | grep -v '<missing>') > /tmp/dockercache/${{parameters.docker.image}}.tar
displayName: 'Build Docker image'
- task: docker@0
diff --git a/azure-pipelines/docker/bionic b/azure-pipelines/docker/bionic
index 648bda704..65a14063a 100644
--- a/azure-pipelines/docker/bionic
+++ b/azure-pipelines/docker/bionic
@@ -1,13 +1,12 @@
ARG BASE
-FROM $BASE
+FROM $BASE AS apt
RUN apt-get update && \
- apt-get install -y --no-install-recommends \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
clang \
cmake \
curl \
gcc \
git \
- gosu \
libcurl4-openssl-dev \
libpcre3-dev \
libssh2-1-dev \
@@ -19,13 +18,14 @@ RUN apt-get update && \
openssl \
pkgconf \
python \
+ sudo \
valgrind \
&& \
rm -rf /var/lib/apt/lists/*
-RUN mkdir /var/run/sshd
+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 && \
@@ -34,7 +34,9 @@ RUN cd /tmp && \
cd .. && \
rm -rf mbedtls-2.16.2
+FROM mbedtls AS configure
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod a+x /usr/local/bin/entrypoint.sh
+RUN mkdir /var/run/sshd
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
diff --git a/azure-pipelines/docker/docurium b/azure-pipelines/docker/docurium
index 15d10a71e..54a4202b6 100644
--- a/azure-pipelines/docker/docurium
+++ b/azure-pipelines/docker/docurium
@@ -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
diff --git a/azure-pipelines/docker/entrypoint.sh b/azure-pipelines/docker/entrypoint.sh
index 38eedf02b..8d96e3acd 100644
--- a/azure-pipelines/docker/entrypoint.sh
+++ b/azure-pipelines/docker/entrypoint.sh
@@ -1,4 +1,4 @@
#!/bin/bash -e
useradd --shell /bin/bash libgit2
-chown -R $(id -u libgit2) /home/libgit2
-exec gosu libgit2 "$@"
+chown --recursive libgit2:libgit2 /home/libgit2
+exec sudo --preserve-env --set-home --user=libgit2 "$@"
diff --git a/azure-pipelines/docker/xenial b/azure-pipelines/docker/xenial
index cb5d4919a..bfb96d9db 100644
--- a/azure-pipelines/docker/xenial
+++ b/azure-pipelines/docker/xenial
@@ -8,7 +8,6 @@ RUN apt-get update && \
curl \
gcc \
git \
- gosu \
krb5-user \
libcurl4-gnutls-dev \
libgcrypt20-dev \
@@ -23,11 +22,14 @@ RUN apt-get update && \
openssl \
pkgconf \
python \
- valgrind
+ sudo \
+ valgrind \
+ && \
+ rm -rf /var/lib/apt/lists/*
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 && \
@@ -38,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 . && \
@@ -48,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 && \
diff --git a/azure-pipelines/nightly.yml b/azure-pipelines/nightly.yml
index a193747b5..a75a9cc24 100644
--- a/azure-pipelines/nightly.yml
+++ b/azure-pipelines/nightly.yml
@@ -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:
diff --git a/azure-pipelines/setup-linux.sh b/azure-pipelines/setup-linux.sh
deleted file mode 100755
index c5ecb550b..000000000
--- a/azure-pipelines/setup-linux.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-set -e
-set -x
-
-TMPDIR=${TMPDIR:-/tmp}
-
-if [ -z "$SKIP_APT" ]; then
- apt-get update
- apt-get -y install build-essential pkg-config clang cmake openssl libssl-dev libssh2-1-dev libcurl4-gnutls-dev openssh-server
-fi
-
-mkdir -p /var/run/sshd
-
-if [ "$MBEDTLS" ]; then
- MBEDTLS_DIR=${MBEDTLS_DIR:-$(mktemp -d ${TMPDIR}/mbedtls.XXXXXXXX)}
-
- git clone --depth 10 --single-branch --branch mbedtls-2.6.1 https://github.com/ARMmbed/mbedtls.git ${MBEDTLS_DIR}
- cd ${MBEDTLS_DIR}
-
- CFLAGS=-fPIC cmake -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DUSE_STATIC_MBEDTLS_LIBRARY=ON .
- cmake --build .
-
- if [ -z "$SKIP_MBEDTLS_INSTALL" ]; then
- make install
- fi
-fi
diff --git a/azure-pipelines/test.sh b/azure-pipelines/test.sh
index 96832d64c..2b43ba198 100755
--- a/azure-pipelines/test.sh
+++ b/azure-pipelines/test.sh
@@ -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..."
diff --git a/cmake/Modules/PkgBuildConfig.cmake b/cmake/Modules/PkgBuildConfig.cmake
index 1c0079eb0..54c5e294c 100644
--- a/cmake/Modules/PkgBuildConfig.cmake
+++ b/cmake/Modules/PkgBuildConfig.cmake
@@ -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()
diff --git a/cmake/Modules/SanitizeBool.cmake b/cmake/Modules/SanitizeBool.cmake
new file mode 100644
index 000000000..b5b99a690
--- /dev/null
+++ b/cmake/Modules/SanitizeBool.cmake
@@ -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()
diff --git a/cmake/Modules/SelectGSSAPI.cmake b/cmake/Modules/SelectGSSAPI.cmake
index 857c449e7..0a42eeefd 100644
--- a/cmake/Modules/SelectGSSAPI.cmake
+++ b/cmake/Modules/SelectGSSAPI.cmake
@@ -1,32 +1,27 @@
-# Select the backend to use
+INCLUDE(SanitizeBool)
# We try to find any packages our backends might use
-
FIND_PACKAGE(GSSAPI)
IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
INCLUDE(FindGSSFramework)
ENDIF()
-# Auto-select GSS backend
-IF (USE_GSSAPI STREQUAL ON)
- IF (GSSFRAMEWORK_FOUND)
- SET(GSS_BACKEND "GSS.framework")
- ELSEIF(GSSAPI_FOUND)
- SET(GSS_BACKEND "gssapi")
- ELSE()
- MESSAGE(FATAL_ERROR "Unable to autodetect a usable GSS backend."
- "Please pass the backend name explicitly (-DUSE_GSS=backend)")
+IF(USE_GSSAPI)
+ # Auto-select GSS backend
+ SanitizeBool(USE_GSSAPI)
+ IF (USE_GSSAPI STREQUAL ON)
+ IF (GSSFRAMEWORK_FOUND)
+ SET(USE_GSSAPI "GSS.framework")
+ ELSEIF(GSSAPI_FOUND)
+ SET(USE_GSSAPI "gssapi")
+ ELSE()
+ MESSAGE(FATAL_ERROR "Unable to autodetect a usable GSS backend."
+ "Please pass the backend name explicitly (-DUSE_GSS=backend)")
+ ENDIF()
ENDIF()
-ELSEIF(USE_GSSAPI)
- # Backend was explicitly set
- SET(GSS_BACKEND ${USE_GSSAPI})
-ELSE()
- SET(GSS_BACKEND NO)
-ENDIF()
-IF(GSS_BACKEND)
# Check that we can find what's required for the selected backend
- IF (GSS_BACKEND STREQUAL "GSS.framework")
+ IF (USE_GSSAPI STREQUAL "GSS.framework")
IF (NOT GSSFRAMEWORK_FOUND)
MESSAGE(FATAL_ERROR "Asked for GSS.framework backend, but it wasn't found")
ENDIF()
@@ -34,8 +29,8 @@ IF(GSS_BACKEND)
LIST(APPEND LIBGIT2_LIBS ${GSSFRAMEWORK_LIBRARIES})
SET(GIT_GSSFRAMEWORK 1)
- ADD_FEATURE_INFO(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${GSS_BACKEND})")
- ELSEIF (GSS_BACKEND STREQUAL "gssapi")
+ ADD_FEATURE_INFO(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${USE_GSSAPI})")
+ ELSEIF (USE_GSSAPI STREQUAL "gssapi")
IF (NOT GSSAPI_FOUND)
MESSAGE(FATAL_ERROR "Asked for gssapi GSS backend, but it wasn't found")
ENDIF()
@@ -43,9 +38,9 @@ IF(GSS_BACKEND)
LIST(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES})
SET(GIT_GSSAPI 1)
- ADD_FEATURE_INFO(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${GSS_BACKEND})")
+ ADD_FEATURE_INFO(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${USE_GSSAPI})")
ELSE()
- MESSAGE(FATAL_ERROR "Asked for backend ${GSS_BACKEND} but it wasn't found")
+ MESSAGE(FATAL_ERROR "Asked for backend ${USE_GSSAPI} but it wasn't found")
ENDIF()
ELSE()
SET(GIT_GSSAPI 0)
diff --git a/cmake/Modules/SelectHTTPSBackend.cmake b/cmake/Modules/SelectHTTPSBackend.cmake
index c7f6b8f1d..afbeac424 100644
--- a/cmake/Modules/SelectHTTPSBackend.cmake
+++ b/cmake/Modules/SelectHTTPSBackend.cmake
@@ -1,4 +1,4 @@
-# Select the backend to use
+INCLUDE(SanitizeBool)
# We try to find any packages our backends might use
FIND_PACKAGE(OpenSSL)
@@ -8,35 +8,31 @@ IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PACKAGE(CoreFoundation)
ENDIF()
-# Auto-select TLS backend
-IF (USE_HTTPS STREQUAL ON)
- IF (SECURITY_FOUND)
- IF (SECURITY_HAS_SSLCREATECONTEXT)
- SET(HTTPS_BACKEND "SecureTransport")
+IF(USE_HTTPS)
+ # Auto-select TLS backend
+ SanitizeBool(USE_HTTPS)
+ IF (USE_HTTPS STREQUAL ON)
+ IF (SECURITY_FOUND)
+ IF (SECURITY_HAS_SSLCREATECONTEXT)
+ SET(USE_HTTPS "SecureTransport")
+ ELSE()
+ MESSAGE(STATUS "Security framework is too old, falling back to OpenSSL")
+ SET(USE_HTTPS "OpenSSL")
+ ENDIF()
+ ELSEIF (WINHTTP)
+ SET(USE_HTTPS "WinHTTP")
+ ELSEIF(OPENSSL_FOUND)
+ SET(USE_HTTPS "OpenSSL")
+ ELSEIF(MBEDTLS_FOUND)
+ SET(USE_HTTPS "mbedTLS")
ELSE()
- MESSAGE(STATUS "Security framework is too old, falling back to OpenSSL")
- SET(HTTPS_BACKEND "OpenSSL")
+ MESSAGE(FATAL_ERROR "Unable to autodetect a usable HTTPS backend."
+ "Please pass the backend name explicitly (-DUSE_HTTPS=backend)")
ENDIF()
- ELSEIF (WINHTTP)
- SET(HTTPS_BACKEND "WinHTTP")
- ELSEIF(OPENSSL_FOUND)
- SET(HTTPS_BACKEND "OpenSSL")
- ELSEIF(MBEDTLS_FOUND)
- SET(HTTPS_BACKEND "mbedTLS")
- ELSE()
- MESSAGE(FATAL_ERROR "Unable to autodetect a usable HTTPS backend."
- "Please pass the backend name explicitly (-DUSE_HTTPS=backend)")
ENDIF()
-ELSEIF(USE_HTTPS)
- # HTTPS backend was explicitly set
- SET(HTTPS_BACKEND ${USE_HTTPS})
-ELSE()
- SET(HTTPS_BACKEND NO)
-ENDIF()
-IF(HTTPS_BACKEND)
# Check that we can find what's required for the selected backend
- IF (HTTPS_BACKEND STREQUAL "SecureTransport")
+ IF (USE_HTTPS STREQUAL "SecureTransport")
IF (NOT COREFOUNDATION_FOUND)
MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, CoreFoundation.framework not found")
ENDIF()
@@ -51,7 +47,7 @@ IF(HTTPS_BACKEND)
LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${SECURITY_INCLUDE_DIR})
LIST(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS})
LIST(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS})
- ELSEIF (HTTPS_BACKEND STREQUAL "OpenSSL")
+ ELSEIF (USE_HTTPS STREQUAL "OpenSSL")
IF (NOT OPENSSL_FOUND)
MESSAGE(FATAL_ERROR "Asked for OpenSSL TLS backend, but it wasn't found")
ENDIF()
@@ -61,7 +57,7 @@ IF(HTTPS_BACKEND)
LIST(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS})
LIST(APPEND LIBGIT2_PC_REQUIRES "openssl")
- ELSEIF(HTTPS_BACKEND STREQUAL "mbedTLS")
+ ELSEIF(USE_HTTPS STREQUAL "mbedTLS")
IF (NOT MBEDTLS_FOUND)
MESSAGE(FATAL_ERROR "Asked for mbedTLS backend, but it wasn't found")
ENDIF()
@@ -110,14 +106,14 @@ IF(HTTPS_BACKEND)
# https://github.com/ARMmbed/mbedtls/issues/228
# For now, pass its link flags as our own
LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES})
- ELSEIF (HTTPS_BACKEND STREQUAL "WinHTTP")
+ ELSEIF (USE_HTTPS STREQUAL "WinHTTP")
# WinHTTP setup was handled in the WinHTTP-specific block above
ELSE()
- MESSAGE(FATAL_ERROR "Asked for backend ${HTTPS_BACKEND} but it wasn't found")
+ MESSAGE(FATAL_ERROR "Asked for backend ${USE_HTTPS} but it wasn't found")
ENDIF()
SET(GIT_HTTPS 1)
- ADD_FEATURE_INFO(HTTPS GIT_HTTPS "using ${HTTPS_BACKEND}")
+ ADD_FEATURE_INFO(HTTPS GIT_HTTPS "using ${USE_HTTPS}")
ELSE()
SET(GIT_HTTPS 0)
ADD_FEATURE_INFO(HTTPS NO "")
diff --git a/cmake/Modules/SelectHashes.cmake b/cmake/Modules/SelectHashes.cmake
index ce28ac23c..27059db6f 100644
--- a/cmake/Modules/SelectHashes.cmake
+++ b/cmake/Modules/SelectHashes.cmake
@@ -1,38 +1,32 @@
# Select a hash backend
+INCLUDE(SanitizeBool)
+
# USE_SHA1=CollisionDetection(ON)/HTTPS/Generic/OFF
-IF(USE_SHA1 STREQUAL ON OR USE_SHA1 STREQUAL "CollisionDetection")
- SET(SHA1_BACKEND "CollisionDetection")
+SanitizeBool(USE_SHA1)
+IF(USE_SHA1 STREQUAL ON)
+ SET(USE_SHA1 "CollisionDetection")
ELSEIF(USE_SHA1 STREQUAL "HTTPS")
- message(STATUS "Checking HTTPS backend… ${HTTPS_BACKEND}")
- IF(HTTPS_BACKEND STREQUAL "SecureTransport")
- SET(SHA1_BACKEND "CommonCrypto")
- ELSEIF(HTTPS_BACKEND STREQUAL "WinHTTP")
- SET(SHA1_BACKEND "Win32")
- ELSEIF(HTTPS_BACKEND)
- SET(SHA1_BACKEND ${HTTPS_BACKEND})
+ IF(USE_HTTPS STREQUAL "SecureTransport")
+ SET(USE_SHA1 "CommonCrypto")
+ ELSEIF(USE_HTTPS STREQUAL "WinHTTP")
+ SET(USE_SHA1 "Win32")
+ ELSEIF(USE_HTTPS)
+ SET(USE_SHA1 ${USE_HTTPS})
ELSE()
+ SET(USE_SHA1 "CollisionDetection")
ENDIF()
- IF(NOT HTTPS_BACKEND)
- SET(SHA1_BACKEND "CollisionDetection")
- ENDIF()
- message(STATUS "Using SHA1 backend ${SHA1_BACKEND}")
-ELSEIF(USE_SHA1 STREQUAL "Generic")
- SET(SHA1_BACKEND "Generic")
-# ELSEIF(NOT USE_SHA1)
-ELSE()
- MESSAGE(FATAL_ERROR "Invalid value for USE_SHA1: ${USE_SHA1}")
ENDIF()
-IF(SHA1_BACKEND STREQUAL "CollisionDetection")
+IF(USE_SHA1 STREQUAL "CollisionDetection")
SET(GIT_SHA1_COLLISIONDETECT 1)
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 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*)
-ELSEIF(SHA1_BACKEND STREQUAL "OpenSSL")
- # OPENSSL_FOUND should already be set, we're checking HTTPS_BACKEND
+ELSEIF(USE_SHA1 STREQUAL "OpenSSL")
+ # OPENSSL_FOUND should already be set, we're checking USE_HTTPS
SET(GIT_SHA1_OPENSSL 1)
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
@@ -41,10 +35,10 @@ ELSEIF(SHA1_BACKEND STREQUAL "OpenSSL")
LIST(APPEND LIBGIT2_PC_REQUIRES "openssl")
ENDIF()
FILE(GLOB SRC_SHA1 hash/sha1/openssl.*)
-ELSEIF(SHA1_BACKEND STREQUAL "CommonCrypto")
+ELSEIF(USE_SHA1 STREQUAL "CommonCrypto")
SET(GIT_SHA1_COMMON_CRYPTO 1)
FILE(GLOB SRC_SHA1 hash/sha1/common_crypto.*)
-ELSEIF(SHA1_BACKEND STREQUAL "mbedTLS")
+ELSEIF(USE_SHA1 STREQUAL "mbedTLS")
SET(GIT_SHA1_MBEDTLS 1)
FILE(GLOB SRC_SHA1 hash/sha1/mbedtls.*)
LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR})
@@ -53,14 +47,13 @@ ELSEIF(SHA1_BACKEND STREQUAL "mbedTLS")
# https://github.com/ARMmbed/mbedtls/issues/228
# For now, pass its link flags as our own
LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES})
-ELSEIF(SHA1_BACKEND STREQUAL "Win32")
+ELSEIF(USE_SHA1 STREQUAL "Win32")
SET(GIT_SHA1_WIN32 1)
FILE(GLOB SRC_SHA1 hash/sha1/win32.*)
-ELSEIF(SHA1_BACKEND STREQUAL "Generic")
+ELSEIF(USE_SHA1 STREQUAL "Generic")
FILE(GLOB SRC_SHA1 hash/sha1/generic.*)
-# ELSEIF(NOT USE_SHA1)
ELSE()
- MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${SHA1_BACKEND}")
+ MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}")
ENDIF()
-ADD_FEATURE_INFO(SHA ON "using ${SHA1_BACKEND}")
+ADD_FEATURE_INFO(SHA ON "using ${USE_SHA1}")
diff --git a/deps/ntlmclient/CMakeLists.txt b/deps/ntlmclient/CMakeLists.txt
index 66e96d6f6..43d32185a 100644
--- a/deps/ntlmclient/CMakeLists.txt
+++ b/deps/ntlmclient/CMakeLists.txt
@@ -4,18 +4,20 @@ ADD_DEFINITIONS(-DNTLM_STATIC=1)
DISABLE_WARNINGS(implicit-fallthrough)
-IF (HTTPS_BACKEND STREQUAL "SecureTransport")
+IF(USE_HTTPS STREQUAL "SecureTransport")
ADD_DEFINITIONS(-DCRYPT_COMMONCRYPTO)
SET(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c")
-ELSEIF (HTTPS_BACKEND STREQUAL "OpenSSL")
+ # CC_MD4 has been deprecated in macOS 10.15.
+ SET_SOURCE_FILES_PROPERTIES("crypt_commoncrypto.c" COMPILE_FLAGS "-Wno-deprecated")
+ELSEIF(USE_HTTPS STREQUAL "OpenSSL")
ADD_DEFINITIONS(-DCRYPT_OPENSSL)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c")
-ELSEIF (HTTPS_BACKEND STREQUAL "mbedTLS")
+ELSEIF(USE_HTTPS STREQUAL "mbedTLS")
ADD_DEFINITIONS(-DCRYPT_MBEDTLS)
SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c")
-ELSE ()
- MESSAGE(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${HTTPS_BACKEND}) for NTLM crypto")
+ELSE()
+ MESSAGE(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${USE_HTTPS}) for NTLM crypto")
ENDIF()
ADD_LIBRARY(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_CRYPTO})
diff --git a/deps/ntlmclient/compat.h b/deps/ntlmclient/compat.h
index efdf34514..555fa3fe4 100644
--- a/deps/ntlmclient/compat.h
+++ b/deps/ntlmclient/compat.h
@@ -22,8 +22,30 @@
#endif
#ifdef __linux__
+/* See man page endian(3) */
# include <endian.h>
# define htonll htobe64
+#elif defined(__OpenBSD__)
+/* See man page htobe64(3) */
+# include <endian.h>
+# define htonll htobe64
+#elif defined(__FreeBSD__)
+/* See man page bwaps64(9) */
+# include <sys/endian.h>
+# define htonll htobe64
+#elif defined(sun) || defined(__sun)
+/* See man page byteorder(3SOCKET) */
+# include <sys/types.h>
+# include <netinet/in.h>
+# include <inttypes.h>
+
+# if !defined(htonll)
+# if defined(_BIG_ENDIAN)
+# define htonll(x) (x)
+# else
+# define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl((uint64_t)(x) >> 32))
+# endif
+# endif
#endif
#ifndef MIN
diff --git a/docs/changelog.md b/docs/changelog.md
index c75164901..97cf94c6b 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,5 +1,340 @@
-v0.28 + 1
----------
+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
+-----
+
+This is v0.99 "Torschlusspanik". This will be the last minor release
+before libgit2 v1.0. We expect to only respond to bugs in this release,
+to stabilize it for next major release.
+
+It contains significant refactorings, but is expected to be API-compatible
+with v0.28.0.
+
+### Changes or improvements
+
+* When fetching from an anonymous remote using a URL with authentication
+ information provided in the URL (eg `https://foo:bar@example.com/repo`),
+ we would erroneously include the literal URL in the FETCH_HEAD file.
+ We now remove that to match git's behavior.
+
+* Some credential structures, enums and values have been renamed:
+ `git_cred` is now `git_credential`. `git_credtype_t` is now
+ `git_credential_t`. Functions and types beginning with
+ `git_cred_` now begin with `git_credential`, and constants beginning
+ with `GIT_CREDTYPE` now begin with `GIT_CREDENTIAL`. The former names
+ are deprecated.
+
+* Several function signatures have been changed to return an `int` to
+ indicate error conditions. We encourage you to check them for errors
+ in the standard way.
+
+ * `git_attr_cache_flush`
+ * `git_error_set_str`
+ * `git_index_name_clear`
+ * `git_index_reuc_clear`
+ * `git_libgit2_version`
+ * `git_mempack_reset`
+ * `git_oid_cpy`
+ * `git_oid_fmt`
+ * `git_oid_fromraw`
+ * `git_oid_nfmt`
+ * `git_oid_pathfmt`
+ * `git_remote_stop`
+ * `git_remote_disconnect`
+ * `git_repository__cleanup`
+ * `git_repository_set_config`
+ * `git_repository_set_index`
+ * `git_repository_set_odb`
+ * `git_repository_set_refdb`
+ * `git_revwalk_reset`
+ * `git_revwalk_simplify_first_parent`
+ * `git_revwalk_sorting`
+ * `git_treebuilder_clear`
+ * `git_treebuilder_filter`
+
+* The NTLM and Negotiate authentication mechanisms are now supported when
+ talking to git implementations hosted on Apache or nginx servers.
+
+* The `HEAD` symbolic reference can no longer be deleted.
+
+* `git_merge_driver_source_repo` no longer returns a `const git_repository *`,
+ it now returns a non-`const` `git_repository *`.
+
+* Relative symbolic links are now supported on Windows when `core.symlinks`
+ is enabled.
+
+* Servers that provide query parameters with a redirect are now supported.
+
+* `git_submodule_sync` will now resolve relative URLs.
+
+* When creating git endpoint URLs, double-slashes are no longer used when
+ the given git URL has a trailing slash.
+
+* On Windows, a `DllMain` function is no longer included and thread-local
+ storage has moved to fiber-local storage in order to prevent race
+ conditions during shutdown.
+
+* The tracing mechanism (`GIT_TRACE`) is now enabled by default and does
+ not need to be explicitly enabled in CMake.
+
+* The size of Git objects is now represented by `git_object_size_t`
+ instead of `off_t`.
+
+* Binary patches without data can now be parsed.
+
+* A configuration snapshot can now be created from another configuration
+ snapshot, not just a "true" configuration object.
+
+* The `git_commit_with_signature` API will now ensure that referenced
+ objects exist in the object database.
+
+* Stash messages containing newlines will now be replaced with spaces;
+ they will no longer be (erroneously) written to the repository.
+
+* `git_commit_create_with_signature` now verifies the commit information
+ to ensure that it points to a valid tree and valid parents.
+
+* `git_apply` has an option `GIT_APPLY_CHECK` that will only do a dry-run.
+ The index and working directory will remain unmodified, and application
+ will report if it would have worked.
+
+* Patches produced by Mercurial (those that lack some git extended headers)
+ can now be parsed and applied.
+
+* Reference locks are obeyed correctly on POSIX platforms, instead of
+ being removed.
+
+* Patches with empty new files can now be read and applied.
+
+* `git_apply_to_tree` can now correctly apply patches that add new files.
+
+* The program data configuration on Windows (`C:\ProgramData\Git\config`)
+ must be owned by an administrator, a system account or the current user
+ to be read.
+
+* `git_blob_filtered_content` is now deprecated in favor of `git_blob_filter`.
+
+* Configuration files can now be included conditionally using the
+ `onbranch` conditional.
+
+* Checkout can now properly create and remove symbolic links to directories
+ on Windows.
+
+* Stash no longer recomputes trees when committing a worktree, for
+ improved performance.
+
+* Repository templates can now include a `HEAD` file to default the
+ initial default branch.
+
+* Some configuration structures, enums and values have been renamed:
+ `git_cvar_map` is now `git_configmap`, `git_cvar_t` is now
+ `git_configmap_t`, `GIT_CVAR_FALSE` is now `GIT_CONFIGMAP_FALSE`,
+ `GIT_CVAR_TRUE` is now `GIT_CONFIGMAP_TRUE`, `GIT_CVAR_INT32` is now
+ `GIT_CONFIGMAP_INT32`, and `GIT_CVAR_STRING` is now `GIT_CONFIGMAP_STRING`.
+ The former names are deprecated.
+
+* Repositories can now be created at the root of a Windows drive.
+
+* Configuration lookups are now more efficiently cached.
+
+* `git_commit_create_with_signature` now supports a `NULL` signature,
+ which will create a commit without adding a signature.
+
+* When a repository lacks an `info` "common directory", we will no
+ longer erroneously return `GIT_ENOTFOUND` for all attribute lookups.
+
+* Several attribute macros have been renamed: `GIT_ATTR_TRUE` is now
+ `GIT_ATTR_IS_TRUE`, `GIT_ATTR_FALSE` is now `GIT_ATTR_IS_FALSE`,
+ `GIT_ATTR_UNSPECIFIED` is now `GIT_ATTR_IS_UNSPECIFIED`. The
+ attribute enum `git_attr_t` is now `git_attr_value_t` and its
+ values have been renamed: `GIT_ATTR_UNSPECIFIED_T` is now
+ `GIT_ATTR_VALUE_UNSPECIFIED`, `GIT_ATTR_TRUE_T` is now
+ `GIT_ATTR_VALUE_TRUE`, `GIT_ATTR_FALSE_T` is now `GIT_ATTR_VALUE_FALSE`,
+ and `GIT_ATTR_VALUE_T` is now `GIT_ATTR_VALUE_STRING`. The
+ former names are deprecated.
+
+* `git_object__size` is now `git_object_size`. The former name is
+ deprecated.
+
+* `git_tag_create_frombuffer` is now `git_tag_create_from_buffer`. The
+ former name is deprecated.
+
+* Several blob creation functions have been renamed:
+ `git_blob_create_frombuffer` is now named `git_blob_create_from_buffer`,
+ `git_blob_create_fromdisk` is now named `git_blob_create_from_disk`,
+ `git_blob_create_fromworkdir` is now named `git_blob_create_from_workdir`,
+ `git_blob_create_fromstream` is now named `git_blob_create_from_stream`,
+ and `git_blob_create_fromstream_commit` is now named
+ `git_blob_create_from_stream_commit`. The former names are deprecated.
+
+* The function `git_oid_iszero` is now named `git_oid_is_zero`. The
+ former name is deprecated.
+
+* Pattern matching is now done using `wildmatch` instead of `fnmatch`
+ for compatibility with git.
+
+* The option initialization functions suffixed by `init_options` are now
+ suffixed with `options_init`. (For example, `git_checkout_init_options`
+ is now `git_checkout_options_init`.) The former names are deprecated.
+
+* NTLM2 authentication is now supported on non-Windows platforms.
+
+* The `git_cred_sign_callback` callback is now named `git_cred_sign_cb`.
+ The `git_cred_ssh_interactive_callback` callback is now named
+ `git_cred_ssh_interactive_cb`.
+
+* Ignore files now:
+
+ * honor escaped trailing whitespace.
+ * do not incorrectly negate sibling paths of a negated pattern.
+ * honor rules that stop ignoring files after a wildcard
+
+* Attribute files now:
+
+ * honor leading and trailing whitespace.
+ * treat paths beginning with `\` as absolute only on Windows.
+ * properly handle escaped characters.
+ * stop reading macros defined in subdirectories
+
+* The C locale is now correctly used when parsing regular expressions.
+
+* The system PCRE2 or PCRE regular expression libraries are now used
+ when `regcomp_l` is not available on the system. If none of these
+ are available on the system, an included version of PCRE is used.
+
+* Wildcards in reference specifications are now supported beyond simply
+ a bare wildcard (`*`) for compatibility with git.
+
+* When `git_ignore_path_is_ignored` is provided a path with a trailing
+ slash (eg, `dir/`), it will now treat it as a directory for the
+ purposes of ignore matching.
+
+* Patches that add or remove a file with a space in the path can now
+ be correctly parsed.
+
+* The `git_remote_completion_type` type is now `git_remote_completion_t`.
+ The former name is deprecated.
+
+* The `git_odb_backend_malloc` is now `git_odb_backend_data_alloc`. The
+ former name is deprecated.
+
+* The `git_transfer_progress_cb` callback is now `git_indexer_progress_cb`
+ and the `git_transfer_progress` structure is now `git_indexer_progress`.
+ The former names are deprecated.
+
+* The example projects are now contained in a single `lg2` executable
+ for ease of use.
+
+* libgit2 now correctly handles more URLs, such as
+ `http://example.com:/repo.git` (colon but no port),
+ `http://example.com` (no path),
+ and `http://example.com:8080/` (path is /, nonstandard port).
+
+* A carefully constructed commit object with a very large number
+ of parents may lead to potential out-of-bounds writes or
+ potential denial of service.
+
+* The ProgramData configuration file is always read for compatibility
+ with Git for Windows and Portable Git installations. The ProgramData
+ location is not necessarily writable only by administrators, so we
+ now ensure that the configuration file is owned by the administrator
+ or the current user.
+
+### API additions
+
+* The SSH host key now supports SHA-256 when `GIT_CERT_SSH_SHA256` is set.
+
+* The diff format option `GIT_DIFF_FORMAT_PATCH_ID` can now be used to
+ emit an output like `git patch-id`.
+
+* The `git_apply_options_init` function will initialize a
+ `git_apply_options` structure.
+
+* The remote callbacks structure adds a `git_url_resolve_cb` callback
+ that is invoked when connecting to a server, so that applications
+ may edit or replace the URL before connection.
+
+* The information about the original `HEAD` in a rebase operation is
+ available with `git_rebase_orig_head_name`. Its ID is available with
+ `git_rebase_orig_head_id`. The `onto` reference name is available with
+ `git_rebase_onto_name` and its ID is available with `git_rebase_onto_id`.
+
+* ODB backends can now free backend data when an error occurs during its
+ backend data creation using `git_odb_backend_data_free`.
+
+* Options may be specified to `git_repository_foreach_head` to control
+ its behavior: `GIT_REPOSITORY_FOREACH_HEAD_SKIP_REPO` will not skip
+ the main repository's HEAD reference, while
+ `GIT_REPOSITORY_FOREACH_HEAD_SKIP_WORKTREES` will now skip the
+ worktree HEAD references.
+
+* The `GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS` option can be specified to
+ `git_libgit2_opts()` to avoid looking for `.keep` files that correspond
+ to packfiles. This setting can improve performance when packfiles are
+ stored on high-latency filesystems like network filesystems.
+
+* Blobs can now be filtered with `git_blob_filter`, which allows for
+ options to be set with `git_blob_filter_options`, including
+ `GIT_FILTER_NO_SYSTEM_ATTRIBUTES` to disable filtering with system-level
+ attributes in `/etc/gitattributes` and `GIT_ATTR_CHECK_INCLUDE_HEAD` to
+ enable filtering with `.gitattributes` files in the HEAD revision.
+
+### API removals
+
+* The unused `git_headlist_cb` function declaration was removed.
+
+* The unused `git_time_monotonic` API is removed.
+
+* The erroneously exported `inttypes.h` header was removed.
# Security Fixes
@@ -82,22 +417,62 @@ v0.28 + 1
"CollisionDetection". If you were using `SHA1_BACKEND` previously, you'll
need to check the value you've used, or switch to the autodetection.
-### Changes or improvements
-
-* libgit2 now correctly handles more URLs, such as
- `http://example.com:/repo.git` (colon but no port),
- `http://example.com` (no path),
- and `http://example.com:8080/` (path is /, nonstandard port).
-
-* A carefully constructed commit object with a very large number
- of parents may lead to potential out-of-bounds writes or
- potential denial of service.
-
-* The ProgramData configuration file is always read for compatibility
- with Git for Windows and Portable Git installations. The ProgramData
- location is not necessarily writable only by administrators, so we
- now ensure that the configuration file is owned by the administrator
- or the current user.
+### Authors
+
+The following individuals provided changes that were included in this
+release:
+
+* Aaron Patterson
+* Alberto Fanjul
+* Anders Borum
+* Augie Fackler
+* Augustin Fabre
+* Ayush Shridhar
+* brian m. carlson
+* buddyspike
+* Carlos Martín Nieto
+* cheese1
+* Dan Skorupski
+* Daniel Cohen Gindi
+* Dave Lee
+* David Brooks
+* David Turner
+* Denis Laxalde
+* Dhruva Krishnamurthy
+* Dominik Ritter
+* Drew DeVault
+* Edward Thomson
+* Eric Huss
+* Erik Aigner
+* Etienne Samson
+* Gregory Herrero
+* Heiko Voigt
+* Ian Hattendorf
+* Jacques Germishuys
+* Janardhan Pulivarthi
+* Jason Haslam
+* Johannes Schindelin
+* Jordan Wallet
+* Josh Bleecher Snyder
+* kas
+* kdj0c
+* Laurence McGlashan
+* lhchavez
+* Lukas Berk
+* Max Kostyukevich
+* Patrick Steinhardt
+* pcpthm
+* Remy Suen
+* Robert Coup
+* romkatv
+* Scott Furry
+* Sebastian Henke
+* Stefan Widgren
+* Steve King Jr
+* Sven Strickroth
+* Tobias Nießen
+* Tyler Ang-Wanek
+* Tyler Wanek
v0.28
-----
diff --git a/docs/fuzzing.md b/docs/fuzzing.md
index cd825766b..25b32cb04 100644
--- a/docs/fuzzing.md
+++ b/docs/fuzzing.md
@@ -3,7 +3,7 @@
libgit2 is currently using [libFuzzer](https://libfuzzer.info) to perform
automated fuzz testing. libFuzzer only works with clang.
-## Prerequisites** for building fuzz targets:
+## Prerequisites for building fuzz targets:
1. All the prerequisites for [building libgit2](https://github.com/libgit2/libgit2).
2. A recent version of clang. 6.0 is preferred. [pre-build Debian/Ubuntu
@@ -27,14 +27,15 @@ automated fuzz testing. libFuzzer only works with clang.
## Run the fuzz targets
-1. `ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolize-6.0
+1. `ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolize
LSAN_OPTIONS=allocator_may_return_null=1
- ASAN_OPTIONS=allocator_may_return_null=1 ./build/fuzz/fuzz_packfile_raw
- fuzz/corpora/fuzz_packfile_raw/`
+ ASAN_OPTIONS=allocator_may_return_null=1 ./build/fuzzers/packfile_fuzzer
+ fuzzers/corpora/packfile/`
The `LSAN_OPTIONS` and `ASAN_OPTIONS` are there to allow `malloc(3)` to return
-`NULL`. The `LLVM_PROFILE_FILE` is there to override the path where libFuzzer
-will write the coverage report.
+`NULL`, which is expected if a huge chunk of memory is allocated. The
+`LLVM_PROFILE_FILE` environment string can also be added to override the path
+where libFuzzer will write the coverage report.
## Get coverage
diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h
index 61d0115fd..e5e56edae 100644
--- a/include/git2/deprecated.h
+++ b/include/git2/deprecated.h
@@ -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
diff --git a/include/git2/repository.h b/include/git2/repository.h
index 45d7962b2..9ddcd3404 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -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
diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h
index 8e22c4f02..c31e26d95 100644
--- a/include/git2/sys/refdb_backend.h
+++ b/include/git2/sys/refdb_backend.h
@@ -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);
diff --git a/include/git2/version.h b/include/git2/version.h
index 148808ca0..b078e1ea2 100644
--- a/include/git2/version.h
+++ b/include/git2/version.h
@@ -7,12 +7,12 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.28.0"
-#define LIBGIT2_VER_MAJOR 0
-#define LIBGIT2_VER_MINOR 28
+#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 28
+#define LIBGIT2_SOVERSION "1.0"
#endif
diff --git a/script/release.py b/script/release.py
new file mode 100755
index 000000000..e0f29538e
--- /dev/null
+++ b/script/release.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+
+from collections import namedtuple
+
+import argparse
+import base64
+import copy
+import json
+import subprocess
+import sys
+import urllib.parse
+import urllib.request
+import urllib.error
+
+class Error(Exception):
+ pass
+
+class Version(object):
+ def __init__(self, version):
+ versions = version.split(sep='.')
+ if len(versions) < 2 or len(versions) > 3:
+ raise Error("Invalid version string '{}'".format(version))
+ self.major = int(versions[0])
+ self.minor = int(versions[1])
+ self.revision = int(versions[2]) if len(versions) == 3 else 0
+
+ def __str__(self):
+ return '{}.{}.{}'.format(self.major, self.minor, self.revision)
+
+ def __eq__(self, other):
+ return self.major == other.major and self.minor == other.minor and self.revision == other.revision
+
+def verify_version(version):
+ expected = {
+ 'VERSION': [ '"{}"'.format(version), None ],
+ 'VER_MAJOR': [ str(version.major), None ],
+ 'VER_MINOR': [ str(version.minor), None ],
+ 'VER_REVISION': [ str(version.revision), None ],
+ 'VER_PATCH': [ '0', None ],
+ 'SOVERSION': [ '"{}.{}"'.format(version.major, version.minor), None ],
+ }
+
+ with open('include/git2/version.h') as f:
+ lines = f.readlines()
+
+ for key in expected.keys():
+ define = '#define LIBGIT2_{} '.format(key)
+ for line in lines:
+ if line.startswith(define):
+ expected[key][1] = line[len(define):].strip()
+ break
+ else:
+ raise Error("version.h: missing define for '{}'".format(key))
+
+ for k, v in expected.items():
+ if v[0] != v[1]:
+ raise Error("version.h: define '{}' does not match (got '{}', expected '{}')".format(k, v[0], v[1]))
+
+def generate_relnotes(tree, version):
+ with open('docs/changelog.md') as f:
+ lines = f.readlines()
+
+ if not lines[0].startswith('v'):
+ raise Error("changelog.md: missing section for v{}".format(version))
+ try:
+ v = Version(lines[0][1:].strip())
+ except:
+ raise Error("changelog.md: invalid version string {}".format(lines[0].strip()))
+ if v != version:
+ raise Error("changelog.md: changelog version doesn't match (got {}, expected {})".format(v, version))
+ if not lines[1].startswith('----'):
+ raise Error("changelog.md: missing version header")
+ if lines[2] != '\n':
+ raise Error("changelog.md: missing newline after version header")
+
+ for i, line in enumerate(lines[3:]):
+ if not line.startswith('v'):
+ continue
+ try:
+ Version(line[1:].strip())
+ break
+ except:
+ continue
+ else:
+ raise Error("changelog.md: cannot find section header of preceding release")
+
+ return ''.join(lines[3:i + 3]).strip()
+
+def git(*args):
+ process = subprocess.run([ 'git', *args ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if process.returncode != 0:
+ raise Error('Failed executing git {}: {}'.format(' '.join(args), process.stderr.decode()))
+ return process.stdout
+
+def post(url, data, contenttype, user, password):
+ request = urllib.request.Request(url, data=data)
+ request.add_header('Accept', 'application/json')
+ request.add_header('Content-Type', contenttype)
+ request.add_header('Content-Length', len(data))
+ request.add_header('Authorization', 'Basic ' + base64.b64encode('{}:{}'.format(user, password).encode()).decode())
+
+ try:
+ response = urllib.request.urlopen(request)
+ if response.getcode() != 201:
+ raise Error("POST to '{}' failed: {}".format(url, response.reason))
+ except urllib.error.URLError as e:
+ raise Error("POST to '{}' failed: {}".format(url, e))
+ data = json.load(response)
+
+ return data
+
+def generate_asset(version, tree, archive_format):
+ Asset = namedtuple('Asset', ['name', 'label', 'mimetype', 'data'])
+ mimetype = 'application/{}'.format('gzip' if archive_format == 'tar.gz' else 'zip')
+ return Asset(
+ "libgit2-{}.{}".format(version, archive_format), "Release sources: libgit2-{}.{}".format(version, archive_format), mimetype,
+ git('archive', '--format', archive_format, '--prefix', 'libgit2-{}/'.format(version), tree)
+ )
+
+def release(args):
+ params = {
+ "tag_name": 'v' + str(args.version),
+ "name": 'libgit2 v' + str(args.version),
+ "target_commitish": git('rev-parse', args.tree).decode().strip(),
+ "body": generate_relnotes(args.tree, args.version),
+ }
+ assets = [
+ generate_asset(args.version, args.tree, 'tar.gz'),
+ generate_asset(args.version, args.tree, 'zip'),
+ ]
+
+ if args.dryrun:
+ for k, v in params.items():
+ print('{}: {}'.format(k, v))
+ for asset in assets:
+ print('asset: name={}, label={}, mimetype={}, bytes={}'.format(asset.name, asset.label, asset.mimetype, len(asset.data)))
+ return
+
+ try:
+ url = 'https://api.github.com/repos/{}/releases'.format(args.repository)
+ response = post(url, json.dumps(params).encode(), 'application/json', args.user, args.password)
+ except Error as e:
+ raise Error('Could not create release: ' + str(e))
+
+ for asset in assets:
+ try:
+ url = list(urllib.parse.urlparse(response['upload_url'].split('{?')[0]))
+ url[4] = urllib.parse.urlencode({ 'name': asset.name, 'label': asset.label })
+ post(urllib.parse.urlunparse(url), asset.data, asset.mimetype, args.user, args.password)
+ except Error as e:
+ raise Error('Could not upload asset: ' + str(e))
+
+def main():
+ parser = argparse.ArgumentParser(description='Create a libgit2 release')
+ parser.add_argument('--tree', default='HEAD', help='tree to create release for (default: HEAD)')
+ parser.add_argument('--dryrun', action='store_true', help='generate release, but do not post it')
+ parser.add_argument('--repository', default='libgit2/libgit2', help='GitHub repository to create repository in')
+ parser.add_argument('--user', help='user to authenitcate as')
+ parser.add_argument('--password', help='password to authenticate with')
+ parser.add_argument('version', type=Version, help='version of the new release')
+ args = parser.parse_args()
+
+ verify_version(args.version)
+ release(args)
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Error as e:
+ print(e)
+ sys.exit(1)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9e4a41a61..dff1d94e8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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)
@@ -288,19 +282,22 @@ IF (WIN32 AND NOT CYGWIN)
ELSEIF (AMIGA)
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP)
ELSE()
- ADD_FEATURE_INFO(valgrind VALGRIND "valgrind hints")
- IF (VALGRIND)
- ADD_DEFINITIONS(-DVALGRIND)
- ENDIF()
-
FILE(GLOB SRC_OS unix/*.c unix/*.h)
ENDIF()
+IF (USE_LEAK_CHECKER STREQUAL "valgrind")
+ ADD_DEFINITIONS(-DVALGRIND)
+ENDIF()
+
FILE(GLOB SRC_GIT2 *.c *.h
allocators/*.c allocators/*.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
@@ -388,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})
diff --git a/src/blame.c b/src/blame.c
index 404f1f643..23c21027a 100644
--- a/src/blame.c
+++ b/src/blame.c
@@ -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(
diff --git a/src/cache.c b/src/cache.c
index 32ba993b0..af42b3959 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -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 */
}
diff --git a/src/diff_print.c b/src/diff_print.c
index 369e5c1e6..a78953c32 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -359,9 +359,9 @@ int diff_delta_format_similarity_header(
abort();
if ((error = git_buf_puts(&old_path, delta->old_file.path)) < 0 ||
- (error = git_buf_puts(&new_path, delta->new_file.path)) < 0 ||
- (error = git_buf_quote(&old_path)) < 0 ||
- (error = git_buf_quote(&new_path)) < 0)
+ (error = git_buf_puts(&new_path, delta->new_file.path)) < 0 ||
+ (error = git_buf_quote(&old_path)) < 0 ||
+ (error = git_buf_quote(&new_path)) < 0)
goto done;
git_buf_printf(out,
@@ -428,8 +428,11 @@ int git_diff_delta__format_file_header(
git_buf_printf(out, "diff --git %s %s\n",
old_path.ptr, new_path.ptr);
+ if (unchanged && delta->old_file.mode != delta->new_file.mode)
+ diff_print_modes(out, delta);
+
if (delta->status == GIT_DELTA_RENAMED ||
- (delta->status == GIT_DELTA_COPIED && unchanged)) {
+ (delta->status == GIT_DELTA_COPIED && unchanged)) {
if ((error = diff_delta_format_similarity_header(out, delta)) < 0)
goto done;
}
@@ -444,9 +447,6 @@ int git_diff_delta__format_file_header(
"--- %s\n+++ %s\n", old_path.ptr, new_path.ptr);
}
- if (unchanged && delta->old_file.mode != delta->new_file.mode)
- diff_print_modes(out, delta);
-
if (git_buf_oom(out))
error = -1;
diff --git a/src/indexer.c b/src/indexer.c
index 717549fa2..68fdd85c5 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -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;
diff --git a/src/notes.c b/src/notes.c
index 4633a16ea..68d2ae9ec 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -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;
}
diff --git a/src/odb_pack.c b/src/odb_pack.c
index c93d07c46..86c858df1 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -15,7 +15,6 @@
#include "hash.h"
#include "odb.h"
#include "delta.h"
-#include "sha1_lookup.h"
#include "mwindow.h"
#include "pack.h"
diff --git a/src/pack-objects.c b/src/pack-objects.c
index bdd5171a8..49b4e4772 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -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 ||
diff --git a/src/pack.c b/src/pack.c
index 7c6fc2cdb..fcf64f57d 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -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,
diff --git a/src/patch_parse.c b/src/patch_parse.c
index 9d089ad83..0e251cb88 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -411,6 +411,7 @@ static const parse_header_transition transitions[] = {
{ "GIT binary patch" , STATE_INDEX, STATE_END, NULL },
{ "Binary files " , STATE_INDEX, STATE_END, NULL },
+ { "similarity index " , STATE_END, STATE_SIMILARITY, parse_header_similarity },
{ "similarity index " , STATE_DIFF, STATE_SIMILARITY, parse_header_similarity },
{ "dissimilarity index ", STATE_DIFF, STATE_SIMILARITY, parse_header_dissimilarity },
{ "rename from " , STATE_SIMILARITY, STATE_RENAME, parse_header_renamefrom },
diff --git a/src/push.c b/src/push.c
index 67ebcfb3e..34867c2e4 100644
--- a/src/push.c
+++ b/src/push.c
@@ -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);
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index a721f9841..653cc1b97 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -5,8 +5,6 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
-#include "refdb_fs.h"
-
#include "refs.h"
#include "hash.h"
#include "repository.h"
@@ -2129,6 +2127,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) {
diff --git a/src/refdb_fs.h b/src/refdb_fs.h
deleted file mode 100644
index 0c84814df..000000000
--- a/src/refdb_fs.h
+++ /dev/null
@@ -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_refdb_fs_h__
-#define INCLUDE_refdb_fs_h__
-
-#include "common.h"
-
-#include "strmap.h"
-
-typedef struct {
- git_strmap *packfile;
- time_t packfile_time;
-} git_refcache;
-
-#endif
diff --git a/src/repository.c b/src/repository.c
index 721ce5e90..da92b274c 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -191,19 +191,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);
- git_buf_rtrim(&common_link);
+ 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);
}
@@ -211,24 +217,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)
@@ -443,15 +451,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);
@@ -477,9 +485,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;
}
@@ -493,28 +500,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);
}
@@ -525,10 +537,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. */
@@ -536,31 +546,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);
@@ -571,14 +578,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);
@@ -2084,6 +2093,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);
@@ -2095,7 +2105,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);
diff --git a/src/revwalk.c b/src/revwalk.c
index 4587b5acc..abbd65ac2 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -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;
diff --git a/src/sha1_lookup.c b/src/sha1_lookup.c
deleted file mode 100644
index 14fcb40e5..000000000
--- a/src/sha1_lookup.c
+++ /dev/null
@@ -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;
-}
diff --git a/src/sha1_lookup.h b/src/sha1_lookup.h
deleted file mode 100644
index 841ea5b22..000000000
--- a/src/sha1_lookup.h
+++ /dev/null
@@ -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
diff --git a/src/streams/openssl.c b/src/streams/openssl.c
index 98a3635af..5b66352ca 100644
--- a/src/streams/openssl.c
+++ b/src/streams/openssl.c
@@ -30,10 +30,6 @@
#include <openssl/x509v3.h>
#include <openssl/bio.h>
-#ifdef VALGRIND
-# include <valgrind/memcheck.h>
-#endif
-
SSL_CTX *git__ssl_ctx;
#define GIT_SSL_DEFAULT_CIPHERS "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
@@ -160,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]);
}
@@ -200,16 +196,69 @@ static void shutdown_ssl(void)
}
}
+#ifdef VALGRIND
+#ifdef OPENSSL_LEGACY_API
+static void *git_openssl_malloc(size_t bytes)
+{
+ return git__calloc(1, bytes);
+}
+
+static void *git_openssl_realloc(void *mem, size_t size)
+{
+ return git__realloc(mem, size);
+}
+
+static void git_openssl_free(void *mem)
+{
+ return git__free(mem);
+}
+#else
+static void *git_openssl_malloc(size_t bytes, const char *file, int line)
+{
+ GIT_UNUSED(file);
+ GIT_UNUSED(line);
+ return git__calloc(1, bytes);
+}
+
+static void *git_openssl_realloc(void *mem, size_t size, const char *file, int line)
+{
+ GIT_UNUSED(file);
+ GIT_UNUSED(line);
+ return git__realloc(mem, size);
+}
+
+static void git_openssl_free(void *mem, const char *file, int line)
+{
+ GIT_UNUSED(file);
+ GIT_UNUSED(line);
+ return git__free(mem);
+}
+#endif
+#endif
+
int git_openssl_stream_global_init(void)
{
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
const char *ciphers = git_libgit2__ssl_ciphers();
+#ifdef VALGRIND
+ static bool allocators_initialized = false;
+#endif
/* Older OpenSSL and MacOS OpenSSL doesn't have this */
#ifdef SSL_OP_NO_COMPRESSION
ssl_opts |= SSL_OP_NO_COMPRESSION;
#endif
+#ifdef VALGRIND
+ /* Swap in our own allocator functions that initialize allocated memory */
+ if (!allocators_initialized &&
+ CRYPTO_set_mem_functions(git_openssl_malloc,
+ git_openssl_realloc,
+ git_openssl_free) != 1)
+ goto error;
+ allocators_initialized = true;
+#endif
+
OPENSSL_init_ssl(0, NULL);
/*
@@ -314,11 +363,6 @@ static int bio_read(BIO *b, char *buf, int len)
static int bio_write(BIO *b, const char *buf, int len)
{
git_stream *io = (git_stream *) BIO_get_data(b);
-
-#ifdef VALGRIND
- VALGRIND_MAKE_MEM_DEFINED(buf, len);
-#endif
-
return (int) git_stream_write(io, buf, len, 0);
}
@@ -595,10 +639,6 @@ static int openssl_connect(git_stream *stream)
BIO_set_data(bio, st->io);
SSL_set_bio(st->ssl, bio, bio);
-#ifdef VALGRIND
- VALGRIND_MAKE_MEM_DEFINED(st->ssl, sizeof(SSL));
-#endif
-
/* specify the host in case SNI is needed */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
SSL_set_tlsext_host_name(st->ssl, st->host);
@@ -609,10 +649,6 @@ static int openssl_connect(git_stream *stream)
st->connected = true;
-#ifdef VALGRIND
- VALGRIND_MAKE_MEM_DEFINED(st->ssl, sizeof(SSL));
-#endif
-
return verify_server_cert(st->ssl, st->host);
}
@@ -679,10 +715,6 @@ static ssize_t openssl_read(git_stream *stream, void *data, size_t len)
if ((ret = SSL_read(st->ssl, data, len)) <= 0)
return ssl_set_error(st->ssl, ret);
-#ifdef VALGRIND
- VALGRIND_MAKE_MEM_DEFINED(data, ret);
-#endif
-
return ret;
}
diff --git a/src/transports/auth_ntlm.c b/src/transports/auth_ntlm.c
index 02a861f07..d134a3db6 100644
--- a/src/transports/auth_ntlm.c
+++ b/src/transports/auth_ntlm.c
@@ -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;
diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c
index f5c2ce58d..bde67ca9f 100644
--- a/src/transports/httpclient.c
+++ b/src/transports/httpclient.c
@@ -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;
}
diff --git a/src/unix/posix.h b/src/unix/posix.h
index d1f902489..4fa725013 100644
--- a/src/unix/posix.h
+++ b/src/unix/posix.h
@@ -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
diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c
index eda85abf4..18b43e728 100644
--- a/src/win32/path_w32.c
+++ b/src/win32/path_w32.c
@@ -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;
diff --git a/src/win32/path_w32.h b/src/win32/path_w32.h
index afd0aa155..dab8b96fa 100644
--- a/src/win32/path_w32.h
+++ b/src/win32/path_w32.h
@@ -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.
@@ -20,12 +22,25 @@
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,
* strip trailing directory separators, ensure directory separators are all
* 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
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 29641bdaf..cacf986e8 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -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;
diff --git a/src/worktree.c b/src/worktree.c
index ef4ebfda8..e171afbb2 100644
--- a/src/worktree.c
+++ b/src/worktree.c
@@ -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;
}
diff --git a/tests/blame/blame_helpers.c b/tests/blame/blame_helpers.c
index 61e87350c..6b3ce677d 100644
--- a/tests/blame/blame_helpers.c
+++ b/tests/blame/blame_helpers.c
@@ -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);
diff --git a/tests/blame/blame_helpers.h b/tests/blame/blame_helpers.h
index fd5a35d2c..5b34b4aef 100644
--- a/tests/blame/blame_helpers.h
+++ b/tests/blame/blame_helpers.h
@@ -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,
diff --git a/tests/blame/buffer.c b/tests/blame/buffer.c
index 340b1dced..06d5042dd 100644
--- a/tests/blame/buffer.c
+++ b/tests/blame/buffer.c
@@ -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;
diff --git a/tests/config/global.c b/tests/config/global.c
index b64b71677..ed47d0251 100644
--- a/tests/config/global.c
+++ b/tests/config/global.c
@@ -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));
diff --git a/tests/config/new.c b/tests/config/new.c
index 2f5d83d52..22c330f6f 100644
--- a/tests/config/new.c
+++ b/tests/config/new.c
@@ -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));
}
diff --git a/tests/core/posix.c b/tests/core/posix.c
index 764ca1942..1bb1e9c6b 100644
--- a/tests/core/posix.c
+++ b/tests/core/posix.c
@@ -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;
diff --git a/tests/diff/tree.c b/tests/diff/tree.c
index 2359a834b..dfe4d254c 100644
--- a/tests/diff/tree.c
+++ b/tests/diff/tree.c
@@ -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);
+}
diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c
index 8b0445214..71b2e91a7 100644
--- a/tests/diff/workdir.c
+++ b/tests/diff/workdir.c
@@ -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);
+}
diff --git a/tests/ignore/path.c b/tests/ignore/path.c
index 864fba41b..e23ac7712 100644
--- a/tests/ignore/path.c
+++ b/tests/ignore/path.c
@@ -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");
diff --git a/tests/index/nsec.c b/tests/index/nsec.c
index dee1509e1..6edcf030a 100644
--- a/tests/index/nsec.c
+++ b/tests/index/nsec.c
@@ -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);
diff --git a/tests/index/tests.c b/tests/index/tests.c
index 4c9deaaba..d9d8371dd 100644
--- a/tests/index/tests.c
+++ b/tests/index/tests.c
@@ -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));
diff --git a/tests/network/refspecs.c b/tests/network/refspecs.c
index 734759060..5c8eb1502 100644
--- a/tests/network/refspecs.c
+++ b/tests/network/refspecs.c
@@ -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);
diff --git a/tests/notes/notes.c b/tests/notes/notes.c
index f2457665c..af9686790 100644
--- a/tests/notes/notes.c
+++ b/tests/notes/notes.c
@@ -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);
diff --git a/tests/object/cache.c b/tests/object/cache.c
index 3ccc325e4..08bf03648 100644
--- a/tests/object/cache.c
+++ b/tests/object/cache.c
@@ -244,15 +244,15 @@ static void *cache_quick(void *arg)
void test_object_cache__fast_thread_rush(void)
{
- int try, th, data[THREADCOUNT*2];
+ int try, th, data[THREADCOUNT];
#ifdef GIT_THREADS
- git_thread t[THREADCOUNT*2];
+ git_thread t[THREADCOUNT];
#endif
for (try = 0; try < REPEAT; ++try) {
cl_git_pass(git_repository_open(&g_repo, cl_fixture("testrepo.git")));
- for (th = 0; th < THREADCOUNT*2; ++th) {
+ for (th = 0; th < THREADCOUNT; ++th) {
data[th] = th;
#ifdef GIT_THREADS
cl_git_pass(
@@ -263,7 +263,7 @@ void test_object_cache__fast_thread_rush(void)
}
#ifdef GIT_THREADS
- for (th = 0; th < THREADCOUNT*2; ++th) {
+ for (th = 0; th < THREADCOUNT; ++th) {
void *rval;
cl_git_pass(git_thread_join(&t[th], &rval));
cl_assert_equal_i(th, *((int *)rval));
diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h
index 731524767..1e03889fc 100644
--- a/tests/patch/patch_common.h
+++ b/tests/patch/patch_common.h
@@ -579,6 +579,14 @@
"rename from file.txt\n" \
"rename to newfile.txt\n"
+#define PATCH_RENAME_EXACT_WITH_MODE \
+ "diff --git a/RENAMED.md b/README.md\n" \
+ "old mode 100644\n" \
+ "new mode 100755\n" \
+ "similarity index 100%\n" \
+ "rename from RENAMED.md\n" \
+ "rename to README.md\n"
+
#define PATCH_RENAME_SIMILAR \
"diff --git a/file.txt b/newfile.txt\n" \
"similarity index 77%\n" \
diff --git a/tests/patch/print.c b/tests/patch/print.c
index c4ff479e9..b0a933943 100644
--- a/tests/patch/print.c
+++ b/tests/patch/print.c
@@ -107,6 +107,12 @@ void test_patch_print__rename_exact(void)
strlen(PATCH_RENAME_EXACT));
}
+void test_patch_print__rename_exact_with_mode(void)
+{
+ patch_print_from_patchfile(PATCH_RENAME_EXACT_WITH_MODE,
+ strlen(PATCH_RENAME_EXACT_WITH_MODE));
+}
+
void test_patch_print__rename_similar(void)
{
patch_print_from_patchfile(PATCH_RENAME_SIMILAR,
diff --git a/tests/path/win32.c b/tests/path/win32.c
index 3ed7d7a6a..b416e9e60 100644
--- a/tests/path/win32.c
+++ b/tests/path/win32.c
@@ -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");
diff --git a/tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e b/tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e
new file mode 100644
index 000000000..71f9c980e
--- /dev/null
+++ b/tests/resources/blametest.git/objects/83/6bc00b06cb60eb0f629e237ad2b58adb2cfc7e
@@ -0,0 +1,3 @@
+xK
+1D]B$OD{{: OգAyu" RAˆ41f/]UϲȣX
+MȖ,sFc8S[}⩼壏78pO.%fZua\uJF \ No newline at end of file
diff --git a/tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f b/tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f
new file mode 100644
index 000000000..0bab0ef53
--- /dev/null
+++ b/tests/resources/blametest.git/objects/a8/ba8436b5d8ccbdfd5be597c194e7bb8e0a092f
@@ -0,0 +1 @@
+x+)JMU04`040031QH+(aٵJ5Ѕ'3P%0 }_ՉΓE{4٩r -3'槚^uU'ݘanP55?p9_$*\9 \ No newline at end of file
diff --git a/tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3 b/tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3
new file mode 100644
index 000000000..942a7eedc
--- /dev/null
+++ b/tests/resources/blametest.git/objects/f9/264f7fbd31ae7a18b7931ed8946fb0aebb0af3
Binary files differ
diff --git a/tests/resources/blametest.git/refs/heads/master b/tests/resources/blametest.git/refs/heads/master
index d1bc4ca6b..994877a20 100644
--- a/tests/resources/blametest.git/refs/heads/master
+++ b/tests/resources/blametest.git/refs/heads/master
@@ -1 +1 @@
-6653ff42313eb5c82806f145391b18a9699800c7
+836bc00b06cb60eb0f629e237ad2b58adb2cfc7e