mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-21 12:24:58 +00:00
Update upstream source from tag 'upstream/0.27.0+dfsg.1'
Update to upstream version '0.27.0+dfsg.1'
with Debian dir 5579c7c802
This commit is contained in:
commit
9fd6a8dfbe
34
.travis.yml
34
.travis.yml
@ -17,19 +17,27 @@ env:
|
|||||||
- secure: "YnhS+8n6B+uoyaYfaJ3Lei7cSJqHDPiKJCKFIF2c87YDfmCvAJke8QtE7IzjYDs7UFkTCM4ox+ph2bERUrxZbSCyEkHdjIZpKuMJfYWja/jgMqTMxdyOH9y8JLFbZsSXDIXDwqBlC6vVyl1fP90M35wuWcNTs6tctfVWVofEFbs="
|
- secure: "YnhS+8n6B+uoyaYfaJ3Lei7cSJqHDPiKJCKFIF2c87YDfmCvAJke8QtE7IzjYDs7UFkTCM4ox+ph2bERUrxZbSCyEkHdjIZpKuMJfYWja/jgMqTMxdyOH9y8JLFbZsSXDIXDwqBlC6vVyl1fP90M35wuWcNTs6tctfVWVofEFbs="
|
||||||
- GITTEST_INVASIVE_FS_SIZE=1
|
- GITTEST_INVASIVE_FS_SIZE=1
|
||||||
matrix:
|
matrix:
|
||||||
- OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release"
|
- OPTIONS="-DTHREADSAFE=ON -DENABLE_TRACE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_WERROR=ON"
|
||||||
- OPTIONS="-DTHREADSAFE=OFF -DBUILD_EXAMPLES=ON"
|
- OPTIONS="-DTHREADSAFE=OFF -DBUILD_EXAMPLES=ON -DENABLE_WERROR=ON"
|
||||||
|
|
||||||
|
dist: trusty
|
||||||
|
sudo: false
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
sources:
|
||||||
- cmake
|
- sourceline: 'deb https://dl.bintray.com/libgit2/ci-dependencies trusty libgit2deps'
|
||||||
- libssh2-1-dev
|
key_url: 'https://bintray.com/user/downloadSubjectPublicKey?username=bintray'
|
||||||
- openssh-client
|
packages:
|
||||||
- openssh-server
|
cmake
|
||||||
- valgrind
|
curl
|
||||||
|
libcurl3
|
||||||
sudo: false
|
libcurl3-gnutls
|
||||||
|
libcurl4-gnutls-dev
|
||||||
|
libssh2-1-dev
|
||||||
|
openssh-client
|
||||||
|
openssh-server
|
||||||
|
valgrind
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
@ -40,16 +48,18 @@ matrix:
|
|||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
env: COVERITY=1
|
env: COVERITY=1
|
||||||
os: linux
|
os: linux
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
env:
|
env:
|
||||||
- VALGRIND=1
|
- VALGRIND=1
|
||||||
OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=OFF -DDEBUG_POOL=ON -DCMAKE_BUILD_TYPE=Debug"
|
OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=OFF -DDEBUG_POOL=ON -DCMAKE_BUILD_TYPE=Debug"
|
||||||
os: linux
|
os: linux
|
||||||
|
dist: trusty
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- env: COVERITY=1
|
- env: COVERITY=1
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./script/install-deps-${TRAVIS_OS_NAME}.sh; fi
|
- if [ -f ./script/install-deps-${TRAVIS_OS_NAME}.sh ]; then ./script/install-deps-${TRAVIS_OS_NAME}.sh; fi
|
||||||
|
|
||||||
# Run the Build script and tests
|
# Run the Build script and tests
|
||||||
script:
|
script:
|
||||||
|
1
AUTHORS
1
AUTHORS
@ -22,6 +22,7 @@ Dmitry Kakurin
|
|||||||
Dmitry Kovega
|
Dmitry Kovega
|
||||||
Emeric Fermas
|
Emeric Fermas
|
||||||
Emmanuel Rodriguez
|
Emmanuel Rodriguez
|
||||||
|
Eric Myhre
|
||||||
Florian Forster
|
Florian Forster
|
||||||
Holger Weiss
|
Holger Weiss
|
||||||
Ingmar Vanhassel
|
Ingmar Vanhassel
|
||||||
|
118
CHANGELOG.md
118
CHANGELOG.md
@ -1,4 +1,4 @@
|
|||||||
v0.26 + 1
|
v0.27 + 1
|
||||||
---------
|
---------
|
||||||
|
|
||||||
### Changes or improvements
|
### Changes or improvements
|
||||||
@ -9,6 +9,122 @@ v0.26 + 1
|
|||||||
|
|
||||||
### Breaking API changes
|
### Breaking API changes
|
||||||
|
|
||||||
|
v0.27
|
||||||
|
---------
|
||||||
|
|
||||||
|
### Changes or improvements
|
||||||
|
|
||||||
|
* Improved `p_unlink` in `posix_w32.c` to try and make a file writable
|
||||||
|
before sleeping in the retry loop to prevent unnecessary calls to sleep.
|
||||||
|
|
||||||
|
* The CMake build infrastructure has been improved to speed up building time.
|
||||||
|
|
||||||
|
* A new CMake option "-DUSE_HTTPS=<backend>" makes it possible to explicitly
|
||||||
|
choose an HTTP backend.
|
||||||
|
|
||||||
|
* A new CMake option "-DSHA1_BACKEND=<backend>" makes it possible to explicitly
|
||||||
|
choose an SHA1 backend. The collision-detecting backend is now the default.
|
||||||
|
|
||||||
|
* A new CMake option "-DUSE_BUNDLED_ZLIB" makes it possible to explicitly use
|
||||||
|
the bundled zlib library.
|
||||||
|
|
||||||
|
* A new CMake option "-DENABLE_REPRODUCIBLE_BUILDS" makes it possible to
|
||||||
|
generate a reproducible static archive. This requires support from your
|
||||||
|
toolchain.
|
||||||
|
|
||||||
|
* The minimum required CMake version has been bumped to 2.8.11.
|
||||||
|
|
||||||
|
* Writing to a configuration file now preserves the case of the key given by the
|
||||||
|
caller for the case-insensitive portions of the key (existing sections are
|
||||||
|
used even if they don't match).
|
||||||
|
|
||||||
|
* We now support conditional includes in configuration files.
|
||||||
|
|
||||||
|
* Fix for handling re-reading of configuration files with includes.
|
||||||
|
|
||||||
|
* Fix for reading patches which contain exact renames only.
|
||||||
|
|
||||||
|
* Fix for reading patches with whitespace in the compared files' paths.
|
||||||
|
|
||||||
|
* We will now fill `FETCH_HEAD` from all passed refspecs instead of overwriting
|
||||||
|
with the last one.
|
||||||
|
|
||||||
|
* There is a new diff option, `GIT_DIFF_INDENT_HEURISTIC` which activates a
|
||||||
|
heuristic which takes into account whitespace and indentation in order to
|
||||||
|
produce better diffs when dealing with ambiguous diff hunks.
|
||||||
|
|
||||||
|
* Fix for pattern-based ignore rules where files ignored by a rule cannot be
|
||||||
|
un-ignored by another rule.
|
||||||
|
|
||||||
|
* Sockets opened by libgit2 are now being closed on exec(3) if the platform
|
||||||
|
supports it.
|
||||||
|
|
||||||
|
* Fix for peeling annotated tags from packed-refs files.
|
||||||
|
|
||||||
|
* Fix reading huge loose objects from the object database.
|
||||||
|
|
||||||
|
* Fix files not being treated as modified when only the file mode has changed.
|
||||||
|
|
||||||
|
* We now explicitly reject adding submodules to the index via
|
||||||
|
`git_index_add_frombuffer`.
|
||||||
|
|
||||||
|
* Fix handling of `GIT_DIFF_FIND_RENAMES_FROM_REWRITES` raising `SIGABRT` when
|
||||||
|
one file has been deleted and another file has been rewritten.
|
||||||
|
|
||||||
|
* Fix for WinHTTP not properly handling NTLM and Negotiate challenges.
|
||||||
|
|
||||||
|
* When using SSH-based transports, we now repeatedly ask for the passphrase to
|
||||||
|
decrypt the private key in case a wrong passphrase is being provided.
|
||||||
|
|
||||||
|
* When generating conflict markers, they will now use the same line endings as
|
||||||
|
the rest of the file.
|
||||||
|
|
||||||
|
### API additions
|
||||||
|
|
||||||
|
* The `git_merge_file_options` structure now contains a new setting,
|
||||||
|
`marker_size`. This allows users to set the size of markers that
|
||||||
|
delineate the sides of merged files in the output conflict file.
|
||||||
|
By default this is 7 (`GIT_MERGE_CONFLICT_MARKER_SIZE`), which
|
||||||
|
produces output markers like `<<<<<<<` and `>>>>>>>`.
|
||||||
|
|
||||||
|
* `git_remote_create_detached()` creates a remote that is not associated
|
||||||
|
to any repository (and does not apply configuration like 'insteadof' rules).
|
||||||
|
This is mostly useful for e.g. emulating `git ls-remote` behavior.
|
||||||
|
|
||||||
|
* `git_diff_patchid()` lets you generate patch IDs for diffs.
|
||||||
|
|
||||||
|
* `git_status_options` now has an additional field `baseline` to allow creating
|
||||||
|
status lists against different trees.
|
||||||
|
|
||||||
|
* New family of functions to allow creating notes for a specific notes commit
|
||||||
|
instead of for a notes reference.
|
||||||
|
|
||||||
|
* New family of functions to allow parsing message trailers. This API is still
|
||||||
|
experimental and may change in future releases.
|
||||||
|
|
||||||
|
### API removals
|
||||||
|
|
||||||
|
### Breaking API changes
|
||||||
|
|
||||||
|
* Signatures now distinguish between +0000 and -0000 UTC offsets.
|
||||||
|
|
||||||
|
* The certificate check callback in the WinHTTP transport will now receive the
|
||||||
|
`message_cb_payload` instead of the `cred_acquire_payload`.
|
||||||
|
|
||||||
|
* We are now reading symlinked directories under .git/refs.
|
||||||
|
|
||||||
|
* We now refuse creating branches named "HEAD".
|
||||||
|
|
||||||
|
* We now refuse reading and writing all-zero object IDs into the
|
||||||
|
object database.
|
||||||
|
|
||||||
|
* We now read the effective user's configuration file instead of the real user's
|
||||||
|
configuration in case libgit2 runs as part of a setuid binary.
|
||||||
|
|
||||||
|
* The `git_odb_open_rstream` function and its `readstream` callback in the
|
||||||
|
`git_odb_backend` interface have changed their signatures to allow providing
|
||||||
|
the object's size and type to the caller.
|
||||||
|
|
||||||
v0.26
|
v0.26
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
575
CMakeLists.txt
575
CMakeLists.txt
@ -12,11 +12,17 @@
|
|||||||
# > cmake --build . --target install
|
# > cmake --build . --target install
|
||||||
|
|
||||||
PROJECT(libgit2 C)
|
PROJECT(libgit2 C)
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11)
|
||||||
CMAKE_POLICY(SET CMP0015 NEW)
|
CMAKE_POLICY(SET CMP0015 NEW)
|
||||||
|
IF (POLICY CMP0051)
|
||||||
|
CMAKE_POLICY(SET CMP0051 NEW)
|
||||||
|
ENDIF()
|
||||||
|
IF (POLICY CMP0042)
|
||||||
|
CMAKE_POLICY(SET CMP0042 NEW)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# Add find modules to the path
|
# Add find modules to the path
|
||||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake/Modules/")
|
||||||
|
|
||||||
INCLUDE(CheckLibraryExists)
|
INCLUDE(CheckLibraryExists)
|
||||||
INCLUDE(CheckFunctionExists)
|
INCLUDE(CheckFunctionExists)
|
||||||
@ -24,6 +30,11 @@ INCLUDE(CheckSymbolExists)
|
|||||||
INCLUDE(CheckStructHasMember)
|
INCLUDE(CheckStructHasMember)
|
||||||
INCLUDE(AddCFlagIfSupported)
|
INCLUDE(AddCFlagIfSupported)
|
||||||
INCLUDE(FindPkgConfig)
|
INCLUDE(FindPkgConfig)
|
||||||
|
INCLUDE(FindThreads)
|
||||||
|
INCLUDE(FindStatNsec)
|
||||||
|
INCLUDE(IdeSplitSources)
|
||||||
|
INCLUDE(FeatureSummary)
|
||||||
|
INCLUDE(EnableWarnings)
|
||||||
|
|
||||||
# Build options
|
# Build options
|
||||||
#
|
#
|
||||||
@ -37,22 +48,23 @@ OPTION( PROFILE "Generate profiling information" OFF )
|
|||||||
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
|
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
|
||||||
OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF )
|
OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF )
|
||||||
|
|
||||||
OPTION( USE_SHA1DC "Use SHA-1 with collision detection" OFF )
|
SET(SHA1_BACKEND "CollisionDetection" CACHE STRING "Backend to use for SHA1. One of Generic, OpenSSL, Win32, CommonCrypto, CollisionDetection. ")
|
||||||
OPTION( USE_ICONV "Link with and use iconv library" OFF )
|
|
||||||
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
|
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
|
||||||
|
OPTION( USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON )
|
||||||
OPTION( USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF )
|
OPTION( USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF )
|
||||||
OPTION( VALGRIND "Configure build for valgrind" OFF )
|
OPTION( VALGRIND "Configure build for valgrind" OFF )
|
||||||
OPTION( CURL "Use curl for HTTP if available" ON)
|
OPTION( CURL "Use curl for HTTP if available" ON)
|
||||||
|
OPTION( USE_EXT_HTTP_PARSER "Use system HTTP_Parser if available" ON)
|
||||||
OPTION( DEBUG_POOL "Enable debug pool allocator" OFF )
|
OPTION( DEBUG_POOL "Enable debug pool allocator" OFF )
|
||||||
|
OPTION( ENABLE_WERROR "Enable compilation with -Werror" OFF )
|
||||||
|
OPTION( USE_BUNDLED_ZLIB "Use the bundled version of zlib" OFF )
|
||||||
|
|
||||||
IF(DEBUG_POOL)
|
IF (UNIX AND NOT APPLE)
|
||||||
ADD_DEFINITIONS(-DGIT_DEBUG_POOL)
|
OPTION( ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
IF (APPLE)
|
||||||
SET( USE_ICONV ON )
|
OPTION( USE_ICONV "Link with and use iconv library" ON )
|
||||||
FIND_PACKAGE(Security)
|
|
||||||
FIND_PACKAGE(CoreFoundation REQUIRED)
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
@ -71,10 +83,6 @@ IF(MSVC)
|
|||||||
# If you want to embed a copy of libssh2 into libgit2, pass a
|
# If you want to embed a copy of libssh2 into libgit2, pass a
|
||||||
# path to libssh2
|
# path to libssh2
|
||||||
OPTION( EMBED_SSH_PATH "Path to libssh2 to embed (Windows)" OFF )
|
OPTION( EMBED_SSH_PATH "Path to libssh2 to embed (Windows)" OFF )
|
||||||
|
|
||||||
ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS)
|
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
|
|
||||||
ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE)
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
@ -89,313 +97,21 @@ IF(MSVC)
|
|||||||
OPTION(MSVC_CRTDBG "Enable CRTDBG memory leak reporting" OFF)
|
OPTION(MSVC_CRTDBG "Enable CRTDBG memory leak reporting" OFF)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
FILE(STRINGS "${libgit2_SOURCE_DIR}/include/git2/version.h" GIT2_HEADER REGEX "^#define LIBGIT2_VERSION \"[^\"]*\"$")
|
||||||
OPTION( USE_OPENSSL "Link with and use openssl library" ON )
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtim "sys/types.h;sys/stat.h"
|
|
||||||
HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C)
|
|
||||||
CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtimespec "sys/types.h;sys/stat.h"
|
|
||||||
HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE C)
|
|
||||||
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtime_nsec sys/stat.h
|
|
||||||
HAVE_STRUCT_STAT_MTIME_NSEC LANGUAGE C)
|
|
||||||
|
|
||||||
IF (HAVE_STRUCT_STAT_ST_MTIM)
|
|
||||||
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h
|
|
||||||
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
|
|
||||||
ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
|
||||||
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec sys/stat.h
|
|
||||||
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
|
|
||||||
ELSE ()
|
|
||||||
SET( HAVE_STRUCT_STAT_NSEC ON )
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (HAVE_STRUCT_STAT_NSEC OR WIN32)
|
|
||||||
OPTION( USE_NSEC "Care about sub-second file mtimes and ctimes" ON )
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# This variable will contain the libraries we need to put into
|
|
||||||
# libgit2.pc's Requires.private. That is, what we're linking to or
|
|
||||||
# what someone who's statically linking us needs to link to.
|
|
||||||
SET(LIBGIT2_PC_REQUIRES "")
|
|
||||||
# This will be set later if we use the system's http-parser library or
|
|
||||||
# use iconv (OSX) and will be written to the Libs.private field in the
|
|
||||||
# pc file.
|
|
||||||
SET(LIBGIT2_PC_LIBS "")
|
|
||||||
|
|
||||||
# Installation paths
|
|
||||||
#
|
|
||||||
SET(BIN_INSTALL_DIR bin CACHE PATH "Where to install binaries to.")
|
|
||||||
SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.")
|
|
||||||
SET(INCLUDE_INSTALL_DIR include CACHE PATH "Where to install headers to.")
|
|
||||||
|
|
||||||
# Set a couple variables to be substituted inside the .pc file.
|
|
||||||
# We can't just use LIB_INSTALL_DIR in the .pc file, as passing them as absolue
|
|
||||||
# or relative paths is both valid and supported by cmake.
|
|
||||||
SET (PKGCONFIG_PREFIX ${CMAKE_INSTALL_PREFIX})
|
|
||||||
|
|
||||||
IF(IS_ABSOLUTE ${LIB_INSTALL_DIR})
|
|
||||||
SET (PKGCONFIG_LIBDIR ${LIB_INSTALL_DIR})
|
|
||||||
ELSE(IS_ABSOLUTE ${LIB_INSTALL_DIR})
|
|
||||||
SET (PKGCONFIG_LIBDIR "\${prefix}/${LIB_INSTALL_DIR}")
|
|
||||||
ENDIF (IS_ABSOLUTE ${LIB_INSTALL_DIR})
|
|
||||||
|
|
||||||
IF(IS_ABSOLUTE ${INCLUDE_INSTALL_DIR})
|
|
||||||
SET (PKGCONFIG_INCLUDEDIR ${INCLUDE_INSTALL_DIR})
|
|
||||||
ELSE(IS_ABSOLUTE ${INCLUDE_INSTALL_DIR})
|
|
||||||
SET (PKGCONFIG_INCLUDEDIR "\${prefix}/${INCLUDE_INSTALL_DIR}")
|
|
||||||
ENDIF(IS_ABSOLUTE ${INCLUDE_INSTALL_DIR})
|
|
||||||
|
|
||||||
FUNCTION(TARGET_OS_LIBRARIES target)
|
|
||||||
IF(WIN32)
|
|
||||||
TARGET_LINK_LIBRARIES(${target} ws2_32)
|
|
||||||
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
|
||||||
TARGET_LINK_LIBRARIES(${target} socket nsl)
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl")
|
|
||||||
SET(LIBGIT2_PC_LIBS ${LIBGIT2_PC_LIBS} PARENT_SCOPE)
|
|
||||||
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Haiku")
|
|
||||||
TARGET_LINK_LIBRARIES(${target} network)
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lnetwork")
|
|
||||||
SET(LIBGIT2_PC_LIBS ${LIBGIT2_PC_LIBS} PARENT_SCOPE)
|
|
||||||
ENDIF()
|
|
||||||
CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" NEED_LIBRT)
|
|
||||||
IF(NEED_LIBRT)
|
|
||||||
TARGET_LINK_LIBRARIES(${target} rt)
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lrt")
|
|
||||||
SET(LIBGIT2_PC_LIBS ${LIBGIT2_PC_LIBS} PARENT_SCOPE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(THREADSAFE)
|
|
||||||
TARGET_LINK_LIBRARIES(${target} ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
SET(LIBGIT2_PC_LIBS ${LIBGIT2_PC_LIBS} PARENT_SCOPE)
|
|
||||||
ENDIF()
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
# This function splits the sources files up into their appropriate
|
|
||||||
# subdirectories. This is especially useful for IDEs like Xcode and
|
|
||||||
# Visual Studio, so that you can navigate into the libgit2_clar project,
|
|
||||||
# and see the folders within the tests folder (instead of just seeing all
|
|
||||||
# source and tests in a single folder.)
|
|
||||||
FUNCTION(IDE_SPLIT_SOURCES target)
|
|
||||||
IF(MSVC_IDE OR CMAKE_GENERATOR STREQUAL Xcode)
|
|
||||||
GET_TARGET_PROPERTY(sources ${target} SOURCES)
|
|
||||||
FOREACH(source ${sources})
|
|
||||||
IF(source MATCHES ".*/")
|
|
||||||
STRING(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/ "" rel ${source})
|
|
||||||
IF(rel)
|
|
||||||
STRING(REGEX REPLACE "/([^/]*)$" "" rel ${rel})
|
|
||||||
IF(rel)
|
|
||||||
STRING(REPLACE "/" "\\\\" rel ${rel})
|
|
||||||
SOURCE_GROUP(${rel} FILES ${source})
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
ENDFOREACH()
|
|
||||||
ENDIF()
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
FILE(STRINGS "include/git2/version.h" GIT2_HEADER REGEX "^#define LIBGIT2_VERSION \"[^\"]*\"$")
|
|
||||||
|
|
||||||
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"([0-9]+).*$" "\\1" LIBGIT2_VERSION_MAJOR "${GIT2_HEADER}")
|
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"([0-9]+).*$" "\\1" LIBGIT2_VERSION_MAJOR "${GIT2_HEADER}")
|
||||||
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_MINOR "${GIT2_HEADER}")
|
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_MINOR "${GIT2_HEADER}")
|
||||||
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}")
|
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}")
|
||||||
SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
|
SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
|
||||||
|
|
||||||
FILE(STRINGS "include/git2/version.h" GIT2_HEADER_SOVERSION REGEX "^#define LIBGIT2_SOVERSION [0-9]+$")
|
FILE(STRINGS "${libgit2_SOURCE_DIR}/include/git2/version.h" GIT2_HEADER_SOVERSION REGEX "^#define LIBGIT2_SOVERSION [0-9]+$")
|
||||||
STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION ([0-9]+)$" "\\1" LIBGIT2_SOVERSION "${GIT2_HEADER_SOVERSION}")
|
STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION ([0-9]+)$" "\\1" LIBGIT2_SOVERSION "${GIT2_HEADER_SOVERSION}")
|
||||||
|
|
||||||
# Find required dependencies
|
|
||||||
INCLUDE_DIRECTORIES(src include)
|
|
||||||
|
|
||||||
IF (SECURITY_FOUND)
|
|
||||||
# OS X 10.7 and older do not have some functions we use, fall back to OpenSSL there
|
|
||||||
CHECK_LIBRARY_EXISTS("${SECURITY_DIRS}" SSLCreateContext "Security/SecureTransport.h" HAVE_NEWER_SECURITY)
|
|
||||||
IF (HAVE_NEWER_SECURITY)
|
|
||||||
MESSAGE("-- Found Security ${SECURITY_DIRS}")
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-framework Security")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE("-- Security framework is too old, falling back to OpenSSL")
|
|
||||||
SET(SECURITY_FOUND "NO")
|
|
||||||
SET(SECURITY_DIRS "")
|
|
||||||
SET(SECURITY_DIR "")
|
|
||||||
SET(USE_OPENSSL "ON")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (COREFOUNDATION_FOUND)
|
|
||||||
MESSAGE("-- Found CoreFoundation ${COREFOUNDATION_DIRS}")
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-framework CoreFoundation")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
|
|
||||||
IF (WIN32 AND EMBED_SSH_PATH)
|
|
||||||
FILE(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c")
|
|
||||||
INCLUDE_DIRECTORIES("${EMBED_SSH_PATH}/include")
|
|
||||||
FILE(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"")
|
|
||||||
ADD_DEFINITIONS(-DGIT_SSH)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (WIN32 AND WINHTTP)
|
|
||||||
ADD_DEFINITIONS(-DGIT_WINHTTP)
|
|
||||||
ADD_DEFINITIONS(-DGIT_HTTPS)
|
|
||||||
|
|
||||||
# Since MinGW does not come with headers or an import library for winhttp,
|
|
||||||
# we have to include a private header and generate our own import library
|
|
||||||
IF (MINGW)
|
|
||||||
FIND_PROGRAM(DLLTOOL dlltool CMAKE_FIND_ROOT_PATH_BOTH)
|
|
||||||
IF (NOT DLLTOOL)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find dlltool command")
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
SET(LIBWINHTTP_PATH "${CMAKE_CURRENT_BINARY_DIR}/deps/winhttp")
|
|
||||||
FILE(MAKE_DIRECTORY ${LIBWINHTTP_PATH})
|
|
||||||
|
|
||||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(WINHTTP_DEF "${CMAKE_CURRENT_SOURCE_DIR}/deps/winhttp/winhttp64.def")
|
|
||||||
ELSE()
|
|
||||||
set(WINHTTP_DEF "${CMAKE_CURRENT_SOURCE_DIR}/deps/winhttp/winhttp.def")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ${LIBWINHTTP_PATH}/libwinhttp.a
|
|
||||||
COMMAND ${DLLTOOL} -d ${WINHTTP_DEF} -k -D winhttp.dll -l libwinhttp.a
|
|
||||||
DEPENDS ${WINHTTP_DEF}
|
|
||||||
WORKING_DIRECTORY ${LIBWINHTTP_PATH}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_SOURCE_FILES_PROPERTIES(
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/transports/winhttp.c
|
|
||||||
PROPERTIES OBJECT_DEPENDS ${LIBWINHTTP_PATH}/libwinhttp.a
|
|
||||||
)
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(deps/winhttp)
|
|
||||||
LINK_DIRECTORIES(${LIBWINHTTP_PATH})
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
LINK_LIBRARIES(winhttp rpcrt4 crypt32 ole32)
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lwinhttp" "-lrpcrt4" "-lcrypt32" "-lole32")
|
|
||||||
ELSE ()
|
|
||||||
IF (CURL)
|
|
||||||
PKG_CHECK_MODULES(CURL libcurl)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
IF (NOT AMIGA AND USE_OPENSSL)
|
|
||||||
FIND_PACKAGE(OpenSSL)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
IF (CURL_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DGIT_CURL)
|
|
||||||
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${CURL_LIBRARY_DIRS})
|
|
||||||
LINK_LIBRARIES(${CURL_LIBRARIES})
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Specify sha1 implementation
|
|
||||||
IF (USE_SHA1DC)
|
|
||||||
ADD_DEFINITIONS(-DGIT_SHA1_COLLISIONDETECT)
|
|
||||||
ADD_DEFINITIONS(-DSHA1DC_NO_STANDARD_INCLUDES=1)
|
|
||||||
ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\")
|
|
||||||
ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\")
|
|
||||||
FILE(GLOB SRC_SHA1 src/hash/hash_collisiondetect.c src/hash/sha1dc/*)
|
|
||||||
ELSEIF (WIN32 AND NOT MINGW)
|
|
||||||
ADD_DEFINITIONS(-DGIT_SHA1_WIN32)
|
|
||||||
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
|
|
||||||
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|
||||||
ADD_DEFINITIONS(-DGIT_SHA1_COMMON_CRYPTO)
|
|
||||||
ELSEIF (OPENSSL_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DGIT_SHA1_OPENSSL)
|
|
||||||
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lssl")
|
|
||||||
ELSE()
|
|
||||||
SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} openssl")
|
|
||||||
ENDIF ()
|
|
||||||
ELSE()
|
|
||||||
FILE(GLOB SRC_SHA1 src/hash/hash_generic.c)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Enable tracing
|
|
||||||
IF (ENABLE_TRACE STREQUAL "ON")
|
|
||||||
ADD_DEFINITIONS(-DGIT_TRACE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Include POSIX regex when it is required
|
|
||||||
IF(WIN32 OR AMIGA OR CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
|
||||||
INCLUDE_DIRECTORIES(deps/regex)
|
|
||||||
SET(SRC_REGEX deps/regex/regex.c)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Optional external dependency: http-parser
|
|
||||||
FIND_PACKAGE(HTTP_Parser)
|
|
||||||
IF (HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
|
|
||||||
INCLUDE_DIRECTORIES(${HTTP_PARSER_INCLUDE_DIRS})
|
|
||||||
LINK_LIBRARIES(${HTTP_PARSER_LIBRARIES})
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lhttp_parser")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "http-parser version 2 was not found; using bundled 3rd-party sources.")
|
|
||||||
INCLUDE_DIRECTORIES(deps/http-parser)
|
|
||||||
FILE(GLOB SRC_HTTP deps/http-parser/*.c deps/http-parser/*.h)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Optional external dependency: zlib
|
|
||||||
FIND_PACKAGE(ZLIB)
|
|
||||||
IF (ZLIB_FOUND)
|
|
||||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
|
|
||||||
LINK_LIBRARIES(${ZLIB_LIBRARIES})
|
|
||||||
IF(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS "-lz")
|
|
||||||
ELSE()
|
|
||||||
SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} zlib")
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." )
|
|
||||||
INCLUDE_DIRECTORIES(deps/zlib)
|
|
||||||
ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP)
|
|
||||||
FILE(GLOB SRC_ZLIB deps/zlib/*.c deps/zlib/*.h)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Optional external dependency: libssh2
|
|
||||||
IF (USE_SSH)
|
|
||||||
PKG_CHECK_MODULES(LIBSSH2 libssh2)
|
|
||||||
ENDIF()
|
|
||||||
IF (LIBSSH2_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DGIT_SSH)
|
|
||||||
INCLUDE_DIRECTORIES(${LIBSSH2_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${LIBSSH2_LIBRARY_DIRS})
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
|
|
||||||
#SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
|
|
||||||
SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES})
|
|
||||||
|
|
||||||
CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
|
|
||||||
IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
|
|
||||||
ADD_DEFINITIONS(-DGIT_SSH_MEMORY_CREDENTIALS)
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Optional external dependency: libgssapi
|
|
||||||
IF (USE_GSSAPI)
|
|
||||||
FIND_PACKAGE(GSSAPI)
|
|
||||||
ENDIF()
|
|
||||||
IF (GSSAPI_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DGIT_GSSAPI)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Optional external dependency: iconv
|
|
||||||
IF (USE_ICONV)
|
|
||||||
FIND_PACKAGE(Iconv)
|
|
||||||
ENDIF()
|
|
||||||
IF (ICONV_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DGIT_USE_ICONV)
|
|
||||||
INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
|
|
||||||
LIST(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES})
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Platform specific compilation flags
|
# Platform specific compilation flags
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
|
ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS)
|
||||||
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
|
||||||
|
ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
|
|
||||||
STRING(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
STRING(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||||
|
|
||||||
@ -417,8 +133,9 @@ IF (MSVC)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (MSVC_CRTDBG)
|
IF (MSVC_CRTDBG)
|
||||||
SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG} /DGIT_MSVC_CRTDBG")
|
SET(GIT_MSVC_CRTDBG 1)
|
||||||
SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}" "Dbghelp.lib")
|
SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}")
|
||||||
|
SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Dbghelp.lib")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# /Zi - Create debugging information
|
# /Zi - Create debugging information
|
||||||
@ -466,13 +183,17 @@ IF (MSVC)
|
|||||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
|
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}")
|
SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}")
|
||||||
|
|
||||||
SET(WIN_RC "src/win32/git2.rc")
|
|
||||||
ELSE ()
|
ELSE ()
|
||||||
|
IF (ENABLE_REPRODUCIBLE_BUILDS)
|
||||||
|
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Dqc <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
|
SET(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> Dq <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
|
SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -D <TARGET>")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}")
|
||||||
|
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wall)
|
ENABLE_WARNINGS(all)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wextra)
|
ENABLE_WARNINGS(extra)
|
||||||
|
|
||||||
IF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
IF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||||
SET(CMAKE_C_FLAGS "-std=c99 -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-std=c99 -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}")
|
||||||
@ -495,16 +216,17 @@ ELSE ()
|
|||||||
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO=1)
|
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO=1)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wdocumentation)
|
ENABLE_WARNINGS(documentation)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wno-missing-field-initializers)
|
DISABLE_WARNINGS(missing-field-initializers)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wstrict-aliasing=2)
|
ENABLE_WARNINGS(strict-aliasing)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wstrict-prototypes)
|
ENABLE_WARNINGS(strict-prototypes)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wdeclaration-after-statement)
|
ENABLE_WARNINGS(declaration-after-statement)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wno-unused-const-variable)
|
ENABLE_WARNINGS(shift-count-overflow)
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wno-unused-function)
|
DISABLE_WARNINGS(unused-const-variable)
|
||||||
|
DISABLE_WARNINGS(unused-function)
|
||||||
|
|
||||||
IF (APPLE) # Apple deprecated OpenSSL
|
IF (APPLE) # Apple deprecated OpenSSL
|
||||||
ADD_C_FLAG_IF_SUPPORTED(-Wno-deprecated-declarations)
|
DISABLE_WARNINGS(deprecated-declarations)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (PROFILE)
|
IF (PROFILE)
|
||||||
@ -513,26 +235,6 @@ ELSE ()
|
|||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
|
|
||||||
IF (HAVE_REGCOMP_L)
|
|
||||||
ADD_DEFINITIONS(-DHAVE_REGCOMP_L)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS)
|
|
||||||
IF (HAVE_FUTIMENS)
|
|
||||||
ADD_DEFINITIONS(-DHAVE_FUTIMENS)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS(qsort_r HAVE_QSORT_R)
|
|
||||||
IF (HAVE_QSORT_R)
|
|
||||||
ADD_DEFINITIONS(-DHAVE_QSORT_R)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS(qsort_s HAVE_QSORT_S)
|
|
||||||
IF (HAVE_QSORT_S)
|
|
||||||
ADD_DEFINITIONS(-DHAVE_QSORT_S)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
IF( NOT CMAKE_CONFIGURATION_TYPES )
|
IF( NOT CMAKE_CONFIGURATION_TYPES )
|
||||||
# Build Debug by default
|
# Build Debug by default
|
||||||
IF (NOT CMAKE_BUILD_TYPE)
|
IF (NOT CMAKE_BUILD_TYPE)
|
||||||
@ -543,177 +245,18 @@ ELSE()
|
|||||||
# that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE
|
# that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (SECURITY_FOUND)
|
ADD_SUBDIRECTORY(src)
|
||||||
ADD_DEFINITIONS(-DGIT_SECURE_TRANSPORT)
|
|
||||||
ADD_DEFINITIONS(-DGIT_HTTPS)
|
|
||||||
INCLUDE_DIRECTORIES(${SECURITY_INCLUDE_DIR})
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
IF (OPENSSL_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DGIT_OPENSSL)
|
|
||||||
ADD_DEFINITIONS(-DGIT_HTTPS)
|
|
||||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
|
||||||
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IF (THREADSAFE)
|
|
||||||
IF (NOT WIN32)
|
|
||||||
FIND_PACKAGE(Threads REQUIRED)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DGIT_THREADS)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (USE_NSEC)
|
|
||||||
ADD_DEFINITIONS(-DGIT_USE_NSEC)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (HAVE_STRUCT_STAT_ST_MTIM)
|
|
||||||
ADD_DEFINITIONS(-DGIT_USE_STAT_MTIM)
|
|
||||||
ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
|
||||||
ADD_DEFINITIONS(-DGIT_USE_STAT_MTIMESPEC)
|
|
||||||
ELSEIF (HAVE_STRUCT_STAT_ST_MTIME_NSEC)
|
|
||||||
ADD_DEFINITIONS(-DGIT_USE_STAT_MTIME_NSEC)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
|
|
||||||
|
|
||||||
# Collect sourcefiles
|
|
||||||
FILE(GLOB SRC_H include/git2.h include/git2/*.h include/git2/sys/*.h)
|
|
||||||
|
|
||||||
# On Windows use specific platform sources
|
|
||||||
IF (WIN32 AND NOT CYGWIN)
|
|
||||||
ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501)
|
|
||||||
FILE(GLOB SRC_OS src/win32/*.c src/win32/*.h)
|
|
||||||
ELSEIF (AMIGA)
|
|
||||||
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP)
|
|
||||||
ELSE()
|
|
||||||
IF (VALGRIND)
|
|
||||||
ADD_DEFINITIONS(-DNO_MMAP)
|
|
||||||
ENDIF()
|
|
||||||
FILE(GLOB SRC_OS src/unix/*.c src/unix/*.h)
|
|
||||||
ENDIF()
|
|
||||||
FILE(GLOB SRC_GIT2 src/*.c src/*.h src/transports/*.c src/transports/*.h src/xdiff/*.c src/xdiff/*.h)
|
|
||||||
|
|
||||||
# Determine architecture of the machine
|
|
||||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
ADD_DEFINITIONS(-DGIT_ARCH_64)
|
|
||||||
ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
|
||||||
ADD_DEFINITIONS(-DGIT_ARCH_32)
|
|
||||||
ELSEIF (CMAKE_SIZEOF_VOID_P)
|
|
||||||
MESSAGE(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Compile and link libgit2
|
|
||||||
ADD_LIBRARY(git2 ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SSH} ${SRC_SHA1} ${WIN_RC})
|
|
||||||
TARGET_LINK_LIBRARIES(git2 ${SECURITY_DIRS})
|
|
||||||
TARGET_LINK_LIBRARIES(git2 ${COREFOUNDATION_DIRS})
|
|
||||||
TARGET_LINK_LIBRARIES(git2 ${SSL_LIBRARIES})
|
|
||||||
TARGET_LINK_LIBRARIES(git2 ${SSH_LIBRARIES})
|
|
||||||
TARGET_LINK_LIBRARIES(git2 ${GSSAPI_LIBRARIES})
|
|
||||||
TARGET_LINK_LIBRARIES(git2 ${ICONV_LIBRARIES})
|
|
||||||
TARGET_OS_LIBRARIES(git2)
|
|
||||||
|
|
||||||
# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
|
|
||||||
# Win64+MSVC+static libs = linker error
|
|
||||||
IF(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS)
|
|
||||||
SET_TARGET_PROPERTIES(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IDE_SPLIT_SOURCES(git2)
|
|
||||||
|
|
||||||
IF (SONAME)
|
|
||||||
SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
|
|
||||||
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_SOVERSION})
|
|
||||||
IF (LIBGIT2_FILENAME)
|
|
||||||
ADD_DEFINITIONS(-DLIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\")
|
|
||||||
SET_TARGET_PROPERTIES(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME})
|
|
||||||
ELSEIF (DEFINED LIBGIT2_PREFIX)
|
|
||||||
SET_TARGET_PROPERTIES(git2 PROPERTIES PREFIX "${LIBGIT2_PREFIX}")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
STRING(REPLACE ";" " " LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS}")
|
|
||||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY)
|
|
||||||
|
|
||||||
IF (MSVC_IDE)
|
|
||||||
# Precompiled headers
|
|
||||||
SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
|
|
||||||
SET_SOURCE_FILES_PROPERTIES(src/win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h")
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
# Install
|
|
||||||
INSTALL(TARGETS git2
|
|
||||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
|
||||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
|
||||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
|
||||||
)
|
|
||||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
|
|
||||||
INSTALL(DIRECTORY include/git2 DESTINATION ${INCLUDE_INSTALL_DIR} )
|
|
||||||
INSTALL(FILES include/git2.h DESTINATION ${INCLUDE_INSTALL_DIR} )
|
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
|
IF (NOT MSVC)
|
||||||
|
IF (NOT BUILD_SHARED_LIBS)
|
||||||
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (BUILD_CLAR)
|
IF (BUILD_CLAR)
|
||||||
FIND_PACKAGE(PythonInterp)
|
|
||||||
|
|
||||||
IF(NOT PYTHONINTERP_FOUND)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. "
|
|
||||||
"Make sure python is available, or pass -DBUILD_CLAR=OFF to skip building the tests")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources/")
|
|
||||||
SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tests")
|
|
||||||
SET(CLAR_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources" CACHE PATH "Path to test resources.")
|
|
||||||
ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
|
|
||||||
ADD_DEFINITIONS(-DCLAR_RESOURCES=\"${TEST_RESOURCES}\")
|
|
||||||
ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\")
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CLAR_PATH})
|
|
||||||
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h)
|
|
||||||
SET(SRC_CLAR "${CLAR_PATH}/main.c" "${CLAR_PATH}/clar_libgit2.c" "${CLAR_PATH}/clar_libgit2_trace.c" "${CLAR_PATH}/clar_libgit2_timer.c" "${CLAR_PATH}/clar.c")
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
OUTPUT ${CLAR_PATH}/clar.suite
|
|
||||||
COMMAND ${PYTHON_EXECUTABLE} generate.py -f -xonline -xstress .
|
|
||||||
DEPENDS ${SRC_TEST}
|
|
||||||
WORKING_DIRECTORY ${CLAR_PATH}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_SOURCE_FILES_PROPERTIES(
|
|
||||||
${CLAR_PATH}/clar.c
|
|
||||||
PROPERTIES OBJECT_DEPENDS ${CLAR_PATH}/clar.suite)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(libgit2_clar ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_CLAR} ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SSH} ${SRC_SHA1})
|
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(libgit2_clar ${COREFOUNDATION_DIRS})
|
|
||||||
TARGET_LINK_LIBRARIES(libgit2_clar ${SECURITY_DIRS})
|
|
||||||
TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES})
|
|
||||||
TARGET_LINK_LIBRARIES(libgit2_clar ${SSH_LIBRARIES})
|
|
||||||
TARGET_LINK_LIBRARIES(libgit2_clar ${GSSAPI_LIBRARIES})
|
|
||||||
TARGET_LINK_LIBRARIES(libgit2_clar ${ICONV_LIBRARIES})
|
|
||||||
TARGET_OS_LIBRARIES(libgit2_clar)
|
|
||||||
IDE_SPLIT_SOURCES(libgit2_clar)
|
|
||||||
|
|
||||||
IF (MSVC_IDE)
|
|
||||||
# Precompiled headers
|
|
||||||
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
ENABLE_TESTING()
|
ENABLE_TESTING()
|
||||||
IF (WINHTTP OR OPENSSL_FOUND OR SECURITY_FOUND)
|
ADD_SUBDIRECTORY(tests)
|
||||||
ADD_TEST(libgit2_clar libgit2_clar -ionline -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
|
|
||||||
ELSE ()
|
|
||||||
ADD_TEST(libgit2_clar libgit2_clar -v -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
|
|
||||||
ENDIF ()
|
|
||||||
|
|
||||||
# Add a test target which runs the cred callback tests, to be
|
|
||||||
# called after setting the url and user
|
|
||||||
ADD_TEST(libgit2_clar-cred_callback libgit2_clar -v -sonline::clone::cred_callback)
|
|
||||||
ADD_TEST(libgit2_clar-proxy_credentials_in_url libgit2_clar -v -sonline::clone::proxy_credentials_in_url)
|
|
||||||
ADD_TEST(libgit2_clar-proxy_credentials_request libgit2_clar -v -sonline::clone::proxy_credentials_request)
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TAGS)
|
IF (TAGS)
|
||||||
@ -738,3 +281,11 @@ ENDIF ()
|
|||||||
IF (BUILD_EXAMPLES)
|
IF (BUILD_EXAMPLES)
|
||||||
ADD_SUBDIRECTORY(examples)
|
ADD_SUBDIRECTORY(examples)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF(CMAKE_VERSION VERSION_GREATER 3)
|
||||||
|
FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
|
||||||
|
FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
|
||||||
|
ELSE()
|
||||||
|
PRINT_ENABLED_FEATURES()
|
||||||
|
PRINT_DISABLED_FEATURES()
|
||||||
|
ENDIF()
|
||||||
|
@ -71,6 +71,22 @@ if we have to read the whole diff to figure out why you're contributing
|
|||||||
in the first place, you're less likely to get feedback and have your change
|
in the first place, you're less likely to get feedback and have your change
|
||||||
merged in.
|
merged in.
|
||||||
|
|
||||||
|
In addition to outlining your thought process in the PR's description, please
|
||||||
|
also try to document it in your commits. We welcome it if every commit has a
|
||||||
|
description of why you have been doing your changes alongside with your
|
||||||
|
reasoning why this is a good idea. The messages shall be written in
|
||||||
|
present-tense and in an imperative style (e.g. "Add feature foobar", not "Added
|
||||||
|
feature foobar" or "Adding feature foobar"). Lines should be wrapped at 80
|
||||||
|
characters so people with small screens are able to read the commit messages in
|
||||||
|
their terminal without any problem.
|
||||||
|
|
||||||
|
To make it easier to attribute commits to certain parts of our code base, we
|
||||||
|
also prefer to have the commit subject be prefixed with a "scope". E.g. if you
|
||||||
|
are changing code in our merging subsystem, make sure to prefix the subject with
|
||||||
|
"merge:". The first word following the colon shall start with an lowercase
|
||||||
|
letter. The maximum line length for the subject is 70 characters, preferably
|
||||||
|
shorter.
|
||||||
|
|
||||||
If you are starting to work on a particular area, feel free to submit a PR
|
If you are starting to work on a particular area, feel free to submit a PR
|
||||||
that highlights your work in progress (and note in the PR title that it's
|
that highlights your work in progress (and note in the PR title that it's
|
||||||
not ready to merge). These early PRs are welcome and will help in getting
|
not ready to merge). These early PRs are welcome and will help in getting
|
||||||
|
@ -36,10 +36,6 @@ These are good small projects to get started with libgit2.
|
|||||||
trick to this one will be doing it in a manner that is clean and
|
trick to this one will be doing it in a manner that is clean and
|
||||||
simple, but still handles the various cases correctly (e.g. `-B/70%`
|
simple, but still handles the various cases correctly (e.g. `-B/70%`
|
||||||
is apparently a legal setting).
|
is apparently a legal setting).
|
||||||
* Implement the `--log-size` option for `examples/log.c`. I think all
|
|
||||||
the data is available, you would just need to add the code into the
|
|
||||||
`print_commit()` routine (along with a way of passing the option
|
|
||||||
into that function).
|
|
||||||
* As an extension to the matching idea for `examples/log.c`, add the
|
* As an extension to the matching idea for `examples/log.c`, add the
|
||||||
`-i` option to use `strcasestr()` for matches.
|
`-i` option to use `strcasestr()` for matches.
|
||||||
* For `examples/log.c`, implement the `--first-parent` option now that
|
* For `examples/log.c`, implement the `--first-parent` option now that
|
||||||
|
93
README.md
93
README.md
@ -6,8 +6,20 @@ libgit2 - the Git linkable library
|
|||||||
[](https://scan.coverity.com/projects/639)
|
[](https://scan.coverity.com/projects/639)
|
||||||
|
|
||||||
`libgit2` is a portable, pure C implementation of the Git core methods
|
`libgit2` is a portable, pure C implementation of the Git core methods
|
||||||
provided as a re-entrant linkable library with a solid API, allowing you to
|
provided as a linkable library with a solid API, allowing to build Git
|
||||||
write native speed custom Git applications in any language with bindings.
|
functionality into your application. Language bindings like
|
||||||
|
[Rugged](https://github.com/libgit2/rugged) (Ruby),
|
||||||
|
[LibGit2Sharp](https://github.com/libgit2/libgit2sharp) (.NET),
|
||||||
|
[pygit2](http://www.pygit2.org/) (Python) and
|
||||||
|
[NodeGit](http://nodegit.org) (Node) allow you to build Git tooling
|
||||||
|
in your favorite language.
|
||||||
|
|
||||||
|
`libgit2` is used to power Git GUI clients like
|
||||||
|
[GitKraken](https://gitkraken.com/) and [gmaster](https://gmaster.io/)
|
||||||
|
and on Git hosting providers like [GitHub](https://github.com/),
|
||||||
|
[GitLab](https://gitlab.com/) and
|
||||||
|
[Visual Studio Team Services](https://visualstudio.com/team-services/).
|
||||||
|
We perform the merge every time you click "merge pull request".
|
||||||
|
|
||||||
`libgit2` is licensed under a **very permissive license** (GPLv2 with a special
|
`libgit2` is licensed under a **very permissive license** (GPLv2 with a special
|
||||||
Linking Exception). This basically means that you can link it (unmodified)
|
Linking Exception). This basically means that you can link it (unmodified)
|
||||||
@ -15,6 +27,30 @@ with any kind of software without having to release its source code.
|
|||||||
Additionally, the example code has been released to the public domain (see the
|
Additionally, the example code has been released to the public domain (see the
|
||||||
[separate license](examples/COPYING) for more information).
|
[separate license](examples/COPYING) for more information).
|
||||||
|
|
||||||
|
Quick Start
|
||||||
|
===========
|
||||||
|
|
||||||
|
**Prerequisites** for building libgit2:
|
||||||
|
|
||||||
|
1. [CMake](https://cmake.org/), and is recommended to be installed into
|
||||||
|
your `PATH`.
|
||||||
|
2. [Python](https://www.python.org) is used by our test framework, and
|
||||||
|
should be installed into your `PATH`.
|
||||||
|
3. C compiler: libgit2 is C90 and should compile on most compilers.
|
||||||
|
* Windows: Visual Studio is recommended
|
||||||
|
* Mac: Xcode is recommended
|
||||||
|
* Unix: gcc or clang is recommended.
|
||||||
|
|
||||||
|
**Build**
|
||||||
|
|
||||||
|
1. Create a build directory beneath the libgit2 source directory, and change
|
||||||
|
into it: `mkdir build && cd build`
|
||||||
|
2. Create the cmake build environment: `cmake ..`
|
||||||
|
3. Build libgit2: `cmake --build .`
|
||||||
|
|
||||||
|
Trouble with these steps? Read `TROUBLESHOOTING.md`. More detailed build
|
||||||
|
guidance is available below.
|
||||||
|
|
||||||
Getting Help
|
Getting Help
|
||||||
============
|
============
|
||||||
|
|
||||||
@ -40,6 +76,12 @@ on a specific repository, please provide a link to it if possible.
|
|||||||
|
|
||||||
We ask that you not open a GitHub Issue for help, only for bug reports.
|
We ask that you not open a GitHub Issue for help, only for bug reports.
|
||||||
|
|
||||||
|
**Reporting Security Issues**
|
||||||
|
|
||||||
|
In case you think to have found a security issue with libgit2, please do not
|
||||||
|
open a public issue. Instead, you can report the issue to the private mailing
|
||||||
|
list [security@libgit2.com](mailto:security@libgit2.com).
|
||||||
|
|
||||||
What It Can Do
|
What It Can Do
|
||||||
==============
|
==============
|
||||||
|
|
||||||
@ -118,6 +160,9 @@ and internal API/coding conventions we use.
|
|||||||
Building libgit2 - Using CMake
|
Building libgit2 - Using CMake
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
`libgit2` builds cleanly on most platforms without any external dependencies.
|
`libgit2` builds cleanly on most platforms without any external dependencies.
|
||||||
Under Unix-like systems, like Linux, \*BSD and Mac OS X, libgit2 expects `pthreads` to be available;
|
Under Unix-like systems, like Linux, \*BSD and Mac OS X, libgit2 expects `pthreads` to be available;
|
||||||
they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API
|
they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API
|
||||||
@ -133,19 +178,49 @@ On most systems you can build the library using the following commands
|
|||||||
|
|
||||||
Alternatively you can point the CMake GUI tool to the CMakeLists.txt file and generate platform specific build project or IDE workspace.
|
Alternatively you can point the CMake GUI tool to the CMakeLists.txt file and generate platform specific build project or IDE workspace.
|
||||||
|
|
||||||
|
Running Tests
|
||||||
|
-------------
|
||||||
|
|
||||||
Once built, you can run the tests from the `build` directory with the command
|
Once built, you can run the tests from the `build` directory with the command
|
||||||
|
|
||||||
$ make test
|
$ ctest -V
|
||||||
|
|
||||||
Alternatively you can run the test suite directly using,
|
Alternatively you can run the test suite directly using,
|
||||||
|
|
||||||
$ ./libgit2_clar
|
$ ./libgit2_clar
|
||||||
|
|
||||||
|
Invoking the test suite directly is useful because it allows you to execute
|
||||||
|
individual tests, or groups of tests using the `-s` flag. For example, to
|
||||||
|
run the index tests:
|
||||||
|
|
||||||
|
$ ./libgit2_clar -sindex
|
||||||
|
|
||||||
|
To run a single test named `index::racy::diff`, which corresponds to the test
|
||||||
|
function (`test_index_racy__diff`)[https://github.com/libgit2/libgit2/blob/master/tests/index/racy.c#L23]:
|
||||||
|
|
||||||
|
$ ./libgit2_clar -sindex::racy::diff
|
||||||
|
|
||||||
|
The test suite will print a `.` for every passing test, and an `F` for any
|
||||||
|
failing test. An `S` indicates that a test was skipped because it is not
|
||||||
|
applicable to your platform or is particularly expensive.
|
||||||
|
|
||||||
|
**Note:** There should be _no_ failing tests when you build an unmodified
|
||||||
|
source tree from a [release](https://github.com/libgit2/libgit2/releases),
|
||||||
|
or from the [master branch](https://github.com/libgit2/libgit2/tree/master).
|
||||||
|
Please contact us or [open an issue](https://github.com/libgit2/libgit2/issues)
|
||||||
|
if you see test failures.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
To install the library you can specify the install prefix by setting:
|
To install the library you can specify the install prefix by setting:
|
||||||
|
|
||||||
$ cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix
|
$ cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix
|
||||||
$ cmake --build . --target install
|
$ cmake --build . --target install
|
||||||
|
|
||||||
|
Advanced Usage
|
||||||
|
--------------
|
||||||
|
|
||||||
For more advanced use or questions about CMake please read <https://cmake.org/Wiki/CMake_FAQ>.
|
For more advanced use or questions about CMake please read <https://cmake.org/Wiki/CMake_FAQ>.
|
||||||
|
|
||||||
The following CMake variables are declared:
|
The following CMake variables are declared:
|
||||||
@ -177,16 +252,6 @@ If you want to build a universal binary for Mac OS X, CMake sets it
|
|||||||
all up for you if you use `-DCMAKE_OSX_ARCHITECTURES="i386;x86_64"`
|
all up for you if you use `-DCMAKE_OSX_ARCHITECTURES="i386;x86_64"`
|
||||||
when configuring.
|
when configuring.
|
||||||
|
|
||||||
Windows
|
|
||||||
-------
|
|
||||||
|
|
||||||
You need to run the CMake commands from the Visual Studio command
|
|
||||||
prompt, not the regular or Windows SDK one. Select the right generator
|
|
||||||
for your version with the `-G "Visual Studio X" option.
|
|
||||||
|
|
||||||
See [the website](http://libgit2.github.com/docs/guides/build-and-link/)
|
|
||||||
for more detailed instructions.
|
|
||||||
|
|
||||||
Android
|
Android
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@ -228,6 +293,8 @@ Here are the bindings to libgit2 that are currently available:
|
|||||||
* git2go <https://github.com/libgit2/git2go>
|
* git2go <https://github.com/libgit2/git2go>
|
||||||
* GObject
|
* GObject
|
||||||
* libgit2-glib <https://wiki.gnome.org/Projects/Libgit2-glib>
|
* libgit2-glib <https://wiki.gnome.org/Projects/Libgit2-glib>
|
||||||
|
* Guile
|
||||||
|
* Guile-Git <https://gitlab.com/guile-git/guile-git>
|
||||||
* Haskell
|
* Haskell
|
||||||
* hgit2 <https://github.com/jwiegley/gitlib>
|
* hgit2 <https://github.com/jwiegley/gitlib>
|
||||||
* Java
|
* Java
|
||||||
|
13
TROUBLESHOOTING.md
Normal file
13
TROUBLESHOOTING.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Troubleshooting libgit2 Problems
|
||||||
|
================================
|
||||||
|
|
||||||
|
CMake Failures
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* **`Asked for OpenSSL TLS backend, but it wasn't found`**
|
||||||
|
CMake cannot find your SSL/TLS libraries. By default, libgit2 always
|
||||||
|
builds with HTTPS support, and you are encouraged to install the
|
||||||
|
OpenSSL libraries for your system (eg, `apt-get install libssl-dev`).
|
||||||
|
|
||||||
|
For development, if you simply want to disable HTTPS support entirely,
|
||||||
|
pass the `-DUSE_HTTPS=OFF` argument to `cmake` when configuring it.
|
29
appveyor.yml
29
appveyor.yml
@ -9,13 +9,23 @@ environment:
|
|||||||
GITTEST_INVASIVE_FS_SIZE: 1
|
GITTEST_INVASIVE_FS_SIZE: 1
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- GENERATOR: "Visual Studio 11"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||||
|
GENERATOR: "Visual Studio 10 2010"
|
||||||
ARCH: 32
|
ARCH: 32
|
||||||
- GENERATOR: "Visual Studio 11 Win64"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||||
|
GENERATOR: "Visual Studio 10 2010 Win64"
|
||||||
ARCH: 64
|
ARCH: 64
|
||||||
- GENERATOR: "MSYS Makefiles"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
GENERATOR: "Visual Studio 14 2015"
|
||||||
|
ARCH: 32
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
GENERATOR: "Visual Studio 14 2015 Win64"
|
||||||
|
ARCH: 64
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
GENERATOR: "MSYS Makefiles"
|
||||||
ARCH: i686 # this is for 32-bit MinGW-w64
|
ARCH: i686 # this is for 32-bit MinGW-w64
|
||||||
- GENERATOR: "MSYS Makefiles"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
GENERATOR: "MSYS Makefiles"
|
||||||
ARCH: 64
|
ARCH: 64
|
||||||
cache:
|
cache:
|
||||||
- i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z
|
- i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z
|
||||||
@ -26,7 +36,7 @@ build_script:
|
|||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
if ($env:GENERATOR -ne "MSYS Makefiles") {
|
if ($env:GENERATOR -ne "MSYS Makefiles") {
|
||||||
cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON -D MSVC_CRTDBG=ON .. -G"$env:GENERATOR"
|
cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON -D BUILD_EXAMPLES=ON -D MSVC_CRTDBG=ON .. -G"$env:GENERATOR"
|
||||||
cmake --build . --config Debug
|
cmake --build . --config Debug
|
||||||
}
|
}
|
||||||
- cmd: |
|
- cmd: |
|
||||||
@ -38,13 +48,8 @@ test_script:
|
|||||||
# Run this early so we know it's ready by the time we need it
|
# Run this early so we know it's ready by the time we need it
|
||||||
$proxyJob = Start-Job { java -jar $Env:APPVEYOR_BUILD_FOLDER\build\poxyproxy.jar -d --port 8080 --credentials foo:bar }
|
$proxyJob = Start-Job { java -jar $Env:APPVEYOR_BUILD_FOLDER\build\poxyproxy.jar -d --port 8080 --credentials foo:bar }
|
||||||
ctest -V -R libgit2_clar
|
ctest -V -R libgit2_clar
|
||||||
$env:GITTEST_REMOTE_URL="https://github.com/libgit2/non-existent"
|
|
||||||
$env:GITTEST_REMOTE_USER="libgit2test"
|
|
||||||
ctest -V -R libgit2_clar-cred_callback
|
|
||||||
Receive-Job -Job $proxyJob
|
Receive-Job -Job $proxyJob
|
||||||
$env:GITTEST_REMOTE_PROXY_URL = "http://foo:bar@localhost:8080"
|
$env:GITTEST_REMOTE_PROXY_URL = "localhost:8080"
|
||||||
ctest -V -R libgit2_clar-proxy_credentials_in_url
|
|
||||||
$env:GITTEST_REMOTE_PROXY_URL = "http://localhost:8080"
|
|
||||||
$env:GITTEST_REMOTE_PROXY_USER = "foo"
|
$env:GITTEST_REMOTE_PROXY_USER = "foo"
|
||||||
$env:GITTEST_REMOTE_PROXY_PASS = "bar"
|
$env:GITTEST_REMOTE_PROXY_PASS = "bar"
|
||||||
ctest -V -R libgit2_clar-proxy_credentials_request
|
ctest -V -R libgit2_clar-proxy_credentials
|
||||||
|
14
cmake/Modules/EnableWarnings.cmake
Normal file
14
cmake/Modules/EnableWarnings.cmake
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
MACRO(ENABLE_WARNINGS flag)
|
||||||
|
IF(ENABLE_WERROR)
|
||||||
|
ADD_C_FLAG_IF_SUPPORTED(-Werror=${flag})
|
||||||
|
ELSE()
|
||||||
|
ADD_C_FLAG_IF_SUPPORTED(-W${flag})
|
||||||
|
ENDIF()
|
||||||
|
ENDMACRO()
|
||||||
|
|
||||||
|
MACRO(DISABLE_WARNINGS flag)
|
||||||
|
ADD_C_FLAG_IF_SUPPORTED(-Wno-${flag})
|
||||||
|
IF(ENABLE_WERROR)
|
||||||
|
ADD_C_FLAG_IF_SUPPORTED(-Wno-error=${flag})
|
||||||
|
ENDIF()
|
||||||
|
ENDMACRO()
|
@ -1,9 +1,26 @@
|
|||||||
IF (COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_DIRS)
|
# Find CoreFoundation.framework
|
||||||
SET(COREFOUNDATION_FOUND TRUE)
|
# This will define :
|
||||||
ELSE ()
|
#
|
||||||
FIND_PATH(COREFOUNDATION_INCLUDE_DIR NAMES CoreFoundation.h)
|
# COREFOUNDATION_FOUND
|
||||||
FIND_LIBRARY(COREFOUNDATION_DIRS NAMES CoreFoundation)
|
# COREFOUNDATION_LIBRARIES
|
||||||
IF (COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_DIRS)
|
# COREFOUNDATION_LDFLAGS
|
||||||
SET(COREFOUNDATION_FOUND TRUE)
|
#
|
||||||
ENDIF ()
|
|
||||||
|
FIND_PATH(COREFOUNDATION_INCLUDE_DIR NAMES CoreFoundation.h)
|
||||||
|
FIND_LIBRARY(COREFOUNDATION_LIBRARIES NAMES CoreFoundation)
|
||||||
|
IF (COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_LIBRARIES)
|
||||||
|
IF (NOT CoreFoundation_FIND_QUIETLY)
|
||||||
|
MESSAGE("-- Found CoreFoundation ${COREFOUNDATION_LIBRARIES}")
|
||||||
|
ENDIF()
|
||||||
|
SET(COREFOUNDATION_FOUND TRUE)
|
||||||
|
SET(COREFOUNDATION_LDFLAGS "-framework CoreFoundation")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (CoreFoundation_FIND_REQUIRED AND NOT COREFOUNDATION_FOUND)
|
||||||
|
MESSAGE(FATAL "-- CoreFoundation not found")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
COREFOUNDATION_INCLUDE_DIR
|
||||||
|
COREFOUNDATION_LIBRARIES
|
||||||
|
)
|
||||||
|
@ -1,9 +1,28 @@
|
|||||||
IF (SECURITY_INCLUDE_DIR AND SECURITY_DIRS)
|
# Find Security.framework
|
||||||
SET(SECURITY_FOUND TRUE)
|
# This will define :
|
||||||
ELSE ()
|
#
|
||||||
FIND_PATH(SECURITY_INCLUDE_DIR NAMES Security/Security.h)
|
# SECURITY_FOUND
|
||||||
FIND_LIBRARY(SECURITY_DIRS NAMES Security)
|
# SECURITY_LIBRARIES
|
||||||
IF (SECURITY_INCLUDE_DIR AND SECURITY_DIRS)
|
# SECURITY_LDFLAGS
|
||||||
SET(SECURITY_FOUND TRUE)
|
# SECURITY_HAS_SSLCREATECONTEXT
|
||||||
ENDIF ()
|
#
|
||||||
|
|
||||||
|
FIND_PATH(SECURITY_INCLUDE_DIR NAMES Security/Security.h)
|
||||||
|
FIND_LIBRARY(SECURITY_LIBRARIES NAMES Security)
|
||||||
|
IF (SECURITY_INCLUDE_DIR AND SECURITY_LIBRARIES)
|
||||||
|
IF (NOT Security_FIND_QUIETLY)
|
||||||
|
MESSAGE("-- Found Security ${SECURITY_LIBRARIES}")
|
||||||
|
ENDIF()
|
||||||
|
SET(SECURITY_FOUND TRUE)
|
||||||
|
SET(SECURITY_LDFLAGS "-framework Security")
|
||||||
|
CHECK_LIBRARY_EXISTS("${SECURITY_LIBRARIES}" SSLCreateContext "Security/SecureTransport.h" SECURITY_HAS_SSLCREATECONTEXT)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (Security_FIND_REQUIRED AND NOT SECURITY_FOUND)
|
||||||
|
MESSAGE(FATAL "-- Security not found")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
SECURITY_INCLUDE_DIR
|
||||||
|
SECURITY_LIBRARIES
|
||||||
|
)
|
||||||
|
20
cmake/Modules/FindStatNsec.cmake
Normal file
20
cmake/Modules/FindStatNsec.cmake
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtim "sys/types.h;sys/stat.h"
|
||||||
|
HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C)
|
||||||
|
CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtimespec "sys/types.h;sys/stat.h"
|
||||||
|
HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE C)
|
||||||
|
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtime_nsec sys/stat.h
|
||||||
|
HAVE_STRUCT_STAT_MTIME_NSEC LANGUAGE C)
|
||||||
|
|
||||||
|
IF (HAVE_STRUCT_STAT_ST_MTIM)
|
||||||
|
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h
|
||||||
|
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
|
||||||
|
ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
||||||
|
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec sys/stat.h
|
||||||
|
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
|
||||||
|
ELSE ()
|
||||||
|
SET( HAVE_STRUCT_STAT_NSEC ON )
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF (HAVE_STRUCT_STAT_NSEC OR WIN32)
|
||||||
|
OPTION( USE_NSEC "Care about sub-second file mtimes and ctimes" ON )
|
||||||
|
ENDIF()
|
22
cmake/Modules/IdeSplitSources.cmake
Normal file
22
cmake/Modules/IdeSplitSources.cmake
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# This function splits the sources files up into their appropriate
|
||||||
|
# subdirectories. This is especially useful for IDEs like Xcode and
|
||||||
|
# Visual Studio, so that you can navigate into the libgit2_clar project,
|
||||||
|
# and see the folders within the tests folder (instead of just seeing all
|
||||||
|
# source and tests in a single folder.)
|
||||||
|
FUNCTION(IDE_SPLIT_SOURCES target)
|
||||||
|
IF(MSVC_IDE OR CMAKE_GENERATOR STREQUAL Xcode)
|
||||||
|
GET_TARGET_PROPERTY(sources ${target} SOURCES)
|
||||||
|
FOREACH(source ${sources})
|
||||||
|
IF(source MATCHES ".*/")
|
||||||
|
STRING(REPLACE ${libgit2_SOURCE_DIR}/ "" rel ${source})
|
||||||
|
IF(rel)
|
||||||
|
STRING(REGEX REPLACE "/([^/]*)$" "" rel ${rel})
|
||||||
|
IF(rel)
|
||||||
|
STRING(REPLACE "/" "\\\\" rel ${rel})
|
||||||
|
SOURCE_GROUP(${rel} FILES ${source})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
ENDFOREACH()
|
||||||
|
ENDIF()
|
||||||
|
ENDFUNCTION()
|
81
docs/release.md
Normal file
81
docs/release.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# Releasing the library
|
||||||
|
|
||||||
|
We have three kinds of releases: "full" releases, maintenance releases and security releases. Full ones release the state of the `master` branch whereas maintenance releases provide bugfixes building on top of the currently released series. Security releases are also for the current series but only contain security fixes on top of the previous release.
|
||||||
|
|
||||||
|
## Full release
|
||||||
|
|
||||||
|
We aim to release once every six months. We start the process by opening an issue. This is accompanied with a feature freeze. From now until the release, only bug fixes are to be merged. Use the following as a base for the issue
|
||||||
|
|
||||||
|
Release v0.X
|
||||||
|
|
||||||
|
Let's release v0.X, codenamed: <something witty>
|
||||||
|
|
||||||
|
- [ ] Bump the versions in the headers
|
||||||
|
- [ ] Make a release candidate
|
||||||
|
- [ ] Plug any final leaks
|
||||||
|
- [ ] Fix any last-minute issues
|
||||||
|
- [ ] Make sure CHANGELOG reflects everything worth discussing
|
||||||
|
- [ ] Update the version in CHANGELOG and the header
|
||||||
|
- [ ] Produce a release candidate
|
||||||
|
- [ ] Tag
|
||||||
|
- [ ] Create maint/v0.X
|
||||||
|
- [ ] Update any bindings the core team works with
|
||||||
|
|
||||||
|
We tag at least one release candidate. This RC must carry the new version in the headers, including the SOVERSION. If there are no significant issues found, we can go straight to the release after a single RC. This is up to the discretion of the release manager. There is no set time to have the candidate out, but we should we should give downstream projects at least a week to give feedback.
|
||||||
|
|
||||||
|
Preparing the first release candidate includes updating the version number of libgit2 to the new version number. To do so, a pull request shall be submitted that adjusts the version number in the following places:
|
||||||
|
|
||||||
|
- CHANGELOG.md
|
||||||
|
- include/git2/version.h
|
||||||
|
|
||||||
|
As soon as the pull request is merged, the merge commit shall be tagged with a lightweight tag.
|
||||||
|
|
||||||
|
The tagging happens via GitHub's "releases" tab which lets us attach release notes to a particular tag. In the description we include the changes in `CHANGELOG.md` between the last full release. Use the following as a base for the release notes
|
||||||
|
|
||||||
|
This is the first release of the v0.X series, <codename>. The changelog follows.
|
||||||
|
|
||||||
|
followed by the three sections in the changelog. For release candidates we can avoid copying the full changelog and only include any new entries.
|
||||||
|
|
||||||
|
During the freeze, and certainly after the first release candidate, any bindings the core team work with should be updated in order to discover any issues that might come up with the multitude of approaches to memory management, embedding or linking.
|
||||||
|
|
||||||
|
Create a branch `maint/v0.X` at the current state of `master` after you've created the tag. This will be used for maintenance releases and lets our dependents track the latest state of the series.
|
||||||
|
|
||||||
|
## Maintenance release
|
||||||
|
|
||||||
|
Every once in a while, when we feel we've accumulated a significant amount of backportable fixes in the mainline branch, we produce a maintenance release in order to provide fixes or improvements for those who track the releases. This also lets our users and integrators receive updates without having to upgrade to the next full release.
|
||||||
|
|
||||||
|
As a rule of thumb, it's a good idea to produce a maintenance release for the current series when we're getting ready for a full release. This gives the (still) current series a last round of fixes without having to upgrade (which with us potentially means adjusting to API changes).
|
||||||
|
|
||||||
|
Start by opening an issue. Use the following as a base.
|
||||||
|
|
||||||
|
Release v0.X.Y
|
||||||
|
|
||||||
|
Enough fixes have accumulated, let's release v0.X.Y
|
||||||
|
|
||||||
|
- [ ] Select the changes we want to backport
|
||||||
|
- [ ] Update maint/v0.X
|
||||||
|
- [ ] Tag
|
||||||
|
|
||||||
|
The list of changes to backport does not need to be comprehensive and we might not backport something if the code in mainline has diverged significantly. These fixes do not include those which require API or ABI changes as we release under the same SOVERSION.
|
||||||
|
|
||||||
|
Do not merge into the `maint/v0.X` until we are getting ready to produce a new release. There is always the possibility that we will need to produce a security release and those must only include the relevant security fixes and not arbitrary fixes we were planning on releasing at some point.
|
||||||
|
|
||||||
|
Here we do not use release candidates as the changes are supposed to be small and proven.
|
||||||
|
|
||||||
|
## Security releases
|
||||||
|
|
||||||
|
This is the same as a maintenance release, except that the fix itself will most likely be developed in a private repository and will only be visible to a select group of people until the release.
|
||||||
|
|
||||||
|
Everything else remains the same. Occasionally we might opt to backport a security fix to the previous series, based on how recently we started the new series and how serious the issue is.
|
||||||
|
|
||||||
|
## Updating documentation
|
||||||
|
|
||||||
|
We use docurium to generate our documentation. It is a tool written in ruby which leverages libclang's documentation parser. Install docurium
|
||||||
|
|
||||||
|
gem install docurium
|
||||||
|
|
||||||
|
and run it against our description file with the tip of master checked out.
|
||||||
|
|
||||||
|
cm doc api.docurium
|
||||||
|
|
||||||
|
It will start up a few proceses and write out the results as a new commit onto the `gh-pages` branch. That can be pushed to GitHub to update what will show up on our documentation reference site.
|
15
examples/.gitignore
vendored
15
examples/.gitignore
vendored
@ -1,15 +0,0 @@
|
|||||||
general
|
|
||||||
showindex
|
|
||||||
diff
|
|
||||||
rev-list
|
|
||||||
blame
|
|
||||||
cat-file
|
|
||||||
init
|
|
||||||
log
|
|
||||||
rev-parse
|
|
||||||
remote
|
|
||||||
status
|
|
||||||
tag
|
|
||||||
for-each-ref
|
|
||||||
describe
|
|
||||||
*.dSYM
|
|
@ -1,4 +1,7 @@
|
|||||||
FILE(GLOB_RECURSE SRC_EXAMPLE_GIT2 network/*.c network/*.h)
|
LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
|
||||||
|
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
|
||||||
|
|
||||||
|
FILE(GLOB_RECURSE SRC_EXAMPLE_GIT2 network/*.c network/*.h common.?)
|
||||||
ADD_EXECUTABLE(cgit2 ${SRC_EXAMPLE_GIT2})
|
ADD_EXECUTABLE(cgit2 ${SRC_EXAMPLE_GIT2})
|
||||||
IF(WIN32 OR ANDROID)
|
IF(WIN32 OR ANDROID)
|
||||||
TARGET_LINK_LIBRARIES(cgit2 git2)
|
TARGET_LINK_LIBRARIES(cgit2 git2)
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
.PHONY: all
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
|
|
||||||
LFLAGS = -L../build -lgit2 -lz
|
|
||||||
APPS = general showindex diff rev-list cat-file status log rev-parse init blame tag remote
|
|
||||||
APPS += for-each-ref
|
|
||||||
APPS += describe
|
|
||||||
|
|
||||||
all: $(APPS)
|
|
||||||
|
|
||||||
% : %.c
|
|
||||||
$(CC) -o $@ common.c $(CFLAGS) $< $(LFLAGS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(APPS)
|
|
||||||
$(RM) -r *.dSYM
|
|
@ -235,3 +235,13 @@ void treeish_to_tree(
|
|||||||
git_object_free(obj);
|
git_object_free(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *xrealloc(void *oldp, size_t newsz)
|
||||||
|
{
|
||||||
|
void *p = realloc(oldp, newsz);
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "Cannot allocate memory, exiting.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -103,3 +103,8 @@ extern int diff_output(
|
|||||||
*/
|
*/
|
||||||
extern void treeish_to_tree(
|
extern void treeish_to_tree(
|
||||||
git_tree **out, git_repository *repo, const char *treeish);
|
git_tree **out, git_repository *repo, const char *treeish);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A realloc that exits on failure
|
||||||
|
*/
|
||||||
|
extern void *xrealloc(void *oldp, size_t newsz);
|
||||||
|
@ -47,16 +47,6 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct args_info args_info;
|
typedef struct args_info args_info;
|
||||||
|
|
||||||
static void *xrealloc(void *oldp, size_t newsz)
|
|
||||||
{
|
|
||||||
void *p = realloc(oldp, newsz);
|
|
||||||
if (p == NULL) {
|
|
||||||
fprintf(stderr, "Cannot allocate memory, exiting.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void opts_add_commit(describe_options *opts, const char *commit)
|
static void opts_add_commit(describe_options *opts, const char *commit)
|
||||||
{
|
{
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
@ -724,6 +724,7 @@ static void config_files(const char *repo_path, git_repository* repo)
|
|||||||
int32_t autocorrect;
|
int32_t autocorrect;
|
||||||
git_config *cfg;
|
git_config *cfg;
|
||||||
git_config *snap_cfg;
|
git_config *snap_cfg;
|
||||||
|
int error_code;
|
||||||
|
|
||||||
printf("\n*Config Listing*\n");
|
printf("\n*Config Listing*\n");
|
||||||
|
|
||||||
@ -740,9 +741,33 @@ static void config_files(const char *repo_path, git_repository* repo)
|
|||||||
git_config_get_string(&email, snap_cfg, "user.email");
|
git_config_get_string(&email, snap_cfg, "user.email");
|
||||||
printf("Email: %s\n", email);
|
printf("Email: %s\n", email);
|
||||||
|
|
||||||
/**
|
error_code = git_config_get_int32(&autocorrect, cfg, "help.autocorrect");
|
||||||
* Remember to free the configurations after usage.
|
switch (error_code)
|
||||||
*/
|
{
|
||||||
|
case 0:
|
||||||
|
printf("Autocorrect: %d\n", autocorrect);
|
||||||
|
break;
|
||||||
|
case GIT_ENOTFOUND:
|
||||||
|
printf("Autocorrect: Undefined\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
check_error(error_code, "get_int32 failed");
|
||||||
|
}
|
||||||
git_config_free(cfg);
|
git_config_free(cfg);
|
||||||
|
|
||||||
|
check_error(git_repository_config_snapshot(&snap_cfg, repo), "config snapshot");
|
||||||
|
error_code = git_config_get_string(&email, snap_cfg, "user.email");
|
||||||
|
switch (error_code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
printf("Email: %s\n", email);
|
||||||
|
break;
|
||||||
|
case GIT_ENOTFOUND:
|
||||||
|
printf("Email: Undefined\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
check_error(error_code, "get_string failed");
|
||||||
|
}
|
||||||
|
|
||||||
git_config_free(snap_cfg);
|
git_config_free(snap_cfg);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ static int add_revision(struct log_state *s, const char *revstr);
|
|||||||
/** log_options holds other command line options that affect log output */
|
/** log_options holds other command line options that affect log output */
|
||||||
struct log_options {
|
struct log_options {
|
||||||
int show_diff;
|
int show_diff;
|
||||||
|
int show_log_size;
|
||||||
int skip, limit;
|
int skip, limit;
|
||||||
int min_parents, max_parents;
|
int min_parents, max_parents;
|
||||||
git_time_t before;
|
git_time_t before;
|
||||||
@ -63,7 +64,7 @@ struct log_options {
|
|||||||
static int parse_options(
|
static int parse_options(
|
||||||
struct log_state *s, struct log_options *opt, int argc, char **argv);
|
struct log_state *s, struct log_options *opt, int argc, char **argv);
|
||||||
static void print_time(const git_time *intime, const char *prefix);
|
static void print_time(const git_time *intime, const char *prefix);
|
||||||
static void print_commit(git_commit *commit);
|
static void print_commit(git_commit *commit, struct log_options *opts);
|
||||||
static int match_with_parent(git_commit *commit, int i, git_diff_options *);
|
static int match_with_parent(git_commit *commit, int i, git_diff_options *);
|
||||||
|
|
||||||
/** utility functions for filtering */
|
/** utility functions for filtering */
|
||||||
@ -148,7 +149,7 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_commit(commit);
|
print_commit(commit, &opt);
|
||||||
|
|
||||||
if (opt.show_diff) {
|
if (opt.show_diff) {
|
||||||
git_tree *a = NULL, *b = NULL;
|
git_tree *a = NULL, *b = NULL;
|
||||||
@ -337,7 +338,7 @@ static void print_time(const git_time *intime, const char *prefix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Helper to print a commit object. */
|
/** Helper to print a commit object. */
|
||||||
static void print_commit(git_commit *commit)
|
static void print_commit(git_commit *commit, struct log_options *opts)
|
||||||
{
|
{
|
||||||
char buf[GIT_OID_HEXSZ + 1];
|
char buf[GIT_OID_HEXSZ + 1];
|
||||||
int i, count;
|
int i, count;
|
||||||
@ -347,6 +348,10 @@ static void print_commit(git_commit *commit)
|
|||||||
git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
|
git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
|
||||||
printf("commit %s\n", buf);
|
printf("commit %s\n", buf);
|
||||||
|
|
||||||
|
if (opts->show_log_size) {
|
||||||
|
printf("log size %d\n", (int)strlen(git_commit_message(commit)));
|
||||||
|
}
|
||||||
|
|
||||||
if ((count = (int)git_commit_parentcount(commit)) > 1) {
|
if ((count = (int)git_commit_parentcount(commit)) > 1) {
|
||||||
printf("Merge:");
|
printf("Merge:");
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
@ -470,6 +475,8 @@ static int parse_options(
|
|||||||
/** Found valid --min_parents. */;
|
/** Found valid --min_parents. */;
|
||||||
else if (!strcmp(a, "-p") || !strcmp(a, "-u") || !strcmp(a, "--patch"))
|
else if (!strcmp(a, "-p") || !strcmp(a, "-u") || !strcmp(a, "--patch"))
|
||||||
opt->show_diff = 1;
|
opt->show_diff = 1;
|
||||||
|
else if (!strcmp(a, "--log-size"))
|
||||||
|
opt->show_log_size = 1;
|
||||||
else
|
else
|
||||||
usage("Unsupported argument", a);
|
usage("Unsupported argument", a);
|
||||||
}
|
}
|
||||||
|
396
examples/merge.c
Normal file
396
examples/merge.c
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
/*
|
||||||
|
* libgit2 "merge" example - shows how to perform merges
|
||||||
|
*
|
||||||
|
* Written by the libgit2 contributors
|
||||||
|
*
|
||||||
|
* To the extent possible under law, the author(s) have dedicated all copyright
|
||||||
|
* and related and neighboring rights to this software to the public domain
|
||||||
|
* worldwide. This software is distributed without any warranty.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
* with this software. If not, see
|
||||||
|
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define snprintf sprintf_s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The following example demonstrates how to do merges with libgit2.
|
||||||
|
*
|
||||||
|
* It will merge whatever commit-ish you pass in into the current branch.
|
||||||
|
*
|
||||||
|
* Recognized options are :
|
||||||
|
* --no-commit: don't actually commit the merge.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char **heads;
|
||||||
|
size_t heads_count;
|
||||||
|
|
||||||
|
git_annotated_commit **annotated;
|
||||||
|
size_t annotated_count;
|
||||||
|
|
||||||
|
int no_commit : 1;
|
||||||
|
} merge_options;
|
||||||
|
|
||||||
|
static void print_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: merge [--no-commit] <commit...>\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void merge_options_init(merge_options *opts)
|
||||||
|
{
|
||||||
|
memset(opts, 0, sizeof(*opts));
|
||||||
|
|
||||||
|
opts->heads = NULL;
|
||||||
|
opts->heads_count = 0;
|
||||||
|
opts->annotated = NULL;
|
||||||
|
opts->annotated_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void opts_add_refish(merge_options *opts, const char *refish)
|
||||||
|
{
|
||||||
|
size_t sz;
|
||||||
|
|
||||||
|
assert(opts != NULL);
|
||||||
|
|
||||||
|
sz = ++opts->heads_count * sizeof(opts->heads[0]);
|
||||||
|
opts->heads = xrealloc(opts->heads, sz);
|
||||||
|
opts->heads[opts->heads_count - 1] = refish;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_options(const char **repo_path, merge_options *opts, int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct args_info args = ARGS_INFO_INIT;
|
||||||
|
|
||||||
|
if (argc <= 1)
|
||||||
|
print_usage();
|
||||||
|
|
||||||
|
for (args.pos = 1; args.pos < argc; ++args.pos) {
|
||||||
|
const char *curr = argv[args.pos];
|
||||||
|
|
||||||
|
if (curr[0] != '-') {
|
||||||
|
opts_add_refish(opts, curr);
|
||||||
|
} else if (!strcmp(curr, "--no-commit")) {
|
||||||
|
opts->no_commit = 1;
|
||||||
|
} else if (match_str_arg(repo_path, &args, "--git-dir")) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
print_usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int resolve_refish(git_annotated_commit **commit, git_repository *repo, const char *refish)
|
||||||
|
{
|
||||||
|
git_reference *ref;
|
||||||
|
int err = 0;
|
||||||
|
git_oid oid;
|
||||||
|
|
||||||
|
assert(commit != NULL);
|
||||||
|
|
||||||
|
err = git_reference_dwim(&ref, repo, refish);
|
||||||
|
if (err == GIT_OK) {
|
||||||
|
git_annotated_commit_from_ref(commit, repo, ref);
|
||||||
|
git_reference_free(ref);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_oid_fromstr(&oid, refish);
|
||||||
|
if (err == GIT_OK) {
|
||||||
|
err = git_annotated_commit_lookup(commit, repo, &oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int resolve_heads(git_repository *repo, merge_options *opts)
|
||||||
|
{
|
||||||
|
git_annotated_commit **annotated = calloc(opts->heads_count, sizeof(git_annotated_commit *));
|
||||||
|
size_t annotated_count = 0, i;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < opts->heads_count; i++) {
|
||||||
|
err = resolve_refish(&annotated[annotated_count++], repo, opts->heads[i]);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to resolve refish %s: %s\n", opts->heads[i], giterr_last()->message);
|
||||||
|
annotated_count--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (annotated_count != opts->heads_count) {
|
||||||
|
fprintf(stderr, "unable to parse some refish\n");
|
||||||
|
free(annotated);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts->annotated = annotated;
|
||||||
|
opts->annotated_count = annotated_count;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perform_fastforward(git_repository *repo, const git_oid *target_oid, int is_unborn)
|
||||||
|
{
|
||||||
|
git_checkout_options ff_checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
|
||||||
|
git_reference *target_ref;
|
||||||
|
git_reference *new_target_ref;
|
||||||
|
git_object *target = NULL;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (is_unborn) {
|
||||||
|
const char *symbolic_ref;
|
||||||
|
git_reference *head_ref;
|
||||||
|
|
||||||
|
/* HEAD reference is unborn, lookup manually so we don't try to resolve it */
|
||||||
|
err = git_reference_lookup(&head_ref, repo, "HEAD");
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to lookup HEAD ref\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grab the reference HEAD should be pointing to */
|
||||||
|
symbolic_ref = git_reference_symbolic_target(head_ref);
|
||||||
|
|
||||||
|
/* Create our master reference on the target OID */
|
||||||
|
err = git_reference_create(&target_ref, repo, symbolic_ref, target_oid, 0, NULL);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to create master reference\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_reference_free(head_ref);
|
||||||
|
} else {
|
||||||
|
/* HEAD exists, just lookup and resolve */
|
||||||
|
err = git_repository_head(&target_ref, repo);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to get HEAD reference\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup the target object */
|
||||||
|
err = git_object_lookup(&target, repo, target_oid, GIT_OBJ_COMMIT);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to lookup OID %s\n", git_oid_tostr_s(target_oid));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checkout the result so the workdir is in the expected state */
|
||||||
|
ff_checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
|
||||||
|
err = git_checkout_tree(repo, target, &ff_checkout_options);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to checkout HEAD reference\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the target reference to the target OID */
|
||||||
|
err = git_reference_set_target(&new_target_ref, target_ref, target_oid, NULL);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "failed to move HEAD reference\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_reference_free(target_ref);
|
||||||
|
git_reference_free(new_target_ref);
|
||||||
|
git_object_free(target);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_conflicts(git_index *index)
|
||||||
|
{
|
||||||
|
git_index_conflict_iterator *conflicts;
|
||||||
|
const git_index_entry *ancestor;
|
||||||
|
const git_index_entry *our;
|
||||||
|
const git_index_entry *their;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
check_lg2(git_index_conflict_iterator_new(&conflicts, index), "failed to create conflict iterator", NULL);
|
||||||
|
|
||||||
|
while ((err = git_index_conflict_next(&ancestor, &our, &their, conflicts)) == 0) {
|
||||||
|
fprintf(stderr, "conflict: a:%s o:%s t:%s\n",
|
||||||
|
ancestor ? ancestor->path : "NULL",
|
||||||
|
our->path ? our->path : "NULL",
|
||||||
|
their->path ? their->path : "NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != GIT_ITEROVER) {
|
||||||
|
fprintf(stderr, "error iterating conflicts\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
git_index_conflict_iterator_free(conflicts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create_merge_commit(git_repository *repo, git_index *index, merge_options *opts)
|
||||||
|
{
|
||||||
|
git_oid tree_oid, commit_oid;
|
||||||
|
git_tree *tree;
|
||||||
|
git_signature *sign;
|
||||||
|
git_reference *merge_ref = NULL;
|
||||||
|
git_annotated_commit *merge_commit;
|
||||||
|
git_reference *head_ref;
|
||||||
|
git_commit **parents = calloc(opts->annotated_count + 1, sizeof(git_commit *));
|
||||||
|
const char *msg_target = NULL;
|
||||||
|
size_t msglen = 0;
|
||||||
|
char *msg;
|
||||||
|
size_t i;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Grab our needed references */
|
||||||
|
check_lg2(git_repository_head(&head_ref, repo), "failed to get repo HEAD", NULL);
|
||||||
|
if (resolve_refish(&merge_commit, repo, opts->heads[0])) {
|
||||||
|
fprintf(stderr, "failed to resolve refish %s", opts->heads[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Maybe that's a ref, so DWIM it */
|
||||||
|
err = git_reference_dwim(&merge_ref, repo, opts->heads[0]);
|
||||||
|
check_lg2(err, "failed to DWIM reference", giterr_last()->message);
|
||||||
|
|
||||||
|
/* Grab a signature */
|
||||||
|
check_lg2(git_signature_now(&sign, "Me", "me@example.com"), "failed to create signature", NULL);
|
||||||
|
|
||||||
|
#define MERGE_COMMIT_MSG "Merge %s '%s'"
|
||||||
|
/* Prepare a standard merge commit message */
|
||||||
|
if (merge_ref != NULL) {
|
||||||
|
check_lg2(git_branch_name(&msg_target, merge_ref), "failed to get branch name of merged ref", NULL);
|
||||||
|
} else {
|
||||||
|
msg_target = git_oid_tostr_s(git_annotated_commit_id(merge_commit));
|
||||||
|
}
|
||||||
|
|
||||||
|
msglen = snprintf(NULL, 0, MERGE_COMMIT_MSG, (merge_ref ? "branch" : "commit"), msg_target);
|
||||||
|
if (msglen > 0) msglen++;
|
||||||
|
msg = malloc(msglen);
|
||||||
|
err = snprintf(msg, msglen, MERGE_COMMIT_MSG, (merge_ref ? "branch" : "commit"), msg_target);
|
||||||
|
|
||||||
|
/* This is only to silence the compiler */
|
||||||
|
if (err < 0) goto cleanup;
|
||||||
|
|
||||||
|
/* Setup our parent commits */
|
||||||
|
err = git_reference_peel((git_object **)&parents[0], head_ref, GIT_OBJ_COMMIT);
|
||||||
|
check_lg2(err, "failed to peel head reference", NULL);
|
||||||
|
for (i = 0; i < opts->annotated_count; i++) {
|
||||||
|
git_commit_lookup(&parents[i + 1], repo, git_annotated_commit_id(opts->annotated[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare our commit tree */
|
||||||
|
check_lg2(git_index_write_tree(&tree_oid, index), "failed to write merged tree", NULL);
|
||||||
|
check_lg2(git_tree_lookup(&tree, repo, &tree_oid), "failed to lookup tree", NULL);
|
||||||
|
|
||||||
|
/* Commit time ! */
|
||||||
|
err = git_commit_create(&commit_oid,
|
||||||
|
repo, git_reference_name(head_ref),
|
||||||
|
sign, sign,
|
||||||
|
NULL, msg,
|
||||||
|
tree,
|
||||||
|
opts->annotated_count + 1, (const git_commit **)parents);
|
||||||
|
check_lg2(err, "failed to create commit", NULL);
|
||||||
|
|
||||||
|
/* We're done merging, cleanup the repository state */
|
||||||
|
git_repository_state_cleanup(repo);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(parents);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
git_repository *repo = NULL;
|
||||||
|
merge_options opts;
|
||||||
|
git_index *index;
|
||||||
|
git_repository_state_t state;
|
||||||
|
git_merge_analysis_t analysis;
|
||||||
|
git_merge_preference_t preference;
|
||||||
|
const char *path = ".";
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
merge_options_init(&opts);
|
||||||
|
parse_options(&path, &opts, argc, argv);
|
||||||
|
|
||||||
|
git_libgit2_init();
|
||||||
|
|
||||||
|
check_lg2(git_repository_open_ext(&repo, path, 0, NULL),
|
||||||
|
"Could not open repository", NULL);
|
||||||
|
|
||||||
|
state = git_repository_state(repo);
|
||||||
|
if (state != GIT_REPOSITORY_STATE_NONE) {
|
||||||
|
fprintf(stderr, "repository is in unexpected state %d\n", state);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resolve_heads(repo, &opts);
|
||||||
|
if (err != 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
err = git_merge_analysis(&analysis, &preference,
|
||||||
|
repo,
|
||||||
|
(const git_annotated_commit **)opts.annotated,
|
||||||
|
opts.annotated_count);
|
||||||
|
check_lg2(err, "merge analysis failed", NULL);
|
||||||
|
|
||||||
|
if (analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) {
|
||||||
|
printf("Already up-to-date\n");
|
||||||
|
return 0;
|
||||||
|
} else if (analysis & GIT_MERGE_ANALYSIS_UNBORN ||
|
||||||
|
(analysis & GIT_MERGE_ANALYSIS_FASTFORWARD &&
|
||||||
|
!(preference & GIT_MERGE_PREFERENCE_NO_FASTFORWARD))) {
|
||||||
|
const git_oid *target_oid;
|
||||||
|
if (analysis & GIT_MERGE_ANALYSIS_UNBORN) {
|
||||||
|
printf("Unborn\n");
|
||||||
|
} else {
|
||||||
|
printf("Fast-forward\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Since this is a fast-forward, there can be only one merge head */
|
||||||
|
target_oid = git_annotated_commit_id(opts.annotated[0]);
|
||||||
|
assert(opts.annotated_count == 1);
|
||||||
|
|
||||||
|
return perform_fastforward(repo, target_oid, (analysis & GIT_MERGE_ANALYSIS_UNBORN));
|
||||||
|
} else if (analysis & GIT_MERGE_ANALYSIS_NORMAL) {
|
||||||
|
git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
|
||||||
|
git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
|
||||||
|
|
||||||
|
merge_opts.flags = 0;
|
||||||
|
merge_opts.file_flags = GIT_MERGE_FILE_STYLE_DIFF3;
|
||||||
|
|
||||||
|
checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE|GIT_CHECKOUT_ALLOW_CONFLICTS;
|
||||||
|
|
||||||
|
if (preference & GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY) {
|
||||||
|
printf("Fast-forward is preferred, but only a merge is possible\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_merge(repo,
|
||||||
|
(const git_annotated_commit **)opts.annotated, opts.annotated_count,
|
||||||
|
&merge_opts, &checkout_opts);
|
||||||
|
check_lg2(err, "merge failed", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get here, we actually performed the merge above */
|
||||||
|
|
||||||
|
check_lg2(git_repository_index(&index, repo), "failed to get repository index", NULL);
|
||||||
|
|
||||||
|
if (git_index_has_conflicts(index)) {
|
||||||
|
/* Handle conflicts */
|
||||||
|
output_conflicts(index);
|
||||||
|
} else if (!opts.no_commit) {
|
||||||
|
create_merge_commit(repo, index, &opts);
|
||||||
|
printf("Merge made\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(opts.heads);
|
||||||
|
free(opts.annotated);
|
||||||
|
git_repository_free(repo);
|
||||||
|
git_libgit2_shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -16,6 +16,43 @@
|
|||||||
# define UNUSED(x) x
|
# define UNUSED(x) x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int readline(char **out)
|
||||||
|
{
|
||||||
|
int c, error = 0, length = 0, allocated = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
while ((c = getchar()) != EOF) {
|
||||||
|
if (length == allocated) {
|
||||||
|
allocated += 16;
|
||||||
|
|
||||||
|
if ((line = realloc(line, allocated)) == NULL) {
|
||||||
|
error = -1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
|
line[length++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno != 0) {
|
||||||
|
error = -1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
line[length] = '\0';
|
||||||
|
*out = line;
|
||||||
|
line = NULL;
|
||||||
|
error = length;
|
||||||
|
error:
|
||||||
|
free(line);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
int cred_acquire_cb(git_cred **out,
|
int cred_acquire_cb(git_cred **out,
|
||||||
const char * UNUSED(url),
|
const char * UNUSED(url),
|
||||||
const char * UNUSED(username_from_url),
|
const char * UNUSED(username_from_url),
|
||||||
@ -26,14 +63,14 @@ int cred_acquire_cb(git_cred **out,
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
printf("Username: ");
|
printf("Username: ");
|
||||||
if (getline(&username, NULL, stdin) < 0) {
|
if (readline(&username) < 0) {
|
||||||
fprintf(stderr, "Unable to read username: %s", strerror(errno));
|
fprintf(stderr, "Unable to read username: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Yup. Right there on your terminal. Careful where you copy/paste output. */
|
/* Yup. Right there on your terminal. Careful where you copy/paste output. */
|
||||||
printf("Password: ");
|
printf("Password: ");
|
||||||
if (getline(&password, NULL, stdin) < 0) {
|
if (readline(&password) < 0) {
|
||||||
fprintf(stderr, "Unable to read password: %s", strerror(errno));
|
fprintf(stderr, "Unable to read password: %s", strerror(errno));
|
||||||
free(username);
|
free(username);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -8,13 +8,6 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct dl_data {
|
|
||||||
git_remote *remote;
|
|
||||||
git_fetch_options *fetch_opts;
|
|
||||||
int ret;
|
|
||||||
int finished;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int progress_cb(const char *str, int len, void *data)
|
static int progress_cb(const char *str, int len, void *data)
|
||||||
{
|
{
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../common.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
// This part is not strictly libgit2-dependent, but you can use this
|
/* This part is not strictly libgit2-dependent, but you can use this
|
||||||
// as a starting point for a git-like tool
|
* as a starting point for a git-like tool */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char *name;
|
char *name;
|
||||||
@ -18,20 +19,12 @@ struct {
|
|||||||
{ NULL, NULL}
|
{ NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int run_command(git_cb fn, int argc, char **argv)
|
static int run_command(git_cb fn, git_repository *repo, struct args_info args)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
git_repository *repo;
|
|
||||||
|
|
||||||
// Before running the actual command, create an instance of the local
|
/* Run the command. If something goes wrong, print the error message to stderr */
|
||||||
// repository and pass it to the function.
|
error = fn(repo, args.argc - args.pos, &args.argv[args.pos]);
|
||||||
|
|
||||||
error = git_repository_open(&repo, ".git");
|
|
||||||
if (error < 0)
|
|
||||||
repo = NULL;
|
|
||||||
|
|
||||||
// Run the command. If something goes wrong, print the error message to stderr
|
|
||||||
error = fn(repo, argc, argv);
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
if (giterr_last() == NULL)
|
if (giterr_last() == NULL)
|
||||||
fprintf(stderr, "Error without message");
|
fprintf(stderr, "Error without message");
|
||||||
@ -39,9 +32,6 @@ static int run_command(git_cb fn, int argc, char **argv)
|
|||||||
fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message);
|
fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(repo)
|
|
||||||
git_repository_free(repo);
|
|
||||||
|
|
||||||
return !!error;
|
return !!error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +39,10 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int return_code = 1;
|
int return_code = 1;
|
||||||
|
int error;
|
||||||
|
git_repository *repo;
|
||||||
|
struct args_info args = ARGS_INFO_INIT;
|
||||||
|
const char *git_dir = NULL;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
|
fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
|
||||||
@ -57,9 +51,30 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
git_libgit2_init();
|
git_libgit2_init();
|
||||||
|
|
||||||
|
for (args.pos = 1; args.pos < args.argc; ++args.pos) {
|
||||||
|
char *a = args.argv[args.pos];
|
||||||
|
|
||||||
|
if (a[0] != '-') {
|
||||||
|
/* non-arg */
|
||||||
|
break;
|
||||||
|
} else if (optional_str_arg(&git_dir, &args, "--git-dir", ".git")) {
|
||||||
|
continue;
|
||||||
|
} else if (!strcmp(a, "--")) {
|
||||||
|
/* arg separator */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Before running the actual command, create an instance of the local
|
||||||
|
* repository and pass it to the function. */
|
||||||
|
|
||||||
|
error = git_repository_open(&repo, git_dir);
|
||||||
|
if (error < 0)
|
||||||
|
repo = NULL;
|
||||||
|
|
||||||
for (i = 0; commands[i].name != NULL; ++i) {
|
for (i = 0; commands[i].name != NULL; ++i) {
|
||||||
if (!strcmp(argv[1], commands[i].name)) {
|
if (!strcmp(args.argv[args.pos], commands[i].name)) {
|
||||||
return_code = run_command(commands[i].fn, --argc, ++argv);
|
return_code = run_command(commands[i].fn, repo, args);
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,6 +82,8 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "Command not found: %s\n", argv[1]);
|
fprintf(stderr, "Command not found: %s\n", argv[1]);
|
||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
|
git_repository_free(repo);
|
||||||
|
|
||||||
git_libgit2_shutdown();
|
git_libgit2_shutdown();
|
||||||
|
|
||||||
return return_code;
|
return return_code;
|
||||||
|
@ -53,6 +53,7 @@ ok Jeff King <peff@peff.net>
|
|||||||
ok Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
ok Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
||||||
ok Johannes Sixt <j6t@kdbg.org>
|
ok Johannes Sixt <j6t@kdbg.org>
|
||||||
ask Jonathan Nieder <jrnieder@gmail.com>
|
ask Jonathan Nieder <jrnieder@gmail.com>
|
||||||
|
ok Jonathan Tan <jonathantanmy@google.com>
|
||||||
ok Junio C Hamano <gitster@pobox.com>
|
ok Junio C Hamano <gitster@pobox.com>
|
||||||
ok Kristian Høgsberg <krh@redhat.com>
|
ok Kristian Høgsberg <krh@redhat.com>
|
||||||
ok Linus Torvalds <torvalds@linux-foundation.org>
|
ok Linus Torvalds <torvalds@linux-foundation.org>
|
||||||
|
@ -62,5 +62,6 @@
|
|||||||
#include "git2/tree.h"
|
#include "git2/tree.h"
|
||||||
#include "git2/types.h"
|
#include "git2/types.h"
|
||||||
#include "git2/version.h"
|
#include "git2/version.h"
|
||||||
|
#include "git2/worktree.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -199,6 +199,8 @@ GIT_EXTERN(int) git_config_new(git_config **out);
|
|||||||
* @param path path to the configuration file to add
|
* @param path path to the configuration file to add
|
||||||
* @param level the priority level of the backend
|
* @param level the priority level of the backend
|
||||||
* @param force replace config file at the given priority level
|
* @param force replace config file at the given priority level
|
||||||
|
* @param repo optional repository to allow parsing of
|
||||||
|
* conditional includes
|
||||||
* @return 0 on success, GIT_EEXISTS when adding more than one file
|
* @return 0 on success, GIT_EEXISTS when adding more than one file
|
||||||
* for a given priority level (and force_replace set to 0),
|
* for a given priority level (and force_replace set to 0),
|
||||||
* GIT_ENOTFOUND when the file doesn't exist or error code
|
* GIT_ENOTFOUND when the file doesn't exist or error code
|
||||||
@ -207,6 +209,7 @@ GIT_EXTERN(int) git_config_add_file_ondisk(
|
|||||||
git_config *cfg,
|
git_config *cfg,
|
||||||
const char *path,
|
const char *path,
|
||||||
git_config_level_t level,
|
git_config_level_t level,
|
||||||
|
const git_repository *repo,
|
||||||
int force);
|
int force);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -398,6 +401,10 @@ GIT_EXTERN(int) git_config_get_string_buf(git_buf *out, const git_config *cfg, c
|
|||||||
*
|
*
|
||||||
* The callback will be called on each variable found
|
* The callback will be called on each variable found
|
||||||
*
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the normalized form of
|
||||||
|
* the variable name: the section and variable parts are lower-cased. The
|
||||||
|
* subsection is left unchanged.
|
||||||
|
*
|
||||||
* @param cfg where to look for the variable
|
* @param cfg where to look for the variable
|
||||||
* @param name the variable's name
|
* @param name the variable's name
|
||||||
* @param regexp regular expression to filter which variables we're
|
* @param regexp regular expression to filter which variables we're
|
||||||
@ -410,6 +417,10 @@ GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const cha
|
|||||||
/**
|
/**
|
||||||
* Get each value of a multivar
|
* Get each value of a multivar
|
||||||
*
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the normalized form of
|
||||||
|
* the variable name: the section and variable parts are lower-cased. The
|
||||||
|
* subsection is left unchanged.
|
||||||
|
*
|
||||||
* @param out pointer to store the iterator
|
* @param out pointer to store the iterator
|
||||||
* @param cfg where to look for the variable
|
* @param cfg where to look for the variable
|
||||||
* @param name the variable's name
|
* @param name the variable's name
|
||||||
@ -487,6 +498,8 @@ GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const c
|
|||||||
/**
|
/**
|
||||||
* Set a multivar in the local config file.
|
* Set a multivar in the local config file.
|
||||||
*
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the value.
|
||||||
|
*
|
||||||
* @param cfg where to look for the variable
|
* @param cfg where to look for the variable
|
||||||
* @param name the variable's name
|
* @param name the variable's name
|
||||||
* @param regexp a regular expression to indicate which values to replace
|
* @param regexp a regular expression to indicate which values to replace
|
||||||
@ -506,6 +519,8 @@ GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name);
|
|||||||
/**
|
/**
|
||||||
* Deletes one or several entries from a multivar in the local config file.
|
* Deletes one or several entries from a multivar in the local config file.
|
||||||
*
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the value.
|
||||||
|
*
|
||||||
* @param cfg where to look for the variables
|
* @param cfg where to look for the variables
|
||||||
* @param name the variable's name
|
* @param name the variable's name
|
||||||
* @param regexp a regular expression to indicate which values to delete
|
* @param regexp a regular expression to indicate which values to delete
|
||||||
@ -552,6 +567,10 @@ GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_con
|
|||||||
* Use `git_config_next` to advance the iteration and
|
* Use `git_config_next` to advance the iteration and
|
||||||
* `git_config_iterator_free` when done.
|
* `git_config_iterator_free` when done.
|
||||||
*
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the normalized form of
|
||||||
|
* the variable name: the section and variable parts are lower-cased. The
|
||||||
|
* subsection is left unchanged.
|
||||||
|
*
|
||||||
* @param out pointer to store the iterator
|
* @param out pointer to store the iterator
|
||||||
* @param cfg where to ge the variables from
|
* @param cfg where to ge the variables from
|
||||||
* @param regexp regular expression to match the names
|
* @param regexp regular expression to match the names
|
||||||
@ -565,8 +584,12 @@ GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const gi
|
|||||||
* regular expression that filters which config keys are passed to the
|
* regular expression that filters which config keys are passed to the
|
||||||
* callback.
|
* callback.
|
||||||
*
|
*
|
||||||
* The pointers passed to the callback are only valid as long as the
|
* The regular expression is applied case-sensitively on the normalized form of
|
||||||
* iteration is ongoing.
|
* the variable name: the section and variable parts are lower-cased. The
|
||||||
|
* subsection is left unchanged.
|
||||||
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the normalized form of
|
||||||
|
* the variable name: the case-insensitive parts are lower-case.
|
||||||
*
|
*
|
||||||
* @param cfg where to get the variables from
|
* @param cfg where to get the variables from
|
||||||
* @param regexp regular expression to match against config names
|
* @param regexp regular expression to match against config names
|
||||||
@ -693,6 +716,10 @@ GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value);
|
|||||||
* This behaviors like `git_config_foreach_match` except instead of all config
|
* This behaviors like `git_config_foreach_match` except instead of all config
|
||||||
* entries it just enumerates through the given backend entry.
|
* entries it just enumerates through the given backend entry.
|
||||||
*
|
*
|
||||||
|
* The regular expression is applied case-sensitively on the normalized form of
|
||||||
|
* the variable name: the section and variable parts are lower-cased. The
|
||||||
|
* subsection is left unchanged.
|
||||||
|
*
|
||||||
* @param backend where to get the variables from
|
* @param backend where to get the variables from
|
||||||
* @param regexp regular expression to match against config names (can be NULL)
|
* @param regexp regular expression to match against config names (can be NULL)
|
||||||
* @param callback the function to call on each variable
|
* @param callback the function to call on each variable
|
||||||
|
@ -23,7 +23,7 @@ GIT_BEGIN_DECL
|
|||||||
/**
|
/**
|
||||||
* Reference lookup strategy
|
* Reference lookup strategy
|
||||||
*
|
*
|
||||||
* These behave like the --tags and --all optios to git-describe,
|
* These behave like the --tags and --all options to git-describe,
|
||||||
* namely they say to look for any reference in either refs/tags/ or
|
* namely they say to look for any reference in either refs/tags/ or
|
||||||
* refs/ respectively.
|
* refs/ respectively.
|
||||||
*/
|
*/
|
||||||
|
@ -200,12 +200,18 @@ typedef enum {
|
|||||||
/** Use the "patience diff" algorithm */
|
/** Use the "patience diff" algorithm */
|
||||||
GIT_DIFF_PATIENCE = (1u << 28),
|
GIT_DIFF_PATIENCE = (1u << 28),
|
||||||
/** Take extra time to find minimal diff */
|
/** Take extra time to find minimal diff */
|
||||||
GIT_DIFF_MINIMAL = (1 << 29),
|
GIT_DIFF_MINIMAL = (1u << 29),
|
||||||
|
|
||||||
/** Include the necessary deflate / delta information so that `git-apply`
|
/** Include the necessary deflate / delta information so that `git-apply`
|
||||||
* can apply given diff information to binary files.
|
* can apply given diff information to binary files.
|
||||||
*/
|
*/
|
||||||
GIT_DIFF_SHOW_BINARY = (1 << 30),
|
GIT_DIFF_SHOW_BINARY = (1u << 30),
|
||||||
|
|
||||||
|
/** Use a heuristic that takes indentation and whitespace into account
|
||||||
|
* which generally can produce better diffs when dealing with ambiguous
|
||||||
|
* diff hunks.
|
||||||
|
*/
|
||||||
|
GIT_DIFF_INDENT_HEURISTIC = (1u << 31),
|
||||||
} git_diff_option_t;
|
} git_diff_option_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -515,12 +521,12 @@ typedef int(*git_diff_binary_cb)(
|
|||||||
* Structure describing a hunk of a diff.
|
* Structure describing a hunk of a diff.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int old_start; /** Starting line number in old_file */
|
int old_start; /**< Starting line number in old_file */
|
||||||
int old_lines; /** Number of lines in old_file */
|
int old_lines; /**< Number of lines in old_file */
|
||||||
int new_start; /** Starting line number in new_file */
|
int new_start; /**< Starting line number in new_file */
|
||||||
int new_lines; /** Number of lines in new_file */
|
int new_lines; /**< Number of lines in new_file */
|
||||||
size_t header_len; /** Number of bytes in header text */
|
size_t header_len; /**< Number of bytes in header text */
|
||||||
char header[GIT_DIFF_HUNK_HEADER_SIZE]; /** Header text, NUL-byte terminated */
|
char header[GIT_DIFF_HUNK_HEADER_SIZE]; /**< Header text, NUL-byte terminated */
|
||||||
} git_diff_hunk;
|
} git_diff_hunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1400,6 +1406,51 @@ GIT_EXTERN(int) git_diff_format_email_init_options(
|
|||||||
git_diff_format_email_options *opts,
|
git_diff_format_email_options *opts,
|
||||||
unsigned int version);
|
unsigned int version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch ID options structure
|
||||||
|
*
|
||||||
|
* Initialize with `GIT_DIFF_PATCHID_OPTIONS_INIT` macro to
|
||||||
|
* correctly set the default values and version.
|
||||||
|
*/
|
||||||
|
typedef struct git_diff_patchid_options {
|
||||||
|
unsigned int version;
|
||||||
|
} git_diff_patchid_options;
|
||||||
|
|
||||||
|
#define GIT_DIFF_PATCHID_OPTIONS_VERSION 1
|
||||||
|
#define GIT_DIFF_PATCHID_OPTIONS_INIT { GIT_DIFF_PATCHID_OPTIONS_VERSION }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize `git_diff_patchid_options` structure.
|
||||||
|
*
|
||||||
|
* Initializes the structure with default values. Equivalent to
|
||||||
|
* creating an instance with `GIT_DIFF_PATCHID_OPTIONS_INIT`.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_diff_patchid_init_options(
|
||||||
|
git_diff_patchid_options *opts,
|
||||||
|
unsigned int version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the patch ID for the given patch.
|
||||||
|
*
|
||||||
|
* Calculate a stable patch ID for the given patch by summing the
|
||||||
|
* hash of the file diffs, ignoring whitespace and line numbers.
|
||||||
|
* This can be used to derive whether two diffs are the same with
|
||||||
|
* a high probability.
|
||||||
|
*
|
||||||
|
* Currently, this function only calculates stable patch IDs, as
|
||||||
|
* defined in git-patch-id(1), and should in fact generate the
|
||||||
|
* same IDs as the upstream git project does.
|
||||||
|
*
|
||||||
|
* @param out Pointer where the calculated patch ID shoul be
|
||||||
|
* stored
|
||||||
|
* @param diff The diff to calculate the ID for
|
||||||
|
* @param opts Options for how to calculate the patch ID. This is
|
||||||
|
* intended for future changes, as currently no options are
|
||||||
|
* available.
|
||||||
|
* @return 0 on success, an error code otherwise.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opts);
|
||||||
|
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -40,6 +40,9 @@ GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_reposi
|
|||||||
/**
|
/**
|
||||||
* Determine if a commit is the descendant of another commit.
|
* Determine if a commit is the descendant of another commit.
|
||||||
*
|
*
|
||||||
|
* Note that a commit is not considered a descendant of itself, in contrast
|
||||||
|
* to `git merge-base --is-ancestor`.
|
||||||
|
*
|
||||||
* @param commit a previously loaded commit.
|
* @param commit a previously loaded commit.
|
||||||
* @param ancestor a potential ancestor commit.
|
* @param ancestor a potential ancestor commit.
|
||||||
* @return 1 if the given commit is a descendant of the potential ancestor,
|
* @return 1 if the given commit is a descendant of the potential ancestor,
|
||||||
|
@ -162,6 +162,8 @@ typedef enum {
|
|||||||
GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
|
GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
|
||||||
} git_merge_file_flag_t;
|
} git_merge_file_flag_t;
|
||||||
|
|
||||||
|
#define GIT_MERGE_CONFLICT_MARKER_SIZE 7
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for merging a file
|
* Options for merging a file
|
||||||
*/
|
*/
|
||||||
@ -191,6 +193,10 @@ typedef struct {
|
|||||||
|
|
||||||
/** see `git_merge_file_flag_t` above */
|
/** see `git_merge_file_flag_t` above */
|
||||||
git_merge_file_flag_t flags;
|
git_merge_file_flag_t flags;
|
||||||
|
|
||||||
|
/** The size of conflict markers (eg, "<<<<<<<"). Default is
|
||||||
|
* GIT_MERGE_CONFLICT_MARKER_SIZE. */
|
||||||
|
unsigned short marker_size;
|
||||||
} git_merge_file_options;
|
} git_merge_file_options;
|
||||||
|
|
||||||
#define GIT_MERGE_FILE_OPTIONS_VERSION 1
|
#define GIT_MERGE_FILE_OPTIONS_VERSION 1
|
||||||
|
@ -19,10 +19,9 @@
|
|||||||
GIT_BEGIN_DECL
|
GIT_BEGIN_DECL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean up message from excess whitespace and make sure that the last line
|
* Clean up excess whitespace and make sure there is a trailing newline in the message.
|
||||||
* ends with a '\n'.
|
|
||||||
*
|
*
|
||||||
* Optionally, can remove lines starting with a "#".
|
* Optionally, it can remove lines which start with the comment character.
|
||||||
*
|
*
|
||||||
* @param out The user-allocated git_buf which will be filled with the
|
* @param out The user-allocated git_buf which will be filled with the
|
||||||
* cleaned up message.
|
* cleaned up message.
|
||||||
@ -38,6 +37,47 @@ GIT_BEGIN_DECL
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
|
GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single git message trailer.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
const char *key;
|
||||||
|
const char *value;
|
||||||
|
} git_message_trailer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an array of git message trailers.
|
||||||
|
*
|
||||||
|
* Struct members under the private comment are private, subject to change
|
||||||
|
* and should not be used by callers.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
git_message_trailer *trailers;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
char *_trailer_block;
|
||||||
|
} git_message_trailer_array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse trailers out of a message, filling the array pointed to by +arr+.
|
||||||
|
*
|
||||||
|
* Trailers are key/value pairs in the last paragraph of a message, not
|
||||||
|
* including any patches or conflicts that may be present.
|
||||||
|
*
|
||||||
|
* @param arr A pre-allocated git_message_trailer_array struct to be filled in
|
||||||
|
* with any trailers found during parsing.
|
||||||
|
* @param message The message to be parsed
|
||||||
|
* @return 0 on success, or non-zero on error.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_message_trailers(git_message_trailer_array *arr, const char *message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean's up any allocated memory in the git_message_trailer_array filled by
|
||||||
|
* a call to git_message_trailers.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(void) git_message_trailer_array_free(git_message_trailer_array *arr);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
|
|
||||||
|
@ -51,6 +51,20 @@ GIT_EXTERN(int) git_note_iterator_new(
|
|||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
const char *notes_ref);
|
const char *notes_ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new iterator for notes from a commit
|
||||||
|
*
|
||||||
|
* The iterator must be freed manually by the user.
|
||||||
|
*
|
||||||
|
* @param out pointer to the iterator
|
||||||
|
* @param notes_commit a pointer to the notes commit object
|
||||||
|
*
|
||||||
|
* @return 0 or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_note_commit_iterator_new(
|
||||||
|
git_note_iterator **out,
|
||||||
|
git_commit *notes_commit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees an git_note_iterator
|
* Frees an git_note_iterator
|
||||||
*
|
*
|
||||||
@ -94,6 +108,25 @@ GIT_EXTERN(int) git_note_read(
|
|||||||
const char *notes_ref,
|
const char *notes_ref,
|
||||||
const git_oid *oid);
|
const git_oid *oid);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the note for an object from a note commit
|
||||||
|
*
|
||||||
|
* The note must be freed manually by the user.
|
||||||
|
*
|
||||||
|
* @param out pointer to the read note; NULL in case of error
|
||||||
|
* @param repo repository where to look up the note
|
||||||
|
* @param notes_commit a pointer to the notes commit object
|
||||||
|
* @param oid OID of the git object to read the note from
|
||||||
|
*
|
||||||
|
* @return 0 or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_note_commit_read(
|
||||||
|
git_note **out,
|
||||||
|
git_repository *repo,
|
||||||
|
git_commit *notes_commit,
|
||||||
|
const git_oid *oid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the note author
|
* Get the note author
|
||||||
*
|
*
|
||||||
@ -153,6 +186,36 @@ GIT_EXTERN(int) git_note_create(
|
|||||||
const char *note,
|
const char *note,
|
||||||
int force);
|
int force);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a note for an object from a commit
|
||||||
|
*
|
||||||
|
* This function will create a notes commit for a given object,
|
||||||
|
* the commit is a dangling commit, no reference is created.
|
||||||
|
*
|
||||||
|
* @param notes_commit_out pointer to store the commit (optional);
|
||||||
|
* NULL in case of error
|
||||||
|
* @param notes_blob_out a point to the id of a note blob (optional)
|
||||||
|
* @param repo repository where the note will live
|
||||||
|
* @param parent Pointer to parent note
|
||||||
|
* or NULL if this shall start a new notes tree
|
||||||
|
* @param author signature of the notes commit author
|
||||||
|
* @param committer signature of the notes commit committer
|
||||||
|
* @param oid OID of the git object to decorate
|
||||||
|
* @param note Content of the note to add for object oid
|
||||||
|
* @param allow_note_overwrite Overwrite existing note
|
||||||
|
*
|
||||||
|
* @return 0 or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_note_commit_create(
|
||||||
|
git_oid *notes_commit_out,
|
||||||
|
git_oid *notes_blob_out,
|
||||||
|
git_repository *repo,
|
||||||
|
git_commit *parent,
|
||||||
|
const git_signature *author,
|
||||||
|
const git_signature *committer,
|
||||||
|
const git_oid *oid,
|
||||||
|
const char *note,
|
||||||
|
int allow_note_overwrite);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the note for an object
|
* Remove the note for an object
|
||||||
@ -173,6 +236,32 @@ GIT_EXTERN(int) git_note_remove(
|
|||||||
const git_signature *committer,
|
const git_signature *committer,
|
||||||
const git_oid *oid);
|
const git_oid *oid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the note for an object
|
||||||
|
*
|
||||||
|
* @param notes_commit_out pointer to store the new notes commit (optional);
|
||||||
|
* NULL in case of error.
|
||||||
|
* When removing a note a new tree containing all notes
|
||||||
|
* sans the note to be removed is created and a new commit
|
||||||
|
* pointing to that tree is also created.
|
||||||
|
* In the case where the resulting tree is an empty tree
|
||||||
|
* a new commit pointing to this empty tree will be returned.
|
||||||
|
* @param repo repository where the note lives
|
||||||
|
* @param notes_commit a pointer to the notes commit object
|
||||||
|
* @param author signature of the notes commit author
|
||||||
|
* @param committer signature of the notes commit committer
|
||||||
|
* @param oid OID of the git object to remove the note from
|
||||||
|
*
|
||||||
|
* @return 0 or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_note_commit_remove(
|
||||||
|
git_oid *notes_commit_out,
|
||||||
|
git_repository *repo,
|
||||||
|
git_commit *notes_commit,
|
||||||
|
const git_signature *author,
|
||||||
|
const git_signature *committer,
|
||||||
|
const git_oid *oid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a git_note object
|
* Free a git_note object
|
||||||
*
|
*
|
||||||
|
@ -357,11 +357,18 @@ GIT_EXTERN(void) git_odb_stream_free(git_odb_stream *stream);
|
|||||||
* @see git_odb_stream
|
* @see git_odb_stream
|
||||||
*
|
*
|
||||||
* @param out pointer where to store the stream
|
* @param out pointer where to store the stream
|
||||||
|
* @param len pointer where to store the length of the object
|
||||||
|
* @param type pointer where to store the type of the object
|
||||||
* @param db object database where the stream will read from
|
* @param db object database where the stream will read from
|
||||||
* @param oid oid of the object the stream will read from
|
* @param oid oid of the object the stream will read from
|
||||||
* @return 0 if the stream was created; error code otherwise
|
* @return 0 if the stream was created; error code otherwise
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const git_oid *oid);
|
GIT_EXTERN(int) git_odb_open_rstream(
|
||||||
|
git_odb_stream **out,
|
||||||
|
size_t *len,
|
||||||
|
git_otype *type,
|
||||||
|
git_odb *db,
|
||||||
|
const git_oid *oid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a stream for writing a pack file to the ODB.
|
* Open a stream for writing a pack file to the ODB.
|
||||||
|
@ -96,7 +96,7 @@ GIT_EXTERN(int) git_patch_from_blob_and_buffer(
|
|||||||
git_patch **out,
|
git_patch **out,
|
||||||
const git_blob *old_blob,
|
const git_blob *old_blob,
|
||||||
const char *old_as_path,
|
const char *old_as_path,
|
||||||
const char *buffer,
|
const void *buffer,
|
||||||
size_t buffer_len,
|
size_t buffer_len,
|
||||||
const char *buffer_as_path,
|
const char *buffer_as_path,
|
||||||
const git_diff_options *opts);
|
const git_diff_options *opts);
|
||||||
@ -124,7 +124,7 @@ GIT_EXTERN(int) git_patch_from_buffers(
|
|||||||
const void *old_buffer,
|
const void *old_buffer,
|
||||||
size_t old_len,
|
size_t old_len,
|
||||||
const char *old_as_path,
|
const char *old_as_path,
|
||||||
const char *new_buffer,
|
const void *new_buffer,
|
||||||
size_t new_len,
|
size_t new_len,
|
||||||
const char *new_as_path,
|
const char *new_as_path,
|
||||||
const git_diff_options *opts);
|
const git_diff_options *opts);
|
||||||
|
@ -26,32 +26,49 @@ typedef struct git_pathspec_match_list git_pathspec_match_list;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Options controlling how pathspec match should be executed
|
* Options controlling how pathspec match should be executed
|
||||||
*
|
|
||||||
* - GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
|
|
||||||
* match will use native case sensitivity of platform filesystem
|
|
||||||
* - GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
|
|
||||||
* match will use native case sensitivity of platform filesystem
|
|
||||||
* - GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
|
|
||||||
* string comparison for matching
|
|
||||||
* - GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
|
|
||||||
* code GIT_ENOTFOUND if no matches are found; otherwise no matches is
|
|
||||||
* still success (return 0) but `git_pathspec_match_list_entrycount`
|
|
||||||
* will indicate 0 matches.
|
|
||||||
* - GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
|
|
||||||
* should track which patterns matched which files so that at the end of
|
|
||||||
* the match we can identify patterns that did not match any files.
|
|
||||||
* - GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
|
|
||||||
* does not need to keep the actual matching filenames. Use this to
|
|
||||||
* just test if there were any matches at all or in combination with
|
|
||||||
* GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
|
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GIT_PATHSPEC_DEFAULT = 0,
|
GIT_PATHSPEC_DEFAULT = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
|
||||||
|
* match will use native case sensitivity of platform filesystem
|
||||||
|
*/
|
||||||
GIT_PATHSPEC_IGNORE_CASE = (1u << 0),
|
GIT_PATHSPEC_IGNORE_CASE = (1u << 0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
|
||||||
|
* match will use native case sensitivity of platform filesystem
|
||||||
|
*/
|
||||||
GIT_PATHSPEC_USE_CASE = (1u << 1),
|
GIT_PATHSPEC_USE_CASE = (1u << 1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
|
||||||
|
* string comparison for matching
|
||||||
|
*/
|
||||||
GIT_PATHSPEC_NO_GLOB = (1u << 2),
|
GIT_PATHSPEC_NO_GLOB = (1u << 2),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
|
||||||
|
* code GIT_ENOTFOUND if no matches are found; otherwise no matches is
|
||||||
|
* still success (return 0) but `git_pathspec_match_list_entrycount`
|
||||||
|
* will indicate 0 matches.
|
||||||
|
*/
|
||||||
GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
|
GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
|
||||||
|
* should track which patterns matched which files so that at the end of
|
||||||
|
* the match we can identify patterns that did not match any files.
|
||||||
|
*/
|
||||||
GIT_PATHSPEC_FIND_FAILURES = (1u << 4),
|
GIT_PATHSPEC_FIND_FAILURES = (1u << 4),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
|
||||||
|
* does not need to keep the actual matching filenames. Use this to
|
||||||
|
* just test if there were any matches at all or in combination with
|
||||||
|
* GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
|
||||||
|
*/
|
||||||
GIT_PATHSPEC_FAILURES_ONLY = (1u << 5),
|
GIT_PATHSPEC_FAILURES_ONLY = (1u << 5),
|
||||||
} git_pathspec_flag_t;
|
} git_pathspec_flag_t;
|
||||||
|
|
||||||
|
@ -433,6 +433,9 @@ typedef int (*git_reference_foreach_name_cb)(const char *name, void *payload);
|
|||||||
* passed to this method. Returning a non-zero value from the callback
|
* passed to this method. Returning a non-zero value from the callback
|
||||||
* will terminate the iteration.
|
* will terminate the iteration.
|
||||||
*
|
*
|
||||||
|
* Note that the callback function is responsible to call `git_reference_free`
|
||||||
|
* on each reference passed to it.
|
||||||
|
*
|
||||||
* @param repo Repository where to find the refs
|
* @param repo Repository where to find the refs
|
||||||
* @param callback Function which will be called for every listed ref
|
* @param callback Function which will be called for every listed ref
|
||||||
* @param payload Additional data to pass to the callback
|
* @param payload Additional data to pass to the callback
|
||||||
|
@ -75,6 +75,24 @@ GIT_EXTERN(int) git_remote_create_anonymous(
|
|||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
const char *url);
|
const char *url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a remote without a connected local repo
|
||||||
|
*
|
||||||
|
* Create a remote with the given url in-memory. You can use this when
|
||||||
|
* you have a URL instead of a remote's name.
|
||||||
|
*
|
||||||
|
* Contrasted with git_remote_create_anonymous, a detached remote
|
||||||
|
* will not consider any repo configuration values (such as insteadof url
|
||||||
|
* substitutions).
|
||||||
|
*
|
||||||
|
* @param out pointer to the new remote objects
|
||||||
|
* @param url the remote repository's URL
|
||||||
|
* @return 0 or an error code
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_remote_create_detached(
|
||||||
|
git_remote **out,
|
||||||
|
const char *url);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the information for a particular remote
|
* Get the information for a particular remote
|
||||||
*
|
*
|
||||||
@ -367,6 +385,20 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);
|
typedef int (*git_push_negotiation)(const git_push_update **updates, size_t len, void *payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used to inform of the update status from the remote.
|
||||||
|
*
|
||||||
|
* Called for each updated reference on push. If `status` is
|
||||||
|
* not `NULL`, the update was rejected by the remote server
|
||||||
|
* and `status` contains the reason given.
|
||||||
|
*
|
||||||
|
* @param refname refname specifying to the remote ref
|
||||||
|
* @param status status message sent from the remote
|
||||||
|
* @param data data provided by the caller
|
||||||
|
* @return 0 on success, otherwise an error
|
||||||
|
*/
|
||||||
|
typedef int (*git_push_update_reference_cb)(const char *refname, const char *status, void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The callback settings structure
|
* The callback settings structure
|
||||||
*
|
*
|
||||||
@ -434,11 +466,9 @@ struct git_remote_callbacks {
|
|||||||
git_push_transfer_progress push_transfer_progress;
|
git_push_transfer_progress push_transfer_progress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called for each updated reference on push. If `status` is
|
* See documentation of git_push_update_reference_cb
|
||||||
* not `NULL`, the update was rejected by the remote server
|
|
||||||
* and `status` contains the reason given.
|
|
||||||
*/
|
*/
|
||||||
int (*push_update_reference)(const char *refname, const char *status, void *data);
|
git_push_update_reference_cb push_update_reference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called once between the negotiation step and the upload. It
|
* Called once between the negotiation step and the upload. It
|
||||||
|
@ -440,7 +440,7 @@ typedef enum {
|
|||||||
* @param item The repository item for which to retrieve the path
|
* @param item The repository item for which to retrieve the path
|
||||||
* @return 0, GIT_ENOTFOUND if the path cannot exist or an error code
|
* @return 0, GIT_ENOTFOUND if the path cannot exist or an error code
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item);
|
GIT_EXTERN(int) git_repository_item_path(git_buf *out, const git_repository *repo, git_repository_item_t item);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path of this repository
|
* Get the path of this repository
|
||||||
@ -451,7 +451,7 @@ GIT_EXTERN(int) git_repository_item_path(git_buf *out, git_repository *repo, git
|
|||||||
* @param repo A repository object
|
* @param repo A repository object
|
||||||
* @return the path to the repository
|
* @return the path to the repository
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(const char *) git_repository_path(git_repository *repo);
|
GIT_EXTERN(const char *) git_repository_path(const git_repository *repo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path of the working directory for this repository
|
* Get the path of the working directory for this repository
|
||||||
@ -462,7 +462,7 @@ GIT_EXTERN(const char *) git_repository_path(git_repository *repo);
|
|||||||
* @param repo A repository object
|
* @param repo A repository object
|
||||||
* @return the path to the working dir, if it exists
|
* @return the path to the working dir, if it exists
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
|
GIT_EXTERN(const char *) git_repository_workdir(const git_repository *repo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path of the shared common directory for this repository
|
* Get the path of the shared common directory for this repository
|
||||||
@ -473,7 +473,7 @@ GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
|
|||||||
* @param repo A repository object
|
* @param repo A repository object
|
||||||
* @return the path to the common dir
|
* @return the path to the common dir
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(const char *) git_repository_commondir(git_repository *repo);
|
GIT_EXTERN(const char *) git_repository_commondir(const git_repository *repo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the path to the working directory for this repository
|
* Set the path to the working directory for this repository
|
||||||
@ -501,7 +501,7 @@ GIT_EXTERN(int) git_repository_set_workdir(
|
|||||||
* @param repo Repo to test
|
* @param repo Repo to test
|
||||||
* @return 1 if the repository is bare, 0 otherwise.
|
* @return 1 if the repository is bare, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
|
GIT_EXTERN(int) git_repository_is_bare(const git_repository *repo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a repository is a linked work tree
|
* Check if a repository is a linked work tree
|
||||||
@ -509,7 +509,7 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
|
|||||||
* @param repo Repo to test
|
* @param repo Repo to test
|
||||||
* @return 1 if the repository is a linked work tree, 0 otherwise.
|
* @return 1 if the repository is a linked work tree, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_repository_is_worktree(git_repository *repo);
|
GIT_EXTERN(int) git_repository_is_worktree(const git_repository *repo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the configuration file for this repository.
|
* Get the configuration file for this repository.
|
||||||
|
@ -61,7 +61,7 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_reset(
|
GIT_EXTERN(int) git_reset(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
git_object *target,
|
const git_object *target,
|
||||||
git_reset_t reset_type,
|
git_reset_t reset_type,
|
||||||
const git_checkout_options *checkout_opts);
|
const git_checkout_options *checkout_opts);
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ GIT_EXTERN(int) git_reset(
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_reset_from_annotated(
|
GIT_EXTERN(int) git_reset_from_annotated(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
git_annotated_commit *commit,
|
const git_annotated_commit *commit,
|
||||||
git_reset_t reset_type,
|
git_reset_t reset_type,
|
||||||
const git_checkout_options *checkout_opts);
|
const git_checkout_options *checkout_opts);
|
||||||
|
|
||||||
@ -103,8 +103,8 @@ GIT_EXTERN(int) git_reset_from_annotated(
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_reset_default(
|
GIT_EXTERN(int) git_reset_default(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
git_object *target,
|
const git_object *target,
|
||||||
git_strarray* pathspecs);
|
const git_strarray* pathspecs);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
|
@ -173,12 +173,16 @@ typedef enum {
|
|||||||
* The `pathspec` is an array of path patterns to match (using
|
* The `pathspec` is an array of path patterns to match (using
|
||||||
* fnmatch-style matching), or just an array of paths to match exactly if
|
* fnmatch-style matching), or just an array of paths to match exactly if
|
||||||
* `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags.
|
* `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags.
|
||||||
|
*
|
||||||
|
* The `baseline` is the tree to be used for comparison to the working directory
|
||||||
|
* and index; defaults to HEAD.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
git_status_show_t show;
|
git_status_show_t show;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
git_strarray pathspec;
|
git_strarray pathspec;
|
||||||
|
git_tree *baseline;
|
||||||
} git_status_options;
|
} git_status_options;
|
||||||
|
|
||||||
#define GIT_STATUS_OPTIONS_VERSION 1
|
#define GIT_STATUS_OPTIONS_VERSION 1
|
||||||
|
@ -58,7 +58,7 @@ struct git_config_backend {
|
|||||||
struct git_config *cfg;
|
struct git_config *cfg;
|
||||||
|
|
||||||
/* Open means open the file/database and parse if necessary */
|
/* Open means open the file/database and parse if necessary */
|
||||||
int (*open)(struct git_config_backend *, git_config_level_t level);
|
int (*open)(struct git_config_backend *, git_config_level_t level, const git_repository *repo);
|
||||||
int (*get)(struct git_config_backend *, const char *key, git_config_entry **entry);
|
int (*get)(struct git_config_backend *, const char *key, git_config_entry **entry);
|
||||||
int (*set)(struct git_config_backend *, const char *key, const char *value);
|
int (*set)(struct git_config_backend *, const char *key, const char *value);
|
||||||
int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
|
int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
|
||||||
@ -111,6 +111,8 @@ GIT_EXTERN(int) git_config_init_backend(
|
|||||||
* @param cfg the configuration to add the file to
|
* @param cfg the configuration to add the file to
|
||||||
* @param file the configuration file (backend) to add
|
* @param file the configuration file (backend) to add
|
||||||
* @param level the priority level of the backend
|
* @param level the priority level of the backend
|
||||||
|
* @param repo optional repository to allow parsing of
|
||||||
|
* conditional includes
|
||||||
* @param force if a config file already exists for the given
|
* @param force if a config file already exists for the given
|
||||||
* priority level, replace it
|
* priority level, replace it
|
||||||
* @return 0 on success, GIT_EEXISTS when adding more than one file
|
* @return 0 on success, GIT_EEXISTS when adding more than one file
|
||||||
@ -120,6 +122,7 @@ GIT_EXTERN(int) git_config_add_backend(
|
|||||||
git_config *cfg,
|
git_config *cfg,
|
||||||
git_config_backend *file,
|
git_config_backend *file,
|
||||||
git_config_level_t level,
|
git_config_level_t level,
|
||||||
|
const git_repository *repo,
|
||||||
int force);
|
int force);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "git2/types.h"
|
#include "git2/types.h"
|
||||||
#include "git2/oid.h"
|
#include "git2/oid.h"
|
||||||
#include "git2/odb.h"
|
#include "git2/odb.h"
|
||||||
|
#include "git2/buffer.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file git2/sys/mempack.h
|
* @file git2/sys/mempack.h
|
||||||
@ -38,10 +39,10 @@ GIT_BEGIN_DECL
|
|||||||
* Subsequent reads will also be served from the in-memory store
|
* Subsequent reads will also be served from the in-memory store
|
||||||
* to ensure consistency, until the memory store is dumped.
|
* to ensure consistency, until the memory store is dumped.
|
||||||
*
|
*
|
||||||
* @param out Poiter where to store the ODB backend
|
* @param out Pointer where to store the ODB backend
|
||||||
* @return 0 on success; error code otherwise
|
* @return 0 on success; error code otherwise
|
||||||
*/
|
*/
|
||||||
int git_mempack_new(git_odb_backend **out);
|
GIT_EXTERN(int) git_mempack_new(git_odb_backend **out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump all the queued in-memory writes to a packfile.
|
* Dump all the queued in-memory writes to a packfile.
|
||||||
@ -64,7 +65,7 @@ int git_mempack_new(git_odb_backend **out);
|
|||||||
* @param backend The mempack backend
|
* @param backend The mempack backend
|
||||||
* @return 0 on success; error code otherwise
|
* @return 0 on success; error code otherwise
|
||||||
*/
|
*/
|
||||||
int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *backend);
|
GIT_EXTERN(int) git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *backend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the memory packer by clearing all the queued objects.
|
* Reset the memory packer by clearing all the queued objects.
|
||||||
@ -78,7 +79,7 @@ int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *backe
|
|||||||
*
|
*
|
||||||
* @param backend The mempack backend
|
* @param backend The mempack backend
|
||||||
*/
|
*/
|
||||||
void git_mempack_reset(git_odb_backend *backend);
|
GIT_EXTERN(void) git_mempack_reset(git_odb_backend *backend);
|
||||||
|
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ struct git_odb_backend {
|
|||||||
git_odb_stream **, git_odb_backend *, git_off_t, git_otype);
|
git_odb_stream **, git_odb_backend *, git_off_t, git_otype);
|
||||||
|
|
||||||
int (* readstream)(
|
int (* readstream)(
|
||||||
git_odb_stream **, git_odb_backend *, const git_oid *);
|
git_odb_stream **, size_t *, git_otype *,
|
||||||
|
git_odb_backend *, const git_oid *);
|
||||||
|
|
||||||
int (* exists)(
|
int (* exists)(
|
||||||
git_odb_backend *, const git_oid *);
|
git_odb_backend *, const git_oid *);
|
||||||
|
@ -1,16 +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_sys_git_transport_h
|
|
||||||
#define INCLUDE_sys_git_transport_h
|
|
||||||
|
|
||||||
#include "git2/net.h"
|
|
||||||
#include "git2/types.h"
|
|
||||||
|
|
||||||
GIT_BEGIN_DECL
|
|
||||||
|
|
||||||
GIT_END_DECL
|
|
@ -307,9 +307,10 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
|
|||||||
* pointer may not be valid past the next operation in this
|
* pointer may not be valid past the next operation in this
|
||||||
* builder. Duplicate the entry if you want to keep it.
|
* builder. Duplicate the entry if you want to keep it.
|
||||||
*
|
*
|
||||||
* No attempt is being made to ensure that the provided oid points
|
* By default the entry that you are inserting will be checked for
|
||||||
* to an existing git object in the object database, nor that the
|
* validity; that it exists in the object database and is of the
|
||||||
* attributes make sense regarding the type of the pointed at object.
|
* correct type. If you do not want this behavior, set the
|
||||||
|
* `GIT_OPT_ENABLE_STRICT_OBJECT_CREATION` library option to false.
|
||||||
*
|
*
|
||||||
* @param out Pointer to store the entry (optional)
|
* @param out Pointer to store the entry (optional)
|
||||||
* @param bld Tree builder
|
* @param bld Tree builder
|
||||||
|
@ -159,6 +159,7 @@ typedef struct git_packbuilder git_packbuilder;
|
|||||||
typedef struct git_time {
|
typedef struct git_time {
|
||||||
git_time_t time; /**< time in seconds from epoch */
|
git_time_t time; /**< time in seconds from epoch */
|
||||||
int offset; /**< timezone offset, in minutes */
|
int offset; /**< timezone offset, in minutes */
|
||||||
|
char sign; /**< indicator for questionable '-0000' offsets in signature */
|
||||||
} git_time;
|
} git_time;
|
||||||
|
|
||||||
/** An action signature (e.g. for committers, taggers, etc) */
|
/** An action signature (e.g. for committers, taggers, etc) */
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
#ifndef INCLUDE_git_version_h__
|
#ifndef INCLUDE_git_version_h__
|
||||||
#define INCLUDE_git_version_h__
|
#define INCLUDE_git_version_h__
|
||||||
|
|
||||||
#define LIBGIT2_VERSION "0.26.0"
|
#define LIBGIT2_VERSION "0.27.0"
|
||||||
#define LIBGIT2_VER_MAJOR 0
|
#define LIBGIT2_VER_MAJOR 0
|
||||||
#define LIBGIT2_VER_MINOR 26
|
#define LIBGIT2_VER_MINOR 27
|
||||||
#define LIBGIT2_VER_REVISION 0
|
#define LIBGIT2_VER_REVISION 0
|
||||||
#define LIBGIT2_VER_PATCH 0
|
#define LIBGIT2_VER_PATCH 0
|
||||||
|
|
||||||
#define LIBGIT2_SOVERSION 26
|
#define LIBGIT2_SOVERSION 27
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -123,7 +123,7 @@ GIT_EXTERN(int) git_worktree_add(git_worktree **out, git_repository *repo,
|
|||||||
* @param reason Reason why the working tree is being locked
|
* @param reason Reason why the working tree is being locked
|
||||||
* @return 0 on success, non-zero otherwise
|
* @return 0 on success, non-zero otherwise
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_worktree_lock(git_worktree *wt, char *reason);
|
GIT_EXTERN(int) git_worktree_lock(git_worktree *wt, const char *reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlock a locked worktree
|
* Unlock a locked worktree
|
||||||
|
@ -19,5 +19,5 @@ fi
|
|||||||
cd build
|
cd build
|
||||||
gcc --version
|
gcc --version
|
||||||
cmake --version
|
cmake --version
|
||||||
cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON .. -G"$GENERATOR"
|
cmake -D ENABLE_TRACE=ON -D BUILD_CLAR=ON -D BUILD_EXAMPLES=ON .. -G"$GENERATOR"
|
||||||
cmake --build . --config RelWithDebInfo
|
cmake --build . --config RelWithDebInfo
|
||||||
|
@ -10,6 +10,15 @@ fi
|
|||||||
|
|
||||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
export PKG_CONFIG_PATH=$(ls -d /usr/local/Cellar/{curl,zlib}/*/lib/pkgconfig | paste -s -d':' -)
|
export PKG_CONFIG_PATH=$(ls -d /usr/local/Cellar/{curl,zlib}/*/lib/pkgconfig | paste -s -d':' -)
|
||||||
|
|
||||||
|
# Set up a ramdisk for us to put our test data on to speed up tests on macOS
|
||||||
|
export CLAR_TMP="$HOME"/_clar_tmp
|
||||||
|
mkdir -p $CLAR_TMP
|
||||||
|
|
||||||
|
# 5*2M sectors aka ~5GB of space
|
||||||
|
device=$(hdiutil attach -nomount ram://$((5 * 2 * 1024 * 1024)))
|
||||||
|
newfs_hfs $device
|
||||||
|
mount -t hfs $device $CLAR_TMP
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Should we ask Travis to cache this file?
|
# Should we ask Travis to cache this file?
|
||||||
@ -43,46 +52,51 @@ ctest -V -R libgit2_clar || exit $?
|
|||||||
|
|
||||||
killall git-daemon
|
killall git-daemon
|
||||||
|
|
||||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
# Set up sshd
|
||||||
echo 'PasswordAuthentication yes' | sudo tee -a /etc/sshd_config
|
mkdir ~/sshd/
|
||||||
fi
|
cat >~/sshd/sshd_config<<-EOF
|
||||||
|
Port 2222
|
||||||
|
ListenAddress 0.0.0.0
|
||||||
|
Protocol 2
|
||||||
|
HostKey ${HOME}/sshd/id_rsa
|
||||||
|
PidFile ${HOME}/sshd/pid
|
||||||
|
RSAAuthentication yes
|
||||||
|
PasswordAuthentication yes
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
ChallengeResponseAuthentication no
|
||||||
|
# Required here as sshd will simply close connection otherwise
|
||||||
|
UsePAM no
|
||||||
|
EOF
|
||||||
|
ssh-keygen -t rsa -f ~/sshd/id_rsa -N "" -q
|
||||||
|
/usr/sbin/sshd -f ~/sshd/sshd_config
|
||||||
|
|
||||||
|
# Set up keys
|
||||||
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q
|
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q
|
||||||
cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
|
cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
|
||||||
ssh-keyscan -t rsa localhost >>~/.ssh/known_hosts
|
while read algorithm key comment; do
|
||||||
|
echo "[localhost]:2222 $algorithm $key" >>~/.ssh/known_hosts
|
||||||
|
done <~/sshd/id_rsa.pub
|
||||||
|
|
||||||
# Get the fingerprint for localhost and remove the colons so we can parse it as
|
# Get the fingerprint for localhost and remove the colons so we can parse it as
|
||||||
# a hex number. The Mac version is newer so it has a different output format.
|
# a hex number. The Mac version is newer so it has a different output format.
|
||||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -E md5 -F localhost -l | tail -n 1 | cut -d ' ' -f 3 | cut -d : -f2- | tr -d :)
|
export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -E md5 -F '[localhost]:2222' -l | tail -n 1 | cut -d ' ' -f 3 | cut -d : -f2- | tr -d :)
|
||||||
else
|
else
|
||||||
export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F localhost -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':')
|
export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F '[localhost]:2222' -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export GITTEST_REMOTE_URL="ssh://localhost/$HOME/_temp/test.git"
|
# Use the SSH server
|
||||||
|
export GITTEST_REMOTE_URL="ssh://localhost:2222/$HOME/_temp/test.git"
|
||||||
export GITTEST_REMOTE_USER=$USER
|
export GITTEST_REMOTE_USER=$USER
|
||||||
export GITTEST_REMOTE_SSH_KEY="$HOME/.ssh/id_rsa"
|
export GITTEST_REMOTE_SSH_KEY="$HOME/.ssh/id_rsa"
|
||||||
export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub"
|
export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub"
|
||||||
export GITTEST_REMOTE_SSH_PASSPHRASE=""
|
export GITTEST_REMOTE_SSH_PASSPHRASE=""
|
||||||
|
ctest -V -R libgit2_clar-ssh || exit $?
|
||||||
|
|
||||||
|
# Use the proxy we started at the beginning
|
||||||
|
export GITTEST_REMOTE_PROXY_URL="localhost:8080"
|
||||||
|
export GITTEST_REMOTE_PROXY_USER="foo"
|
||||||
|
export GITTEST_REMOTE_PROXY_PASS="bar"
|
||||||
|
ctest -V -R libgit2_clar-proxy_credentials || exit $?
|
||||||
|
|
||||||
if [ -e ./libgit2_clar ]; then
|
kill $(cat "$HOME/sshd/pid")
|
||||||
./libgit2_clar -sonline::push -sonline::clone::ssh_cert &&
|
|
||||||
./libgit2_clar -sonline::clone::ssh_with_paths || exit $?
|
|
||||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
|
||||||
./libgit2_clar -sonline::clone::cred_callback || exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use the proxy we started at the beginning
|
|
||||||
export GITTEST_REMOTE_PROXY_URL="http://foo:bar@localhost:8080/"
|
|
||||||
./libgit2_clar -sonline::clone::proxy_credentials_in_url || exit $?
|
|
||||||
export GITTEST_REMOTE_PROXY_URL="http://localhost:8080/"
|
|
||||||
export GITTEST_REMOTE_PROXY_USER="foo"
|
|
||||||
export GITTEST_REMOTE_PROXY_PASS="bar"
|
|
||||||
./libgit2_clar -sonline::clone::proxy_credentials_request || exit $?
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
export GITTEST_REMOTE_URL="https://github.com/libgit2/non-existent"
|
|
||||||
export GITTEST_REMOTE_USER="libgit2test"
|
|
||||||
ctest -V -R libgit2_clar-cred_callback
|
|
||||||
|
463
src/CMakeLists.txt
Normal file
463
src/CMakeLists.txt
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
IF(DEBUG_POOL)
|
||||||
|
SET(GIT_DEBUG_POOL 1)
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator")
|
||||||
|
|
||||||
|
# This variable will contain the libraries we need to put into
|
||||||
|
# libgit2.pc's Requires.private. That is, what we're linking to or
|
||||||
|
# what someone who's statically linking us needs to link to.
|
||||||
|
SET(LIBGIT2_PC_REQUIRES "")
|
||||||
|
# This will be set later if we use the system's http-parser library or
|
||||||
|
# use iconv (OSX) and will be written to the Libs.private field in the
|
||||||
|
# pc file.
|
||||||
|
SET(LIBGIT2_PC_LIBS "")
|
||||||
|
|
||||||
|
SET(LIBGIT2_INCLUDES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
"${libgit2_SOURCE_DIR}/src"
|
||||||
|
"${libgit2_SOURCE_DIR}/include")
|
||||||
|
SET(LIBGIT2_LIBS "")
|
||||||
|
SET(LIBGIT2_LIBDIRS "")
|
||||||
|
|
||||||
|
# Installation paths
|
||||||
|
#
|
||||||
|
SET(BIN_INSTALL_DIR bin CACHE PATH "Where to install binaries to.")
|
||||||
|
SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.")
|
||||||
|
SET(INCLUDE_INSTALL_DIR include CACHE PATH "Where to install headers to.")
|
||||||
|
|
||||||
|
# Set a couple variables to be substituted inside the .pc file.
|
||||||
|
# We can't just use LIB_INSTALL_DIR in the .pc file, as passing them as absolue
|
||||||
|
# or relative paths is both valid and supported by cmake.
|
||||||
|
SET (PKGCONFIG_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||||
|
|
||||||
|
IF(IS_ABSOLUTE ${LIB_INSTALL_DIR})
|
||||||
|
SET (PKGCONFIG_LIBDIR ${LIB_INSTALL_DIR})
|
||||||
|
ELSE(IS_ABSOLUTE ${LIB_INSTALL_DIR})
|
||||||
|
SET (PKGCONFIG_LIBDIR "\${prefix}/${LIB_INSTALL_DIR}")
|
||||||
|
ENDIF (IS_ABSOLUTE ${LIB_INSTALL_DIR})
|
||||||
|
|
||||||
|
IF(IS_ABSOLUTE ${INCLUDE_INSTALL_DIR})
|
||||||
|
SET (PKGCONFIG_INCLUDEDIR ${INCLUDE_INSTALL_DIR})
|
||||||
|
ELSE(IS_ABSOLUTE ${INCLUDE_INSTALL_DIR})
|
||||||
|
SET (PKGCONFIG_INCLUDEDIR "\${prefix}/${INCLUDE_INSTALL_DIR}")
|
||||||
|
ENDIF(IS_ABSOLUTE ${INCLUDE_INSTALL_DIR})
|
||||||
|
|
||||||
|
# Enable tracing
|
||||||
|
IF (ENABLE_TRACE STREQUAL "ON")
|
||||||
|
SET(GIT_TRACE 1)
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(tracing GIT_TRACE "tracing support")
|
||||||
|
|
||||||
|
CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
|
||||||
|
IF (HAVE_REGCOMP_L)
|
||||||
|
SET(GIT_USE_REGCOMP_L 1)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS)
|
||||||
|
IF (HAVE_FUTIMENS)
|
||||||
|
SET(GIT_USE_FUTIMENS 1)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
CHECK_FUNCTION_EXISTS(qsort_r HAVE_QSORT_R)
|
||||||
|
IF (HAVE_QSORT_R)
|
||||||
|
ADD_DEFINITIONS(-DHAVE_QSORT_R)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
CHECK_FUNCTION_EXISTS(qsort_s HAVE_QSORT_S)
|
||||||
|
IF (HAVE_QSORT_S)
|
||||||
|
ADD_DEFINITIONS(-DHAVE_QSORT_S)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
# Find required dependencies
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ws2_32)
|
||||||
|
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||||
|
LIST(APPEND LIBGIT2_LIBS socket nsl)
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl")
|
||||||
|
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Haiku")
|
||||||
|
LIST(APPEND LIBGIT2_LIBS network)
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lnetwork")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" NEED_LIBRT)
|
||||||
|
IF(NEED_LIBRT)
|
||||||
|
LIST(APPEND LIBGIT2_LIBS rt)
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lrt")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF(THREADSAFE)
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(threadsafe THREADSAFE "threadsafe support")
|
||||||
|
|
||||||
|
|
||||||
|
IF (WIN32 AND EMBED_SSH_PATH)
|
||||||
|
FILE(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c")
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES "${EMBED_SSH_PATH}/include")
|
||||||
|
FILE(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"")
|
||||||
|
SET(GIT_SSH 1)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF (WIN32 AND 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("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp")
|
||||||
|
LIST(APPEND LIBGIT2_LIBS winhttp)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp")
|
||||||
|
LIST(APPEND LIBGIT2_LIBDIRS ${LIBWINHTTP_PATH})
|
||||||
|
ELSE()
|
||||||
|
LIST(APPEND LIBGIT2_LIBS "winhttp")
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lwinhttp")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
LIST(APPEND LIBGIT2_LIBS "rpcrt4" "crypt32" "ole32")
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
|
||||||
|
ELSE ()
|
||||||
|
IF (CURL)
|
||||||
|
PKG_CHECK_MODULES(CURL libcurl)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (CURL_FOUND)
|
||||||
|
SET(GIT_CURL 1)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${CURL_INCLUDE_DIRS})
|
||||||
|
LIST(APPEND LIBGIT2_LIBDIRS ${CURL_LIBRARY_DIRS})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${CURL_LIBRARIES})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(cURL GIT_CURL "cURL for HTTP proxy support")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF (USE_HTTPS)
|
||||||
|
IF (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
FIND_PACKAGE(Security)
|
||||||
|
FIND_PACKAGE(CoreFoundation)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Auto-select TLS backend
|
||||||
|
IF (USE_HTTPS STREQUAL ON)
|
||||||
|
IF (SECURITY_FOUND)
|
||||||
|
IF (SECURITY_HAS_SSLCREATECONTEXT)
|
||||||
|
SET(HTTPS_BACKEND "SecureTransport")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE("-- Security framework is too old, falling back to OpenSSL")
|
||||||
|
SET(HTTPS_BACKEND "OpenSSL")
|
||||||
|
ENDIF()
|
||||||
|
ELSEIF (WINHTTP)
|
||||||
|
SET(HTTPS_BACKEND "WinHTTP")
|
||||||
|
ELSE()
|
||||||
|
SET(HTTPS_BACKEND "OpenSSL")
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
# Backend was explicitly set
|
||||||
|
SET(HTTPS_BACKEND ${USE_HTTPS})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Check that we can find what's required for the selected backend
|
||||||
|
IF (HTTPS_BACKEND STREQUAL "SecureTransport")
|
||||||
|
IF (NOT COREFOUNDATION_FOUND)
|
||||||
|
MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, CoreFoundation.framework not found")
|
||||||
|
ENDIF()
|
||||||
|
IF (NOT SECURITY_FOUND)
|
||||||
|
MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, Security.framework not found")
|
||||||
|
ENDIF()
|
||||||
|
IF (NOT SECURITY_HAS_SSLCREATECONTEXT)
|
||||||
|
MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, SSLCreateContext not supported")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(GIT_SECURE_TRANSPORT 1)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${SECURITY_INCLUDE_DIR})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LIBRARIES} ${SECURITY_LIBRARIES})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS})
|
||||||
|
ELSEIF (HTTPS_BACKEND STREQUAL "OpenSSL")
|
||||||
|
FIND_PACKAGE(OpenSSL)
|
||||||
|
|
||||||
|
IF (NOT OPENSSL_FOUND)
|
||||||
|
MESSAGE(FATAL_ERROR "Asked for OpenSSL TLS backend, but it wasn't found")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(GIT_OPENSSL 1)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS})
|
||||||
|
LIST(APPEND LIBGIT2_PC_REQUIRES "openssl")
|
||||||
|
ELSEIF (HTTPS_BACKEND STREQUAL "WinHTTP")
|
||||||
|
# WinHTTP setup was handled in the WinHTTP-specific block above
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR "Asked for backend ${HTTPS_BACKEND} but it wasn't found")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
ADD_FEATURE_INFO(HTTPS ON "using ${HTTPS_BACKEND}")
|
||||||
|
SET(GIT_HTTPS 1)
|
||||||
|
ELSE()
|
||||||
|
ADD_FEATURE_INFO(HTTPS OFF "no support")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Specify sha1 implementation
|
||||||
|
IF(SHA1_BACKEND STREQUAL "OpenSSL")
|
||||||
|
IF(NOT OPENSSL_FOUND)
|
||||||
|
FIND_PACKAGE(OpenSSL)
|
||||||
|
IF(NOT OPENSSL_FOUND)
|
||||||
|
MESSAGE(FATAL_ERROR "Requested OpenSSL SHA1 backend, but OpenSSL could not be found")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
ADD_FEATURE_INFO(SHA ON "using OpenSSL")
|
||||||
|
SET(GIT_SHA1_OPENSSL 1)
|
||||||
|
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lssl")
|
||||||
|
ELSE()
|
||||||
|
LIST(APPEND LIBGIT2_PC_REQUIRES "openssl")
|
||||||
|
ENDIF()
|
||||||
|
ELSEIF(SHA1_BACKEND STREQUAL "CollisionDetection")
|
||||||
|
ADD_FEATURE_INFO(SHA ON "using CollisionDetection")
|
||||||
|
SET(GIT_SHA1_COLLISIONDETECT 1)
|
||||||
|
ADD_DEFINITIONS(-DSHA1DC_NO_STANDARD_INCLUDES=1)
|
||||||
|
ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\")
|
||||||
|
ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\")
|
||||||
|
FILE(GLOB SRC_SHA1 hash/hash_collisiondetect.c hash/sha1dc/*)
|
||||||
|
ELSEIF(SHA1_BACKEND STREQUAL "Generic")
|
||||||
|
ADD_FEATURE_INFO(SHA ON "using Generic")
|
||||||
|
FILE(GLOB SRC_SHA1 hash/hash_generic.c)
|
||||||
|
ELSEIF(SHA1_BACKEND STREQUAL "Win32")
|
||||||
|
ADD_FEATURE_INFO(SHA ON "using Win32")
|
||||||
|
SET(GIT_SHA1_WIN32 1)
|
||||||
|
FILE(GLOB SRC_SHA1 hash/hash_win32.c)
|
||||||
|
ELSEIF(SHA1_BACKEND STREQUAL "CommonCrypto")
|
||||||
|
ADD_FEATURE_INFO(SHA ON "using CommonCrypto")
|
||||||
|
SET(GIT_SHA1_COMMON_CRYPTO 1)
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend ${SHA1_BACKEND}")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Include POSIX regex when it is required
|
||||||
|
IF(WIN32 OR AMIGA OR CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||||
|
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/regex" "${libgit2_BINARY_DIR}/deps/regex")
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/regex")
|
||||||
|
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:regex>)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Optional external dependency: http-parser
|
||||||
|
FIND_PACKAGE(HTTP_Parser)
|
||||||
|
IF (USE_EXT_HTTP_PARSER AND HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${HTTP_PARSER_LIBRARIES})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lhttp_parser")
|
||||||
|
ADD_FEATURE_INFO(http-parser ON "http-parser support")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.")
|
||||||
|
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser")
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser")
|
||||||
|
LIST(APPEND LIBGIT2_OBJECTS "$<TARGET_OBJECTS:http-parser>")
|
||||||
|
ADD_FEATURE_INFO(http-parser ON "http-parser support (bundled)")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Optional external dependency: zlib
|
||||||
|
IF(NOT USE_BUNDLED_ZLIB)
|
||||||
|
FIND_PACKAGE(ZLIB)
|
||||||
|
IF(ZLIB_FOUND)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${ZLIB_INCLUDE_DIRS})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${ZLIB_LIBRARIES})
|
||||||
|
IF(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
LIST(APPEND LIBGIT2_LIBS "z")
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS "-lz")
|
||||||
|
ELSE()
|
||||||
|
LIST(APPEND LIBGIT2_PC_REQUIRES "zlib")
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(zlib ON "using system zlib")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." )
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
IF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND)
|
||||||
|
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib")
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib")
|
||||||
|
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:zlib>)
|
||||||
|
ADD_FEATURE_INFO(zlib ON "using bundled zlib")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Optional external dependency: libssh2
|
||||||
|
IF (USE_SSH)
|
||||||
|
PKG_CHECK_MODULES(LIBSSH2 libssh2)
|
||||||
|
ENDIF()
|
||||||
|
IF (LIBSSH2_FOUND)
|
||||||
|
SET(GIT_SSH 1)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${LIBSSH2_INCLUDE_DIRS})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES})
|
||||||
|
LIST(APPEND LIBGIT2_LIBDIRS ${LIBSSH2_LIBRARY_DIRS})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
|
||||||
|
#SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
|
||||||
|
|
||||||
|
CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
|
||||||
|
IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
|
||||||
|
SET(GIT_SSH_MEMORY_CREDENTIALS 1)
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.")
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(SSH GIT_SSH "SSH transport support")
|
||||||
|
|
||||||
|
# Optional external dependency: libgssapi
|
||||||
|
IF (USE_GSSAPI)
|
||||||
|
FIND_PACKAGE(GSSAPI)
|
||||||
|
ENDIF()
|
||||||
|
IF (GSSAPI_FOUND)
|
||||||
|
SET(GIT_GSSAPI 1)
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES})
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(SPNEGO GIT_GSSAPI "SPNEGO authentication support")
|
||||||
|
|
||||||
|
# Optional external dependency: iconv
|
||||||
|
IF (USE_ICONV)
|
||||||
|
FIND_PACKAGE(Iconv)
|
||||||
|
ENDIF()
|
||||||
|
IF (ICONV_FOUND)
|
||||||
|
SET(GIT_USE_ICONV 1)
|
||||||
|
LIST(APPEND LIBGIT2_INCLUDES ${ICONV_INCLUDE_DIR})
|
||||||
|
LIST(APPEND LIBGIT2_LIBS ${ICONV_LIBRARIES})
|
||||||
|
LIST(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES})
|
||||||
|
ENDIF()
|
||||||
|
ADD_FEATURE_INFO(iconv GIT_USE_ICONV "iconv encoding conversion support")
|
||||||
|
|
||||||
|
|
||||||
|
IF (THREADSAFE)
|
||||||
|
IF (NOT WIN32)
|
||||||
|
FIND_PACKAGE(Threads REQUIRED)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(GIT_THREADS 1)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF (USE_NSEC)
|
||||||
|
SET(GIT_USE_NSEC 1)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF (HAVE_STRUCT_STAT_ST_MTIM)
|
||||||
|
SET(GIT_USE_STAT_MTIM 1)
|
||||||
|
ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC)
|
||||||
|
SET(GIT_USE_STAT_MTIMESPEC 1)
|
||||||
|
ELSEIF (HAVE_STRUCT_STAT_ST_MTIME_NSEC)
|
||||||
|
SET(GIT_USE_STAT_MTIME_NSEC 1)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
|
||||||
|
|
||||||
|
# Collect sourcefiles
|
||||||
|
FILE(GLOB SRC_H
|
||||||
|
"${libgit2_SOURCE_DIR}/include/git2.h"
|
||||||
|
"${libgit2_SOURCE_DIR}/include/git2/*.h"
|
||||||
|
"${libgit2_SOURCE_DIR}/include/git2/sys/*.h")
|
||||||
|
|
||||||
|
# On Windows use specific platform sources
|
||||||
|
IF (WIN32 AND NOT CYGWIN)
|
||||||
|
ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501)
|
||||||
|
|
||||||
|
IF(MSVC)
|
||||||
|
SET(WIN_RC "win32/git2.rc")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
FILE(GLOB SRC_OS win32/*.c win32/*.h)
|
||||||
|
ELSEIF (AMIGA)
|
||||||
|
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP)
|
||||||
|
ELSE()
|
||||||
|
IF (VALGRIND)
|
||||||
|
ADD_DEFINITIONS(-DNO_MMAP)
|
||||||
|
ENDIF()
|
||||||
|
FILE(GLOB SRC_OS unix/*.c unix/*.h)
|
||||||
|
ENDIF()
|
||||||
|
FILE(GLOB SRC_GIT2 *.c *.h
|
||||||
|
streams/*.c streams/*.h
|
||||||
|
transports/*.c transports/*.h
|
||||||
|
xdiff/*.c xdiff/*.h)
|
||||||
|
|
||||||
|
# Determine architecture of the machine
|
||||||
|
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
SET(GIT_ARCH_64 1)
|
||||||
|
ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
|
SET(GIT_ARCH_32 1)
|
||||||
|
ELSEIF (CMAKE_SIZEOF_VOID_P)
|
||||||
|
MESSAGE(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
CONFIGURE_FILE(features.h.in git2/sys/features.h)
|
||||||
|
|
||||||
|
SET(LIBGIT2_SOURCES ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_SSH} ${SRC_SHA1})
|
||||||
|
|
||||||
|
ADD_LIBRARY(git2internal OBJECT ${LIBGIT2_SOURCES})
|
||||||
|
IDE_SPLIT_SOURCES(git2internal)
|
||||||
|
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:git2internal>)
|
||||||
|
|
||||||
|
IF (${CMAKE_VERSION} VERSION_LESS 2.8.12)
|
||||||
|
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
|
||||||
|
ELSE()
|
||||||
|
TARGET_INCLUDE_DIRECTORIES(git2internal
|
||||||
|
PRIVATE ${LIBGIT2_INCLUDES}
|
||||||
|
PUBLIC ${libgit2_SOURCE_DIR}/include)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE)
|
||||||
|
SET(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE)
|
||||||
|
SET(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE)
|
||||||
|
SET(LIBGIT2_LIBDIRS ${LIBGIT2_LIBDIRS} PARENT_SCOPE)
|
||||||
|
|
||||||
|
IF(XCODE_VERSION)
|
||||||
|
# This is required for Xcode to actually link the libgit2 library
|
||||||
|
# when using only object libraries.
|
||||||
|
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "")
|
||||||
|
LIST(APPEND LIBGIT2_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/dummy.c)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Compile and link libgit2
|
||||||
|
LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
|
||||||
|
ADD_LIBRARY(git2 ${WIN_RC} ${LIBGIT2_OBJECTS})
|
||||||
|
TARGET_LINK_LIBRARIES(git2 ${LIBGIT2_LIBS})
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR})
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR})
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR})
|
||||||
|
|
||||||
|
# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
|
||||||
|
# Win64+MSVC+static libs = linker error
|
||||||
|
IF(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS)
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IDE_SPLIT_SOURCES(git2)
|
||||||
|
|
||||||
|
IF (SONAME)
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_SOVERSION})
|
||||||
|
IF (LIBGIT2_FILENAME)
|
||||||
|
ADD_DEFINITIONS(-DLIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\")
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME})
|
||||||
|
ELSEIF (DEFINED LIBGIT2_PREFIX)
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES PREFIX "${LIBGIT2_PREFIX}")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
LIST(REMOVE_DUPLICATES LIBGIT2_PC_REQUIRES)
|
||||||
|
STRING(REPLACE ";" " " LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES}")
|
||||||
|
STRING(REPLACE ";" " " LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS}")
|
||||||
|
CONFIGURE_FILE(${libgit2_SOURCE_DIR}/libgit2.pc.in ${libgit2_BINARY_DIR}/libgit2.pc @ONLY)
|
||||||
|
|
||||||
|
IF (MSVC_IDE)
|
||||||
|
# Precompiled headers
|
||||||
|
SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
# Install
|
||||||
|
INSTALL(TARGETS git2
|
||||||
|
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||||
|
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||||
|
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
INSTALL(FILES ${libgit2_BINARY_DIR}/libgit2.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
|
||||||
|
INSTALL(DIRECTORY ${libgit2_SOURCE_DIR}/include/git2 DESTINATION ${INCLUDE_INSTALL_DIR} )
|
||||||
|
INSTALL(FILES ${libgit2_SOURCE_DIR}/include/git2.h DESTINATION ${INCLUDE_INSTALL_DIR} )
|
@ -5,8 +5,8 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "annotated_commit.h"
|
#include "annotated_commit.h"
|
||||||
|
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_annotated_commit_h__
|
#ifndef INCLUDE_annotated_commit_h__
|
||||||
#define INCLUDE_annotated_commit_h__
|
#define INCLUDE_annotated_commit_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "oidarray.h"
|
#include "oidarray.h"
|
||||||
|
|
||||||
#include "git2/oid.h"
|
#include "git2/oid.h"
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "apply.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "git2/patch.h"
|
#include "git2/patch.h"
|
||||||
@ -12,7 +14,6 @@
|
|||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "patch.h"
|
#include "patch.h"
|
||||||
#include "fileops.h"
|
#include "fileops.h"
|
||||||
#include "apply.h"
|
|
||||||
#include "delta.h"
|
#include "delta.h"
|
||||||
#include "zstream.h"
|
#include "zstream.h"
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_apply_h__
|
#ifndef INCLUDE_apply_h__
|
||||||
#define INCLUDE_apply_h__
|
#define INCLUDE_apply_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/patch.h"
|
#include "git2/patch.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
28
src/attr.c
28
src/attr.c
@ -1,4 +1,12 @@
|
|||||||
#include "common.h"
|
/*
|
||||||
|
* 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 "attr.h"
|
||||||
|
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "sysdir.h"
|
#include "sysdir.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -48,12 +56,16 @@ int git_attr_get(
|
|||||||
git_attr_file *file;
|
git_attr_file *file;
|
||||||
git_attr_name attr;
|
git_attr_name attr;
|
||||||
git_attr_rule *rule;
|
git_attr_rule *rule;
|
||||||
|
git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN;
|
||||||
|
|
||||||
assert(value && repo && name);
|
assert(value && repo && name);
|
||||||
|
|
||||||
*value = NULL;
|
*value = NULL;
|
||||||
|
|
||||||
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), GIT_DIR_FLAG_UNKNOWN) < 0)
|
if (git_repository_is_bare(repo))
|
||||||
|
dir_flag = GIT_DIR_FLAG_FALSE;
|
||||||
|
|
||||||
|
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0)
|
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0)
|
||||||
@ -106,13 +118,17 @@ int git_attr_get_many_with_session(
|
|||||||
git_attr_rule *rule;
|
git_attr_rule *rule;
|
||||||
attr_get_many_info *info = NULL;
|
attr_get_many_info *info = NULL;
|
||||||
size_t num_found = 0;
|
size_t num_found = 0;
|
||||||
|
git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN;
|
||||||
|
|
||||||
if (!num_attr)
|
if (!num_attr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
assert(values && repo && names);
|
assert(values && repo && names);
|
||||||
|
|
||||||
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), GIT_DIR_FLAG_UNKNOWN) < 0)
|
if (git_repository_is_bare(repo))
|
||||||
|
dir_flag = GIT_DIR_FLAG_FALSE;
|
||||||
|
|
||||||
|
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((error = collect_attr_files(repo, attr_session, flags, pathname, &files)) < 0)
|
if ((error = collect_attr_files(repo, attr_session, flags, pathname, &files)) < 0)
|
||||||
@ -188,10 +204,14 @@ int git_attr_foreach(
|
|||||||
git_attr_rule *rule;
|
git_attr_rule *rule;
|
||||||
git_attr_assignment *assign;
|
git_attr_assignment *assign;
|
||||||
git_strmap *seen = NULL;
|
git_strmap *seen = NULL;
|
||||||
|
git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN;
|
||||||
|
|
||||||
assert(repo && callback);
|
assert(repo && callback);
|
||||||
|
|
||||||
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), GIT_DIR_FLAG_UNKNOWN) < 0)
|
if (git_repository_is_bare(repo))
|
||||||
|
dir_flag = GIT_DIR_FLAG_FALSE;
|
||||||
|
|
||||||
|
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 ||
|
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 ||
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_attr_h__
|
#ifndef INCLUDE_attr_h__
|
||||||
#define INCLUDE_attr_h__
|
#define INCLUDE_attr_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "attr_file.h"
|
#include "attr_file.h"
|
||||||
#include "attrcache.h"
|
#include "attrcache.h"
|
||||||
|
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
#include "common.h"
|
/*
|
||||||
|
* 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 "attr_file.h"
|
||||||
|
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "filebuf.h"
|
#include "filebuf.h"
|
||||||
#include "attr_file.h"
|
|
||||||
#include "attrcache.h"
|
#include "attrcache.h"
|
||||||
#include "git2/blob.h"
|
#include "git2/blob.h"
|
||||||
#include "git2/tree.h"
|
#include "git2/tree.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_attr_file_h__
|
#ifndef INCLUDE_attr_file_h__
|
||||||
#define INCLUDE_attr_file_h__
|
#define INCLUDE_attr_file_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/oid.h"
|
#include "git2/oid.h"
|
||||||
#include "git2/attr.h"
|
#include "git2/attr.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
#include "common.h"
|
/*
|
||||||
|
* 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 "attrcache.h"
|
||||||
|
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "attr_file.h"
|
#include "attr_file.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_attrcache_h__
|
#ifndef INCLUDE_attrcache_h__
|
||||||
#define INCLUDE_attrcache_h__
|
#define INCLUDE_attrcache_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "attr_file.h"
|
#include "attr_file.h"
|
||||||
#include "strmap.h"
|
#include "strmap.h"
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "blame.h"
|
#include "blame.h"
|
||||||
|
|
||||||
#include "git2/commit.h"
|
#include "git2/commit.h"
|
||||||
#include "git2/revparse.h"
|
#include "git2/revparse.h"
|
||||||
#include "git2/revwalk.h"
|
#include "git2/revwalk.h"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#ifndef INCLUDE_blame_h__
|
#ifndef INCLUDE_blame_h__
|
||||||
#define INCLUDE_blame_h__
|
#define INCLUDE_blame_h__
|
||||||
|
|
||||||
#include "git2/blame.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "git2/blame.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "blame_git.h"
|
#include "blame_git.h"
|
||||||
|
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "xdiff/xinclude.h"
|
#include "xdiff/xinclude.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_blame_git__
|
#ifndef INCLUDE_blame_git__
|
||||||
#define INCLUDE_blame_git__
|
#define INCLUDE_blame_git__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "blame.h"
|
#include "blame.h"
|
||||||
|
|
||||||
int git_blame__get_origin(
|
int git_blame__get_origin(
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "blob.h"
|
||||||
|
|
||||||
#include "git2/common.h"
|
#include "git2/common.h"
|
||||||
#include "git2/object.h"
|
#include "git2/object.h"
|
||||||
#include "git2/repository.h"
|
#include "git2/repository.h"
|
||||||
#include "git2/odb_backend.h"
|
#include "git2/odb_backend.h"
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "filebuf.h"
|
#include "filebuf.h"
|
||||||
#include "blob.h"
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "buf_text.h"
|
#include "buf_text.h"
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_blob_h__
|
#ifndef INCLUDE_blob_h__
|
||||||
#define INCLUDE_blob_h__
|
#define INCLUDE_blob_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/blob.h"
|
#include "git2/blob.h"
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "branch.h"
|
||||||
|
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -69,6 +70,12 @@ static int create_branch(
|
|||||||
assert(branch_name && commit && ref_out);
|
assert(branch_name && commit && ref_out);
|
||||||
assert(git_object_owner((const git_object *)commit) == repository);
|
assert(git_object_owner((const git_object *)commit) == repository);
|
||||||
|
|
||||||
|
if (!git__strcmp(branch_name, "HEAD")) {
|
||||||
|
giterr_set(GITERR_REFERENCE, "'HEAD' is not a valid branch name");
|
||||||
|
error = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (force && !bare && git_branch_lookup(&branch, repository, branch_name, GIT_BRANCH_LOCAL) == 0) {
|
if (force && !bare && git_branch_lookup(&branch, repository, branch_name, GIT_BRANCH_LOCAL) == 0) {
|
||||||
error = git_branch_is_head(branch);
|
error = git_branch_is_head(branch);
|
||||||
git_reference_free(branch);
|
git_reference_free(branch);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_branch_h__
|
#ifndef INCLUDE_branch_h__
|
||||||
#define INCLUDE_branch_h__
|
#define INCLUDE_branch_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
int git_branch_upstream__name(
|
int git_branch_upstream__name(
|
||||||
|
@ -188,7 +188,7 @@ bool git_buf_text_is_binary(const git_buf *buf)
|
|||||||
git_bom_t bom;
|
git_bom_t bom;
|
||||||
int printable = 0, nonprintable = 0;
|
int printable = 0, nonprintable = 0;
|
||||||
|
|
||||||
scan += git_buf_text_detect_bom(&bom, buf, 0);
|
scan += git_buf_text_detect_bom(&bom, buf);
|
||||||
|
|
||||||
if (bom > GIT_BOM_UTF8)
|
if (bom > GIT_BOM_UTF8)
|
||||||
return 1;
|
return 1;
|
||||||
@ -215,18 +215,18 @@ bool git_buf_text_contains_nul(const git_buf *buf)
|
|||||||
return (memchr(buf->ptr, '\0', buf->size) != NULL);
|
return (memchr(buf->ptr, '\0', buf->size) != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_buf_text_detect_bom(git_bom_t *bom, const git_buf *buf, size_t offset)
|
int git_buf_text_detect_bom(git_bom_t *bom, const git_buf *buf)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
*bom = GIT_BOM_NONE;
|
*bom = GIT_BOM_NONE;
|
||||||
/* need at least 2 bytes after offset to look for any BOM */
|
/* need at least 2 bytes to look for any BOM */
|
||||||
if (buf->size < offset + 2)
|
if (buf->size < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ptr = buf->ptr + offset;
|
ptr = buf->ptr;
|
||||||
len = buf->size - offset;
|
len = buf->size;
|
||||||
|
|
||||||
switch (*ptr++) {
|
switch (*ptr++) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -274,7 +274,7 @@ bool git_buf_text_gather_stats(
|
|||||||
memset(stats, 0, sizeof(*stats));
|
memset(stats, 0, sizeof(*stats));
|
||||||
|
|
||||||
/* BOM detection */
|
/* BOM detection */
|
||||||
skip = git_buf_text_detect_bom(&stats->bom, buf, 0);
|
skip = git_buf_text_detect_bom(&stats->bom, buf);
|
||||||
if (skip_bom)
|
if (skip_bom)
|
||||||
scan += skip;
|
scan += skip;
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_buf_text_h__
|
#ifndef INCLUDE_buf_text_h__
|
||||||
#define INCLUDE_buf_text_h__
|
#define INCLUDE_buf_text_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -97,11 +99,9 @@ extern bool git_buf_text_contains_nul(const git_buf *buf);
|
|||||||
*
|
*
|
||||||
* @param bom Set to the type of BOM detected or GIT_BOM_NONE
|
* @param bom Set to the type of BOM detected or GIT_BOM_NONE
|
||||||
* @param buf Buffer in which to check the first bytes for a BOM
|
* @param buf Buffer in which to check the first bytes for a BOM
|
||||||
* @param offset Offset into buffer to look for BOM
|
|
||||||
* @return Number of bytes of BOM data (or 0 if no BOM found)
|
* @return Number of bytes of BOM data (or 0 if no BOM found)
|
||||||
*/
|
*/
|
||||||
extern int git_buf_text_detect_bom(
|
extern int git_buf_text_detect_bom(git_bom_t *bom, const git_buf *buf);
|
||||||
git_bom_t *bom, const git_buf *buf, size_t offset);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gather stats for a piece of text
|
* Gather stats for a piece of text
|
||||||
|
32
src/buffer.c
32
src/buffer.c
@ -212,7 +212,7 @@ int git_buf_put(git_buf *buf, const char *data, size_t len)
|
|||||||
size_t new_size;
|
size_t new_size;
|
||||||
|
|
||||||
assert(data);
|
assert(data);
|
||||||
|
|
||||||
GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
|
GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
|
||||||
GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
|
GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
|
||||||
ENSURE_SIZE(buf, new_size);
|
ENSURE_SIZE(buf, new_size);
|
||||||
@ -455,6 +455,36 @@ on_error:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HEX_DECODE(c) ((c | 32) % 39 - 9)
|
||||||
|
|
||||||
|
int git_buf_decode_percent(
|
||||||
|
git_buf *buf,
|
||||||
|
const char *str,
|
||||||
|
size_t str_len)
|
||||||
|
{
|
||||||
|
size_t str_pos, new_size;
|
||||||
|
|
||||||
|
GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, str_len);
|
||||||
|
GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
|
||||||
|
ENSURE_SIZE(buf, new_size);
|
||||||
|
|
||||||
|
for (str_pos = 0; str_pos < str_len; buf->size++, str_pos++) {
|
||||||
|
if (str[str_pos] == '%' &&
|
||||||
|
str_len > str_pos + 2 &&
|
||||||
|
isxdigit(str[str_pos + 1]) &&
|
||||||
|
isxdigit(str[str_pos + 2])) {
|
||||||
|
buf->ptr[buf->size] = (HEX_DECODE(str[str_pos + 1]) << 4) +
|
||||||
|
HEX_DECODE(str[str_pos + 2]);
|
||||||
|
str_pos += 2;
|
||||||
|
} else {
|
||||||
|
buf->ptr[buf->size] = str[str_pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->ptr[buf->size] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
|
int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
size_t expected_size, new_size;
|
size_t expected_size, new_size;
|
||||||
|
@ -190,6 +190,9 @@ int git_buf_encode_base85(git_buf *buf, const char *data, size_t len);
|
|||||||
/* Decode the given "base85" and write the result to the buffer */
|
/* Decode the given "base85" and write the result to the buffer */
|
||||||
int git_buf_decode_base85(git_buf *buf, const char *base64, size_t len, size_t output_len);
|
int git_buf_decode_base85(git_buf *buf, const char *base64, size_t len, size_t output_len);
|
||||||
|
|
||||||
|
/* Decode the given percent-encoded string and write the result to the buffer */
|
||||||
|
int git_buf_decode_percent(git_buf *buf, const char *str, size_t len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert, remove or replace a portion of the buffer.
|
* Insert, remove or replace a portion of the buffer.
|
||||||
*
|
*
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "cache.h"
|
||||||
|
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "thread-utils.h"
|
#include "thread-utils.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "git2/oid.h"
|
#include "git2/oid.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_cache_h__
|
#ifndef INCLUDE_cache_h__
|
||||||
#define INCLUDE_cache_h__
|
#define INCLUDE_cache_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/common.h"
|
#include "git2/common.h"
|
||||||
#include "git2/oid.h"
|
#include "git2/oid.h"
|
||||||
#include "git2/odb.h"
|
#include "git2/odb.h"
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
#ifndef INCLUDE_compat_h__
|
#ifndef INCLUDE_cc_compat_h__
|
||||||
#define INCLUDE_compat_h__
|
#define INCLUDE_cc_compat_h__
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
@ -84,4 +84,4 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* INCLUDE_compat_h__ */
|
#endif
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "checkout.h"
|
#include "checkout.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "git2/repository.h"
|
#include "git2/repository.h"
|
||||||
#include "git2/refs.h"
|
#include "git2/refs.h"
|
||||||
#include "git2/tree.h"
|
#include "git2/tree.h"
|
||||||
@ -70,6 +70,7 @@ typedef struct {
|
|||||||
git_buf tmp;
|
git_buf tmp;
|
||||||
unsigned int strategy;
|
unsigned int strategy;
|
||||||
int can_symlink;
|
int can_symlink;
|
||||||
|
int respect_filemode;
|
||||||
bool reload_submodules;
|
bool reload_submodules;
|
||||||
size_t total_steps;
|
size_t total_steps;
|
||||||
size_t completed_steps;
|
size_t completed_steps;
|
||||||
@ -159,6 +160,22 @@ GIT_INLINE(bool) is_workdir_base_or_new(
|
|||||||
git_oid__cmp(&newitem->id, workdir_id) == 0);
|
git_oid__cmp(&newitem->id, workdir_id) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(bool) is_filemode_changed(git_filemode_t a, git_filemode_t b, int respect_filemode)
|
||||||
|
{
|
||||||
|
/* If core.filemode = false, ignore links in the repository and executable bit changes */
|
||||||
|
if (!respect_filemode) {
|
||||||
|
if (a == S_IFLNK)
|
||||||
|
a = GIT_FILEMODE_BLOB;
|
||||||
|
if (b == S_IFLNK)
|
||||||
|
b = GIT_FILEMODE_BLOB;
|
||||||
|
|
||||||
|
a &= ~0111;
|
||||||
|
b &= ~0111;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (a != b);
|
||||||
|
}
|
||||||
|
|
||||||
static bool checkout_is_workdir_modified(
|
static bool checkout_is_workdir_modified(
|
||||||
checkout_data *data,
|
checkout_data *data,
|
||||||
const git_diff_file *baseitem,
|
const git_diff_file *baseitem,
|
||||||
@ -192,16 +209,23 @@ static bool checkout_is_workdir_modified(
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look at the cache to decide if the workdir is modified. If not,
|
/*
|
||||||
* we can simply compare the oid in the cache to the baseitem instead
|
* Look at the cache to decide if the workdir is modified: if the
|
||||||
* of hashing the file. If so, we allow the checkout to proceed if the
|
* cache contents match the workdir contents, then we do not need
|
||||||
* oid is identical (ie, the staged item is what we're trying to check
|
* to examine the working directory directly, instead we can
|
||||||
* out.)
|
* examine the cache to see if _it_ has been modified. This allows
|
||||||
|
* us to avoid touching the disk.
|
||||||
*/
|
*/
|
||||||
if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) {
|
ie = git_index_get_bypath(data->index, wditem->path, 0);
|
||||||
if (git_index_time_eq(&wditem->mtime, &ie->mtime) &&
|
|
||||||
wditem->file_size == ie->file_size)
|
if (ie != NULL &&
|
||||||
return !is_workdir_base_or_new(&ie->id, baseitem, newitem);
|
git_index_time_eq(&wditem->mtime, &ie->mtime) &&
|
||||||
|
wditem->file_size == ie->file_size &&
|
||||||
|
!is_filemode_changed(wditem->mode, ie->mode, data->respect_filemode)) {
|
||||||
|
|
||||||
|
/* The workdir is modified iff the index entry is modified */
|
||||||
|
return !is_workdir_base_or_new(&ie->id, baseitem, newitem) ||
|
||||||
|
is_filemode_changed(baseitem->mode, ie->mode, data->respect_filemode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* depending on where base is coming from, we may or may not know
|
/* depending on where base is coming from, we may or may not know
|
||||||
@ -214,6 +238,9 @@ static bool checkout_is_workdir_modified(
|
|||||||
if (S_ISDIR(wditem->mode))
|
if (S_ISDIR(wditem->mode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (is_filemode_changed(baseitem->mode, wditem->mode, data->respect_filemode))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
|
if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2005,8 +2032,11 @@ static int checkout_write_entry(
|
|||||||
(error = checkout_safe_for_update_only(data, fullpath->ptr, side->mode)) <= 0)
|
(error = checkout_safe_for_update_only(data, fullpath->ptr, side->mode)) <= 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
return checkout_write_content(data,
|
if (!S_ISGITLINK(side->mode))
|
||||||
&side->id, fullpath->ptr, hint_path, side->mode, &st);
|
return checkout_write_content(data,
|
||||||
|
&side->id, fullpath->ptr, hint_path, side->mode, &st);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int checkout_write_entries(
|
static int checkout_write_entries(
|
||||||
@ -2428,6 +2458,10 @@ static int checkout_data_init(
|
|||||||
&data->can_symlink, repo, GIT_CVAR_SYMLINKS)) < 0)
|
&data->can_symlink, repo, GIT_CVAR_SYMLINKS)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((error = git_repository__cvar(
|
||||||
|
&data->respect_filemode, repo, GIT_CVAR_FILEMODE)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (!data->opts.baseline && !data->opts.baseline_index) {
|
if (!data->opts.baseline && !data->opts.baseline_index) {
|
||||||
data->opts_free_baseline = true;
|
data->opts_free_baseline = true;
|
||||||
error = 0;
|
error = 0;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_checkout_h__
|
#ifndef INCLUDE_checkout_h__
|
||||||
#define INCLUDE_checkout_h__
|
#define INCLUDE_checkout_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/checkout.h"
|
#include "git2/checkout.h"
|
||||||
#include "iterator.h"
|
#include "iterator.h"
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "filebuf.h"
|
#include "filebuf.h"
|
||||||
#include "merge.h"
|
#include "merge.h"
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "clone.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "git2/clone.h"
|
#include "git2/clone.h"
|
||||||
@ -16,7 +18,6 @@
|
|||||||
#include "git2/commit.h"
|
#include "git2/commit.h"
|
||||||
#include "git2/tree.h"
|
#include "git2/tree.h"
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "fileops.h"
|
#include "fileops.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
#ifndef INCLUDE_clone_h__
|
#ifndef INCLUDE_clone_h__
|
||||||
#define INCLUDE_clone_h__
|
#define INCLUDE_clone_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "git2/clone.h"
|
||||||
|
|
||||||
extern int git_clone__should_clone_local(const char *url, git_clone_local_t local);
|
extern int git_clone__should_clone_local(const char *url, git_clone_local_t local);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,13 +5,14 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "commit.h"
|
||||||
|
|
||||||
#include "git2/common.h"
|
#include "git2/common.h"
|
||||||
#include "git2/object.h"
|
#include "git2/object.h"
|
||||||
#include "git2/repository.h"
|
#include "git2/repository.h"
|
||||||
#include "git2/signature.h"
|
#include "git2/signature.h"
|
||||||
#include "git2/sys/commit.h"
|
#include "git2/sys/commit.h"
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "signature.h"
|
#include "signature.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_commit_h__
|
#ifndef INCLUDE_commit_h__
|
||||||
#define INCLUDE_commit_h__
|
#define INCLUDE_commit_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/commit.h"
|
#include "git2/commit.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "commit_list.h"
|
#include "commit_list.h"
|
||||||
#include "common.h"
|
|
||||||
#include "revwalk.h"
|
#include "revwalk.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_commit_list_h__
|
#ifndef INCLUDE_commit_list_h__
|
||||||
#define INCLUDE_commit_list_h__
|
#define INCLUDE_commit_list_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/oid.h"
|
#include "git2/oid.h"
|
||||||
|
|
||||||
#define PARENT1 (1 << 0)
|
#define PARENT1 (1 << 0)
|
||||||
|
16
src/common.h
16
src/common.h
@ -7,6 +7,10 @@
|
|||||||
#ifndef INCLUDE_common_h__
|
#ifndef INCLUDE_common_h__
|
||||||
#define INCLUDE_common_h__
|
#define INCLUDE_common_h__
|
||||||
|
|
||||||
|
#ifndef LIBGIT2_NO_FEATURES_H
|
||||||
|
# include "git2/sys/features.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "git2/common.h"
|
#include "git2/common.h"
|
||||||
#include "cc-compat.h"
|
#include "cc-compat.h"
|
||||||
|
|
||||||
@ -47,10 +51,6 @@
|
|||||||
# ifdef GIT_THREADS
|
# ifdef GIT_THREADS
|
||||||
# include "win32/thread.h"
|
# include "win32/thread.h"
|
||||||
# endif
|
# endif
|
||||||
# if defined(GIT_MSVC_CRTDBG)
|
|
||||||
# include "win32/w32_stack.h"
|
|
||||||
# include "win32/w32_crtdbg_stacktrace.h"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -230,6 +230,12 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
|
|||||||
GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
|
||||||
GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; }
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; }
|
||||||
|
|
||||||
|
#define GITERR_CHECK_ALLOC_ADD5(out, one, two, three, four, five) \
|
||||||
|
if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \
|
||||||
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
|
||||||
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), four) || \
|
||||||
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), five)) { return -1; }
|
||||||
|
|
||||||
/** Check for multiplicative overflow, failing if it would occur. */
|
/** Check for multiplicative overflow, failing if it would occur. */
|
||||||
#define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
|
#define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
|
||||||
if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
|
if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
|
||||||
@ -238,4 +244,4 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#endif /* INCLUDE_common_h__ */
|
#endif
|
||||||
|
22
src/config.c
22
src/config.c
@ -5,9 +5,9 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "sysdir.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "sysdir.h"
|
||||||
#include "git2/config.h"
|
#include "git2/config.h"
|
||||||
#include "git2/sys/config.h"
|
#include "git2/sys/config.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
@ -99,6 +99,7 @@ int git_config_add_file_ondisk(
|
|||||||
git_config *cfg,
|
git_config *cfg,
|
||||||
const char *path,
|
const char *path,
|
||||||
git_config_level_t level,
|
git_config_level_t level,
|
||||||
|
const git_repository *repo,
|
||||||
int force)
|
int force)
|
||||||
{
|
{
|
||||||
git_config_backend *file = NULL;
|
git_config_backend *file = NULL;
|
||||||
@ -116,7 +117,7 @@ int git_config_add_file_ondisk(
|
|||||||
if (git_config_file__ondisk(&file, path) < 0)
|
if (git_config_file__ondisk(&file, path) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((res = git_config_add_backend(cfg, file, level, force)) < 0) {
|
if ((res = git_config_add_backend(cfg, file, level, repo, force)) < 0) {
|
||||||
/*
|
/*
|
||||||
* free manually; the file is not owned by the config
|
* free manually; the file is not owned by the config
|
||||||
* instance yet and will not be freed on cleanup
|
* instance yet and will not be freed on cleanup
|
||||||
@ -138,7 +139,7 @@ int git_config_open_ondisk(git_config **out, const char *path)
|
|||||||
if (git_config_new(&config) < 0)
|
if (git_config_new(&config) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0)
|
if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, NULL, 0)) < 0)
|
||||||
git_config_free(config);
|
git_config_free(config);
|
||||||
else
|
else
|
||||||
*out = config;
|
*out = config;
|
||||||
@ -164,7 +165,7 @@ int git_config_snapshot(git_config **out, git_config *in)
|
|||||||
if ((error = internal->file->snapshot(&b, internal->file)) < 0)
|
if ((error = internal->file->snapshot(&b, internal->file)) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((error = git_config_add_backend(config, b, internal->level, 0)) < 0) {
|
if ((error = git_config_add_backend(config, b, internal->level, NULL, 0)) < 0) {
|
||||||
b->free(b);
|
b->free(b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -307,6 +308,7 @@ int git_config_add_backend(
|
|||||||
git_config *cfg,
|
git_config *cfg,
|
||||||
git_config_backend *file,
|
git_config_backend *file,
|
||||||
git_config_level_t level,
|
git_config_level_t level,
|
||||||
|
const git_repository *repo,
|
||||||
int force)
|
int force)
|
||||||
{
|
{
|
||||||
file_internal *internal;
|
file_internal *internal;
|
||||||
@ -316,7 +318,7 @@ int git_config_add_backend(
|
|||||||
|
|
||||||
GITERR_CHECK_VERSION(file, GIT_CONFIG_BACKEND_VERSION, "git_config_backend");
|
GITERR_CHECK_VERSION(file, GIT_CONFIG_BACKEND_VERSION, "git_config_backend");
|
||||||
|
|
||||||
if ((result = file->open(file, level)) < 0)
|
if ((result = file->open(file, level, repo)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
internal = git__malloc(sizeof(file_internal));
|
internal = git__malloc(sizeof(file_internal));
|
||||||
@ -1147,20 +1149,20 @@ int git_config_open_default(git_config **out)
|
|||||||
|
|
||||||
if (!git_config_find_global(&buf) || !git_config__global_location(&buf)) {
|
if (!git_config_find_global(&buf) || !git_config__global_location(&buf)) {
|
||||||
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
||||||
GIT_CONFIG_LEVEL_GLOBAL, 0);
|
GIT_CONFIG_LEVEL_GLOBAL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error && !git_config_find_xdg(&buf))
|
if (!error && !git_config_find_xdg(&buf))
|
||||||
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
||||||
GIT_CONFIG_LEVEL_XDG, 0);
|
GIT_CONFIG_LEVEL_XDG, NULL, 0);
|
||||||
|
|
||||||
if (!error && !git_config_find_system(&buf))
|
if (!error && !git_config_find_system(&buf))
|
||||||
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
||||||
GIT_CONFIG_LEVEL_SYSTEM, 0);
|
GIT_CONFIG_LEVEL_SYSTEM, NULL, 0);
|
||||||
|
|
||||||
if (!error && !git_config_find_programdata(&buf))
|
if (!error && !git_config_find_programdata(&buf))
|
||||||
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
||||||
GIT_CONFIG_LEVEL_PROGRAMDATA, 0);
|
GIT_CONFIG_LEVEL_PROGRAMDATA, NULL, 0);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&buf);
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_config_h__
|
#ifndef INCLUDE_config_h__
|
||||||
#define INCLUDE_config_h__
|
#define INCLUDE_config_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2.h"
|
#include "git2.h"
|
||||||
#include "git2/config.h"
|
#include "git2/config.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "fileops.h"
|
#include "fileops.h"
|
||||||
#include "repository.h"
|
#include "repository.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
1141
src/config_file.c
1141
src/config_file.c
File diff suppressed because it is too large
Load Diff
@ -7,12 +7,14 @@
|
|||||||
#ifndef INCLUDE_config_file_h__
|
#ifndef INCLUDE_config_file_h__
|
||||||
#define INCLUDE_config_file_h__
|
#define INCLUDE_config_file_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/sys/config.h"
|
#include "git2/sys/config.h"
|
||||||
#include "git2/config.h"
|
#include "git2/config.h"
|
||||||
|
|
||||||
GIT_INLINE(int) git_config_file_open(git_config_backend *cfg, unsigned int level)
|
GIT_INLINE(int) git_config_file_open(git_config_backend *cfg, unsigned int level, const git_repository *repo)
|
||||||
{
|
{
|
||||||
return cfg->open(cfg, level);
|
return cfg->open(cfg, level, repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(void) git_config_file_free(git_config_backend *cfg)
|
GIT_INLINE(void) git_config_file_free(git_config_backend *cfg)
|
||||||
@ -69,4 +71,3 @@ GIT_INLINE(int) git_config_file_unlock(git_config_backend *cfg, int success)
|
|||||||
extern int git_config_file_normalize_section(char *start, char *end);
|
extern int git_config_file_normalize_section(char *start, char *end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
525
src/config_parse.c
Normal file
525
src/config_parse.c
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
/*
|
||||||
|
* 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 "config_parse.h"
|
||||||
|
|
||||||
|
#include "buf_text.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
static void set_parse_error(git_config_parser *reader, int col, const char *error_str)
|
||||||
|
{
|
||||||
|
giterr_set(GITERR_CONFIG, "failed to parse config file: %s (in %s:%"PRIuZ", column %d)",
|
||||||
|
error_str, reader->file->path, reader->ctx.line_num, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GIT_INLINE(int) config_keychar(int c)
|
||||||
|
{
|
||||||
|
return isalnum(c) || c == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int strip_comments(char *line, int in_quotes)
|
||||||
|
{
|
||||||
|
int quote_count = in_quotes, backslash_count = 0;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
for (ptr = line; *ptr; ++ptr) {
|
||||||
|
if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\')
|
||||||
|
quote_count++;
|
||||||
|
|
||||||
|
if ((ptr[0] == ';' || ptr[0] == '#') &&
|
||||||
|
(quote_count % 2) == 0 &&
|
||||||
|
(backslash_count % 2) == 0) {
|
||||||
|
ptr[0] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr[0] == '\\')
|
||||||
|
backslash_count++;
|
||||||
|
else
|
||||||
|
backslash_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip any space at the end */
|
||||||
|
while (ptr > line && git__isspace(ptr[-1])) {
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
|
ptr[0] = '\0';
|
||||||
|
|
||||||
|
return quote_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int parse_section_header_ext(git_config_parser *reader, const char *line, const char *base_name, char **section_name)
|
||||||
|
{
|
||||||
|
int c, rpos;
|
||||||
|
char *first_quote, *last_quote;
|
||||||
|
git_buf buf = GIT_BUF_INIT;
|
||||||
|
size_t quoted_len, alloc_len, base_name_len = strlen(base_name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* base_name is what came before the space. We should be at the
|
||||||
|
* first quotation mark, except for now, line isn't being kept in
|
||||||
|
* sync so we only really use it to calculate the length.
|
||||||
|
*/
|
||||||
|
|
||||||
|
first_quote = strchr(line, '"');
|
||||||
|
if (first_quote == NULL) {
|
||||||
|
set_parse_error(reader, 0, "Missing quotation marks in section header");
|
||||||
|
goto end_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_quote = strrchr(line, '"');
|
||||||
|
quoted_len = last_quote - first_quote;
|
||||||
|
|
||||||
|
if (quoted_len == 0) {
|
||||||
|
set_parse_error(reader, 0, "Missing closing quotation mark in section header");
|
||||||
|
goto end_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
|
||||||
|
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
|
||||||
|
|
||||||
|
if (git_buf_grow(&buf, alloc_len) < 0 ||
|
||||||
|
git_buf_printf(&buf, "%s.", base_name) < 0)
|
||||||
|
goto end_error;
|
||||||
|
|
||||||
|
rpos = 0;
|
||||||
|
|
||||||
|
line = first_quote;
|
||||||
|
c = line[++rpos];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At the end of each iteration, whatever is stored in c will be
|
||||||
|
* added to the string. In case of error, jump to out
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 0:
|
||||||
|
set_parse_error(reader, 0, "Unexpected end-of-line in section header");
|
||||||
|
goto end_error;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
goto end_parse;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
c = line[++rpos];
|
||||||
|
|
||||||
|
if (c == 0) {
|
||||||
|
set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
|
||||||
|
goto end_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_buf_putc(&buf, (char)c);
|
||||||
|
c = line[++rpos];
|
||||||
|
} while (line + rpos < last_quote);
|
||||||
|
|
||||||
|
end_parse:
|
||||||
|
if (git_buf_oom(&buf))
|
||||||
|
goto end_error;
|
||||||
|
|
||||||
|
if (line[rpos] != '"' || line[rpos + 1] != ']') {
|
||||||
|
set_parse_error(reader, rpos, "Unexpected text after closing quotes");
|
||||||
|
git_buf_free(&buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*section_name = git_buf_detach(&buf);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
end_error:
|
||||||
|
git_buf_free(&buf);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_section_header(git_config_parser *reader, char **section_out)
|
||||||
|
{
|
||||||
|
char *name, *name_end;
|
||||||
|
int name_length, c, pos;
|
||||||
|
int result;
|
||||||
|
char *line;
|
||||||
|
size_t line_len;
|
||||||
|
|
||||||
|
git_parse_advance_ws(&reader->ctx);
|
||||||
|
line = git__strndup(reader->ctx.line, reader->ctx.line_len);
|
||||||
|
if (line == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* find the end of the variable's name */
|
||||||
|
name_end = strrchr(line, ']');
|
||||||
|
if (name_end == NULL) {
|
||||||
|
git__free(line);
|
||||||
|
set_parse_error(reader, 0, "Missing ']' in section header");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
|
||||||
|
name = git__malloc(line_len);
|
||||||
|
GITERR_CHECK_ALLOC(name);
|
||||||
|
|
||||||
|
name_length = 0;
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
/* Make sure we were given a section header */
|
||||||
|
c = line[pos++];
|
||||||
|
assert(c == '[');
|
||||||
|
|
||||||
|
c = line[pos++];
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (git__isspace(c)){
|
||||||
|
name[name_length] = '\0';
|
||||||
|
result = parse_section_header_ext(reader, line, name, section_out);
|
||||||
|
git__free(line);
|
||||||
|
git__free(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config_keychar(c) && c != '.') {
|
||||||
|
set_parse_error(reader, pos, "Unexpected character in header");
|
||||||
|
goto fail_parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
name[name_length++] = (char)git__tolower(c);
|
||||||
|
|
||||||
|
} while ((c = line[pos++]) != ']');
|
||||||
|
|
||||||
|
if (line[pos - 1] != ']') {
|
||||||
|
set_parse_error(reader, pos, "Unexpected end of file");
|
||||||
|
goto fail_parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
git__free(line);
|
||||||
|
|
||||||
|
name[name_length] = 0;
|
||||||
|
*section_out = name;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail_parse:
|
||||||
|
git__free(line);
|
||||||
|
git__free(name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int skip_bom(git_parse_ctx *parser)
|
||||||
|
{
|
||||||
|
git_buf buf = GIT_BUF_INIT_CONST(parser->content, parser->content_len);
|
||||||
|
git_bom_t bom;
|
||||||
|
int bom_offset = git_buf_text_detect_bom(&bom, &buf);
|
||||||
|
|
||||||
|
if (bom == GIT_BOM_UTF8)
|
||||||
|
git_parse_advance_chars(parser, bom_offset);
|
||||||
|
|
||||||
|
/* TODO: reference implementation is pretty stupid with BoM */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
(* basic types *)
|
||||||
|
digit = "0".."9"
|
||||||
|
integer = digit { digit }
|
||||||
|
alphabet = "a".."z" + "A" .. "Z"
|
||||||
|
|
||||||
|
section_char = alphabet | "." | "-"
|
||||||
|
extension_char = (* any character except newline *)
|
||||||
|
any_char = (* any character *)
|
||||||
|
variable_char = "alphabet" | "-"
|
||||||
|
|
||||||
|
|
||||||
|
(* actual grammar *)
|
||||||
|
config = { section }
|
||||||
|
|
||||||
|
section = header { definition }
|
||||||
|
|
||||||
|
header = "[" section [subsection | subsection_ext] "]"
|
||||||
|
|
||||||
|
subsection = "." section
|
||||||
|
subsection_ext = "\"" extension "\""
|
||||||
|
|
||||||
|
section = section_char { section_char }
|
||||||
|
extension = extension_char { extension_char }
|
||||||
|
|
||||||
|
definition = variable_name ["=" variable_value] "\n"
|
||||||
|
|
||||||
|
variable_name = variable_char { variable_char }
|
||||||
|
variable_value = string | boolean | integer
|
||||||
|
|
||||||
|
string = quoted_string | plain_string
|
||||||
|
quoted_string = "\"" plain_string "\""
|
||||||
|
plain_string = { any_char }
|
||||||
|
|
||||||
|
boolean = boolean_true | boolean_false
|
||||||
|
boolean_true = "yes" | "1" | "true" | "on"
|
||||||
|
boolean_false = "no" | "0" | "false" | "off"
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* '\"' -> '"' etc */
|
||||||
|
static int unescape_line(
|
||||||
|
char **out, bool *is_multi, const char *ptr, int quote_count)
|
||||||
|
{
|
||||||
|
char *str, *fixed, *esc;
|
||||||
|
size_t ptr_len = strlen(ptr), alloc_len;
|
||||||
|
|
||||||
|
*is_multi = false;
|
||||||
|
|
||||||
|
if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, ptr_len, 1) ||
|
||||||
|
(str = git__malloc(alloc_len)) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed = str;
|
||||||
|
|
||||||
|
while (*ptr != '\0') {
|
||||||
|
if (*ptr == '"') {
|
||||||
|
quote_count++;
|
||||||
|
} else if (*ptr != '\\') {
|
||||||
|
*fixed++ = *ptr;
|
||||||
|
} else {
|
||||||
|
/* backslash, check the next char */
|
||||||
|
ptr++;
|
||||||
|
/* if we're at the end, it's a multiline, so keep the backslash */
|
||||||
|
if (*ptr == '\0') {
|
||||||
|
*is_multi = true;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((esc = strchr(git_config_escapes, *ptr)) != NULL) {
|
||||||
|
*fixed++ = git_config_escaped[esc - git_config_escapes];
|
||||||
|
} else {
|
||||||
|
git__free(str);
|
||||||
|
giterr_set(GITERR_CONFIG, "invalid escape at %s", ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
*fixed = '\0';
|
||||||
|
*out = str;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes)
|
||||||
|
{
|
||||||
|
char *line = NULL, *proc_line = NULL;
|
||||||
|
int quote_count;
|
||||||
|
bool multiline;
|
||||||
|
|
||||||
|
/* Check that the next line exists */
|
||||||
|
git_parse_advance_line(&reader->ctx);
|
||||||
|
line = git__strndup(reader->ctx.line, reader->ctx.line_len);
|
||||||
|
if (line == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* We've reached the end of the file, there is no continuation.
|
||||||
|
* (this is not an error).
|
||||||
|
*/
|
||||||
|
if (line[0] == '\0') {
|
||||||
|
git__free(line);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
quote_count = strip_comments(line, !!in_quotes);
|
||||||
|
|
||||||
|
/* If it was just a comment, pretend it didn't exist */
|
||||||
|
if (line[0] == '\0') {
|
||||||
|
git__free(line);
|
||||||
|
return parse_multiline_variable(reader, value, quote_count);
|
||||||
|
/* TODO: unbounded recursion. This **could** be exploitable */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
|
||||||
|
git__free(line);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* add this line to the multiline var */
|
||||||
|
|
||||||
|
git_buf_puts(value, proc_line);
|
||||||
|
git__free(line);
|
||||||
|
git__free(proc_line);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we need to continue reading the next line, let's just
|
||||||
|
* keep putting stuff in the buffer
|
||||||
|
*/
|
||||||
|
if (multiline)
|
||||||
|
return parse_multiline_variable(reader, value, quote_count);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIT_INLINE(bool) is_namechar(char c)
|
||||||
|
{
|
||||||
|
return isalnum(c) || c == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_name(
|
||||||
|
char **name, const char **value, git_config_parser *reader, const char *line)
|
||||||
|
{
|
||||||
|
const char *name_end = line, *value_start;
|
||||||
|
|
||||||
|
*name = NULL;
|
||||||
|
*value = NULL;
|
||||||
|
|
||||||
|
while (*name_end && is_namechar(*name_end))
|
||||||
|
name_end++;
|
||||||
|
|
||||||
|
if (line == name_end) {
|
||||||
|
set_parse_error(reader, 0, "Invalid configuration key");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_start = name_end;
|
||||||
|
|
||||||
|
while (*value_start && git__isspace(*value_start))
|
||||||
|
value_start++;
|
||||||
|
|
||||||
|
if (*value_start == '=') {
|
||||||
|
*value = value_start + 1;
|
||||||
|
} else if (*value_start) {
|
||||||
|
set_parse_error(reader, 0, "Invalid configuration key");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*name = git__strndup(line, name_end - line)) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_variable(git_config_parser *reader, char **var_name, char **var_value)
|
||||||
|
{
|
||||||
|
const char *value_start = NULL;
|
||||||
|
char *line;
|
||||||
|
int quote_count;
|
||||||
|
bool multiline;
|
||||||
|
|
||||||
|
git_parse_advance_ws(&reader->ctx);
|
||||||
|
line = git__strndup(reader->ctx.line, reader->ctx.line_len);
|
||||||
|
if (line == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
quote_count = strip_comments(line, 0);
|
||||||
|
|
||||||
|
/* If there is no value, boolean true is assumed */
|
||||||
|
*var_value = NULL;
|
||||||
|
|
||||||
|
if (parse_name(var_name, &value_start, reader, line) < 0)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, let's try to parse the value
|
||||||
|
*/
|
||||||
|
if (value_start != NULL) {
|
||||||
|
while (git__isspace(value_start[0]))
|
||||||
|
value_start++;
|
||||||
|
|
||||||
|
if (unescape_line(var_value, &multiline, value_start, 0) < 0)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
if (multiline) {
|
||||||
|
git_buf multi_value = GIT_BUF_INIT;
|
||||||
|
git_buf_attach(&multi_value, *var_value, 0);
|
||||||
|
|
||||||
|
if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 ||
|
||||||
|
git_buf_oom(&multi_value)) {
|
||||||
|
git_buf_free(&multi_value);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*var_value = git_buf_detach(&multi_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
git__free(line);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
git__free(*var_name);
|
||||||
|
git__free(line);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int git_config_parse(
|
||||||
|
git_config_parser *parser,
|
||||||
|
git_config_parser_section_cb on_section,
|
||||||
|
git_config_parser_variable_cb on_variable,
|
||||||
|
git_config_parser_comment_cb on_comment,
|
||||||
|
git_config_parser_eof_cb on_eof,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
git_parse_ctx *ctx;
|
||||||
|
char *current_section = NULL, *var_name, *var_value;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
ctx = &parser->ctx;
|
||||||
|
|
||||||
|
skip_bom(ctx);
|
||||||
|
|
||||||
|
for (; ctx->remain_len > 0; git_parse_advance_line(ctx)) {
|
||||||
|
const char *line_start = parser->ctx.line;
|
||||||
|
size_t line_len = parser->ctx.line_len;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get either first non-whitespace character or, if that does
|
||||||
|
* not exist, the first whitespace character. This is required
|
||||||
|
* to preserve whitespaces when writing back the file.
|
||||||
|
*/
|
||||||
|
if (git_parse_peek(&c, ctx, GIT_PARSE_PEEK_SKIP_WHITESPACE) < 0 &&
|
||||||
|
git_parse_peek(&c, ctx, 0) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '[': /* section header, new section begins */
|
||||||
|
git__free(current_section);
|
||||||
|
current_section = NULL;
|
||||||
|
|
||||||
|
if ((result = parse_section_header(parser, ¤t_section)) == 0 && on_section) {
|
||||||
|
result = on_section(parser, current_section, line_start, line_len, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\n': /* comment or whitespace-only */
|
||||||
|
case '\r':
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case ';':
|
||||||
|
case '#':
|
||||||
|
if (on_comment) {
|
||||||
|
result = on_comment(parser, line_start, line_len, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* assume variable declaration */
|
||||||
|
if ((result = parse_variable(parser, &var_name, &var_value)) == 0 && on_variable) {
|
||||||
|
result = on_variable(parser, current_section, var_name, var_value, line_start, line_len, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (on_eof)
|
||||||
|
result = on_eof(parser, current_section, data);
|
||||||
|
|
||||||
|
out:
|
||||||
|
git__free(current_section);
|
||||||
|
return result;
|
||||||
|
}
|
64
src/config_parse.h
Normal file
64
src/config_parse.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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_config_parse_h__
|
||||||
|
#define INCLUDE_config_parse_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "array.h"
|
||||||
|
#include "oid.h"
|
||||||
|
#include "parse.h"
|
||||||
|
|
||||||
|
static const char *git_config_escapes = "ntb\"\\";
|
||||||
|
static const char *git_config_escaped = "\n\t\b\"\\";
|
||||||
|
|
||||||
|
typedef struct config_file {
|
||||||
|
git_oid checksum;
|
||||||
|
char *path;
|
||||||
|
git_array_t(struct config_file) includes;
|
||||||
|
} git_config_file;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct config_file *file;
|
||||||
|
git_parse_ctx ctx;
|
||||||
|
} git_config_parser;
|
||||||
|
|
||||||
|
typedef int (*git_config_parser_section_cb)(
|
||||||
|
git_config_parser *parser,
|
||||||
|
const char *current_section,
|
||||||
|
const char *line,
|
||||||
|
size_t line_len,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
typedef int (*git_config_parser_variable_cb)(
|
||||||
|
git_config_parser *parser,
|
||||||
|
const char *current_section,
|
||||||
|
char *var_name,
|
||||||
|
char *var_value,
|
||||||
|
const char *line,
|
||||||
|
size_t line_len,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
typedef int (*git_config_parser_comment_cb)(
|
||||||
|
git_config_parser *parser,
|
||||||
|
const char *line,
|
||||||
|
size_t line_len,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
typedef int (*git_config_parser_eof_cb)(
|
||||||
|
git_config_parser *parser,
|
||||||
|
const char *current_section,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
int git_config_parse(
|
||||||
|
git_config_parser *parser,
|
||||||
|
git_config_parser_section_cb on_section,
|
||||||
|
git_config_parser_variable_cb on_variable,
|
||||||
|
git_config_parser_comment_cb on_comment,
|
||||||
|
git_config_parser_eof_cb on_eof,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
#endif
|
@ -5,12 +5,13 @@
|
|||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/attr.h"
|
#include "git2/attr.h"
|
||||||
#include "git2/blob.h"
|
#include "git2/blob.h"
|
||||||
#include "git2/index.h"
|
#include "git2/index.h"
|
||||||
#include "git2/sys/filter.h"
|
#include "git2/sys/filter.h"
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "fileops.h"
|
#include "fileops.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define INCLUDE_git_delta_h__
|
#define INCLUDE_git_delta_h__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
|
||||||
typedef struct git_delta_index git_delta_index;
|
typedef struct git_delta_index git_delta_index;
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||||
* a Linking Exception. For full terms see the included COPYING file.
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include "git2/describe.h"
|
#include "git2/describe.h"
|
||||||
#include "git2/strarray.h"
|
#include "git2/strarray.h"
|
||||||
#include "git2/diff.h"
|
#include "git2/diff.h"
|
||||||
#include "git2/status.h"
|
#include "git2/status.h"
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "commit_list.h"
|
#include "commit_list.h"
|
||||||
#include "oidmap.h"
|
#include "oidmap.h"
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user