mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-10 19:19:18 +00:00
New upstream version 1.7.1+ds
This commit is contained in:
parent
f1fdcff351
commit
d11d1f257e
45
.github/actions/run-build/action.yml
vendored
Normal file
45
.github/actions/run-build/action.yml
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
# Run a build step in a container or directly on the Actions runner
|
||||
name: Run Build Step
|
||||
description: Run a build step in a container or directly on the Actions runner
|
||||
|
||||
inputs:
|
||||
command:
|
||||
description: Command to run
|
||||
required: true
|
||||
type: string
|
||||
container:
|
||||
description: Optional container to run in
|
||||
type: string
|
||||
container-version:
|
||||
description: Version of the container to run
|
||||
type: string
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- run: |
|
||||
if [ -n "${{ inputs.container }}" ]; then
|
||||
docker run \
|
||||
--rm \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-v "$(pwd)/source:/home/libgit2/source" \
|
||||
-v "$(pwd)/build:/home/libgit2/build" \
|
||||
-w /home/libgit2 \
|
||||
-e ASAN_SYMBOLIZER_PATH \
|
||||
-e CC \
|
||||
-e CFLAGS \
|
||||
-e CMAKE_GENERATOR \
|
||||
-e CMAKE_OPTIONS \
|
||||
-e GITTEST_NEGOTIATE_PASSWORD \
|
||||
-e GITTEST_FLAKY_STAT \
|
||||
-e PKG_CONFIG_PATH \
|
||||
-e SKIP_NEGOTIATE_TESTS \
|
||||
-e SKIP_SSH_TESTS \
|
||||
-e TSAN_OPTIONS \
|
||||
-e UBSAN_OPTIONS \
|
||||
${{ inputs.container-version }} \
|
||||
/bin/bash -c "${{ inputs.command }}"
|
||||
else
|
||||
${{ inputs.command }}
|
||||
fi
|
||||
shell: bash
|
6
.github/release.yml
vendored
6
.github/release.yml
vendored
@ -3,6 +3,9 @@ changelog:
|
||||
- title: New features
|
||||
labels:
|
||||
- feature
|
||||
- title: Performance improvements
|
||||
labels:
|
||||
- performance
|
||||
- title: Bug fixes
|
||||
labels:
|
||||
- bug
|
||||
@ -18,6 +21,9 @@ changelog:
|
||||
- title: Documentation improvements
|
||||
labels:
|
||||
- documentation
|
||||
- title: Git compatibility fixes
|
||||
labels:
|
||||
- git compatibility
|
||||
- title: Other changes
|
||||
labels:
|
||||
- '*'
|
||||
|
72
.github/workflows/build-containers.yml
vendored
Normal file
72
.github/workflows/build-containers.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
# Generate the containers that we use for builds.
|
||||
name: Build Containers
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
docker-registry: ghcr.io
|
||||
docker-config-path: source/ci/docker
|
||||
|
||||
jobs:
|
||||
# Build the docker container images that we will use for our Linux
|
||||
# builds. This will identify the last commit to the repository that
|
||||
# updated the docker images, and try to download the image tagged with
|
||||
# that sha. If it does not exist, we'll do a docker build and push
|
||||
# the image up to GitHub Packages for the actual CI/CD runs. We tag
|
||||
# with both the sha and "latest" so that the subsequent runs need not
|
||||
# know the sha. Only do this on CI builds (when the event is a "push")
|
||||
# because PR builds from forks lack permission to write packages.
|
||||
containers:
|
||||
strategy:
|
||||
matrix:
|
||||
container:
|
||||
- name: xenial
|
||||
- name: bionic
|
||||
- name: focal
|
||||
- name: docurium
|
||||
- name: bionic-x86
|
||||
dockerfile: bionic
|
||||
base: multiarch/ubuntu-core:x86-bionic
|
||||
qemu: true
|
||||
- name: bionic-arm32
|
||||
dockerfile: bionic
|
||||
base: multiarch/ubuntu-core:armhf-bionic
|
||||
qemu: true
|
||||
- name: bionic-arm64
|
||||
dockerfile: bionic
|
||||
base: multiarch/ubuntu-core:arm64-bionic
|
||||
qemu: true
|
||||
- name: centos7
|
||||
- name: centos8
|
||||
runs-on: ubuntu-latest
|
||||
name: "Create container: ${{ matrix.container.name }}"
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: source
|
||||
fetch-depth: 0
|
||||
if: github.event_name != 'pull_request'
|
||||
- name: Setup QEMU
|
||||
run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
if: matrix.container.qemu == true
|
||||
- name: Download existing container
|
||||
run: |
|
||||
"${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.container.name }}" "${{ matrix.container.dockerfile }}"
|
||||
env:
|
||||
DOCKER_REGISTRY: ${{ env.docker-registry }}
|
||||
GITHUB_TOKEN: ${{ secrets.github_token }}
|
||||
working-directory: ${{ env.docker-config-path }}
|
||||
if: github.event_name != 'pull_request'
|
||||
- name: Build and publish image
|
||||
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 }} .
|
||||
docker tag ${{ env.docker-registry-container-sha }} ${{ env.docker-registry-container-latest }}
|
||||
docker push ${{ env.docker-registry-container-sha }}
|
||||
docker push ${{ env.docker-registry-container-latest }}
|
||||
working-directory: ${{ env.docker-config-path }}
|
||||
if: github.event_name != 'pull_request' && env.docker-container-exists != 'true'
|
124
.github/workflows/main.yml
vendored
124
.github/workflows/main.yml
vendored
@ -14,67 +14,8 @@ env:
|
||||
docker-config-path: source/ci/docker
|
||||
|
||||
jobs:
|
||||
# Build the docker container images that we will use for our Linux
|
||||
# builds. This will identify the last commit to the repository that
|
||||
# updated the docker images, and try to download the image tagged with
|
||||
# that sha. If it does not exist, we'll do a docker build and push
|
||||
# the image up to GitHub Packages for the actual CI/CD runs. We tag
|
||||
# with both the sha and "latest" so that the subsequent runs need not
|
||||
# know the sha. Only do this on CI builds (when the event is a "push")
|
||||
# because PR builds from forks lack permission to write packages.
|
||||
containers:
|
||||
strategy:
|
||||
matrix:
|
||||
container:
|
||||
- name: xenial
|
||||
- name: bionic
|
||||
- name: focal
|
||||
- name: docurium
|
||||
- name: bionic-x86
|
||||
dockerfile: bionic
|
||||
base: multiarch/ubuntu-core:x86-bionic
|
||||
qemu: true
|
||||
- name: bionic-arm32
|
||||
dockerfile: bionic
|
||||
base: multiarch/ubuntu-core:armhf-bionic
|
||||
qemu: true
|
||||
- name: bionic-arm64
|
||||
dockerfile: bionic
|
||||
base: multiarch/ubuntu-core:arm64-bionic
|
||||
qemu: true
|
||||
- name: centos7
|
||||
- name: centos8
|
||||
runs-on: ubuntu-latest
|
||||
name: "Create container: ${{ matrix.container.name }}"
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: source
|
||||
fetch-depth: 0
|
||||
if: github.event_name != 'pull_request'
|
||||
- name: Setup QEMU
|
||||
run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
if: matrix.container.qemu == true
|
||||
- name: Download existing container
|
||||
run: |
|
||||
"${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.container.name }}" "${{ matrix.container.dockerfile }}"
|
||||
env:
|
||||
DOCKER_REGISTRY: ${{ env.docker-registry }}
|
||||
GITHUB_TOKEN: ${{ secrets.github_token }}
|
||||
working-directory: ${{ env.docker-config-path }}
|
||||
if: github.event_name != 'pull_request'
|
||||
- name: Build and publish image
|
||||
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 }} .
|
||||
docker tag ${{ env.docker-registry-container-sha }} ${{ env.docker-registry-container-latest }}
|
||||
docker push ${{ env.docker-registry-container-sha }}
|
||||
docker push ${{ env.docker-registry-container-latest }}
|
||||
working-directory: ${{ env.docker-config-path }}
|
||||
if: github.event_name != 'pull_request' && env.docker-container-exists != 'true'
|
||||
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)
|
||||
@ -130,19 +71,19 @@ jobs:
|
||||
SKIP_SSH_TESTS: true
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
setup-script: osx
|
||||
- name: "Windows (amd64, Visual Studio)"
|
||||
- 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_SSH=ON -DCMAKE_PREFIX_PATH=D:\Temp\libssh2
|
||||
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)"
|
||||
- name: "Windows (x86, Visual Studio, WinHTTP)"
|
||||
id: windows-x86-vs
|
||||
os: windows-2019
|
||||
setup-script: win32
|
||||
@ -154,7 +95,7 @@ jobs:
|
||||
BUILD_TEMP: D:\Temp
|
||||
SKIP_SSH_TESTS: true
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
- name: "Windows (amd64, mingw)"
|
||||
- name: "Windows (amd64, mingw, WinHTTP)"
|
||||
id: windows-amd64-mingw
|
||||
os: windows-2019
|
||||
setup-script: mingw
|
||||
@ -166,14 +107,14 @@ jobs:
|
||||
BUILD_PATH: D:\Temp\mingw64\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 (x86, mingw)"
|
||||
- name: "Windows (x86, mingw, Schannel)"
|
||||
id: windows-x86-mingw
|
||||
os: windows-2019
|
||||
setup-script: mingw
|
||||
env:
|
||||
ARCH: x86
|
||||
CMAKE_GENERATOR: MinGW Makefiles
|
||||
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON
|
||||
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_HTTPS=Schannel
|
||||
BUILD_TEMP: D:\Temp
|
||||
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
|
||||
@ -286,43 +227,20 @@ jobs:
|
||||
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: Build and test
|
||||
run: |
|
||||
export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}"
|
||||
export GITTEST_GITHUB_SSH_KEY="${{ secrets.GITTEST_GITHUB_SSH_KEY }}"
|
||||
export GITTEST_GITHUB_SSH_PUBKEY="${{ secrets.GITTEST_GITHUB_SSH_PUBKEY }}"
|
||||
export GITTEST_GITHUB_SSH_PASSPHRASE="${{ secrets.GITTEST_GITHUB_SSH_PASSPHRASE }}"
|
||||
export GITTEST_GITHUB_SSH_REMOTE_HOSTKEY="${{ secrets.GITTEST_GITHUB_SSH_REMOTE_HOSTKEY }}"
|
||||
|
||||
if [ -n "${{ matrix.platform.container.name }}" ]; then
|
||||
mkdir build
|
||||
docker run \
|
||||
--rm \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-v "$(pwd)/source:/home/libgit2/source" \
|
||||
-v "$(pwd)/build:/home/libgit2/build" \
|
||||
-w /home/libgit2 \
|
||||
-e ASAN_SYMBOLIZER_PATH \
|
||||
-e CC \
|
||||
-e CFLAGS \
|
||||
-e CMAKE_GENERATOR \
|
||||
-e CMAKE_OPTIONS \
|
||||
-e GITTEST_NEGOTIATE_PASSWORD \
|
||||
-e GITTEST_FLAKY_STAT \
|
||||
-e PKG_CONFIG_PATH \
|
||||
-e SKIP_NEGOTIATE_TESTS \
|
||||
-e SKIP_SSH_TESTS \
|
||||
-e TSAN_OPTIONS \
|
||||
-e UBSAN_OPTIONS \
|
||||
${{ env.docker-registry-container-sha }} \
|
||||
/bin/bash -c "cd build && ../source/ci/build.sh && ../source/ci/test.sh"
|
||||
else
|
||||
mkdir build
|
||||
cd build
|
||||
../source/ci/build.sh
|
||||
../source/ci/test.sh
|
||||
fi
|
||||
shell: bash
|
||||
- name: Prepare build
|
||||
run: mkdir build
|
||||
- name: Build
|
||||
uses: ./source/.github/actions/run-build
|
||||
with:
|
||||
command: cd build && ../source/ci/build.sh
|
||||
container: ${{ matrix.platform.container.name }}
|
||||
container-version: ${{ env.docker-registry-container-sha }}
|
||||
- name: Test
|
||||
uses: ./source/.github/actions/run-build
|
||||
with:
|
||||
command: cd build && ../source/ci/test.sh
|
||||
container: ${{ matrix.platform.container.name }}
|
||||
container-version: ${{ env.docker-registry-container-sha }}
|
||||
- name: Upload test results
|
||||
uses: actions/upload-artifact@v3
|
||||
if: success() || failure()
|
||||
|
91
.github/workflows/nightly.yml
vendored
91
.github/workflows/nightly.yml
vendored
@ -162,32 +162,39 @@ jobs:
|
||||
SKIP_SSH_TESTS: true
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
setup-script: osx
|
||||
- name: "Windows (amd64, Visual Studio)"
|
||||
- name: "Windows (amd64, Visual Studio, WinHTTP)"
|
||||
os: windows-2019
|
||||
env:
|
||||
ARCH: amd64
|
||||
CMAKE_GENERATOR: Visual Studio 16 2019
|
||||
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON
|
||||
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_HTTPS=WinHTTP
|
||||
SKIP_SSH_TESTS: true
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
- name: "Windows (no mmap)"
|
||||
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
|
||||
- name: "Windows (x86, Visual Studio)"
|
||||
- name: "Windows (x86, Visual Studio, WinHTTP)"
|
||||
os: windows-2019
|
||||
env:
|
||||
ARCH: x86
|
||||
CMAKE_GENERATOR: Visual Studio 16 2019
|
||||
CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON
|
||||
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, mingw)"
|
||||
- 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
|
||||
SKIP_SSH_TESTS: true
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
- name: "Windows (amd64, mingw, WinHTTP)"
|
||||
os: windows-2019
|
||||
setup-script: mingw
|
||||
env:
|
||||
@ -198,17 +205,26 @@ jobs:
|
||||
BUILD_PATH: D:\Temp\mingw64\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 (x86, mingw)"
|
||||
- name: "Windows (x86, mingw, Schannel)"
|
||||
os: windows-2019
|
||||
setup-script: mingw
|
||||
env:
|
||||
ARCH: x86
|
||||
CMAKE_GENERATOR: MinGW Makefiles
|
||||
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON
|
||||
CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_HTTPS=Schannel
|
||||
BUILD_TEMP: D:\Temp
|
||||
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
|
||||
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
|
||||
- name: "Linux (Bionic, GCC, dynamically-loaded OpenSSL)"
|
||||
container:
|
||||
name: bionic
|
||||
@ -324,35 +340,20 @@ jobs:
|
||||
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: Build and test
|
||||
run: |
|
||||
export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}"
|
||||
|
||||
if [ -n "${{ matrix.platform.container.name }}" ]; then
|
||||
docker run \
|
||||
--rm \
|
||||
--user libgit2:libgit2 \
|
||||
-v "$(pwd)/source:/home/libgit2/source" \
|
||||
-w /home/libgit2 \
|
||||
-e ASAN_SYMBOLIZER_PATH \
|
||||
-e CC \
|
||||
-e CFLAGS \
|
||||
-e CMAKE_GENERATOR \
|
||||
-e CMAKE_OPTIONS \
|
||||
-e GITTEST_NEGOTIATE_PASSWORD \
|
||||
-e GITTEST_FLAKY_STAT \
|
||||
-e PKG_CONFIG_PATH \
|
||||
-e SKIP_NEGOTIATE_TESTS \
|
||||
-e SKIP_SSH_TESTS \
|
||||
-e TSAN_OPTIONS \
|
||||
${{ env.docker-registry-container-sha }} \
|
||||
/bin/bash -c "mkdir build && cd build && ../source/ci/build.sh && ../source/ci/test.sh"
|
||||
else
|
||||
mkdir build && cd build
|
||||
../source/ci/build.sh
|
||||
../source/ci/test.sh
|
||||
fi
|
||||
shell: bash
|
||||
- name: Prepare build
|
||||
run: mkdir build
|
||||
- name: Build
|
||||
uses: ./source/.github/actions/run-build
|
||||
with:
|
||||
command: cd build && ../source/ci/build.sh
|
||||
container: ${{ matrix.platform.container.name }}
|
||||
container-version: ${{ env.docker-registry-container-sha }}
|
||||
- name: Test
|
||||
uses: ./source/.github/actions/run-build
|
||||
with:
|
||||
command: cd build && ../source/ci/test.sh
|
||||
container: ${{ matrix.platform.container.name }}
|
||||
container-version: ${{ env.docker-registry-container-sha }}
|
||||
|
||||
coverity:
|
||||
# Only run scheduled workflows on the main repository; prevents people
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
project(libgit2 VERSION "1.6.4" LANGUAGES C)
|
||||
project(libgit2 VERSION "1.7.1" LANGUAGES C)
|
||||
|
||||
# Add find modules to the path
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
|
||||
@ -36,6 +36,7 @@ option(USE_SHA1 "Enable SHA1. Can be set to CollisionDetection(ON
|
||||
option(USE_SHA256 "Enable SHA256. Can be set to HTTPS/Builtin" ON)
|
||||
option(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF)
|
||||
set(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")
|
||||
# set(USE_XDIFF "" CACHE STRING "Specifies the xdiff implementation; either system or builtin.")
|
||||
set(REGEX_BACKEND "" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.")
|
||||
option(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF)
|
||||
|
||||
@ -82,12 +83,6 @@ if(MSVC)
|
||||
option(WIN32_LEAKCHECK "Enable leak reporting via crtdbg" OFF)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# By default, libgit2 is built with WinHTTP. To use the built-in
|
||||
# HTTP transport, invoke CMake with the "-DUSE_WINHTTP=OFF" argument.
|
||||
option(USE_WINHTTP "Use Win32 WinHTTP routines" ON)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
endif()
|
||||
@ -99,7 +94,7 @@ include(CheckLibraryExists)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckPrototypeDefinition)
|
||||
include(CheckPrototypeDefinitionSafe)
|
||||
include(AddCFlagIfSupported)
|
||||
include(FindPkgLibraries)
|
||||
include(FindThreads)
|
||||
|
@ -4,8 +4,8 @@ libgit2 - the Git linkable library
|
||||
| Build Status | |
|
||||
| ------------ | - |
|
||||
| **main** branch CI builds | [](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) |
|
||||
| **v1.7 branch** CI builds | [](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.7) |
|
||||
| **v1.6 branch** CI builds | [](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.6) |
|
||||
| **v1.5 branch** CI builds | [](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.5) |
|
||||
| **Nightly** builds | [](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [](https://scan.coverity.com/projects/639) |
|
||||
|
||||
`libgit2` is a portable, pure C implementation of the Git core methods
|
||||
|
@ -171,7 +171,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
|
||||
fi
|
||||
|
||||
if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then
|
||||
curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.5.1/poxygit-0.5.1.jar >poxygit.jar
|
||||
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`
|
||||
@ -271,9 +271,13 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then
|
||||
|
||||
export GITTEST_REMOTE_REDIRECT_INITIAL="http://localhost:9000/initial-redirect/libgit2/TestGitRepository"
|
||||
export GITTEST_REMOTE_REDIRECT_SUBSEQUENT="http://localhost:9000/subsequent-redirect/libgit2/TestGitRepository"
|
||||
export GITTEST_REMOTE_SPEED_SLOW="http://localhost:9000/speed-9600/test.git"
|
||||
export GITTEST_REMOTE_SPEED_TIMESOUT="http://localhost:9000/speed-0.5/test.git"
|
||||
run_test online
|
||||
unset GITTEST_REMOTE_REDIRECT_INITIAL
|
||||
unset GITTEST_REMOTE_REDIRECT_SUBSEQUENT
|
||||
unset GITTEST_REMOTE_SPEED_SLOW
|
||||
unset GITTEST_REMOTE_SPEED_TIMESOUT
|
||||
|
||||
# Run the online tests that immutably change global state separately
|
||||
# to avoid polluting the test environment.
|
||||
|
16
cmake/CheckPrototypeDefinitionSafe.cmake
Normal file
16
cmake/CheckPrototypeDefinitionSafe.cmake
Normal file
@ -0,0 +1,16 @@
|
||||
include(CheckPrototypeDefinition)
|
||||
|
||||
function(check_prototype_definition_safe function prototype return header variable)
|
||||
# temporarily save CMAKE_C_FLAGS and disable warnings about unused
|
||||
# unused functions and parameters, otherwise they will always fail
|
||||
# if ENABLE_WERROR is on
|
||||
set(SAVED_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
|
||||
disable_warnings(unused-function)
|
||||
disable_warnings(unused-parameter)
|
||||
|
||||
check_prototype_definition("${function}" "${prototype}" "${return}" "${header}" "${variable}")
|
||||
|
||||
# restore CMAKE_C_FLAGS
|
||||
set(CMAKE_C_FLAGS "${SAVED_CMAKE_C_FLAGS}")
|
||||
endfunction()
|
@ -29,7 +29,7 @@ if(USE_GSSAPI)
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS ${GSSFRAMEWORK_LIBRARIES})
|
||||
|
||||
set(GIT_GSSFRAMEWORK 1)
|
||||
add_feature_info(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${USE_GSSAPI})")
|
||||
add_feature_info(GSSAPI GIT_GSSFRAMEWORK "GSSAPI support for SPNEGO authentication (${USE_GSSAPI})")
|
||||
elseif(USE_GSSAPI STREQUAL "gssapi")
|
||||
if(NOT GSSAPI_FOUND)
|
||||
message(FATAL_ERROR "Asked for gssapi GSS backend, but it wasn't found")
|
||||
@ -38,11 +38,11 @@ if(USE_GSSAPI)
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS ${GSSAPI_LIBRARIES})
|
||||
|
||||
set(GIT_GSSAPI 1)
|
||||
add_feature_info(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${USE_GSSAPI})")
|
||||
add_feature_info(GSSAPI GIT_GSSAPI "GSSAPI support for SPNEGO authentication (${USE_GSSAPI})")
|
||||
else()
|
||||
message(FATAL_ERROR "Asked for backend ${USE_GSSAPI} but it wasn't found")
|
||||
endif()
|
||||
else()
|
||||
set(GIT_GSSAPI 0)
|
||||
add_feature_info(SPNEGO NO "SPNEGO authentication support")
|
||||
add_feature_info(GSSAPI NO "GSSAPI support for SPNEGO authentication")
|
||||
endif()
|
||||
|
@ -19,7 +19,7 @@ if(USE_HTTPS)
|
||||
message(STATUS "Security framework is too old, falling back to OpenSSL")
|
||||
set(USE_HTTPS "OpenSSL")
|
||||
endif()
|
||||
elseif(USE_WINHTTP)
|
||||
elseif(WIN32)
|
||||
set(USE_HTTPS "WinHTTP")
|
||||
elseif(OPENSSL_FOUND)
|
||||
set(USE_HTTPS "OpenSSL")
|
||||
@ -106,8 +106,27 @@ if(USE_HTTPS)
|
||||
# https://github.com/ARMmbed/mbedtls/issues/228
|
||||
# For now, pass its link flags as our own
|
||||
list(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES})
|
||||
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")
|
||||
elseif(USE_HTTPS STREQUAL "WinHTTP")
|
||||
# WinHTTP setup was handled in the WinHTTP-specific block above
|
||||
set(GIT_WINHTTP 1)
|
||||
|
||||
# Since MinGW does not come with headers or an import library for winhttp,
|
||||
# we have to include a private header and generate our own import library
|
||||
if(MINGW)
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/winhttp" "${PROJECT_BINARY_DIR}/deps/winhttp")
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS winhttp)
|
||||
list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/winhttp")
|
||||
else()
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS "winhttp")
|
||||
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")
|
||||
elseif(USE_HTTPS STREQUAL "OpenSSL-Dynamic")
|
||||
set(GIT_OPENSSL 1)
|
||||
set(GIT_OPENSSL_DYNAMIC 1)
|
||||
|
@ -13,6 +13,8 @@ if(USE_SHA1 STREQUAL ON)
|
||||
elseif(USE_SHA1 STREQUAL "HTTPS")
|
||||
if(USE_HTTPS STREQUAL "SecureTransport")
|
||||
set(USE_SHA1 "CommonCrypto")
|
||||
elseif(USE_HTTPS STREQUAL "Schannel")
|
||||
set(USE_SHA1 "Win32")
|
||||
elseif(USE_HTTPS STREQUAL "WinHTTP")
|
||||
set(USE_SHA1 "Win32")
|
||||
elseif(USE_HTTPS)
|
||||
@ -51,6 +53,8 @@ endif()
|
||||
if(USE_SHA256 STREQUAL "HTTPS")
|
||||
if(USE_HTTPS STREQUAL "SecureTransport")
|
||||
set(USE_SHA256 "CommonCrypto")
|
||||
elseif(USE_HTTPS STREQUAL "Schannel")
|
||||
set(USE_SHA256 "Win32")
|
||||
elseif(USE_HTTPS STREQUAL "WinHTTP")
|
||||
set(USE_SHA256 "Win32")
|
||||
elseif(USE_HTTPS)
|
||||
|
@ -1,17 +0,0 @@
|
||||
if(WIN32 AND USE_WINHTTP)
|
||||
set(GIT_WINHTTP 1)
|
||||
|
||||
# Since MinGW does not come with headers or an import library for winhttp,
|
||||
# we have to include a private header and generate our own import library
|
||||
if(MINGW)
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/winhttp" "${PROJECT_BINARY_DIR}/deps/winhttp")
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS winhttp)
|
||||
list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/winhttp")
|
||||
else()
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS "winhttp")
|
||||
list(APPEND LIBGIT2_PC_LIBS "-lwinhttp")
|
||||
endif()
|
||||
|
||||
list(APPEND LIBGIT2_SYSTEM_LIBS "rpcrt4" "crypt32" "ole32")
|
||||
list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
|
||||
endif()
|
9
cmake/SelectXdiff.cmake
Normal file
9
cmake/SelectXdiff.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
# Optional external dependency: xdiff
|
||||
if(USE_XDIFF STREQUAL "system")
|
||||
message(FATAL_ERROR "external/system xdiff is not yet supported")
|
||||
else()
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/xdiff" "${PROJECT_BINARY_DIR}/deps/xdiff")
|
||||
list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/xdiff")
|
||||
list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$<TARGET_OBJECTS:xdiff>")
|
||||
add_feature_info(xdiff ON "xdiff support (bundled)")
|
||||
endif()
|
28
deps/xdiff/CMakeLists.txt
vendored
Normal file
28
deps/xdiff/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
file(GLOB SRC_XDIFF "*.c" "*.h")
|
||||
list(SORT SRC_XDIFF)
|
||||
|
||||
add_library(xdiff OBJECT ${SRC_XDIFF})
|
||||
target_include_directories(xdiff SYSTEM PRIVATE
|
||||
"${PROJECT_SOURCE_DIR}/include"
|
||||
"${PROJECT_SOURCE_DIR}/src/util"
|
||||
"${PROJECT_BINARY_DIR}/src/util"
|
||||
${LIBGIT2_SYSTEM_INCLUDES}
|
||||
${LIBGIT2_DEPENDENCY_INCLUDES})
|
||||
|
||||
# the xdiff dependency is not (yet) warning-free, disable warnings
|
||||
# as errors for the xdiff sources until we've sorted them out
|
||||
if(MSVC)
|
||||
set_source_files_properties(xdiffi.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xemit.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xhistogram.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xmerge.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xutils.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xpatience.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
else()
|
||||
set_source_files_properties(xdiffi.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter")
|
||||
set_source_files_properties(xemit.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter")
|
||||
set_source_files_properties(xhistogram.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare")
|
||||
set_source_files_properties(xutils.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare")
|
||||
set_source_files_properties(xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare")
|
||||
endif()
|
@ -27,11 +27,14 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define XDL_UNUSED GIT_UNUSED_ARG
|
||||
|
||||
#define xdl_malloc(x) git__malloc(x)
|
||||
#define xdl_calloc(n, sz) git__calloc(n, sz)
|
||||
#define xdl_free(ptr) git__free(ptr)
|
||||
#define xdl_realloc(ptr, x) git__realloc(ptr, x)
|
||||
|
||||
#define XDL_BUG(msg) GIT_ASSERT(msg)
|
||||
#define XDL_BUG(msg) GIT_ASSERT(!msg)
|
||||
|
||||
#define xdl_regex_t git_regexp
|
||||
#define xdl_regmatch_t git_regmatch
|
39
src/libgit2/xdiff/xdiffi.c → deps/xdiff/xdiffi.c
vendored
39
src/libgit2/xdiff/xdiffi.c → deps/xdiff/xdiffi.c
vendored
@ -315,16 +315,19 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
long *kvd, *kvdf, *kvdb;
|
||||
xdalgoenv_t xenv;
|
||||
diffdata_t dd1, dd2;
|
||||
int res;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
|
||||
return xdl_do_patience_diff(mf1, mf2, xpp, xe);
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
|
||||
return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
|
||||
|
||||
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
|
||||
|
||||
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0)
|
||||
return -1;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF) {
|
||||
res = xdl_do_patience_diff(xpp, xe);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF) {
|
||||
res = xdl_do_histogram_diff(xpp, xe);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -334,7 +337,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
* One is to store the forward path and one to store the backward path.
|
||||
*/
|
||||
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
|
||||
if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
|
||||
if (!XDL_ALLOC_ARRAY(kvd, 2 * ndiags + 2)) {
|
||||
|
||||
xdl_free_env(xe);
|
||||
return -1;
|
||||
@ -359,17 +362,15 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
dd2.rchg = xe->xdf2.rchg;
|
||||
dd2.rindex = xe->xdf2.rindex;
|
||||
|
||||
if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
|
||||
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
|
||||
|
||||
xdl_free(kvd);
|
||||
xdl_free_env(xe);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
|
||||
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0,
|
||||
&xenv);
|
||||
xdl_free(kvd);
|
||||
out:
|
||||
if (res < 0)
|
||||
xdl_free_env(xe);
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -972,7 +973,7 @@ void xdl_free_script(xdchange_t *xscr) {
|
||||
}
|
||||
}
|
||||
|
||||
static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
static int xdl_call_hunk_func(xdfenv_t *xe XDL_UNUSED, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg)
|
||||
{
|
||||
xdchange_t *xch, *xche;
|
@ -56,9 +56,7 @@ int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
|
||||
void xdl_free_script(xdchange_t *xscr);
|
||||
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg);
|
||||
int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *env);
|
||||
int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *env);
|
||||
int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env);
|
||||
int xdl_do_histogram_diff(xpparam_t const *xpp, xdfenv_t *env);
|
||||
|
||||
#endif /* #if !defined(XDIFFI_H) */
|
@ -65,7 +65,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
|
||||
*xscr = xch;
|
||||
}
|
||||
|
||||
if (*xscr == NULL)
|
||||
if (!*xscr)
|
||||
return NULL;
|
||||
|
||||
lxch = *xscr;
|
||||
@ -95,7 +95,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
|
||||
}
|
||||
|
||||
|
||||
static long def_ff(const char *rec, long len, char *buf, long sz, void *priv)
|
||||
static long def_ff(const char *rec, long len, char *buf, long sz)
|
||||
{
|
||||
if (len > 0 &&
|
||||
(isalpha((unsigned char)*rec) || /* identifier? */
|
||||
@ -117,7 +117,7 @@ static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri,
|
||||
const char *rec;
|
||||
long len = xdl_get_rec(xdf, ri, &rec);
|
||||
if (!xecfg->find_func)
|
||||
return def_ff(rec, len, buf, sz, xecfg->find_func_priv);
|
||||
return def_ff(rec, len, buf, sz);
|
||||
return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv);
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
int b_ptr;
|
||||
int sz, ret = -1;
|
||||
int ret = -1;
|
||||
struct histindex index;
|
||||
|
||||
memset(&index, 0, sizeof(index));
|
||||
@ -265,23 +265,16 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
||||
index.rcha.head = NULL;
|
||||
|
||||
index.table_bits = xdl_hashbits(count1);
|
||||
sz = index.records_size = 1 << index.table_bits;
|
||||
sz *= sizeof(struct record *);
|
||||
if (!(index.records = (struct record **) xdl_malloc(sz)))
|
||||
index.records_size = 1 << index.table_bits;
|
||||
if (!XDL_CALLOC_ARRAY(index.records, index.records_size))
|
||||
goto cleanup;
|
||||
memset(index.records, 0, sz);
|
||||
|
||||
sz = index.line_map_size = count1;
|
||||
sz *= sizeof(struct record *);
|
||||
if (!(index.line_map = (struct record **) xdl_malloc(sz)))
|
||||
index.line_map_size = count1;
|
||||
if (!XDL_CALLOC_ARRAY(index.line_map, index.line_map_size))
|
||||
goto cleanup;
|
||||
memset(index.line_map, 0, sz);
|
||||
|
||||
sz = index.line_map_size;
|
||||
sz *= sizeof(unsigned int);
|
||||
if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
|
||||
if (!XDL_CALLOC_ARRAY(index.next_ptrs, index.line_map_size))
|
||||
goto cleanup;
|
||||
memset(index.next_ptrs, 0, sz);
|
||||
|
||||
/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
|
||||
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
|
||||
@ -369,12 +362,8 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env)
|
||||
int xdl_do_histogram_diff(xpparam_t const *xpp, xdfenv_t *env)
|
||||
{
|
||||
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
|
||||
return -1;
|
||||
|
||||
return histogram_diff(xpp, env,
|
||||
env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
|
||||
env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);
|
@ -34,7 +34,6 @@
|
||||
#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
|
||||
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
|
||||
#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
|
||||
#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
|
||||
#define XDL_LE32_PUT(p, v) \
|
||||
do { \
|
||||
unsigned char *__p = (unsigned char *) (p); \
|
||||
@ -50,5 +49,23 @@ do { \
|
||||
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
|
||||
} while (0)
|
||||
|
||||
/* Allocate an array of nr elements, returns NULL on failure */
|
||||
#define XDL_ALLOC_ARRAY(p, nr) \
|
||||
((p) = SIZE_MAX / sizeof(*(p)) >= (size_t)(nr) \
|
||||
? xdl_malloc((nr) * sizeof(*(p))) \
|
||||
: NULL)
|
||||
|
||||
/* Allocate an array of nr zeroed out elements, returns NULL on failure */
|
||||
#define XDL_CALLOC_ARRAY(p, nr) ((p) = xdl_calloc(nr, sizeof(*(p))))
|
||||
|
||||
/*
|
||||
* Ensure array p can accommodate at least nr elements, growing the
|
||||
* array and updating alloc (which is the number of allocated
|
||||
* elements) as necessary. Frees p and returns -1 on failure, returns
|
||||
* 0 on success
|
||||
*/
|
||||
#define XDL_ALLOC_GROW(p, nr, alloc) \
|
||||
(-!((nr) <= (alloc) || \
|
||||
((p) = xdl_alloc_grow_helper((p), (nr), &(alloc), sizeof(*(p))))))
|
||||
|
||||
#endif /* #if !defined(XMACROS_H) */
|
46
src/libgit2/xdiff/xmerge.c → deps/xdiff/xmerge.c
vendored
46
src/libgit2/xdiff/xmerge.c → deps/xdiff/xmerge.c
vendored
@ -88,7 +88,7 @@ static int xdl_cleanup_merge(xdmerge_t *c)
|
||||
if (c->mode == 0)
|
||||
count++;
|
||||
next_c = c->next;
|
||||
xdl_free(c);
|
||||
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;
|
||||
xdl_free(next_m);
|
||||
free(next_m);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -684,42 +684,42 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
|
||||
int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
|
||||
xmparam_t const *xmp, mmbuffer_t *result)
|
||||
{
|
||||
xdchange_t *xscr1, *xscr2;
|
||||
xdchange_t *xscr1 = NULL, *xscr2 = NULL;
|
||||
xdfenv_t xe1, xe2;
|
||||
int status;
|
||||
int status = -1;
|
||||
xpparam_t const *xpp = &xmp->xpp;
|
||||
|
||||
result->ptr = NULL;
|
||||
result->size = 0;
|
||||
|
||||
if (xdl_do_diff(orig, mf1, xpp, &xe1) < 0) {
|
||||
if (xdl_do_diff(orig, mf1, xpp, &xe1) < 0)
|
||||
return -1;
|
||||
}
|
||||
if (xdl_do_diff(orig, mf2, xpp, &xe2) < 0) {
|
||||
xdl_free_env(&xe1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xdl_do_diff(orig, mf2, xpp, &xe2) < 0)
|
||||
goto free_xe1; /* avoid double free of xe2 */
|
||||
|
||||
if (xdl_change_compact(&xe1.xdf1, &xe1.xdf2, xpp->flags) < 0 ||
|
||||
xdl_change_compact(&xe1.xdf2, &xe1.xdf1, xpp->flags) < 0 ||
|
||||
xdl_build_script(&xe1, &xscr1) < 0) {
|
||||
xdl_free_env(&xe1);
|
||||
return -1;
|
||||
}
|
||||
xdl_build_script(&xe1, &xscr1) < 0)
|
||||
goto out;
|
||||
|
||||
if (xdl_change_compact(&xe2.xdf1, &xe2.xdf2, xpp->flags) < 0 ||
|
||||
xdl_change_compact(&xe2.xdf2, &xe2.xdf1, xpp->flags) < 0 ||
|
||||
xdl_build_script(&xe2, &xscr2) < 0) {
|
||||
xdl_free_script(xscr1);
|
||||
xdl_free_env(&xe1);
|
||||
xdl_free_env(&xe2);
|
||||
return -1;
|
||||
}
|
||||
status = 0;
|
||||
xdl_build_script(&xe2, &xscr2) < 0)
|
||||
goto out;
|
||||
|
||||
if (!xscr1) {
|
||||
result->ptr = xdl_malloc(mf2->size);
|
||||
if (!result->ptr)
|
||||
goto out;
|
||||
status = 0;
|
||||
memcpy(result->ptr, mf2->ptr, mf2->size);
|
||||
result->size = mf2->size;
|
||||
} else if (!xscr2) {
|
||||
result->ptr = xdl_malloc(mf1->size);
|
||||
if (!result->ptr)
|
||||
goto out;
|
||||
status = 0;
|
||||
memcpy(result->ptr, mf1->ptr, mf1->size);
|
||||
result->size = mf1->size;
|
||||
} else {
|
||||
@ -727,11 +727,13 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
|
||||
&xe2, xscr2,
|
||||
xmp, result);
|
||||
}
|
||||
out:
|
||||
xdl_free_script(xscr1);
|
||||
xdl_free_script(xscr2);
|
||||
|
||||
xdl_free_env(&xe1);
|
||||
xdl_free_env(&xe2);
|
||||
free_xe1:
|
||||
xdl_free_env(&xe1);
|
||||
|
||||
return status;
|
||||
}
|
@ -69,7 +69,6 @@ struct hashmap {
|
||||
} *entries, *first, *last;
|
||||
/* were common records found? */
|
||||
unsigned long has_matches;
|
||||
mmfile_t *file1, *file2;
|
||||
xdfenv_t *env;
|
||||
xpparam_t const *xpp;
|
||||
};
|
||||
@ -139,23 +138,17 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
|
||||
*
|
||||
* It is assumed that env has been prepared using xdl_prepare().
|
||||
*/
|
||||
static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
static int fill_hashmap(xpparam_t const *xpp, xdfenv_t *env,
|
||||
struct hashmap *result,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
result->file1 = file1;
|
||||
result->file2 = file2;
|
||||
result->xpp = xpp;
|
||||
result->env = env;
|
||||
|
||||
/* We know exactly how large we want the hash map */
|
||||
result->alloc = count1 * 2;
|
||||
result->entries = (struct entry *)
|
||||
xdl_malloc(result->alloc * sizeof(struct entry));
|
||||
if (!result->entries)
|
||||
if (!XDL_CALLOC_ARRAY(result->entries, result->alloc))
|
||||
return -1;
|
||||
memset(result->entries, 0, result->alloc * sizeof(struct entry));
|
||||
|
||||
/* First, fill with entries from the first file */
|
||||
while (count1--)
|
||||
@ -198,9 +191,9 @@ static int binary_search(struct entry **sequence, int longest,
|
||||
* item per sequence length: the sequence with the smallest last
|
||||
* element (in terms of line2).
|
||||
*/
|
||||
static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
|
||||
{
|
||||
struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
|
||||
struct entry **sequence;
|
||||
int longest = 0, i;
|
||||
struct entry *entry;
|
||||
|
||||
@ -211,6 +204,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
*/
|
||||
int anchor_i = -1;
|
||||
|
||||
if (!XDL_ALLOC_ARRAY(sequence, map->nr))
|
||||
return -1;
|
||||
|
||||
for (entry = map->first; entry; entry = entry->next) {
|
||||
if (!entry->line2 || entry->line2 == NON_UNIQUE)
|
||||
continue;
|
||||
@ -230,8 +226,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
|
||||
/* No common unique lines were found */
|
||||
if (!longest) {
|
||||
*res = NULL;
|
||||
xdl_free(sequence);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Iterate starting at the last element, adjusting the "next" members */
|
||||
@ -241,8 +238,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
entry->previous->next = entry;
|
||||
entry = entry->previous;
|
||||
}
|
||||
*res = entry;
|
||||
xdl_free(sequence);
|
||||
return entry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match(struct hashmap *map, int line1, int line2)
|
||||
@ -252,8 +250,7 @@ static int match(struct hashmap *map, int line1, int line2)
|
||||
return record1->ha == record2->ha;
|
||||
}
|
||||
|
||||
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2);
|
||||
|
||||
static int walk_common_sequence(struct hashmap *map, struct entry *first,
|
||||
@ -284,8 +281,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
|
||||
|
||||
/* Recurse */
|
||||
if (next1 > line1 || next2 > line2) {
|
||||
if (patience_diff(map->file1, map->file2,
|
||||
map->xpp, map->env,
|
||||
if (patience_diff(map->xpp, map->env,
|
||||
line1, next1 - line1,
|
||||
line2, next2 - line2))
|
||||
return -1;
|
||||
@ -324,8 +320,7 @@ static int fall_back_to_classic_diff(struct hashmap *map,
|
||||
*
|
||||
* This function assumes that env was prepared with xdl_prepare_env().
|
||||
*/
|
||||
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
struct hashmap map;
|
||||
@ -344,7 +339,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
}
|
||||
|
||||
memset(&map, 0, sizeof(map));
|
||||
if (fill_hashmap(file1, file2, xpp, env, &map,
|
||||
if (fill_hashmap(xpp, env, &map,
|
||||
line1, count1, line2, count2))
|
||||
return -1;
|
||||
|
||||
@ -358,25 +353,21 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
return 0;
|
||||
}
|
||||
|
||||
first = find_longest_common_sequence(&map);
|
||||
result = find_longest_common_sequence(&map, &first);
|
||||
if (result)
|
||||
goto out;
|
||||
if (first)
|
||||
result = walk_common_sequence(&map, first,
|
||||
line1, count1, line2, count2);
|
||||
else
|
||||
result = fall_back_to_classic_diff(&map,
|
||||
line1, count1, line2, count2);
|
||||
|
||||
out:
|
||||
xdl_free(map.entries);
|
||||
return result;
|
||||
}
|
||||
|
||||
int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env)
|
||||
int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env)
|
||||
{
|
||||
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
|
||||
return -1;
|
||||
|
||||
/* environment is cleaned up in xdl_diff() */
|
||||
return patience_diff(file1, file2, xpp, env,
|
||||
1, env->xdf1.nrec, 1, env->xdf2.nrec);
|
||||
return patience_diff(xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec);
|
||||
}
|
@ -78,15 +78,14 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
|
||||
if (!XDL_CALLOC_ARRAY(cf->rchash, cf->hsize)) {
|
||||
|
||||
xdl_cha_free(&cf->ncha);
|
||||
return -1;
|
||||
}
|
||||
memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
|
||||
|
||||
cf->alloc = size;
|
||||
if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
|
||||
if (!XDL_ALLOC_ARRAY(cf->rcrecs, cf->alloc)) {
|
||||
|
||||
xdl_free(cf->rchash);
|
||||
xdl_cha_free(&cf->ncha);
|
||||
@ -112,7 +111,6 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
|
||||
long hi;
|
||||
char const *line;
|
||||
xdlclass_t *rcrec;
|
||||
xdlclass_t **rcrecs;
|
||||
|
||||
line = rec->ptr;
|
||||
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
|
||||
@ -128,14 +126,8 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
|
||||
return -1;
|
||||
}
|
||||
rcrec->idx = cf->count++;
|
||||
if (cf->count > cf->alloc) {
|
||||
cf->alloc *= 2;
|
||||
if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
|
||||
|
||||
if (XDL_ALLOC_GROW(cf->rcrecs, cf->count, cf->alloc))
|
||||
return -1;
|
||||
}
|
||||
cf->rcrecs = rcrecs;
|
||||
}
|
||||
cf->rcrecs[rcrec->idx] = rcrec;
|
||||
rcrec->line = line;
|
||||
rcrec->size = rec->size;
|
||||
@ -164,7 +156,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
||||
unsigned long hav;
|
||||
char const *blk, *cur, *top, *prev;
|
||||
xrecord_t *crec;
|
||||
xrecord_t **recs, **rrecs;
|
||||
xrecord_t **recs;
|
||||
xrecord_t **rhash;
|
||||
unsigned long *ha;
|
||||
char *rchg;
|
||||
@ -178,26 +170,21 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
||||
|
||||
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
|
||||
goto abort;
|
||||
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
|
||||
if (!XDL_ALLOC_ARRAY(recs, narec))
|
||||
goto abort;
|
||||
|
||||
hbits = xdl_hashbits((unsigned int) narec);
|
||||
hsize = 1 << hbits;
|
||||
if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
|
||||
if (!XDL_CALLOC_ARRAY(rhash, hsize))
|
||||
goto abort;
|
||||
memset(rhash, 0, hsize * sizeof(xrecord_t *));
|
||||
|
||||
nrec = 0;
|
||||
if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
|
||||
if ((cur = blk = xdl_mmfile_first(mf, &bsize))) {
|
||||
for (top = blk + bsize; cur < top; ) {
|
||||
prev = cur;
|
||||
hav = xdl_hash_record(&cur, top, xpp->flags);
|
||||
if (nrec >= narec) {
|
||||
narec *= 2;
|
||||
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
|
||||
goto abort;
|
||||
recs = rrecs;
|
||||
}
|
||||
if (XDL_ALLOC_GROW(recs, nrec + 1, narec))
|
||||
goto abort;
|
||||
if (!(crec = xdl_cha_alloc(&xdf->rcha)))
|
||||
goto abort;
|
||||
crec->ptr = prev;
|
||||
@ -209,15 +196,14 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
||||
}
|
||||
}
|
||||
|
||||
if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
|
||||
if (!XDL_CALLOC_ARRAY(rchg, nrec + 2))
|
||||
goto abort;
|
||||
memset(rchg, 0, (nrec + 2) * sizeof(char));
|
||||
|
||||
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
|
||||
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) {
|
||||
if (!(rindex = xdl_malloc((nrec + 1) * sizeof(*rindex))))
|
||||
if (!XDL_ALLOC_ARRAY(rindex, nrec + 1))
|
||||
goto abort;
|
||||
if (!(ha = xdl_malloc((nrec + 1) * sizeof(*ha))))
|
||||
if (!XDL_ALLOC_ARRAY(ha, nrec + 1))
|
||||
goto abort;
|
||||
}
|
||||
|
||||
@ -383,11 +369,8 @@ static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xd
|
||||
xdlclass_t *rcrec;
|
||||
char *dis, *dis1, *dis2;
|
||||
|
||||
if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
|
||||
|
||||
if (!XDL_CALLOC_ARRAY(dis, xdf1->nrec + xdf2->nrec + 2))
|
||||
return -1;
|
||||
}
|
||||
memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
|
||||
dis1 = dis;
|
||||
dis2 = dis1 + xdf1->nrec + 1;
|
||||
|
19
src/libgit2/xdiff/xutils.c → deps/xdiff/xutils.c
vendored
19
src/libgit2/xdiff/xutils.c → deps/xdiff/xutils.c
vendored
@ -122,7 +122,7 @@ long xdl_guess_lines(mmfile_t *mf, long sample) {
|
||||
long nl = 0, size, tsize = 0;
|
||||
char const *data, *cur, *top;
|
||||
|
||||
if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
|
||||
if ((cur = data = xdl_mmfile_first(mf, &size))) {
|
||||
for (top = data + size; nl < sample && cur < top; ) {
|
||||
nl++;
|
||||
if (!(cur = memchr(cur, '\n', top - cur)))
|
||||
@ -432,3 +432,20 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* xdl_alloc_grow_helper(void *p, long nr, long *alloc, size_t size)
|
||||
{
|
||||
void *tmp = NULL;
|
||||
size_t n = ((LONG_MAX - 16) / 2 >= *alloc) ? 2 * *alloc + 16 : LONG_MAX;
|
||||
if (nr > n)
|
||||
n = nr;
|
||||
if (SIZE_MAX / size >= n)
|
||||
tmp = xdl_realloc(p, n * size);
|
||||
if (tmp) {
|
||||
*alloc = n;
|
||||
} else {
|
||||
xdl_free(p);
|
||||
*alloc = 0;
|
||||
}
|
||||
return tmp;
|
||||
}
|
@ -42,6 +42,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
|
||||
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||
int line1, int count1, int line2, int count2);
|
||||
|
||||
|
||||
/* Do not call this function, use XDL_ALLOC_GROW instead */
|
||||
void* xdl_alloc_grow_helper(void* p, long nr, long* alloc, size_t size);
|
||||
|
||||
#endif /* #if !defined(XUTILS_H) */
|
@ -1,12 +1,153 @@
|
||||
v1.6.4
|
||||
v1.7.1
|
||||
------
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Bug fixes
|
||||
* config: return `GIT_ENOTFOUND` for missing programdata by @ethomson in https://github.com/libgit2/libgit2/pull/6547
|
||||
|
||||
**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.6.3...v1.6.4
|
||||
* 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
|
||||
|
||||
### Compatibility improvements
|
||||
|
||||
* stransport: macOS: replace errSSLNetworkTimeout, with hard-coded value by @mascguy in https://github.com/libgit2/libgit2/pull/6610
|
||||
|
||||
## 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
|
||||
|
||||
v1.7
|
||||
----
|
||||
|
||||
This is release v1.7.0, "Kleine Raupe Nimmersatt". This release adds
|
||||
shallow clone support, completes the experimental SHA256 support,
|
||||
adds Schannel support for Windows, and includes many other new
|
||||
features and bugfixes.
|
||||
|
||||
## Major changes
|
||||
|
||||
* **Shallow clone support**
|
||||
libgit2 now supports shallow clone and shallow repositories, thanks
|
||||
to a significant investment from many community members -- hundreds
|
||||
of commits by many contributors.
|
||||
|
||||
* Shallow (#6396) with some fixes from review by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6557
|
||||
* Shallow Clone Support by @lya001 in
|
||||
https://github.com/libgit2/libgit2/pull/6396
|
||||
* Shallow support v2 by @pks-t in
|
||||
https://github.com/libgit2/libgit2/pull/5254
|
||||
|
||||
* **SHA256 support**
|
||||
libgit2 should now support SHA256 repositories using the
|
||||
`extensions.objectFormat` configuration option when the library is
|
||||
built with `EXPERIMENTAL_SHA256=ON`. Users are encouraged to begin
|
||||
testing their applications with this option and provide bug reports
|
||||
and feedback. This _is_ a breaking API change; SHA256 support will
|
||||
be enabled by default in libgit2 v2.0.
|
||||
|
||||
* sha256: less hardcoded SHA1 types and lengths by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6549
|
||||
* Support SHA256 in git_repository_wrap_odb by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6556
|
||||
|
||||
* **Schannel and SSPI for Windows**
|
||||
libgit2 now supports the Windows Schannel and SSPI APIs for HTTPS
|
||||
support on Windows, when configured with `USE_HTTPS=Schannel`.
|
||||
Setting this option will not use the existing WinHTTP support, but
|
||||
will use libgit2's standard HTTP client stack with Windows TLS
|
||||
primitives. Windows users are encouraged to begin testing their
|
||||
applications with this option and provide bug reports and feedback.
|
||||
This will be enabled by default in a future version of libgit2.
|
||||
|
||||
* Introduce Schannel and SSPI for Windows by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6533
|
||||
|
||||
## Breaking changes
|
||||
|
||||
* **Simplify custom pluggable allocator** (System API / ABI breaking change)
|
||||
The `git_allocator` structure (configurable by the
|
||||
`GIT_OPT_SET_ALLOCATOR` option) now only contains `gmalloc`,
|
||||
`grealloc` and `gfree` members. This simplifies both the work needed
|
||||
by an implementer _and_ allows more flexibility and correctness in
|
||||
libgit2 itself, especially during out-of-memory situations and
|
||||
errors during bootstrapping.
|
||||
|
||||
* tests: add allocator with limited number of bytes by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6563
|
||||
|
||||
## Other changes
|
||||
|
||||
### New features
|
||||
* repo: honor environment variables for more scenarios by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6544
|
||||
* Introduce timeouts on sockets by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6535
|
||||
|
||||
### Performance improvements
|
||||
* midx: do not try to look at every object in the index by @carlosmn in
|
||||
https://github.com/libgit2/libgit2/pull/6585
|
||||
* Partial fix for #6532: insert-by-date order. by @arroz in
|
||||
https://github.com/libgit2/libgit2/pull/6539
|
||||
|
||||
### Bug fixes
|
||||
* repo: don't allow repeated extensions by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6505
|
||||
* config: return `GIT_ENOTFOUND` for missing programdata by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6547
|
||||
* Fix missing oid type for "fake" repositories by @oreiche in
|
||||
https://github.com/libgit2/libgit2/pull/6554
|
||||
* Thread-local storage: handle failure cases by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/5722
|
||||
* midx: allow unknown chunk ids in multi-pack index files by @carlosmn in
|
||||
https://github.com/libgit2/libgit2/pull/6583
|
||||
* pack: cast the number of objects to size_t by @carlosmn in
|
||||
https://github.com/libgit2/libgit2/pull/6584
|
||||
* Fixes #6344: git_branch_move now renames the reflog instead of deleting
|
||||
by @arroz in https://github.com/libgit2/libgit2/pull/6345
|
||||
* #6576 git_diff_index_to_workdir reverse now loads untracked content by
|
||||
@arroz in https://github.com/libgit2/libgit2/pull/6577
|
||||
|
||||
### Build and CI improvements
|
||||
* meta: the main branch is now v1.7.0 by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6516
|
||||
* xdiff: move xdiff to 'deps' by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6482
|
||||
* util: detect all possible qsort_r and qsort_s variants by
|
||||
@DimitryAndric in https://github.com/libgit2/libgit2/pull/6555
|
||||
* Work around -Werror problems when detecting qsort variants by
|
||||
@DimitryAndric in https://github.com/libgit2/libgit2/pull/6558
|
||||
* actions: simplify execution with composite action by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6488
|
||||
* CMake: Search for ssh2 instead of libssh2. by @Faless in
|
||||
https://github.com/libgit2/libgit2/pull/6586
|
||||
|
||||
### Documentation improvements
|
||||
* docs: fix IRC server from freenode to libera by @vincenzopalazzo in
|
||||
https://github.com/libgit2/libgit2/pull/6590
|
||||
|
||||
### Dependency upgrades
|
||||
* Update xdiff to git 2.40.1's version by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6561
|
||||
* deps: update pcre to 8.45 by @ethomson in
|
||||
https://github.com/libgit2/libgit2/pull/6593
|
||||
|
||||
## New Contributors
|
||||
* @oreiche made their first contribution in
|
||||
https://github.com/libgit2/libgit2/pull/6554
|
||||
* @DimitryAndric made their first contribution in
|
||||
https://github.com/libgit2/libgit2/pull/6555
|
||||
* @vincenzopalazzo made their first contribution in
|
||||
https://github.com/libgit2/libgit2/pull/6590
|
||||
* @Faless made their first contribution in
|
||||
https://github.com/libgit2/libgit2/pull/6586
|
||||
|
||||
**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.6.3...v1.7.0
|
||||
|
||||
v1.6.3
|
||||
------
|
||||
|
@ -24,9 +24,8 @@ by the following licenses:
|
||||
|
||||
## Discussion & Chat
|
||||
|
||||
We hang out in the
|
||||
[`#libgit2`](http://webchat.freenode.net/?channels=#libgit2)) channel on
|
||||
irc.freenode.net.
|
||||
We hang out in the [#libgit2](https://web.libera.chat/#libgit2) channel on
|
||||
[libera](https://libera.chat).
|
||||
|
||||
Also, feel free to open an
|
||||
[Issue](https://github.com/libgit2/libgit2/issues/new) to start a discussion
|
||||
|
@ -188,9 +188,17 @@ static void compute_diff_no_index(git_diff **diff, struct diff_options *o) {
|
||||
check_lg2(
|
||||
git_patch_to_buf(&buf, patch),
|
||||
"patch to buf", NULL);
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
check_lg2(
|
||||
git_diff_from_buffer(diff, buf.ptr, buf.size, NULL),
|
||||
"diff from patch", NULL);
|
||||
#else
|
||||
check_lg2(
|
||||
git_diff_from_buffer(diff, buf.ptr, buf.size),
|
||||
"diff from patch", NULL);
|
||||
#endif
|
||||
|
||||
git_patch_free(patch);
|
||||
git_buf_dispose(&buf);
|
||||
free(file1_str);
|
||||
|
@ -30,7 +30,11 @@ int lg2_show_index(git_repository *repo, int argc, char **argv)
|
||||
|
||||
dirlen = strlen(dir);
|
||||
if (dirlen > 5 && strcmp(dir + dirlen - 5, "index") == 0) {
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
check_lg2(git_index_open(&index, dir, GIT_OID_SHA1), "could not open index", dir);
|
||||
#else
|
||||
check_lg2(git_index_open(&index, dir), "could not open index", dir);
|
||||
#endif
|
||||
} else {
|
||||
check_lg2(git_repository_open_ext(&repo, dir, 0, NULL), "could not open repository", dir);
|
||||
check_lg2(git_repository_index(&index, repo), "could not open repository index", NULL);
|
||||
|
@ -224,7 +224,11 @@ typedef enum {
|
||||
GIT_OPT_GET_OWNER_VALIDATION,
|
||||
GIT_OPT_SET_OWNER_VALIDATION,
|
||||
GIT_OPT_GET_HOMEDIR,
|
||||
GIT_OPT_SET_HOMEDIR
|
||||
GIT_OPT_SET_HOMEDIR,
|
||||
GIT_OPT_SET_SERVER_CONNECT_TIMEOUT,
|
||||
GIT_OPT_GET_SERVER_CONNECT_TIMEOUT,
|
||||
GIT_OPT_SET_SERVER_TIMEOUT,
|
||||
GIT_OPT_GET_SERVER_TIMEOUT
|
||||
} git_libgit2_opt_t;
|
||||
|
||||
/**
|
||||
@ -480,6 +484,27 @@ typedef enum {
|
||||
* >
|
||||
* > - `path` directory of home directory.
|
||||
*
|
||||
* opts(GIT_OPT_GET_SERVER_CONNECT_TIMEOUT, int *timeout)
|
||||
* > Gets the timeout (in milliseconds) to attempt connections to
|
||||
* > a remote server.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* opts(GIT_OPT_GET_SERVER_TIMEOUT, int *timeout)
|
||||
* > Gets the timeout (in milliseconds) for reading from and writing
|
||||
* > to a remote server.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param option Option key
|
||||
* @param ... value to set the option
|
||||
* @return 0 on success, <0 on failure
|
||||
|
@ -421,6 +421,22 @@ typedef struct {
|
||||
*/
|
||||
uint32_t interhunk_lines;
|
||||
|
||||
/**
|
||||
* The object ID type to emit in diffs; this is used by functions
|
||||
* that operate without a repository - namely `git_diff_buffers`,
|
||||
* or `git_diff_blobs` and `git_diff_blob_to_buffer` when one blob
|
||||
* is `NULL`.
|
||||
*
|
||||
* This may be omitted (set to `0`). If a repository is available,
|
||||
* the object ID format of the repository will be used. If no
|
||||
* repository is available then the default is `GIT_OID_SHA`.
|
||||
*
|
||||
* If this is specified and a repository is available, then the
|
||||
* specified `oid_type` must match the repository's object ID
|
||||
* format.
|
||||
*/
|
||||
git_oid_t oid_type;
|
||||
|
||||
/**
|
||||
* The abbreviation length to use when formatting object ids.
|
||||
* Defaults to the value of 'core.abbrev' from the config, or 7 if unset.
|
||||
@ -1153,9 +1169,8 @@ GIT_EXTERN(int) git_diff_to_buf(
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
/*
|
||||
* Misc
|
||||
* Low-level file comparison, invoking callbacks per difference.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -1271,6 +1286,25 @@ GIT_EXTERN(int) git_diff_buffers(
|
||||
git_diff_line_cb line_cb,
|
||||
void *payload);
|
||||
|
||||
/* Patch file parsing. */
|
||||
|
||||
/**
|
||||
* Options for parsing a diff / patch file.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int version;
|
||||
git_oid_t oid_type;
|
||||
} git_diff_parse_options;
|
||||
|
||||
/* The current version of the diff parse options structure */
|
||||
#define GIT_DIFF_PARSE_OPTIONS_VERSION 1
|
||||
|
||||
/* Stack initializer for diff parse options. Alternatively use
|
||||
* `git_diff_parse_options_init` programmatic initialization.
|
||||
*/
|
||||
#define GIT_DIFF_PARSE_OPTIONS_INIT \
|
||||
{ GIT_DIFF_PARSE_OPTIONS_VERSION, GIT_OID_DEFAULT }
|
||||
|
||||
/**
|
||||
* Read the contents of a git patch file into a `git_diff` object.
|
||||
*
|
||||
@ -1293,7 +1327,11 @@ GIT_EXTERN(int) git_diff_buffers(
|
||||
GIT_EXTERN(int) git_diff_from_buffer(
|
||||
git_diff **out,
|
||||
const char *content,
|
||||
size_t content_len);
|
||||
size_t content_len
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_diff_parse_options *opts
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
* This is an opaque structure which is allocated by `git_diff_get_stats`.
|
||||
|
@ -58,7 +58,8 @@ typedef enum {
|
||||
GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */
|
||||
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_EOWNER = -36, /**< The object is not owned by the current user */
|
||||
GIT_TIMEOUT = -37 /**< The operation timed out */
|
||||
} git_error_code;
|
||||
|
||||
/**
|
||||
@ -109,7 +110,8 @@ typedef enum {
|
||||
GIT_ERROR_WORKTREE,
|
||||
GIT_ERROR_SHA,
|
||||
GIT_ERROR_HTTP,
|
||||
GIT_ERROR_INTERNAL
|
||||
GIT_ERROR_INTERNAL,
|
||||
GIT_ERROR_GRAFTS
|
||||
} git_error_t;
|
||||
|
||||
/**
|
||||
|
@ -184,7 +184,12 @@ typedef enum {
|
||||
* @param index_path the path to the index file in disk
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path, git_oid_t oid_type);
|
||||
#else
|
||||
GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create an in-memory index object.
|
||||
@ -197,7 +202,11 @@ GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path);
|
||||
* @param out the pointer for the new index
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
GIT_EXTERN(int) git_index_new(git_index **out, git_oid_t oid_type);
|
||||
#else
|
||||
GIT_EXTERN(int) git_index_new(git_index **out);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Free an existing index object.
|
||||
|
@ -225,7 +225,7 @@ GIT_EXTERN(int) git_oid_pathfmt(char *out, const git_oid *id);
|
||||
* concurrent calls of the function.
|
||||
*
|
||||
* @param oid The oid structure to format
|
||||
* @return the c-string
|
||||
* @return the c-string or NULL on failure
|
||||
*/
|
||||
GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
|
||||
|
||||
|
@ -702,6 +702,15 @@ typedef enum {
|
||||
GIT_REMOTE_DOWNLOAD_TAGS_ALL
|
||||
} git_remote_autotag_option_t;
|
||||
|
||||
/** Constants for fetch depth (shallowness of fetch). */
|
||||
typedef enum {
|
||||
/** The fetch is "full" (not shallow). This is the default. */
|
||||
GIT_FETCH_DEPTH_FULL = 0,
|
||||
|
||||
/** The fetch should "unshallow" and fetch missing data. */
|
||||
GIT_FETCH_DEPTH_UNSHALLOW = 2147483647
|
||||
} git_fetch_depth_t;
|
||||
|
||||
/**
|
||||
* Fetch options structure.
|
||||
*
|
||||
@ -743,6 +752,15 @@ typedef struct {
|
||||
*/
|
||||
git_proxy_options proxy_opts;
|
||||
|
||||
/**
|
||||
* Depth of the fetch to perform, or `GIT_FETCH_DEPTH_FULL`
|
||||
* (or `0`) for full history, or `GIT_FETCH_DEPTH_UNSHALLOW`
|
||||
* to "unshallow" a shallow repository.
|
||||
*
|
||||
* The default is full (`GIT_FETCH_DEPTH_FULL` or `0`).
|
||||
*/
|
||||
int depth;
|
||||
|
||||
/**
|
||||
* Whether to allow off-site redirects. If this is not
|
||||
* specified, the `http.followRedirects` configuration setting
|
||||
|
@ -56,9 +56,19 @@ GIT_EXTERN(int) git_repository_open_from_worktree(git_repository **out, git_work
|
||||
*
|
||||
* @param out pointer to the repo
|
||||
* @param odb the object database to wrap
|
||||
* @param oid_type the oid type of the object database
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
GIT_EXTERN(int) git_repository_wrap_odb(
|
||||
git_repository **out,
|
||||
git_odb *odb,
|
||||
git_oid_t oid_type);
|
||||
#else
|
||||
GIT_EXTERN(int) git_repository_wrap_odb(
|
||||
git_repository **out,
|
||||
git_odb *odb);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Look for a git repository and copy its path in the given buffer.
|
||||
@ -536,7 +546,7 @@ GIT_EXTERN(const char *) git_repository_workdir(const git_repository *repo);
|
||||
|
||||
/**
|
||||
* Get the path of the shared common directory for this repository.
|
||||
*
|
||||
*
|
||||
* If the repository is bare, it is the root directory for the repository.
|
||||
* If the repository is a worktree, it is the parent repo's gitdir.
|
||||
* Otherwise, it is the gitdir.
|
||||
|
@ -24,28 +24,6 @@ typedef struct {
|
||||
/** Allocate `n` bytes of memory */
|
||||
void * GIT_CALLBACK(gmalloc)(size_t n, const char *file, int line);
|
||||
|
||||
/**
|
||||
* Allocate memory for an array of `nelem` elements, where each element
|
||||
* has a size of `elsize`. Returned memory shall be initialized to
|
||||
* all-zeroes
|
||||
*/
|
||||
void * GIT_CALLBACK(gcalloc)(size_t nelem, size_t elsize, const char *file, int line);
|
||||
|
||||
/** Allocate memory for the string `str` and duplicate its contents. */
|
||||
char * GIT_CALLBACK(gstrdup)(const char *str, const char *file, int line);
|
||||
|
||||
/**
|
||||
* Equivalent to the `gstrdup` function, but only duplicating at most
|
||||
* `n + 1` bytes
|
||||
*/
|
||||
char * GIT_CALLBACK(gstrndup)(const char *str, size_t n, const char *file, int line);
|
||||
|
||||
/**
|
||||
* Equivalent to `gstrndup`, but will always duplicate exactly `n` bytes
|
||||
* of `str`. Thus, out of bounds reads at `str` may happen.
|
||||
*/
|
||||
char * GIT_CALLBACK(gsubstrdup)(const char *str, size_t n, const char *file, int line);
|
||||
|
||||
/**
|
||||
* This function shall deallocate the old object `ptr` and return a
|
||||
* pointer to a new object that has the size specified by `size`. In
|
||||
@ -53,18 +31,6 @@ typedef struct {
|
||||
*/
|
||||
void * GIT_CALLBACK(grealloc)(void *ptr, size_t size, const char *file, int line);
|
||||
|
||||
/**
|
||||
* This function shall be equivalent to `grealloc`, but allocating
|
||||
* `neleme * elsize` bytes.
|
||||
*/
|
||||
void * GIT_CALLBACK(greallocarray)(void *ptr, size_t nelem, size_t elsize, const char *file, int line);
|
||||
|
||||
/**
|
||||
* This function shall allocate a new array of `nelem` elements, where
|
||||
* each element has a size of `elsize` bytes.
|
||||
*/
|
||||
void * GIT_CALLBACK(gmallocarray)(size_t nelem, size_t elsize, const char *file, int line);
|
||||
|
||||
/**
|
||||
* This function shall free the memory pointed to by `ptr`. In case
|
||||
* `ptr` is `NULL`, this shall be a no-op.
|
||||
|
@ -28,7 +28,13 @@ GIT_BEGIN_DECL
|
||||
* @param objects_dir the path to a git objects directory.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_graph_open(git_commit_graph **cgraph_out, const char *objects_dir);
|
||||
GIT_EXTERN(int) git_commit_graph_open(
|
||||
git_commit_graph **cgraph_out,
|
||||
const char *objects_dir
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_oid_t oid_type
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
* Frees commit-graph data. This should only be called when memory allocated
|
||||
@ -50,7 +56,11 @@ GIT_EXTERN(void) git_commit_graph_free(git_commit_graph *cgraph);
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_graph_writer_new(
|
||||
git_commit_graph_writer **out,
|
||||
const char *objects_info_dir);
|
||||
const char *objects_info_dir
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_oid_t oid_type
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
* Free the commit-graph writer and its resources.
|
||||
|
@ -29,7 +29,11 @@ GIT_BEGIN_DECL
|
||||
*/
|
||||
GIT_EXTERN(int) git_midx_writer_new(
|
||||
git_midx_writer **out,
|
||||
const char *pack_dir);
|
||||
const char *pack_dir
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_oid_t oid_type
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
* Free the multi-pack-index writer and its resources.
|
||||
|
@ -29,8 +29,22 @@ GIT_BEGIN_DECL
|
||||
typedef struct git_stream {
|
||||
int version;
|
||||
|
||||
int encrypted;
|
||||
int proxy_support;
|
||||
int encrypted : 1,
|
||||
proxy_support : 1;
|
||||
|
||||
/**
|
||||
* Timeout for read and write operations; can be set to `0` to
|
||||
* block indefinitely.
|
||||
*/
|
||||
int timeout;
|
||||
|
||||
/**
|
||||
* Timeout to connect to the remote server; can be set to `0`
|
||||
* to use the system defaults. This can be shorter than the
|
||||
* system default - often 75 seconds - but cannot be longer.
|
||||
*/
|
||||
int connect_timeout;
|
||||
|
||||
int GIT_CALLBACK(connect)(struct git_stream *);
|
||||
int GIT_CALLBACK(certificate)(git_cert **, struct git_stream *);
|
||||
int GIT_CALLBACK(set_proxy)(struct git_stream *, const git_proxy_options *proxy_opts);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define INCLUDE_sys_git_transport_h
|
||||
|
||||
#include "git2/net.h"
|
||||
#include "git2/oidarray.h"
|
||||
#include "git2/proxy.h"
|
||||
#include "git2/remote.h"
|
||||
#include "git2/strarray.h"
|
||||
@ -25,6 +26,14 @@
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
typedef struct {
|
||||
const git_remote_head * const *refs;
|
||||
size_t refs_len;
|
||||
git_oid *shallow_roots;
|
||||
size_t shallow_roots_len;
|
||||
int depth;
|
||||
} git_fetch_negotiation;
|
||||
|
||||
struct git_transport {
|
||||
unsigned int version; /**< The struct version */
|
||||
|
||||
@ -96,8 +105,17 @@ struct git_transport {
|
||||
int GIT_CALLBACK(negotiate_fetch)(
|
||||
git_transport *transport,
|
||||
git_repository *repo,
|
||||
const git_remote_head * const *refs,
|
||||
size_t count);
|
||||
const git_fetch_negotiation *fetch_data);
|
||||
|
||||
/**
|
||||
* Return the shallow roots of the remote.
|
||||
*
|
||||
* This function may be called after a successful call to
|
||||
* `negotiate_fetch`.
|
||||
*/
|
||||
int GIT_CALLBACK(shallow_roots)(
|
||||
git_oidarray *out,
|
||||
git_transport *transport);
|
||||
|
||||
/**
|
||||
* Start downloading the packfile from the remote repository.
|
||||
|
@ -11,16 +11,16 @@
|
||||
* The version string for libgit2. This string follows semantic
|
||||
* versioning (v2) guidelines.
|
||||
*/
|
||||
#define LIBGIT2_VERSION "1.6.4"
|
||||
#define LIBGIT2_VERSION "1.7.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 6
|
||||
#define LIBGIT2_VER_MINOR 7
|
||||
|
||||
/** The revision ("teeny") version number for this version of libgit2. */
|
||||
#define LIBGIT2_VER_REVISION 4
|
||||
#define LIBGIT2_VER_REVISION 1
|
||||
|
||||
/** The Windows DLL patch number for this version of libgit2. */
|
||||
#define LIBGIT2_VER_PATCH 0
|
||||
@ -34,6 +34,6 @@
|
||||
#define LIBGIT2_VER_PRERELEASE NULL
|
||||
|
||||
/** The library ABI soversion for this version of libgit2. */
|
||||
#define LIBGIT2_SOVERSION "1.6"
|
||||
#define LIBGIT2_SOVERSION "1.7"
|
||||
|
||||
#endif
|
||||
|
@ -237,7 +237,9 @@ GIT_EXTERN(int) git_worktree_prune_options_init(
|
||||
*
|
||||
* If the worktree is not valid and not locked or if the above
|
||||
* flags have been passed in, this function will return a
|
||||
* positive value.
|
||||
* positive value. If the worktree is not prunable, an error
|
||||
* message will be set (visible in `giterr_last`) with details about
|
||||
* why.
|
||||
*
|
||||
* @param wt Worktree to check.
|
||||
* @param opts The prunable options.
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libgit2",
|
||||
"version": "1.6.4",
|
||||
"version": "1.7.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 ."
|
||||
|
@ -41,8 +41,8 @@ include(SelectHTTPSBackend)
|
||||
include(SelectHashes)
|
||||
include(SelectHTTPParser)
|
||||
include(SelectRegex)
|
||||
include(SelectXdiff)
|
||||
include(SelectSSH)
|
||||
include(SelectWinHTTP)
|
||||
include(SelectZlib)
|
||||
|
||||
#
|
||||
@ -58,20 +58,43 @@ add_feature_info(futimens GIT_USE_FUTIMENS "futimens support")
|
||||
|
||||
# qsort
|
||||
|
||||
check_prototype_definition(qsort_r
|
||||
"void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))"
|
||||
"" "stdlib.h" GIT_QSORT_R_BSD)
|
||||
# old-style FreeBSD qsort_r() has the 'context' parameter as the first argument
|
||||
# of the comparison function:
|
||||
check_prototype_definition_safe(qsort_r
|
||||
"void (qsort_r)(void *base, size_t nmemb, size_t size, void *context, int (*compar)(void *, const void *, const void *))"
|
||||
"" "stdlib.h" GIT_QSORT_BSD)
|
||||
|
||||
check_prototype_definition(qsort_r
|
||||
"void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)"
|
||||
"" "stdlib.h" GIT_QSORT_R_GNU)
|
||||
# GNU or POSIX qsort_r() has the 'context' parameter as the last argument of the
|
||||
# comparison function:
|
||||
check_prototype_definition_safe(qsort_r
|
||||
"void (qsort_r)(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *context)"
|
||||
"" "stdlib.h" GIT_QSORT_GNU)
|
||||
|
||||
check_function_exists(qsort_s GIT_QSORT_S)
|
||||
# C11 qsort_s() has the 'context' parameter as the last argument of the
|
||||
# comparison function, and returns an error status:
|
||||
check_prototype_definition_safe(qsort_s
|
||||
"errno_t (qsort_s)(void *base, rsize_t nmemb, rsize_t size, int (*compar)(const void *, const void *, void *), void *context)"
|
||||
"0" "stdlib.h" GIT_QSORT_C11)
|
||||
|
||||
# MSC qsort_s() has the 'context' parameter as the first argument of the
|
||||
# comparison function, and as the last argument of qsort_s():
|
||||
check_prototype_definition_safe(qsort_s
|
||||
"void (qsort_s)(void *base, size_t num, size_t width, int (*compare )(void *, const void *, const void *), void *context)"
|
||||
"" "stdlib.h" GIT_QSORT_MSC)
|
||||
|
||||
# random / entropy data
|
||||
|
||||
check_function_exists(getentropy GIT_RAND_GETENTROPY)
|
||||
check_function_exists(getloadavg GIT_RAND_GETLOADAVG)
|
||||
check_symbol_exists(getentropy unistd.h GIT_RAND_GETENTROPY)
|
||||
check_symbol_exists(getloadavg stdlib.h GIT_RAND_GETLOADAVG)
|
||||
|
||||
# poll
|
||||
|
||||
if(WIN32)
|
||||
set(GIT_IO_WSAPOLL 1)
|
||||
else()
|
||||
check_symbol_exists(poll poll.h GIT_IO_POLL)
|
||||
check_symbol_exists(select sys/select.h GIT_IO_SELECT)
|
||||
endif()
|
||||
|
||||
# determine architecture of the machine
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#define COMMAND_NAME "clone"
|
||||
|
||||
static char *branch, *remote_path, *local_path;
|
||||
static char *branch, *remote_path, *local_path, *depth;
|
||||
static int show_help, quiet, checkout = 1, bare;
|
||||
static bool local_path_exists;
|
||||
static cli_progress progress = CLI_PROGRESS_INIT;
|
||||
@ -36,6 +36,8 @@ static const cli_opt_spec opts[] = {
|
||||
CLI_OPT_USAGE_DEFAULT, NULL, "don't create a working directory" },
|
||||
{ CLI_OPT_TYPE_VALUE, "branch", 'b', &branch, 0,
|
||||
CLI_OPT_USAGE_DEFAULT, "name", "branch to check out" },
|
||||
{ CLI_OPT_TYPE_VALUE, "depth", 0, &depth, 0,
|
||||
CLI_OPT_USAGE_DEFAULT, "depth", "commit depth to check out " },
|
||||
{ CLI_OPT_TYPE_LITERAL },
|
||||
{ CLI_OPT_TYPE_ARG, "repository", 0, &remote_path, 0,
|
||||
CLI_OPT_USAGE_REQUIRED, "repository", "repository path" },
|
||||
@ -71,6 +73,22 @@ static char *compute_local_path(const char *orig_path)
|
||||
return local_path;
|
||||
}
|
||||
|
||||
static int compute_depth(const char *depth)
|
||||
{
|
||||
int64_t i;
|
||||
const char *endptr;
|
||||
|
||||
if (!depth)
|
||||
return 0;
|
||||
|
||||
if (git__strntol64(&i, depth, strlen(depth), &endptr, 10) < 0 || i < 0 || i > INT_MAX || *endptr) {
|
||||
fprintf(stderr, "fatal: depth '%s' is not valid.\n", depth);
|
||||
exit(128);
|
||||
}
|
||||
|
||||
return (int)i;
|
||||
}
|
||||
|
||||
static bool validate_local_path(const char *path)
|
||||
{
|
||||
if (!git_fs_path_exists(path))
|
||||
@ -127,11 +145,9 @@ int cmd_clone(int argc, char **argv)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bare)
|
||||
clone_opts.bare = 1;
|
||||
|
||||
if (branch)
|
||||
clone_opts.checkout_branch = branch;
|
||||
clone_opts.bare = !!bare;
|
||||
clone_opts.checkout_branch = branch;
|
||||
clone_opts.fetch_opts.depth = compute_depth(depth);
|
||||
|
||||
if (!checkout)
|
||||
clone_opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
|
||||
|
@ -15,10 +15,10 @@
|
||||
/*
|
||||
* Show updates to the percentage and number of objects received
|
||||
* separately from the throughput to give an accurate progress while
|
||||
* avoiding too much noise on the screen.
|
||||
* avoiding too much noise on the screen. (In milliseconds.)
|
||||
*/
|
||||
#define PROGRESS_UPDATE_TIME 0.10
|
||||
#define THROUGHPUT_UPDATE_TIME 1.00
|
||||
#define PROGRESS_UPDATE_TIME 60
|
||||
#define THROUGHPUT_UPDATE_TIME 500
|
||||
|
||||
#define is_nl(c) ((c) == '\r' || (c) == '\n')
|
||||
|
||||
@ -54,7 +54,7 @@ static int progress_write(cli_progress *progress, bool force, git_str *line)
|
||||
bool has_nl;
|
||||
size_t no_nl = no_nl_len(line->ptr, line->size);
|
||||
size_t nl = nl_len(&has_nl, line->ptr + no_nl, line->size - no_nl);
|
||||
double now = git__timer();
|
||||
uint64_t now = git_time_monotonic();
|
||||
size_t i;
|
||||
|
||||
/* Avoid spamming the console with progress updates */
|
||||
@ -191,20 +191,21 @@ static int fetch_receiving(
|
||||
{
|
||||
char *recv_units[] = { "B", "KiB", "MiB", "GiB", "TiB", NULL };
|
||||
char *rate_units[] = { "B/s", "KiB/s", "MiB/s", "GiB/s", "TiB/s", NULL };
|
||||
uint64_t now, elapsed;
|
||||
|
||||
double now, recv_len, rate, elapsed;
|
||||
double recv_len, rate;
|
||||
size_t recv_unit_idx = 0, rate_unit_idx = 0;
|
||||
bool done = (stats->received_objects == stats->total_objects);
|
||||
|
||||
if (!progress->action_start)
|
||||
progress->action_start = git__timer();
|
||||
progress->action_start = git_time_monotonic();
|
||||
|
||||
if (done && progress->action_finish)
|
||||
now = progress->action_finish;
|
||||
else if (done)
|
||||
progress->action_finish = now = git__timer();
|
||||
progress->action_finish = now = git_time_monotonic();
|
||||
else
|
||||
now = git__timer();
|
||||
now = git_time_monotonic();
|
||||
|
||||
if (progress->throughput_update &&
|
||||
now - progress->throughput_update < THROUGHPUT_UPDATE_TIME) {
|
||||
|
@ -30,11 +30,11 @@ typedef struct {
|
||||
cli_progress_t action;
|
||||
|
||||
/* Actions may time themselves (eg fetch) but are not required to */
|
||||
double action_start;
|
||||
double action_finish;
|
||||
uint64_t action_start;
|
||||
uint64_t action_finish;
|
||||
|
||||
/* Last console update, avoid too frequent updates. */
|
||||
double last_update;
|
||||
uint64_t last_update;
|
||||
|
||||
/* Accumulators for partial output and deferred updates. */
|
||||
git_str sideband;
|
||||
@ -42,7 +42,7 @@ typedef struct {
|
||||
git_str deferred;
|
||||
|
||||
/* Last update about throughput */
|
||||
double throughput_update;
|
||||
uint64_t throughput_update;
|
||||
double throughput_bytes;
|
||||
} cli_progress;
|
||||
|
||||
|
@ -24,8 +24,7 @@ target_sources(libgit2 PRIVATE ${SRC_H})
|
||||
|
||||
file(GLOB SRC_GIT2 *.c *.h
|
||||
streams/*.c streams/*.h
|
||||
transports/*.c transports/*.h
|
||||
xdiff/*.c xdiff/*.h)
|
||||
transports/*.c transports/*.h)
|
||||
list(SORT SRC_GIT2)
|
||||
target_sources(libgit2 PRIVATE ${SRC_GIT2})
|
||||
|
||||
@ -39,23 +38,6 @@ if(APPLE)
|
||||
set_source_files_properties(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated)
|
||||
endif()
|
||||
|
||||
# the xdiff dependency is not (yet) warning-free, disable warnings
|
||||
# as errors for the xdiff sources until we've sorted them out
|
||||
if(MSVC)
|
||||
set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xdiff/xmerge.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS -WX-)
|
||||
else()
|
||||
set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter")
|
||||
set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter")
|
||||
set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare")
|
||||
set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare")
|
||||
set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare")
|
||||
endif()
|
||||
|
||||
ide_split_sources(libgit2)
|
||||
list(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:util> $<TARGET_OBJECTS:libgit2> ${LIBGIT2_DEPENDENCY_OBJECTS})
|
||||
list(APPEND LIBGIT2_INCLUDES ${LIBGIT2_DEPENDENCY_INCLUDES})
|
||||
|
@ -39,8 +39,8 @@ static int annotated_commit_init(
|
||||
if ((error = git_commit_dup(&annotated_commit->commit, commit)) < 0)
|
||||
goto done;
|
||||
|
||||
git_oid_fmt(annotated_commit->id_str, git_commit_id(commit));
|
||||
annotated_commit->id_str[GIT_OID_SHA1_HEXSIZE] = '\0';
|
||||
git_oid_tostr(annotated_commit->id_str, GIT_OID_MAX_HEXSIZE + 1,
|
||||
git_commit_id(commit));
|
||||
|
||||
if (!description)
|
||||
description = annotated_commit->id_str;
|
||||
|
@ -41,7 +41,7 @@ struct git_annotated_commit {
|
||||
const char *ref_name;
|
||||
const char *remote_url;
|
||||
|
||||
char id_str[GIT_OID_SHA1_HEXSIZE+1];
|
||||
char id_str[GIT_OID_MAX_HEXSIZE + 1];
|
||||
};
|
||||
|
||||
extern int git_annotated_commit_from_head(git_annotated_commit **out,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "zstream.h"
|
||||
#include "reader.h"
|
||||
#include "index.h"
|
||||
#include "repository.h"
|
||||
#include "apply.h"
|
||||
|
||||
typedef struct {
|
||||
@ -644,7 +645,7 @@ int git_apply_to_tree(
|
||||
* put the current tree into the postimage as-is - the diff will
|
||||
* replace any entries contained therein
|
||||
*/
|
||||
if ((error = git_index_new(&postimage)) < 0 ||
|
||||
if ((error = git_index__new(&postimage, repo->oid_type)) < 0 ||
|
||||
(error = git_index_read_tree(postimage, preimage)) < 0 ||
|
||||
(error = git_reader_for_index(&post_reader, repo, postimage)) < 0)
|
||||
goto done;
|
||||
@ -851,8 +852,8 @@ int git_apply(
|
||||
* having the full repo index, so we will limit our checkout
|
||||
* to only write these files that were affected by the diff.
|
||||
*/
|
||||
if ((error = git_index_new(&preimage)) < 0 ||
|
||||
(error = git_index_new(&postimage)) < 0 ||
|
||||
if ((error = git_index__new(&preimage, repo->oid_type)) < 0 ||
|
||||
(error = git_index__new(&postimage, repo->oid_type)) < 0 ||
|
||||
(error = git_reader_for_index(&post_reader, repo, postimage)) < 0)
|
||||
goto done;
|
||||
|
||||
|
@ -60,10 +60,11 @@ static bool hunk_starts_at_or_after_line(git_blame_hunk *hunk, size_t line)
|
||||
}
|
||||
|
||||
static git_blame_hunk *new_hunk(
|
||||
size_t start,
|
||||
size_t lines,
|
||||
size_t orig_start,
|
||||
const char *path)
|
||||
size_t start,
|
||||
size_t lines,
|
||||
size_t orig_start,
|
||||
const char *path,
|
||||
git_blame *blame)
|
||||
{
|
||||
git_blame_hunk *hunk = git__calloc(1, sizeof(git_blame_hunk));
|
||||
if (!hunk) return NULL;
|
||||
@ -72,8 +73,8 @@ static git_blame_hunk *new_hunk(
|
||||
hunk->final_start_line_number = start;
|
||||
hunk->orig_start_line_number = orig_start;
|
||||
hunk->orig_path = path ? git__strdup(path) : NULL;
|
||||
git_oid_clear(&hunk->orig_commit_id, GIT_OID_SHA1);
|
||||
git_oid_clear(&hunk->final_commit_id, GIT_OID_SHA1);
|
||||
git_oid_clear(&hunk->orig_commit_id, blame->repository->oid_type);
|
||||
git_oid_clear(&hunk->final_commit_id, blame->repository->oid_type);
|
||||
|
||||
return hunk;
|
||||
}
|
||||
@ -86,13 +87,14 @@ static void free_hunk(git_blame_hunk *hunk)
|
||||
git__free(hunk);
|
||||
}
|
||||
|
||||
static git_blame_hunk *dup_hunk(git_blame_hunk *hunk)
|
||||
static git_blame_hunk *dup_hunk(git_blame_hunk *hunk, git_blame *blame)
|
||||
{
|
||||
git_blame_hunk *newhunk = new_hunk(
|
||||
hunk->final_start_line_number,
|
||||
hunk->lines_in_hunk,
|
||||
hunk->orig_start_line_number,
|
||||
hunk->orig_path);
|
||||
hunk->orig_path,
|
||||
blame);
|
||||
|
||||
if (!newhunk)
|
||||
return NULL;
|
||||
@ -237,7 +239,8 @@ static git_blame_hunk *split_hunk_in_vector(
|
||||
git_vector *vec,
|
||||
git_blame_hunk *hunk,
|
||||
size_t rel_line,
|
||||
bool return_new)
|
||||
bool return_new,
|
||||
git_blame *blame)
|
||||
{
|
||||
size_t new_line_count;
|
||||
git_blame_hunk *nh;
|
||||
@ -250,8 +253,9 @@ static git_blame_hunk *split_hunk_in_vector(
|
||||
}
|
||||
|
||||
new_line_count = hunk->lines_in_hunk - rel_line;
|
||||
nh = new_hunk(hunk->final_start_line_number + rel_line, new_line_count,
|
||||
hunk->orig_start_line_number + rel_line, hunk->orig_path);
|
||||
nh = new_hunk(hunk->final_start_line_number + rel_line,
|
||||
new_line_count, hunk->orig_start_line_number + rel_line,
|
||||
hunk->orig_path, blame);
|
||||
|
||||
if (!nh)
|
||||
return NULL;
|
||||
@ -304,7 +308,8 @@ static int index_blob_lines(git_blame *blame)
|
||||
static git_blame_hunk *hunk_from_entry(git_blame__entry *e, git_blame *blame)
|
||||
{
|
||||
git_blame_hunk *h = new_hunk(
|
||||
e->lno+1, e->num_lines, e->s_lno+1, e->suspect->path);
|
||||
e->lno+1, e->num_lines, e->s_lno+1, e->suspect->path,
|
||||
blame);
|
||||
|
||||
if (!h)
|
||||
return NULL;
|
||||
@ -445,14 +450,16 @@ static int buffer_hunk_cb(
|
||||
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->current_hunk = new_hunk(wedge_line, 0, wedge_line,
|
||||
blame->path, blame);
|
||||
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->orig_start_line_number, true,
|
||||
blame);
|
||||
GIT_ERROR_CHECK_ALLOC(blame->current_hunk);
|
||||
}
|
||||
|
||||
@ -481,7 +488,7 @@ static int buffer_line_cb(
|
||||
} 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->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);
|
||||
@ -529,7 +536,7 @@ int git_blame_buffer(
|
||||
|
||||
/* Duplicate all of the hunk structures in the reference blame */
|
||||
git_vector_foreach(&reference->hunks, i, hunk) {
|
||||
git_blame_hunk *h = dup_hunk(hunk);
|
||||
git_blame_hunk *h = dup_hunk(hunk, blame);
|
||||
GIT_ERROR_CHECK_ALLOC(h);
|
||||
|
||||
git_vector_insert(&blame->hunks, h);
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "commit.h"
|
||||
#include "blob.h"
|
||||
#include "xdiff/xinclude.h"
|
||||
#include "diff_xdiff.h"
|
||||
|
||||
/*
|
||||
|
@ -134,9 +134,9 @@ int git_branch_create(
|
||||
const git_commit *commit,
|
||||
int force)
|
||||
{
|
||||
char commit_id[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char commit_id[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
git_oid_tostr(commit_id, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit));
|
||||
git_oid_tostr(commit_id, GIT_OID_MAX_HEXSIZE + 1, git_commit_id(commit));
|
||||
return create_branch(ref_out, repository, branch_name, commit, commit_id, force);
|
||||
}
|
||||
|
||||
|
@ -106,10 +106,10 @@ static int cherrypick_state_cleanup(git_repository *repo)
|
||||
|
||||
static int cherrypick_seterr(git_commit *commit, const char *fmt)
|
||||
{
|
||||
char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char commit_oidstr[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
git_error_set(GIT_ERROR_CHERRYPICK, fmt,
|
||||
git_oid_tostr(commit_oidstr, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit)));
|
||||
git_oid_tostr(commit_oidstr, GIT_OID_MAX_HEXSIZE + 1, git_commit_id(commit)));
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -173,7 +173,7 @@ int git_cherrypick(
|
||||
git_cherrypick_options opts;
|
||||
git_reference *our_ref = NULL;
|
||||
git_commit *our_commit = NULL;
|
||||
char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char commit_oidstr[GIT_OID_MAX_HEXSIZE + 1];
|
||||
const char *commit_msg, *commit_summary;
|
||||
git_str their_label = GIT_STR_INIT;
|
||||
git_index *index = NULL;
|
||||
|
@ -420,7 +420,9 @@ static int clone_into(
|
||||
|
||||
memcpy(&fetch_opts, opts, sizeof(git_fetch_options));
|
||||
fetch_opts.update_fetchhead = 0;
|
||||
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
|
||||
|
||||
if (!opts->depth)
|
||||
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
|
||||
|
||||
if ((error = git_remote_connect_options__from_fetch_opts(&connect_opts, remote, &fetch_opts)) < 0)
|
||||
goto cleanup;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "object.h"
|
||||
#include "array.h"
|
||||
#include "oidarray.h"
|
||||
#include "grafts.h"
|
||||
|
||||
void git_commit__free(void *_commit)
|
||||
{
|
||||
@ -427,10 +428,6 @@ static int commit_parse(
|
||||
buffer += tree_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: commit grafts!
|
||||
*/
|
||||
|
||||
while (git_object__parse_oid_header(&parent_id,
|
||||
&buffer, buffer_end, "parent ",
|
||||
opts->oid_type) == 0) {
|
||||
@ -532,16 +529,41 @@ int git_commit__parse_raw(
|
||||
return commit_parse(commit, data, size, &parse_options);
|
||||
}
|
||||
|
||||
static int assign_commit_parents_from_graft(git_commit *commit, git_commit_graft *graft) {
|
||||
size_t idx;
|
||||
git_oid *oid;
|
||||
|
||||
git_array_clear(commit->parent_ids);
|
||||
git_array_init_to_size(commit->parent_ids, git_array_size(graft->parents));
|
||||
git_array_foreach(graft->parents, idx, oid) {
|
||||
git_oid *id = git_array_alloc(commit->parent_ids);
|
||||
GIT_ERROR_CHECK_ALLOC(id);
|
||||
|
||||
git_oid_cpy(id, oid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_commit__parse_ext(
|
||||
git_commit *commit,
|
||||
git_odb_object *odb_obj,
|
||||
git_commit__parse_options *parse_opts)
|
||||
{
|
||||
return commit_parse(
|
||||
commit,
|
||||
git_odb_object_data(odb_obj),
|
||||
git_odb_object_size(odb_obj),
|
||||
parse_opts);
|
||||
git_repository *repo = git_object_owner((git_object *)commit);
|
||||
git_commit_graft *graft;
|
||||
int error;
|
||||
|
||||
if ((error = commit_parse(commit, git_odb_object_data(odb_obj),
|
||||
git_odb_object_size(odb_obj), parse_opts)) < 0)
|
||||
return error;
|
||||
|
||||
/* Perform necessary grafts */
|
||||
if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) != 0 &&
|
||||
git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) != 0)
|
||||
return 0;
|
||||
|
||||
return assign_commit_parents_from_graft(commit, graft);
|
||||
}
|
||||
|
||||
#define GIT_COMMIT_GETTER(_rvalue, _name, _return, _invalid) \
|
||||
|
@ -138,19 +138,22 @@ static int commit_graph_parse_oid_lookup(
|
||||
struct git_commit_graph_chunk *chunk_oid_lookup)
|
||||
{
|
||||
uint32_t i;
|
||||
unsigned char *oid, *prev_oid, zero_oid[GIT_OID_SHA1_SIZE] = {0};
|
||||
unsigned char *oid, *prev_oid, zero_oid[GIT_OID_MAX_SIZE] = {0};
|
||||
size_t oid_size;
|
||||
|
||||
oid_size = git_oid_size(file->oid_type);
|
||||
|
||||
if (chunk_oid_lookup->offset == 0)
|
||||
return commit_graph_error("missing OID Lookup chunk");
|
||||
if (chunk_oid_lookup->length == 0)
|
||||
return commit_graph_error("empty OID Lookup chunk");
|
||||
if (chunk_oid_lookup->length != file->num_commits * GIT_OID_SHA1_SIZE)
|
||||
if (chunk_oid_lookup->length != file->num_commits * oid_size)
|
||||
return commit_graph_error("OID Lookup chunk has wrong length");
|
||||
|
||||
file->oid_lookup = oid = (unsigned char *)(data + chunk_oid_lookup->offset);
|
||||
prev_oid = zero_oid;
|
||||
for (i = 0; i < file->num_commits; ++i, oid += GIT_OID_SHA1_SIZE) {
|
||||
if (git_oid_raw_cmp(prev_oid, oid, GIT_OID_SHA1_SIZE) >= 0)
|
||||
for (i = 0; i < file->num_commits; ++i, oid += oid_size) {
|
||||
if (git_oid_raw_cmp(prev_oid, oid, oid_size) >= 0)
|
||||
return commit_graph_error("OID Lookup index is non-monotonic");
|
||||
prev_oid = oid;
|
||||
}
|
||||
@ -163,11 +166,13 @@ static int commit_graph_parse_commit_data(
|
||||
const unsigned char *data,
|
||||
struct git_commit_graph_chunk *chunk_commit_data)
|
||||
{
|
||||
size_t oid_size = git_oid_size(file->oid_type);
|
||||
|
||||
if (chunk_commit_data->offset == 0)
|
||||
return commit_graph_error("missing Commit Data chunk");
|
||||
if (chunk_commit_data->length == 0)
|
||||
return commit_graph_error("empty Commit Data chunk");
|
||||
if (chunk_commit_data->length != file->num_commits * (GIT_OID_SHA1_SIZE + 16))
|
||||
if (chunk_commit_data->length != file->num_commits * (oid_size + 16))
|
||||
return commit_graph_error("Commit Data chunk has wrong length");
|
||||
|
||||
file->commit_data = data + chunk_commit_data->offset;
|
||||
@ -209,7 +214,9 @@ int git_commit_graph_file_parse(
|
||||
|
||||
GIT_ASSERT_ARG(file);
|
||||
|
||||
if (size < sizeof(struct git_commit_graph_header) + GIT_OID_SHA1_SIZE)
|
||||
checksum_size = git_oid_size(file->oid_type);
|
||||
|
||||
if (size < sizeof(struct git_commit_graph_header) + checksum_size)
|
||||
return commit_graph_error("commit-graph is too short");
|
||||
|
||||
hdr = ((struct git_commit_graph_header *)data);
|
||||
@ -226,8 +233,7 @@ int git_commit_graph_file_parse(
|
||||
* headers, and a special zero chunk.
|
||||
*/
|
||||
last_chunk_offset = sizeof(struct git_commit_graph_header) + (1 + hdr->chunks) * 12;
|
||||
trailer_offset = size - GIT_OID_SHA1_SIZE;
|
||||
checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
trailer_offset = size - checksum_size;
|
||||
|
||||
if (trailer_offset < last_chunk_offset)
|
||||
return commit_graph_error("wrong commit-graph size");
|
||||
@ -295,25 +301,35 @@ int git_commit_graph_file_parse(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_commit_graph_new(git_commit_graph **cgraph_out, const char *objects_dir, bool open_file)
|
||||
int git_commit_graph_new(
|
||||
git_commit_graph **cgraph_out,
|
||||
const char *objects_dir,
|
||||
bool open_file,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
git_commit_graph *cgraph = NULL;
|
||||
int error = 0;
|
||||
|
||||
GIT_ASSERT_ARG(cgraph_out);
|
||||
GIT_ASSERT_ARG(objects_dir);
|
||||
GIT_ASSERT_ARG(oid_type);
|
||||
|
||||
cgraph = git__calloc(1, sizeof(git_commit_graph));
|
||||
GIT_ERROR_CHECK_ALLOC(cgraph);
|
||||
|
||||
cgraph->oid_type = oid_type;
|
||||
|
||||
error = git_str_joinpath(&cgraph->filename, objects_dir, "info/commit-graph");
|
||||
if (error < 0)
|
||||
goto error;
|
||||
|
||||
if (open_file) {
|
||||
error = git_commit_graph_file_open(&cgraph->file, git_str_cstr(&cgraph->filename));
|
||||
error = git_commit_graph_file_open(&cgraph->file,
|
||||
git_str_cstr(&cgraph->filename), oid_type);
|
||||
|
||||
if (error < 0)
|
||||
goto error;
|
||||
|
||||
cgraph->checked = 1;
|
||||
}
|
||||
|
||||
@ -326,14 +342,18 @@ error:
|
||||
}
|
||||
|
||||
int git_commit_graph_validate(git_commit_graph *cgraph) {
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
size_t checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
size_t trailer_offset = cgraph->file->graph_map.len - checksum_size;
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
git_hash_algorithm_t checksum_type;
|
||||
size_t checksum_size, trailer_offset;
|
||||
|
||||
checksum_type = git_oid_algorithm(cgraph->oid_type);
|
||||
checksum_size = git_hash_size(checksum_type);
|
||||
trailer_offset = cgraph->file->graph_map.len - checksum_size;
|
||||
|
||||
if (cgraph->file->graph_map.len < checksum_size)
|
||||
return commit_graph_error("map length too small");
|
||||
|
||||
if (git_hash_buf(checksum, cgraph->file->graph_map.data, trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0)
|
||||
if (git_hash_buf(checksum, cgraph->file->graph_map.data, trailer_offset, checksum_type) < 0)
|
||||
return commit_graph_error("could not calculate signature");
|
||||
if (memcmp(checksum, cgraph->file->checksum, checksum_size) != 0)
|
||||
return commit_graph_error("index signature mismatch");
|
||||
@ -341,16 +361,32 @@ int git_commit_graph_validate(git_commit_graph *cgraph) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_commit_graph_open(git_commit_graph **cgraph_out, const char *objects_dir)
|
||||
int git_commit_graph_open(
|
||||
git_commit_graph **cgraph_out,
|
||||
const char *objects_dir
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_oid_t oid_type
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int error = git_commit_graph_new(cgraph_out, objects_dir, true);
|
||||
if (!error) {
|
||||
#ifndef GIT_EXPERIMENTAL_SHA256
|
||||
git_oid_t oid_type = GIT_OID_SHA1;
|
||||
#endif
|
||||
int error;
|
||||
|
||||
error = git_commit_graph_new(cgraph_out, objects_dir, true,
|
||||
oid_type);
|
||||
|
||||
if (!error)
|
||||
return git_commit_graph_validate(*cgraph_out);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *path)
|
||||
int git_commit_graph_file_open(
|
||||
git_commit_graph_file **file_out,
|
||||
const char *path,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
git_commit_graph_file *file;
|
||||
git_file fd = -1;
|
||||
@ -379,6 +415,8 @@ int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *pat
|
||||
file = git__calloc(1, sizeof(git_commit_graph_file));
|
||||
GIT_ERROR_CHECK_ALLOC(file);
|
||||
|
||||
file->oid_type = oid_type;
|
||||
|
||||
error = git_futils_mmap_ro(&file->graph_map, fd, 0, cgraph_size);
|
||||
p_close(fd);
|
||||
if (error < 0) {
|
||||
@ -395,7 +433,9 @@ int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *pat
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_commit_graph_get_file(git_commit_graph_file **file_out, git_commit_graph *cgraph)
|
||||
int git_commit_graph_get_file(
|
||||
git_commit_graph_file **file_out,
|
||||
git_commit_graph *cgraph)
|
||||
{
|
||||
if (!cgraph->checked) {
|
||||
int error = 0;
|
||||
@ -405,7 +445,8 @@ int git_commit_graph_get_file(git_commit_graph_file **file_out, git_commit_graph
|
||||
cgraph->checked = 1;
|
||||
|
||||
/* Best effort */
|
||||
error = git_commit_graph_file_open(&result, git_str_cstr(&cgraph->filename));
|
||||
error = git_commit_graph_file_open(&result,
|
||||
git_str_cstr(&cgraph->filename), cgraph->oid_type);
|
||||
|
||||
if (error < 0)
|
||||
return error;
|
||||
@ -441,6 +482,7 @@ static int git_commit_graph_entry_get_byindex(
|
||||
size_t pos)
|
||||
{
|
||||
const unsigned char *commit_data;
|
||||
size_t oid_size = git_oid_size(file->oid_type);
|
||||
|
||||
GIT_ASSERT_ARG(e);
|
||||
GIT_ASSERT_ARG(file);
|
||||
@ -450,15 +492,15 @@ static int git_commit_graph_entry_get_byindex(
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
commit_data = file->commit_data + pos * (GIT_OID_SHA1_SIZE + 4 * sizeof(uint32_t));
|
||||
git_oid__fromraw(&e->tree_oid, commit_data, GIT_OID_SHA1);
|
||||
e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE)));
|
||||
commit_data = file->commit_data + pos * (oid_size + 4 * sizeof(uint32_t));
|
||||
git_oid__fromraw(&e->tree_oid, commit_data, file->oid_type);
|
||||
e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + oid_size)));
|
||||
e->parent_indices[1] = ntohl(
|
||||
*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE + sizeof(uint32_t))));
|
||||
*((uint32_t *)(commit_data + oid_size + sizeof(uint32_t))));
|
||||
e->parent_count = (e->parent_indices[0] != GIT_COMMIT_GRAPH_MISSING_PARENT)
|
||||
+ (e->parent_indices[1] != GIT_COMMIT_GRAPH_MISSING_PARENT);
|
||||
e->generation = ntohl(*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE + 2 * sizeof(uint32_t))));
|
||||
e->commit_time = ntohl(*((uint32_t *)(commit_data + GIT_OID_SHA1_SIZE + 3 * sizeof(uint32_t))));
|
||||
e->generation = ntohl(*((uint32_t *)(commit_data + oid_size + 2 * sizeof(uint32_t))));
|
||||
e->commit_time = ntohl(*((uint32_t *)(commit_data + oid_size + 3 * sizeof(uint32_t))));
|
||||
|
||||
e->commit_time |= (e->generation & UINT64_C(0x3)) << UINT64_C(32);
|
||||
e->generation >>= 2u;
|
||||
@ -485,7 +527,7 @@ static int git_commit_graph_entry_get_byindex(
|
||||
}
|
||||
}
|
||||
|
||||
git_oid__fromraw(&e->sha1, &file->oid_lookup[pos * GIT_OID_SHA1_SIZE], GIT_OID_SHA1);
|
||||
git_oid__fromraw(&e->sha1, &file->oid_lookup[pos * oid_size], file->oid_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -494,8 +536,8 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons
|
||||
git_file fd = -1;
|
||||
struct stat st;
|
||||
ssize_t bytes_read;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
size_t checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
size_t checksum_size = git_oid_size(file->oid_type);
|
||||
|
||||
/* TODO: properly open the file without access time using O_NOATIME */
|
||||
fd = git_futils_open_ro(path);
|
||||
@ -530,35 +572,40 @@ int git_commit_graph_entry_find(
|
||||
int pos, found = 0;
|
||||
uint32_t hi, lo;
|
||||
const unsigned char *current = NULL;
|
||||
size_t oid_size, oid_hexsize;
|
||||
|
||||
GIT_ASSERT_ARG(e);
|
||||
GIT_ASSERT_ARG(file);
|
||||
GIT_ASSERT_ARG(short_oid);
|
||||
|
||||
oid_size = git_oid_size(file->oid_type);
|
||||
oid_hexsize = git_oid_hexsize(file->oid_type);
|
||||
|
||||
hi = ntohl(file->oid_fanout[(int)short_oid->id[0]]);
|
||||
lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(file->oid_fanout[(int)short_oid->id[0] - 1]));
|
||||
|
||||
pos = git_pack__lookup_id(file->oid_lookup, GIT_OID_SHA1_SIZE, lo, hi, short_oid->id, GIT_OID_SHA1);
|
||||
pos = git_pack__lookup_id(file->oid_lookup, oid_size, lo, hi,
|
||||
short_oid->id, file->oid_type);
|
||||
|
||||
if (pos >= 0) {
|
||||
/* An object matching exactly the oid was found */
|
||||
found = 1;
|
||||
current = file->oid_lookup + (pos * GIT_OID_SHA1_SIZE);
|
||||
current = file->oid_lookup + (pos * oid_size);
|
||||
} else {
|
||||
/* No object was found */
|
||||
/* pos refers to the object with the "closest" oid to short_oid */
|
||||
pos = -1 - pos;
|
||||
if (pos < (int)file->num_commits) {
|
||||
current = file->oid_lookup + (pos * GIT_OID_SHA1_SIZE);
|
||||
current = file->oid_lookup + (pos * oid_size);
|
||||
|
||||
if (!git_oid_raw_ncmp(short_oid->id, current, len))
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (found && len != GIT_OID_SHA1_HEXSIZE && pos + 1 < (int)file->num_commits) {
|
||||
if (found && len != oid_hexsize && pos + 1 < (int)file->num_commits) {
|
||||
/* Check for ambiguousity */
|
||||
const unsigned char *next = current + GIT_OID_SHA1_SIZE;
|
||||
const unsigned char *next = current + oid_size;
|
||||
|
||||
if (!git_oid_raw_ncmp(short_oid->id, next, len))
|
||||
found = 2;
|
||||
@ -637,11 +684,27 @@ static int packed_commit__cmp(const void *a_, const void *b_)
|
||||
return git_oid_cmp(&a->sha1, &b->sha1);
|
||||
}
|
||||
|
||||
int git_commit_graph_writer_new(git_commit_graph_writer **out, const char *objects_info_dir)
|
||||
int git_commit_graph_writer_new(
|
||||
git_commit_graph_writer **out,
|
||||
const char *objects_info_dir
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_oid_t oid_type
|
||||
#endif
|
||||
)
|
||||
{
|
||||
git_commit_graph_writer *w = git__calloc(1, sizeof(git_commit_graph_writer));
|
||||
git_commit_graph_writer *w;
|
||||
|
||||
#ifndef GIT_EXPERIMENTAL_SHA256
|
||||
git_oid_t oid_type = GIT_OID_SHA1;
|
||||
#endif
|
||||
|
||||
GIT_ASSERT_ARG(out && objects_info_dir && oid_type);
|
||||
|
||||
w = git__calloc(1, sizeof(git_commit_graph_writer));
|
||||
GIT_ERROR_CHECK_ALLOC(w);
|
||||
|
||||
w->oid_type = oid_type;
|
||||
|
||||
if (git_str_sets(&w->objects_info_dir, objects_info_dir) < 0) {
|
||||
git__free(w);
|
||||
return -1;
|
||||
@ -993,8 +1056,9 @@ static int commit_graph_write(
|
||||
off64_t offset;
|
||||
git_str oid_lookup = GIT_STR_INIT, commit_data = GIT_STR_INIT,
|
||||
extra_edge_list = GIT_STR_INIT;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
size_t checksum_size;
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
git_hash_algorithm_t checksum_type;
|
||||
size_t checksum_size, oid_size;
|
||||
git_hash_ctx ctx;
|
||||
struct commit_graph_write_hash_context hash_cb_data = {0};
|
||||
|
||||
@ -1007,8 +1071,11 @@ static int commit_graph_write(
|
||||
hash_cb_data.cb_data = cb_data;
|
||||
hash_cb_data.ctx = &ctx;
|
||||
|
||||
checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1);
|
||||
oid_size = git_oid_size(w->oid_type);
|
||||
checksum_type = git_oid_algorithm(w->oid_type);
|
||||
checksum_size = git_hash_size(checksum_type);
|
||||
|
||||
error = git_hash_ctx_init(&ctx, checksum_type);
|
||||
if (error < 0)
|
||||
return error;
|
||||
cb_data = &hash_cb_data;
|
||||
@ -1035,7 +1102,7 @@ static int commit_graph_write(
|
||||
git_vector_foreach (&w->commits, i, packed_commit) {
|
||||
error = git_str_put(&oid_lookup,
|
||||
(const char *)&packed_commit->sha1.id,
|
||||
GIT_OID_SHA1_SIZE);
|
||||
oid_size);
|
||||
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
@ -1052,7 +1119,7 @@ static int commit_graph_write(
|
||||
|
||||
error = git_str_put(&commit_data,
|
||||
(const char *)&packed_commit->tree_oid.id,
|
||||
GIT_OID_SHA1_SIZE);
|
||||
oid_size);
|
||||
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
@ -30,6 +30,9 @@
|
||||
typedef struct git_commit_graph_file {
|
||||
git_map graph_map;
|
||||
|
||||
/* The type of object IDs in the commit graph file. */
|
||||
git_oid_t oid_type;
|
||||
|
||||
/* The OID Fanout table. */
|
||||
const uint32_t *oid_fanout;
|
||||
/* The total number of commits in the graph. */
|
||||
@ -84,10 +87,10 @@ typedef struct git_commit_graph_entry {
|
||||
/* The index within the Extra Edge List of any parent after the first two. */
|
||||
size_t extra_parents_index;
|
||||
|
||||
/* The SHA-1 hash of the root tree of the commit. */
|
||||
/* The object ID of the root tree of the commit. */
|
||||
git_oid tree_oid;
|
||||
|
||||
/* The SHA-1 hash of the requested commit. */
|
||||
/* The object ID hash of the requested commit. */
|
||||
git_oid sha1;
|
||||
} git_commit_graph_entry;
|
||||
|
||||
@ -99,18 +102,28 @@ struct git_commit_graph {
|
||||
/* The underlying commit-graph file. */
|
||||
git_commit_graph_file *file;
|
||||
|
||||
/* The object ID types in the commit graph. */
|
||||
git_oid_t oid_type;
|
||||
|
||||
/* Whether the commit-graph file was already checked for validity. */
|
||||
bool checked;
|
||||
};
|
||||
|
||||
/** Create a new commit-graph, optionally opening the underlying file. */
|
||||
int git_commit_graph_new(git_commit_graph **cgraph_out, const char *objects_dir, bool open_file);
|
||||
int git_commit_graph_new(
|
||||
git_commit_graph **cgraph_out,
|
||||
const char *objects_dir,
|
||||
bool open_file,
|
||||
git_oid_t oid_type);
|
||||
|
||||
/** Validate the checksum of a commit graph */
|
||||
int git_commit_graph_validate(git_commit_graph *cgraph);
|
||||
|
||||
/** Open and validate a commit-graph file. */
|
||||
int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *path);
|
||||
int git_commit_graph_file_open(
|
||||
git_commit_graph_file **file_out,
|
||||
const char *path,
|
||||
git_oid_t oid_type);
|
||||
|
||||
/*
|
||||
* Attempt to get the git_commit_graph's commit-graph file. This object is
|
||||
@ -134,6 +147,9 @@ struct git_commit_graph_writer {
|
||||
*/
|
||||
git_str objects_info_dir;
|
||||
|
||||
/* The object ID type of the commit graph. */
|
||||
git_oid_t oid_type;
|
||||
|
||||
/* The list of packed commits. */
|
||||
git_vector commits;
|
||||
};
|
||||
|
@ -43,13 +43,18 @@ int git_commit_list_time_cmp(const void *a, const void *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
|
||||
{
|
||||
git_commit_list *git_commit_list_create(git_commit_list_node *item, git_commit_list *next) {
|
||||
git_commit_list *new_list = git__malloc(sizeof(git_commit_list));
|
||||
if (new_list != NULL) {
|
||||
new_list->item = item;
|
||||
new_list->next = *list_p;
|
||||
new_list->next = next;
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
|
||||
{
|
||||
git_commit_list *new_list = git_commit_list_create(item, *list_p);
|
||||
*list_p = new_list;
|
||||
return new_list;
|
||||
}
|
||||
@ -125,7 +130,7 @@ static int commit_quick_parse(
|
||||
git_oid *parent_oid;
|
||||
git_commit *commit;
|
||||
git_commit__parse_options parse_opts = {
|
||||
GIT_OID_SHA1,
|
||||
walk->repo->oid_type,
|
||||
GIT_COMMIT_PARSE_QUICK
|
||||
};
|
||||
size_t i;
|
||||
@ -176,7 +181,9 @@ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
|
||||
if (cgraph_file) {
|
||||
git_commit_graph_entry e;
|
||||
|
||||
error = git_commit_graph_entry_find(&e, cgraph_file, &commit->oid, GIT_OID_SHA1_SIZE);
|
||||
error = git_commit_graph_entry_find(&e, cgraph_file,
|
||||
&commit->oid, git_oid_size(walk->repo->oid_type));
|
||||
|
||||
if (error == 0 && git__is_uint16(e.parent_count)) {
|
||||
size_t i;
|
||||
commit->generation = (uint32_t)e.generation;
|
||||
|
@ -49,6 +49,7 @@ git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk);
|
||||
int git_commit_list_generation_cmp(const void *a, const void *b);
|
||||
int git_commit_list_time_cmp(const void *a, const void *b);
|
||||
void git_commit_list_free(git_commit_list **list_p);
|
||||
git_commit_list *git_commit_list_create(git_commit_list_node *item, git_commit_list *next);
|
||||
git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p);
|
||||
git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p);
|
||||
int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit);
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
typedef struct config_file {
|
||||
git_futils_filestamp stamp;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
unsigned char checksum[GIT_HASH_SHA256_SIZE];
|
||||
char *path;
|
||||
git_array_t(struct config_file) includes;
|
||||
} config_file;
|
||||
@ -133,7 +133,7 @@ static int config_file_is_modified(int *modified, config_file *file)
|
||||
{
|
||||
config_file *include;
|
||||
git_str buf = GIT_STR_INIT;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
unsigned char checksum[GIT_HASH_SHA256_SIZE];
|
||||
uint32_t i;
|
||||
int error = 0;
|
||||
|
||||
@ -145,10 +145,10 @@ static int config_file_is_modified(int *modified, config_file *file)
|
||||
if ((error = git_futils_readbuffer(&buf, file->path)) < 0)
|
||||
goto out;
|
||||
|
||||
if ((error = git_hash_buf(checksum, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0)
|
||||
if ((error = git_hash_buf(checksum, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA256)) < 0)
|
||||
goto out;
|
||||
|
||||
if (memcmp(checksum, file->checksum, GIT_HASH_SHA1_SIZE) != 0) {
|
||||
if (memcmp(checksum, file->checksum, GIT_HASH_SHA256_SIZE) != 0) {
|
||||
*modified = 1;
|
||||
goto out;
|
||||
}
|
||||
@ -881,7 +881,7 @@ static int config_file_read(
|
||||
goto out;
|
||||
|
||||
git_futils_filestamp_set_from_stat(&file->stamp, &st);
|
||||
if ((error = git_hash_buf(file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0)
|
||||
if ((error = git_hash_buf(file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA256)) < 0)
|
||||
goto out;
|
||||
|
||||
if ((error = config_file_read_buffer(entries, repo, file, level, depth,
|
||||
@ -1116,7 +1116,12 @@ static int write_on_eof(
|
||||
/*
|
||||
* This is pretty much the parsing, except we write out anything we don't have
|
||||
*/
|
||||
static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char *value)
|
||||
static int config_file_write(
|
||||
config_file_backend *cfg,
|
||||
const char *orig_key,
|
||||
const char *key,
|
||||
const git_regexp *preg,
|
||||
const char *value)
|
||||
|
||||
{
|
||||
char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot;
|
||||
@ -1131,8 +1136,9 @@ static int config_file_write(config_file_backend *cfg, const char *orig_key, con
|
||||
if (cfg->locked) {
|
||||
error = git_str_puts(&contents, git_str_cstr(&cfg->locked_content) == NULL ? "" : git_str_cstr(&cfg->locked_content));
|
||||
} else {
|
||||
if ((error = git_filebuf_open(&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS,
|
||||
GIT_CONFIG_FILE_MODE)) < 0)
|
||||
if ((error = git_filebuf_open(&file, cfg->file.path,
|
||||
GIT_FILEBUF_HASH_SHA256,
|
||||
GIT_CONFIG_FILE_MODE)) < 0)
|
||||
goto done;
|
||||
|
||||
/* We need to read in our own config file */
|
||||
|
@ -363,12 +363,15 @@ static int find_unique_abbrev_size(
|
||||
size_t size = abbreviated_size;
|
||||
git_odb *odb;
|
||||
git_oid dummy;
|
||||
size_t hexsize;
|
||||
int error;
|
||||
|
||||
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
return error;
|
||||
|
||||
while (size < GIT_OID_SHA1_HEXSIZE) {
|
||||
hexsize = git_oid_hexsize(repo->oid_type);
|
||||
|
||||
while (size < hexsize) {
|
||||
if ((error = git_odb_exists_prefix(&dummy, odb, oid_in, size)) == 0) {
|
||||
*out = (int) size;
|
||||
return 0;
|
||||
@ -383,7 +386,7 @@ static int find_unique_abbrev_size(
|
||||
}
|
||||
|
||||
/* If we didn't find any shorter prefix, we have to do the whole thing */
|
||||
*out = GIT_OID_SHA1_HEXSIZE;
|
||||
*out = (int)hexsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -397,7 +400,7 @@ static int show_suffix(
|
||||
{
|
||||
int error, size = 0;
|
||||
|
||||
char hex_oid[GIT_OID_SHA1_HEXSIZE];
|
||||
char hex_oid[GIT_OID_MAX_HEXSIZE];
|
||||
|
||||
if ((error = find_unique_abbrev_size(&size, repo, id, abbrev_size)) < 0)
|
||||
return error;
|
||||
@ -414,7 +417,7 @@ static int show_suffix(
|
||||
#define MAX_CANDIDATES_TAGS FLAG_BITS - 1
|
||||
|
||||
static int describe_not_found(const git_oid *oid, const char *message_format) {
|
||||
char oid_str[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char oid_str[GIT_OID_MAX_HEXSIZE + 1];
|
||||
git_oid_tostr(oid_str, sizeof(oid_str), oid);
|
||||
|
||||
git_error_set(GIT_ERROR_DESCRIBE, message_format, oid_str);
|
||||
@ -525,7 +528,7 @@ static int describe(
|
||||
if (annotated_cnt && (git_pqueue_size(&list) == 0)) {
|
||||
/*
|
||||
if (debug) {
|
||||
char oid_str[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char oid_str[GIT_OID_MAX_HEXSIZE + 1];
|
||||
git_oid_tostr(oid_str, sizeof(oid_str), &c->oid);
|
||||
|
||||
fprintf(stderr, "finished search at %s\n", oid_str);
|
||||
@ -592,7 +595,7 @@ static int describe(
|
||||
"head", "lightweight", "annotated",
|
||||
};
|
||||
|
||||
char oid_str[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char oid_str[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
if (debug) {
|
||||
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
|
||||
@ -816,7 +819,7 @@ static int git_describe__format(
|
||||
|
||||
/* If we didn't find *any* tags, we fall back to the commit's id */
|
||||
if (result->fallback_to_id) {
|
||||
char hex_oid[GIT_OID_SHA1_HEXSIZE + 1] = {0};
|
||||
char hex_oid[GIT_OID_MAX_HEXSIZE + 1] = {0};
|
||||
int size = 0;
|
||||
|
||||
if ((error = find_unique_abbrev_size(
|
||||
|
@ -19,8 +19,10 @@
|
||||
#include "git2/email.h"
|
||||
|
||||
struct patch_id_args {
|
||||
git_diff *diff;
|
||||
git_hash_ctx ctx;
|
||||
git_oid result;
|
||||
git_oid_t oid_type;
|
||||
int first_file;
|
||||
};
|
||||
|
||||
@ -280,17 +282,19 @@ int git_diff_find_options_init(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flush_hunk(git_oid *result, git_hash_ctx *ctx)
|
||||
static int flush_hunk(git_oid *result, struct patch_id_args *args)
|
||||
{
|
||||
git_hash_ctx *ctx = &args->ctx;
|
||||
git_oid hash;
|
||||
unsigned short carry = 0;
|
||||
int error, i;
|
||||
size_t i;
|
||||
int error;
|
||||
|
||||
if ((error = git_hash_final(hash.id, ctx)) < 0 ||
|
||||
(error = git_hash_init(ctx)) < 0)
|
||||
return error;
|
||||
|
||||
for (i = 0; i < GIT_OID_SHA1_SIZE; i++) {
|
||||
for (i = 0; i < git_oid_size(args->oid_type); i++) {
|
||||
carry += result->id[i] + hash.id[i];
|
||||
result->id[i] = (unsigned char)carry;
|
||||
carry >>= 8;
|
||||
@ -338,7 +342,7 @@ static int diff_patchid_print_callback_to_buf(
|
||||
|
||||
if (line->origin == GIT_DIFF_LINE_FILE_HDR &&
|
||||
!args->first_file &&
|
||||
(error = flush_hunk(&args->result, &args->ctx) < 0))
|
||||
(error = flush_hunk(&args->result, args) < 0))
|
||||
goto out;
|
||||
|
||||
if ((error = git_hash_update(&args->ctx, buf.ptr, buf.size)) < 0)
|
||||
@ -362,14 +366,19 @@ int git_diff_patchid_options_init(git_diff_patchid_options *opts, unsigned int v
|
||||
int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opts)
|
||||
{
|
||||
struct patch_id_args args;
|
||||
git_hash_algorithm_t algorithm;
|
||||
int error;
|
||||
|
||||
GIT_ERROR_CHECK_VERSION(
|
||||
opts, GIT_DIFF_PATCHID_OPTIONS_VERSION, "git_diff_patchid_options");
|
||||
|
||||
algorithm = git_oid_algorithm(diff->opts.oid_type);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.diff = diff;
|
||||
args.first_file = 1;
|
||||
if ((error = git_hash_ctx_init(&args.ctx, GIT_HASH_ALGORITHM_SHA1)) < 0)
|
||||
args.oid_type = diff->opts.oid_type;
|
||||
if ((error = git_hash_ctx_init(&args.ctx, algorithm)) < 0)
|
||||
goto out;
|
||||
|
||||
if ((error = git_diff_print(diff,
|
||||
@ -378,11 +387,11 @@ int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opt
|
||||
&args)) < 0)
|
||||
goto out;
|
||||
|
||||
if ((error = (flush_hunk(&args.result, &args.ctx))) < 0)
|
||||
if ((error = (flush_hunk(&args.result, &args))) < 0)
|
||||
goto out;
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
args.result.type = GIT_OID_SHA1;
|
||||
args.result.type = diff->opts.oid_type;
|
||||
#endif
|
||||
|
||||
git_oid_cpy(out, &args.result);
|
||||
|
@ -30,15 +30,15 @@ typedef enum {
|
||||
} git_diff_origin_t;
|
||||
|
||||
struct git_diff {
|
||||
git_refcount rc;
|
||||
git_refcount rc;
|
||||
git_repository *repo;
|
||||
git_attr_session attrsession;
|
||||
git_attr_session attrsession;
|
||||
git_diff_origin_t type;
|
||||
git_diff_options opts;
|
||||
git_vector deltas; /* vector of git_diff_delta */
|
||||
git_diff_options opts;
|
||||
git_vector deltas; /* vector of git_diff_delta */
|
||||
git_pool pool;
|
||||
git_iterator_t old_src;
|
||||
git_iterator_t new_src;
|
||||
git_iterator_t old_src;
|
||||
git_iterator_t new_src;
|
||||
git_diff_perfdata perf;
|
||||
|
||||
int (*strcomp)(const char *, const char *);
|
||||
|
@ -112,7 +112,7 @@ int git_diff_file_content__init_from_diff(
|
||||
case GIT_DELTA_DELETED:
|
||||
has_data = use_old; break;
|
||||
case GIT_DELTA_UNTRACKED:
|
||||
has_data = !use_old &&
|
||||
has_data = (use_old == (diff->opts.flags & GIT_DIFF_REVERSE)) &&
|
||||
(diff->opts.flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) != 0;
|
||||
break;
|
||||
case GIT_DELTA_UNREADABLE:
|
||||
@ -144,7 +144,7 @@ int git_diff_file_content__init_from_src(
|
||||
|
||||
if (!src->blob && !src->buf) {
|
||||
fc->flags |= GIT_DIFF_FLAG__NO_DATA;
|
||||
git_oid_clear(&fc->file->id, GIT_OID_SHA1);
|
||||
git_oid_clear(&fc->file->id, opts->oid_type);
|
||||
} else {
|
||||
fc->flags |= GIT_DIFF_FLAG__LOADED;
|
||||
fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
@ -154,7 +154,7 @@ int git_diff_file_content__init_from_src(
|
||||
git_blob_dup((git_blob **)&fc->blob, (git_blob *) src->blob);
|
||||
fc->file->size = git_blob_rawsize(src->blob);
|
||||
git_oid_cpy(&fc->file->id, git_blob_id(src->blob));
|
||||
fc->file->id_abbrev = GIT_OID_SHA1_HEXSIZE;
|
||||
fc->file->id_abbrev = (uint16_t)git_oid_hexsize(repo->oid_type);
|
||||
|
||||
fc->map.len = (size_t)fc->file->size;
|
||||
fc->map.data = (char *)git_blob_rawcontent(src->blob);
|
||||
@ -162,10 +162,10 @@ int git_diff_file_content__init_from_src(
|
||||
fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
|
||||
} else {
|
||||
int error;
|
||||
if ((error = git_odb__hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB, GIT_OID_SHA1)) < 0)
|
||||
if ((error = git_odb__hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB, opts->oid_type)) < 0)
|
||||
return error;
|
||||
fc->file->size = src->buflen;
|
||||
fc->file->id_abbrev = GIT_OID_SHA1_HEXSIZE;
|
||||
fc->file->id_abbrev = (uint16_t)git_oid_hexsize(opts->oid_type);
|
||||
|
||||
fc->map.len = src->buflen;
|
||||
fc->map.data = (char *)src->buf;
|
||||
@ -178,7 +178,7 @@ int git_diff_file_content__init_from_src(
|
||||
static int diff_file_content_commit_to_str(
|
||||
git_diff_file_content *fc, bool check_status)
|
||||
{
|
||||
char oid[GIT_OID_SHA1_HEXSIZE+1];
|
||||
char oid[GIT_OID_MAX_HEXSIZE+1];
|
||||
git_str content = GIT_STR_INIT;
|
||||
const char *status = "";
|
||||
|
||||
@ -420,7 +420,7 @@ static int diff_file_content_load_workdir(
|
||||
if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0) {
|
||||
error = git_odb__hash(
|
||||
&fc->file->id, fc->map.data, fc->map.len,
|
||||
GIT_OBJECT_BLOB, GIT_OID_SHA1);
|
||||
GIT_OBJECT_BLOB, diff_opts->oid_type);
|
||||
fc->file->flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ static git_diff_delta *diff_delta__alloc(
|
||||
}
|
||||
delta->status = status;
|
||||
|
||||
git_oid_clear(&delta->old_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&delta->new_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&delta->old_file.id, diff->base.opts.oid_type);
|
||||
git_oid_clear(&delta->new_file.id, diff->base.opts.oid_type);
|
||||
|
||||
return delta;
|
||||
}
|
||||
@ -149,10 +149,13 @@ static int diff_delta__from_one(
|
||||
const git_index_entry *entry = nitem;
|
||||
bool has_old = false;
|
||||
git_diff_delta *delta;
|
||||
git_oid_t oid_type;
|
||||
const char *matched_pathspec;
|
||||
|
||||
GIT_ASSERT_ARG((oitem != NULL) ^ (nitem != NULL));
|
||||
|
||||
oid_type = diff->base.opts.oid_type;
|
||||
|
||||
if (oitem) {
|
||||
entry = oitem;
|
||||
has_old = true;
|
||||
@ -186,20 +189,23 @@ static int diff_delta__from_one(
|
||||
GIT_ASSERT(status != GIT_DELTA_MODIFIED);
|
||||
delta->nfiles = 1;
|
||||
|
||||
git_oid_clear(&delta->old_file.id, diff->base.opts.oid_type);
|
||||
git_oid_clear(&delta->new_file.id, diff->base.opts.oid_type);
|
||||
|
||||
if (has_old) {
|
||||
delta->old_file.mode = entry->mode;
|
||||
delta->old_file.size = entry->file_size;
|
||||
delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
||||
git_oid_cpy(&delta->old_file.id, &entry->id);
|
||||
git_oid_clear(&delta->new_file.id, GIT_OID_SHA1);
|
||||
delta->old_file.id_abbrev = GIT_OID_SHA1_HEXSIZE;
|
||||
git_oid_clear(&delta->new_file.id, oid_type);
|
||||
delta->old_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type);
|
||||
} else /* ADDED, IGNORED, UNTRACKED */ {
|
||||
delta->new_file.mode = entry->mode;
|
||||
delta->new_file.size = entry->file_size;
|
||||
delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
||||
git_oid_clear(&delta->old_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&delta->old_file.id, oid_type);
|
||||
git_oid_cpy(&delta->new_file.id, &entry->id);
|
||||
delta->new_file.id_abbrev = GIT_OID_SHA1_HEXSIZE;
|
||||
delta->new_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type);
|
||||
}
|
||||
|
||||
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
@ -225,6 +231,9 @@ static int diff_delta__from_two(
|
||||
const git_oid *old_id = &old_entry->id;
|
||||
git_diff_delta *delta;
|
||||
const char *canonical_path = old_entry->path;
|
||||
git_oid_t oid_type;
|
||||
|
||||
oid_type = diff->base.opts.oid_type;
|
||||
|
||||
if (status == GIT_DELTA_UNMODIFIED &&
|
||||
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNMODIFIED))
|
||||
@ -254,14 +263,14 @@ static int diff_delta__from_two(
|
||||
delta->old_file.size = old_entry->file_size;
|
||||
delta->old_file.mode = old_mode;
|
||||
git_oid_cpy(&delta->old_file.id, old_id);
|
||||
delta->old_file.id_abbrev = GIT_OID_SHA1_HEXSIZE;
|
||||
delta->old_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type);
|
||||
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID |
|
||||
GIT_DIFF_FLAG_EXISTS;
|
||||
}
|
||||
|
||||
if (!git_index_entry_is_conflict(new_entry)) {
|
||||
git_oid_cpy(&delta->new_file.id, new_id);
|
||||
delta->new_file.id_abbrev = GIT_OID_SHA1_HEXSIZE;
|
||||
delta->new_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type);
|
||||
delta->new_file.size = new_entry->file_size;
|
||||
delta->new_file.mode = new_mode;
|
||||
delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
||||
@ -490,6 +499,14 @@ static int diff_generated_apply_options(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!diff->base.opts.oid_type) {
|
||||
diff->base.opts.oid_type = repo->oid_type;
|
||||
} else if (diff->base.opts.oid_type != repo->oid_type) {
|
||||
git_error_set(GIT_ERROR_INVALID,
|
||||
"specified object ID type does not match repository object ID type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* flag INCLUDE_TYPECHANGE_TREES implies INCLUDE_TYPECHANGE */
|
||||
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE_TREES))
|
||||
diff->base.opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
|
||||
@ -603,7 +620,7 @@ int git_diff__oid_for_file(
|
||||
entry.mode = mode;
|
||||
entry.file_size = (uint32_t)size;
|
||||
entry.path = (char *)path;
|
||||
git_oid_clear(&entry.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&entry.id, diff->opts.oid_type);
|
||||
|
||||
return git_diff__oid_for_entry(out, diff, &entry, mode, NULL);
|
||||
}
|
||||
@ -624,7 +641,7 @@ int git_diff__oid_for_entry(
|
||||
GIT_ASSERT(d->type == GIT_DIFF_TYPE_GENERATED);
|
||||
diff = (git_diff_generated *)d;
|
||||
|
||||
git_oid_clear(out, GIT_OID_SHA1);
|
||||
git_oid_clear(out, diff->base.opts.oid_type);
|
||||
|
||||
if (git_repository_workdir_path(&full_path, diff->base.repo, entry.path) < 0)
|
||||
return -1;
|
||||
@ -660,7 +677,8 @@ int git_diff__oid_for_entry(
|
||||
git_error_clear();
|
||||
}
|
||||
} else if (S_ISLNK(mode)) {
|
||||
error = git_odb__hashlink(out, full_path.ptr, GIT_OID_SHA1);
|
||||
error = git_odb__hashlink(out, full_path.ptr,
|
||||
diff->base.opts.oid_type);
|
||||
diff->base.perf.oid_calculations++;
|
||||
} else if (!git__is_sizet(entry.file_size)) {
|
||||
git_error_set(GIT_ERROR_NOMEMORY, "file size overflow (for 32-bits) on '%s'",
|
||||
@ -676,7 +694,8 @@ int git_diff__oid_for_entry(
|
||||
else {
|
||||
error = git_odb__hashfd_filtered(
|
||||
out, fd, (size_t)entry.file_size,
|
||||
GIT_OBJECT_BLOB, GIT_OID_SHA1, fl);
|
||||
GIT_OBJECT_BLOB, diff->base.opts.oid_type,
|
||||
fl);
|
||||
p_close(fd);
|
||||
diff->base.perf.oid_calculations++;
|
||||
}
|
||||
@ -785,7 +804,7 @@ static int maybe_modified(
|
||||
git_diff_generated *diff,
|
||||
diff_in_progress *info)
|
||||
{
|
||||
git_oid noid = GIT_OID_SHA1_ZERO;
|
||||
git_oid noid;
|
||||
git_delta_t status = GIT_DELTA_MODIFIED;
|
||||
const git_index_entry *oitem = info->oitem;
|
||||
const git_index_entry *nitem = info->nitem;
|
||||
@ -796,6 +815,8 @@ static int maybe_modified(
|
||||
const char *matched_pathspec;
|
||||
int error = 0;
|
||||
|
||||
git_oid_clear(&noid, diff->base.opts.oid_type);
|
||||
|
||||
if (!diff_pathspec_match(&matched_pathspec, diff, oitem))
|
||||
return 0;
|
||||
|
||||
@ -1700,11 +1721,11 @@ int git_diff__commit(
|
||||
*out = NULL;
|
||||
|
||||
if ((parents = git_commit_parentcount(commit)) > 1) {
|
||||
char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char commit_oidstr[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
error = -1;
|
||||
git_error_set(GIT_ERROR_INVALID, "commit %s is a merge commit",
|
||||
git_oid_tostr(commit_oidstr, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit)));
|
||||
git_oid_tostr(commit_oidstr, GIT_OID_MAX_HEXSIZE + 1, git_commit_id(commit)));
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ static void diff_parsed_free(git_diff *d)
|
||||
git__free(diff);
|
||||
}
|
||||
|
||||
static git_diff_parsed *diff_parsed_alloc(void)
|
||||
static git_diff_parsed *diff_parsed_alloc(git_oid_t oid_type)
|
||||
{
|
||||
git_diff_parsed *diff;
|
||||
|
||||
@ -51,6 +51,7 @@ static git_diff_parsed *diff_parsed_alloc(void)
|
||||
}
|
||||
|
||||
diff->base.opts.flags &= ~GIT_DIFF_IGNORE_CASE;
|
||||
diff->base.opts.oid_type = oid_type;
|
||||
|
||||
if (git_pool_init(&diff->base.pool, 1) < 0 ||
|
||||
git_vector_init(&diff->patches, 0, NULL) < 0 ||
|
||||
@ -67,19 +68,34 @@ static git_diff_parsed *diff_parsed_alloc(void)
|
||||
int git_diff_from_buffer(
|
||||
git_diff **out,
|
||||
const char *content,
|
||||
size_t content_len)
|
||||
size_t content_len
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_diff_parse_options *opts
|
||||
#endif
|
||||
)
|
||||
{
|
||||
git_diff_parsed *diff;
|
||||
git_patch *patch;
|
||||
git_patch_parse_ctx *ctx = NULL;
|
||||
git_patch_options patch_opts = GIT_PATCH_OPTIONS_INIT;
|
||||
git_oid_t oid_type;
|
||||
int error = 0;
|
||||
|
||||
*out = NULL;
|
||||
|
||||
diff = diff_parsed_alloc();
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
oid_type = (opts && opts->oid_type) ? opts->oid_type :
|
||||
GIT_OID_DEFAULT;
|
||||
#else
|
||||
oid_type = GIT_OID_DEFAULT;
|
||||
#endif
|
||||
|
||||
patch_opts.oid_type = oid_type;
|
||||
|
||||
diff = diff_parsed_alloc(oid_type);
|
||||
GIT_ERROR_CHECK_ALLOC(diff);
|
||||
|
||||
ctx = git_patch_parse_ctx_init(content, content_len, NULL);
|
||||
ctx = git_patch_parse_ctx_init(content, content_len, &patch_opts);
|
||||
GIT_ERROR_CHECK_ALLOC(ctx);
|
||||
|
||||
while (ctx->parse_ctx.remain_len) {
|
||||
|
@ -29,6 +29,7 @@ typedef struct {
|
||||
const char *new_prefix;
|
||||
uint32_t flags;
|
||||
int id_strlen;
|
||||
git_oid_t oid_type;
|
||||
|
||||
int (*strcomp)(const char *, const char *);
|
||||
} diff_print_info;
|
||||
@ -46,6 +47,8 @@ static int diff_print_info_init__common(
|
||||
pi->payload = payload;
|
||||
pi->buf = out;
|
||||
|
||||
GIT_ASSERT(pi->oid_type);
|
||||
|
||||
if (!pi->id_strlen) {
|
||||
if (!repo)
|
||||
pi->id_strlen = GIT_ABBREV_DEFAULT;
|
||||
@ -53,8 +56,9 @@ static int diff_print_info_init__common(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pi->id_strlen > GIT_OID_SHA1_HEXSIZE)
|
||||
pi->id_strlen = GIT_OID_SHA1_HEXSIZE;
|
||||
if (pi->id_strlen > 0 &&
|
||||
(size_t)pi->id_strlen > git_oid_hexsize(pi->oid_type))
|
||||
pi->id_strlen = (int)git_oid_hexsize(pi->oid_type);
|
||||
|
||||
memset(&pi->line, 0, sizeof(pi->line));
|
||||
pi->line.old_lineno = -1;
|
||||
@ -78,6 +82,7 @@ static int diff_print_info_init_fromdiff(
|
||||
|
||||
if (diff) {
|
||||
pi->flags = diff->opts.flags;
|
||||
pi->oid_type = diff->opts.oid_type;
|
||||
pi->id_strlen = diff->opts.id_abbrev;
|
||||
pi->old_prefix = diff->opts.old_prefix;
|
||||
pi->new_prefix = diff->opts.new_prefix;
|
||||
@ -101,6 +106,7 @@ static int diff_print_info_init_frompatch(
|
||||
memset(pi, 0, sizeof(diff_print_info));
|
||||
|
||||
pi->flags = patch->diff_opts.flags;
|
||||
pi->oid_type = patch->diff_opts.oid_type;
|
||||
pi->id_strlen = patch->diff_opts.id_abbrev;
|
||||
pi->old_prefix = patch->diff_opts.old_prefix;
|
||||
pi->new_prefix = patch->diff_opts.new_prefix;
|
||||
@ -212,7 +218,10 @@ static int diff_print_one_raw(
|
||||
git_str *out = pi->buf;
|
||||
int id_abbrev;
|
||||
char code = git_diff_status_char(delta->status);
|
||||
char start_oid[GIT_OID_SHA1_HEXSIZE+1], end_oid[GIT_OID_SHA1_HEXSIZE+1];
|
||||
char start_oid[GIT_OID_MAX_HEXSIZE + 1],
|
||||
end_oid[GIT_OID_MAX_HEXSIZE + 1];
|
||||
size_t oid_hexsize;
|
||||
bool id_is_abbrev;
|
||||
|
||||
GIT_UNUSED(progress);
|
||||
|
||||
@ -231,12 +240,21 @@ static int diff_print_one_raw(
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
GIT_ASSERT(delta->old_file.id.type == delta->new_file.id.type);
|
||||
oid_hexsize = git_oid_hexsize(delta->old_file.id.type);
|
||||
#else
|
||||
oid_hexsize = GIT_OID_SHA1_HEXSIZE;
|
||||
#endif
|
||||
|
||||
id_is_abbrev = (pi->id_strlen > 0 &&
|
||||
(size_t)pi->id_strlen <= oid_hexsize);
|
||||
|
||||
git_oid_tostr(start_oid, pi->id_strlen + 1, &delta->old_file.id);
|
||||
git_oid_tostr(end_oid, pi->id_strlen + 1, &delta->new_file.id);
|
||||
|
||||
git_str_printf(
|
||||
out, (pi->id_strlen <= GIT_OID_SHA1_HEXSIZE) ?
|
||||
":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c",
|
||||
git_str_printf(out,
|
||||
id_is_abbrev ? ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c",
|
||||
delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code);
|
||||
|
||||
if (delta->similarity > 0)
|
||||
@ -273,7 +291,8 @@ static int diff_print_oid_range(
|
||||
git_str *out, const git_diff_delta *delta, int id_strlen,
|
||||
bool print_index)
|
||||
{
|
||||
char start_oid[GIT_OID_SHA1_HEXSIZE+1], end_oid[GIT_OID_SHA1_HEXSIZE+1];
|
||||
char start_oid[GIT_OID_MAX_HEXSIZE + 1],
|
||||
end_oid[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
if (delta->old_file.mode &&
|
||||
id_strlen > delta->old_file.id_abbrev) {
|
||||
|
@ -364,7 +364,7 @@ static int insert_delete_side_of_split(
|
||||
memset(&deleted->new_file, 0, sizeof(deleted->new_file));
|
||||
deleted->new_file.path = deleted->old_file.path;
|
||||
deleted->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
git_oid_clear(&deleted->new_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&deleted->new_file.id, diff->opts.oid_type);
|
||||
|
||||
return git_vector_insert(onto, deleted);
|
||||
}
|
||||
@ -398,7 +398,7 @@ static int apply_splits_and_deletes(
|
||||
memset(&delta->old_file, 0, sizeof(delta->old_file));
|
||||
delta->old_file.path = delta->new_file.path;
|
||||
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
git_oid_clear(&delta->old_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&delta->old_file.id, diff->opts.oid_type);
|
||||
}
|
||||
|
||||
/* clean up delta before inserting into new list */
|
||||
@ -997,7 +997,7 @@ find_best_matches:
|
||||
memset(&src->new_file, 0, sizeof(src->new_file));
|
||||
src->new_file.path = src->old_file.path;
|
||||
src->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
git_oid_clear(&src->new_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&src->new_file.id, diff->opts.oid_type);
|
||||
|
||||
num_updates++;
|
||||
|
||||
@ -1023,7 +1023,7 @@ find_best_matches:
|
||||
memset(&src->old_file, 0, sizeof(src->old_file));
|
||||
src->old_file.path = src->new_file.path;
|
||||
src->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
||||
git_oid_clear(&src->old_file.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&src->old_file.id, diff->opts.oid_type);
|
||||
|
||||
src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
|
||||
num_rewrites--;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "diff.h"
|
||||
#include "xdiff/xdiff.h"
|
||||
#include "xdiff.h"
|
||||
#include "patch_generate.h"
|
||||
|
||||
/* xdiff cannot cope with large files. these files should not be passed to
|
||||
|
@ -130,11 +130,12 @@ static int append_header(
|
||||
const git_signature *author,
|
||||
git_email_create_options *opts)
|
||||
{
|
||||
char id[GIT_OID_SHA1_HEXSIZE];
|
||||
char id[GIT_OID_MAX_HEXSIZE + 1];
|
||||
int error;
|
||||
|
||||
if ((error = git_oid_fmt(id, commit_id)) < 0 ||
|
||||
(error = git_str_printf(out, "From %.*s %s\n", GIT_OID_SHA1_HEXSIZE, id, EMAIL_TIMESTAMP)) < 0 ||
|
||||
git_oid_tostr(id, GIT_OID_MAX_HEXSIZE + 1, commit_id);
|
||||
|
||||
if ((error = git_str_printf(out, "From %s %s\n", id, EMAIL_TIMESTAMP)) < 0 ||
|
||||
(error = git_str_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 ||
|
||||
(error = append_date(out, &author->when)) < 0 ||
|
||||
(error = append_subject(out, patch_idx, patch_count, summary, opts)) < 0)
|
||||
|
@ -16,32 +16,51 @@
|
||||
* New error handling
|
||||
********************************************/
|
||||
|
||||
static git_error g_git_oom_error = {
|
||||
static git_error oom_error = {
|
||||
"Out of memory",
|
||||
GIT_ERROR_NOMEMORY
|
||||
};
|
||||
|
||||
static git_error g_git_uninitialized_error = {
|
||||
static git_error uninitialized_error = {
|
||||
"libgit2 has not been initialized; you must call git_libgit2_init",
|
||||
GIT_ERROR_INVALID
|
||||
};
|
||||
|
||||
static git_error tlsdata_error = {
|
||||
"thread-local data initialization failure",
|
||||
GIT_ERROR
|
||||
};
|
||||
|
||||
static void set_error_from_buffer(int error_class)
|
||||
{
|
||||
git_error *error = &GIT_THREADSTATE->error_t;
|
||||
git_str *buf = &GIT_THREADSTATE->error_buf;
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
git_error *error;
|
||||
git_str *buf;
|
||||
|
||||
if (!threadstate)
|
||||
return;
|
||||
|
||||
error = &threadstate->error_t;
|
||||
buf = &threadstate->error_buf;
|
||||
|
||||
error->message = buf->ptr;
|
||||
error->klass = error_class;
|
||||
|
||||
GIT_THREADSTATE->last_error = error;
|
||||
threadstate->last_error = error;
|
||||
}
|
||||
|
||||
static void set_error(int error_class, char *string)
|
||||
{
|
||||
git_str *buf = &GIT_THREADSTATE->error_buf;
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
git_str *buf;
|
||||
|
||||
if (!threadstate)
|
||||
return;
|
||||
|
||||
buf = &threadstate->error_buf;
|
||||
|
||||
git_str_clear(buf);
|
||||
|
||||
if (string) {
|
||||
git_str_puts(buf, string);
|
||||
git__free(string);
|
||||
@ -52,7 +71,12 @@ static void set_error(int error_class, char *string)
|
||||
|
||||
void git_error_set_oom(void)
|
||||
{
|
||||
GIT_THREADSTATE->last_error = &g_git_oom_error;
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
|
||||
if (!threadstate)
|
||||
return;
|
||||
|
||||
threadstate->last_error = &oom_error;
|
||||
}
|
||||
|
||||
void git_error_set(int error_class, const char *fmt, ...)
|
||||
@ -69,10 +93,18 @@ void git_error_vset(int error_class, const char *fmt, va_list ap)
|
||||
#ifdef GIT_WIN32
|
||||
DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0;
|
||||
#endif
|
||||
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
int error_code = (error_class == GIT_ERROR_OS) ? errno : 0;
|
||||
git_str *buf = &GIT_THREADSTATE->error_buf;
|
||||
git_str *buf;
|
||||
|
||||
if (!threadstate)
|
||||
return;
|
||||
|
||||
buf = &threadstate->error_buf;
|
||||
|
||||
git_str_clear(buf);
|
||||
|
||||
if (fmt) {
|
||||
git_str_vprintf(buf, fmt, ap);
|
||||
if (error_class == GIT_ERROR_OS)
|
||||
@ -81,7 +113,7 @@ void git_error_vset(int error_class, const char *fmt, va_list ap)
|
||||
|
||||
if (error_class == GIT_ERROR_OS) {
|
||||
#ifdef GIT_WIN32
|
||||
char * win32_error = git_win32_get_error_message(win32_error_code);
|
||||
char *win32_error = git_win32_get_error_message(win32_error_code);
|
||||
if (win32_error) {
|
||||
git_str_puts(buf, win32_error);
|
||||
git__free(win32_error);
|
||||
@ -103,10 +135,16 @@ void git_error_vset(int error_class, const char *fmt, va_list ap)
|
||||
|
||||
int git_error_set_str(int error_class, const char *string)
|
||||
{
|
||||
git_str *buf = &GIT_THREADSTATE->error_buf;
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
git_str *buf;
|
||||
|
||||
GIT_ASSERT_ARG(string);
|
||||
|
||||
if (!threadstate)
|
||||
return -1;
|
||||
|
||||
buf = &threadstate->error_buf;
|
||||
|
||||
git_str_clear(buf);
|
||||
git_str_puts(buf, string);
|
||||
|
||||
@ -119,9 +157,14 @@ int git_error_set_str(int error_class, const char *string)
|
||||
|
||||
void git_error_clear(void)
|
||||
{
|
||||
if (GIT_THREADSTATE->last_error != NULL) {
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
|
||||
if (!threadstate)
|
||||
return;
|
||||
|
||||
if (threadstate->last_error != NULL) {
|
||||
set_error(0, NULL);
|
||||
GIT_THREADSTATE->last_error = NULL;
|
||||
threadstate->last_error = NULL;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
@ -132,17 +175,29 @@ void git_error_clear(void)
|
||||
|
||||
const git_error *git_error_last(void)
|
||||
{
|
||||
git_threadstate *threadstate;
|
||||
|
||||
/* If the library is not initialized, return a static error. */
|
||||
if (!git_libgit2_init_count())
|
||||
return &g_git_uninitialized_error;
|
||||
return &uninitialized_error;
|
||||
|
||||
return GIT_THREADSTATE->last_error;
|
||||
if ((threadstate = git_threadstate_get()) == NULL)
|
||||
return &tlsdata_error;
|
||||
|
||||
return threadstate->last_error;
|
||||
}
|
||||
|
||||
int git_error_state_capture(git_error_state *state, int error_code)
|
||||
{
|
||||
git_error *error = GIT_THREADSTATE->last_error;
|
||||
git_str *error_buf = &GIT_THREADSTATE->error_buf;
|
||||
git_threadstate *threadstate = git_threadstate_get();
|
||||
git_error *error;
|
||||
git_str *error_buf;
|
||||
|
||||
if (!threadstate)
|
||||
return -1;
|
||||
|
||||
error = threadstate->last_error;
|
||||
error_buf = &threadstate->error_buf;
|
||||
|
||||
memset(state, 0, sizeof(git_error_state));
|
||||
|
||||
@ -150,13 +205,13 @@ int git_error_state_capture(git_error_state *state, int error_code)
|
||||
return 0;
|
||||
|
||||
state->error_code = error_code;
|
||||
state->oom = (error == &g_git_oom_error);
|
||||
state->oom = (error == &oom_error);
|
||||
|
||||
if (error) {
|
||||
state->error_msg.klass = error->klass;
|
||||
|
||||
if (state->oom)
|
||||
state->error_msg.message = g_git_oom_error.message;
|
||||
state->error_msg.message = oom_error.message;
|
||||
else
|
||||
state->error_msg.message = git_str_detach(error_buf);
|
||||
}
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include "remote.h"
|
||||
#include "refspec.h"
|
||||
#include "pack.h"
|
||||
#include "netops.h"
|
||||
#include "repository.h"
|
||||
#include "refs.h"
|
||||
#include "transports/smart.h"
|
||||
|
||||
static int maybe_want(git_remote *remote, git_remote_head *head, git_refspec *tagspec, git_remote_autotag_option_t tagopt)
|
||||
{
|
||||
@ -59,8 +59,10 @@ static int mark_local(git_remote *remote)
|
||||
return -1;
|
||||
|
||||
git_vector_foreach(&remote->refs, i, head) {
|
||||
/* If we have the object, mark it so we don't ask for it */
|
||||
if (git_odb_exists(odb, &head->oid))
|
||||
/* If we have the object, mark it so we don't ask for it.
|
||||
However if we are unshallowing, we need to ask for it
|
||||
even though the head exists locally. */
|
||||
if (remote->nego.depth != INT_MAX && git_odb_exists(odb, &head->oid))
|
||||
head->local = 1;
|
||||
else
|
||||
remote->need_pack = 1;
|
||||
@ -76,7 +78,7 @@ static int maybe_want_oid(git_remote *remote, git_refspec *spec)
|
||||
oid_head = git__calloc(1, sizeof(git_remote_head));
|
||||
GIT_ERROR_CHECK_ALLOC(oid_head);
|
||||
|
||||
git_oid__fromstr(&oid_head->oid, spec->src, GIT_OID_SHA1);
|
||||
git_oid__fromstr(&oid_head->oid, spec->src, remote->repo->oid_type);
|
||||
|
||||
if (spec->dst) {
|
||||
oid_head->name = git__strdup(spec->dst);
|
||||
@ -137,7 +139,7 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts)
|
||||
|
||||
/* Handle explicitly specified OID specs */
|
||||
git_vector_foreach(&remote->active_refspecs, i, spec) {
|
||||
if (!git_oid__is_hexstr(spec->src, GIT_OID_SHA1))
|
||||
if (!git_oid__is_hexstr(spec->src, remote->repo->oid_type))
|
||||
continue;
|
||||
|
||||
if (!(remote_caps & oid_mask)) {
|
||||
@ -166,9 +168,15 @@ cleanup:
|
||||
int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
|
||||
{
|
||||
git_transport *t = remote->transport;
|
||||
int error;
|
||||
|
||||
remote->need_pack = 0;
|
||||
|
||||
if (opts) {
|
||||
GIT_ASSERT_ARG(opts->depth >= 0);
|
||||
remote->nego.depth = opts->depth;
|
||||
}
|
||||
|
||||
if (filter_wants(remote, opts) < 0)
|
||||
return -1;
|
||||
|
||||
@ -180,20 +188,40 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
|
||||
* Now we have everything set up so we can start tell the
|
||||
* server what we want and what we have.
|
||||
*/
|
||||
return t->negotiate_fetch(t,
|
||||
remote->nego.refs = (const git_remote_head * const *)remote->refs.contents;
|
||||
remote->nego.refs_len = remote->refs.length;
|
||||
|
||||
if (git_repository__shallow_roots(&remote->nego.shallow_roots,
|
||||
&remote->nego.shallow_roots_len,
|
||||
remote->repo) < 0)
|
||||
return -1;
|
||||
|
||||
error = t->negotiate_fetch(t,
|
||||
remote->repo,
|
||||
(const git_remote_head * const *)remote->refs.contents,
|
||||
remote->refs.length);
|
||||
&remote->nego);
|
||||
|
||||
git__free(remote->nego.shallow_roots);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_fetch_download_pack(git_remote *remote)
|
||||
{
|
||||
git_oidarray shallow_roots = { NULL };
|
||||
git_transport *t = remote->transport;
|
||||
int error;
|
||||
|
||||
if (!remote->need_pack)
|
||||
return 0;
|
||||
|
||||
return t->download_pack(t, remote->repo, &remote->stats);
|
||||
if ((error = t->download_pack(t, remote->repo, &remote->stats)) != 0 ||
|
||||
(error = t->shallow_roots(&shallow_roots, t)) != 0)
|
||||
return error;
|
||||
|
||||
error = git_repository__shallow_roots_write(remote->repo, &shallow_roots);
|
||||
|
||||
git_oidarray_dispose(&shallow_roots);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_fetch_options_init(git_fetch_options *opts, unsigned int version)
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
#include "git2/remote.h"
|
||||
|
||||
#include "netops.h"
|
||||
|
||||
int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts);
|
||||
|
||||
int git_fetch_download_pack(git_remote *remote);
|
||||
|
@ -105,15 +105,14 @@ static int fetchhead_ref_write(
|
||||
git_filebuf *file,
|
||||
git_fetchhead_ref *fetchhead_ref)
|
||||
{
|
||||
char oid[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char oid[GIT_OID_MAX_HEXSIZE + 1];
|
||||
const char *type, *name;
|
||||
int head = 0;
|
||||
|
||||
GIT_ASSERT_ARG(file);
|
||||
GIT_ASSERT_ARG(fetchhead_ref);
|
||||
|
||||
git_oid_fmt(oid, &fetchhead_ref->oid);
|
||||
oid[GIT_OID_SHA1_HEXSIZE] = '\0';
|
||||
git_oid_tostr(oid, GIT_OID_MAX_HEXSIZE + 1, &fetchhead_ref->oid);
|
||||
|
||||
if (git__prefixcmp(fetchhead_ref->ref_name, GIT_REFS_HEADS_DIR) == 0) {
|
||||
type = "branch ";
|
||||
@ -174,7 +173,8 @@ static int fetchhead_ref_parse(
|
||||
git_str *ref_name,
|
||||
const char **remote_url,
|
||||
char *line,
|
||||
size_t line_num)
|
||||
size_t line_num,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
char *oid_str, *is_merge_str, *desc, *name = NULL;
|
||||
const char *type = NULL;
|
||||
@ -196,13 +196,13 @@ static int fetchhead_ref_parse(
|
||||
*is_merge = 1;
|
||||
}
|
||||
|
||||
if (strlen(oid_str) != GIT_OID_SHA1_HEXSIZE) {
|
||||
if (strlen(oid_str) != git_oid_hexsize(oid_type)) {
|
||||
git_error_set(GIT_ERROR_FETCHHEAD,
|
||||
"invalid object ID in FETCH_HEAD line %"PRIuZ, line_num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_oid__fromstr(oid, oid_str, GIT_OID_SHA1) < 0) {
|
||||
if (git_oid__fromstr(oid, oid_str, oid_type) < 0) {
|
||||
const git_error *oid_err = git_error_last();
|
||||
const char *err_msg = oid_err ? oid_err->message : "invalid object ID";
|
||||
|
||||
@ -269,7 +269,8 @@ static int fetchhead_ref_parse(
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_repository_fetchhead_foreach(git_repository *repo,
|
||||
int git_repository_fetchhead_foreach(
|
||||
git_repository *repo,
|
||||
git_repository_fetchhead_foreach_cb cb,
|
||||
void *payload)
|
||||
{
|
||||
@ -296,8 +297,9 @@ int git_repository_fetchhead_foreach(git_repository *repo,
|
||||
while ((line = git__strsep(&buffer, "\n")) != NULL) {
|
||||
++line_num;
|
||||
|
||||
if ((error = fetchhead_ref_parse(
|
||||
&oid, &is_merge, &name, &remote_url, line, line_num)) < 0)
|
||||
if ((error = fetchhead_ref_parse(&oid, &is_merge, &name,
|
||||
&remote_url, line, line_num,
|
||||
repo->oid_type)) < 0)
|
||||
goto done;
|
||||
|
||||
if (git_str_len(&name) > 0)
|
||||
|
272
src/libgit2/grafts.c
Normal file
272
src/libgit2/grafts.c
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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 "grafts.h"
|
||||
|
||||
#include "futils.h"
|
||||
#include "oid.h"
|
||||
#include "oidarray.h"
|
||||
#include "parse.h"
|
||||
|
||||
struct git_grafts {
|
||||
/* Map of `git_commit_graft`s */
|
||||
git_oidmap *commits;
|
||||
|
||||
/* Type of object IDs */
|
||||
git_oid_t oid_type;
|
||||
|
||||
/* File backing the graft. NULL if it's an in-memory graft */
|
||||
char *path;
|
||||
unsigned char path_checksum[GIT_HASH_SHA256_SIZE];
|
||||
};
|
||||
|
||||
int git_grafts_new(git_grafts **out, git_oid_t oid_type)
|
||||
{
|
||||
git_grafts *grafts;
|
||||
|
||||
GIT_ASSERT_ARG(out && oid_type);
|
||||
|
||||
grafts = git__calloc(1, sizeof(*grafts));
|
||||
GIT_ERROR_CHECK_ALLOC(grafts);
|
||||
|
||||
if ((git_oidmap_new(&grafts->commits)) < 0) {
|
||||
git__free(grafts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
grafts->oid_type = oid_type;
|
||||
|
||||
*out = grafts;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_grafts_open(
|
||||
git_grafts **out,
|
||||
const char *path,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
git_grafts *grafts = NULL;
|
||||
int error;
|
||||
|
||||
GIT_ASSERT_ARG(out && path && oid_type);
|
||||
|
||||
if ((error = git_grafts_new(&grafts, oid_type)) < 0)
|
||||
goto error;
|
||||
|
||||
grafts->path = git__strdup(path);
|
||||
GIT_ERROR_CHECK_ALLOC(grafts->path);
|
||||
|
||||
if ((error = git_grafts_refresh(grafts)) < 0)
|
||||
goto error;
|
||||
|
||||
*out = grafts;
|
||||
|
||||
error:
|
||||
if (error < 0)
|
||||
git_grafts_free(grafts);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_grafts_open_or_refresh(
|
||||
git_grafts **out,
|
||||
const char *path,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
GIT_ASSERT_ARG(out && path && oid_type);
|
||||
|
||||
return *out ? git_grafts_refresh(*out) : git_grafts_open(out, path, oid_type);
|
||||
}
|
||||
|
||||
void git_grafts_free(git_grafts *grafts)
|
||||
{
|
||||
if (!grafts)
|
||||
return;
|
||||
git__free(grafts->path);
|
||||
git_grafts_clear(grafts);
|
||||
git_oidmap_free(grafts->commits);
|
||||
git__free(grafts);
|
||||
}
|
||||
|
||||
void git_grafts_clear(git_grafts *grafts)
|
||||
{
|
||||
git_commit_graft *graft;
|
||||
|
||||
if (!grafts)
|
||||
return;
|
||||
|
||||
git_oidmap_foreach_value(grafts->commits, graft, {
|
||||
git__free(graft->parents.ptr);
|
||||
git__free(graft);
|
||||
});
|
||||
|
||||
git_oidmap_clear(grafts->commits);
|
||||
}
|
||||
|
||||
int git_grafts_refresh(git_grafts *grafts)
|
||||
{
|
||||
git_str contents = GIT_STR_INIT;
|
||||
int error, updated = 0;
|
||||
|
||||
GIT_ASSERT_ARG(grafts);
|
||||
|
||||
if (!grafts->path)
|
||||
return 0;
|
||||
|
||||
if ((error = git_futils_readbuffer_updated(&contents, grafts->path,
|
||||
grafts->path_checksum, &updated)) < 0) {
|
||||
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
git_grafts_clear(grafts);
|
||||
error = 0;
|
||||
}
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((error = git_grafts_parse(grafts, contents.ptr, contents.size)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
git_str_dispose(&contents);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len)
|
||||
{
|
||||
git_array_oid_t parents = GIT_ARRAY_INIT;
|
||||
git_parse_ctx parser;
|
||||
int error;
|
||||
|
||||
git_grafts_clear(grafts);
|
||||
|
||||
if ((error = git_parse_ctx_init(&parser, buf, len)) < 0)
|
||||
goto error;
|
||||
|
||||
for (; parser.remain_len; git_parse_advance_line(&parser)) {
|
||||
git_oid graft_oid;
|
||||
|
||||
if ((error = git_parse_advance_oid(&graft_oid, &parser, grafts->oid_type)) < 0) {
|
||||
git_error_set(GIT_ERROR_GRAFTS, "invalid graft OID at line %" PRIuZ, parser.line_num);
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (parser.line_len && git_parse_advance_expected(&parser, "\n", 1) != 0) {
|
||||
git_oid *id = git_array_alloc(parents);
|
||||
GIT_ERROR_CHECK_ALLOC(id);
|
||||
|
||||
if ((error = git_parse_advance_expected(&parser, " ", 1)) < 0 ||
|
||||
(error = git_parse_advance_oid(id, &parser, grafts->oid_type)) < 0) {
|
||||
git_error_set(GIT_ERROR_GRAFTS, "invalid parent OID at line %" PRIuZ, parser.line_num);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if ((error = git_grafts_add(grafts, &graft_oid, parents)) < 0)
|
||||
goto error;
|
||||
|
||||
git_array_clear(parents);
|
||||
}
|
||||
|
||||
error:
|
||||
git_array_clear(parents);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents)
|
||||
{
|
||||
git_commit_graft *graft;
|
||||
git_oid *parent_oid;
|
||||
int error;
|
||||
size_t i;
|
||||
|
||||
GIT_ASSERT_ARG(grafts && oid);
|
||||
|
||||
graft = git__calloc(1, sizeof(*graft));
|
||||
GIT_ERROR_CHECK_ALLOC(graft);
|
||||
|
||||
git_array_init_to_size(graft->parents, git_array_size(parents));
|
||||
git_array_foreach(parents, i, parent_oid) {
|
||||
git_oid *id = git_array_alloc(graft->parents);
|
||||
GIT_ERROR_CHECK_ALLOC(id);
|
||||
|
||||
git_oid_cpy(id, parent_oid);
|
||||
}
|
||||
git_oid_cpy(&graft->oid, oid);
|
||||
|
||||
if ((error = git_grafts_remove(grafts, &graft->oid)) < 0 && error != GIT_ENOTFOUND)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_oidmap_set(grafts->commits, &graft->oid, graft)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
git_array_clear(graft->parents);
|
||||
git__free(graft);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_grafts_remove(git_grafts *grafts, const git_oid *oid)
|
||||
{
|
||||
git_commit_graft *graft;
|
||||
int error;
|
||||
|
||||
GIT_ASSERT_ARG(grafts && oid);
|
||||
|
||||
if ((graft = git_oidmap_get(grafts->commits, oid)) == NULL)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if ((error = git_oidmap_delete(grafts->commits, oid)) < 0)
|
||||
return error;
|
||||
|
||||
git__free(graft->parents.ptr);
|
||||
git__free(graft);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid)
|
||||
{
|
||||
GIT_ASSERT_ARG(out && grafts && oid);
|
||||
if ((*out = git_oidmap_get(grafts->commits, oid)) == NULL)
|
||||
return GIT_ENOTFOUND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_grafts_oids(git_oid **out, size_t *out_len, git_grafts *grafts)
|
||||
{
|
||||
git_array_oid_t array = GIT_ARRAY_INIT;
|
||||
const git_oid *oid;
|
||||
size_t existing, i = 0;
|
||||
|
||||
GIT_ASSERT_ARG(out && grafts);
|
||||
|
||||
if ((existing = git_oidmap_size(grafts->commits)) > 0)
|
||||
git_array_init_to_size(array, existing);
|
||||
|
||||
while (git_oidmap_iterate(NULL, grafts->commits, &i, &oid) == 0) {
|
||||
git_oid *cpy = git_array_alloc(array);
|
||||
GIT_ERROR_CHECK_ALLOC(cpy);
|
||||
git_oid_cpy(cpy, oid);
|
||||
}
|
||||
|
||||
*out = array.ptr;
|
||||
*out_len = array.size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t git_grafts_size(git_grafts *grafts)
|
||||
{
|
||||
return git_oidmap_size(grafts->commits);
|
||||
}
|
36
src/libgit2/grafts.h
Normal file
36
src/libgit2/grafts.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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_graft_h__
|
||||
#define INCLUDE_graft_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "oidarray.h"
|
||||
#include "oidmap.h"
|
||||
|
||||
/** graft commit */
|
||||
typedef struct {
|
||||
git_oid oid;
|
||||
git_array_oid_t parents;
|
||||
} git_commit_graft;
|
||||
|
||||
typedef struct git_grafts git_grafts;
|
||||
|
||||
int git_grafts_new(git_grafts **out, git_oid_t oid_type);
|
||||
int git_grafts_open(git_grafts **out, const char *path, git_oid_t oid_type);
|
||||
int git_grafts_open_or_refresh(git_grafts **out, const char *path, git_oid_t oid_type);
|
||||
void git_grafts_free(git_grafts *grafts);
|
||||
void git_grafts_clear(git_grafts *grafts);
|
||||
|
||||
int git_grafts_refresh(git_grafts *grafts);
|
||||
int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len);
|
||||
int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents);
|
||||
int git_grafts_remove(git_grafts *grafts, const git_oid *oid);
|
||||
int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid);
|
||||
int git_grafts_oids(git_oid **out, size_t *out_len, git_grafts *grafts);
|
||||
size_t git_grafts_size(git_grafts *grafts);
|
||||
|
||||
#endif
|
@ -42,7 +42,7 @@ static int ident_find_id(
|
||||
static int ident_insert_id(
|
||||
git_str *to, const git_str *from, const git_filter_source *src)
|
||||
{
|
||||
char oid[GIT_OID_SHA1_HEXSIZE+1];
|
||||
char oid[GIT_OID_MAX_HEXSIZE + 1];
|
||||
const char *id_start, *id_end, *from_end = from->ptr + from->size;
|
||||
size_t need_size;
|
||||
|
||||
@ -57,7 +57,7 @@ static int ident_insert_id(
|
||||
return GIT_PASSTHROUGH;
|
||||
|
||||
need_size = (size_t)(id_start - from->ptr) +
|
||||
5 /* "$Id: " */ + GIT_OID_SHA1_HEXSIZE + 2 /* " $" */ +
|
||||
5 /* "$Id: " */ + GIT_OID_MAX_HEXSIZE + 2 /* " $" */ +
|
||||
(size_t)(from_end - id_end);
|
||||
|
||||
if (git_str_grow(to, need_size) < 0)
|
||||
@ -65,7 +65,7 @@ static int ident_insert_id(
|
||||
|
||||
git_str_set(to, from->ptr, (size_t)(id_start - from->ptr));
|
||||
git_str_put(to, "$Id: ", 5);
|
||||
git_str_put(to, oid, GIT_OID_SHA1_HEXSIZE);
|
||||
git_str_puts(to, oid);
|
||||
git_str_put(to, " $", 2);
|
||||
git_str_put(to, id_end, (size_t)(from_end - id_end));
|
||||
|
||||
|
@ -32,8 +32,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr
|
||||
unsigned int flags,
|
||||
git_index_matched_path_cb cb, void *payload);
|
||||
|
||||
#define minimal_entry_size (offsetof(struct entry_short, path))
|
||||
|
||||
static const size_t INDEX_HEADER_SIZE = 12;
|
||||
|
||||
static const unsigned int INDEX_VERSION_NUMBER_DEFAULT = 2;
|
||||
@ -65,7 +63,7 @@ struct entry_time {
|
||||
uint32_t nanoseconds;
|
||||
};
|
||||
|
||||
struct entry_short {
|
||||
struct entry_common {
|
||||
struct entry_time ctime;
|
||||
struct entry_time mtime;
|
||||
uint32_t dev;
|
||||
@ -74,25 +72,35 @@ struct entry_short {
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
uint32_t file_size;
|
||||
unsigned char oid[GIT_OID_SHA1_SIZE];
|
||||
uint16_t flags;
|
||||
char path[1]; /* arbitrary length */
|
||||
};
|
||||
|
||||
struct entry_long {
|
||||
struct entry_time ctime;
|
||||
struct entry_time mtime;
|
||||
uint32_t dev;
|
||||
uint32_t ino;
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
uint32_t file_size;
|
||||
unsigned char oid[GIT_OID_SHA1_SIZE];
|
||||
uint16_t flags;
|
||||
uint16_t flags_extended;
|
||||
char path[1]; /* arbitrary length */
|
||||
};
|
||||
#define entry_short(oid_size) \
|
||||
struct { \
|
||||
struct entry_common common; \
|
||||
unsigned char oid[oid_size]; \
|
||||
uint16_t flags; \
|
||||
char path[1]; /* arbitrary length */ \
|
||||
}
|
||||
|
||||
#define entry_long(oid_size) \
|
||||
struct { \
|
||||
struct entry_common common; \
|
||||
unsigned char oid[oid_size]; \
|
||||
uint16_t flags; \
|
||||
uint16_t flags_extended; \
|
||||
char path[1]; /* arbitrary length */ \
|
||||
}
|
||||
|
||||
typedef entry_short(GIT_OID_SHA1_SIZE) index_entry_short_sha1;
|
||||
typedef entry_long(GIT_OID_SHA1_SIZE) index_entry_long_sha1;
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
typedef entry_short(GIT_OID_SHA256_SIZE) index_entry_short_sha256;
|
||||
typedef entry_long(GIT_OID_SHA256_SIZE) index_entry_long_sha256;
|
||||
#endif
|
||||
|
||||
#undef entry_short
|
||||
#undef entry_long
|
||||
|
||||
struct entry_srch_key {
|
||||
const char *path;
|
||||
@ -115,12 +123,12 @@ struct reuc_entry_internal {
|
||||
bool git_index__enforce_unsaved_safety = false;
|
||||
|
||||
/* local declarations */
|
||||
static int read_extension(size_t *read_len, git_index *index, const char *buffer, size_t buffer_size);
|
||||
static int read_extension(size_t *read_len, git_index *index, size_t checksum_size, const char *buffer, size_t buffer_size);
|
||||
static int read_header(struct index_header *dest, const void *buffer);
|
||||
|
||||
static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
|
||||
static bool is_index_extended(git_index *index);
|
||||
static int write_index(unsigned char checksum[GIT_HASH_SHA1_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file);
|
||||
static int write_index(unsigned char checksum[GIT_HASH_MAX_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file);
|
||||
|
||||
static void index_entry_free(git_index_entry *entry);
|
||||
static void index_entry_reuc_free(git_index_reuc_entry *reuc);
|
||||
@ -401,7 +409,10 @@ void git_index__set_ignore_case(git_index *index, bool ignore_case)
|
||||
git_vector_sort(&index->reuc);
|
||||
}
|
||||
|
||||
int git_index_open(git_index **index_out, const char *index_path)
|
||||
int git_index__open(
|
||||
git_index **index_out,
|
||||
const char *index_path,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
git_index *index;
|
||||
int error = -1;
|
||||
@ -411,6 +422,8 @@ int git_index_open(git_index **index_out, const char *index_path)
|
||||
index = git__calloc(1, sizeof(git_index));
|
||||
GIT_ERROR_CHECK_ALLOC(index);
|
||||
|
||||
index->oid_type = oid_type;
|
||||
|
||||
if (git_pool_init(&index->tree_pool, 1) < 0)
|
||||
goto fail;
|
||||
|
||||
@ -451,10 +464,34 @@ fail:
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
int git_index_open(git_index **index_out, const char *index_path, git_oid_t oid_type)
|
||||
{
|
||||
return git_index__open(index_out, index_path, oid_type);
|
||||
}
|
||||
#else
|
||||
int git_index_open(git_index **index_out, const char *index_path)
|
||||
{
|
||||
return git_index__open(index_out, index_path, GIT_OID_SHA1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int git_index__new(git_index **out, git_oid_t oid_type)
|
||||
{
|
||||
return git_index__open(out, NULL, oid_type);
|
||||
}
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
int git_index_new(git_index **out, git_oid_t oid_type)
|
||||
{
|
||||
return git_index__new(out, oid_type);
|
||||
}
|
||||
#else
|
||||
int git_index_new(git_index **out)
|
||||
{
|
||||
return git_index_open(out, NULL);
|
||||
return git_index__new(out, GIT_OID_SHA1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void index_free(git_index *index)
|
||||
{
|
||||
@ -620,8 +657,8 @@ static int compare_checksum(git_index *index)
|
||||
{
|
||||
int fd;
|
||||
ssize_t bytes_read;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
size_t checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
size_t checksum_size = git_oid_size(index->oid_type);
|
||||
|
||||
if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0)
|
||||
return fd;
|
||||
@ -2306,6 +2343,7 @@ static int index_error_invalid(const char *message)
|
||||
static int read_reuc(git_index *index, const char *buffer, size_t size)
|
||||
{
|
||||
const char *endptr;
|
||||
size_t oid_size = git_oid_size(index->oid_type);
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
@ -2354,16 +2392,16 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!lost->mode[i])
|
||||
continue;
|
||||
if (size < GIT_OID_SHA1_SIZE) {
|
||||
if (size < oid_size) {
|
||||
index_entry_reuc_free(lost);
|
||||
return index_error_invalid("reading reuc entry oid");
|
||||
}
|
||||
|
||||
if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, GIT_OID_SHA1) < 0)
|
||||
if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, index->oid_type) < 0)
|
||||
return -1;
|
||||
|
||||
size -= GIT_OID_SHA1_SIZE;
|
||||
buffer += GIT_OID_SHA1_SIZE;
|
||||
size -= oid_size;
|
||||
buffer += oid_size;
|
||||
}
|
||||
|
||||
/* entry was read successfully - insert into reuc vector */
|
||||
@ -2433,73 +2471,157 @@ out_err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t index_entry_size(size_t path_len, size_t varint_len, uint32_t flags)
|
||||
GIT_INLINE(size_t) index_entry_path_offset(
|
||||
git_oid_t oid_type,
|
||||
uint32_t flags)
|
||||
{
|
||||
if (oid_type == GIT_OID_SHA1)
|
||||
return (flags & GIT_INDEX_ENTRY_EXTENDED) ?
|
||||
offsetof(index_entry_long_sha1, path) :
|
||||
offsetof(index_entry_short_sha1, path);
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
else if (oid_type == GIT_OID_SHA256)
|
||||
return (flags & GIT_INDEX_ENTRY_EXTENDED) ?
|
||||
offsetof(index_entry_long_sha256, path) :
|
||||
offsetof(index_entry_short_sha256, path);
|
||||
#endif
|
||||
|
||||
git_error_set(GIT_ERROR_INTERNAL, "invalid oid type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GIT_INLINE(size_t) index_entry_flags_offset(git_oid_t oid_type)
|
||||
{
|
||||
if (oid_type == GIT_OID_SHA1)
|
||||
return offsetof(index_entry_long_sha1, flags_extended);
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
else if (oid_type == GIT_OID_SHA256)
|
||||
return offsetof(index_entry_long_sha256, flags_extended);
|
||||
#endif
|
||||
|
||||
git_error_set(GIT_ERROR_INTERNAL, "invalid oid type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t index_entry_size(
|
||||
size_t path_len,
|
||||
size_t varint_len,
|
||||
git_oid_t oid_type,
|
||||
uint32_t flags)
|
||||
{
|
||||
size_t offset, size;
|
||||
|
||||
if (!(offset = index_entry_path_offset(oid_type, flags)))
|
||||
return 0;
|
||||
|
||||
if (varint_len) {
|
||||
if (flags & GIT_INDEX_ENTRY_EXTENDED)
|
||||
return offsetof(struct entry_long, path) + path_len + 1 + varint_len;
|
||||
else
|
||||
return offsetof(struct entry_short, path) + path_len + 1 + varint_len;
|
||||
if (GIT_ADD_SIZET_OVERFLOW(&size, offset, path_len) ||
|
||||
GIT_ADD_SIZET_OVERFLOW(&size, size, 1) ||
|
||||
GIT_ADD_SIZET_OVERFLOW(&size, size, varint_len))
|
||||
return 0;
|
||||
} else {
|
||||
#define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
|
||||
if (flags & GIT_INDEX_ENTRY_EXTENDED)
|
||||
return entry_size(struct entry_long, path_len);
|
||||
else
|
||||
return entry_size(struct entry_short, path_len);
|
||||
#undef entry_size
|
||||
if (GIT_ADD_SIZET_OVERFLOW(&size, offset, path_len) ||
|
||||
GIT_ADD_SIZET_OVERFLOW(&size, size, 8))
|
||||
return 0;
|
||||
|
||||
size &= ~7;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int read_entry(
|
||||
git_index_entry **out,
|
||||
size_t *out_size,
|
||||
git_index *index,
|
||||
size_t checksum_size,
|
||||
const void *buffer,
|
||||
size_t buffer_size,
|
||||
const char *last)
|
||||
{
|
||||
size_t path_length, entry_size;
|
||||
size_t path_length, path_offset, entry_size;
|
||||
const char *path_ptr;
|
||||
struct entry_short source;
|
||||
struct entry_common *source_common;
|
||||
index_entry_short_sha1 source_sha1;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
index_entry_short_sha256 source_sha256;
|
||||
#endif
|
||||
git_index_entry entry = {{0}};
|
||||
bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP;
|
||||
char *tmp_path = NULL;
|
||||
size_t checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
|
||||
size_t minimal_entry_size = index_entry_path_offset(index->oid_type, 0);
|
||||
|
||||
if (checksum_size + minimal_entry_size > buffer_size)
|
||||
return -1;
|
||||
|
||||
/* buffer is not guaranteed to be aligned */
|
||||
memcpy(&source, buffer, sizeof(struct entry_short));
|
||||
switch (index->oid_type) {
|
||||
case GIT_OID_SHA1:
|
||||
source_common = &source_sha1.common;
|
||||
memcpy(&source_sha1, buffer, sizeof(source_sha1));
|
||||
break;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
case GIT_OID_SHA256:
|
||||
source_common = &source_sha256.common;
|
||||
memcpy(&source_sha256, buffer, sizeof(source_sha256));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
GIT_ASSERT(!"invalid oid type");
|
||||
}
|
||||
|
||||
entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds);
|
||||
entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds);
|
||||
entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds);
|
||||
entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds);
|
||||
entry.dev = ntohl(source.dev);
|
||||
entry.ino = ntohl(source.ino);
|
||||
entry.mode = ntohl(source.mode);
|
||||
entry.uid = ntohl(source.uid);
|
||||
entry.gid = ntohl(source.gid);
|
||||
entry.file_size = ntohl(source.file_size);
|
||||
entry.flags = ntohs(source.flags);
|
||||
entry.ctime.seconds = (git_time_t)ntohl(source_common->ctime.seconds);
|
||||
entry.ctime.nanoseconds = ntohl(source_common->ctime.nanoseconds);
|
||||
entry.mtime.seconds = (git_time_t)ntohl(source_common->mtime.seconds);
|
||||
entry.mtime.nanoseconds = ntohl(source_common->mtime.nanoseconds);
|
||||
entry.dev = ntohl(source_common->dev);
|
||||
entry.ino = ntohl(source_common->ino);
|
||||
entry.mode = ntohl(source_common->mode);
|
||||
entry.uid = ntohl(source_common->uid);
|
||||
entry.gid = ntohl(source_common->gid);
|
||||
entry.file_size = ntohl(source_common->file_size);
|
||||
|
||||
if (git_oid__fromraw(&entry.id, source.oid, GIT_OID_SHA1) < 0)
|
||||
switch (index->oid_type) {
|
||||
case GIT_OID_SHA1:
|
||||
if (git_oid__fromraw(&entry.id, source_sha1.oid,
|
||||
GIT_OID_SHA1) < 0)
|
||||
return -1;
|
||||
entry.flags = ntohs(source_sha1.flags);
|
||||
break;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
case GIT_OID_SHA256:
|
||||
if (git_oid__fromraw(&entry.id, source_sha256.oid,
|
||||
GIT_OID_SHA256) < 0)
|
||||
return -1;
|
||||
entry.flags = ntohs(source_sha256.flags);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
GIT_ASSERT(!"invalid oid type");
|
||||
}
|
||||
|
||||
if (!(path_offset = index_entry_path_offset(index->oid_type, entry.flags)))
|
||||
return -1;
|
||||
|
||||
|
||||
if (entry.flags & GIT_INDEX_ENTRY_EXTENDED) {
|
||||
uint16_t flags_raw;
|
||||
size_t flags_offset;
|
||||
|
||||
flags_offset = offsetof(struct entry_long, flags_extended);
|
||||
memcpy(&flags_raw, (const char *) buffer + flags_offset,
|
||||
sizeof(flags_raw));
|
||||
if (!(flags_offset = index_entry_flags_offset(index->oid_type)))
|
||||
return -1;
|
||||
|
||||
memcpy(&flags_raw, (const char *)buffer + flags_offset, sizeof(flags_raw));
|
||||
flags_raw = ntohs(flags_raw);
|
||||
|
||||
memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw));
|
||||
path_ptr = (const char *) buffer + offsetof(struct entry_long, path);
|
||||
} else
|
||||
path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
|
||||
path_ptr = (const char *)buffer + path_offset;
|
||||
} else {
|
||||
path_ptr = (const char *)buffer + path_offset;
|
||||
}
|
||||
|
||||
if (!compressed) {
|
||||
path_length = entry.flags & GIT_INDEX_ENTRY_NAMEMASK;
|
||||
@ -2511,12 +2633,12 @@ static int read_entry(
|
||||
|
||||
path_end = memchr(path_ptr, '\0', buffer_size);
|
||||
if (path_end == NULL)
|
||||
return -1;
|
||||
return index_error_invalid("invalid path name");
|
||||
|
||||
path_length = path_end - path_ptr;
|
||||
}
|
||||
|
||||
entry_size = index_entry_size(path_length, 0, entry.flags);
|
||||
entry_size = index_entry_size(path_length, 0, index->oid_type, entry.flags);
|
||||
entry.path = (char *)path_ptr;
|
||||
} else {
|
||||
size_t varint_len, last_len, prefix_len, suffix_len, path_len;
|
||||
@ -2542,15 +2664,18 @@ static int read_entry(
|
||||
|
||||
memcpy(tmp_path, last, prefix_len);
|
||||
memcpy(tmp_path + prefix_len, path_ptr + varint_len, suffix_len + 1);
|
||||
entry_size = index_entry_size(suffix_len, varint_len, entry.flags);
|
||||
|
||||
entry_size = index_entry_size(suffix_len, varint_len, index->oid_type, entry.flags);
|
||||
entry.path = tmp_path;
|
||||
}
|
||||
|
||||
if (entry_size == 0)
|
||||
return -1;
|
||||
|
||||
if (checksum_size + entry_size > buffer_size)
|
||||
if (checksum_size + entry_size > buffer_size) {
|
||||
git_error_set(GIT_ERROR_INTERNAL, "invalid index checksum");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (index_entry_dup(out, index, &entry) < 0) {
|
||||
git__free(tmp_path);
|
||||
@ -2579,11 +2704,10 @@ static int read_header(struct index_header *dest, const void *buffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_extension(size_t *read_len, git_index *index, const char *buffer, size_t buffer_size)
|
||||
static int read_extension(size_t *read_len, git_index *index, size_t checksum_size, const char *buffer, size_t buffer_size)
|
||||
{
|
||||
struct index_extension dest;
|
||||
size_t total_size;
|
||||
size_t checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
|
||||
/* buffer is not guaranteed to be aligned */
|
||||
memcpy(&dest, buffer, sizeof(struct index_extension));
|
||||
@ -2602,7 +2726,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer
|
||||
if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') {
|
||||
/* tree cache */
|
||||
if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) {
|
||||
if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, &index->tree_pool) < 0)
|
||||
if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, index->oid_type, &index->tree_pool) < 0)
|
||||
return -1;
|
||||
} else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
|
||||
if (read_reuc(index, buffer + 8, dest.extension_size) < 0)
|
||||
@ -2630,8 +2754,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
||||
int error = 0;
|
||||
unsigned int i;
|
||||
struct index_header header = { 0 };
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
size_t checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
size_t checksum_size = git_hash_size(git_oid_algorithm(index->oid_type));
|
||||
const char *last = NULL;
|
||||
const char *empty = "";
|
||||
|
||||
@ -2646,9 +2770,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
||||
if (buffer_size < INDEX_HEADER_SIZE + checksum_size)
|
||||
return index_error_invalid("insufficient buffer space");
|
||||
|
||||
/* Precalculate the SHA1 of the files's contents -- we'll match it to
|
||||
* the provided SHA1 in the footer */
|
||||
git_hash_buf(checksum, buffer, buffer_size - checksum_size, GIT_HASH_ALGORITHM_SHA1);
|
||||
/*
|
||||
* Precalculate the hash of the files's contents -- we'll match
|
||||
* it to the provided checksum in the footer.
|
||||
*/
|
||||
git_hash_buf(checksum, buffer, buffer_size - checksum_size,
|
||||
git_oid_algorithm(index->oid_type));
|
||||
|
||||
/* Parse header */
|
||||
if ((error = read_header(&header, buffer)) < 0)
|
||||
@ -2670,7 +2797,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
||||
git_index_entry *entry = NULL;
|
||||
size_t entry_size;
|
||||
|
||||
if ((error = read_entry(&entry, &entry_size, index, buffer, buffer_size, last)) < 0) {
|
||||
if ((error = read_entry(&entry, &entry_size, index, checksum_size, buffer, buffer_size, last)) < 0) {
|
||||
error = index_error_invalid("invalid entry");
|
||||
goto done;
|
||||
}
|
||||
@ -2701,7 +2828,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
||||
while (buffer_size > checksum_size) {
|
||||
size_t extension_size;
|
||||
|
||||
if ((error = read_extension(&extension_size, index, buffer, buffer_size)) < 0) {
|
||||
if ((error = read_extension(&extension_size, index, checksum_size, buffer, buffer_size)) < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -2714,7 +2841,10 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 160-bit SHA-1 over the content of the index file before this checksum. */
|
||||
/*
|
||||
* SHA-1 or SHA-256 (depending on the repository's object format)
|
||||
* over the content of the index file before this checksum.
|
||||
*/
|
||||
if (memcmp(checksum, buffer, checksum_size) != 0) {
|
||||
error = index_error_invalid(
|
||||
"calculated checksum does not match expected");
|
||||
@ -2754,16 +2884,40 @@ static bool is_index_extended(git_index *index)
|
||||
return (extended > 0);
|
||||
}
|
||||
|
||||
static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char *last)
|
||||
static int write_disk_entry(
|
||||
git_index *index,
|
||||
git_filebuf *file,
|
||||
git_index_entry *entry,
|
||||
const char *last)
|
||||
{
|
||||
void *mem = NULL;
|
||||
struct entry_short ondisk;
|
||||
size_t path_len, disk_size;
|
||||
struct entry_common *ondisk_common;
|
||||
size_t path_len, path_offset, disk_size;
|
||||
int varint_len = 0;
|
||||
char *path;
|
||||
const char *path_start = entry->path;
|
||||
size_t same_len = 0;
|
||||
|
||||
index_entry_short_sha1 ondisk_sha1;
|
||||
index_entry_long_sha1 ondisk_ext_sha1;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
index_entry_short_sha256 ondisk_sha256;
|
||||
index_entry_long_sha256 ondisk_ext_sha256;
|
||||
#endif
|
||||
|
||||
switch (index->oid_type) {
|
||||
case GIT_OID_SHA1:
|
||||
ondisk_common = &ondisk_sha1.common;
|
||||
break;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
case GIT_OID_SHA256:
|
||||
ondisk_common = &ondisk_sha256.common;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
GIT_ASSERT(!"invalid oid type");
|
||||
}
|
||||
|
||||
path_len = ((struct entry_internal *)entry)->pathlen;
|
||||
|
||||
if (last) {
|
||||
@ -2780,9 +2934,9 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
|
||||
varint_len = git_encode_varint(NULL, 0, strlen(last) - same_len);
|
||||
}
|
||||
|
||||
disk_size = index_entry_size(path_len, varint_len, entry->flags);
|
||||
disk_size = index_entry_size(path_len, varint_len, index->oid_type, entry->flags);
|
||||
|
||||
if (git_filebuf_reserve(file, &mem, disk_size) < 0)
|
||||
if (!disk_size || git_filebuf_reserve(file, &mem, disk_size) < 0)
|
||||
return -1;
|
||||
|
||||
memset(mem, 0x0, disk_size);
|
||||
@ -2797,35 +2951,77 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
|
||||
*
|
||||
* In 2038 I will be either too dead or too rich to care about this
|
||||
*/
|
||||
ondisk.ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
|
||||
ondisk.mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
|
||||
ondisk.ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
|
||||
ondisk.mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
|
||||
ondisk.dev = htonl(entry->dev);
|
||||
ondisk.ino = htonl(entry->ino);
|
||||
ondisk.mode = htonl(entry->mode);
|
||||
ondisk.uid = htonl(entry->uid);
|
||||
ondisk.gid = htonl(entry->gid);
|
||||
ondisk.file_size = htonl((uint32_t)entry->file_size);
|
||||
git_oid_raw_cpy(ondisk.oid, entry->id.id, GIT_OID_SHA1_SIZE);
|
||||
ondisk.flags = htons(entry->flags);
|
||||
ondisk_common->ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
|
||||
ondisk_common->mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
|
||||
ondisk_common->ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
|
||||
ondisk_common->mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
|
||||
ondisk_common->dev = htonl(entry->dev);
|
||||
ondisk_common->ino = htonl(entry->ino);
|
||||
ondisk_common->mode = htonl(entry->mode);
|
||||
ondisk_common->uid = htonl(entry->uid);
|
||||
ondisk_common->gid = htonl(entry->gid);
|
||||
ondisk_common->file_size = htonl((uint32_t)entry->file_size);
|
||||
|
||||
switch (index->oid_type) {
|
||||
case GIT_OID_SHA1:
|
||||
git_oid_raw_cpy(ondisk_sha1.oid, entry->id.id, GIT_OID_SHA1_SIZE);
|
||||
ondisk_sha1.flags = htons(entry->flags);
|
||||
break;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
case GIT_OID_SHA256:
|
||||
git_oid_raw_cpy(ondisk_sha256.oid, entry->id.id, GIT_OID_SHA256_SIZE);
|
||||
ondisk_sha256.flags = htons(entry->flags);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
GIT_ASSERT(!"invalid oid type");
|
||||
}
|
||||
|
||||
path_offset = index_entry_path_offset(index->oid_type, entry->flags);
|
||||
|
||||
if (entry->flags & GIT_INDEX_ENTRY_EXTENDED) {
|
||||
const size_t path_offset = offsetof(struct entry_long, path);
|
||||
struct entry_long ondisk_ext;
|
||||
memcpy(&ondisk_ext, &ondisk, sizeof(struct entry_short));
|
||||
ondisk_ext.flags_extended = htons(entry->flags_extended &
|
||||
struct entry_common *ondisk_ext;
|
||||
uint16_t flags_extended = htons(entry->flags_extended &
|
||||
GIT_INDEX_ENTRY_EXTENDED_FLAGS);
|
||||
memcpy(mem, &ondisk_ext, path_offset);
|
||||
path = (char *)mem + path_offset;
|
||||
disk_size -= path_offset;
|
||||
|
||||
switch (index->oid_type) {
|
||||
case GIT_OID_SHA1:
|
||||
memcpy(&ondisk_ext_sha1, &ondisk_sha1,
|
||||
sizeof(index_entry_short_sha1));
|
||||
ondisk_ext_sha1.flags_extended = flags_extended;
|
||||
ondisk_ext = &ondisk_ext_sha1.common;
|
||||
break;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
case GIT_OID_SHA256:
|
||||
memcpy(&ondisk_ext_sha256, &ondisk_sha256,
|
||||
sizeof(index_entry_short_sha256));
|
||||
ondisk_ext_sha256.flags_extended = flags_extended;
|
||||
ondisk_ext = &ondisk_ext_sha256.common;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
GIT_ASSERT(!"invalid oid type");
|
||||
}
|
||||
|
||||
memcpy(mem, ondisk_ext, path_offset);
|
||||
} else {
|
||||
const size_t path_offset = offsetof(struct entry_short, path);
|
||||
memcpy(mem, &ondisk, path_offset);
|
||||
path = (char *)mem + path_offset;
|
||||
disk_size -= path_offset;
|
||||
switch (index->oid_type) {
|
||||
case GIT_OID_SHA1:
|
||||
memcpy(mem, &ondisk_sha1, path_offset);
|
||||
break;
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
case GIT_OID_SHA256:
|
||||
memcpy(mem, &ondisk_sha256, path_offset);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
GIT_ASSERT(!"invalid oid type");
|
||||
}
|
||||
}
|
||||
|
||||
path = (char *)mem + path_offset;
|
||||
disk_size -= path_offset;
|
||||
|
||||
if (last) {
|
||||
varint_len = git_encode_varint((unsigned char *) path,
|
||||
disk_size, strlen(last) - same_len);
|
||||
@ -2877,7 +3073,7 @@ static int write_entries(git_index *index, git_filebuf *file)
|
||||
last = "";
|
||||
|
||||
git_vector_foreach(entries, i, entry) {
|
||||
if ((error = write_disk_entry(file, entry, last)) < 0)
|
||||
if ((error = write_disk_entry(index, file, entry, last)) < 0)
|
||||
break;
|
||||
if (index->version >= INDEX_VERSION_NUMBER_COMP)
|
||||
last = entry->path;
|
||||
@ -2955,8 +3151,9 @@ done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *reuc)
|
||||
static int create_reuc_extension_data(git_str *reuc_buf, git_index *index, git_index_reuc_entry *reuc)
|
||||
{
|
||||
size_t oid_size = git_oid_size(index->oid_type);
|
||||
int i;
|
||||
int error = 0;
|
||||
|
||||
@ -2970,7 +3167,7 @@ static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *r
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_SHA1_SIZE)) < 0)
|
||||
if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, oid_size)) < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -2987,7 +3184,7 @@ static int write_reuc_extension(git_index *index, git_filebuf *file)
|
||||
int error = 0;
|
||||
|
||||
git_vector_foreach(out, i, reuc) {
|
||||
if ((error = create_reuc_extension_data(&reuc_buf, reuc)) < 0)
|
||||
if ((error = create_reuc_extension_data(&reuc_buf, index, reuc)) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -3036,7 +3233,7 @@ static void clear_uptodate(git_index *index)
|
||||
}
|
||||
|
||||
static int write_index(
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE],
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE],
|
||||
size_t *checksum_size,
|
||||
git_index *index,
|
||||
git_filebuf *file)
|
||||
@ -3048,7 +3245,9 @@ static int write_index(
|
||||
GIT_ASSERT_ARG(index);
|
||||
GIT_ASSERT_ARG(file);
|
||||
|
||||
*checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
GIT_ASSERT(index->oid_type);
|
||||
|
||||
*checksum_size = git_hash_size(git_oid_algorithm(index->oid_type));
|
||||
|
||||
if (index->version <= INDEX_VERSION_NUMBER_EXT) {
|
||||
is_extended = is_index_extended(index);
|
||||
@ -3209,7 +3408,7 @@ cleanup:
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
error = git_tree_cache_read_tree(&index->tree, tree, &index->tree_pool);
|
||||
error = git_tree_cache_read_tree(&index->tree, tree, index->oid_type, &index->tree_pool);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -3668,19 +3867,23 @@ int git_indexwriter_init(
|
||||
git_indexwriter *writer,
|
||||
git_index *index)
|
||||
{
|
||||
int error;
|
||||
int filebuf_hash, error;
|
||||
|
||||
GIT_REFCOUNT_INC(index);
|
||||
|
||||
writer->index = index;
|
||||
|
||||
filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(index->oid_type));
|
||||
GIT_ASSERT(filebuf_hash);
|
||||
|
||||
if (!index->index_file_path)
|
||||
return create_index_error(-1,
|
||||
"failed to write index: The index is in-memory only");
|
||||
|
||||
if ((error = git_filebuf_open(
|
||||
&writer->file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) {
|
||||
|
||||
if ((error = git_filebuf_open(&writer->file,
|
||||
index->index_file_path,
|
||||
git_filebuf_hash_flags(filebuf_hash),
|
||||
GIT_INDEX_FILE_MODE)) < 0) {
|
||||
if (error == GIT_ELOCKED)
|
||||
git_error_set(GIT_ERROR_INDEX, "the index is locked; this might be due to a concurrent or crashed process");
|
||||
|
||||
@ -3712,7 +3915,7 @@ int git_indexwriter_init_for_operation(
|
||||
|
||||
int git_indexwriter_commit(git_indexwriter *writer)
|
||||
{
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
size_t checksum_size;
|
||||
int error;
|
||||
|
||||
|
@ -27,7 +27,7 @@ struct git_index {
|
||||
|
||||
char *index_file_path;
|
||||
git_futils_filestamp stamp;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
|
||||
git_vector entries;
|
||||
git_idxmap *entries_map;
|
||||
@ -35,6 +35,8 @@ struct git_index {
|
||||
git_vector deleted; /* deleted entries if readers > 0 */
|
||||
git_atomic32 readers; /* number of active iterators */
|
||||
|
||||
git_oid_t oid_type;
|
||||
|
||||
unsigned int on_disk:1;
|
||||
unsigned int ignore_case:1;
|
||||
unsigned int distrust_filemode:1;
|
||||
@ -141,6 +143,17 @@ GIT_INLINE(unsigned char *) git_index__checksum(git_index *index)
|
||||
return index->checksum;
|
||||
}
|
||||
|
||||
/* SHA256-aware internal functions */
|
||||
|
||||
extern int git_index__new(
|
||||
git_index **index_out,
|
||||
git_oid_t oid_type);
|
||||
|
||||
extern int git_index__open(
|
||||
git_index **index_out,
|
||||
const char *index_path,
|
||||
git_oid_t oid_type);
|
||||
|
||||
/* Copy the current entries vector *and* increment the index refcount.
|
||||
* Call `git_index__release_snapshot` when done.
|
||||
*/
|
||||
|
@ -519,7 +519,13 @@ static int store_object(git_indexer *idx)
|
||||
pentry->offset = entry_start;
|
||||
|
||||
if (git_oidmap_exists(idx->pack->idx_cache, &pentry->id)) {
|
||||
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->id));
|
||||
const char *idstr = git_oid_tostr_s(&pentry->id);
|
||||
|
||||
if (!idstr)
|
||||
git_error_set(GIT_ERROR_INDEXER, "failed to parse object id");
|
||||
else
|
||||
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", idstr);
|
||||
|
||||
git__free(pentry);
|
||||
goto on_error;
|
||||
}
|
||||
@ -1232,6 +1238,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
|
||||
git_filebuf index_file = {0};
|
||||
void *packfile_trailer;
|
||||
size_t checksum_size;
|
||||
int filebuf_hash;
|
||||
bool mismatch;
|
||||
|
||||
if (!idx->parsed_header) {
|
||||
@ -1240,6 +1247,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
|
||||
}
|
||||
|
||||
checksum_size = git_hash_size(indexer_hash_algorithm(idx));
|
||||
filebuf_hash = git_filebuf_hash_flags(indexer_hash_algorithm(idx));
|
||||
GIT_ASSERT(checksum_size);
|
||||
|
||||
/* Test for this before resolve_deltas(), as it plays with idx->off */
|
||||
@ -1314,8 +1322,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
|
||||
return -1;
|
||||
|
||||
if (git_filebuf_open(&index_file, filename.ptr,
|
||||
GIT_FILEBUF_HASH_CONTENTS |
|
||||
(idx->do_fsync ? GIT_FILEBUF_FSYNC : 0),
|
||||
filebuf_hash | (idx->do_fsync ? GIT_FILEBUF_FSYNC : 0),
|
||||
idx->mode) < 0)
|
||||
goto on_error;
|
||||
|
||||
|
@ -1036,6 +1036,8 @@ typedef struct {
|
||||
git_index *index;
|
||||
git_vector index_snapshot;
|
||||
|
||||
git_oid_t oid_type;
|
||||
|
||||
git_array_t(filesystem_iterator_frame) frames;
|
||||
git_ignores ignores;
|
||||
|
||||
@ -1271,7 +1273,7 @@ static int filesystem_iterator_entry_hash(
|
||||
int error;
|
||||
|
||||
if (S_ISDIR(entry->st.st_mode)) {
|
||||
memset(&entry->id, 0, GIT_OID_SHA1_SIZE);
|
||||
memset(&entry->id, 0, git_oid_size(iter->oid_type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1281,7 +1283,7 @@ static int filesystem_iterator_entry_hash(
|
||||
|
||||
if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) &&
|
||||
!(error = git_path_validate_str_length(iter->base.repo, &fullpath)))
|
||||
error = git_odb__hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB, GIT_OID_SHA1);
|
||||
error = git_odb__hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB, iter->oid_type);
|
||||
|
||||
git_str_dispose(&fullpath);
|
||||
return error;
|
||||
@ -1530,7 +1532,7 @@ static void filesystem_iterator_set_current(
|
||||
if (iter->base.flags & GIT_ITERATOR_INCLUDE_HASH)
|
||||
git_oid_cpy(&iter->entry.id, &entry->id);
|
||||
else
|
||||
git_oid_clear(&iter->entry.id, GIT_OID_SHA1);
|
||||
git_oid_clear(&iter->entry.id, iter->oid_type);
|
||||
|
||||
iter->entry.path = entry->path;
|
||||
|
||||
@ -1975,6 +1977,8 @@ static int iterator_for_filesystem(
|
||||
(iterator__flag(&iter->base, PRECOMPOSE_UNICODE) ?
|
||||
GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE : 0);
|
||||
|
||||
iter->oid_type = options->oid_type;
|
||||
|
||||
if ((error = filesystem_iterator_init(iter)) < 0)
|
||||
goto on_error;
|
||||
|
||||
@ -1989,10 +1993,15 @@ on_error:
|
||||
int git_iterator_for_filesystem(
|
||||
git_iterator **out,
|
||||
const char *root,
|
||||
git_iterator_options *options)
|
||||
git_iterator_options *given_opts)
|
||||
{
|
||||
git_iterator_options options = GIT_ITERATOR_OPTIONS_INIT;
|
||||
|
||||
if (given_opts)
|
||||
memcpy(&options, given_opts, sizeof(git_iterator_options));
|
||||
|
||||
return iterator_for_filesystem(out,
|
||||
NULL, root, NULL, NULL, GIT_ITERATOR_FS, options);
|
||||
NULL, root, NULL, NULL, GIT_ITERATOR_FS, &options);
|
||||
}
|
||||
|
||||
int git_iterator_for_workdir_ext(
|
||||
@ -2019,6 +2028,12 @@ int git_iterator_for_workdir_ext(
|
||||
options.flags |= GIT_ITERATOR_HONOR_IGNORES |
|
||||
GIT_ITERATOR_IGNORE_DOT_GIT;
|
||||
|
||||
if (!options.oid_type)
|
||||
options.oid_type = repo->oid_type;
|
||||
else if (options.oid_type != repo->oid_type)
|
||||
git_error_set(GIT_ERROR_INVALID,
|
||||
"specified object ID type does not match repository object ID type");
|
||||
|
||||
return iterator_for_filesystem(out,
|
||||
repo, repo_workdir, index, tree, GIT_ITERATOR_WORKDIR, &options);
|
||||
}
|
||||
|
@ -63,6 +63,9 @@ typedef struct {
|
||||
|
||||
/* flags, from above */
|
||||
unsigned int flags;
|
||||
|
||||
/* oid type - necessary for non-workdir filesystem iterators */
|
||||
git_oid_t oid_type;
|
||||
} git_iterator_options;
|
||||
|
||||
#define GIT_ITERATOR_OPTIONS_INIT {0}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "cache.h"
|
||||
#include "common.h"
|
||||
#include "filter.h"
|
||||
#include "grafts.h"
|
||||
#include "hash.h"
|
||||
#include "index.h"
|
||||
#include "merge_driver.h"
|
||||
@ -30,6 +31,7 @@
|
||||
#include "streams/registry.h"
|
||||
#include "streams/mbedtls.h"
|
||||
#include "streams/openssl.h"
|
||||
#include "streams/socket.h"
|
||||
#include "transports/smart.h"
|
||||
#include "transports/http.h"
|
||||
#include "transports/ssh.h"
|
||||
@ -46,6 +48,8 @@ extern size_t git_indexer__max_objects;
|
||||
extern bool git_disable_pack_keep_file_checks;
|
||||
extern int git_odb__packed_priority;
|
||||
extern int git_odb__loose_priority;
|
||||
extern int git_socket_stream__connect_timeout;
|
||||
extern int git_socket_stream__timeout;
|
||||
|
||||
char *git__user_agent;
|
||||
char *git__ssl_ciphers;
|
||||
@ -78,6 +82,7 @@ int git_libgit2_init(void)
|
||||
git_merge_driver_global_init,
|
||||
git_transport_ssh_global_init,
|
||||
git_stream_registry_global_init,
|
||||
git_socket_stream_global_init,
|
||||
git_openssl_stream_global_init,
|
||||
git_mbedtls_stream_global_init,
|
||||
git_mwindow_global_init,
|
||||
@ -433,6 +438,40 @@ int git_libgit2_opts(int key, ...)
|
||||
error = git_sysdir_set(GIT_SYSDIR_HOME, va_arg(ap, const char *));
|
||||
break;
|
||||
|
||||
case GIT_OPT_GET_SERVER_CONNECT_TIMEOUT:
|
||||
*(va_arg(ap, int *)) = git_socket_stream__connect_timeout;
|
||||
break;
|
||||
|
||||
case GIT_OPT_SET_SERVER_CONNECT_TIMEOUT:
|
||||
{
|
||||
int timeout = va_arg(ap, int);
|
||||
|
||||
if (timeout < 0) {
|
||||
git_error_set(GIT_ERROR_INVALID, "invalid connect timeout");
|
||||
error = -1;
|
||||
} else {
|
||||
git_socket_stream__connect_timeout = timeout;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GIT_OPT_GET_SERVER_TIMEOUT:
|
||||
*(va_arg(ap, int *)) = git_socket_stream__timeout;
|
||||
break;
|
||||
|
||||
case GIT_OPT_SET_SERVER_TIMEOUT:
|
||||
{
|
||||
int timeout = va_arg(ap, int);
|
||||
|
||||
if (timeout < 0) {
|
||||
git_error_set(GIT_ERROR_INVALID, "invalid timeout");
|
||||
error = -1;
|
||||
} else {
|
||||
git_socket_stream__timeout = timeout;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
git_error_set(GIT_ERROR_INVALID, "invalid option key");
|
||||
error = -1;
|
||||
|
@ -611,13 +611,13 @@ int git_repository_mergehead_foreach(
|
||||
buffer = merge_head_file.ptr;
|
||||
|
||||
while ((line = git__strsep(&buffer, "\n")) != NULL) {
|
||||
if (strlen(line) != GIT_OID_SHA1_HEXSIZE) {
|
||||
if (strlen(line) != git_oid_hexsize(repo->oid_type)) {
|
||||
git_error_set(GIT_ERROR_INVALID, "unable to parse OID - invalid length");
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((error = git_oid__fromstr(&oid, line, GIT_OID_SHA1)) < 0)
|
||||
if ((error = git_oid__fromstr(&oid, line, repo->oid_type)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = cb(&oid, payload)) != 0) {
|
||||
@ -1061,7 +1061,7 @@ static int index_entry_similarity_calc(
|
||||
const git_merge_options *opts)
|
||||
{
|
||||
git_blob *blob;
|
||||
git_diff_file diff_file = { GIT_OID_SHA1_ZERO };
|
||||
git_diff_file diff_file;
|
||||
git_object_size_t blobsize;
|
||||
int error;
|
||||
|
||||
@ -1070,6 +1070,8 @@ static int index_entry_similarity_calc(
|
||||
|
||||
*out = NULL;
|
||||
|
||||
git_oid_clear(&diff_file.id, repo->oid_type);
|
||||
|
||||
if ((error = git_blob_lookup(&blob, repo, &entry->id)) < 0)
|
||||
return error;
|
||||
|
||||
@ -1997,8 +1999,11 @@ static int index_update_reuc(git_index *index, git_merge_diff_list *diff_list)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int index_from_diff_list(git_index **out,
|
||||
git_merge_diff_list *diff_list, bool skip_reuc)
|
||||
static int index_from_diff_list(
|
||||
git_index **out,
|
||||
git_merge_diff_list *diff_list,
|
||||
git_oid_t oid_type,
|
||||
bool skip_reuc)
|
||||
{
|
||||
git_index *index;
|
||||
size_t i;
|
||||
@ -2007,7 +2012,7 @@ static int index_from_diff_list(git_index **out,
|
||||
|
||||
*out = NULL;
|
||||
|
||||
if ((error = git_index_new(&index)) < 0)
|
||||
if ((error = git_index__new(&index, oid_type)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = git_index__fill(index, &diff_list->staged)) < 0)
|
||||
@ -2157,7 +2162,7 @@ int git_merge__iterators(
|
||||
}
|
||||
}
|
||||
|
||||
error = index_from_diff_list(out, diff_list,
|
||||
error = index_from_diff_list(out, diff_list, repo->oid_type,
|
||||
(opts.flags & GIT_MERGE_SKIP_REUC));
|
||||
|
||||
done:
|
||||
@ -2200,8 +2205,8 @@ int git_merge_trees(
|
||||
result = our_tree;
|
||||
|
||||
if (result) {
|
||||
if ((error = git_index_new(out)) == 0)
|
||||
error = git_index_read_tree(*out, result);
|
||||
if ((error = git_index__new(out, repo->oid_type)) == 0)
|
||||
error = git_index_read_tree(*out, result);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include "git2/index.h"
|
||||
#include "git2/merge.h"
|
||||
|
||||
#include "xdiff/xdiff.h"
|
||||
|
||||
/* only examine the first 8000 bytes for binaryness.
|
||||
* https://github.com/git/git/blob/77bd3ea9f54f1584147b594abc04c26ca516d987/xdiff-interface.c#L197
|
||||
*/
|
||||
|
@ -114,23 +114,16 @@ static int midx_parse_oid_lookup(
|
||||
const unsigned char *data,
|
||||
struct git_midx_chunk *chunk_oid_lookup)
|
||||
{
|
||||
uint32_t i;
|
||||
unsigned char *oid, *prev_oid, zero_oid[GIT_OID_SHA1_SIZE] = {0};
|
||||
size_t oid_size = git_oid_size(idx->oid_type);
|
||||
|
||||
if (chunk_oid_lookup->offset == 0)
|
||||
return midx_error("missing OID Lookup chunk");
|
||||
if (chunk_oid_lookup->length == 0)
|
||||
return midx_error("empty OID Lookup chunk");
|
||||
if (chunk_oid_lookup->length != idx->num_objects * GIT_OID_SHA1_SIZE)
|
||||
if (chunk_oid_lookup->length != idx->num_objects * oid_size)
|
||||
return midx_error("OID Lookup chunk has wrong length");
|
||||
|
||||
idx->oid_lookup = oid = (unsigned char *)(data + chunk_oid_lookup->offset);
|
||||
prev_oid = zero_oid;
|
||||
for (i = 0; i < idx->num_objects; ++i, oid += GIT_OID_SHA1_SIZE) {
|
||||
if (git_oid_raw_cmp(prev_oid, oid, GIT_OID_SHA1_SIZE) >= 0)
|
||||
return midx_error("OID Lookup index is non-monotonic");
|
||||
prev_oid = oid;
|
||||
}
|
||||
idx->oid_lookup = (unsigned char *)(data + chunk_oid_lookup->offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -178,17 +171,20 @@ int git_midx_parse(
|
||||
struct git_midx_chunk *last_chunk;
|
||||
uint32_t i;
|
||||
off64_t last_chunk_offset, chunk_offset, trailer_offset;
|
||||
size_t checksum_size;
|
||||
size_t checksum_size, oid_size;
|
||||
int error;
|
||||
struct git_midx_chunk chunk_packfile_names = {0},
|
||||
chunk_oid_fanout = {0},
|
||||
chunk_oid_lookup = {0},
|
||||
chunk_object_offsets = {0},
|
||||
chunk_object_large_offsets = {0};
|
||||
chunk_object_large_offsets = {0},
|
||||
chunk_unknown = {0};
|
||||
|
||||
GIT_ASSERT_ARG(idx);
|
||||
|
||||
if (size < sizeof(struct git_midx_header) + GIT_OID_SHA1_SIZE)
|
||||
oid_size = git_oid_size(idx->oid_type);
|
||||
|
||||
if (size < sizeof(struct git_midx_header) + oid_size)
|
||||
return midx_error("multi-pack index is too short");
|
||||
|
||||
hdr = ((struct git_midx_header *)data);
|
||||
@ -209,7 +205,7 @@ int git_midx_parse(
|
||||
sizeof(struct git_midx_header) +
|
||||
(1 + hdr->chunks) * 12;
|
||||
|
||||
checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
checksum_size = oid_size;
|
||||
trailer_offset = size - checksum_size;
|
||||
|
||||
if (trailer_offset < last_chunk_offset)
|
||||
@ -261,7 +257,9 @@ int git_midx_parse(
|
||||
break;
|
||||
|
||||
default:
|
||||
return midx_error("unrecognized chunk ID");
|
||||
chunk_unknown.offset = last_chunk_offset;
|
||||
last_chunk = &chunk_unknown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
last_chunk->length = (size_t)(trailer_offset - last_chunk_offset);
|
||||
@ -287,8 +285,9 @@ int git_midx_parse(
|
||||
}
|
||||
|
||||
int git_midx_open(
|
||||
git_midx_file **idx_out,
|
||||
const char *path)
|
||||
git_midx_file **idx_out,
|
||||
const char *path,
|
||||
git_oid_t oid_type)
|
||||
{
|
||||
git_midx_file *idx;
|
||||
git_file fd = -1;
|
||||
@ -296,6 +295,8 @@ int git_midx_open(
|
||||
struct stat st;
|
||||
int error;
|
||||
|
||||
GIT_ASSERT_ARG(idx_out && path && oid_type);
|
||||
|
||||
/* TODO: properly open the file without access time using O_NOATIME */
|
||||
fd = git_futils_open_ro(path);
|
||||
if (fd < 0)
|
||||
@ -317,6 +318,8 @@ int git_midx_open(
|
||||
idx = git__calloc(1, sizeof(git_midx_file));
|
||||
GIT_ERROR_CHECK_ALLOC(idx);
|
||||
|
||||
idx->oid_type = oid_type;
|
||||
|
||||
error = git_str_sets(&idx->filename, path);
|
||||
if (error < 0)
|
||||
return error;
|
||||
@ -344,7 +347,7 @@ bool git_midx_needs_refresh(
|
||||
git_file fd = -1;
|
||||
struct stat st;
|
||||
ssize_t bytes_read;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
size_t checksum_size;
|
||||
|
||||
/* TODO: properly open the file without access time using O_NOATIME */
|
||||
@ -364,8 +367,8 @@ bool git_midx_needs_refresh(
|
||||
return true;
|
||||
}
|
||||
|
||||
checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_SHA1_SIZE);
|
||||
checksum_size = git_oid_size(idx->oid_type);
|
||||
bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - checksum_size);
|
||||
p_close(fd);
|
||||
|
||||
if (bytes_read != (ssize_t)checksum_size)
|
||||
@ -381,7 +384,7 @@ int git_midx_entry_find(
|
||||
size_t len)
|
||||
{
|
||||
int pos, found = 0;
|
||||
size_t pack_index;
|
||||
size_t pack_index, oid_size, oid_hexsize;
|
||||
uint32_t hi, lo;
|
||||
unsigned char *current = NULL;
|
||||
const unsigned char *object_offset;
|
||||
@ -389,30 +392,33 @@ int git_midx_entry_find(
|
||||
|
||||
GIT_ASSERT_ARG(idx);
|
||||
|
||||
oid_size = git_oid_size(idx->oid_type);
|
||||
oid_hexsize = git_oid_hexsize(idx->oid_type);
|
||||
|
||||
hi = ntohl(idx->oid_fanout[(int)short_oid->id[0]]);
|
||||
lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(idx->oid_fanout[(int)short_oid->id[0] - 1]));
|
||||
|
||||
pos = git_pack__lookup_id(idx->oid_lookup, GIT_OID_SHA1_SIZE, lo, hi, short_oid->id, GIT_OID_SHA1);
|
||||
pos = git_pack__lookup_id(idx->oid_lookup, oid_size, lo, hi, short_oid->id, idx->oid_type);
|
||||
|
||||
if (pos >= 0) {
|
||||
/* An object matching exactly the oid was found */
|
||||
found = 1;
|
||||
current = idx->oid_lookup + (pos * GIT_OID_SHA1_SIZE);
|
||||
current = idx->oid_lookup + (pos * oid_size);
|
||||
} else {
|
||||
/* No object was found */
|
||||
/* pos refers to the object with the "closest" oid to short_oid */
|
||||
pos = -1 - pos;
|
||||
if (pos < (int)idx->num_objects) {
|
||||
current = idx->oid_lookup + (pos * GIT_OID_SHA1_SIZE);
|
||||
current = idx->oid_lookup + (pos * oid_size);
|
||||
|
||||
if (!git_oid_raw_ncmp(short_oid->id, current, len))
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (found && len != GIT_OID_SHA1_HEXSIZE && pos + 1 < (int)idx->num_objects) {
|
||||
if (found && len != oid_hexsize && pos + 1 < (int)idx->num_objects) {
|
||||
/* Check for ambiguousity */
|
||||
const unsigned char *next = current + GIT_OID_SHA1_SIZE;
|
||||
const unsigned char *next = current + oid_size;
|
||||
|
||||
if (!git_oid_raw_ncmp(short_oid->id, next, len))
|
||||
found = 2;
|
||||
@ -443,7 +449,7 @@ int git_midx_entry_find(
|
||||
return midx_error("invalid index into the packfile names table");
|
||||
e->pack_index = pack_index;
|
||||
e->offset = offset;
|
||||
git_oid__fromraw(&e->sha1, current, GIT_OID_SHA1);
|
||||
git_oid__fromraw(&e->sha1, current, idx->oid_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -453,13 +459,15 @@ int git_midx_foreach_entry(
|
||||
void *data)
|
||||
{
|
||||
git_oid oid;
|
||||
size_t i;
|
||||
size_t oid_size, i;
|
||||
int error;
|
||||
|
||||
GIT_ASSERT_ARG(idx);
|
||||
|
||||
oid_size = git_oid_size(idx->oid_type);
|
||||
|
||||
for (i = 0; i < idx->num_objects; ++i) {
|
||||
if ((error = git_oid__fromraw(&oid, &idx->oid_lookup[i * GIT_OID_SHA1_SIZE], GIT_OID_SHA1)) < 0)
|
||||
if ((error = git_oid__fromraw(&oid, &idx->oid_lookup[i * oid_size], idx->oid_type)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = cb(&oid, data)) != 0)
|
||||
@ -501,9 +509,21 @@ static int packfile__cmp(const void *a_, const void *b_)
|
||||
|
||||
int git_midx_writer_new(
|
||||
git_midx_writer **out,
|
||||
const char *pack_dir)
|
||||
const char *pack_dir
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
, git_oid_t oid_type
|
||||
#endif
|
||||
)
|
||||
{
|
||||
git_midx_writer *w = git__calloc(1, sizeof(git_midx_writer));
|
||||
git_midx_writer *w;
|
||||
|
||||
#ifndef GIT_EXPERIMENTAL_SHA256
|
||||
git_oid_t oid_type = GIT_OID_SHA1;
|
||||
#endif
|
||||
|
||||
GIT_ASSERT_ARG(out && pack_dir && oid_type);
|
||||
|
||||
w = git__calloc(1, sizeof(git_midx_writer));
|
||||
GIT_ERROR_CHECK_ALLOC(w);
|
||||
|
||||
if (git_str_sets(&w->pack_dir, pack_dir) < 0) {
|
||||
@ -518,6 +538,8 @@ int git_midx_writer_new(
|
||||
return -1;
|
||||
}
|
||||
|
||||
w->oid_type = oid_type;
|
||||
|
||||
*out = w;
|
||||
return 0;
|
||||
}
|
||||
@ -662,12 +684,13 @@ static int midx_write(
|
||||
oid_lookup = GIT_STR_INIT,
|
||||
object_offsets = GIT_STR_INIT,
|
||||
object_large_offsets = GIT_STR_INIT;
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
size_t checksum_size;
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
size_t checksum_size, oid_size;
|
||||
git_midx_entry *entry;
|
||||
object_entry_array_t object_entries_array = GIT_ARRAY_INIT;
|
||||
git_vector object_entries = GIT_VECTOR_INIT;
|
||||
git_hash_ctx ctx;
|
||||
git_hash_algorithm_t checksum_type;
|
||||
struct midx_write_hash_context hash_cb_data = {0};
|
||||
|
||||
hdr.signature = htonl(MIDX_SIGNATURE);
|
||||
@ -679,10 +702,14 @@ static int midx_write(
|
||||
hash_cb_data.cb_data = cb_data;
|
||||
hash_cb_data.ctx = &ctx;
|
||||
|
||||
checksum_size = GIT_HASH_SHA1_SIZE;
|
||||
error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1);
|
||||
if (error < 0)
|
||||
oid_size = git_oid_size(w->oid_type);
|
||||
|
||||
GIT_ASSERT((checksum_type = git_oid_algorithm(w->oid_type)));
|
||||
checksum_size = git_hash_size(checksum_type);
|
||||
|
||||
if ((error = git_hash_ctx_init(&ctx, checksum_type)) < 0)
|
||||
return error;
|
||||
|
||||
cb_data = &hash_cb_data;
|
||||
write_cb = midx_write_hash;
|
||||
|
||||
@ -749,7 +776,9 @@ static int midx_write(
|
||||
|
||||
/* Fill the OID Lookup table. */
|
||||
git_vector_foreach (&object_entries, i, entry) {
|
||||
error = git_str_put(&oid_lookup, (char *)&entry->sha1.id, GIT_OID_SHA1_SIZE);
|
||||
error = git_str_put(&oid_lookup,
|
||||
(char *)&entry->sha1.id, oid_size);
|
||||
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -51,8 +51,14 @@ typedef struct git_midx_file {
|
||||
/* The number of entries in the Object Large Offsets table. Each entry has an 8-byte with an offset */
|
||||
size_t num_object_large_offsets;
|
||||
|
||||
/* The trailer of the file. Contains the SHA1-checksum of the whole file. */
|
||||
unsigned char checksum[GIT_HASH_SHA1_SIZE];
|
||||
/*
|
||||
* The trailer of the file. Contains the checksum of the whole
|
||||
* file, in the repository's object format hash.
|
||||
*/
|
||||
unsigned char checksum[GIT_HASH_MAX_SIZE];
|
||||
|
||||
/* The type of object IDs in the midx. */
|
||||
git_oid_t oid_type;
|
||||
|
||||
/* something like ".git/objects/pack/multi-pack-index". */
|
||||
git_str filename;
|
||||
@ -82,11 +88,15 @@ struct git_midx_writer {
|
||||
|
||||
/* The list of `git_pack_file`s. */
|
||||
git_vector packs;
|
||||
|
||||
/* The object ID type of the writer. */
|
||||
git_oid_t oid_type;
|
||||
};
|
||||
|
||||
int git_midx_open(
|
||||
git_midx_file **idx_out,
|
||||
const char *path);
|
||||
const char *path,
|
||||
git_oid_t oid_type);
|
||||
bool git_midx_needs_refresh(
|
||||
const git_midx_file *idx,
|
||||
const char *path);
|
||||
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "netops.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "git2/errors.h"
|
||||
|
||||
#include "posix.h"
|
||||
#include "str.h"
|
||||
#include "runtime.h"
|
||||
|
||||
int gitno_recv(gitno_buffer *buf)
|
||||
{
|
||||
return buf->recv(buf);
|
||||
}
|
||||
|
||||
void gitno_buffer_setup_callback(
|
||||
gitno_buffer *buf,
|
||||
char *data,
|
||||
size_t len,
|
||||
int (*recv)(gitno_buffer *buf), void *cb_data)
|
||||
{
|
||||
memset(data, 0x0, len);
|
||||
buf->data = data;
|
||||
buf->len = len;
|
||||
buf->offset = 0;
|
||||
buf->recv = recv;
|
||||
buf->cb_data = cb_data;
|
||||
}
|
||||
|
||||
static int recv_stream(gitno_buffer *buf)
|
||||
{
|
||||
git_stream *io = (git_stream *) buf->cb_data;
|
||||
size_t readlen = buf->len - buf->offset;
|
||||
ssize_t ret;
|
||||
|
||||
readlen = min(readlen, INT_MAX);
|
||||
|
||||
ret = git_stream_read(io, buf->data + buf->offset, (int)readlen);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
buf->offset += ret;
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len)
|
||||
{
|
||||
memset(data, 0x0, len);
|
||||
buf->data = data;
|
||||
buf->len = len;
|
||||
buf->offset = 0;
|
||||
buf->recv = recv_stream;
|
||||
buf->cb_data = st;
|
||||
}
|
||||
|
||||
/* Consume up to ptr and move the rest of the buffer to the beginning */
|
||||
int gitno_consume(gitno_buffer *buf, const char *ptr)
|
||||
{
|
||||
size_t consumed;
|
||||
|
||||
GIT_ASSERT(ptr - buf->data >= 0);
|
||||
GIT_ASSERT(ptr - buf->data <= (int) buf->len);
|
||||
|
||||
consumed = ptr - buf->data;
|
||||
|
||||
memmove(buf->data, ptr, buf->offset - consumed);
|
||||
memset(buf->data + buf->offset, 0x0, buf->len - buf->offset);
|
||||
buf->offset -= consumed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Consume const bytes and move the rest of the buffer to the beginning */
|
||||
void gitno_consume_n(gitno_buffer *buf, size_t cons)
|
||||
{
|
||||
memmove(buf->data, buf->data + cons, buf->len - buf->offset);
|
||||
memset(buf->data + cons, 0x0, buf->len - buf->offset);
|
||||
buf->offset -= cons;
|
||||
}
|
||||
|
||||
/* Match host names according to RFC 2818 rules */
|
||||
int gitno__match_host(const char *pattern, const char *host)
|
||||
{
|
||||
for (;;) {
|
||||
char c = git__tolower(*pattern++);
|
||||
|
||||
if (c == '\0')
|
||||
return *host ? -1 : 0;
|
||||
|
||||
if (c == '*') {
|
||||
c = *pattern;
|
||||
/* '*' at the end matches everything left */
|
||||
if (c == '\0')
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We've found a pattern, so move towards the next matching
|
||||
* char. The '.' is handled specially because wildcards aren't
|
||||
* allowed to cross subdomains.
|
||||
*/
|
||||
|
||||
while(*host) {
|
||||
char h = git__tolower(*host);
|
||||
if (c == h)
|
||||
return gitno__match_host(pattern, host++);
|
||||
if (h == '.')
|
||||
return gitno__match_host(pattern, host);
|
||||
host++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c != git__tolower(*host++))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_netops_h__
|
||||
#define INCLUDE_netops_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "posix.h"
|
||||
#include "stream.h"
|
||||
#include "net.h"
|
||||
|
||||
#ifdef GIT_OPENSSL
|
||||
# include "streams/openssl.h"
|
||||
#endif
|
||||
|
||||
typedef struct gitno_ssl {
|
||||
#ifdef GIT_OPENSSL
|
||||
SSL *ssl;
|
||||
#else
|
||||
size_t dummy;
|
||||
#endif
|
||||
} gitno_ssl;
|
||||
|
||||
/* Represents a socket that may or may not be using SSL */
|
||||
typedef struct gitno_socket {
|
||||
GIT_SOCKET socket;
|
||||
gitno_ssl ssl;
|
||||
} gitno_socket;
|
||||
|
||||
typedef struct gitno_buffer {
|
||||
char *data;
|
||||
size_t len;
|
||||
size_t offset;
|
||||
int (*recv)(struct gitno_buffer *buffer);
|
||||
void *cb_data;
|
||||
} gitno_buffer;
|
||||
|
||||
/* Flags to gitno_connect */
|
||||
enum {
|
||||
/* Attempt to create an SSL connection. */
|
||||
GITNO_CONNECT_SSL = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the name in a cert matches the wanted hostname
|
||||
*
|
||||
* Check if a pattern from a certificate matches the hostname we
|
||||
* wanted to connect to according to RFC2818 rules (which specifies
|
||||
* HTTP over TLS). Mainly, an asterisk matches anything, but is
|
||||
* limited to a single url component.
|
||||
*
|
||||
* Note that this does not set an error message. It expects the user
|
||||
* to provide the message for the user.
|
||||
*/
|
||||
int gitno__match_host(const char *pattern, const char *host);
|
||||
|
||||
void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len);
|
||||
void gitno_buffer_setup_callback(gitno_buffer *buf, char *data, size_t len, int (*recv)(gitno_buffer *buf), void *cb_data);
|
||||
int gitno_recv(gitno_buffer *buf);
|
||||
|
||||
int gitno_consume(gitno_buffer *buf, const char *ptr);
|
||||
void gitno_consume_n(gitno_buffer *buf, size_t cons);
|
||||
|
||||
#endif
|
@ -460,7 +460,7 @@ int git_note_commit_read(
|
||||
{
|
||||
int error;
|
||||
git_tree *tree = NULL;
|
||||
char target[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char target[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
git_oid_tostr(target, sizeof(target), oid);
|
||||
|
||||
@ -507,7 +507,7 @@ int git_note_commit_create(
|
||||
{
|
||||
int error;
|
||||
git_tree *tree = NULL;
|
||||
char target[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char target[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
git_oid_tostr(target, sizeof(target), oid);
|
||||
|
||||
@ -578,7 +578,7 @@ int git_note_commit_remove(
|
||||
{
|
||||
int error;
|
||||
git_tree *tree = NULL;
|
||||
char target[GIT_OID_SHA1_HEXSIZE + 1];
|
||||
char target[GIT_OID_MAX_HEXSIZE + 1];
|
||||
|
||||
git_oid_tostr(target, sizeof(target), oid);
|
||||
|
||||
@ -665,8 +665,9 @@ void git_note_free(git_note *note)
|
||||
}
|
||||
|
||||
static int process_entry_path(
|
||||
const char *entry_path,
|
||||
git_oid *annotated_object_id)
|
||||
git_oid *annotated_object_id,
|
||||
git_note_iterator *it,
|
||||
const char *entry_path)
|
||||
{
|
||||
int error = 0;
|
||||
size_t i = 0, j = 0, len;
|
||||
@ -698,12 +699,12 @@ static int process_entry_path(
|
||||
buf.ptr[j] = '\0';
|
||||
buf.size = j;
|
||||
|
||||
if (j != GIT_OID_SHA1_HEXSIZE) {
|
||||
if (j != git_oid_hexsize(it->repo->oid_type)) {
|
||||
/* This is not a note entry */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = git_oid__fromstr(annotated_object_id, buf.ptr, GIT_OID_SHA1);
|
||||
error = git_oid__fromstr(annotated_object_id, buf.ptr, it->repo->oid_type);
|
||||
|
||||
cleanup:
|
||||
git_str_dispose(&buf);
|
||||
@ -799,7 +800,7 @@ int git_note_next(
|
||||
|
||||
git_oid_cpy(note_id, &item->id);
|
||||
|
||||
if ((error = process_entry_path(item->path, annotated_id)) < 0)
|
||||
if ((error = process_entry_path(annotated_id, it, item->path)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = git_iterator_advance(NULL, it)) < 0 && error != GIT_ITEROVER)
|
||||
|
@ -108,15 +108,13 @@ int git_object__from_raw(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_object__from_odb_object(
|
||||
int git_object__init_from_odb_object(
|
||||
git_object **object_out,
|
||||
git_repository *repo,
|
||||
git_odb_object *odb_obj,
|
||||
git_object_t type)
|
||||
{
|
||||
int error;
|
||||
size_t object_size;
|
||||
git_object_def *def;
|
||||
git_object *object = NULL;
|
||||
|
||||
GIT_ASSERT_ARG(object_out);
|
||||
@ -143,6 +141,23 @@ int git_object__from_odb_object(
|
||||
object->cached.size = odb_obj->cached.size;
|
||||
object->repo = repo;
|
||||
|
||||
*object_out = object;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_object__from_odb_object(
|
||||
git_object **object_out,
|
||||
git_repository *repo,
|
||||
git_odb_object *odb_obj,
|
||||
git_object_t type)
|
||||
{
|
||||
int error;
|
||||
git_object_def *def;
|
||||
git_object *object = NULL;
|
||||
|
||||
if ((error = git_object__init_from_odb_object(&object, repo, odb_obj, type)) < 0)
|
||||
return error;
|
||||
|
||||
/* Parse raw object data */
|
||||
def = &git_objects_table[odb_obj->cached.type];
|
||||
GIT_ASSERT(def->free && def->parse);
|
||||
@ -181,6 +196,7 @@ int git_object_lookup_prefix(
|
||||
git_object *object = NULL;
|
||||
git_odb *odb = NULL;
|
||||
git_odb_object *odb_obj = NULL;
|
||||
size_t oid_hexsize;
|
||||
int error = 0;
|
||||
|
||||
GIT_ASSERT_ARG(repo);
|
||||
@ -196,10 +212,12 @@ int git_object_lookup_prefix(
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (len > GIT_OID_SHA1_HEXSIZE)
|
||||
len = GIT_OID_SHA1_HEXSIZE;
|
||||
oid_hexsize = git_oid_hexsize(repo->oid_type);
|
||||
|
||||
if (len == GIT_OID_SHA1_HEXSIZE) {
|
||||
if (len > oid_hexsize)
|
||||
len = oid_hexsize;
|
||||
|
||||
if (len == oid_hexsize) {
|
||||
git_cached_obj *cached = NULL;
|
||||
|
||||
/* We want to match the full id : we can first look up in the cache,
|
||||
@ -233,8 +251,9 @@ int git_object_lookup_prefix(
|
||||
error = git_odb_read(&odb_obj, odb, id);
|
||||
}
|
||||
} else {
|
||||
git_oid short_oid = GIT_OID_SHA1_ZERO;
|
||||
git_oid short_oid;
|
||||
|
||||
git_oid_clear(&short_oid, repo->oid_type);
|
||||
git_oid__cpy_prefix(&short_oid, id, len);
|
||||
|
||||
/* If len < GIT_OID_SHA1_HEXSIZE (a strict short oid was given), we have
|
||||
@ -262,7 +281,8 @@ int git_object_lookup_prefix(
|
||||
}
|
||||
|
||||
int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_object_t type) {
|
||||
return git_object_lookup_prefix(object_out, repo, id, GIT_OID_SHA1_HEXSIZE, type);
|
||||
return git_object_lookup_prefix(object_out,
|
||||
repo, id, git_oid_hexsize(repo->oid_type), type);
|
||||
}
|
||||
|
||||
void git_object_free(git_object *object)
|
||||
@ -503,31 +523,36 @@ cleanup:
|
||||
static int git_object__short_id(git_str *out, const git_object *obj)
|
||||
{
|
||||
git_repository *repo;
|
||||
int len = GIT_ABBREV_DEFAULT, error;
|
||||
git_oid id = GIT_OID_SHA1_ZERO;
|
||||
git_oid id;
|
||||
git_odb *odb;
|
||||
size_t oid_hexsize;
|
||||
int len = GIT_ABBREV_DEFAULT, error;
|
||||
|
||||
GIT_ASSERT_ARG(out);
|
||||
GIT_ASSERT_ARG(obj);
|
||||
|
||||
repo = git_object_owner(obj);
|
||||
|
||||
git_oid_clear(&id, repo->oid_type);
|
||||
oid_hexsize = git_oid_hexsize(repo->oid_type);
|
||||
|
||||
if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0)
|
||||
return error;
|
||||
|
||||
if (len < 0 || (size_t)len > oid_hexsize) {
|
||||
git_error_set(GIT_ERROR_CONFIG, "invalid oid abbreviation setting: '%d'", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((error = git_repository_odb(&odb, repo)) < 0)
|
||||
return error;
|
||||
|
||||
while (len < GIT_OID_SHA1_HEXSIZE) {
|
||||
while ((size_t)len < oid_hexsize) {
|
||||
/* set up short oid */
|
||||
memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2);
|
||||
if (len & 1)
|
||||
id.id[len / 2] &= 0xf0;
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
id.type = GIT_OID_SHA1;
|
||||
#endif
|
||||
|
||||
error = git_odb_exists_prefix(NULL, odb, &id, len);
|
||||
if (error != GIT_EAMBIGUOUS)
|
||||
break;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user