New upstream version 1.8.1+ds

This commit is contained in:
Timo Röhling 2024-05-20 11:15:36 +02:00
parent 810f20f573
commit 3e184db30b
307 changed files with 12619 additions and 4975 deletions

2
.gitattributes vendored
View File

@ -1,2 +1,4 @@
* text=auto
ci/**/*.sh text eol=lf
script/**/*.sh text eol=lf
tests/resources/** linguist-vendored

View File

@ -0,0 +1,109 @@
# Run a build step in a container or directly on the Actions runner
name: Download or Build Container
description: Download a container from the package registry, or build it if it's not found
inputs:
container:
description: Container name
type: string
required: true
dockerfile:
description: Dockerfile
type: string
base:
description: Container base
type: string
registry:
description: Docker registry to read and publish to
type: string
default: ghcr.io
config-path:
description: Path to Dockerfiles
type: string
github_token:
description: GitHub Token
type: string
runs:
using: 'composite'
steps:
- name: Download container
run: |
IMAGE_NAME="${{ inputs.container }}"
DOCKERFILE_PATH="${{ inputs.dockerfile }}"
DOCKER_REGISTRY="${{ inputs.registry }}"
DOCKERFILE_ROOT="${{ inputs.config-path }}"
if [ "${DOCKERFILE_PATH}" = "" ]; then
DOCKERFILE_PATH="${DOCKERFILE_ROOT}/${IMAGE_NAME}"
else
DOCKERFILE_PATH="${DOCKERFILE_ROOT}/${DOCKERFILE_PATH}"
fi
GIT_WORKTREE=$(cd "${GITHUB_ACTION_PATH}" && git rev-parse --show-toplevel)
echo "::: git worktree is ${GIT_WORKTREE}"
cd "${GIT_WORKTREE}"
DOCKER_CONTAINER="${GITHUB_REPOSITORY}/${IMAGE_NAME}"
DOCKER_REGISTRY_CONTAINER="${DOCKER_REGISTRY}/${DOCKER_CONTAINER}"
echo "dockerfile=${DOCKERFILE_PATH}" >> $GITHUB_ENV
echo "docker-container=${DOCKER_CONTAINER}" >> $GITHUB_ENV
echo "docker-registry-container=${DOCKER_REGISTRY_CONTAINER}" >> $GITHUB_ENV
# Identify the last git commit that touched the Dockerfiles
# Use this as a hash to identify the resulting docker containers
echo "::: dockerfile path is ${DOCKERFILE_PATH}"
DOCKER_SHA=$(git log -1 --pretty=format:"%h" -- "${DOCKERFILE_PATH}")
echo "docker-sha=${DOCKER_SHA}" >> $GITHUB_ENV
echo "::: docker sha is ${DOCKER_SHA}"
DOCKER_REGISTRY_CONTAINER_SHA="${DOCKER_REGISTRY_CONTAINER}:${DOCKER_SHA}"
echo "docker-registry-container-sha=${DOCKER_REGISTRY_CONTAINER_SHA}" >> $GITHUB_ENV
echo "docker-registry-container-latest=${DOCKER_REGISTRY_CONTAINER}:latest" >> $GITHUB_ENV
echo "::: logging in to ${DOCKER_REGISTRY} as ${GITHUB_ACTOR}"
exists="true"
docker login https://${DOCKER_REGISTRY} -u ${GITHUB_ACTOR} -p ${GITHUB_TOKEN} || exists="false"
echo "::: pulling ${DOCKER_REGISTRY_CONTAINER_SHA}"
if [ "${exists}" != "false" ]; then
docker pull ${DOCKER_REGISTRY_CONTAINER_SHA} || exists="false"
fi
if [ "${exists}" = "true" ]; then
echo "::: docker container exists in registry"
echo "docker-container-exists=true" >> $GITHUB_ENV
else
echo "::: docker container does not exist in registry"
echo "docker-container-exists=false" >> $GITHUB_ENV
fi
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github_token }}
- name: Create container
run: |
if [ "${{ inputs.base }}" != "" ]; then
BASE_ARG="--build-arg BASE=${{ inputs.base }}"
fi
GIT_WORKTREE=$(cd "${GITHUB_ACTION_PATH}" && git rev-parse --show-toplevel)
echo "::: git worktree is ${GIT_WORKTREE}"
cd "${GIT_WORKTREE}"
docker build -t ${{ env.docker-registry-container-sha }} --build-arg UID=$(id -u) --build-arg GID=$(id -g) ${BASE_ARG} -f ${{ env.dockerfile }} .
docker tag ${{ env.docker-registry-container-sha }} ${{ env.docker-registry-container-latest }}
shell: bash
working-directory: source/${{ inputs.config-path }}
if: env.docker-container-exists != 'true'
- name: Publish container
run: |
docker push ${{ env.docker-registry-container-sha }}
docker push ${{ env.docker-registry-container-latest }}
shell: bash
if: env.docker-container-exists != 'true' && github.event_name != 'pull_request'

View File

@ -5,14 +5,19 @@ description: Run a build step in a container or directly on the Actions runner
inputs:
command:
description: Command to run
required: true
type: string
required: true
container:
description: Optional container to run in
type: string
container-version:
description: Version of the container to run
type: string
shell:
description: Shell to use
type: string
required: true
default: 'bash'
runs:
using: 'composite'
@ -35,6 +40,7 @@ runs:
-e PKG_CONFIG_PATH \
-e SKIP_NEGOTIATE_TESTS \
-e SKIP_SSH_TESTS \
-e SKIP_PUSHOPTIONS_TESTS \
-e TSAN_OPTIONS \
-e UBSAN_OPTIONS \
${{ inputs.container-version }} \
@ -42,4 +48,4 @@ runs:
else
${{ inputs.command }}
fi
shell: bash
shell: ${{ inputs.shell != '' && inputs.shell || 'bash' }}

6
.github/release.yml vendored
View File

@ -21,9 +21,15 @@ changelog:
- title: Documentation improvements
labels:
- documentation
- title: Platform compatibility fixes
labels:
- compatibility
- title: Git compatibility fixes
labels:
- git compatibility
- title: Dependency updates
labels:
- dependency
- title: Other changes
labels:
- '*'

View File

@ -6,10 +6,14 @@ on:
schedule:
- cron: '15 4 * * *'
permissions:
contents: read
jobs:
# Run our nightly builds. We build a matrix with the various build
# targets and their details. Then we build either in a docker container
# (Linux) or on the actual hosts (macOS, Windows).
# Run our benchmarks. We build a matrix with the various build
# targets and their details. Unlike our CI builds, we run these
# directly on the VM instead of in containers since we do not
# need the breadth of platform diversity.
build:
# Only run scheduled workflows on the main repository; prevents people
# from using build minutes on their forks.
@ -27,7 +31,7 @@ jobs:
os: ubuntu-latest
setup-script: ubuntu
- name: "macOS"
os: macos-11
os: macos-12
env:
CC: clang
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_CLI=ON -DCMAKE_BUILD_TYPE=Release
@ -45,12 +49,12 @@ jobs:
id: windows
setup-script: win32
fail-fast: false
name: "Build ${{ matrix.platform.name }}"
name: "Benchmark ${{ matrix.platform.name }}"
env: ${{ matrix.platform.env }}
runs-on: ${{ matrix.platform.os }}
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
@ -72,11 +76,65 @@ jobs:
fi
mkdir benchmark && cd benchmark
../source/tests/benchmarks/benchmark.sh --baseline-cli "git" --cli "${GIT2_CLI}" --json benchmarks.json --zip benchmarks.zip
../source/tests/benchmarks/benchmark.sh --baseline-cli "git" --cli "${GIT2_CLI}" --name libgit2 --json benchmarks.json --zip benchmarks.zip
shell: bash
- name: Upload results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: benchmark-${{ matrix.platform.id }}
path: benchmark
if: always()
# Publish the results
publish:
name: Publish results
needs: [ build ]
if: ${{ always() && github.repository == 'libgit2/libgit2' }}
runs-on: ubuntu-latest
steps:
- name: Check out benchmark repository
uses: actions/checkout@v4
with:
repository: libgit2/benchmarks
path: site
fetch-depth: 0
ssh-key: ${{ secrets.BENCHMARKS_PUBLISH_KEY }}
- name: Download test results
uses: actions/download-artifact@v4
- name: Publish API
run: |
# Move today's benchmark run into the right place
for platform in linux macos windows; do
TIMESTAMP=$(jq .time.start < "benchmark-${platform}/benchmarks.json")
TIMESTAMP_LEN=$(echo -n ${TIMESTAMP} | wc -c | xargs)
DENOMINATOR=1
if [ "${TIMESTAMP_LEN}" = "19" ]; then
DENOMINATOR="1000000000"
elif [ "${TIMESTAMP_LEN}" = "13" ]; then
DENOMINATOR="1000"
else
echo "unknown timestamp"
exit 1
fi
if [[ "$(uname -s)" == "Darwin" ]]; then
DATE=$(date -R -r $(("${TIMESTAMP}/${DENOMINATOR}")) +"%Y-%m-%d")
else
DATE=$(date -d @$(("${TIMESTAMP}/${DENOMINATOR}")) +"%Y-%m-%d")
fi
mkdir -p "site/public/api/runs/${DATE}"
cp "benchmark-${platform}/benchmarks.json" "site/public/api/runs/${DATE}/${platform}.json"
done
(cd site && node scripts/aggregate.js)
(
cd site &&
git config user.name 'Benchmark Site Generation' &&
git config user.email 'libgit2@users.noreply.github.com' &&
git add . &&
git commit --allow-empty -m"benchmark update ${DATE}" &&
git push origin main
)
shell: bash

View File

@ -24,6 +24,7 @@ jobs:
- name: xenial
- name: bionic
- name: focal
- name: noble
- name: docurium
- name: bionic-x86
dockerfile: bionic
@ -39,11 +40,12 @@ jobs:
qemu: true
- name: centos7
- name: centos8
- name: fedora
runs-on: ubuntu-latest
name: "Create container: ${{ matrix.container.name }}"
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0

118
.github/workflows/experimental.yml vendored Normal file
View File

@ -0,0 +1,118 @@
# Validation builds for experimental features; these shouldn't be
# required for pull request approval.
name: Experimental Features
on:
push:
branches: [ main, maint/* ]
pull_request:
branches: [ main, maint/* ]
workflow_dispatch:
env:
docker-registry: ghcr.io
docker-config-path: ci/docker
permissions:
contents: write
packages: write
jobs:
# Run our CI/CD builds. We build a matrix with the various build targets
# and their details. Then we build either in a docker container (Linux)
# or on the actual hosts (macOS, Windows).
build:
strategy:
matrix:
platform:
# All builds: experimental SHA256 support
- name: "Linux (SHA256, Xenial, Clang, OpenSSL)"
id: linux-sha256
os: ubuntu-latest
container:
name: xenial
env:
CC: clang
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DEXPERIMENTAL_SHA256=ON
- name: "macOS (SHA256)"
id: macos-sha256
os: macos-12
setup-script: osx
env:
CC: clang
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON -DEXPERIMENTAL_SHA256=ON
CMAKE_GENERATOR: Ninja
PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (SHA256, amd64, Visual Studio)"
id: windows-sha256
os: windows-2019
env:
ARCH: amd64
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DEXPERIMENTAL_SHA256=ON
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
fail-fast: false
env: ${{ matrix.platform.env }}
runs-on: ${{ matrix.platform.os }}
name: "Build: ${{ matrix.platform.name }}"
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
- name: Set up build environment
run: source/ci/setup-${{ matrix.platform.setup-script }}-build.sh
shell: bash
if: matrix.platform.setup-script != ''
- name: Setup QEMU
run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
if: matrix.platform.container.qemu == true
- name: Set up container
uses: ./source/.github/actions/download-or-build-container
with:
registry: ${{ env.docker-registry }}
config-path: ${{ env.docker-config-path }}
container: ${{ matrix.platform.container.name }}
github_token: ${{ secrets.github_token }}
dockerfile: ${{ matrix.platform.container.dockerfile }}
if: matrix.platform.container.name != ''
- name: Prepare build
run: mkdir build
- name: Build
uses: ./source/.github/actions/run-build
with:
command: cd ${BUILD_WORKSPACE:-.}/build && ../source/ci/build.sh
container: ${{ matrix.platform.container.name }}
container-version: ${{ env.docker-registry-container-sha }}
shell: ${{ matrix.platform.shell }}
- name: Test
uses: ./source/.github/actions/run-build
with:
command: cd ${BUILD_WORKSPACE:-.}/build && ../source/ci/test.sh
container: ${{ matrix.platform.container.name }}
container-version: ${{ env.docker-registry-container-sha }}
shell: ${{ matrix.platform.shell }}
- name: Upload test results
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: test-results-${{ matrix.platform.id }}
path: build/results_*.xml
test_results:
name: Test results
needs: [ build ]
if: always()
runs-on: ubuntu-latest
steps:
- name: Download test results
uses: actions/download-artifact@v3
- name: Generate test summary
uses: test-summary/action@v2
with:
paths: 'test-results-*/*.xml'

View File

@ -11,66 +11,68 @@ on:
env:
docker-registry: ghcr.io
docker-config-path: source/ci/docker
docker-config-path: ci/docker
permissions:
contents: write
packages: write
jobs:
containers:
uses: ./.github/workflows/build-containers.yml
# Run our CI/CD builds. We build a matrix with the various build targets
# and their details. Then we build either in a docker container (Linux)
# or on the actual hosts (macOS, Windows).
build:
needs: [ containers ]
strategy:
matrix:
platform:
- name: "Linux (Xenial, GCC, OpenSSL)"
# All builds: core platforms
- name: "Linux (Noble, GCC, OpenSSL, libssh2)"
id: noble-gcc-openssl
os: ubuntu-latest
container:
name: noble
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=libssh2 -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON
- name: "Linux (Noble, Clang, mbedTLS, OpenSSH)"
id: noble-clang-mbedtls
os: ubuntu-latest
container:
name: noble
env:
CC: clang
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=exec
CMAKE_GENERATOR: Ninja
- name: "Linux (Xenial, GCC, OpenSSL, OpenSSH)"
id: xenial-gcc-openssl
os: ubuntu-latest
container:
name: xenial
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON
os: ubuntu-latest
- name: Linux (Xenial, GCC, mbedTLS)
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=exec -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON
- name: "Linux (Xenial, Clang, mbedTLS, libssh2)"
id: xenial-gcc-mbedtls
container:
name: xenial
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
os: ubuntu-latest
- name: "Linux (Xenial, Clang, OpenSSL)"
id: xenial-clang-openssl
container:
name: xenial
env:
CC: clang
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
os: ubuntu-latest
- name: "Linux (Xenial, Clang, mbedTLS)"
id: xenial-clang-mbedtls
container:
name: xenial
env:
CC: clang
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
os: ubuntu-latest
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=libssh2
- name: "macOS"
id: macos
os: macos-11
os: macos-12
setup-script: osx
env:
CC: clang
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON
CMAKE_GENERATOR: Ninja
PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
setup-script: osx
- name: "Windows (amd64, Visual Studio, Schannel)"
id: windows-amd64-vs
os: windows-2019
@ -120,13 +122,15 @@ jobs:
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
# Sanitizers
# All builds: sanitizers
- name: "Sanitizer (Memory)"
id: memorysanitizer
id: sanitizer-memory
os: ubuntu-latest
setup-script: sanitizer
container:
name: focal
name: noble
env:
CC: clang-10
CC: clang
CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
@ -134,13 +138,29 @@ jobs:
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
- name: "Sanitizer (Address)"
id: sanitizer-address
os: ubuntu-latest
- name: "Sanitizer (UndefinedBehavior)"
id: ubsanitizer
setup-script: sanitizer
container:
name: focal
name: noble
env:
CC: clang-10
CC: clang
CFLAGS: -fsanitize=address -ggdb -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
- name: "Sanitizer (UndefinedBehavior)"
id: sanitizer-ub
os: ubuntu-latest
setup-script: sanitizer
container:
name: noble
env:
CC: clang
CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
@ -148,13 +168,14 @@ jobs:
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
os: ubuntu-latest
- name: "Sanitizer (Thread)"
id: threadsanitizer
id: sanitizer-thread
os: ubuntu-latest
setup-script: sanitizer
container:
name: focal
name: noble
env:
CC: clang-10
CC: clang
CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
@ -163,44 +184,13 @@ jobs:
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1
os: ubuntu-latest
# Experimental: SHA256 support
- name: "Linux (SHA256, Xenial, Clang, OpenSSL)"
id: xenial-clang-openssl
container:
name: xenial
env:
CC: clang
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DEXPERIMENTAL_SHA256=ON
os: ubuntu-latest
- name: "macOS (SHA256)"
id: macos
os: macos-11
env:
CC: clang
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON -DEXPERIMENTAL_SHA256=ON
PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
setup-script: osx
- name: "Windows (SHA256, amd64, Visual Studio)"
id: windows-amd64-vs
os: windows-2019
env:
ARCH: amd64
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DEXPERIMENTAL_SHA256=ON
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
fail-fast: false
env: ${{ matrix.platform.env }}
runs-on: ${{ matrix.platform.os }}
name: "Build: ${{ matrix.platform.name }}"
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
@ -211,38 +201,33 @@ jobs:
- name: Setup QEMU
run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
if: matrix.platform.container.qemu == true
- name: Download container
run: |
"${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}"
env:
DOCKER_REGISTRY: ${{ env.docker-registry }}
GITHUB_TOKEN: ${{ secrets.github_token }}
working-directory: ${{ env.docker-config-path }}
- name: Set up container
uses: ./source/.github/actions/download-or-build-container
with:
registry: ${{ env.docker-registry }}
config-path: ${{ env.docker-config-path }}
container: ${{ matrix.platform.container.name }}
github_token: ${{ secrets.github_token }}
dockerfile: ${{ matrix.platform.container.dockerfile }}
if: matrix.platform.container.name != ''
- name: Create container
run: |
if [ "${{ matrix.container.base }}" != "" ]; then
BASE_ARG="--build-arg BASE=${{ matrix.container.base }}"
fi
docker build -t ${{ env.docker-registry-container-sha }} --build-arg UID=$(id -u) --build-arg GID=$(id -g) ${BASE_ARG} -f ${{ env.dockerfile }} .
working-directory: ${{ env.docker-config-path }}
if: matrix.platform.container.name != '' && env.docker-container-exists != 'true'
- name: Prepare build
run: mkdir build
- name: Build
uses: ./source/.github/actions/run-build
with:
command: cd build && ../source/ci/build.sh
command: cd ${BUILD_WORKSPACE:-.}/build && ../source/ci/build.sh
container: ${{ matrix.platform.container.name }}
container-version: ${{ env.docker-registry-container-sha }}
shell: ${{ matrix.platform.shell }}
- name: Test
uses: ./source/.github/actions/run-build
with:
command: cd build && ../source/ci/test.sh
command: cd ${BUILD_WORKSPACE:-.}/build && ../source/ci/test.sh
container: ${{ matrix.platform.container.name }}
container-version: ${{ env.docker-registry-container-sha }}
shell: ${{ matrix.platform.shell }}
- name: Upload test results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: test-results-${{ matrix.platform.id }}
@ -269,15 +254,22 @@ jobs:
# published to our documentation site.
documentation:
name: Generate documentation
needs: [ containers ]
if: success() || failure()
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
- name: Set up container
uses: ./source/.github/actions/download-or-build-container
with:
registry: ${{ env.docker-registry }}
config-path: ${{ env.docker-config-path }}
container: docurium
github_token: ${{ secrets.github_token }}
dockerfile: ${{ matrix.platform.container.dockerfile }}
- name: Generate documentation
working-directory: source
run: |
@ -293,7 +285,7 @@ jobs:
cm doc api.docurium
git checkout gh-pages
zip --exclude .git/\* --exclude .gitignore --exclude .gitattributes -r api-documentation.zip .
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifact
with:
name: api-documentation

View File

@ -8,7 +8,11 @@ on:
env:
docker-registry: ghcr.io
docker-config-path: source/ci/docker
docker-config-path: ci/docker
permissions:
contents: read
packages: write
jobs:
# Run our nightly builds. We build a matrix with the various build
@ -22,179 +26,80 @@ jobs:
strategy:
matrix:
platform:
- name: Linux (Xenial, GCC, OpenSSL)
# All builds: core platforms
- name: "Linux (Noble, GCC, OpenSSL, libssh2)"
id: noble-gcc-openssl
os: ubuntu-latest
container:
name: noble
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=libssh2 -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON
- name: "Linux (Noble, Clang, mbedTLS, OpenSSH)"
id: noble-clang-mbedtls
os: ubuntu-latest
container:
name: noble
env:
CC: clang
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=exec
CMAKE_GENERATOR: Ninja
- name: "Linux (Xenial, GCC, OpenSSL, OpenSSH)"
id: xenial-gcc-openssl
os: ubuntu-latest
container:
name: xenial
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=exec -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON
- name: "Linux (Xenial, Clang, mbedTLS, libssh2)"
id: xenial-gcc-mbedtls
os: ubuntu-latest
- name: "Linux (Xenial, GCC, mbedTLS)"
container:
name: xenial
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
os: ubuntu-latest
- name: "Linux (Xenial, Clang, OpenSSL)"
container:
name: xenial
env:
CC: clang
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
os: ubuntu-latest
- name: "Linux (Xenial, Clang, mbedTLS)"
container:
name: xenial
env:
CC: clang
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
os: ubuntu-latest
- name: "Linux (no threads)"
container:
name: xenial
env:
CC: gcc
CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
os: ubuntu-latest
- name: "Linux (dynamically-loaded OpenSSL)"
container:
name: xenial
env:
CC: clang
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
os: ubuntu-latest
- name: "Linux (MemorySanitizer)"
container:
name: focal
env:
CC: clang-10
CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
os: ubuntu-latest
- name: "Linux (UndefinedBehaviorSanitizer)"
container:
name: focal
env:
CC: clang-10
CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
os: ubuntu-latest
- name: "Linux (ThreadSanitizer)"
container:
name: focal
env:
CC: clang-10
CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1
os: ubuntu-latest
- name: "Linux (no mmap)"
container:
name: focal
env:
CC: clang-10
CFLAGS: -DNO_MMAP
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
os: ubuntu-latest
- name: "Linux (CentOS 7)"
container:
name: centos7
env:
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
os: ubuntu-latest
- name: "Linux (CentOS 7, dynamically-loaded OpenSSL)"
container:
name: centos7
env:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
os: ubuntu-latest
- name: "Linux (CentOS 8)"
container:
name: centos8
env:
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
SKIP_SSH_TESTS: true
os: ubuntu-latest
- name: "Linux (CentOS 8, dynamically-loaded OpenSSL)"
container:
name: centos8
env:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
SKIP_SSH_TESTS: true
os: ubuntu-latest
CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=libssh2
- name: "macOS"
os: macos-11
id: macos
os: macos-12
setup-script: osx
env:
CC: clang
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON
CMAKE_GENERATOR: Ninja
PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
setup-script: osx
- name: "Windows (amd64, Visual Studio, WinHTTP)"
- name: "Windows (amd64, Visual Studio, Schannel)"
id: windows-amd64-vs
os: windows-2019
setup-script: win32
env:
ARCH: amd64
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_HTTPS=WinHTTP
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_HTTPS=Schannel -DUSE_SSH=ON -DCMAKE_PREFIX_PATH=D:\Temp\libssh2
BUILD_PATH: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin;D:\Temp\libssh2\bin
BUILD_TEMP: D:\Temp
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (x86, Visual Studio, WinHTTP)"
id: windows-x86-vs
os: windows-2019
setup-script: win32
env:
ARCH: x86
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_HTTPS=WinHTTP -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (amd64, Visual Studio, Schannel)"
os: windows-2019
env:
ARCH: amd64
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_HTTPS=Schannel
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (x86, Visual Studio, Schannel)"
os: windows-2019
env:
ARCH: x86
CMAKE_GENERATOR: Visual Studio 16 2019
CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_HTTPS=Schannel -DUSE_BUNDLED_ZLIB=ON
CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON -DCMAKE_PREFIX_PATH=D:\Temp\libssh2
BUILD_PATH: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin;D:\Temp\libssh2\bin
BUILD_TEMP: D:\Temp
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (amd64, mingw, WinHTTP)"
id: windows-amd64-mingw
os: windows-2019
setup-script: mingw
env:
@ -206,6 +111,7 @@ jobs:
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (x86, mingw, Schannel)"
id: windows-x86-mingw
os: windows-2019
setup-script: mingw
env:
@ -216,16 +122,108 @@ jobs:
BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (no mmap)"
os: windows-2019
# All builds: sanitizers
- name: "Sanitizer (Memory)"
id: memorysanitizer
os: ubuntu-latest
setup-script: sanitizer
container:
name: noble
env:
ARCH: amd64
CMAKE_GENERATOR: Visual Studio 16 2019
CFLAGS: -DNO_MMAP
CMAKE_OPTIONS: -A x64 -DDEPRECATE_HARD=ON
CC: clang-17
CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
- name: "Sanitizer (UndefinedBehavior)"
id: ubsanitizer
os: ubuntu-latest
setup-script: sanitizer
container:
name: noble
env:
CC: clang-17
CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
- name: "Sanitizer (Thread)"
id: threadsanitizer
os: ubuntu-latest
setup-script: sanitizer
container:
name: noble
env:
CC: clang-17
CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10
UBSAN_OPTIONS: print_stacktrace=1
TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1
# Nightly builds: extended platforms
- name: "Linux (CentOS 7, OpenSSL)"
id: centos7-openssl
os: ubuntu-latest
container:
name: centos7
env:
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
- name: "Linux (CentOS 7, dynamically-loaded OpenSSL)"
id: centos7-dynamicopenssl
os: ubuntu-latest
container:
name: centos7
env:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
- name: "Linux (CentOS 8, OpenSSL)"
id: centos8-openssl
os: ubuntu-latest
container:
name: centos8
env:
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
SKIP_SSH_TESTS: true
- name: "Linux (CentOS 8, dynamically-loaded OpenSSL)"
id: centos8-dynamicopenssl
os: ubuntu-latest
container:
name: centos8
env:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
SKIP_NEGOTIATE_TESTS: true
SKIP_SSH_TESTS: true
ARCH: x86
- name: "Linux (Fedora, llhttp)"
id: fedora
os: ubuntu-latest
container:
name: fedora
env:
CC: gcc
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=pcre2 -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=libssh2 -DUSE_HTTP_PARSER=llhttp
- name: "Linux (Bionic, GCC, dynamically-loaded OpenSSL)"
id: bionic-gcc-dynamicopenssl
container:
name: bionic
dockerfile: bionic
@ -234,8 +232,10 @@ jobs:
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
RUN_INVASIVE_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
os: ubuntu-latest
- name: "Linux (x86, Bionic, Clang, OpenSSL)"
id: bionic-x86-clang-openssl
container:
name: bionic-x86
dockerfile: bionic
@ -245,8 +245,10 @@ jobs:
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
RUN_INVASIVE_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
os: ubuntu-latest
- name: "Linux (x86, Bionic, GCC, OpenSSL)"
id: bionic-x86-gcc-openssl
container:
name: bionic-x86
dockerfile: bionic
@ -255,8 +257,10 @@ jobs:
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
RUN_INVASIVE_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
os: ubuntu-latest
- name: "Linux (arm32, Bionic, GCC, OpenSSL)"
id: bionic-arm32-gcc-openssl
container:
name: bionic-arm32
dockerfile: bionic
@ -267,9 +271,11 @@ jobs:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON -DUSE_SSH=ON
RUN_INVASIVE_TESTS: true
SKIP_PROXY_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
GITTEST_FLAKY_STAT: true
os: ubuntu-latest
- name: "Linux (arm64, Bionic, GCC, OpenSSL)"
id: bionic-arm64-gcc-openssl
container:
name: bionic-arm64
dockerfile: bionic
@ -280,11 +286,57 @@ jobs:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON -DUSE_SSH=ON
RUN_INVASIVE_TESTS: true
SKIP_PROXY_TESTS: true
SKIP_PUSHOPTIONS_TESTS: true
os: ubuntu-latest
# Experimental: SHA256 support
# Nightly builds: ensure we fallback when missing core functionality
- name: "Linux (no threads)"
id: xenial-nothreads
os: ubuntu-latest
container:
name: xenial
env:
CC: gcc
CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
SKIP_PUSHOPTIONS_TESTS: true
- name: "Linux (no mmap)"
id: noble-nommap
os: ubuntu-latest
container:
name: noble
env:
CC: gcc
CFLAGS: -DNO_MMAP
CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local
CMAKE_GENERATOR: Ninja
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
- name: "Windows (no mmap)"
id: windows-nommap
os: windows-2019
env:
ARCH: amd64
CMAKE_GENERATOR: Visual Studio 16 2019
CFLAGS: -DNO_MMAP
CMAKE_OPTIONS: -A x64 -DDEPRECATE_HARD=ON
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
# Nightly builds: extended SSL support
- name: "Linux (dynamically-loaded OpenSSL)"
id: xenial-dynamicopenssl
os: ubuntu-latest
container:
name: xenial
env:
CC: clang
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
CMAKE_GENERATOR: Ninja
# All builds: experimental SHA256 support
- name: "Linux (SHA256, Xenial, Clang, OpenSSL)"
id: xenial-clang-openssl
id: linux-sha256
container:
name: xenial
env:
@ -293,17 +345,17 @@ jobs:
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON
os: ubuntu-latest
- name: "macOS (SHA256)"
id: macos
os: macos-10.15
id: macos-sha256
os: macos-12
setup-script: osx
env:
CC: clang
CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON -DEXPERIMENTAL_SHA256=ON
PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig
SKIP_SSH_TESTS: true
SKIP_NEGOTIATE_TESTS: true
setup-script: osx
- name: "Windows (SHA256, amd64, Visual Studio)"
id: windows-amd64-vs
id: windows-sha256
os: windows-2019
env:
ARCH: amd64
@ -317,7 +369,7 @@ jobs:
name: "Build ${{ matrix.platform.name }}"
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
@ -328,32 +380,50 @@ jobs:
- name: Setup QEMU
run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
if: matrix.platform.container.qemu == true
- name: Download container
run: |
"${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}"
env:
DOCKER_REGISTRY: ${{ env.docker-registry }}
GITHUB_TOKEN: ${{ secrets.github_token }}
working-directory: ${{ env.docker-config-path }}
- name: Set up container
uses: ./source/.github/actions/download-or-build-container
with:
registry: ${{ env.docker-registry }}
config-path: ${{ env.docker-config-path }}
container: ${{ matrix.platform.container.name }}
github_token: ${{ secrets.github_token }}
dockerfile: ${{ matrix.platform.container.dockerfile }}
if: matrix.platform.container.name != ''
- name: Create container
run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ env.dockerfile }} .
working-directory: ${{ env.docker-config-path }}
if: matrix.platform.container.name != '' && env.docker-container-exists != 'true'
- name: Prepare build
run: mkdir build
- name: Build
uses: ./source/.github/actions/run-build
with:
command: cd build && ../source/ci/build.sh
command: cd ${BUILD_WORKSPACE:-.}/build && ../source/ci/build.sh
container: ${{ matrix.platform.container.name }}
container-version: ${{ env.docker-registry-container-sha }}
shell: ${{ matrix.platform.shell }}
- name: Test
uses: ./source/.github/actions/run-build
with:
command: cd build && ../source/ci/test.sh
command: cd ${BUILD_WORKSPACE:-.}/build && ../source/ci/test.sh
container: ${{ matrix.platform.container.name }}
container-version: ${{ env.docker-registry-container-sha }}
shell: ${{ matrix.platform.shell }}
- name: Upload test results
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: test-results-${{ matrix.platform.id }}
path: build/results_*.xml
test_results:
name: Test results
needs: [ build ]
if: ${{ always() && github.repository == 'libgit2/libgit2' }}
runs-on: ubuntu-latest
steps:
- name: Download test results
uses: actions/download-artifact@v3
- name: Generate test summary
uses: test-summary/action@v2
with:
paths: 'test-results-*/*.xml'
coverity:
# Only run scheduled workflows on the main repository; prevents people
@ -364,17 +434,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: source
fetch-depth: 0
- name: Download container
run: |
"${{ github.workspace }}/source/ci/getcontainer.sh" xenial
env:
DOCKER_REGISTRY: ${{ env.docker-registry }}
GITHUB_TOKEN: ${{ secrets.github_token }}
working-directory: ${{ env.docker-config-path }}
- name: Set up container
uses: ./source/.github/actions/download-or-build-container
with:
registry: ${{ env.docker-registry }}
config-path: ${{ env.docker-config-path }}
container: xenial
github_token: ${{ secrets.github_token }}
if: matrix.platform.container.name != ''
- name: Run Coverity
run: source/ci/coverity.sh
env:
@ -385,11 +456,16 @@ jobs:
# from using build minutes on their forks.
if: github.repository == 'libgit2/libgit2'
permissions:
actions: read
contents: read
security-events: write
name: CodeQL
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

View File

@ -6,7 +6,7 @@
cmake_minimum_required(VERSION 3.5.1)
project(libgit2 VERSION "1.7.2" LANGUAGES C)
project(libgit2 VERSION "1.8.1" LANGUAGES C)
# Add find modules to the path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
@ -30,7 +30,7 @@ option(USE_THREADS "Use threads for parallel processing when possibl
option(USE_NSEC "Support nanosecond precision file mtimes and ctimes" ON)
# Backend selection
option(USE_SSH "Link with libssh2 to enable SSH support" OFF)
option(USE_SSH "Enable SSH support. Can be set to a specific backend" OFF)
option(USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON)
option(USE_SHA1 "Enable SHA1. Can be set to CollisionDetection(ON)/HTTPS" ON)
option(USE_SHA256 "Enable SHA256. Can be set to HTTPS/Builtin" ON)

196
COPYING
View File

@ -365,7 +365,7 @@ Public License instead of this License.
The bundled ZLib code is licensed under the ZLib license:
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
(C) 1995-2022 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -1214,3 +1214,197 @@ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
----------------------------------------------------------------------
The bundled ntlmclient code is licensed under the MIT license:
Copyright (c) Edward Thomson. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Portions of this software derived from Team Explorer Everywhere:
Copyright (c) Microsoft Corporation
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------------------------
Portions of this software derived from the LLVM Compiler Infrastructure:
Copyright (c) 2003-2016 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
---------------------------------------------------------------------------
Portions of this software derived from Unicode, Inc:
Copyright 2001-2004 Unicode, Inc.
Disclaimer
This source code is provided as is by Unicode, Inc. No claims are
made as to fitness for any particular purpose. No warranties of any
kind are expressed or implied. The recipient agrees to determine
applicability of information provided. If this file has been
purchased on magnetic or optical media from Unicode, Inc., the
sole remedy for any claim will be exchange of defective media
within 90 days of receipt.
Limitations on Rights to Redistribute This Code
Unicode, Inc. hereby grants the right to freely use the information
supplied in this file in the creation of products supporting the
Unicode Standard, and to make copies of this file in any form
for internal or external distribution as long as this notice
remains attached.
---------------------------------------------------------------------------
Portions of this software derived from sheredom/utf8.h:
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
---------------------------------------------------------------------------
Portions of this software derived from RFC 1320:
Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD4 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD4 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
----------------------------------------------------------------------
The bundled llhttp dependency is licensed under the MIT license:
Copyright Fedor Indutny, 2018.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -4,8 +4,8 @@ libgit2 - the Git linkable library
| Build Status | |
| ------------ | - |
| **main** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) |
| **v1.8 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.8&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.8) |
| **v1.7 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.7&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.7) |
| **v1.6 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.6&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.6) |
| **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan 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
@ -18,7 +18,7 @@ functionality into your application. Language bindings like
in your favorite language.
`libgit2` is used to power Git GUI clients like
[GitKraken](https://gitkraken.com/) and [gmaster](https://gmaster.io/)
[GitKraken](https://gitkraken.com/) and [GitButler](https://gitbutler.com/)
and on Git hosting providers like [GitHub](https://github.com/),
[GitLab](https://gitlab.com/) and
[Azure DevOps](https://azure.com/devops).
@ -68,7 +68,7 @@ But if you _do_ want to use libgit2 directly - because you're building
an application in C - then you may be able use an existing binary.
There are packages for the
[vcpkg](https://github.com/Microsoft/vcpkg) and
[conan](https://conan.io/center/libgit2)
[conan](https://conan.io/center/recipes/libgit2)
package managers. And libgit2 is available in
[Homebrew](https://formulae.brew.sh/formula/libgit2) and most Linux
distributions.
@ -113,7 +113,7 @@ Getting Help
**Getting Help**
If you have questions about the library, please be sure to check out the
[API documentation](http://libgit2.github.com/libgit2/). If you still have
[API documentation](https://libgit2.org/libgit2/). If you still have
questions, reach out to us on Slack or post a question on
[StackOverflow](http://stackoverflow.com/questions/tagged/libgit2) (with the `libgit2` tag).

View File

@ -61,6 +61,8 @@ if test -n "${CC}"; then
"${CC}" --version 2>&1 | indent
fi
echo "Environment:"
echo "PATH=${BUILD_PATH}" | indent
if test -n "${CC}"; then
echo "CC=${CC}" | indent
fi

View File

@ -12,7 +12,6 @@ RUN apt-get update && \
libcurl4-openssl-dev \
libkrb5-dev \
libpcre3-dev \
libssh2-1-dev \
libssl-dev \
libz-dev \
ninja-build \
@ -37,7 +36,16 @@ RUN cd /tmp && \
cd .. && \
rm -rf mbedtls-mbedtls-2.16.2
FROM mbedtls AS adduser
FROM mbedtls AS libssh2
RUN cd /tmp && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.11.0.tar.gz | tar -xz && \
cd libssh2-1.11.0 && \
CFLAGS=-fPIC cmake -G Ninja -DBUILD_SHARED_LIBS=ON . && \
ninja install && \
cd .. && \
rm -rf libssh2-1.11.0
FROM libssh2 AS adduser
ARG UID=""
ARG GID=""
RUN if [ "${UID}" != "" ]; then USER_ARG="--uid ${UID}"; fi && \

View File

@ -18,13 +18,13 @@ RUN yum install -y \
FROM yum AS libssh2
RUN cd /tmp && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \
cd libssh2-1.8.0 && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.11.0.tar.gz | tar -xz && \
cd libssh2-1.11.0 && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf libssh-1.8.0
rm -rf libssh-1.11.0
FROM libssh2 AS valgrind
RUN cd /tmp && \

View File

@ -24,13 +24,13 @@ RUN yum install -y \
FROM yum AS libssh2
RUN cd /tmp && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \
cd libssh2-1.8.0 && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.11.0.tar.gz | tar -xz && \
cd libssh2-1.11.0 && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf libssh2-1.8.0
rm -rf libssh2-1.11.0
FROM libssh2 AS valgrind
RUN cd /tmp && \

52
ci/docker/fedora Normal file
View File

@ -0,0 +1,52 @@
ARG BASE=fedora:rawhide
FROM ${BASE} AS stream
RUN dnf -y distro-sync
FROM stream AS yum
RUN yum install -y \
which \
bzip2 \
git \
libarchive \
cmake \
gcc \
make \
openssl-devel \
openssh-server \
git-daemon \
java-1.8.0-openjdk-headless \
sudo \
python3 \
valgrind \
krb5-workstation \
krb5-libs \
krb5-devel \
pcre2-devel \
zlib-devel \
ninja-build \
llhttp-devel
FROM yum AS libssh2
RUN cd /tmp && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.11.0.tar.gz | tar -xz && \
cd libssh2-1.11.0 && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf libssh2-1.11.0
FROM libssh2 AS adduser
ARG UID=""
ARG GID=""
RUN if [ "${UID}" != "" ]; then USER_ARG="--uid ${UID}"; fi && \
if [ "${GID}" != "" ]; then GROUP_ARG="--gid ${GID}"; fi && \
groupadd ${GROUP_ARG} libgit2 && \
useradd ${USER_ARG} --gid libgit2 --shell /bin/bash --create-home libgit2
FROM adduser AS configure
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig
RUN mkdir /var/run/sshd
RUN echo "/usr/local/lib" > /etc/ld.so.conf.d/local && \
ldconfig

View File

@ -53,7 +53,7 @@ RUN cd /tmp && \
cd libssh2-1.9.0 && \
mkdir build build-msan && \
cd build && \
CC=clang-10 CFLAGS="-fPIC" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=Libgcrypt -DCMAKE_PREFIX_PATH=/usr/local -DCMAKE_INSTALL_PREFIX=/usr/local .. && \
CC=clang-10 CFLAGS="-fPIC" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCMAKE_PREFIX_PATH=/usr/local -DCMAKE_INSTALL_PREFIX=/usr/local .. && \
ninja install && \
cd ../build-msan && \
CC=clang-10 CFLAGS="-fPIC -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer" LDFLAGS="-fsanitize=memory" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=mbedTLS -DCMAKE_PREFIX_PATH=/usr/local/msan -DCMAKE_INSTALL_PREFIX=/usr/local/msan .. && \

88
ci/docker/noble Normal file
View File

@ -0,0 +1,88 @@
ARG BASE=ubuntu:noble
FROM ${BASE} AS apt
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
bzip2 \
clang \
cmake \
curl \
gcc \
git \
krb5-user \
libclang-rt-17-dev \
libcurl4-gnutls-dev \
libgcrypt20-dev \
libkrb5-dev \
libpcre3-dev \
libssl-dev \
libz-dev \
llvm-17 \
make \
ninja-build \
openjdk-8-jre-headless \
openssh-server \
openssl \
pkgconf \
python3 \
sudo \
valgrind \
&& \
rm -rf /var/lib/apt/lists/* && \
mkdir /usr/local/msan
FROM apt AS mbedtls
RUN cd /tmp && \
curl --location --silent --show-error https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/mbedtls-2.28.6.tar.gz | \
tar -xz && \
cd mbedtls-mbedtls-2.28.6 && \
scripts/config.pl unset MBEDTLS_AESNI_C && \
scripts/config.pl set MBEDTLS_MD4_C 1 && \
mkdir build build-msan && \
cd build && \
CC=clang-17 CFLAGS="-fPIC" cmake -G Ninja -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -DUSE_SHARED_MBEDTLS_LIBRARY=ON -DUSE_STATIC_MBEDTLS_LIBRARY=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/usr/local -DCMAKE_INSTALL_PREFIX=/usr/local .. && \
ninja install && \
cd ../build-msan && \
CC=clang-17 CFLAGS="-fPIC" cmake -G Ninja -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -DUSE_SHARED_MBEDTLS_LIBRARY=ON -DUSE_STATIC_MBEDTLS_LIBRARY=OFF -DCMAKE_BUILD_TYPE=MemSanDbg -DCMAKE_INSTALL_PREFIX=/usr/local/msan .. && \
ninja install && \
cd .. && \
rm -rf mbedtls-mbedtls-2.28.6
FROM mbedtls AS libssh2
RUN cd /tmp && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.11.0.tar.gz | tar -xz && \
cd libssh2-1.11.0 && \
mkdir build build-msan && \
cd build && \
CC=clang-17 CFLAGS="-fPIC" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCMAKE_PREFIX_PATH=/usr/local -DCMAKE_INSTALL_PREFIX=/usr/local .. && \
ninja install && \
cd ../build-msan && \
CC=clang-17 CFLAGS="-fPIC -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer" LDFLAGS="-fsanitize=memory" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=mbedTLS -DCMAKE_PREFIX_PATH=/usr/local/msan -DCMAKE_INSTALL_PREFIX=/usr/local/msan .. && \
ninja install && \
cd .. && \
rm -rf libssh2-1.11.0
FROM libssh2 AS valgrind
RUN cd /tmp && \
curl --insecure --location --silent --show-error https://sourceware.org/pub/valgrind/valgrind-3.22.0.tar.bz2 | \
tar -xj && \
cd valgrind-3.22.0 && \
CC=clang-17 ./configure && \
make MAKEFLAGS="-j -l$(grep -c ^processor /proc/cpuinfo)" && \
make install && \
cd .. && \
rm -rf valgrind-3.22.0
FROM valgrind AS adduser
ARG UID=""
ARG GID=""
RUN if [ "${UID}" != "" ]; then USER_ARG="--uid ${UID}"; fi && \
if [ "${GID}" != "" ]; then GROUP_ARG="--gid ${GID}"; fi && \
groupadd ${GROUP_ARG} libgit2 && \
useradd ${USER_ARG} --gid libgit2 --shell /bin/bash --create-home libgit2
FROM adduser AS ldconfig
RUN ldconfig
FROM ldconfig AS configure
RUN mkdir /var/run/sshd

View File

@ -53,12 +53,12 @@ RUN cd /tmp && \
FROM mbedtls AS libssh2
RUN cd /tmp && \
curl --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 . && \
curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.11.0.tar.gz | tar -xz && \
cd libssh2-1.11.0 && \
CFLAGS=-fPIC cmake -G Ninja -DBUILD_SHARED_LIBS=ON . && \
ninja install && \
cd .. && \
rm -rf libssh2-1.8.2
rm -rf libssh2-1.11.0
FROM libssh2 AS valgrind
RUN cd /tmp && \

View File

@ -1,55 +0,0 @@
#!/bin/bash
set -e
IMAGE_NAME=$1
DOCKERFILE_PATH=$2
if [ "${IMAGE_NAME}" = "" ]; then
echo "usage: $0 image_name [dockerfile]"
exit 1
fi
if [ "${DOCKERFILE_PATH}" = "" ]; then
DOCKERFILE_PATH="${IMAGE_NAME}"
fi
if [ "${DOCKER_REGISTRY}" = "" ]; then
echo "DOCKER_REGISTRY environment variable is unset."
echo "Not running inside GitHub Actions or misconfigured?"
exit 1
fi
DOCKER_CONTAINER="${GITHUB_REPOSITORY}/${IMAGE_NAME}"
DOCKER_REGISTRY_CONTAINER="${DOCKER_REGISTRY}/${DOCKER_CONTAINER}"
echo "dockerfile=${DOCKERFILE_PATH}" >> $GITHUB_ENV
echo "docker-container=${DOCKER_CONTAINER}" >> $GITHUB_ENV
echo "docker-registry-container=${DOCKER_REGISTRY_CONTAINER}" >> $GITHUB_ENV
# Identify the last git commit that touched the Dockerfiles
# Use this as a hash to identify the resulting docker containers
DOCKER_SHA=$(git log -1 --pretty=format:"%h" -- "${DOCKERFILE_PATH}")
echo "docker-sha=${DOCKER_SHA}" >> $GITHUB_ENV
DOCKER_REGISTRY_CONTAINER_SHA="${DOCKER_REGISTRY_CONTAINER}:${DOCKER_SHA}"
echo "docker-registry-container-sha=${DOCKER_REGISTRY_CONTAINER_SHA}" >> $GITHUB_ENV
echo "docker-registry-container-latest=${DOCKER_REGISTRY_CONTAINER}:latest" >> $GITHUB_ENV
echo "::: logging in to ${DOCKER_REGISTRY} as ${GITHUB_ACTOR}"
exists="true"
docker login https://${DOCKER_REGISTRY} -u ${GITHUB_ACTOR} -p ${GITHUB_TOKEN} || exists="false"
echo "::: pulling ${DOCKER_REGISTRY_CONTAINER_SHA}"
if [ "${exists}" != "false" ]; then
docker pull ${DOCKER_REGISTRY_CONTAINER_SHA} || exists="false"
fi
if [ "${exists}" = "true" ]; then
echo "docker-container-exists=true" >> $GITHUB_ENV
else
echo "docker-container-exists=false" >> $GITHUB_ENV
fi

View File

@ -3,6 +3,6 @@
set -ex
brew update
brew install pkgconfig zlib curl openssl libssh2 ninja
brew install pkgconfig libssh2 ninja
ln -s /Applications/Xcode.app/Contents/Developer/usr/lib/libLeaksAtExit.dylib /usr/local/lib

7
ci/setup-sanitizer-build.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
set -ex
# Linux updated its ASLR randomization in a way that is incompatible with
# TSAN. See https://github.com/google/sanitizers/issues/1716
sudo sysctl vm.mmap_rnd_bits=28

View File

@ -3,7 +3,14 @@
set -e
if [ -n "$SKIP_TESTS" ]; then
exit 0
if [ -z "$SKIP_OFFLINE_TESTS" ]; then SKIP_OFFLINE_TESTS=1; fi
if [ -z "$SKIP_ONLINE_TESTS" ]; then SKIP_ONLINE_TESTS=1; fi
if [ -z "$SKIP_GITDAEMON_TESTS" ]; then SKIP_GITDAEMON_TESTS=1; fi
if [ -z "$SKIP_PROXY_TESTS" ]; then SKIP_PROXY_TESTS=1; fi
if [ -z "$SKIP_NTLM_TESTS" ]; then SKIP_NTLM_TESTS=1; fi
if [ -z "$SKIP_NEGOTIATE_TESTS" ]; then SKIP_NEGOTIATE_TESTS=1; fi
if [ -z "$SKIP_SSH_TESTS" ]; then SKIP_SSH_TESTS=1; fi
if [ -z "$SKIP_FUZZERS" ]; then SKIP_FUZZERS=1; fi
fi
# Windows doesn't run the NTLM tests properly (yet)
@ -11,6 +18,11 @@ if [[ "$(uname -s)" == MINGW* ]]; then
SKIP_NTLM_TESTS=1
fi
# older versions of git don't support push options
if [ -z "$SKIP_PUSHOPTIONS_TESTS" ]; then
export GITTEST_PUSH_OPTIONS=true
fi
SOURCE_DIR=${SOURCE_DIR:-$( cd "$( dirname "${BASH_SOURCE[0]}" )" && dirname $( pwd ) )}
BUILD_DIR=$(pwd)
BUILD_PATH=${BUILD_PATH:=$PATH}
@ -18,12 +30,24 @@ CTEST=$(which ctest)
TMPDIR=${TMPDIR:-/tmp}
USER=${USER:-$(whoami)}
GITTEST_SSH_KEYTYPE=${GITTEST_SSH_KEYTYPE:="ecdsa"}
HOME=`mktemp -d ${TMPDIR}/home.XXXXXXXX`
export CLAR_HOMEDIR=${HOME}
SUCCESS=1
CONTINUE_ON_FAILURE=0
should_run() {
eval "skip=\${SKIP_${1}}"
[ -z "$skip" \
-o "$skip" == "no" -o "$skip" == "NO" \
-o "$skip" == "n" -o "$skip" == "N" \
-o "$skip" == "false" -o "$skip" == "FALSE" \
-o "$skip" == "f" -o "$skip" == "F" \
-o "$skip" == "0" ]
}
cleanup() {
echo "Cleaning up..."
@ -78,6 +102,8 @@ run_test() {
echo ""
echo "Re-running flaky ${1} tests..."
echo ""
sleep 2
fi
RETURN_CODE=0
@ -138,11 +164,12 @@ echo "##########################################################################
echo ""
if [ -z "$SKIP_GITDAEMON_TESTS" ]; then
if should_run "GITDAEMON_TESTS"; then
echo "Starting git daemon (standard)..."
GIT_STANDARD_DIR=`mktemp -d ${TMPDIR}/git_standard.XXXXXXXX`
git init --bare "${GIT_STANDARD_DIR}/test.git" >/dev/null
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${GIT_STANDARD_DIR}/test.git"
git daemon --listen=localhost --export-all --enable=receive-pack --base-path="${GIT_STANDARD_DIR}" "${GIT_STANDARD_DIR}" 2>/dev/null &
GIT_STANDARD_PID=$!
echo "Starting git daemon (namespace)..."
@ -158,7 +185,7 @@ if [ -z "$SKIP_GITDAEMON_TESTS" ]; then
GIT_SHA256_PID=$!
fi
if [ -z "$SKIP_PROXY_TESTS" ]; then
if should_run "PROXY_TESTS"; then
curl --location --silent --show-error https://github.com/ethomson/poxyproxy/releases/download/v0.7.0/poxyproxy-0.7.0.jar >poxyproxy.jar
echo "Starting HTTP proxy (Basic)..."
@ -170,25 +197,27 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
PROXY_NTLM_PID=$!
fi
if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then
if should_run "NTLM_TESTS" || should_run "ONLINE_TESTS"; then
curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.6.0/poxygit-0.6.0.jar >poxygit.jar
echo "Starting HTTP server..."
HTTP_DIR=`mktemp -d ${TMPDIR}/http.XXXXXXXX`
git init --bare "${HTTP_DIR}/test.git"
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${HTTP_DIR}/test.git"
java -jar poxygit.jar --address 127.0.0.1 --port 9000 --credentials foo:baz --quiet "${HTTP_DIR}" &
HTTP_PID=$!
fi
if [ -z "$SKIP_SSH_TESTS" ]; then
if should_run "SSH_TESTS"; then
echo "Starting SSH server..."
SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX`
git init --bare "${SSHD_DIR}/test.git" >/dev/null
cp -R "${SOURCE_DIR}/tests/resources/pushoptions.git" "${SSHD_DIR}/test.git"
cat >"${SSHD_DIR}/sshd_config" <<-EOF
Port 2222
ListenAddress 0.0.0.0
Protocol 2
HostKey ${SSHD_DIR}/id_rsa
HostKey ${SSHD_DIR}/id_${GITTEST_SSH_KEYTYPE}
PidFile ${SSHD_DIR}/pid
AuthorizedKeysFile ${HOME}/.ssh/authorized_keys
LogLevel DEBUG
@ -197,19 +226,21 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
PubkeyAuthentication yes
ChallengeResponseAuthentication no
StrictModes no
HostCertificate ${SSHD_DIR}/id_${GITTEST_SSH_KEYTYPE}.pub
HostKey ${SSHD_DIR}/id_${GITTEST_SSH_KEYTYPE}
# Required here as sshd will simply close connection otherwise
UsePAM no
EOF
ssh-keygen -t rsa -f "${SSHD_DIR}/id_rsa" -N "" -q
ssh-keygen -t "${GITTEST_SSH_KEYTYPE}" -f "${SSHD_DIR}/id_${GITTEST_SSH_KEYTYPE}" -N "" -q
/usr/sbin/sshd -f "${SSHD_DIR}/sshd_config" -E "${SSHD_DIR}/log"
# Set up keys
mkdir "${HOME}/.ssh"
ssh-keygen -t rsa -f "${HOME}/.ssh/id_rsa" -N "" -q
cat "${HOME}/.ssh/id_rsa.pub" >>"${HOME}/.ssh/authorized_keys"
ssh-keygen -t "${GITTEST_SSH_KEYTYPE}" -f "${HOME}/.ssh/id_${GITTEST_SSH_KEYTYPE}" -N "" -q
cat "${HOME}/.ssh/id_${GITTEST_SSH_KEYTYPE}.pub" >>"${HOME}/.ssh/authorized_keys"
while read algorithm key comment; do
echo "[localhost]:2222 $algorithm $key" >>"${HOME}/.ssh/known_hosts"
done <"${SSHD_DIR}/id_rsa.pub"
done <"${SSHD_DIR}/id_${GITTEST_SSH_KEYTYPE}.pub"
# Append the github.com keys for the tests that don't override checks.
# We ask for ssh-rsa to test that the selection based off of known_hosts
@ -228,7 +259,7 @@ fi
# Run the tests that do not require network connectivity.
if [ -z "$SKIP_OFFLINE_TESTS" ]; then
if should_run "OFFLINE_TESTS"; then
echo ""
echo "##############################################################################"
echo "## Running core tests"
@ -259,7 +290,11 @@ if [ -n "$RUN_INVASIVE_TESTS" ]; then
unset GITTEST_INVASIVE_SPEED
fi
if [ -z "$SKIP_ONLINE_TESTS" ]; then
# the various network tests can fail due to network connectivity problems;
# allow them to retry up to 5 times
export GITTEST_FLAKY_RETRY=5
if should_run "ONLINE_TESTS"; then
# Run the online tests. The "online" test suite only includes the
# default online tests that do not require additional configuration.
# The "proxy" and "ssh" test suites require further setup.
@ -288,7 +323,7 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then
run_test online_customcert
fi
if [ -z "$SKIP_GITDAEMON_TESTS" ]; then
if should_run "GITDAEMON_TESTS"; then
echo ""
echo "Running gitdaemon (standard) tests"
echo ""
@ -316,7 +351,7 @@ if [ -z "$SKIP_GITDAEMON_TESTS" ]; then
unset GITTEST_REMOTE_URL
fi
if [ -z "$SKIP_PROXY_TESTS" ]; then
if should_run "PROXY_TESTS"; then
echo ""
echo "Running proxy tests (Basic authentication)"
echo ""
@ -342,7 +377,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
unset GITTEST_REMOTE_PROXY_PASS
fi
if [ -z "$SKIP_NTLM_TESTS" ]; then
if should_run "NTLM_TESTS"; then
echo ""
echo "Running NTLM tests (IIS emulation)"
echo ""
@ -368,7 +403,7 @@ if [ -z "$SKIP_NTLM_TESTS" ]; then
unset GITTEST_REMOTE_PASS
fi
if [ -z "$SKIP_NEGOTIATE_TESTS" -a -n "$GITTEST_NEGOTIATE_PASSWORD" ]; then
if should_run "NEGOTIATE_TESTS" && -n "$GITTEST_NEGOTIATE_PASSWORD" ; then
echo ""
echo "Running SPNEGO tests"
echo ""
@ -401,13 +436,15 @@ if [ -z "$SKIP_NEGOTIATE_TESTS" -a -n "$GITTEST_NEGOTIATE_PASSWORD" ]; then
kdestroy -A
fi
if [ -z "$SKIP_SSH_TESTS" ]; then
if should_run "SSH_TESTS"; then
export GITTEST_REMOTE_USER=$USER
export GITTEST_REMOTE_SSH_KEY="${HOME}/.ssh/id_rsa"
export GITTEST_REMOTE_SSH_PUBKEY="${HOME}/.ssh/id_rsa.pub"
export GITTEST_REMOTE_SSH_KEY="${HOME}/.ssh/id_${GITTEST_SSH_KEYTYPE}"
export GITTEST_REMOTE_SSH_PUBKEY="${HOME}/.ssh/id_${GITTEST_SSH_KEYTYPE}.pub"
export GITTEST_REMOTE_SSH_PASSPHRASE=""
export GITTEST_REMOTE_SSH_FINGERPRINT="${SSH_FINGERPRINT}"
export GITTEST_SSH_CMD="ssh -i ${HOME}/.ssh/id_${GITTEST_SSH_KEYTYPE} -o UserKnownHostsFile=${HOME}/.ssh/known_hosts"
echo ""
echo "Running ssh tests"
echo ""
@ -424,6 +461,8 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
run_test ssh
unset GITTEST_REMOTE_URL
unset GITTEST_SSH_CMD
unset GITTEST_REMOTE_USER
unset GITTEST_REMOTE_SSH_KEY
unset GITTEST_REMOTE_SSH_PUBKEY
@ -431,7 +470,9 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
unset GITTEST_REMOTE_SSH_FINGERPRINT
fi
if [ -z "$SKIP_FUZZERS" ]; then
unset GITTEST_FLAKY_RETRY
if should_run "FUZZERS"; then
echo ""
echo "##############################################################################"
echo "## Running fuzzers"

39
cmake/FindLLHTTP.cmake Normal file
View File

@ -0,0 +1,39 @@
# - Try to find llhttp
#
# Defines the following variables:
#
# LLHTTP_FOUND - system has llhttp
# LLHTTP_INCLUDE_DIR - the llhttp include directory
# LLHTTP_LIBRARIES - Link these to use llhttp
# LLHTTP_VERSION_MAJOR - major version
# LLHTTP_VERSION_MINOR - minor version
# LLHTTP_VERSION_STRING - the version of llhttp found
# Find the header and library
find_path(LLHTTP_INCLUDE_DIR NAMES llhttp.h)
find_library(LLHTTP_LIBRARY NAMES llhttp libllhttp)
# Found the header, read version
if(LLHTTP_INCLUDE_DIR AND EXISTS "${LLHTTP_INCLUDE_DIR}/llhttp.h")
file(READ "${LLHTTP_INCLUDE_DIR}/llhttp.h" LLHTTP_H)
if(LLHTTP_H)
string(REGEX REPLACE ".*#define[\t ]+LLHTTP_VERSION_MAJOR[\t ]+([0-9]+).*" "\\1" LLHTTP_VERSION_MAJOR "${LLHTTP_H}")
string(REGEX REPLACE ".*#define[\t ]+LLHTTP_VERSION_MINOR[\t ]+([0-9]+).*" "\\1" LLHTTP_VERSION_MINOR "${LLHTTP_H}")
set(LLHTTP_VERSION_STRING "${LLHTTP_VERSION_MAJOR}.${LLHTTP_VERSION_MINOR}")
endif()
unset(LLHTTP_H)
endif()
# Handle the QUIETLY and REQUIRED arguments and set LLHTTP_FOUND
# to TRUE if all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLHTTP REQUIRED_VARS LLHTTP_INCLUDE_DIR LLHTTP_LIBRARY)
# Hide advanced variables
mark_as_advanced(LLHTTP_INCLUDE_DIR LLHTTP_LIBRARY)
# Set standard variables
if(LLHTTP_FOUND)
set(LLHTTP_LIBRARIES ${LLHTTP_LIBRARY})
set(LLHTTP_INCLUDE_DIRS ${LLHTTP_INCLUDE_DIR})
endif()

View File

@ -1,19 +1,32 @@
# Optional external dependency: http-parser
if(USE_HTTP_PARSER STREQUAL "system")
if(USE_HTTP_PARSER STREQUAL "http-parser")
find_package(HTTPParser)
if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS})
list(APPEND LIBGIT2_SYSTEM_LIBS ${HTTP_PARSER_LIBRARIES})
list(APPEND LIBGIT2_PC_LIBS "-lhttp_parser")
add_feature_info(http-parser ON "http-parser support (system)")
set(GIT_HTTPPARSER_HTTPPARSER 1)
add_feature_info(http-parser ON "using http-parser (system)")
else()
message(FATAL_ERROR "http-parser support was requested but not found")
endif()
elseif(USE_HTTP_PARSER STREQUAL "llhttp")
find_package(LLHTTP)
if(LLHTTP_FOUND AND LLHTTP_VERSION_MAJOR EQUAL 9)
list(APPEND LIBGIT2_SYSTEM_INCLUDES ${LLHTTP_INCLUDE_DIRS})
list(APPEND LIBGIT2_SYSTEM_LIBS ${LLHTTP_LIBRARIES})
list(APPEND LIBGIT2_PC_LIBS "-lllhttp")
set(GIT_HTTPPARSER_LLHTTP 1)
add_feature_info(http-parser ON "using llhttp (system)")
else()
message(FATAL_ERROR "llhttp support was requested but not found")
endif()
else()
message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.")
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/http-parser" "${PROJECT_BINARY_DIR}/deps/http-parser")
list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/http-parser")
list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$<TARGET_OBJECTS:http-parser>")
add_feature_info(http-parser ON "http-parser support (bundled)")
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/llhttp" "${PROJECT_BINARY_DIR}/deps/llhttp")
list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/llhttp")
list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$<TARGET_OBJECTS:llhttp>")
set(GIT_HTTPPARSER_BUILTIN 1)
add_feature_info(http-parser ON "using bundled parser")
endif()

View File

@ -55,6 +55,10 @@ if(USE_HTTPS)
set(GIT_OPENSSL 1)
list(APPEND LIBGIT2_SYSTEM_INCLUDES ${OPENSSL_INCLUDE_DIR})
list(APPEND LIBGIT2_SYSTEM_LIBS ${OPENSSL_LIBRARIES})
# Static OpenSSL (lib crypto.a) requires libdl, include it explicitly
if(LINK_WITH_STATIC_LIBRARIES STREQUAL ON)
list(APPEND LIBGIT2_SYSTEM_LIBS ${CMAKE_DL_LIBS})
endif()
list(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS})
list(APPEND LIBGIT2_PC_REQUIRES "openssl")
elseif(USE_HTTPS STREQUAL "mbedTLS")
@ -109,8 +113,8 @@ if(USE_HTTPS)
elseif(USE_HTTPS STREQUAL "Schannel")
set(GIT_SCHANNEL 1)
list(APPEND LIBGIT2_SYSTEM_LIBS "rpcrt4" "crypt32" "ole32" "secur32")
list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32" "-lsecur32")
list(APPEND LIBGIT2_SYSTEM_LIBS "rpcrt4" "crypt32" "ole32")
list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
elseif(USE_HTTPS STREQUAL "WinHTTP")
set(GIT_WINHTTP 1)
@ -125,8 +129,8 @@ if(USE_HTTPS)
list(APPEND LIBGIT2_PC_LIBS "-lwinhttp")
endif()
list(APPEND LIBGIT2_SYSTEM_LIBS "rpcrt4" "crypt32" "ole32" "secur32")
list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32" "-lsecur32")
list(APPEND LIBGIT2_SYSTEM_LIBS "rpcrt4" "crypt32" "ole32")
list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
elseif(USE_HTTPS STREQUAL "OpenSSL-Dynamic")
set(GIT_OPENSSL 1)
set(GIT_OPENSSL_DYNAMIC 1)

View File

@ -1,6 +1,11 @@
# Optional external dependency: libssh2
if(USE_SSH)
if(USE_SSH STREQUAL "exec")
set(GIT_SSH 1)
set(GIT_SSH_EXEC 1)
add_feature_info(SSH ON "using OpenSSH exec support")
elseif(USE_SSH STREQUAL ON OR USE_SSH STREQUAL "libssh2")
find_pkglibraries(LIBSSH2 libssh2)
if(NOT LIBSSH2_FOUND)
find_package(LibSSH2)
set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR})
@ -12,30 +17,28 @@ if(USE_SSH)
if(NOT LIBSSH2_FOUND)
message(FATAL_ERROR "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.")
endif()
endif()
if(LIBSSH2_FOUND)
set(GIT_SSH 1)
list(APPEND LIBGIT2_SYSTEM_INCLUDES ${LIBSSH2_INCLUDE_DIRS})
list(APPEND LIBGIT2_SYSTEM_LIBS ${LIBSSH2_LIBRARIES})
list(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
check_library_exists("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
if(HAVE_LIBSSH2_MEMORY_CREDENTIALS)
set(GIT_SSH_MEMORY_CREDENTIALS 1)
set(GIT_SSH_LIBSSH2_MEMORY_CREDENTIALS 1)
endif()
else()
message(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.")
endif()
if(WIN32 AND EMBED_SSH_PATH)
if(WIN32 AND EMBED_SSH_PATH)
file(GLOB SSH_SRC "${EMBED_SSH_PATH}/src/*.c")
list(SORT SSH_SRC)
list(APPEND LIBGIT2_DEPENDENCY_OBJECTS ${SSH_SRC})
list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${EMBED_SSH_PATH}/include")
file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"")
set(GIT_SSH 1)
endif()
endif()
add_feature_info(SSH GIT_SSH "SSH transport support")
set(GIT_SSH 1)
set(GIT_SSH_LIBSSH2 1)
add_feature_info(SSH ON "using libssh2")
else()
add_feature_info(SSH OFF "SSH transport support")
endif()

4
deps/xdiff/xmerge.c vendored
View File

@ -88,7 +88,7 @@ static int xdl_cleanup_merge(xdmerge_t *c)
if (c->mode == 0)
count++;
next_c = c->next;
free(c);
xdl_free(c);
}
return count;
}
@ -456,7 +456,7 @@ static void xdl_merge_two_conflicts(xdmerge_t *m)
m->chg1 = next_m->i1 + next_m->chg1 - m->i1;
m->chg2 = next_m->i2 + next_m->chg2 - m->i2;
m->next = next_m->next;
free(next_m);
xdl_free(next_m);
}
/*

View File

@ -1,42 +1,408 @@
v1.7.2
v1.8.1
------
This release primarily includes straightforward bugfixes, as well as
new functionality to have more control over the HTTP User-Agent header.
However, there is an API change from v1.8 that was required for
improved compatibility.
In v1.8, libgit2 introduced the `report_unchanged ` member in the
`git_fetch_options` structure. We mistakenly introduced this as a
bitfield, which is not suitable for our public API. To correct this
mistake, we have _removed_ the `report_unchanged ` member. To support
the report unchanged tips option, users can set the `update_fetchhead`
member to include the `GIT_REMOTE_UPDATE_REPORT_UNCHANGED` value.
The libgit2 projects regrets the API change, but this was required to
support cross-platform compatibility.
## What's Changed
This release fixes three bugs that can cause undefined behavior when given well-crafted inputs, either in input files or over network connections. These bugs may be able to be leveraged to cause denial of service attacks or unauthorized code execution.
### New features
Two of these issues were discovered and reported by security engineers at Amazon Web Services. We thank the AWS Security team for their efforts to identify these issues, provide helpful reproduction cases, and responsibly disclose their findings.
### Security fixes
* transport: safely handle messages with no caps
* revparse: fix parsing bug for trailing `@`
* index: correct index has_dir_name check
**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.7.1...v1.7.2
v1.7.1
------
## What's Changed
* Allow more control over the user-agent by @ethomson in
https://github.com/libgit2/libgit2/pull/6788
### Bug fixes
* proxy: Return an error for invalid proxy URLs instead of crashing. by @lrm29 in https://github.com/libgit2/libgit2/pull/6597
* ssh: fix known_hosts leak in _git_ssh_setup_conn by @steven9724 in https://github.com/libgit2/libgit2/pull/6599
* repository: make cleanup safe for re-use with grafts by @carlosmn in https://github.com/libgit2/libgit2/pull/6600
* fix: Add missing include for oidarray. by @dvzrv in https://github.com/libgit2/libgit2/pull/6608
* Revert "CMake: Search for ssh2 instead of libssh2." by @ethomson in https://github.com/libgit2/libgit2/pull/6619
* commit: Fix git_commit_create_from_stage without author and
committer by @florianpircher in
https://github.com/libgit2/libgit2/pull/6781
* process.c: fix environ for macOS by @barracuda156 in
https://github.com/libgit2/libgit2/pull/6792
* Bounds check for pack index read by @ConradIrwin in
https://github.com/libgit2/libgit2/pull/6796
* transport: provide a useful error message during cancellation
by @ethomson in https://github.com/libgit2/libgit2/pull/6802
* transport: support sha256 oids by @ethomson in
https://github.com/libgit2/libgit2/pull/6803
* Revparse: Correctly accept ref with '@' at the end by @csware in
https://github.com/libgit2/libgit2/pull/6809
* remote: drop bitfields in git_remote_fetch_options by @ethomson in
https://github.com/libgit2/libgit2/pull/6806
* examples: fix memory leak in for-each-ref.c by @qaqland in
https://github.com/libgit2/libgit2/pull/6808
* xdiff: use proper free function by @ethomson in
https://github.com/libgit2/libgit2/pull/6810
* rand: avoid uninitialized loadavg warnings by @ethomson in
https://github.com/libgit2/libgit2/pull/6812
* cli: include alloca on illumos / solaris / sunos by @ethomson in
https://github.com/libgit2/libgit2/pull/6813
* Update git_array allocator to obey strict aliasing rules
by @ethomson in https://github.com/libgit2/libgit2/pull/6814
* tree: avoid mixed signedness comparison by @ethomson in
https://github.com/libgit2/libgit2/pull/6815
### Compatibility improvements
### Build and CI improvements
* stransport: macOS: replace errSSLNetworkTimeout, with hard-coded value by @mascguy in https://github.com/libgit2/libgit2/pull/6610
* ci: update nightly workflows by @ethomson in
https://github.com/libgit2/libgit2/pull/6773
* ci: give all nightly builds a unique id by @ethomson in
https://github.com/libgit2/libgit2/pull/6782
* cmake: remove workaround that isn't compatible with Windows on
ARM by @hackhaslam in https://github.com/libgit2/libgit2/pull/6794
### Documentation improvements
* Docs meta-updates by @ethomson in
https://github.com/libgit2/libgit2/pull/6787
### Dependency updates
* Enable llhttp for HTTP parsing by @sgallagher in
https://github.com/libgit2/libgit2/pull/6713
## New Contributors
* @dvzrv made their first contribution in https://github.com/libgit2/libgit2/pull/6608
* @steven9724 made their first contribution in https://github.com/libgit2/libgit2/pull/6599
**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.7.0...v1.7.1
* @florianpircher made their first contribution in
https://github.com/libgit2/libgit2/pull/6781
* @barracuda156 made their first contribution in
https://github.com/libgit2/libgit2/pull/6792
* @sgallagher made their first contribution in
https://github.com/libgit2/libgit2/pull/6713
* @ConradIrwin made their first contribution in
https://github.com/libgit2/libgit2/pull/6796
* @qaqland made their first contribution in
https://github.com/libgit2/libgit2/pull/6808
**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.8.0...v1.8.1
v1.8
----
This is release v1.8.0, "Das Fliegende Klassenzimmer". This release
includes optional, experimental support for invoking OpenSSH to fetch
and push, an easier mechanism to perform the default behavior of
`git commit`, and has many improvements for worktrees. This release
also includes many other new features and bugfixes.
## Major changes
* **Executable SSH (OpenSSH) support**
libgit2 can now invoke the command-line OpenSSH to fetch from and push
to remotes over SSH. This support takes the place of libssh2 support.
To use it, configure libgit2 with `cmake -DUSE_SSH=exec`, and please
report any problems that you discover. By @ethomson in
https://github.com/libgit2/libgit2/pull/6617
* **Simplified commit creation**
The `git_commit_create_from_stage` API was introduced to allow users to
better emulate the behavior of `git commit` without needing to provide
unnecessary information. The current state of the index is committed to
the current branch. By @ethomson in
https://github.com/libgit2/libgit2/pull/6716
* **Worktree improvements**
A number of worktree improvements have been made for better
compatibility with core git. First, libgit2 now understands per-worktree
references, thanks to @csware in
https://github.com/libgit2/libgit2/pull/6387. Worktree-specific
configuration is now supported, thanks to @vermiculus in
https://github.com/libgit2/libgit2/pull/6202. And improved compatibility
with `git worktree add` is now supported, thanks to @herrerog in
https://github.com/libgit2/libgit2/pull/5319.
## Breaking changes
* **Adding `WORKTREE` configuration level** (ABI breaking change)
To support worktree configurations at the appropriate level (higher
priority than local configuration, but lower priority than app-specific
configuration), the `GIT_CONFIG_LEVEL_WORKTREE` level was introduced at
priority 6. `GIT_CONFIG_LEVEL_APP` now begins at priority 7.
* **Changes to `git_config_entry`** (ABI breaking change)
The `git_config_entry` structure now contains information about the
`backend_type` and `origin_path`. The unused `payload` value has been
removed.
* **`git_push_options` includes remote push options** (ABI breaking change)
The `git_push_options` structure now contains a value for remote push
options.
## Other changes
### New features
* config: provide an "origin" for config entries by @ethomson in
https://github.com/libgit2/libgit2/pull/6615
* cli: add a `git config` command by @ethomson in
https://github.com/libgit2/libgit2/pull/6616
* Add OpenSSH support by @ethomson in
https://github.com/libgit2/libgit2/pull/6617
* remote: optionally report unchanged tips by @ethomson in
https://github.com/libgit2/libgit2/pull/6645
* Support setting oid type for in-memory repositories by @kcsaul in
https://github.com/libgit2/libgit2/pull/6671
* cli: add `index-pack` command by @ethomson in
https://github.com/libgit2/libgit2/pull/6681
* Add `git_repository_commit_parents` to identify the parents of the next
commit given the repository state by @ethomson in
https://github.com/libgit2/libgit2/pull/6707
* commit: introduce `git_commit_create_from_stage` by @ethomson in
https://github.com/libgit2/libgit2/pull/6716
* set SSH timeout by @vafada in
https://github.com/libgit2/libgit2/pull/6721
* Implement push options on push by @russell in
https://github.com/libgit2/libgit2/pull/6439
* Support index.skipHash true config by @parnic in
https://github.com/libgit2/libgit2/pull/6738
* worktree: mimic 'git worktree add' behavior. by @herrerog in
https://github.com/libgit2/libgit2/pull/5319
* Support the extension for worktree-specific config by @vermiculus in
https://github.com/libgit2/libgit2/pull/6202
* Separate config reader and writer backend priorities (for worktree
configs) by @ethomson in https://github.com/libgit2/libgit2/pull/6756
* fetch: enable deepening/shortening shallow clones by @kempniu in
https://github.com/libgit2/libgit2/pull/6662
### Bug fixes
* repository: make cleanup safe for re-use with grafts by @carlosmn in
https://github.com/libgit2/libgit2/pull/6600
* fix: Add missing include for `oidarray`. by @dvzrv in
https://github.com/libgit2/libgit2/pull/6608
* ssh: fix `known_hosts` leak in `_git_ssh_setup_conn` by @steven9724 in
https://github.com/libgit2/libgit2/pull/6599
* proxy: Return an error for invalid proxy URLs instead of crashing by
@lrm29 in https://github.com/libgit2/libgit2/pull/6597
* errors: refactoring - never return `NULL` in `git_error_last()` by
@ethomson in https://github.com/libgit2/libgit2/pull/6625
* Reject potential option injections over ssh by @carlosmn in
https://github.com/libgit2/libgit2/pull/6636
* remote: fix memory leak in `git_remote_download()` by @7Ji in
https://github.com/libgit2/libgit2/pull/6651
* git2: Fix crash when called w/o parameters by @csware in
https://github.com/libgit2/libgit2/pull/6673
* Avoid macro redefinition of `ENABLE_INTSAFE_SIGNED_FUNCTIONS` by @csware
in https://github.com/libgit2/libgit2/pull/6666
* util: suppress some uninitialized variable warnings by @boretrk in
https://github.com/libgit2/libgit2/pull/6659
* push: set generic error in `push_negotiation` cb by @ethomson in
https://github.com/libgit2/libgit2/pull/6675
* process: test `/usr/bin/false` on BSDs by @ethomson in
https://github.com/libgit2/libgit2/pull/6677
* clone: don't mix up "http://url" with "http:/url" when figuring out if we
should do a local clone by @boretrk in
https://github.com/libgit2/libgit2/pull/6361
* Several compatibility fixes by @ethomson in
https://github.com/libgit2/libgit2/pull/6678
* Git blame buffer gives the wrong result in many cases where there are
by @thosey in https://github.com/libgit2/libgit2/pull/6572
* Fix 'path cannot exist in repository' during diff for in-memory repository
by @kcsaul in https://github.com/libgit2/libgit2/pull/6683
* process: don't try to close the status by @ethomson in
https://github.com/libgit2/libgit2/pull/6693
* Minor bug fixes by @ethomson in
https://github.com/libgit2/libgit2/pull/6695
* Bypass shallow clone support for in-memory repositories by @kcsaul in
https://github.com/libgit2/libgit2/pull/6684
* examples: use `unsigned` int for bitfields by @ethomson in
https://github.com/libgit2/libgit2/pull/6699
* Fix some bugs caught by UBscan by @ethomson in
https://github.com/libgit2/libgit2/pull/6700
* `git_diff_find_similar` doesn't always remove unmodified deltas by @yori
in https://github.com/libgit2/libgit2/pull/6642
* httpclient: clear `client->parser.data` after use by @ethomson in
https://github.com/libgit2/libgit2/pull/6705
* Do not normalize `safe.directory` paths by @csware in
https://github.com/libgit2/libgit2/pull/6668
* clone: don't swallow error in `should_checkout` by @ethomson in
https://github.com/libgit2/libgit2/pull/6727
* Correct index add directory/file conflict detection by @ethomson in
https://github.com/libgit2/libgit2/pull/6729
* Correct `git_revparse_single` and add revparse fuzzing by @ethomson in
https://github.com/libgit2/libgit2/pull/6730
* config: properly delete or rename section containing multivars by
@samueltardieu in https://github.com/libgit2/libgit2/pull/6723
* revparse: ensure bare '@' is truly bare by @ethomson in
https://github.com/libgit2/libgit2/pull/6742
* repo: ensure we can initialize win32 paths by @ethomson in
https://github.com/libgit2/libgit2/pull/6743
* Swap `GIT_DIFF_LINE_(ADD|DEL)_EOFNL` to match other Diffs by @xphoniex in
https://github.com/libgit2/libgit2/pull/6240
* diff: fix test for SHA256 support in `diff_from_buffer` by @ethomson in
https://github.com/libgit2/libgit2/pull/6745
* http: support empty http.proxy config setting by @ethomson in
https://github.com/libgit2/libgit2/pull/6744
* More `safe.directory` improvements by @ethomson in
https://github.com/libgit2/libgit2/pull/6739
* Ensure that completely ignored diff is empty by @ethomson in
https://github.com/libgit2/libgit2/pull/5893
* Fix broken regexp that matches submodule names containing ".path" by
@csware in https://github.com/libgit2/libgit2/pull/6749
* Fix memory leaks by @csware in
https://github.com/libgit2/libgit2/pull/6748
* Make `refdb_fs` (hopefully) fully aware of per worktree refs by @csware in
https://github.com/libgit2/libgit2/pull/6387
* fix log example by @albfan in https://github.com/libgit2/libgit2/pull/6359
* fetch: fail on depth for local transport by @ethomson in
https://github.com/libgit2/libgit2/pull/6757
* Fix message trailer parsing by @ethomson in
https://github.com/libgit2/libgit2/pull/6761
* config: correct fetching the `HIGHEST_LEVEL` config by @ethomson in
https://github.com/libgit2/libgit2/pull/6766
* Avoid some API breaking changes in v1.8 by @ethomson in
https://github.com/libgit2/libgit2/pull/6768
### Build and CI improvements
* meta: update version numbers to v1.8 by @ethomson in
https://github.com/libgit2/libgit2/pull/6596
* Revert "CMake: Search for ssh2 instead of libssh2." by @ethomson in
https://github.com/libgit2/libgit2/pull/6619
* cmake: fix openssl build on win32 by @lazka in
https://github.com/libgit2/libgit2/pull/6626
* ci: retry flaky online tests by @ethomson in
https://github.com/libgit2/libgit2/pull/6628
* ci: update to macOS 12 by @ethomson in
https://github.com/libgit2/libgit2/pull/6629
* Use `#!/bin/bash` for script with bash-specific commands by @roehling in
https://github.com/libgit2/libgit2/pull/6581
* ci: overwrite nonsense in `/usr/local` during macOS setup by @ethomson in
https://github.com/libgit2/libgit2/pull/6664
* release: add a compatibility label by @ethomson in
https://github.com/libgit2/libgit2/pull/6676
* actions: set permissions by @ethomson in
https://github.com/libgit2/libgit2/pull/6680
* cmake: rename FindIconv to avoid collision with cmake by @ethomson in
https://github.com/libgit2/libgit2/pull/6682
* ci: allow workflows to read and write packages by @ethomson in
https://github.com/libgit2/libgit2/pull/6687
* ci: allow workflows to push changes by @ethomson in
https://github.com/libgit2/libgit2/pull/6688
* tests: remove test for strcasecmp by @boretrk in
https://github.com/libgit2/libgit2/pull/6691
* CI fixes by @ethomson in
https://github.com/libgit2/libgit2/pull/6694
* ci: improvements to prepare for Cygwin support by @ethomson in
https://github.com/libgit2/libgit2/pull/6696
* Yet more CI improvements by @ethomson in
https://github.com/libgit2/libgit2/pull/6697
* Fix nightly builds by @ethomson in
https://github.com/libgit2/libgit2/pull/6709
* Benchmarks: add a site to view results by @ethomson in
https://github.com/libgit2/libgit2/pull/6715
* `GIT_RAND_GETENTROPY`: do not include `sys/random.h` by @semarie in
https://github.com/libgit2/libgit2/pull/6736
* add dl to `LIBGIT2_SYSTEM_LIBS` by @christopherfujino in
https://github.com/libgit2/libgit2/pull/6631
* meta: add dependency tag to release.yml by @ethomson in
https://github.com/libgit2/libgit2/pull/6740
* CI: fix our nightlies by @ethomson in
https://github.com/libgit2/libgit2/pull/6751
* trace: Re-enable tests as tracing is now enabled by default by @lrm29 in
https://github.com/libgit2/libgit2/pull/6752
* tests: don't free an unininitialized repo by @ethomson in
https://github.com/libgit2/libgit2/pull/6763
* ci: reduce ASLR randomization for TSAN by @ethomson in
https://github.com/libgit2/libgit2/pull/6764
* packbuilder: adjust nondeterministic tests by @ethomson in
https://github.com/libgit2/libgit2/pull/6762
* Allow libgit2 to be compiled with mbedtls3. by @adamharrison in
https://github.com/libgit2/libgit2/pull/6759
* build: update to latest actions versions by @ethomson in
https://github.com/libgit2/libgit2/pull/6765
* ctype: cast characters to unsigned when classifying characters by
@boretrk in https://github.com/libgit2/libgit2/pull/6679 and
@ethomson in https://github.com/libgit2/libgit2/pull/6770
* valgrind: suppress OpenSSL warnings by @ethomson in https://github.com/libgit2/libgit2/pull/6769
### Documentation improvements
* README.md: Fix link to conan packages by @lrm29 in
https://github.com/libgit2/libgit2/pull/6621
* README: replace gmaster with GitButler by @ethomson in
https://github.com/libgit2/libgit2/pull/6692
* blame example: Fix support for line range in CLI by @wetneb in
https://github.com/libgit2/libgit2/pull/6638
* Support authentication in push example by @pluehne in
https://github.com/libgit2/libgit2/pull/5904
* docs: fix mistake in attr.h by @DavHau in
https://github.com/libgit2/libgit2/pull/6714
* Fix broken links by @csware in
https://github.com/libgit2/libgit2/pull/6747
### Platform compatibility fixes
* stransport: macOS: replace `errSSLNetworkTimeout`, with hard-coded
value by @mascguy in https://github.com/libgit2/libgit2/pull/6610
### Git compatibility fixes
* Do not trim dots from usernames by @georgthegreat in
https://github.com/libgit2/libgit2/pull/6657
* merge: fix incorrect rename detection for empty files by @herrerog in
https://github.com/libgit2/libgit2/pull/6717
### Dependency updates
* zlib: upgrade bundled zlib to v1.3 by @ethomson in
https://github.com/libgit2/libgit2/pull/6698
* ntlmclient: update to latest upstream ntlmclient by @ethomson in
https://github.com/libgit2/libgit2/pull/6704
## New Contributors
* @dvzrv made their first contribution in
https://github.com/libgit2/libgit2/pull/6608
* @mascguy made their first contribution in
https://github.com/libgit2/libgit2/pull/6610
* @steven9724 made their first contribution in
https://github.com/libgit2/libgit2/pull/6599
* @lazka made their first contribution in
https://github.com/libgit2/libgit2/pull/6626
* @roehling made their first contribution in
https://github.com/libgit2/libgit2/pull/6581
* @7Ji made their first contribution in
https://github.com/libgit2/libgit2/pull/6651
* @kempniu made their first contribution in
https://github.com/libgit2/libgit2/pull/6662
* @thosey made their first contribution in
https://github.com/libgit2/libgit2/pull/6572
* @wetneb made their first contribution in
https://github.com/libgit2/libgit2/pull/6638
* @yori made their first contribution in
https://github.com/libgit2/libgit2/pull/6642
* @pluehne made their first contribution in
https://github.com/libgit2/libgit2/pull/5904
* @DavHau made their first contribution in
https://github.com/libgit2/libgit2/pull/6714
* @vafada made their first contribution in
https://github.com/libgit2/libgit2/pull/6721
* @semarie made their first contribution in
https://github.com/libgit2/libgit2/pull/6736
* @christopherfujino made their first contribution in
https://github.com/libgit2/libgit2/pull/6631
* @parnic made their first contribution in
https://github.com/libgit2/libgit2/pull/6738
* @samueltardieu made their first contribution in
https://github.com/libgit2/libgit2/pull/6723
* @xphoniex made their first contribution in
https://github.com/libgit2/libgit2/pull/6240
* @adamharrison made their first contribution in
https://github.com/libgit2/libgit2/pull/6759
**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.7.0...v1.8.0
v1.7
----

View File

@ -15,8 +15,8 @@ so there are no restrictions on their use.
For annotated HTML versions, see the "Examples" section of:
http://libgit2.github.com/libgit2
https://libgit2.org/libgit2
such as:
http://libgit2.github.com/libgit2/ex/HEAD/general.html
https://libgit2.org/libgit2/ex/HEAD/general.html

View File

@ -8,7 +8,7 @@ struct args_info {
int argc;
char **argv;
int pos;
int opts_done : 1; /**< Did we see a -- separator */
unsigned int opts_done : 1; /**< Did we see a -- separator */
};
#define ARGS_INFO_INIT { argc, argv, 0, 0 }
#define ARGS_CURRENT(args) args->argv[args->pos]

View File

@ -47,6 +47,10 @@ int lg2_blame(git_repository *repo, int argc, char *argv[])
if (o.M) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
if (o.C) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
if (o.F) blameopts.flags |= GIT_BLAME_FIRST_PARENT;
if (o.start_line && o.end_line) {
blameopts.min_line = o.start_line;
blameopts.max_line = o.end_line;
}
/**
* The commit range comes in "committish" form. Use the rev-parse API to

View File

@ -35,9 +35,9 @@
*/
typedef struct {
int force : 1;
int progress : 1;
int perf : 1;
unsigned int force : 1;
unsigned int progress : 1;
unsigned int perf : 1;
} checkout_options;
static void print_usage(void)

View File

@ -25,6 +25,8 @@ static int show_ref(git_reference *ref, void *data)
git_object_type2string(git_object_type(obj)),
git_reference_name(ref));
git_object_free(obj);
git_reference_free(ref);
if (resolved)
git_reference_free(resolved);
return 0;

View File

@ -31,8 +31,8 @@
* Git Internals that you will need to know to work with Git at this level,
* check out [Chapter 10][pg] of the Pro Git book.
*
* [lg]: http://libgit2.github.com
* [ap]: http://libgit2.github.com/libgit2
* [lg]: https://libgit2.org
* [ap]: https://libgit2.org/libgit2
* [pg]: https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain
*/
@ -97,7 +97,7 @@ int lg2_general(git_repository *repo, int argc, char** argv)
*
* (Try running this program against tests/resources/testrepo.git.)
*
* [me]: http://libgit2.github.com/libgit2/#HEAD/group/repository
* [me]: https://libgit2.org/libgit2/#HEAD/group/repository
*/
repo_path = (argc > 1) ? argv[1] : "/opt/libgit2-test/.git";
@ -173,7 +173,7 @@ static void oid_parsing(git_oid *oid)
* working with raw objects, we'll need to get this structure from the
* repository.
*
* [odb]: http://libgit2.github.com/libgit2/#HEAD/group/odb
* [odb]: https://libgit2.org/libgit2/#HEAD/group/odb
*/
static void object_database(git_repository *repo, git_oid *oid)
{
@ -262,7 +262,7 @@ static void object_database(git_repository *repo, git_oid *oid)
* of them here. You can read about the other ones in the [commit API
* docs][cd].
*
* [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit
* [cd]: https://libgit2.org/libgit2/#HEAD/group/commit
*/
static void commit_writing(git_repository *repo)
{
@ -347,7 +347,7 @@ static void commit_writing(git_repository *repo)
* data in the commit - the author (name, email, datetime), committer
* (same), tree, message, encoding and parent(s).
*
* [pco]: http://libgit2.github.com/libgit2/#HEAD/group/commit
* [pco]: https://libgit2.org/libgit2/#HEAD/group/commit
*/
static void commit_parsing(git_repository *repo)
{
@ -418,7 +418,7 @@ static void commit_parsing(git_repository *repo)
* functions very similarly to the commit lookup, parsing and creation
* methods, since the objects themselves are very similar.
*
* [tm]: http://libgit2.github.com/libgit2/#HEAD/group/tag
* [tm]: https://libgit2.org/libgit2/#HEAD/group/tag
*/
static void tag_parsing(git_repository *repo)
{
@ -472,7 +472,7 @@ static void tag_parsing(git_repository *repo)
* object type in Git, but a useful structure for parsing and traversing
* tree entries.
*
* [tp]: http://libgit2.github.com/libgit2/#HEAD/group/tree
* [tp]: https://libgit2.org/libgit2/#HEAD/group/tree
*/
static void tree_parsing(git_repository *repo)
{
@ -536,7 +536,7 @@ static void tree_parsing(git_repository *repo)
* from disk and writing it to the db and getting the oid back so you
* don't have to do all those steps yourself.
*
* [ba]: http://libgit2.github.com/libgit2/#HEAD/group/blob
* [ba]: https://libgit2.org/libgit2/#HEAD/group/blob
*/
static void blob_parsing(git_repository *repo)
{
@ -578,7 +578,7 @@ static void blob_parsing(git_repository *repo)
* that were ancestors of (reachable from) a given starting point. This
* can allow you to create `git log` type functionality.
*
* [rw]: http://libgit2.github.com/libgit2/#HEAD/group/revwalk
* [rw]: https://libgit2.org/libgit2/#HEAD/group/revwalk
*/
static void revwalking(git_repository *repo)
{
@ -643,7 +643,7 @@ static void revwalking(git_repository *repo)
* The [index file API][gi] allows you to read, traverse, update and write
* the Git index file (sometimes thought of as the staging area).
*
* [gi]: http://libgit2.github.com/libgit2/#HEAD/group/index
* [gi]: https://libgit2.org/libgit2/#HEAD/group/index
*/
static void index_walking(git_repository *repo)
{
@ -687,7 +687,7 @@ static void index_walking(git_repository *repo)
* references such as branches, tags and remote references (everything in
* the .git/refs directory).
*
* [ref]: http://libgit2.github.com/libgit2/#HEAD/group/reference
* [ref]: https://libgit2.org/libgit2/#HEAD/group/reference
*/
static void reference_listing(git_repository *repo)
{
@ -740,7 +740,7 @@ static void reference_listing(git_repository *repo)
* The [config API][config] allows you to list and update config values
* in any of the accessible config file locations (system, global, local).
*
* [config]: http://libgit2.github.com/libgit2/#HEAD/group/config
* [config]: https://libgit2.org/libgit2/#HEAD/group/config
*/
static void config_files(const char *repo_path, git_repository* repo)
{

View File

@ -50,6 +50,7 @@ static int add_revision(struct log_state *s, const char *revstr);
/** log_options holds other command line options that affect log output */
struct log_options {
int show_diff;
int show_oneline;
int show_log_size;
int skip, limit;
int min_parents, max_parents;
@ -81,9 +82,11 @@ int lg2_log(git_repository *repo, int argc, char *argv[])
git_commit *commit = NULL;
git_pathspec *ps = NULL;
memset(&s, 0, sizeof(s));
/** Parse arguments and set up revwalker. */
last_arg = parse_options(&s, &opt, argc, argv);
s.repo = repo;
last_arg = parse_options(&s, &opt, argc, argv);
diffopts.pathspec.strings = &argv[last_arg];
diffopts.pathspec.count = argc - last_arg;
@ -335,6 +338,10 @@ static void print_commit(git_commit *commit, struct log_options *opts)
const char *scan, *eol;
git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
if (opts->show_oneline) {
printf("%s ", buf);
} else {
printf("commit %s\n", buf);
if (opts->show_log_size) {
@ -355,13 +362,20 @@ static void print_commit(git_commit *commit, struct log_options *opts)
print_time(&sig->when, "Date: ");
}
printf("\n");
}
for (scan = git_commit_message(commit); scan && *scan; ) {
for (eol = scan; *eol && *eol != '\n'; ++eol) /* find eol */;
if (opts->show_oneline)
printf("%.*s\n", (int)(eol - scan), scan);
else
printf(" %.*s\n", (int)(eol - scan), scan);
scan = *eol ? eol + 1 : NULL;
if (opts->show_oneline)
break;
}
if (!opts->show_oneline)
printf("\n");
}
@ -407,8 +421,6 @@ static int parse_options(
struct log_state *s, struct log_options *opt, int argc, char **argv)
{
struct args_info args = ARGS_INFO_INIT;
memset(s, 0, sizeof(*s));
s->sorting = GIT_SORT_TIME;
memset(opt, 0, sizeof(*opt));
@ -424,7 +436,7 @@ static int parse_options(
else
/** Try failed revision parse as filename. */
break;
} else if (!match_arg_separator(&args)) {
} else if (match_arg_separator(&args)) {
break;
}
else if (!strcmp(a, "--date-order"))
@ -474,6 +486,8 @@ static int parse_options(
opt->show_diff = 1;
else if (!strcmp(a, "--log-size"))
opt->show_log_size = 1;
else if (!strcmp(a, "--oneline"))
opt->show_oneline = 1;
else
usage("Unsupported argument", a);
}

View File

@ -30,7 +30,7 @@ struct merge_options {
git_annotated_commit **annotated;
size_t annotated_count;
int no_commit : 1;
unsigned int no_commit : 1;
};
static void print_usage(void)
@ -263,7 +263,7 @@ static int create_merge_commit(git_repository *repo, git_index *index, struct me
sign, sign,
NULL, msg,
tree,
opts->annotated_count + 1, (const git_commit **)parents);
opts->annotated_count + 1, parents);
check_lg2(err, "failed to create commit", NULL);
/* We're done merging, cleanup the repository state */

View File

@ -32,6 +32,7 @@
/** Entry point for this command */
int lg2_push(git_repository *repo, int argc, char **argv) {
git_push_options options;
git_remote_callbacks callbacks;
git_remote* remote = NULL;
char *refspec = "refs/heads/master";
const git_strarray refspecs = {
@ -47,7 +48,11 @@ int lg2_push(git_repository *repo, int argc, char **argv) {
check_lg2(git_remote_lookup(&remote, repo, "origin" ), "Unable to lookup remote", NULL);
check_lg2(git_remote_init_callbacks(&callbacks, GIT_REMOTE_CALLBACKS_VERSION), "Error initializing remote callbacks", NULL);
callbacks.credentials = cred_acquire_cb;
check_lg2(git_push_options_init(&options, GIT_PUSH_OPTIONS_VERSION ), "Error initializing push", NULL);
options.callbacks = callbacks;
check_lg2(git_remote_push(remote, &refspecs, &options), "Error pushing", NULL);

View File

@ -12,10 +12,13 @@ foreach(fuzz_target_src ${SRC_FUZZERS})
string(REPLACE ".c" "" fuzz_target_name ${fuzz_target_src})
string(REPLACE "_fuzzer" "" fuzz_name ${fuzz_target_name})
set(${fuzz_target_name}_SOURCES ${fuzz_target_src} ${LIBGIT2_OBJECTS})
set(${fuzz_target_name}_SOURCES
${fuzz_target_src} "fuzzer_utils.c" ${LIBGIT2_OBJECTS})
if(USE_STANDALONE_FUZZERS)
list(APPEND ${fuzz_target_name}_SOURCES "standalone_driver.c")
endif()
add_executable(${fuzz_target_name} ${${fuzz_target_name}_SOURCES})
set_target_properties(${fuzz_target_name} PROPERTIES C_STANDARD 90)

View File

@ -43,7 +43,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
goto out;
}
if ((err = git_config_backend_from_string(&backend, (const char*)data, size)) != 0) {
if ((err = git_config_backend_from_string(&backend, (const char*)data, size, NULL)) != 0) {
goto out;
}
if ((err = git_config_add_backend(cfg, backend, 0, NULL, 0)) != 0) {

View File

@ -0,0 +1 @@
HEAD

View File

@ -0,0 +1 @@
xxxxxxxxxxxxxxxx@

View File

@ -16,6 +16,7 @@
#include "futils.h"
#include "standalone_driver.h"
#include "fuzzer_utils.h"
#define UNUSED(x) (void)(x)
@ -157,33 +158,10 @@ static int fuzzer_transport_cb(git_transport **out, git_remote *owner, void *par
return git_transport_smart(out, owner, &def);
}
static void fuzzer_git_abort(const char *op)
{
const git_error *err = git_error_last();
fprintf(stderr, "unexpected libgit error: %s: %s\n",
op, err ? err->message : "<none>");
abort();
}
int LLVMFuzzerInitialize(int *argc, char ***argv)
{
#if defined(_WIN32)
char tmpdir[MAX_PATH], path[MAX_PATH];
if (GetTempPath((DWORD)sizeof(tmpdir), tmpdir) == 0)
abort();
if (GetTempFileName(tmpdir, "lg2", 1, path) == 0)
abort();
if (git_futils_mkdir(path, 0700, 0) < 0)
abort();
#else
char path[] = "/tmp/git2.XXXXXX";
if (mkdtemp(path) != path)
abort();
#endif
UNUSED(argc);
UNUSED(argv);
if (git_libgit2_init() < 0)
abort();
@ -191,12 +169,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
if (git_libgit2_opts(GIT_OPT_SET_PACK_MAX_OBJECTS, 10000000) < 0)
abort();
UNUSED(argc);
UNUSED(argv);
if (git_repository_init(&repo, path, 1) < 0)
fuzzer_git_abort("git_repository_init");
repo = fuzzer_repo_init();
return 0;
}

51
fuzzers/fuzzer_utils.c Normal file
View File

@ -0,0 +1,51 @@
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "git2.h"
#include "futils.h"
#include "fuzzer_utils.h"
void fuzzer_git_abort(const char *op)
{
const git_error *err = git_error_last();
fprintf(stderr, "unexpected libgit error: %s: %s\n",
op, err ? err->message : "<none>");
abort();
}
git_repository *fuzzer_repo_init(void)
{
git_repository *repo;
#if defined(_WIN32)
char tmpdir[MAX_PATH], path[MAX_PATH];
if (GetTempPath((DWORD)sizeof(tmpdir), tmpdir) == 0)
abort();
if (GetTempFileName(tmpdir, "lg2", 1, path) == 0)
abort();
if (git_futils_mkdir(path, 0700, 0) < 0)
abort();
#else
char path[] = "/tmp/git2.XXXXXX";
if (mkdtemp(path) != path)
abort();
#endif
if (git_repository_init(&repo, path, 1) < 0)
fuzzer_git_abort("git_repository_init");
return repo;
}

View File

@ -4,11 +4,11 @@
* 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_transports_ssh_h__
#define INCLUDE_transports_ssh_h__
#include "common.h"
#ifndef INCLUDE_fuzzer_utils_h__
#define INCLUDE_fuzzer_utils_h__
int git_transport_ssh_global_init(void);
extern void fuzzer_git_abort(const char *op);
extern git_repository *fuzzer_repo_init(void);
#endif

52
fuzzers/revparse_fuzzer.c Normal file
View File

@ -0,0 +1,52 @@
/*
* libgit2 revparse fuzzer target.
*
* 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 <stdio.h>
#include <string.h>
#include "git2.h"
#include "standalone_driver.h"
#include "fuzzer_utils.h"
#define UNUSED(x) (void)(x)
static git_repository *repo;
int LLVMFuzzerInitialize(int *argc, char ***argv)
{
UNUSED(argc);
UNUSED(argv);
if (git_libgit2_init() < 0)
abort();
if (git_libgit2_opts(GIT_OPT_SET_PACK_MAX_OBJECTS, 10000000) < 0)
abort();
repo = fuzzer_repo_init();
return 0;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
git_object *obj = NULL;
char *c;
if ((c = calloc(1, size + 1)) == NULL)
abort();
memcpy(c, data, size);
git_revparse_single(&obj, repo, c);
git_object_free(obj);
free(c);
return 0;
}

View File

@ -122,8 +122,6 @@ GIT_EXTERN(git_attr_value_t) git_attr_value(const char *attr);
* Check attribute flags: controlling extended attribute behavior.
*
* Normally, attribute checks include looking in the /etc (or system
* equivalent) directory for a `gitattributes` file. Passing this
* flag will cause attribute checks to ignore that file.
* equivalent) directory for a `gitattributes` file. Passing the
* `GIT_ATTR_CHECK_NO_SYSTEM` flag will cause attribute checks to
* ignore that file.

View File

@ -366,7 +366,7 @@ GIT_EXTERN(int) git_commit_create(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[]);
git_commit * const parents[]);
/**
* Create new commit in the repository using a variable argument list.
@ -394,6 +394,49 @@ GIT_EXTERN(int) git_commit_create_v(
size_t parent_count,
...);
typedef struct {
unsigned int version;
/**
* Flags for creating the commit.
*
* If `allow_empty_commit` is specified, a commit with no changes
* from the prior commit (and "empty" commit) is allowed. Otherwise,
* commit creation will be stopped.
*/
unsigned int allow_empty_commit : 1;
/** The commit author, or NULL for the default. */
const git_signature *author;
/** The committer, or NULL for the default. */
const git_signature *committer;
/** Encoding for the commit message; leave NULL for default. */
const char *message_encoding;
} git_commit_create_options;
#define GIT_COMMIT_CREATE_OPTIONS_VERSION 1
#define GIT_COMMIT_CREATE_OPTIONS_INIT { GIT_COMMIT_CREATE_OPTIONS_VERSION }
/**
* Commits the staged changes in the repository; this is a near analog to
* `git commit -m message`.
*
* By default, empty commits are not allowed.
*
* @param id pointer to store the new commit's object id
* @param repo repository to commit changes in
* @param message the commit message
* @param opts options for creating the commit
* @return 0 on success, GIT_EUNCHANGED if there were no changes to commit, or an error code
*/
GIT_EXTERN(int) git_commit_create_from_stage(
git_oid *id,
git_repository *repo,
const char *message,
const git_commit_create_options *opts);
/**
* Amend an existing commit by replacing only non-NULL values.
*
@ -469,7 +512,7 @@ GIT_EXTERN(int) git_commit_create_buffer(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[]);
git_commit * const parents[]);
/**
* Create a commit object from the given buffer and signature
@ -538,9 +581,27 @@ typedef int (*git_commit_create_cb)(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[],
git_commit * const parents[],
void *payload);
/** An array of commits returned from the library */
typedef struct git_commitarray {
git_commit *const *commits;
size_t count;
} git_commitarray;
/**
* Free the commits contained in a commit array. This method should
* be called on `git_commitarray` objects that were provided by the
* library. Not doing so will result in a memory leak.
*
* This does not free the `git_commitarray` itself, since the library
* will never allocate that object directly itself.
*
* @param array The git_commitarray that contains commits to free
*/
GIT_EXTERN(void) git_commitarray_dispose(git_commitarray *array);
/** @} */
GIT_END_DECL
#endif

View File

@ -228,7 +228,9 @@ typedef enum {
GIT_OPT_SET_SERVER_CONNECT_TIMEOUT,
GIT_OPT_GET_SERVER_CONNECT_TIMEOUT,
GIT_OPT_SET_SERVER_TIMEOUT,
GIT_OPT_GET_SERVER_TIMEOUT
GIT_OPT_GET_SERVER_TIMEOUT,
GIT_OPT_SET_USER_AGENT_PRODUCT,
GIT_OPT_GET_USER_AGENT_PRODUCT
} git_libgit2_opt_t;
/**
@ -337,11 +339,35 @@ typedef enum {
*
* * opts(GIT_OPT_SET_USER_AGENT, const char *user_agent)
*
* > Set the value of the User-Agent header. This value will be
* > appended to "git/1.0", for compatibility with other git clients.
* > Set the value of the comment section of the User-Agent header.
* > This can be information about your product and its version.
* > By default this is "libgit2" followed by the libgit2 version.
* >
* > - `user_agent` is the value that will be delivered as the
* > User-Agent header on HTTP requests.
* > This value will be appended to User-Agent _product_, which
* > is typically set to "git/2.0".
* >
* > Set to the empty string ("") to not send any information in the
* > comment section, or set to NULL to restore the default.
*
* * opts(GIT_OPT_GET_USER_AGENT, git_buf *out)
*
* > Get the value of the User-Agent header.
* > The User-Agent is written to the `out` buffer.
*
* * opts(GIT_OPT_SET_USER_AGENT_PRODUCT, const char *user_agent_product)
*
* > Set the value of the product portion of the User-Agent header.
* > This defaults to "git/2.0", for compatibility with other git
* > clients. It is recommended to keep this as git/<version> for
* > compatibility with servers that do user-agent detection.
* >
* > Set to the empty string ("") to not send any user-agent string,
* > or set to NULL to restore the default.
*
* * opts(GIT_OPT_GET_USER_AGENT_PRODUCT, git_buf *out)
*
* > Get the value of the User-Agent product header.
* > The User-Agent product is written to the `out` buffer.
*
* * opts(GIT_OPT_SET_WINDOWS_SHAREMODE, unsigned long value)
*
@ -377,11 +403,6 @@ typedef enum {
* >
* > - `ciphers` is the list of ciphers that are eanbled.
*
* * opts(GIT_OPT_GET_USER_AGENT, git_buf *out)
*
* > Get the value of the User-Agent header.
* > The User-Agent is written to the `out` buffer.
*
* * opts(GIT_OPT_ENABLE_OFS_DELTA, int enabled)
*
* > Enable or disable the use of "offset deltas" when creating packfiles,
@ -490,10 +511,9 @@ typedef enum {
*
* opts(GIT_OPT_SET_SERVER_CONNECT_TIMEOUT, int timeout)
* > Sets the timeout (in milliseconds) to attempt connections to
* > a remote server. This is supported only for HTTP(S) connections
* > and is not supported by SSH. Set to 0 to use the system default.
* > Note that this may not be able to be configured longer than the
* > system default, typically 75 seconds.
* > a remote server. Set to 0 to use the system default. Note that
* > this may not be able to be configured longer than the system
* > default, typically 75 seconds.
*
* opts(GIT_OPT_GET_SERVER_TIMEOUT, int *timeout)
* > Gets the timeout (in milliseconds) for reading from and writing
@ -501,9 +521,7 @@ typedef enum {
*
* opts(GIT_OPT_SET_SERVER_TIMEOUT, int timeout)
* > Sets the timeout (in milliseconds) for reading from and writing
* > to a remote server. This is supported only for HTTP(S)
* > connections and is not supported by SSH. Set to 0 to use the
* > system default.
* > to a remote server. Set to 0 to use the system default.
*
* @param option Option key
* @param ... value to set the option

View File

@ -22,8 +22,19 @@ GIT_BEGIN_DECL
/**
* Priority level of a config file.
*
* These priority levels correspond to the natural escalation logic
* (from higher to lower) when searching for config entries in git.git.
* (from higher to lower) when reading or searching for config entries
* in git.git. Meaning that for the same key, the configuration in
* the local configuration is preferred over the configuration in
* the system configuration file.
*
* Callers can add their own custom configuration, beginning at the
* `GIT_CONFIG_LEVEL_APP` level.
*
* Writes, by default, occur in the highest priority level backend
* that is writable. This ordering can be overridden with
* `git_config_set_writeorder`.
*
* git_config_open_default() and git_repository_config() honor those
* priority levels as well.
@ -48,9 +59,13 @@ typedef enum {
*/
GIT_CONFIG_LEVEL_LOCAL = 5,
/** Worktree specific configuration file; $GIT_DIR/config.worktree
*/
GIT_CONFIG_LEVEL_WORKTREE = 6,
/** Application specific configuration file; freely defined by applications
*/
GIT_CONFIG_LEVEL_APP = 6,
GIT_CONFIG_LEVEL_APP = 7,
/** Represents the highest level available config file (i.e. the most
* specific config file available that actually is loaded)
@ -62,12 +77,32 @@ typedef enum {
* An entry in a configuration file
*/
typedef struct git_config_entry {
const char *name; /**< Name of the entry (normalised) */
const char *value; /**< String value of the entry */
unsigned int include_depth; /**< Depth of includes where this variable was found */
git_config_level_t level; /**< Which config file this was found in */
void GIT_CALLBACK(free)(struct git_config_entry *entry); /**< Free function for this entry */
void *payload; /**< Opaque value for the free function. Do not read or write */
/** Name of the configuration entry (normalized) */
const char *name;
/** Literal (string) value of the entry */
const char *value;
/** The type of backend that this entry exists in (eg, "file") */
const char *backend_type;
/**
* The path to the origin of this entry. For config files, this is
* the path to the file.
*/
const char *origin_path;
/** Depth of includes where this variable was found */
unsigned int include_depth;
/** Configuration level for the file this was found in */
git_config_level_t level;
/**
* Free function for this entry; for internal purposes. Callers
* should call `git_config_entry_free` to free data.
*/
void GIT_CALLBACK(free)(struct git_config_entry *entry);
} git_config_entry;
/**
@ -276,6 +311,11 @@ GIT_EXTERN(int) git_config_open_level(
*/
GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config);
GIT_EXTERN(int) git_config_set_writeorder(
git_config *cfg,
git_config_level_t *levels,
size_t len);
/**
* Create a snapshot of the configuration
*

View File

@ -8,6 +8,7 @@
#define INCLUDE_git_email_h__
#include "common.h"
#include "diff.h"
/**
* @file git2/email.h

View File

@ -59,7 +59,10 @@ typedef enum {
GIT_EINDEXDIRTY = -34, /**< Unsaved changes in the index would be overwritten */
GIT_EAPPLYFAIL = -35, /**< Patch application failed */
GIT_EOWNER = -36, /**< The object is not owned by the current user */
GIT_TIMEOUT = -37 /**< The operation timed out */
GIT_TIMEOUT = -37, /**< The operation timed out */
GIT_EUNCHANGED = -38, /**< There were no changes */
GIT_ENOTSUPPORTED = -39, /**< An option is not supported */
GIT_EREADONLY = -40 /**< The subject is read-only */
} git_error_code;
/**
@ -118,64 +121,23 @@ typedef enum {
* Return the last `git_error` object that was generated for the
* current thread.
*
* The default behaviour of this function is to return NULL if no previous error has occurred.
* However, libgit2's error strings are not cleared aggressively, so a prior
* (unrelated) error may be returned. This can be avoided by only calling
* this function if the prior call to a libgit2 API returned an error.
* This function will never return NULL.
*
* Callers should not rely on this to determine whether an error has
* occurred. For error checking, callers should examine the return
* codes of libgit2 functions.
*
* This call can only reliably report error messages when an error
* has occurred. (It may contain stale information if it is called
* after a different function that succeeds.)
*
* The memory for this object is managed by libgit2. It should not
* be freed.
*
* @return A git_error object.
*/
GIT_EXTERN(const git_error *) git_error_last(void);
/**
* Clear the last library error that occurred for this thread.
*/
GIT_EXTERN(void) git_error_clear(void);
/**
* Set the error message string for this thread, using `printf`-style
* formatting.
*
* This function is public so that custom ODB backends and the like can
* relay an error message through libgit2. Most regular users of libgit2
* will never need to call this function -- actually, calling it in most
* circumstances (for example, calling from within a callback function)
* will just end up having the value overwritten by libgit2 internals.
*
* This error message is stored in thread-local storage and only applies
* to the particular thread that this libgit2 call is made from.
*
* @param error_class One of the `git_error_t` enum above describing the
* general subsystem that is responsible for the error.
* @param fmt The `printf`-style format string; subsequent arguments must
* be the arguments for the format string.
*/
GIT_EXTERN(void) git_error_set(int error_class, const char *fmt, ...)
GIT_FORMAT_PRINTF(2, 3);
/**
* Set the error message string for this thread. This function is like
* `git_error_set` but takes a static string instead of a `printf`-style
* format.
*
* @param error_class One of the `git_error_t` enum above describing the
* general subsystem that is responsible for the error.
* @param string The error message to keep
* @return 0 on success or -1 on failure
*/
GIT_EXTERN(int) git_error_set_str(int error_class, const char *string);
/**
* Set the error message to a special value for memory allocation failure.
*
* The normal `git_error_set_str()` function attempts to `strdup()` the
* string that is passed in. This is not a good idea when the error in
* question is a memory allocation failure. That circumstance has a
* special setter function that sets the error string to a known and
* statically allocated internal value.
*/
GIT_EXTERN(void) git_error_set_oom(void);
/** @} */
GIT_END_DECL
#endif

View File

@ -58,7 +58,7 @@ GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
* Get the refspec's string
*
* @param refspec the refspec
* @returns the refspec's original string
* @return the refspec's original string
*/
GIT_EXTERN(const char *) git_refspec_string(const git_refspec *refspec);

View File

@ -76,6 +76,17 @@ typedef enum {
GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC = (1 << 1)
} git_remote_create_flags;
/**
* How to handle reference updates.
*/
typedef enum {
/* Write the fetch results to FETCH_HEAD. */
GIT_REMOTE_UPDATE_FETCHHEAD = (1 << 0),
/* Report unchanged tips in the update_tips callback. */
GIT_REMOTE_UPDATE_REPORT_UNCHANGED = (1 << 1)
} git_remote_update_flags;
/**
* Remote creation options structure
*
@ -733,10 +744,9 @@ typedef struct {
git_fetch_prune_t prune;
/**
* Whether to write the results to FETCH_HEAD. Defaults to
* on. Leave this default in order to behave like git.
* How to handle reference updates; see `git_remote_update_flags`.
*/
int update_fetchhead;
unsigned int update_fetchhead;
/**
* Determines how to behave regarding tags on the remote, such
@ -775,8 +785,13 @@ typedef struct {
} git_fetch_options;
#define GIT_FETCH_OPTIONS_VERSION 1
#define GIT_FETCH_OPTIONS_INIT { GIT_FETCH_OPTIONS_VERSION, GIT_REMOTE_CALLBACKS_INIT, GIT_FETCH_PRUNE_UNSPECIFIED, 1, \
GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED, GIT_PROXY_OPTIONS_INIT }
#define GIT_FETCH_OPTIONS_INIT { \
GIT_FETCH_OPTIONS_VERSION, \
GIT_REMOTE_CALLBACKS_INIT, \
GIT_FETCH_PRUNE_UNSPECIFIED, \
GIT_REMOTE_UPDATE_FETCHHEAD, \
GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED, \
GIT_PROXY_OPTIONS_INIT }
/**
* Initialize git_fetch_options structure
@ -830,6 +845,11 @@ typedef struct {
* Extra headers for this push operation
*/
git_strarray custom_headers;
/**
* "Push options" to deliver to the remote.
*/
git_strarray remote_push_options;
} git_push_options;
#define GIT_PUSH_OPTIONS_VERSION 1
@ -1001,7 +1021,7 @@ GIT_EXTERN(int) git_remote_upload(
* the name of the remote (or its url, for in-memory remotes). This
* parameter is ignored when pushing.
* @param callbacks pointer to the callback structure to use or NULL
* @param update_fetchhead whether to write to FETCH_HEAD. Pass 1 to behave like git.
* @param update_flags the git_remote_update_flags for these tips.
* @param download_tags what the behaviour for downloading tags is for this fetch. This is
* ignored for push. This must be the same value passed to `git_remote_download()`.
* @return 0 or an error code
@ -1009,7 +1029,7 @@ GIT_EXTERN(int) git_remote_upload(
GIT_EXTERN(int) git_remote_update_tips(
git_remote *remote,
const git_remote_callbacks *callbacks,
int update_fetchhead,
unsigned int update_flags,
git_remote_autotag_option_t download_tags,
const char *reflog_message);

View File

@ -11,6 +11,7 @@
#include "types.h"
#include "oid.h"
#include "buffer.h"
#include "commit.h"
/**
* @file git2/repository.h
@ -503,6 +504,7 @@ typedef enum {
GIT_REPOSITORY_ITEM_LOGS,
GIT_REPOSITORY_ITEM_MODULES,
GIT_REPOSITORY_ITEM_WORKTREES,
GIT_REPOSITORY_ITEM_WORKTREE_CONFIG,
GIT_REPOSITORY_ITEM__LAST
} git_repository_item_t;
@ -978,6 +980,17 @@ GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name,
*/
GIT_EXTERN(git_oid_t) git_repository_oid_type(git_repository *repo);
/**
* Gets the parents of the next commit, given the current repository state.
* Generally, this is the HEAD commit, except when performing a merge, in
* which case it is two or more commits.
*
* @param commits a `git_commitarray` that will contain the commit parents
* @param repo the repository
* @return 0 or an error code
*/
GIT_EXTERN(int) git_repository_commit_parents(git_commitarray *commits, git_repository *repo);
/** @} */
GIT_END_DECL
#endif

View File

@ -125,6 +125,57 @@ GIT_EXTERN(int) git_config_add_backend(
const git_repository *repo,
int force);
/** Options for in-memory configuration backends. */
typedef struct {
unsigned int version;
/**
* The type of this backend (eg, "command line"). If this is
* NULL, then this will be "in-memory".
*/
const char *backend_type;
/**
* The path to the origin; if this is NULL then it will be
* left unset in the resulting configuration entries.
*/
const char *origin_path;
} git_config_backend_memory_options;
#define GIT_CONFIG_BACKEND_MEMORY_OPTIONS_VERSION 1
#define GIT_CONFIG_BACKEND_MEMORY_OPTIONS_INIT { GIT_CONFIG_BACKEND_MEMORY_OPTIONS_VERSION }
/**
* Create an in-memory configuration backend from a string in standard
* git configuration file format.
*
* @param out the new backend
* @param cfg the configuration that is to be parsed
* @param len the length of the string pointed to by `cfg`
* @param opts the options to initialize this backend with, or NULL
*/
extern int git_config_backend_from_string(
git_config_backend **out,
const char *cfg,
size_t len,
git_config_backend_memory_options *opts);
/**
* Create an in-memory configuration backend from a list of name/value
* pairs.
*
* @param out the new backend
* @param values the configuration values to set (in "key=value" format)
* @param len the length of the values array
* @param opts the options to initialize this backend with, or NULL
*/
extern int git_config_backend_from_values(
git_config_backend **out,
const char **values,
size_t len,
git_config_backend_memory_options *opts);
/** @} */
GIT_END_DECL
#endif

View File

@ -7,6 +7,11 @@
#ifndef INCLUDE_sys_git_email_h__
#define INCLUDE_sys_git_email_h__
#include "git2/common.h"
#include "git2/diff.h"
#include "git2/email.h"
#include "git2/types.h"
/**
* @file git2/sys/email.h
* @brief Advanced git email creation routines

66
include/git2/sys/errors.h Normal file
View File

@ -0,0 +1,66 @@
/*
* 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_sys_git_errors_h__
#define INCLUDE_sys_git_errors_h__
#include "git2/common.h"
GIT_BEGIN_DECL
/**
* Clear the last library error that occurred for this thread.
*/
GIT_EXTERN(void) git_error_clear(void);
/**
* Set the error message string for this thread, using `printf`-style
* formatting.
*
* This function is public so that custom ODB backends and the like can
* relay an error message through libgit2. Most regular users of libgit2
* will never need to call this function -- actually, calling it in most
* circumstances (for example, calling from within a callback function)
* will just end up having the value overwritten by libgit2 internals.
*
* This error message is stored in thread-local storage and only applies
* to the particular thread that this libgit2 call is made from.
*
* @param error_class One of the `git_error_t` enum above describing the
* general subsystem that is responsible for the error.
* @param fmt The `printf`-style format string; subsequent arguments must
* be the arguments for the format string.
*/
GIT_EXTERN(void) git_error_set(int error_class, const char *fmt, ...)
GIT_FORMAT_PRINTF(2, 3);
/**
* Set the error message string for this thread. This function is like
* `git_error_set` but takes a static string instead of a `printf`-style
* format.
*
* @param error_class One of the `git_error_t` enum above describing the
* general subsystem that is responsible for the error.
* @param string The error message to keep
* @return 0 on success or -1 on failure
*/
GIT_EXTERN(int) git_error_set_str(int error_class, const char *string);
/**
* Set the error message to a special value for memory allocation failure.
*
* The normal `git_error_set_str()` function attempts to `strdup()` the
* string that is passed in. This is not a good idea when the error in
* question is a memory allocation failure. That circumstance has a
* special setter function that sets the error string to a known and
* statically allocated internal value.
*/
GIT_EXTERN(void) git_error_set_oom(void);
GIT_END_DECL
#endif

View File

@ -20,12 +20,18 @@
GIT_BEGIN_DECL
/**
* A remote's capabilities.
*/
typedef enum {
/** Remote supports fetching an advertised object by ID. */
GIT_REMOTE_CAPABILITY_TIP_OID = (1 << 0),
/** Remote supports fetching an individual reachable object. */
GIT_REMOTE_CAPABILITY_REACHABLE_OID = (1 << 1),
/** Remote supports push options. */
GIT_REMOTE_CAPABILITY_PUSH_OPTIONS = (1 << 2),
} git_remote_capability_t;
/**

View File

@ -9,6 +9,7 @@
#include "git2/common.h"
#include "git2/types.h"
#include "git2/oid.h"
/**
* @file git2/sys/repository.h
@ -32,7 +33,11 @@ GIT_BEGIN_DECL
* @param out The blank repository
* @return 0 on success, or an error code
*/
#ifdef GIT_EXPERIMENTAL_SHA256
GIT_EXTERN(int) git_repository_new(git_repository **out, git_oid_t oid_type);
#else
GIT_EXTERN(int) git_repository_new(git_repository **out);
#endif
/**
* Reset all the internal state in a repository.

View File

@ -29,7 +29,7 @@ GIT_BEGIN_DECL
typedef struct git_stream {
int version;
int encrypted : 1,
unsigned int encrypted : 1,
proxy_support : 1;
/**

View File

@ -11,16 +11,16 @@
* The version string for libgit2. This string follows semantic
* versioning (v2) guidelines.
*/
#define LIBGIT2_VERSION "1.7.2"
#define LIBGIT2_VERSION "1.8.1"
/** The major version number for this version of libgit2. */
#define LIBGIT2_VER_MAJOR 1
/** The minor version number for this version of libgit2. */
#define LIBGIT2_VER_MINOR 7
#define LIBGIT2_VER_MINOR 8
/** The revision ("teeny") version number for this version of libgit2. */
#define LIBGIT2_VER_REVISION 2
#define LIBGIT2_VER_REVISION 1
/** The Windows DLL patch number for this version of libgit2. */
#define LIBGIT2_VER_PATCH 0
@ -33,7 +33,11 @@
*/
#define LIBGIT2_VER_PRERELEASE NULL
/** The library ABI soversion for this version of libgit2. */
#define LIBGIT2_SOVERSION "1.7"
/**
* The library ABI soversion for this version of libgit2. This should
* only be changed when the library has a breaking ABI change, and so
* may trail the library's version number.
*/
#define LIBGIT2_SOVERSION "1.8"
#endif

View File

@ -11,6 +11,7 @@
#include "buffer.h"
#include "types.h"
#include "strarray.h"
#include "checkout.h"
/**
* @file git2/worktrees.h
@ -86,6 +87,7 @@ typedef struct git_worktree_add_options {
unsigned int version;
int lock; /**< lock newly created worktree */
int checkout_existing; /**< allow checkout of existing branch matching worktree name */
git_reference *ref; /**< reference to use for the new worktree HEAD */
/**
@ -95,7 +97,8 @@ typedef struct git_worktree_add_options {
} git_worktree_add_options;
#define GIT_WORKTREE_ADD_OPTIONS_VERSION 1
#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL,GIT_CHECKOUT_OPTIONS_INIT}
#define GIT_WORKTREE_ADD_OPTIONS_INIT { GIT_WORKTREE_ADD_OPTIONS_VERSION, \
0, 0, NULL, GIT_CHECKOUT_OPTIONS_INIT }
/**
* Initialize git_worktree_add_options structure

View File

@ -1,6 +1,6 @@
{
"name": "libgit2",
"version": "1.7.2",
"version": "1.8.1",
"repo": "https://github.com/libgit2/libgit2",
"description": " A cross-platform, linkable library implementation of Git that you can use in your application.",
"install": "mkdir build && cd build && cmake .. && cmake --build ."

View File

@ -1,2 +1,2 @@
#!/bin/bash
exec valgrind --leak-check=full --show-reachable=yes --error-exitcode=125 --num-callers=50 --suppressions="$(dirname "${BASH_SOURCE[0]}")/valgrind.supp" "$@"
exec valgrind --leak-check=full --show-reachable=yes --child-silent-after-fork=yes --error-exitcode=125 --num-callers=50 --suppressions="$(dirname "${BASH_SOURCE[0]}")/valgrind.supp" "$@"

View File

@ -80,6 +80,13 @@
fun:__check_pf
}
{
ignore-glibc-getaddrinfo-fn
Memcheck:Leak
...
fun:getaddrinfo
}
{
ignore-curl-global-init
Memcheck:Leak
@ -191,6 +198,16 @@
...
}
{
ignore-openssl-undefined-in-connect
Memcheck:Cond
...
obj:*libcrypto.so*
...
fun:openssl_connect
...
}
{
ignore-libssh2-rsa-sha1-sign
Memcheck:Leak

View File

@ -135,7 +135,8 @@ endif()
# platform libraries
if(WIN32)
list(APPEND LIBGIT2_SYSTEM_LIBS ws2_32)
list(APPEND LIBGIT2_SYSTEM_LIBS "ws2_32" "secur32")
list(APPEND LIBGIT2_PC_LIBS "-lws2_32" "-lsecur32")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
@ -183,7 +184,7 @@ add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix")
# iconv
if(USE_ICONV)
find_package(Iconv)
find_package(IntlIconv)
endif()
if(ICONV_FOUND)
set(GIT_USE_ICONV 1)

View File

@ -4,7 +4,8 @@ set(CLI_INCLUDES
"${libgit2_SOURCE_DIR}/src/util"
"${libgit2_SOURCE_DIR}/src/cli"
"${libgit2_SOURCE_DIR}/include"
"${LIBGIT2_DEPENDENCY_INCLUDES}")
"${LIBGIT2_DEPENDENCY_INCLUDES}"
"${LIBGIT2_SYSTEM_INCLUDES}")
if(WIN32 AND NOT CYGWIN)
file(GLOB CLI_SRC_OS win32/*.c)

View File

@ -1,20 +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 CLI_cli_h__
#define CLI_cli_h__
#define PROGRAM_NAME "git2"
#include "git2_util.h"
#include "error.h"
#include "opt.h"
#include "opt_usage.h"
#include "sighandler.h"
#endif /* CLI_cli_h__ */

View File

@ -5,7 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "cli.h"
#include "common.h"
#include "cmd.h"
const cli_cmd_spec *cli_cmd_spec_byname(const char *name)

View File

@ -27,7 +27,9 @@ extern const cli_cmd_spec *cli_cmd_spec_byname(const char *name);
/* Commands */
extern int cmd_cat_file(int argc, char **argv);
extern int cmd_clone(int argc, char **argv);
extern int cmd_config(int argc, char **argv);
extern int cmd_hash_object(int argc, char **argv);
extern int cmd_help(int argc, char **argv);
extern int cmd_index_pack(int argc, char **argv);
#endif /* CLI_cmd_h__ */

View File

@ -6,7 +6,7 @@
*/
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#define COMMAND_NAME "cat-file"
@ -24,9 +24,7 @@ static int display = DISPLAY_CONTENT;
static char *type_name, *object_spec;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_SWITCH, NULL, 't', &display, DISPLAY_TYPE,
CLI_OPT_USAGE_REQUIRED, NULL, "display the type of the object" },
@ -139,6 +137,7 @@ static int print_pretty(git_object *object)
int cmd_cat_file(int argc, char **argv)
{
cli_repository_open_options open_opts = { argv + 1, argc - 1};
git_repository *repo = NULL;
git_object *object = NULL;
git_object_t type;
@ -153,7 +152,7 @@ int cmd_cat_file(int argc, char **argv)
return 0;
}
if (git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0)
if (cli_repository_open(&repo, &open_opts) < 0)
return cli_error_git();
if ((giterr = git_revparse_single(&object, repo, object_spec)) < 0) {

View File

@ -7,7 +7,7 @@
#include <stdio.h>
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#include "error.h"
#include "sighandler.h"
@ -24,9 +24,7 @@ static bool local_path_exists;
static cli_progress progress = CLI_PROGRESS_INIT;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_SWITCH, "quiet", 'q', &quiet, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display the type of the object" },

242
src/cli/cmd_config.c Normal file
View File

@ -0,0 +1,242 @@
/*
* 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 <git2.h>
#include "common.h"
#include "cmd.h"
#define COMMAND_NAME "config"
typedef enum {
ACTION_NONE = 0,
ACTION_GET,
ACTION_ADD,
ACTION_REPLACE_ALL,
ACTION_LIST
} action_t;
static action_t action = ACTION_NONE;
static int show_origin;
static int show_scope;
static int show_help;
static int null_separator;
static int config_level;
static char *config_filename;
static char *name, *value, *value_pattern;
static const cli_opt_spec opts[] = {
CLI_COMMON_OPT, \
{ CLI_OPT_TYPE_SWITCH, "null", 'z', &null_separator, 1,
0, NULL, "use NUL as a separator" },
{ CLI_OPT_TYPE_SWITCH, "system", 0, &config_level, GIT_CONFIG_LEVEL_SYSTEM,
0, NULL, "read/write to system configuration" },
{ CLI_OPT_TYPE_SWITCH, "global", 0, &config_level, GIT_CONFIG_LEVEL_GLOBAL,
CLI_OPT_USAGE_CHOICE, NULL, "read/write to global configuration" },
{ CLI_OPT_TYPE_SWITCH, "local", 0, &config_level, GIT_CONFIG_LEVEL_LOCAL,
CLI_OPT_USAGE_CHOICE, NULL, "read/write to local configuration" },
{ CLI_OPT_TYPE_VALUE, "file", 0, &config_filename, 0,
CLI_OPT_USAGE_CHOICE, "filename", "read/write to specified configuration file" },
{ CLI_OPT_TYPE_SWITCH, "get", 0, &action, ACTION_GET,
CLI_OPT_USAGE_REQUIRED, NULL, "get a configuration value" },
{ CLI_OPT_TYPE_SWITCH, "add", 0, &action, ACTION_ADD,
CLI_OPT_USAGE_CHOICE, NULL, "add a configuration value" },
{ CLI_OPT_TYPE_SWITCH, "replace-all", 0, &action, ACTION_REPLACE_ALL,
CLI_OPT_USAGE_CHOICE, NULL, "add a configuration value, replacing any old values" },
{ CLI_OPT_TYPE_SWITCH, "list", 'l', &action, ACTION_LIST,
CLI_OPT_USAGE_CHOICE | CLI_OPT_USAGE_SHOW_LONG,
NULL, "list all configuration entries" },
{ CLI_OPT_TYPE_SWITCH, "show-origin", 0, &show_origin, 1,
0, NULL, "show origin of configuration" },
{ CLI_OPT_TYPE_SWITCH, "show-scope", 0, &show_scope, 1,
0, NULL, "show scope of configuration" },
{ CLI_OPT_TYPE_ARG, "name", 0, &name, 0,
0, "name", "name of configuration entry" },
{ CLI_OPT_TYPE_ARG, "value", 0, &value, 0,
0, "value", "value of configuration entry" },
{ CLI_OPT_TYPE_ARG, "regexp", 0, &value_pattern, 0,
0, "regexp", "regular expression of values to replace" },
{ 0 },
};
static void print_help(void)
{
cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts);
printf("\n");
printf("Query and set configuration options.\n");
printf("\n");
printf("Options:\n");
cli_opt_help_fprint(stdout, opts);
}
static int get_config(git_config *config)
{
git_buf value = GIT_BUF_INIT;
char sep = null_separator ? '\0' : '\n';
int error;
error = git_config_get_string_buf(&value, config, name);
if (error && error != GIT_ENOTFOUND)
return cli_error_git();
else if (error == GIT_ENOTFOUND)
return 1;
printf("%s%c", value.ptr, sep);
return 0;
}
static int add_config(git_config *config)
{
if (git_config_set_multivar(config, name, "$^", value) < 0)
return cli_error_git();
return 0;
}
static int replace_all_config(git_config *config)
{
if (git_config_set_multivar(config, name, value_pattern ? value_pattern : ".*", value) < 0)
return cli_error_git();
return 0;
}
static const char *level_name(git_config_level_t level)
{
switch (level) {
case GIT_CONFIG_LEVEL_PROGRAMDATA:
return "programdata";
case GIT_CONFIG_LEVEL_SYSTEM:
return "system";
case GIT_CONFIG_LEVEL_XDG:
return "global";
case GIT_CONFIG_LEVEL_GLOBAL:
return "global";
case GIT_CONFIG_LEVEL_LOCAL:
return "local";
case GIT_CONFIG_LEVEL_APP:
return "command";
default:
return "unknown";
}
}
static int list_config(git_config *config)
{
git_config_iterator *iterator;
git_config_entry *entry;
char data_separator = null_separator ? '\0' : '\t';
char kv_separator = null_separator ? '\n' : '=';
char entry_separator = null_separator ? '\0' : '\n';
int error;
if (git_config_iterator_new(&iterator, config) < 0)
return cli_error_git();
while ((error = git_config_next(&entry, iterator)) == 0) {
if (show_scope)
printf("%s%c",
level_name(entry->level),
data_separator);
if (show_origin)
printf("%s%s%s%c",
entry->backend_type ? entry->backend_type : "",
entry->backend_type && entry->origin_path ? ":" : "",
entry->origin_path ? entry->origin_path : "",
data_separator);
printf("%s%c%s%c", entry->name, kv_separator, entry->value,
entry_separator);
}
if (error != GIT_ITEROVER)
return cli_error_git();
git_config_iterator_free(iterator);
return 0;
}
int cmd_config(int argc, char **argv)
{
git_repository *repo = NULL;
git_config *config = NULL;
cli_repository_open_options open_opts = { argv + 1, argc - 1};
cli_opt invalid_opt;
int ret = 0;
if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU))
return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt);
if (show_help) {
print_help();
return 0;
}
if (config_filename) {
if (git_config_new(&config) < 0 ||
git_config_add_file_ondisk(config, config_filename,
GIT_CONFIG_LEVEL_APP, NULL, 0) < 0) {
ret = cli_error_git();
goto done;
}
} else {
if (cli_repository_open(&repo, &open_opts) < 0 ||
git_repository_config(&config, repo) < 0) {
ret = cli_error_git();
goto done;
}
if (config_level &&
git_config_open_level(&config, config, config_level) < 0) {
ret = cli_error_git();
goto done;
}
}
switch (action) {
case ACTION_ADD:
if (!name || !value || value_pattern)
ret = cli_error_usage("%s --add requires two arguments", COMMAND_NAME);
else
ret = add_config(config);
break;
case ACTION_REPLACE_ALL:
if (!name || !value)
ret = cli_error_usage("%s --replace-all requires two or three arguments", COMMAND_NAME);
else
ret = replace_all_config(config);
break;
case ACTION_GET:
if (!name)
ret = cli_error_usage("%s --get requires an argument", COMMAND_NAME);
else
ret = get_config(config);
break;
case ACTION_LIST:
if (name)
ret = cli_error_usage("%s --list does not take an argument", COMMAND_NAME);
else
ret = list_config(config);
break;
default:
ret = cli_error_usage("unknown action");
}
done:
git_config_free(config);
git_repository_free(repo);
return ret;
}

View File

@ -6,7 +6,7 @@
*/
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#include "futils.h"
@ -19,9 +19,7 @@ static int write_object, read_stdin, literally;
static char **filenames;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_VALUE, NULL, 't', &type_name, 0,
CLI_OPT_USAGE_DEFAULT, "type", "the type of object to hash (default: \"blob\")" },
@ -92,6 +90,7 @@ static int hash_buf(
int cmd_hash_object(int argc, char **argv)
{
cli_repository_open_options open_opts = { argv + 1, argc - 1};
git_repository *repo = NULL;
git_odb *odb = NULL;
git_oid_t oid_type;
@ -113,7 +112,7 @@ int cmd_hash_object(int argc, char **argv)
return cli_error_usage("invalid object type '%s'", type_name);
if (write_object &&
(git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0 ||
(cli_repository_open(&repo, &open_opts) < 0 ||
git_repository_odb(&odb, repo) < 0)) {
ret = cli_error_git();
goto done;

View File

@ -7,7 +7,7 @@
#include <stdio.h>
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#define COMMAND_NAME "help"
@ -16,8 +16,8 @@ static char *command;
static int show_help;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN, NULL, "display help about the help command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_ARG, "command", 0, &command, 0,
CLI_OPT_USAGE_DEFAULT, "command", "the command to show help for" },
{ 0 },

114
src/cli/cmd_index_pack.c Normal file
View File

@ -0,0 +1,114 @@
/*
* 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 <git2.h>
#include "common.h"
#include "cmd.h"
#include "progress.h"
#define COMMAND_NAME "index-pack"
#define BUFFER_SIZE (1024 * 1024)
static int show_help, verbose, read_stdin;
static char *filename;
static cli_progress progress = CLI_PROGRESS_INIT;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
{ CLI_OPT_TYPE_SWITCH, "verbose", 'v', &verbose, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display progress output" },
{ CLI_OPT_TYPE_LITERAL },
{ CLI_OPT_TYPE_SWITCH, "stdin", 0, &read_stdin, 1,
CLI_OPT_USAGE_REQUIRED, NULL, "read from stdin" },
{ CLI_OPT_TYPE_ARG, "pack-file", 0, &filename, 0,
CLI_OPT_USAGE_CHOICE, "pack-file", "packfile path" },
{ 0 },
};
static void print_help(void)
{
cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts);
printf("\n");
printf("Indexes a packfile and writes the index to disk.\n");
printf("\n");
printf("Options:\n");
cli_opt_help_fprint(stdout, opts);
}
int cmd_index_pack(int argc, char **argv)
{
cli_opt invalid_opt;
git_indexer *idx = NULL;
git_indexer_options idx_opts = GIT_INDEXER_OPTIONS_INIT;
git_indexer_progress stats = {0};
char buf[BUFFER_SIZE];
ssize_t read_len;
int fd, ret;
if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU))
return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt);
if (show_help) {
print_help();
return 0;
}
if (verbose) {
idx_opts.progress_cb = cli_progress_indexer;
idx_opts.progress_cb_payload = &progress;
}
if (read_stdin) {
fd = fileno(stdin);
} else if ((fd = p_open(filename, O_RDONLY)) < 0) {
ret = cli_error_git();
goto done;
}
#ifdef GIT_EXPERIMENTAL_SHA256
ret = git_indexer_new(&idx, ".", GIT_OID_SHA1, &idx_opts);
#else
ret = git_indexer_new(&idx, ".", 0, NULL, &idx_opts);
#endif
if (ret < 0) {
ret = cli_error_git();
goto done;
}
while ((read_len = p_read(fd, buf, sizeof(buf))) > 0) {
if (git_indexer_append(idx, buf, (size_t)read_len, &stats) < 0) {
ret = cli_error_git();
goto done;
}
}
if (git_indexer_commit(idx, &stats) < 0) {
ret = cli_error_git();
goto done;
}
cli_progress_finish(&progress);
done:
if (!read_stdin && fd >= 0)
p_close(fd);
cli_progress_dispose(&progress);
git_indexer_free(idx);
return ret;
}

126
src/cli/common.c Normal file
View File

@ -0,0 +1,126 @@
/*
* 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 <git2.h>
#include <git2/sys/config.h>
#include "git2_util.h"
#include "vector.h"
#include "common.h"
#include "error.h"
static int parse_option(cli_opt *opt, void *data)
{
git_str kv = GIT_STR_INIT, env = GIT_STR_INIT;
git_vector *cmdline_config = data;
int error = 0;
if (opt->spec && opt->spec->alias == 'c') {
if (git_str_puts(&kv, opt->value) < 0) {
error = cli_error_git();
goto done;
}
}
else if (opt->spec && !strcmp(opt->spec->name, "config-env")) {
char *val = strchr(opt->value, '=');
if (val == NULL || *(val + 1) == '\0') {
error = cli_error("invalid config format: '%s'", opt->value);
goto done;
}
if (git_str_put(&kv, opt->value, (val - opt->value)) < 0) {
error = cli_error_git();
goto done;
}
val++;
if ((error = git__getenv(&env, val)) == GIT_ENOTFOUND) {
error = cli_error("missing environment variable '%s' for configuration '%s'", val, kv.ptr);
goto done;
} else if (error) {
error = cli_error_git();
goto done;
}
if (git_str_putc(&kv, '=') < 0 ||
git_str_puts(&kv, env.ptr) < 0) {
error = cli_error_git();
goto done;
}
}
if (kv.size > 0 &&
git_vector_insert(cmdline_config, git_str_detach(&kv)) < 0)
error = cli_error_git();
done:
git_str_dispose(&env);
git_str_dispose(&kv);
return error;
}
static int parse_common_options(
git_repository *repo,
cli_repository_open_options *opts)
{
cli_opt_spec common_opts[] = {
{ CLI_COMMON_OPT_CONFIG },
{ CLI_COMMON_OPT_CONFIG_ENV },
{ 0 }
};
git_config_backend_memory_options config_opts =
GIT_CONFIG_BACKEND_MEMORY_OPTIONS_INIT;
git_vector cmdline = GIT_VECTOR_INIT;
git_config *config = NULL;
git_config_backend *backend = NULL;
int error = 0;
config_opts.backend_type = "command line";
if ((error = cli_opt_foreach(common_opts, opts->args,
opts->args_len, CLI_OPT_PARSE_GNU, parse_option,
&cmdline)) < 0)
goto done;
if (git_vector_length(&cmdline) == 0)
goto done;
if (git_repository_config(&config, repo) < 0 ||
git_config_backend_from_values(&backend,
(const char **)cmdline.contents, cmdline.length,
&config_opts) < 0 ||
git_config_add_backend(config, backend, GIT_CONFIG_LEVEL_APP,
repo, 0) < 0)
error = cli_error_git();
done:
if (error && backend)
backend->free(backend);
git_config_free(config);
git_vector_free_deep(&cmdline);
return error;
}
int cli_repository_open(
git_repository **out,
cli_repository_open_options *opts)
{
git_repository *repo;
if (git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0)
return -1;
if (opts && parse_common_options(repo, opts) < 0)
return -1;
*out = repo;
return 0;
}

66
src/cli/common.h Normal file
View File

@ -0,0 +1,66 @@
/*
* 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 CLI_common_h__
#define CLI_common_h__
#define PROGRAM_NAME "git2"
#include "git2_util.h"
#include "error.h"
#include "opt.h"
#include "opt_usage.h"
/*
* Common command arguments.
*/
#define CLI_COMMON_OPT_HELP \
CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, \
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING
#define CLI_COMMON_OPT_CONFIG \
CLI_OPT_TYPE_VALUE, NULL, 'c', NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT_CONFIG_ENV \
CLI_OPT_TYPE_VALUE, "config-env", 0, NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT \
{ CLI_COMMON_OPT_HELP }, \
{ CLI_COMMON_OPT_CONFIG }, \
{ CLI_COMMON_OPT_CONFIG_ENV }
typedef struct {
char **args;
int args_len;
} cli_repository_open_options;
extern int cli_repository_open(
git_repository **out,
cli_repository_open_options *opts);
/*
* Common command arguments.
*/
#define CLI_COMMON_OPT_HELP \
CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, \
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING
#define CLI_COMMON_OPT_CONFIG \
CLI_OPT_TYPE_VALUE, NULL, 'c', NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT_CONFIG_ENV \
CLI_OPT_TYPE_VALUE, "config-env", 0, NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT \
{ CLI_COMMON_OPT_HELP }, \
{ CLI_COMMON_OPT_CONFIG }, \
{ CLI_COMMON_OPT_CONFIG_ENV }
#endif /* CLI_common_h__ */

View File

@ -8,7 +8,7 @@
#ifndef CLI_error_h__
#define CLI_error_h__
#include "cli.h"
#include "common.h"
#include <stdio.h>
#define CLI_EXIT_OK 0

View File

@ -7,7 +7,7 @@
#include <stdio.h>
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
static int show_help = 0;
@ -18,6 +18,10 @@ static char **args = NULL;
const cli_opt_spec cli_common_opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display help information" },
{ CLI_OPT_TYPE_VALUE, NULL, 'c', NULL, 0,
CLI_OPT_USAGE_DEFAULT, "key=value", "add configuration value" },
{ CLI_OPT_TYPE_VALUE, "config-env", 0, NULL, 0,
CLI_OPT_USAGE_DEFAULT, "key=value", "set configuration value to environment variable" },
{ CLI_OPT_TYPE_SWITCH, "version", 0, &show_version, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display the version" },
{ CLI_OPT_TYPE_ARG, "command", 0, &command, 0,
@ -30,19 +34,40 @@ const cli_opt_spec cli_common_opts[] = {
const cli_cmd_spec cli_cmds[] = {
{ "cat-file", cmd_cat_file, "Display an object in the repository" },
{ "clone", cmd_clone, "Clone a repository into a new directory" },
{ "config", cmd_config, "View or set configuration values " },
{ "hash-object", cmd_hash_object, "Hash a raw object and product its object ID" },
{ "help", cmd_help, "Display help information" },
{ "index-pack", cmd_index_pack, "Create an index for a packfile" },
{ NULL }
};
/*
* Reorder the argv as it was given, since git has the notion of global
* options (like `--help` or `-c key=val`) that we want to pass to the
* subcommand, and that can appear early in the arguments, before the
* command name. Put the command-name in argv[1] to allow easier parsing.
*/
static void reorder_args(char **argv, size_t first)
{
char *tmp;
size_t i;
if (first == 1)
return;
tmp = argv[first];
for (i = first; i > 1; i--)
argv[i] = argv[i - 1];
argv[1] = tmp;
}
int main(int argc, char **argv)
{
const cli_cmd_spec *cmd;
cli_opt_parser optparser;
cli_opt opt;
char *help_args[3] = { NULL };
int help_args_len;
int args_len = 0;
int ret = 0;
if (git_libgit2_init() < 0) {
@ -66,8 +91,7 @@ int main(int argc, char **argv)
* remaining arguments as args for the command itself.
*/
if (command) {
args = &argv[optparser.idx];
args_len = (int)(argc - optparser.idx);
reorder_args(argv, optparser.idx);
break;
}
}
@ -77,19 +101,9 @@ int main(int argc, char **argv)
goto done;
}
/*
* If `--help <command>` is specified, delegate to that command's
* `--help` option. If no command is specified, run the `help`
* command. Do this by updating the args to emulate that behavior.
*/
if (!command || show_help) {
help_args[0] = command ? (char *)command : "help";
help_args[1] = command ? "--help" : NULL;
help_args_len = command ? 2 : 1;
command = help_args[0];
args = help_args;
args_len = help_args_len;
if (!command) {
ret = cmd_help(argc, argv);
goto done;
}
if ((cmd = cli_cmd_spec_byname(command)) == NULL) {
@ -98,7 +112,7 @@ int main(int argc, char **argv)
goto done;
}
ret = cmd->fn(args_len, args);
ret = cmd->fn(argc - 1, &argv[1]);
done:
git_libgit2_shutdown();

View File

@ -10,7 +10,7 @@
* This file was produced by using the `rename.pl` script included with
* adopt. The command-line specified was:
*
* ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status --without-usage
* ./rename.pl cli_opt --filename=opt --include=common.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status --without-usage
*/
#include <stdlib.h>
@ -19,7 +19,11 @@
#include <limits.h>
#include <assert.h>
#include "cli.h"
#if defined(__sun) || defined(__illumos__)
# include <alloca.h>
#endif
#include "common.h"
#include "opt.h"
#ifdef _WIN32
@ -73,7 +77,7 @@ GIT_INLINE(const cli_opt_spec *) spec_for_long(
/* Handle --option=value arguments */
if (spec->type == CLI_OPT_TYPE_VALUE &&
eql &&
spec->name && eql &&
strncmp(arg, spec->name, eql_pos) == 0 &&
spec->name[eql_pos] == '\0') {
*has_value = 1;
@ -575,6 +579,28 @@ cli_opt_status_t cli_opt_parse(
return validate_required(opt, specs, given_specs);
}
int cli_opt_foreach(
const cli_opt_spec specs[],
char **args,
size_t args_len,
unsigned int flags,
int (*callback)(cli_opt *, void *),
void *callback_data)
{
cli_opt_parser parser;
cli_opt opt;
int ret;
cli_opt_parser_init(&parser, specs, args, args_len, flags);
while (cli_opt_parser_next(&opt, &parser)) {
if ((ret = callback(&opt, callback_data)) != 0)
return ret;
}
return 0;
}
static int spec_name_fprint(FILE *file, const cli_opt_spec *spec)
{
int error;

View File

@ -10,7 +10,7 @@
* This file was produced by using the `rename.pl` script included with
* adopt. The command-line specified was:
*
* ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status --without-usage
* ./rename.pl cli_opt --filename=opt --include=common.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status --without-usage
*/
#ifndef CLI_opt_h__
@ -275,7 +275,7 @@ typedef struct cli_opt_parser {
size_t arg_idx;
size_t in_args;
size_t in_short;
int needs_sort : 1,
unsigned int needs_sort : 1,
in_literal : 1;
} cli_opt_parser;
@ -300,6 +300,24 @@ cli_opt_status_t cli_opt_parse(
size_t args_len,
unsigned int flags);
/**
* Quickly executes the given callback for each argument.
*
* @param specs A NULL-terminated array of `cli_opt_spec`s that can be parsed
* @param args The arguments that will be parsed
* @param args_len The length of arguments to be parsed
* @param flags The `cli_opt_flag_t flags for parsing
* @param callback The callback to invoke for each specified option
* @param callback_data Data to be provided to the callback
*/
int cli_opt_foreach(
const cli_opt_spec specs[],
char **args,
size_t args_len,
unsigned int flags,
int (*callback)(cli_opt *, void *),
void *callback_data);
/**
* Initializes a parser that parses the given arguments according to the
* given specifications.

View File

@ -5,7 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "cli.h"
#include "common.h"
#include "str.h"
static int print_spec_name(git_str *out, const cli_opt_spec *spec)

View File

@ -242,7 +242,21 @@ static int fetch_receiving(
done ? ", done." : "");
}
static int fetch_resolving(
static int indexer_indexing(
cli_progress *progress,
const git_indexer_progress *stats)
{
bool done = (stats->received_objects == stats->total_objects);
return progress_printf(progress, false,
"Indexing objects: %3d%% (%d/%d)%s\r",
percent(stats->received_objects, stats->total_objects),
stats->received_objects,
stats->total_objects,
done ? ", done." : "");
}
static int indexer_resolving(
cli_progress *progress,
const git_indexer_progress *stats)
{
@ -283,7 +297,42 @@ int cli_progress_fetch_transfer(const git_indexer_progress *stats, void *payload
/* fall through */
case CLI_PROGRESS_RESOLVING:
error = fetch_resolving(progress, stats);
error = indexer_resolving(progress, stats);
break;
default:
/* should not be reached */
GIT_ASSERT(!"unexpected progress state");
}
return error;
}
int cli_progress_indexer(
const git_indexer_progress *stats,
void *payload)
{
cli_progress *progress = (cli_progress *)payload;
int error = 0;
switch (progress->action) {
case CLI_PROGRESS_NONE:
progress->action = CLI_PROGRESS_INDEXING;
/* fall through */
case CLI_PROGRESS_INDEXING:
if ((error = indexer_indexing(progress, stats)) < 0)
break;
if (stats->indexed_deltas == stats->total_deltas)
break;
progress_complete(progress);
progress->action = CLI_PROGRESS_RESOLVING;
/* fall through */
case CLI_PROGRESS_RESOLVING:
error = indexer_resolving(progress, stats);
break;
default:

View File

@ -22,6 +22,7 @@
typedef enum {
CLI_PROGRESS_NONE,
CLI_PROGRESS_RECEIVING,
CLI_PROGRESS_INDEXING,
CLI_PROGRESS_RESOLVING,
CLI_PROGRESS_CHECKING_OUT
} cli_progress_t;
@ -74,6 +75,17 @@ extern int cli_progress_fetch_transfer(
const git_indexer_progress *stats,
void *payload);
/**
* Prints indexer progress to the console. Suitable for a
* `progress_cb` callback for `git_indexer_options`.
*
* @param stats The indexer stats
* @param payload A pointer to the cli_progress
*/
extern int cli_progress_indexer(
const git_indexer_progress *stats,
void *payload);
/**
* Prints checkout progress to the console. Suitable for a
* `progress_cb` callback for `git_checkout_options`.

View File

@ -8,7 +8,8 @@
#include <stdint.h>
#include <signal.h>
#include "git2_util.h"
#include "cli.h"
#include "common.h"
#include "sighandler.h"
static void (*interrupt_handler)(void) = NULL;

View File

@ -1,3 +1,3 @@
#include <git2.h>
#include "cli.h"
#include "common.h"

View File

@ -8,7 +8,7 @@
#include "git2_util.h"
#include <windows.h>
#include "cli.h"
#include "sighandler.h"
static void (*interrupt_handler)(void) = NULL;

View File

@ -65,12 +65,6 @@ set_target_properties(libgit2package PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJE
set_target_properties(libgit2package PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set_target_properties(libgit2package PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
# Win64+MSVC+static libs = linker error
if(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS)
set_target_properties(libgit2package PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64")
endif()
ide_split_sources(libgit2package)
if(SONAME)

View File

@ -424,9 +424,13 @@ static int attr_setup(
goto out;
if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
(error = preload_attr_source(repo, attr_session, &index_source)) < 0)
(error = preload_attr_source(repo, attr_session, &index_source)) < 0) {
if (error != GIT_ENOTFOUND)
goto out;
error = 0;
}
if ((opts && (opts->flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) &&
(error = preload_attr_source(repo, attr_session, &head_source)) < 0)
goto out;

View File

@ -117,12 +117,12 @@ static git_blame_hunk *dup_hunk(git_blame_hunk *hunk, git_blame *blame)
static void shift_hunks_by(git_vector *v, size_t start_line, int shift_by)
{
size_t i;
if (!git_vector_bsearch2(&i, v, hunk_byfinalline_search_cmp, &start_line)) {
for (; i < v->length; i++) {
for (i = 0; i < v->length; i++) {
git_blame_hunk *hunk = (git_blame_hunk*)v->contents[i];
hunk->final_start_line_number += shift_by;
if(hunk->final_start_line_number < start_line){
continue;
}
hunk->final_start_line_number += shift_by;
}
}
@ -444,21 +444,20 @@ static int buffer_hunk_cb(
GIT_UNUSED(delta);
wedge_line = (hunk->old_lines == 0) ? hunk->new_start : hunk->old_start;
wedge_line = (hunk->new_start >= hunk->old_start || hunk->old_lines==0) ? hunk->new_start : hunk->old_start;
blame->current_diff_line = wedge_line;
blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byline(blame, wedge_line);
if (!blame->current_hunk) {
/* Line added at the end of the file */
blame->current_hunk = new_hunk(wedge_line, 0, wedge_line,
blame->path, blame);
blame->current_diff_line++;
GIT_ERROR_CHECK_ALLOC(blame->current_hunk);
git_vector_insert(&blame->hunks, blame->current_hunk);
} else if (!hunk_starts_at_or_after_line(blame->current_hunk, wedge_line)){
/* If this hunk doesn't start between existing hunks, split a hunk up so it does */
blame->current_hunk = split_hunk_in_vector(&blame->hunks, blame->current_hunk,
wedge_line - blame->current_hunk->orig_start_line_number, true,
wedge_line - blame->current_hunk->final_start_line_number, true,
blame);
GIT_ERROR_CHECK_ALLOC(blame->current_hunk);
}
@ -484,13 +483,12 @@ static int buffer_line_cb(
hunk_ends_at_or_before_line(blame->current_hunk, blame->current_diff_line)) {
/* Append to the current buffer-blame hunk */
blame->current_hunk->lines_in_hunk++;
shift_hunks_by(&blame->hunks, blame->current_diff_line+1, 1);
shift_hunks_by(&blame->hunks, blame->current_diff_line, 1);
} else {
/* Create a new buffer-blame hunk with this line */
shift_hunks_by(&blame->hunks, blame->current_diff_line, 1);
blame->current_hunk = new_hunk(blame->current_diff_line, 1, 0, blame->path, blame);
GIT_ERROR_CHECK_ALLOC(blame->current_hunk);
git_vector_insert_sorted(&blame->hunks, blame->current_hunk, NULL);
}
blame->current_diff_line++;
@ -498,15 +496,16 @@ static int buffer_line_cb(
if (line->origin == GIT_DIFF_LINE_DELETION) {
/* Trim the line from the current hunk; remove it if it's now empty */
size_t shift_base = blame->current_diff_line + blame->current_hunk->lines_in_hunk+1;
size_t shift_base = blame->current_diff_line + blame->current_hunk->lines_in_hunk;
if (--(blame->current_hunk->lines_in_hunk) == 0) {
size_t i;
shift_base--;
size_t i_next;
if (!git_vector_search2(&i, &blame->hunks, ptrs_equal_cmp, blame->current_hunk)) {
git_vector_remove(&blame->hunks, i);
free_hunk(blame->current_hunk);
blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byindex(blame, (uint32_t)i);
i_next = min( i , blame->hunks.length -1);
blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byindex(blame, (uint32_t)i_next);
}
}
shift_hunks_by(&blame->hunks, shift_base, -1);

View File

@ -22,6 +22,7 @@
#include "fs_path.h"
#include "repository.h"
#include "odb.h"
#include "net.h"
static int clone_local_into(git_repository *repo, git_remote *remote, const git_fetch_options *fetch_opts, const git_checkout_options *co_opts, const char *branch, int link);
@ -336,8 +337,9 @@ static int create_and_configure_origin(
git_remote_create_cb remote_create = options->remote_cb;
void *payload = options->remote_cb_payload;
/* If the path exists and is a dir, the url should be the absolute path */
if (git_fs_path_root(url) < 0 && git_fs_path_exists(url) && git_fs_path_isdir(url)) {
/* If the path is local and exists it should be the absolute path. */
if (!git_net_str_is_url(url) && git_fs_path_root(url) < 0 &&
git_fs_path_exists(url)) {
if (p_realpath(url, buf) == NULL)
return -1;
@ -360,25 +362,29 @@ on_error:
return error;
}
static bool should_checkout(
static int should_checkout(
bool *out,
git_repository *repo,
bool is_bare,
const git_checkout_options *opts)
{
if (is_bare)
return false;
int error;
if (!opts)
return false;
if (!opts || is_bare || opts->checkout_strategy == GIT_CHECKOUT_NONE) {
*out = 0;
return 0;
}
if (opts->checkout_strategy == GIT_CHECKOUT_NONE)
return false;
if ((error = git_repository_head_unborn(repo)) < 0)
return error;
return !git_repository_head_unborn(repo);
*out = !error;
return 0;
}
static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const char *reflog_message)
{
bool checkout;
int error;
if (branch)
@ -387,7 +393,13 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
else
error = update_head_to_remote(repo, remote, reflog_message);
if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
if (error < 0)
return error;
if ((error = should_checkout(&checkout, repo, git_repository_is_bare(repo), co_opts)) < 0)
return error;
if (checkout)
error = git_checkout_head(repo, co_opts);
return error;
@ -458,26 +470,25 @@ cleanup:
int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t local)
{
git_str fromurl = GIT_STR_INIT;
const char *path = url_or_path;
bool is_url, is_local;
bool is_local;
if (local == GIT_CLONE_NO_LOCAL)
return 0;
if ((is_url = git_fs_path_is_local_file_url(url_or_path)) != 0) {
if (git_fs_path_fromurl(&fromurl, url_or_path) < 0) {
if (git_net_str_is_url(url_or_path)) {
/* If GIT_CLONE_LOCAL_AUTO is specified, any url should be treated as remote */
if (local == GIT_CLONE_LOCAL_AUTO ||
!git_fs_path_is_local_file_url(url_or_path))
return 0;
if (git_fs_path_fromurl(&fromurl, url_or_path) == 0)
is_local = git_fs_path_isdir(git_str_cstr(&fromurl));
else
is_local = -1;
goto done;
}
path = fromurl.ptr;
}
is_local = (!is_url || local != GIT_CLONE_LOCAL_AUTO) &&
git_fs_path_isdir(path);
done:
git_str_dispose(&fromurl);
} else {
is_local = git_fs_path_isdir(url_or_path);
}
return is_local;
}
@ -542,15 +553,15 @@ static int git__clone(
}
if (error != 0) {
git_error_state last_error = {0};
git_error_state_capture(&last_error, error);
git_error *last_error;
git_error_save(&last_error);
git_repository_free(repo);
repo = NULL;
(void)git_futils_rmdir_r(local_path, NULL, rmdir_flags);
git_error_state_restore(&last_error);
git_error_restore(last_error);
}
*out = repo;

View File

@ -281,7 +281,7 @@ int git_commit_create_from_ids(
typedef struct {
size_t total;
const git_commit **parents;
git_commit * const *parents;
git_repository *repo;
} commit_parent_data;
@ -307,7 +307,7 @@ int git_commit_create(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[])
git_commit * const parents[])
{
commit_parent_data data = { parent_count, parents, repo };
@ -945,7 +945,7 @@ int git_commit_create_buffer(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[])
git_commit * const parents[])
{
GIT_BUF_WRAP_PRIVATE(out, git_commit__create_buffer, repo,
author, committer, message_encoding, message,
@ -961,7 +961,7 @@ int git_commit__create_buffer(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[])
git_commit * const parents[])
{
int error;
commit_parent_data data = { parent_count, parents, repo };
@ -1086,6 +1086,82 @@ cleanup:
return error;
}
int git_commit_create_from_stage(
git_oid *out,
git_repository *repo,
const char *message,
const git_commit_create_options *given_opts)
{
git_commit_create_options opts = GIT_COMMIT_CREATE_OPTIONS_INIT;
git_signature *default_signature = NULL;
const git_signature *author, *committer;
git_index *index = NULL;
git_diff *diff = NULL;
git_oid tree_id;
git_tree *head_tree = NULL, *tree = NULL;
git_commitarray parents = { 0 };
int error = -1;
GIT_ASSERT_ARG(out && repo);
if (given_opts)
memcpy(&opts, given_opts, sizeof(git_commit_create_options));
author = opts.author;
committer = opts.committer;
if (!author || !committer) {
if (git_signature_default(&default_signature, repo) < 0)
goto done;
if (!author)
author = default_signature;
if (!committer)
committer = default_signature;
}
if (git_repository_index(&index, repo) < 0)
goto done;
if (!opts.allow_empty_commit) {
error = git_repository_head_tree(&head_tree, repo);
if (error && error != GIT_EUNBORNBRANCH)
goto done;
error = -1;
if (git_diff_tree_to_index(&diff, repo, head_tree, index, NULL) < 0)
goto done;
if (git_diff_num_deltas(diff) == 0) {
git_error_set(GIT_ERROR_REPOSITORY,
"no changes are staged for commit");
error = GIT_EUNCHANGED;
goto done;
}
}
if (git_index_write_tree(&tree_id, index) < 0 ||
git_tree_lookup(&tree, repo, &tree_id) < 0 ||
git_repository_commit_parents(&parents, repo) < 0)
goto done;
error = git_commit_create(out, repo, "HEAD", author, committer,
opts.message_encoding, message,
tree, parents.count, parents.commits);
done:
git_commitarray_dispose(&parents);
git_signature_free(default_signature);
git_tree_free(tree);
git_tree_free(head_tree);
git_diff_free(diff);
git_index_free(index);
return error;
}
int git_commit_committer_with_mailmap(
git_signature **out, const git_commit *commit, const git_mailmap *mailmap)
{
@ -1097,3 +1173,18 @@ int git_commit_author_with_mailmap(
{
return git_mailmap_resolve_signature(out, mailmap, commit->author);
}
void git_commitarray_dispose(git_commitarray *array)
{
size_t i;
if (array == NULL)
return;
for (i = 0; i < array->count; i++)
git_commit_free(array->commits[i]);
git__free((git_commit **)array->commits);
memset(array, 0, sizeof(*array));
}

View File

@ -64,7 +64,7 @@ int git_commit__create_buffer(
const char *message,
const git_tree *tree,
size_t parent_count,
const git_commit *parents[]);
git_commit * const parents[]);
int git_commit__parse(
void *commit,

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,8 @@
struct git_config {
git_refcount rc;
git_vector backends;
git_vector readers;
git_vector writers;
};
extern int git_config__global_location(git_str *buf);
@ -94,17 +95,21 @@ int git_config_lookup_map_enum(git_configmap_t *type_out,
size_t map_n, int enum_val);
/**
* Unlock the backend with the highest priority
* Unlock the given backend that was previously locked.
*
* Unlocking will allow other writers to update the configuration
* file. Optionally, any changes performed since the lock will be
* applied to the configuration.
*
* @param cfg the configuration
* @param config the config instance
* @param data the config data passed to git_transaction_new
* @param commit boolean which indicates whether to commit any changes
* done since locking
* @return 0 or an error code
*/
GIT_EXTERN(int) git_config_unlock(git_config *cfg, int commit);
GIT_EXTERN(int) git_config_unlock(
git_config *config,
void *data,
int commit);
#endif

View File

@ -37,15 +37,6 @@ extern int git_config_backend_from_file(git_config_backend **out, const char *pa
*/
extern int git_config_backend_snapshot(git_config_backend **out, git_config_backend *source);
/**
* Create an in-memory configuration file backend
*
* @param out the new backend
* @param cfg the configuration that is to be parsed
* @param len the length of the string pointed to by `cfg`
*/
extern int git_config_backend_from_string(git_config_backend **out, const char *cfg, size_t len);
GIT_INLINE(int) git_config_backend_open(git_config_backend *cfg, unsigned int level, const git_repository *repo)
{
return cfg->open(cfg, level, repo);

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