mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 19:04:05 +00:00
Merge branch 'development'
This commit is contained in:
commit
a50086d174
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/tests-clar/clar.h
|
||||
/tests-clar/clar_main.c
|
||||
/tests-clar/clar.suite
|
||||
/tests-clar/clar.suite.rule
|
||||
/tests-clar/.clarcache
|
||||
/apidocs
|
||||
/trash-*.exe
|
||||
/libgit2.pc
|
||||
@ -13,6 +14,7 @@
|
||||
.lock-wafbuild
|
||||
.waf*
|
||||
build/
|
||||
build-amiga/
|
||||
tests/tmp/
|
||||
msvc/Debug/
|
||||
msvc/Release/
|
||||
@ -26,3 +28,5 @@ CMake*
|
||||
*.cmake
|
||||
.DS_Store
|
||||
*~
|
||||
tags
|
||||
mkmf.log
|
||||
|
3
.mailmap
Normal file
3
.mailmap
Normal file
@ -0,0 +1,3 @@
|
||||
Vicent Martí <vicent@github.com> Vicent Marti <tanoku@gmail.com>
|
||||
Vicent Martí <vicent@github.com> Vicent Martí <tanoku@gmail.com>
|
||||
Michael Schubert <schu@schu.io> schu <schu-github@schulog.org>
|
42
.travis.yml
42
.travis.yml
@ -2,16 +2,26 @@
|
||||
# see travis-ci.org for details
|
||||
|
||||
# As CMake is not officially supported we use erlang VMs
|
||||
language: erlang
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
# Settings to try
|
||||
env:
|
||||
- OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release"
|
||||
- OPTIONS="-DBUILD_CLAR=ON"
|
||||
|
||||
- OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=ON"
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: i586-mingw32msvc-gcc
|
||||
env: OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON"
|
||||
|
||||
# Make sure CMake is installed
|
||||
install:
|
||||
- sudo apt-get install cmake
|
||||
- sudo apt-get update >/dev/null
|
||||
- sudo apt-get -q install cmake valgrind
|
||||
|
||||
# Run the Build script
|
||||
script:
|
||||
@ -19,20 +29,28 @@ script:
|
||||
- cd _build
|
||||
- cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS
|
||||
- cmake --build . --target install
|
||||
- ctest -V .
|
||||
|
||||
# Run Tests
|
||||
after_script:
|
||||
- ctest -V .
|
||||
after_success:
|
||||
- valgrind --leak-check=full --show-reachable=yes --suppressions=../libgit2_clar.supp ./libgit2_clar -ionline
|
||||
|
||||
# Only watch the development branch
|
||||
branches:
|
||||
only:
|
||||
- development
|
||||
|
||||
|
||||
# Notify development list when needed
|
||||
notifications:
|
||||
recipients:
|
||||
- vicent@github.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
irc:
|
||||
channels:
|
||||
- irc.freenode.net#libgit2
|
||||
on_success: change
|
||||
on_failure: always
|
||||
use_notice: true
|
||||
skip_join: true
|
||||
campfire:
|
||||
on_success: always
|
||||
on_failure: always
|
||||
rooms:
|
||||
- secure: "sH0dpPWMirbEe7AvLddZ2yOp8rzHalGmv0bYL/LIhVw3JDI589HCYckeLMSB\n3e/FeXw4bn0EqXWEXijVa4ijbilVY6d8oprdqMdWHEodng4KvY5vID3iZSGT\nxylhahO1XHmRynKQLOAvxlc93IlpVW38vQfby8giIY1nkpspb2w="
|
||||
|
16
AUTHORS
16
AUTHORS
@ -4,9 +4,12 @@ to the libgit2 project (sorted alphabetically):
|
||||
Alex Budovski
|
||||
Alexei Sholik
|
||||
Andreas Ericsson
|
||||
Anton "antong" Gyllenberg
|
||||
Ankur Sethi
|
||||
Ben Noordhuis
|
||||
Ben Straub
|
||||
Benjamin C Meyer
|
||||
Brian Downing
|
||||
Brian Lopez
|
||||
Carlos Martín Nieto
|
||||
Colin Timmermans
|
||||
@ -14,9 +17,12 @@ Daniel Huckstep
|
||||
Dave Borowitz
|
||||
David Boyce
|
||||
David Glesser
|
||||
Dmitry Kakurin
|
||||
Dmitry Kovega
|
||||
Emeric Fermas
|
||||
Emmanuel Rodriguez
|
||||
Florian Forster
|
||||
Holger Weiss
|
||||
Ingmar Vanhassel
|
||||
J. David Ibáñez
|
||||
Jakob Pfender
|
||||
@ -29,12 +35,15 @@ Jonathan "Duke" Leto
|
||||
Julien Miotte
|
||||
Julio Espinoza-Sokal
|
||||
Justin Love
|
||||
Kelly "kelly.leahy" Leahy
|
||||
Kirill A. Shutemov
|
||||
Lambert CLARA
|
||||
Luc Bertrand
|
||||
Marc Pegon
|
||||
Marcel Groothuis
|
||||
Marco Villegas
|
||||
Michael "schu" Schubert
|
||||
Microsoft Corporation
|
||||
Olivier Ramonat
|
||||
Peter Drahoš
|
||||
Pierre Habouzit
|
||||
@ -45,8 +54,9 @@ Romain Geissler
|
||||
Romain Muller
|
||||
Russell Belfer
|
||||
Sakari Jokinen
|
||||
Sam
|
||||
Samuel Charles "Sam" Day
|
||||
Sarath Lakshman
|
||||
Sascha Cunz
|
||||
Sascha Peilicke
|
||||
Scott Chacon
|
||||
Sebastian Schuberth
|
||||
@ -54,11 +64,9 @@ Sergey Nikishin
|
||||
Shawn O. Pearce
|
||||
Shuhei Tanuma
|
||||
Steve Frécinaux
|
||||
Sven Strickroth
|
||||
Tim Branyen
|
||||
Tim Clem
|
||||
Tim Harder
|
||||
Trent Mick
|
||||
Vicent Marti
|
||||
antong
|
||||
kelly.leahy
|
||||
schu
|
||||
|
339
CMakeLists.txt
339
CMakeLists.txt
@ -14,6 +14,73 @@
|
||||
PROJECT(libgit2 C)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
# Build options
|
||||
#
|
||||
OPTION( SONAME "Set the (SO)VERSION of the target" ON )
|
||||
OPTION( BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON )
|
||||
OPTION( THREADSAFE "Build libgit2 as threadsafe" OFF )
|
||||
OPTION( BUILD_CLAR "Build Tests using the Clar suite" ON )
|
||||
OPTION( BUILD_EXAMPLES "Build library usage example apps" OFF )
|
||||
OPTION( TAGS "Generate tags" OFF )
|
||||
OPTION( PROFILE "Generate profiling information" OFF )
|
||||
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
|
||||
IF(MSVC)
|
||||
# This option is only availalbe when building with MSVC. By default,
|
||||
# libgit2 is build using the stdcall calling convention, as that's what
|
||||
# the CLR expects by default and how the Windows API is built.
|
||||
#
|
||||
# If you are writing a C or C++ program and want to link to libgit2, you
|
||||
# have to either:
|
||||
# - Add /Gz to the compiler options of _your_ program / library.
|
||||
# - Turn this off by invoking CMake with the "-DSTDCALL=Off" argument.
|
||||
#
|
||||
OPTION( STDCALL "Build libgit2 with the __stdcall convention" ON )
|
||||
|
||||
# This option must match the settings used in your program, in particular if you
|
||||
# are linking statically
|
||||
OPTION( STATIC_CRT "Link the static CRT libraries" ON )
|
||||
ENDIF()
|
||||
|
||||
# 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.")
|
||||
|
||||
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)
|
||||
ENDIF ()
|
||||
IF(THREADSAFE)
|
||||
TARGET_LINK_LIBRARIES(${target} ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF()
|
||||
ENDFUNCTION()
|
||||
|
||||
# For the MSVC IDE, this function splits up the source files like windows
|
||||
# explorer does. This is esp. useful with the libgit2_clar project, were
|
||||
# usually 2 or more files share the same name. Sadly, this file grouping
|
||||
# is a per-directory option in cmake and not per-target, resulting in
|
||||
# empty virtual folders "tests-clar" for the git2.dll
|
||||
FUNCTION(MSVC_SPLIT_SOURCES target)
|
||||
IF(MSVC_IDE)
|
||||
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}")
|
||||
@ -22,58 +89,146 @@ STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1"
|
||||
SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
|
||||
|
||||
# Find required dependencies
|
||||
INCLUDE_DIRECTORIES(src include deps/http-parser)
|
||||
INCLUDE_DIRECTORIES(src include)
|
||||
|
||||
FILE(GLOB SRC_HTTP deps/http-parser/*.c)
|
||||
IF (WIN32 AND NOT MINGW)
|
||||
ADD_DEFINITIONS(-DGIT_WINHTTP)
|
||||
ELSE ()
|
||||
IF (NOT AMIGA)
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
ENDIF ()
|
||||
FILE(GLOB SRC_HTTP deps/http-parser/*.c)
|
||||
INCLUDE_DIRECTORIES(deps/http-parser)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
# Specify sha1 implementation
|
||||
IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin")
|
||||
ADD_DEFINITIONS(-DWIN32_SHA1)
|
||||
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
|
||||
ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin")
|
||||
ADD_DEFINITIONS(-DOPENSSL_SHA1)
|
||||
ELSE()
|
||||
# Windows doesn't understand POSIX regex on its own
|
||||
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)
|
||||
INCLUDE_DIRECTORIES(deps/regex)
|
||||
SET(SRC_REGEX deps/regex/regex.c)
|
||||
ENDIF()
|
||||
|
||||
# Optional external dependency: zlib
|
||||
IF(NOT ZLIB_LIBRARY)
|
||||
# It's optional, but FIND_PACKAGE gives a warning that looks more like an
|
||||
# error.
|
||||
FIND_PACKAGE(ZLIB QUIET)
|
||||
ENDIF()
|
||||
IF (ZLIB_FOUND)
|
||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${ZLIB_LIBRARIES})
|
||||
ELSE (ZLIB_FOUND)
|
||||
ELSE()
|
||||
MESSAGE( "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)
|
||||
ENDIF()
|
||||
|
||||
# Installation paths
|
||||
SET(INSTALL_BIN bin CACHE PATH "Where to install binaries to.")
|
||||
SET(INSTALL_LIB lib CACHE PATH "Where to install libraries to.")
|
||||
SET(INSTALL_INC include CACHE PATH "Where to install headers to.")
|
||||
|
||||
# Build options
|
||||
OPTION (BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON)
|
||||
OPTION (THREADSAFE "Build libgit2 as threadsafe" OFF)
|
||||
OPTION (BUILD_CLAR "Build Tests using the Clar suite" ON)
|
||||
OPTION (TAGS "Generate tags" OFF)
|
||||
OPTION (PROFILE "Generate profiling information" OFF)
|
||||
|
||||
# Platform specific compilation flags
|
||||
IF (MSVC)
|
||||
# Not using __stdcall with the CRT causes problems
|
||||
OPTION (STDCALL "Buildl libgit2 with the __stdcall convention" ON)
|
||||
|
||||
SET(CMAKE_C_FLAGS "/W4 /MP /nologo /Zi ${CMAKE_C_FLAGS}")
|
||||
STRING(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
|
||||
# /GF - String pooling
|
||||
# /MP - Parallel build
|
||||
SET(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}")
|
||||
|
||||
IF (STDCALL)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gz")
|
||||
# /Gz - stdcall calling convention
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gz")
|
||||
ENDIF ()
|
||||
SET(CMAKE_C_FLAGS_DEBUG "/Od /DEBUG /MTd /RTC1 /RTCs /RTCu")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "/MT /O2")
|
||||
|
||||
IF (STATIC_CRT)
|
||||
SET(CRT_FLAG_DEBUG "/MTd")
|
||||
SET(CRT_FLAG_RELEASE "/MT")
|
||||
ELSE()
|
||||
SET(CRT_FLAG_DEBUG "/MDd")
|
||||
SET(CRT_FLAG_RELEASE "/MD")
|
||||
ENDIF()
|
||||
|
||||
# /Zi - Create debugging information
|
||||
# /Od - Disable optimization
|
||||
# /D_DEBUG - #define _DEBUG
|
||||
# /MTd - Statically link the multithreaded debug version of the CRT
|
||||
# /MDd - Dynamically link the multithreaded debug version of the CRT
|
||||
# /RTC1 - Run time checks
|
||||
SET(CMAKE_C_FLAGS_DEBUG "/Zi /Od /D_DEBUG /RTC1 ${CRT_FLAG_DEBUG}")
|
||||
|
||||
# /DNDEBUG - Disables asserts
|
||||
# /MT - Statically link the multithreaded release version of the CRT
|
||||
# /MD - Dynamically link the multithreaded release version of the CRT
|
||||
# /O2 - Optimize for speed
|
||||
# /Oy - Enable frame pointer omission (FPO) (otherwise CMake will automatically turn it off)
|
||||
# /GL - Link time code generation (whole program optimization)
|
||||
# /Gy - Function-level linking
|
||||
SET(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy ${CRT_FLAG_RELEASE}")
|
||||
|
||||
# /Oy- - Disable frame pointer omission (FPO)
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy ${CRT_FLAG_RELEASE}")
|
||||
|
||||
# /O1 - Optimize for size
|
||||
SET(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O1 /Oy /GL /Gy ${CRT_FLAG_RELEASE}")
|
||||
|
||||
# /DYNAMICBASE - Address space load randomization (ASLR)
|
||||
# /NXCOMPAT - Data execution prevention (DEP)
|
||||
# /LARGEADDRESSAWARE - >2GB user address space on x86
|
||||
# /VERSION - Embed version information in PE header
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "/DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /VERSION:${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}")
|
||||
|
||||
# /DEBUG - Create a PDB
|
||||
# /LTCG - Link time code generation (whole program optimization)
|
||||
# /OPT:REF /OPT:ICF - Fold out duplicate code at link step
|
||||
# /INCREMENTAL:NO - Required to use /LTCG
|
||||
# /DEBUGTYPE:cv,fixup - Additional data embedded in the PDB (requires /INCREMENTAL:NO, so not on for Debug)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
|
||||
|
||||
# Same linker settings for DLL as EXE
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
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_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}")
|
||||
|
||||
SET(WIN_RC "src/win32/git2.rc")
|
||||
|
||||
# Precompiled headers
|
||||
|
||||
ELSE ()
|
||||
SET(CMAKE_C_FLAGS "-O2 -g -D_GNU_SOURCE -fvisibility=hidden -Wall -Wextra -Wno-missing-field-initializers -Wstrict-aliasing=2 -Wstrict-prototypes -Wmissing-prototypes ${CMAKE_C_FLAGS}")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
|
||||
IF (NOT MINGW) # MinGW always does PIC and complains if we tell it to
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -Wall -Wextra -Wno-missing-field-initializers -Wstrict-aliasing=2 -Wstrict-prototypes ${CMAKE_C_FLAGS}")
|
||||
|
||||
IF (WIN32 AND NOT CYGWIN)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-D_DEBUG")
|
||||
ENDIF ()
|
||||
|
||||
IF (MINGW) # MinGW always does PIC and complains if we tell it to
|
||||
STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||
# MinGW >= 3.14 uses the C99-style stdio functions
|
||||
# automatically, but forks like mingw-w64 still want
|
||||
# us to define this in order to use them
|
||||
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO=1)
|
||||
|
||||
ELSEIF (BUILD_SHARED_LIBS)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fPIC")
|
||||
ENDIF ()
|
||||
IF (APPLE) # Apple deprecated OpenSSL
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
|
||||
ENDIF ()
|
||||
IF (PROFILE)
|
||||
SET(CMAKE_C_FLAGS "-pg ${CMAKE_C_FLAGS}")
|
||||
@ -81,10 +236,21 @@ ELSE ()
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
|
||||
# Build Debug by default
|
||||
IF (NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
ENDIF ()
|
||||
IF( NOT CMAKE_CONFIGURATION_TYPES )
|
||||
# Build Debug by default
|
||||
IF (NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
ENDIF ()
|
||||
ELSE()
|
||||
# Using a multi-configuration generator eg MSVC or Xcode
|
||||
# that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE
|
||||
ENDIF()
|
||||
|
||||
IF (OPENSSL_FOUND)
|
||||
ADD_DEFINITIONS(-DGIT_SSL)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
IF (THREADSAFE)
|
||||
IF (NOT WIN32)
|
||||
@ -101,41 +267,53 @@ FILE(GLOB SRC_H include/git2/*.h)
|
||||
|
||||
# On Windows use specific platform sources
|
||||
IF (WIN32 AND NOT CYGWIN)
|
||||
ADD_DEFINITIONS(-DWIN32 -D_DEBUG -D_WIN32_WINNT=0x0501)
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/win32/*.c src/compat/*.c)
|
||||
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c src/compat/*.c)
|
||||
ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501)
|
||||
FILE(GLOB SRC_OS src/win32/*.c)
|
||||
ELSEIF (AMIGA)
|
||||
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R)
|
||||
FILE(GLOB SRC_OS src/amiga/*.c)
|
||||
ELSE()
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c)
|
||||
ENDIF ()
|
||||
FILE(GLOB SRC_OS src/unix/*.c)
|
||||
ENDIF()
|
||||
FILE(GLOB SRC_GIT2 src/*.c src/transports/*.c src/xdiff/*.c)
|
||||
|
||||
# Compile and link libgit2
|
||||
ADD_LIBRARY(git2 ${SRC} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${WIN_RC})
|
||||
ADD_LIBRARY(git2 ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC})
|
||||
TARGET_LINK_LIBRARIES(git2 ${SSL_LIBRARIES})
|
||||
TARGET_OS_LIBRARIES(git2)
|
||||
|
||||
IF (WIN32)
|
||||
TARGET_LINK_LIBRARIES(git2 ws2_32)
|
||||
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
TARGET_LINK_LIBRARIES(git2 socket nsl)
|
||||
ENDIF ()
|
||||
# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
|
||||
# Win64+MSVC+static libs = linker error
|
||||
IF(MSVC AND NOT BUILD_SHARED_LIBS AND (${CMAKE_SIZEOF_VOID_P} MATCHES "8") )
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64")
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(git2 ${CMAKE_THREAD_LIBS_INIT})
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_VERSION_MAJOR})
|
||||
MSVC_SPLIT_SOURCES(git2)
|
||||
|
||||
IF (SONAME)
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_VERSION_MAJOR})
|
||||
ENDIF()
|
||||
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 ${INSTALL_BIN}
|
||||
LIBRARY DESTINATION ${INSTALL_LIB}
|
||||
ARCHIVE DESTINATION ${INSTALL_LIB}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc DESTINATION ${INSTALL_LIB}/pkgconfig )
|
||||
INSTALL(DIRECTORY include/git2 DESTINATION ${INSTALL_INC} )
|
||||
INSTALL(FILES include/git2.h DESTINATION ${INSTALL_INC} )
|
||||
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
|
||||
IF (BUILD_CLAR)
|
||||
|
||||
FIND_PACKAGE(PythonInterp REQUIRED)
|
||||
|
||||
SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar/resources/")
|
||||
@ -145,24 +323,33 @@ IF (BUILD_CLAR)
|
||||
ADD_DEFINITIONS(-DCLAR_RESOURCES=\"${TEST_RESOURCES}\")
|
||||
|
||||
INCLUDE_DIRECTORIES(${CLAR_PATH})
|
||||
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/clar_helpers.c ${CLAR_PATH}/testlib.c)
|
||||
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c)
|
||||
SET(SRC_CLAR "${CLAR_PATH}/main.c" "${CLAR_PATH}/clar_libgit2.c" "${CLAR_PATH}/clar.c")
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CLAR_PATH}/clar_main.c ${CLAR_PATH}/clar.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} clar -vtap .
|
||||
DEPENDS ${CLAR_PATH}/clar ${SRC_TEST}
|
||||
OUTPUT ${CLAR_PATH}/clar.suite
|
||||
COMMAND ${PYTHON_EXECUTABLE} generate.py -xonline .
|
||||
DEPENDS ${SRC_TEST}
|
||||
WORKING_DIRECTORY ${CLAR_PATH}
|
||||
)
|
||||
ADD_EXECUTABLE(libgit2_clar ${SRC} ${CLAR_PATH}/clar_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX})
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ${CMAKE_THREAD_LIBS_INIT})
|
||||
IF (WIN32)
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ws2_32)
|
||||
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar socket nsl)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(
|
||||
${CLAR_PATH}/clar.c
|
||||
PROPERTIES OBJECT_DEPENDS ${CLAR_PATH}/clar.suite)
|
||||
|
||||
ADD_EXECUTABLE(libgit2_clar ${SRC_GIT2} ${SRC_OS} ${SRC_CLAR} ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1})
|
||||
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES})
|
||||
TARGET_OS_LIBRARIES(libgit2_clar)
|
||||
MSVC_SPLIT_SOURCES(libgit2_clar)
|
||||
|
||||
IF (MSVC_IDE)
|
||||
# Precompiled headers
|
||||
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
|
||||
ENDIF ()
|
||||
|
||||
ENABLE_TESTING()
|
||||
ADD_TEST(libgit2_clar libgit2_clar)
|
||||
ADD_TEST(libgit2_clar libgit2_clar -ionline)
|
||||
ENDIF ()
|
||||
|
||||
IF (TAGS)
|
||||
@ -183,3 +370,25 @@ IF (TAGS)
|
||||
DEPENDS tags
|
||||
)
|
||||
ENDIF ()
|
||||
|
||||
IF (BUILD_EXAMPLES)
|
||||
FILE(GLOB_RECURSE EXAMPLE_SRC examples/network/*.c)
|
||||
ADD_EXECUTABLE(cgit2 ${EXAMPLE_SRC})
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(cgit2 git2)
|
||||
ELSE()
|
||||
TARGET_LINK_LIBRARIES(cgit2 git2 pthread)
|
||||
ENDIF()
|
||||
|
||||
ADD_EXECUTABLE(git-diff examples/diff.c)
|
||||
TARGET_LINK_LIBRARIES(git-diff git2)
|
||||
|
||||
ADD_EXECUTABLE(git-general examples/general.c)
|
||||
TARGET_LINK_LIBRARIES(git-general git2)
|
||||
|
||||
ADD_EXECUTABLE(git-showindex examples/showindex.c)
|
||||
TARGET_LINK_LIBRARIES(git-showindex git2)
|
||||
|
||||
ADD_EXECUTABLE(git-rev-list examples/rev-list.c)
|
||||
TARGET_LINK_LIBRARIES(git-rev-list git2)
|
||||
ENDIF ()
|
||||
|
99
CONTRIBUTING.md
Normal file
99
CONTRIBUTING.md
Normal file
@ -0,0 +1,99 @@
|
||||
# Welcome to libgit2!
|
||||
|
||||
We're making it easy to do interesting things with git, and we'd love to have
|
||||
your help.
|
||||
|
||||
## Discussion & Chat
|
||||
|
||||
We hang out in the #libgit2 channel on irc.freenode.net.
|
||||
|
||||
Also, feel free to open an
|
||||
[Issue](https://github.com/libgit2/libgit2/issues/new) to start a discussion
|
||||
about any concerns you have. We like to use Issues for that so there is an
|
||||
easily accessible permanent record of the conversation.
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
First, know which version of libgit2 your problem is in and include it in
|
||||
your bug report. This can either be a tag (e.g.
|
||||
[v0.17.0](https://github.com/libgit2/libgit2/tree/v0.17.0) ) or a commit
|
||||
SHA (e.g.
|
||||
[01be7863](https://github.com/libgit2/libgit2/commit/01be786319238fd6507a08316d1c265c1a89407f)
|
||||
). Using [`git describe`](http://git-scm.com/docs/git-describe) is a great
|
||||
way to tell us what version you're working with.
|
||||
|
||||
If you're not running against the latest `development` branch version,
|
||||
please compile and test against that to avoid re-reporting an issue that's
|
||||
already been fixed.
|
||||
|
||||
It's *incredibly* helpful to be able to reproduce the problem. Please
|
||||
include a list of steps, a bit of code, and/or a zipped repository (if
|
||||
possible). Note that some of the libgit2 developers are employees of
|
||||
GitHub, so if your repository is private, find us on IRC and we'll figure
|
||||
out a way to help you.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Our work flow is a typical GitHub flow, where contributors fork the
|
||||
[libgit2 repository](https://github.com/libgit2/libgit2), make their changes
|
||||
on branch, and submit a
|
||||
[Pull Request](https://help.github.com/articles/using-pull-requests)
|
||||
(a.k.a. "PR").
|
||||
|
||||
Life will be a lot easier for you (and us) if you follow this pattern
|
||||
(i.e. fork, named branch, submit PR). If you use your fork's `development`
|
||||
branch, things can get messy.
|
||||
|
||||
Please include a nice description of your changes with your PR; 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 merged in.
|
||||
|
||||
## Porting Code From Other Open-Source Projects
|
||||
|
||||
`libgit2` is licensed under the terms of the GPL v2 with a linking
|
||||
exception. Any code brought in must be compatible with those terms.
|
||||
|
||||
The most common case is porting code from core Git. Git is a pure GPL
|
||||
project, which means that in order to port code to this project, we need the
|
||||
explicit permission of the author. Check the
|
||||
[`git.git-authors`](https://github.com/libgit2/libgit2/blob/development/git.git-authors)
|
||||
file for authors who have already consented; feel free to add someone if
|
||||
you've obtained their consent.
|
||||
|
||||
Other licenses have other requirements; check the license of the library
|
||||
you're porting code *from* to see what you need to do. As a general rule,
|
||||
MIT and BSD (3-clause) licenses are typically no problem. Apache 2.0
|
||||
license typically doesn't work due to GPL incompatibility.
|
||||
|
||||
## Style Guide
|
||||
|
||||
`libgit2` is written in [ANSI C](http://en.wikipedia.org/wiki/ANSI_C)
|
||||
(a.k.a. C89) with some specific conventions for function and type naming,
|
||||
code formatting, and testing.
|
||||
|
||||
We like to keep the source code consistent and easy to read. Maintaining
|
||||
this takes some discipline, but it's been more than worth it. Take a look
|
||||
at the
|
||||
[conventions file](https://github.com/libgit2/libgit2/blob/development/CONVENTIONS.md).
|
||||
|
||||
## Starter Projects
|
||||
|
||||
So, you want to start helping out with `libgit2`? That's fantastic? We
|
||||
welcome contributions and we promise we'll try to be nice.
|
||||
|
||||
If you want to jump in, you can look at our issues list to see if there
|
||||
are any unresolved issues to jump in on. Also, here is a list of some
|
||||
smaller project ideas that could help you become familiar with the code
|
||||
base and make a nice first step:
|
||||
|
||||
* Convert a `git_*modulename*_foreach()` callback-based iteration API
|
||||
into a `git_*modulename*_iterator` object with a create/advance style
|
||||
of API. This helps folks writing language bindings and usually isn't
|
||||
too complicated.
|
||||
* Write a new `examples/` program that mirrors a particular core git
|
||||
command. (See `examples/diff.c` for example.) This lets you (and us)
|
||||
easily exercise a particular facet of the API and measure compatability
|
||||
and feature parity with core git.
|
||||
* Submit a PR to clarify documentation! While we do try to document all of
|
||||
the APIs, your fresh eyes on the documentation will find areas that are
|
||||
confusing much more easily.
|
107
CONVENTIONS
107
CONVENTIONS
@ -1,107 +0,0 @@
|
||||
libgit2 conventions
|
||||
===================
|
||||
|
||||
Namespace Prefixes
|
||||
------------------
|
||||
|
||||
All types and functions start with 'git_'.
|
||||
|
||||
All #define macros start with 'GIT_'.
|
||||
|
||||
|
||||
Type Definitions
|
||||
----------------
|
||||
|
||||
Most types should be opaque, e.g.:
|
||||
|
||||
----
|
||||
typedef struct git_odb git_odb;
|
||||
----
|
||||
|
||||
with allocation functions returning an "instance" created within
|
||||
the library, and not within the application. This allows the type
|
||||
to grow (or shrink) in size without rebuilding client code.
|
||||
|
||||
|
||||
Public Exported Function Definitions
|
||||
------------------------------------
|
||||
|
||||
All exported functions must be declared as:
|
||||
|
||||
----
|
||||
GIT_EXTERN(result_type) git_modulename_functionname(arg_list);
|
||||
----
|
||||
|
||||
|
||||
Semi-Private Exported Functions
|
||||
-------------------------------
|
||||
|
||||
Functions whose modulename is followed by two underscores,
|
||||
for example 'git_odb__read_packed', are semi-private functions.
|
||||
They are primarily intended for use within the library itself,
|
||||
and may disappear or change their signature in a future release.
|
||||
|
||||
|
||||
Calling Conventions
|
||||
-------------------
|
||||
|
||||
Functions should prefer to return a 'int' to indicate success or
|
||||
failure and supply any output through the first argument (or first
|
||||
few arguments if multiple outputs are supplied).
|
||||
|
||||
int status codes are 0 for GIT_SUCCESS and < 0 for an error.
|
||||
This permits common POSIX result testing:
|
||||
|
||||
----
|
||||
if (git_odb_open(&odb, path))
|
||||
abort("odb open failed");
|
||||
----
|
||||
|
||||
Functions returning a pointer may return NULL instead of an int
|
||||
if there is only one type of failure (ENOMEM).
|
||||
|
||||
Functions returning a pointer may also return NULL if the common
|
||||
case needed by the application is strictly success/failure and a
|
||||
(possibly slower) function exists that the caller can use to get
|
||||
more detailed information. Parsing common data structures from
|
||||
on-disk formats is a good example of this pattern; in general a
|
||||
"corrupt" entity can be treated as though it does not exist but
|
||||
a more sophisticated "fsck" support function can report how the
|
||||
entity is malformed.
|
||||
|
||||
|
||||
Documentation Fomatting
|
||||
-----------------------
|
||||
|
||||
All comments should conform to Doxygen "javadoc" style conventions
|
||||
for formatting the public API documentation.
|
||||
|
||||
|
||||
Public Header Format
|
||||
--------------------
|
||||
|
||||
All public headers defining types, functions or macros must use
|
||||
the following form, where ${filename} is the name of the file,
|
||||
after replacing non-identifier characters with '_'.
|
||||
|
||||
----
|
||||
#ifndef INCLUDE_git_${filename}_h__
|
||||
#define INCLUDE_git_${filename}_h__
|
||||
|
||||
#include "git/common.h"
|
||||
|
||||
/**
|
||||
* @file git/${filename}.h
|
||||
* @brief Git some description
|
||||
* @defgroup git_${filename} some description routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
... definitions ...
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
----
|
227
CONVENTIONS.md
Normal file
227
CONVENTIONS.md
Normal file
@ -0,0 +1,227 @@
|
||||
# Libgit2 Conventions
|
||||
|
||||
We like to keep the source consistent and readable. Herein are some
|
||||
guidelines that should help with that.
|
||||
|
||||
## Compatibility
|
||||
|
||||
`libgit2` runs on many different platforms with many different compilers.
|
||||
It is written in [ANSI C](http://en.wikipedia.org/wiki/ANSI_C) (a.k.a. C89)
|
||||
with some specific standards for function and type naming, code formatting,
|
||||
and testing.
|
||||
|
||||
We try to avoid more recent extensions to maximize portability. We also, to
|
||||
the greatest extent possible, try to avoid lots of `#ifdef`s inside the core
|
||||
code base. This is somewhat unavoidable, but since it can really hamper
|
||||
maintainability, we keep it to a minimum.
|
||||
|
||||
## Match Surrounding Code
|
||||
|
||||
If there is one rule to take away from this document, it is *new code should
|
||||
match the surrounding code in a way that makes it impossible to distinguish
|
||||
the new from the old.* Consistency is more important to us than anyone's
|
||||
personal opinion about where braces should be placed or spaces vs. tabs.
|
||||
|
||||
If a section of code is being completely rewritten, it is okay to bring it
|
||||
in line with the standards that are laid out here, but we will not accept
|
||||
submissions that contain a large number of changes that are merely
|
||||
reformatting.
|
||||
|
||||
## Naming Things
|
||||
|
||||
All external types and functions start with `git_` and all `#define` macros
|
||||
start with `GIT_`. The `libgit2` API is mostly broken into related
|
||||
functional modules each with a corresponding header. All functions in a
|
||||
module should be named like `git_modulename_functioname()`
|
||||
(e.g. `git_repository_open()`).
|
||||
|
||||
Functions with a single output parameter should name that parameter `out`.
|
||||
Multiple outputs should be named `foo_out`, `bar_out`, etc.
|
||||
|
||||
Parameters of type `git_oid` should be named `id`, or `foo_id`. Calls that
|
||||
return an OID should be named `git_foo_id`.
|
||||
|
||||
Where a callback function is used, the function should also include a
|
||||
user-supplied extra input that is a `void *` named "payload" that will be
|
||||
passed through to the callback at each invocation.
|
||||
|
||||
## Typedefs
|
||||
|
||||
Wherever possible, use `typedef`. In some cases, if a structure is just a
|
||||
collection of function pointers, the pointer types don't need to be
|
||||
separately typedef'd, but loose function pointer types should be.
|
||||
|
||||
## Exports
|
||||
|
||||
All exported functions must be declared as:
|
||||
|
||||
```c
|
||||
GIT_EXTERN(result_type) git_modulename_functionname(arg_list);
|
||||
```
|
||||
|
||||
## Internals
|
||||
|
||||
Functions whose *modulename* is followed by two underscores,
|
||||
for example `git_odb__read_packed`, are semi-private functions.
|
||||
They are primarily intended for use within the library itself,
|
||||
and may disappear or change their signature in a future release.
|
||||
|
||||
## Parameters
|
||||
|
||||
Out parameters come first.
|
||||
|
||||
Whenever possible, pass argument pointers as `const`. Some structures (such
|
||||
as `git_repository` and `git_index`) have mutable internal structure that
|
||||
prevents this.
|
||||
|
||||
Callbacks should always take a `void *` payload as their last parameter.
|
||||
Callback pointers are grouped with their payloads, and typically come last
|
||||
when passed as arguments:
|
||||
|
||||
```c
|
||||
int git_foo(git_repository *repo, git_foo_cb callback, void *payload);
|
||||
```
|
||||
|
||||
## Memory Ownership
|
||||
|
||||
Some APIs allocate memory which the caller is responsible for freeing; others
|
||||
return a pointer into a buffer that's owned by some other object. Make this
|
||||
explicit in the documentation.
|
||||
|
||||
## Return codes
|
||||
|
||||
Most public APIs should return an `int` error code. As is typical with most
|
||||
C library functions, a zero value indicates success and a negative value
|
||||
indicates failure.
|
||||
|
||||
Some bindings will transform these returned error codes into exception
|
||||
types, so returning a semantically appropriate error code is important.
|
||||
Check
|
||||
[`include/git2/errors.h`](https://github.com/libgit2/libgit2/blob/development/include/git2/errors.h)
|
||||
for the return codes already defined.
|
||||
|
||||
In your implementation, use `giterr_set()` to provide extended error
|
||||
information to callers.
|
||||
|
||||
If a `libgit2` function internally invokes another function that reports an
|
||||
error, but the error is not propagated up, use `giterr_clear()` to prevent
|
||||
callers from getting the wrong error message later on.
|
||||
|
||||
|
||||
## Structs
|
||||
|
||||
Most public types should be opaque, e.g.:
|
||||
|
||||
```C
|
||||
typedef struct git_odb git_odb;
|
||||
```
|
||||
|
||||
...with allocation functions returning an "instance" created within
|
||||
the library, and not within the application. This allows the type
|
||||
to grow (or shrink) in size without rebuilding client code.
|
||||
|
||||
To preserve ABI compatibility, include an `int version` field in all opaque
|
||||
structures, and initialize to the latest version in the construction call.
|
||||
Increment the "latest" version whenever the structure changes, and try to only
|
||||
append to the end of the structure.
|
||||
|
||||
## Option Structures
|
||||
|
||||
If a function's parameter count is too high, it may be desirable to package
|
||||
up the options in a structure. Make them transparent, include a version
|
||||
field, and provide an initializer constant or constructor. Using these
|
||||
structures should be this easy:
|
||||
|
||||
```C
|
||||
git_foo_options opts = GIT_FOO_OPTIONS_INIT;
|
||||
opts.baz = BAZ_OPTION_ONE;
|
||||
git_foo(&opts);
|
||||
```
|
||||
|
||||
## Enumerations
|
||||
|
||||
Typedef all enumerated types. If each option stands alone, use the enum
|
||||
type for passing them as parameters; if they are flags to be OR'ed together,
|
||||
pass them as `unsigned int` or `uint32_t` or some appropriate type.
|
||||
|
||||
## Code Layout
|
||||
|
||||
Try to keep lines less than 80 characters long. This is a loose
|
||||
requirement, but going significantly over 80 columns is not nice.
|
||||
|
||||
Use common sense to wrap most code lines; public function declarations
|
||||
can use a couple of different styles:
|
||||
|
||||
```c
|
||||
/** All on one line is okay if it fits */
|
||||
GIT_EXTERN(int) git_foo_simple(git_oid *id);
|
||||
|
||||
/** Otherwise one argument per line is a good next step */
|
||||
GIT_EXTERN(int) git_foo_id(
|
||||
git_oid **out,
|
||||
int a,
|
||||
int b);
|
||||
```
|
||||
|
||||
Indent with tabs; set your editor's tab width to 4 for best effect.
|
||||
|
||||
Avoid trailing whitespace and only commit Unix-style newlines (i.e. no CRLF
|
||||
in the repository - just set `core.autocrlf` to true if you are writing code
|
||||
on a Windows machine).
|
||||
|
||||
## Documentation
|
||||
|
||||
All comments should conform to Doxygen "javadoc" style conventions for
|
||||
formatting the public API documentation. Try to document every parameter,
|
||||
and keep the comments up to date if you change the parameter list.
|
||||
|
||||
## Public Header Template
|
||||
|
||||
Use this template when creating a new public header.
|
||||
|
||||
```C
|
||||
#ifndef INCLUDE_git_${filename}_h__
|
||||
#define INCLUDE_git_${filename}_h__
|
||||
|
||||
#include "git/common.h"
|
||||
|
||||
/**
|
||||
* @file git/${filename}.h
|
||||
* @brief Git some description
|
||||
* @defgroup git_${filename} some description routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/* ... definitions ... */
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
```
|
||||
|
||||
## Inlined functions
|
||||
|
||||
All inlined functions must be declared as:
|
||||
|
||||
```C
|
||||
GIT_INLINE(result_type) git_modulename_functionname(arg_list);
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
`libgit2` uses the [clar](https://github.com/vmg/clar) testing framework.
|
||||
|
||||
All PRs should have corresponding tests.
|
||||
|
||||
* If the PR fixes an existing issue, the test should fail prior to applying
|
||||
the PR and succeed after applying it.
|
||||
* If the PR is for new functionality, then the tests should exercise that
|
||||
new functionality to a certain extent. We don't require 100% coverage
|
||||
right now (although we are getting stricter over time).
|
||||
|
||||
When adding new tests, we prefer if you attempt to reuse existing test data
|
||||
(in `tests-clar/resources/`) if possible. If you are going to add new test
|
||||
repositories, please try to strip them of unnecessary files (e.g. sample
|
||||
hooks, etc).
|
2
COPYING
2
COPYING
@ -1,4 +1,4 @@
|
||||
libgit2 is Copyright (C) 2009-2012 the libgit2 contributors,
|
||||
libgit2 is Copyright (C) the libgit2 contributors,
|
||||
unless otherwise stated. See the AUTHORS file for details.
|
||||
|
||||
Note that the only valid version of the GPL as far as this project
|
||||
|
@ -1,15 +1,31 @@
|
||||
PLATFORM=$(shell uname -o)
|
||||
|
||||
rm=rm -f
|
||||
CC=cc
|
||||
AR=ar cq
|
||||
RANLIB=ranlib
|
||||
LIBNAME=libgit2.a
|
||||
ifeq ($(PLATFORM),Msys)
|
||||
CC=gcc
|
||||
else
|
||||
CC=cc
|
||||
endif
|
||||
|
||||
INCLUDES= -I. -Isrc -Iinclude -Ideps/http-parser -Ideps/zlib
|
||||
|
||||
DEFINES= $(INCLUDES) -DNO_VIZ -DSTDC -DNO_GZIP -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
|
||||
CFLAGS= -g $(DEFINES) -Wall -Wextra -fPIC -O2
|
||||
DEFINES= $(INCLUDES) -DNO_VIZ -DSTDC -DNO_GZIP -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(EXTRA_DEFINES)
|
||||
CFLAGS= -g $(DEFINES) -Wall -Wextra -O2 $(EXTRA_CFLAGS)
|
||||
|
||||
SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/xdiff/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c) src/hash/hash_generic.c
|
||||
|
||||
ifeq ($(PLATFORM),Msys)
|
||||
SRCS += $(wildcard src/win32/*.c) $(wildcard src/compat/*.c) deps/regex/regex.c
|
||||
INCLUDES += -Ideps/regex
|
||||
DEFINES += -DWIN32 -D_WIN32_WINNT=0x0501
|
||||
else
|
||||
SRCS += $(wildcard src/unix/*.c)
|
||||
CFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/unix/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c)
|
||||
OBJS = $(patsubst %.c,%.o,$(SRCS))
|
||||
|
||||
%.c.o:
|
||||
|
60
README.md
60
README.md
@ -11,11 +11,14 @@ libgit2 is licensed under a **very permissive license** (GPLv2 with a special Li
|
||||
This basically means that you can link it (unmodified) with any kind of software without having to
|
||||
release its source code.
|
||||
|
||||
* Mailing list: <libgit2@librelist.org>
|
||||
* Mailing list: ~~<libgit2@librelist.org>~~
|
||||
The libgit2 mailing list has
|
||||
traditionally been hosted in Librelist, but Librelist is and has always
|
||||
been a shitshow. We encourage you to [open an issue](https://github.com/libgit2/libgit2/issues)
|
||||
on GitHub instead for any questions regarding the library.
|
||||
* Archives: <http://librelist.com/browser/libgit2/>
|
||||
* Website: <http://libgit2.github.com>
|
||||
* API documentation: <http://libgit2.github.com/libgit2>
|
||||
* Usage guide: <http://libgit2.github.com/api.html>
|
||||
|
||||
What It Can Do
|
||||
==================================
|
||||
@ -58,20 +61,47 @@ To install the library you can specify the install prefix by setting:
|
||||
$ cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix
|
||||
$ cmake --build . --target install
|
||||
|
||||
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"`
|
||||
when configuring.
|
||||
|
||||
For more advanced use or questions about CMake please read <http://www.cmake.org/Wiki/CMake_FAQ>.
|
||||
|
||||
The following CMake variables are declared:
|
||||
|
||||
- `INSTALL_BIN`: Where to install binaries to.
|
||||
- `INSTALL_LIB`: Where to install libraries to.
|
||||
- `INSTALL_INC`: Where to install headers to.
|
||||
- `BIN_INSTALL_DIR`: Where to install binaries to.
|
||||
- `LIB_INSTALL_DIR`: Where to install libraries to.
|
||||
- `INCLUDE_INSTALL_DIR`: Where to install headers to.
|
||||
- `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON)
|
||||
- `BUILD_CLAR`: Build [Clar](https://github.com/tanoku/clar)-based test suite (defaults to ON)
|
||||
- `BUILD_CLAR`: Build [Clar](https://github.com/vmg/clar)-based test suite (defaults to ON)
|
||||
- `THREADSAFE`: Build libgit2 with threading support (defaults to OFF)
|
||||
- `STDCALL`: Build libgit2 as `stdcall`. Turn off for `cdecl` (Windows; defaults to ON)
|
||||
|
||||
Compiler and linker options
|
||||
---------------------------
|
||||
|
||||
CMake lets you specify a few variables to control the behavior of the
|
||||
compiler and linker. These flags are rarely used but can be useful for
|
||||
64-bit to 32-bit cross-compilation.
|
||||
|
||||
- `CMAKE_C_FLAGS`: Set your own compiler flags
|
||||
- `CMAKE_FIND_ROOT_PATH`: Override the search path for libraries
|
||||
- `ZLIB_LIBRARY`, `OPENSSL_SSL_LIBRARY` AND `OPENSSL_CRYPTO_LIBRARY`:
|
||||
Tell CMake where to find those specific libraries
|
||||
|
||||
MacOS X
|
||||
-------
|
||||
|
||||
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"`
|
||||
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 wiki]
|
||||
(https://github.com/libgit2/libgit2/wiki/Building-libgit2-on-Windows)
|
||||
for more detailed instructions.
|
||||
|
||||
Language Bindings
|
||||
==================================
|
||||
@ -82,6 +112,8 @@ Here are the bindings to libgit2 that are currently available:
|
||||
* libqgit2, Qt bindings <https://projects.kde.org/projects/playground/libs/libqgit2/>
|
||||
* Chicken Scheme
|
||||
* chicken-git <https://wiki.call-cc.org/egg/git>
|
||||
* D
|
||||
* dlibgit <https://github.com/AndrejMitrovic/dlibgit>
|
||||
* Delphi
|
||||
* GitForDelphi <https://github.com/libgit2/GitForDelphi>
|
||||
* Erlang
|
||||
@ -89,9 +121,9 @@ Here are the bindings to libgit2 that are currently available:
|
||||
* Go
|
||||
* go-git <https://github.com/str1ngs/go-git>
|
||||
* GObject
|
||||
* libgit2-glib <https://github.com/nacho/libgit2-glib>
|
||||
* libgit2-glib <https://live.gnome.org/Libgit2-glib>
|
||||
* Haskell
|
||||
* hgit2 <https://github.com/norm2782/hgit2>
|
||||
* hgit2 <https://github.com/fpco/gitlib>
|
||||
* Lua
|
||||
* luagit2 <https://github.com/libgit2/luagit2>
|
||||
* .NET
|
||||
@ -124,7 +156,9 @@ How Can I Contribute?
|
||||
==================================
|
||||
|
||||
Fork libgit2/libgit2 on GitHub, add your improvement, push it to a branch
|
||||
in your fork named for the topic, send a pull request.
|
||||
in your fork named for the topic, send a pull request. If you change the
|
||||
API or make other large changes, make a note of it in docs/rel-notes/ in a
|
||||
file named after the next release.
|
||||
|
||||
You can also file bugs or feature requests under the libgit2 project on
|
||||
GitHub, or join us on the mailing list by sending an email to:
|
||||
|
1590
deps/http-parser/http_parser.c
vendored
1590
deps/http-parser/http_parser.c
vendored
File diff suppressed because it is too large
Load Diff
176
deps/http-parser/http_parser.h
vendored
176
deps/http-parser/http_parser.h
vendored
@ -24,16 +24,25 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HTTP_PARSER_VERSION_MAJOR 1
|
||||
#define HTTP_PARSER_VERSION_MAJOR 2
|
||||
#define HTTP_PARSER_VERSION_MINOR 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* disable silly warnings */
|
||||
# pragma warning(disable: 4127 4214)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "git2/common.h"
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
|
||||
#include <BaseTsd.h>
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef SIZE_T size_t;
|
||||
typedef SSIZE_T ssize_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
|
||||
* faster
|
||||
@ -42,21 +51,12 @@ extern "C" {
|
||||
# define HTTP_PARSER_STRICT 1
|
||||
#endif
|
||||
|
||||
/* Compile with -DHTTP_PARSER_DEBUG=1 to add extra debugging information to
|
||||
* the error reporting facility.
|
||||
*/
|
||||
#ifndef HTTP_PARSER_DEBUG
|
||||
# define HTTP_PARSER_DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Maximium header size allowed */
|
||||
#define HTTP_MAX_HEADER_SIZE (80*1024)
|
||||
|
||||
|
||||
typedef struct http_parser http_parser;
|
||||
typedef struct http_parser_settings http_parser_settings;
|
||||
typedef struct http_parser_result http_parser_result;
|
||||
|
||||
|
||||
/* Callbacks should return non-zero to indicate an error. The parser will
|
||||
@ -69,7 +69,7 @@ typedef struct http_parser_result http_parser_result;
|
||||
* chunked' headers that indicate the presence of a body.
|
||||
*
|
||||
* http_data_cb does not return data chunks. It will be call arbitrarally
|
||||
* many times for each string. E.G. you might get 10 callbacks for "on_path"
|
||||
* many times for each string. E.G. you might get 10 callbacks for "on_url"
|
||||
* each providing just a few characters more data.
|
||||
*/
|
||||
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
|
||||
@ -77,36 +77,44 @@ typedef int (*http_cb) (http_parser*);
|
||||
|
||||
|
||||
/* Request Methods */
|
||||
#define HTTP_METHOD_MAP(XX) \
|
||||
XX(0, DELETE, DELETE) \
|
||||
XX(1, GET, GET) \
|
||||
XX(2, HEAD, HEAD) \
|
||||
XX(3, POST, POST) \
|
||||
XX(4, PUT, PUT) \
|
||||
/* pathological */ \
|
||||
XX(5, CONNECT, CONNECT) \
|
||||
XX(6, OPTIONS, OPTIONS) \
|
||||
XX(7, TRACE, TRACE) \
|
||||
/* webdav */ \
|
||||
XX(8, COPY, COPY) \
|
||||
XX(9, LOCK, LOCK) \
|
||||
XX(10, MKCOL, MKCOL) \
|
||||
XX(11, MOVE, MOVE) \
|
||||
XX(12, PROPFIND, PROPFIND) \
|
||||
XX(13, PROPPATCH, PROPPATCH) \
|
||||
XX(14, SEARCH, SEARCH) \
|
||||
XX(15, UNLOCK, UNLOCK) \
|
||||
/* subversion */ \
|
||||
XX(16, REPORT, REPORT) \
|
||||
XX(17, MKACTIVITY, MKACTIVITY) \
|
||||
XX(18, CHECKOUT, CHECKOUT) \
|
||||
XX(19, MERGE, MERGE) \
|
||||
/* upnp */ \
|
||||
XX(20, MSEARCH, M-SEARCH) \
|
||||
XX(21, NOTIFY, NOTIFY) \
|
||||
XX(22, SUBSCRIBE, SUBSCRIBE) \
|
||||
XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \
|
||||
/* RFC-5789 */ \
|
||||
XX(24, PATCH, PATCH) \
|
||||
XX(25, PURGE, PURGE) \
|
||||
|
||||
enum http_method
|
||||
{ HTTP_DELETE = 0
|
||||
, HTTP_GET
|
||||
, HTTP_HEAD
|
||||
, HTTP_POST
|
||||
, HTTP_PUT
|
||||
/* pathological */
|
||||
, HTTP_CONNECT
|
||||
, HTTP_OPTIONS
|
||||
, HTTP_TRACE
|
||||
/* webdav */
|
||||
, HTTP_COPY
|
||||
, HTTP_LOCK
|
||||
, HTTP_MKCOL
|
||||
, HTTP_MOVE
|
||||
, HTTP_PROPFIND
|
||||
, HTTP_PROPPATCH
|
||||
, HTTP_UNLOCK
|
||||
/* subversion */
|
||||
, HTTP_REPORT
|
||||
, HTTP_MKACTIVITY
|
||||
, HTTP_CHECKOUT
|
||||
, HTTP_MERGE
|
||||
/* upnp */
|
||||
, HTTP_MSEARCH
|
||||
, HTTP_NOTIFY
|
||||
, HTTP_SUBSCRIBE
|
||||
, HTTP_UNSUBSCRIBE
|
||||
/* RFC-5789 */
|
||||
, HTTP_PATCH
|
||||
{
|
||||
#define XX(num, name, string) HTTP_##name = num,
|
||||
HTTP_METHOD_MAP(XX)
|
||||
#undef XX
|
||||
};
|
||||
|
||||
|
||||
@ -134,10 +142,7 @@ enum flags
|
||||
\
|
||||
/* Callback-related errors */ \
|
||||
XX(CB_message_begin, "the on_message_begin callback failed") \
|
||||
XX(CB_path, "the on_path callback failed") \
|
||||
XX(CB_query_string, "the on_query_string callback failed") \
|
||||
XX(CB_url, "the on_url callback failed") \
|
||||
XX(CB_fragment, "the on_fragment callback failed") \
|
||||
XX(CB_header_field, "the on_header_field callback failed") \
|
||||
XX(CB_header_value, "the on_header_value callback failed") \
|
||||
XX(CB_headers_complete, "the on_headers_complete callback failed") \
|
||||
@ -168,6 +173,7 @@ enum flags
|
||||
XX(INVALID_CONSTANT, "invalid constant string") \
|
||||
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
|
||||
XX(STRICT, "strict mode assertion failed") \
|
||||
XX(PAUSED, "parser is paused") \
|
||||
XX(UNKNOWN, "an unknown error occurred")
|
||||
|
||||
|
||||
@ -182,30 +188,23 @@ enum http_errno {
|
||||
/* Get an http_errno value from an http_parser */
|
||||
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
|
||||
|
||||
/* Get the line number that generated the current error */
|
||||
#if HTTP_PARSER_DEBUG
|
||||
#define HTTP_PARSER_ERRNO_LINE(p) ((p)->error_lineno)
|
||||
#else
|
||||
#define HTTP_PARSER_ERRNO_LINE(p) 0
|
||||
#endif
|
||||
|
||||
|
||||
struct http_parser {
|
||||
/** PRIVATE **/
|
||||
unsigned char type : 2;
|
||||
unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */
|
||||
unsigned char state;
|
||||
unsigned char header_state;
|
||||
unsigned char index;
|
||||
unsigned char type : 2; /* enum http_parser_type */
|
||||
unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */
|
||||
unsigned char state; /* enum state from http_parser.c */
|
||||
unsigned char header_state; /* enum header_state from http_parser.c */
|
||||
unsigned char index; /* index into current matcher */
|
||||
|
||||
size_t nread;
|
||||
int64_t content_length;
|
||||
uint32_t nread; /* # bytes read in various scenarios */
|
||||
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
|
||||
|
||||
/** READ-ONLY **/
|
||||
unsigned short http_major;
|
||||
unsigned short http_minor;
|
||||
unsigned short status_code; /* responses only */
|
||||
unsigned char method; /* requests only */
|
||||
unsigned char method; /* requests only */
|
||||
unsigned char http_errno : 7;
|
||||
|
||||
/* 1 = Upgrade header was present and the parser has exited because of that.
|
||||
@ -215,10 +214,6 @@ struct http_parser {
|
||||
*/
|
||||
unsigned char upgrade : 1;
|
||||
|
||||
#if HTTP_PARSER_DEBUG
|
||||
uint32_t error_lineno;
|
||||
#endif
|
||||
|
||||
/** PUBLIC **/
|
||||
void *data; /* A pointer to get hook to the "connection" or "socket" object */
|
||||
};
|
||||
@ -235,6 +230,36 @@ struct http_parser_settings {
|
||||
};
|
||||
|
||||
|
||||
enum http_parser_url_fields
|
||||
{ UF_SCHEMA = 0
|
||||
, UF_HOST = 1
|
||||
, UF_PORT = 2
|
||||
, UF_PATH = 3
|
||||
, UF_QUERY = 4
|
||||
, UF_FRAGMENT = 5
|
||||
, UF_USERINFO = 6
|
||||
, UF_MAX = 7
|
||||
};
|
||||
|
||||
|
||||
/* Result structure for http_parser_parse_url().
|
||||
*
|
||||
* Callers should index into field_data[] with UF_* values iff field_set
|
||||
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
|
||||
* because we probably have padding left over), we convert any port to
|
||||
* a uint16_t.
|
||||
*/
|
||||
struct http_parser_url {
|
||||
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
|
||||
uint16_t port; /* Converted UF_PORT string */
|
||||
|
||||
struct {
|
||||
uint16_t off; /* Offset into buffer in which field starts */
|
||||
uint16_t len; /* Length of run in buffer */
|
||||
} field_data[UF_MAX];
|
||||
};
|
||||
|
||||
|
||||
void http_parser_init(http_parser *parser, enum http_parser_type type);
|
||||
|
||||
|
||||
@ -245,12 +270,12 @@ size_t http_parser_execute(http_parser *parser,
|
||||
|
||||
|
||||
/* If http_should_keep_alive() in the on_headers_complete or
|
||||
* on_message_complete callback returns true, then this will be should be
|
||||
* on_message_complete callback returns 0, then this should be
|
||||
* the last message on the connection.
|
||||
* If you are the server, respond with the "Connection: close" header.
|
||||
* If you are the client, close the connection.
|
||||
*/
|
||||
int http_should_keep_alive(http_parser *parser);
|
||||
int http_should_keep_alive(const http_parser *parser);
|
||||
|
||||
/* Returns a string version of the HTTP method. */
|
||||
const char *http_method_str(enum http_method m);
|
||||
@ -261,6 +286,17 @@ const char *http_errno_name(enum http_errno err);
|
||||
/* Return a string description of the given error */
|
||||
const char *http_errno_description(enum http_errno err);
|
||||
|
||||
/* Parse a URL; return nonzero on failure */
|
||||
int http_parser_parse_url(const char *buf, size_t buflen,
|
||||
int is_connect,
|
||||
struct http_parser_url *u);
|
||||
|
||||
/* Pause or un-pause the parser; a nonzero value pauses */
|
||||
void http_parser_pause(http_parser *parser, int paused);
|
||||
|
||||
/* Checks if this is the final chunk of the body. */
|
||||
int http_body_is_final(const http_parser *parser);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
13
deps/regex/regcomp.c
vendored
13
deps/regex/regcomp.c
vendored
@ -542,7 +542,7 @@ weak_alias (__regcomp, regcomp)
|
||||
from either regcomp or regexec. We don't use PREG here. */
|
||||
|
||||
size_t
|
||||
regerror(int errcode, const regex_t *__restrict preg,
|
||||
regerror(int errcode, UNUSED const regex_t *__restrict preg,
|
||||
char *__restrict errbuf, size_t errbuf_size)
|
||||
{
|
||||
const char *msg;
|
||||
@ -1140,7 +1140,7 @@ analyze (regex_t *preg)
|
||||
dfa->subexp_map[i] = i;
|
||||
preorder (dfa->str_tree, optimize_subexps, dfa);
|
||||
for (i = 0; i < preg->re_nsub; i++)
|
||||
if (dfa->subexp_map[i] != i)
|
||||
if (dfa->subexp_map[i] != (int)i)
|
||||
break;
|
||||
if (i == preg->re_nsub)
|
||||
{
|
||||
@ -1358,7 +1358,7 @@ calc_first (void *extra, bin_tree_t *node)
|
||||
|
||||
/* Pass 2: compute NEXT on the tree. Preorder visit. */
|
||||
static reg_errcode_t
|
||||
calc_next (void *extra, bin_tree_t *node)
|
||||
calc_next (UNUSED void *extra, bin_tree_t *node)
|
||||
{
|
||||
switch (node->token.type)
|
||||
{
|
||||
@ -1609,7 +1609,8 @@ calc_inveclosure (re_dfa_t *dfa)
|
||||
static reg_errcode_t
|
||||
calc_eclosure (re_dfa_t *dfa)
|
||||
{
|
||||
int node_idx, incomplete;
|
||||
size_t node_idx;
|
||||
int incomplete;
|
||||
#ifdef DEBUG
|
||||
assert (dfa->nodes_len > 0);
|
||||
#endif
|
||||
@ -3308,7 +3309,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
||||
|
||||
static reg_errcode_t
|
||||
parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
|
||||
re_token_t *token, int token_len, re_dfa_t *dfa,
|
||||
re_token_t *token, int token_len, UNUSED re_dfa_t *dfa,
|
||||
reg_syntax_t syntax, int accept_hyphen)
|
||||
{
|
||||
#ifdef RE_ENABLE_I18N
|
||||
@ -3803,7 +3804,7 @@ free_token (re_token_t *node)
|
||||
and its children. */
|
||||
|
||||
static reg_errcode_t
|
||||
free_tree (void *extra, bin_tree_t *node)
|
||||
free_tree (UNUSED void *extra, bin_tree_t *node)
|
||||
{
|
||||
free_token (&node->token);
|
||||
return REG_NOERROR;
|
||||
|
2
deps/regex/regex_internal.c
vendored
2
deps/regex/regex_internal.c
vendored
@ -32,7 +32,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
|
||||
|
||||
#ifdef GAWK
|
||||
#undef MAX /* safety */
|
||||
static int
|
||||
static size_t
|
||||
MAX(size_t a, size_t b)
|
||||
{
|
||||
return (a > b ? a : b);
|
||||
|
15
deps/regex/regex_internal.h
vendored
15
deps/regex/regex_internal.h
vendored
@ -27,6 +27,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef UNUSED
|
||||
# ifdef __GNUC__
|
||||
# define UNUSED __attribute__((unused))
|
||||
# else
|
||||
# define UNUSED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
|
||||
# include <langinfo.h>
|
||||
#endif
|
||||
@ -63,7 +71,7 @@
|
||||
#endif
|
||||
#else /* GAWK */
|
||||
/*
|
||||
* This is a freaking mess. On glibc systems you have to define
|
||||
* This is a mess. On glibc systems you have to define
|
||||
* a magic constant to get isblank() out of <ctype.h>, since it's
|
||||
* a C99 function. To heck with all that and borrow a page from
|
||||
* dfa.c's book.
|
||||
@ -171,8 +179,9 @@ extern const size_t __re_error_msgid_idx[] attribute_hidden;
|
||||
typedef unsigned long int bitset_word_t;
|
||||
/* All bits set in a bitset_word_t. */
|
||||
#define BITSET_WORD_MAX ULONG_MAX
|
||||
/* Number of bits in a bitset_word_t. */
|
||||
#define BITSET_WORD_BITS (sizeof (bitset_word_t) * CHAR_BIT)
|
||||
/* Number of bits in a bitset_word_t. Cast to int as most code use it
|
||||
* like that for counting */
|
||||
#define BITSET_WORD_BITS ((int)(sizeof (bitset_word_t) * CHAR_BIT))
|
||||
/* Number of bitset_word_t in a bit_set. */
|
||||
#define BITSET_WORDS (SBC_MAX / BITSET_WORD_BITS)
|
||||
typedef bitset_word_t bitset_t[BITSET_WORDS];
|
||||
|
10
deps/regex/regexec.c
vendored
10
deps/regex/regexec.c
vendored
@ -689,7 +689,7 @@ re_search_internal (const regex_t *preg,
|
||||
if (nmatch > 1 || dfa->has_mb_node)
|
||||
{
|
||||
/* Avoid overflow. */
|
||||
if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0))
|
||||
if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= (size_t)mctx.input.bufs_len, 0))
|
||||
{
|
||||
err = REG_ESPACE;
|
||||
goto free_return;
|
||||
@ -920,7 +920,7 @@ re_search_internal (const regex_t *preg,
|
||||
|
||||
if (dfa->subexp_map)
|
||||
for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
|
||||
if (dfa->subexp_map[reg_idx] != reg_idx)
|
||||
if (dfa->subexp_map[reg_idx] != (int)reg_idx)
|
||||
{
|
||||
pmatch[reg_idx + 1].rm_so
|
||||
= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
|
||||
@ -953,7 +953,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
|
||||
halt_node = mctx->last_node;
|
||||
|
||||
/* Avoid overflow. */
|
||||
if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0))
|
||||
if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= (size_t)match_last, 0))
|
||||
return REG_ESPACE;
|
||||
|
||||
sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
|
||||
@ -3375,7 +3375,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
||||
/* Avoid arithmetic overflow in size calculation. */
|
||||
if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
|
||||
/ (3 * sizeof (re_dfastate_t *)))
|
||||
< ndests),
|
||||
< (size_t)ndests),
|
||||
0))
|
||||
goto out_free;
|
||||
|
||||
@ -4099,7 +4099,7 @@ extend_buffers (re_match_context_t *mctx)
|
||||
re_string_t *pstr = &mctx->input;
|
||||
|
||||
/* Avoid overflow. */
|
||||
if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
|
||||
if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= (size_t)pstr->bufs_len, 0))
|
||||
return REG_ESPACE;
|
||||
|
||||
/* Double the lengthes of the buffers. */
|
||||
|
203
docs/checkout-internals.md
Normal file
203
docs/checkout-internals.md
Normal file
@ -0,0 +1,203 @@
|
||||
Checkout Internals
|
||||
==================
|
||||
|
||||
Checkout has to handle a lot of different cases. It examines the
|
||||
differences between the target tree, the baseline tree and the working
|
||||
directory, plus the contents of the index, and groups files into five
|
||||
categories:
|
||||
|
||||
1. UNMODIFIED - Files that match in all places.
|
||||
2. SAFE - Files where the working directory and the baseline content
|
||||
match that can be safely updated to the target.
|
||||
3. DIRTY/MISSING - Files where the working directory differs from the
|
||||
baseline but there is no conflicting change with the target. One
|
||||
example is a file that doesn't exist in the working directory - no
|
||||
data would be lost as a result of writing this file. Which action
|
||||
will be taken with these files depends on the options you use.
|
||||
4. CONFLICTS - Files where changes in the working directory conflict
|
||||
with changes to be applied by the target. If conflicts are found,
|
||||
they prevent any other modifications from being made (although there
|
||||
are options to override that and force the update, of course).
|
||||
5. UNTRACKED/IGNORED - Files in the working directory that are untracked
|
||||
or ignored (i.e. only in the working directory, not the other places).
|
||||
|
||||
Right now, this classification is done via 3 iterators (for the three
|
||||
trees), with a final lookup in the index. At some point, this may move to
|
||||
a 4 iterator version to incorporate the index better.
|
||||
|
||||
The actual checkout is done in five phases (at least right now).
|
||||
|
||||
1. The diff between the baseline and the target tree is used as a base
|
||||
list of possible updates to be applied.
|
||||
2. Iterate through the diff and the working directory, building a list of
|
||||
actions to be taken (and sending notifications about conflicts and
|
||||
dirty files).
|
||||
3. Remove any files / directories as needed (because alphabetical
|
||||
iteration means that an untracked directory will end up sorted *after*
|
||||
a blob that should be checked out with the same name).
|
||||
4. Update all blobs.
|
||||
5. Update all submodules (after 4 in case a new .gitmodules blob was
|
||||
checked out)
|
||||
|
||||
Checkout could be driven either off a target-to-workdir diff or a
|
||||
baseline-to-target diff. There are pros and cons of each.
|
||||
|
||||
Target-to-workdir means the diff includes every file that could be
|
||||
modified, which simplifies bookkeeping, but the code to constantly refer
|
||||
back to the baseline gets complicated.
|
||||
|
||||
Baseline-to-target has simpler code because the diff defines the action to
|
||||
take, but needs special handling for untracked and ignored files, if they
|
||||
need to be removed.
|
||||
|
||||
The current checkout implementation is based on a baseline-to-target diff.
|
||||
|
||||
|
||||
Picking Actions
|
||||
===============
|
||||
|
||||
The most interesting aspect of this is phase 2, picking the actions that
|
||||
should be taken. There are a lot of corner cases, so it may be easier to
|
||||
start by looking at the rules for a simple 2-iterator diff:
|
||||
|
||||
Key
|
||||
---
|
||||
- B1,B2,B3 - blobs with different SHAs,
|
||||
- Bi - ignored blob (WD only)
|
||||
- T1,T2,T3 - trees with different SHAs,
|
||||
- Ti - ignored tree (WD only)
|
||||
- x - nothing
|
||||
|
||||
Diff with 2 non-workdir iterators
|
||||
---------------------------------
|
||||
|
||||
Old New
|
||||
--- ---
|
||||
0 x x - nothing
|
||||
1 x B1 - added blob
|
||||
2 x T1 - added tree
|
||||
3 B1 x - removed blob
|
||||
4 B1 B1 - unmodified blob
|
||||
5 B1 B2 - modified blob
|
||||
6 B1 T1 - typechange blob -> tree
|
||||
7 T1 x - removed tree
|
||||
8 T1 B1 - typechange tree -> blob
|
||||
9 T1 T1 - unmodified tree
|
||||
10 T1 T2 - modified tree (implies modified/added/removed blob inside)
|
||||
|
||||
|
||||
Now, let's make the "New" iterator into a working directory iterator, so
|
||||
we replace "added" items with either untracked or ignored, like this:
|
||||
|
||||
Diff with non-work & workdir iterators
|
||||
--------------------------------------
|
||||
|
||||
Old New-WD
|
||||
--- ------
|
||||
0 x x - nothing
|
||||
1 x B1 - untracked blob
|
||||
2 x Bi - ignored file
|
||||
3 x T1 - untracked tree
|
||||
4 x Ti - ignored tree
|
||||
5 B1 x - removed blob
|
||||
6 B1 B1 - unmodified blob
|
||||
7 B1 B2 - modified blob
|
||||
8 B1 T1 - typechange blob -> tree
|
||||
9 B1 Ti - removed blob AND ignored tree as separate items
|
||||
10 T1 x - removed tree
|
||||
11 T1 B1 - typechange tree -> blob
|
||||
12 T1 Bi - removed tree AND ignored blob as separate items
|
||||
13 T1 T1 - unmodified tree
|
||||
14 T1 T2 - modified tree (implies modified/added/removed blob inside)
|
||||
|
||||
Note: if there is a corresponding entry in the old tree, then a working
|
||||
directory item won't be ignored (i.e. no Bi or Ti for tracked items).
|
||||
|
||||
|
||||
Now, expand this to three iterators: a baseline tree, a target tree, and
|
||||
an actual working directory tree:
|
||||
|
||||
Checkout From 3 Iterators (2 not workdir, 1 workdir)
|
||||
----------------------------------------------------
|
||||
|
||||
(base == old HEAD; target == what to checkout; actual == working dir)
|
||||
|
||||
base target actual/workdir
|
||||
---- ------ ------
|
||||
0 x x x - nothing
|
||||
1 x x B1/Bi/T1/Ti - untracked/ignored blob/tree (SAFE)
|
||||
2+ x B1 x - add blob (SAFE)
|
||||
3 x B1 B1 - independently added blob (FORCEABLE-2)
|
||||
4* x B1 B2/Bi/T1/Ti - add blob with content conflict (FORCEABLE-2)
|
||||
5+ x T1 x - add tree (SAFE)
|
||||
6* x T1 B1/Bi - add tree with blob conflict (FORCEABLE-2)
|
||||
7 x T1 T1/i - independently added tree (SAFE+MISSING)
|
||||
8 B1 x x - independently deleted blob (SAFE+MISSING)
|
||||
9- B1 x B1 - delete blob (SAFE)
|
||||
10- B1 x B2 - delete of modified blob (FORCEABLE-1)
|
||||
11 B1 x T1/Ti - independently deleted blob AND untrack/ign tree (SAFE+MISSING !!!)
|
||||
12 B1 B1 x - locally deleted blob (DIRTY || SAFE+CREATE)
|
||||
13+ B1 B2 x - update to deleted blob (SAFE+MISSING)
|
||||
14 B1 B1 B1 - unmodified file (SAFE)
|
||||
15 B1 B1 B2 - locally modified file (DIRTY)
|
||||
16+ B1 B2 B1 - update unmodified blob (SAFE)
|
||||
17 B1 B2 B2 - independently updated blob (FORCEABLE-1)
|
||||
18+ B1 B2 B3 - update to modified blob (FORCEABLE-1)
|
||||
19 B1 B1 T1/Ti - locally deleted blob AND untrack/ign tree (DIRTY)
|
||||
20* B1 B2 T1/Ti - update to deleted blob AND untrack/ign tree (F-1)
|
||||
21+ B1 T1 x - add tree with locally deleted blob (SAFE+MISSING)
|
||||
22* B1 T1 B1 - add tree AND deleted blob (SAFE)
|
||||
23* B1 T1 B2 - add tree with delete of modified blob (F-1)
|
||||
24 B1 T1 T1 - add tree with deleted blob (F-1)
|
||||
25 T1 x x - independently deleted tree (SAFE+MISSING)
|
||||
26 T1 x B1/Bi - independently deleted tree AND untrack/ign blob (F-1)
|
||||
27- T1 x T1 - deleted tree (MAYBE SAFE)
|
||||
28+ T1 B1 x - deleted tree AND added blob (SAFE+MISSING)
|
||||
29 T1 B1 B1 - independently typechanged tree -> blob (F-1)
|
||||
30+ T1 B1 B2 - typechange tree->blob with conflicting blob (F-1)
|
||||
31* T1 B1 T1/T2 - typechange tree->blob (MAYBE SAFE)
|
||||
32+ T1 T1 x - restore locally deleted tree (SAFE+MISSING)
|
||||
33 T1 T1 B1/Bi - locally typechange tree->untrack/ign blob (DIRTY)
|
||||
34 T1 T1 T1/T2 - unmodified tree (MAYBE SAFE)
|
||||
35+ T1 T2 x - update locally deleted tree (SAFE+MISSING)
|
||||
36* T1 T2 B1/Bi - update to tree with typechanged tree->blob conflict (F-1)
|
||||
37 T1 T2 T1/T2/T3 - update to existing tree (MAYBE SAFE)
|
||||
|
||||
The number is followed by ' ' if no change is needed or '+' if the case
|
||||
needs to write to disk or '-' if something must be deleted and '*' if
|
||||
there should be a delete followed by an write.
|
||||
|
||||
There are four tiers of safe cases:
|
||||
|
||||
- SAFE == completely safe to update
|
||||
- SAFE+MISSING == safe except the workdir is missing the expect content
|
||||
- MAYBE SAFE == safe if workdir tree matches (or is missing) baseline
|
||||
content, which is unknown at this point
|
||||
- FORCEABLE == conflict unless FORCE is given
|
||||
- DIRTY == no conflict but change is not applied unless FORCE
|
||||
|
||||
Some slightly unusual circumstances:
|
||||
|
||||
8 - parent dir is only deleted when file is, so parent will be left if
|
||||
empty even though it would be deleted if the file were present
|
||||
11 - core git does not consider this a conflict but attempts to delete T1
|
||||
and gives "unable to unlink file" error yet does not skip the rest
|
||||
of the operation
|
||||
12 - without FORCE file is left deleted (i.e. not restored) so new wd is
|
||||
dirty (and warning message "D file" is printed), with FORCE, file is
|
||||
restored.
|
||||
24 - This should be considered MAYBE SAFE since effectively it is 7 and 8
|
||||
combined, but core git considers this a conflict unless forced.
|
||||
26 - This combines two cases (1 & 25) (and also implied 8 for tree content)
|
||||
which are ok on their own, but core git treat this as a conflict.
|
||||
If not forced, this is a conflict. If forced, this actually doesn't
|
||||
have to write anything and leaves the new blob as an untracked file.
|
||||
32 - This is the only case where the baseline and target values match
|
||||
and yet we will still write to the working directory. In all other
|
||||
cases, if baseline == target, we don't touch the workdir (it is
|
||||
either already right or is "dirty"). However, since this case also
|
||||
implies that a ?/B1/x case will exist as well, it can be skipped.
|
||||
|
||||
Cases 3, 17, 24, 26, and 29 are all considered conflicts even though
|
||||
none of them will require making any updates to the working directory.
|
||||
|
@ -29,7 +29,7 @@ The simple error API
|
||||
- `void giterr_set(git_error **, int, const char *, ...)`: the main function used to set an error. It allocates a new error object and stores it in the passed error pointer. It has no return value. The arguments for `giterr_set` are as follows:
|
||||
|
||||
- `git_error **error_ptr`: the pointer where the error will be created.
|
||||
- `int error_class`: the class for the error. This is **not** an error code: this is an speficic enum that specifies the error family. The point is to map these families 1-1 with Exception types on higher level languages (e.g. GitRepositoryException)
|
||||
- `int error_class`: the class for the error. This is **not** an error code: this is an specific enum that specifies the error family. The point is to map these families 1-1 with Exception types on higher level languages (e.g. GitRepositoryException)
|
||||
- `const char *error_str, ...`: the error string, with optional formatting arguments
|
||||
|
||||
- `void giterr_free(git_error *)`: takes an error and frees it. This function is available in the external API.
|
||||
@ -56,7 +56,7 @@ Here are some guidelines when writing error messages:
|
||||
|
||||
- Use short, direct and objective messages. **One line, max**. libgit2 is a low level library: think that all the messages reported will be thrown as Ruby or Python exceptions. Think how long are common exception messages in those languages.
|
||||
|
||||
- **Do not add redundant information to the error message**, specially information that can be infered from the context.
|
||||
- **Do not add redundant information to the error message**, specially information that can be inferred from the context.
|
||||
|
||||
E.g. in `git_repository_open`, do not report a message like "Failed to open repository: path not found". Somebody is
|
||||
calling that function. If it fails, he already knows that the repository failed to open!
|
||||
|
3
examples/.gitignore
vendored
3
examples/.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
general
|
||||
showindex
|
||||
diff
|
||||
rev-list
|
||||
*.dSYM
|
||||
|
@ -1,9 +1,9 @@
|
||||
.PHONY: all
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -I../include -I../src
|
||||
CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
|
||||
LFLAGS = -L../build -lgit2 -lz
|
||||
APPS = general showindex diff
|
||||
APPS = general showindex diff rev-list
|
||||
|
||||
all: $(APPS)
|
||||
|
||||
|
11
examples/README.md
Normal file
11
examples/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
libgit2 examples
|
||||
================
|
||||
|
||||
These examples are meant as thin, easy-to-read snippets for Docurium
|
||||
(https://github.com/github/docurium) rather than full-blown
|
||||
implementations of Git commands. They are not vetted as carefully
|
||||
for bugs, error handling, or cross-platform compatibility as the
|
||||
rest of the code in libgit2, so copy with some caution.
|
||||
|
||||
For HTML versions, check "Examples" at http://libgit2.github.com/libgit2
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void check(int error, const char *message)
|
||||
static void check(int error, const char *message)
|
||||
{
|
||||
if (error) {
|
||||
fprintf(stderr, "%s (%d)\n", message, error);
|
||||
@ -11,32 +11,14 @@ void check(int error, const char *message)
|
||||
}
|
||||
}
|
||||
|
||||
int resolve_to_tree(git_repository *repo, const char *identifier, git_tree **tree)
|
||||
static int resolve_to_tree(
|
||||
git_repository *repo, const char *identifier, git_tree **tree)
|
||||
{
|
||||
int err = 0;
|
||||
size_t len = strlen(identifier);
|
||||
git_oid oid;
|
||||
git_object *obj = NULL;
|
||||
|
||||
/* try to resolve as OID */
|
||||
if (git_oid_fromstrn(&oid, identifier, len) == 0)
|
||||
git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY);
|
||||
|
||||
/* try to resolve as reference */
|
||||
if (obj == NULL) {
|
||||
git_reference *ref, *resolved;
|
||||
if (git_reference_lookup(&ref, repo, identifier) == 0) {
|
||||
git_reference_resolve(&resolved, ref);
|
||||
git_reference_free(ref);
|
||||
if (resolved) {
|
||||
git_object_lookup(&obj, repo, git_reference_oid(resolved), GIT_OBJ_ANY);
|
||||
git_reference_free(resolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj == NULL)
|
||||
return GIT_ENOTFOUND;
|
||||
if ((err = git_revparse_single(&obj, repo, identifier)) < 0)
|
||||
return err;
|
||||
|
||||
switch (git_object_type(obj)) {
|
||||
case GIT_OBJ_TREE:
|
||||
@ -61,16 +43,18 @@ char *colors[] = {
|
||||
"\033[36m" /* cyan */
|
||||
};
|
||||
|
||||
int printer(
|
||||
void *data,
|
||||
git_diff_delta *delta,
|
||||
git_diff_range *range,
|
||||
static int printer(
|
||||
const git_diff_delta *delta,
|
||||
const git_diff_range *range,
|
||||
char usage,
|
||||
const char *line,
|
||||
size_t line_len)
|
||||
size_t line_len,
|
||||
void *data)
|
||||
{
|
||||
int *last_color = data, color = 0;
|
||||
|
||||
(void)delta; (void)range; (void)line_len;
|
||||
|
||||
if (*last_color >= 0) {
|
||||
switch (usage) {
|
||||
case GIT_DIFF_LINE_ADDITION: color = 3; break;
|
||||
@ -93,7 +77,7 @@ int printer(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_uint16_param(const char *arg, const char *pattern, uint16_t *val)
|
||||
static int check_uint16_param(const char *arg, const char *pattern, uint16_t *val)
|
||||
{
|
||||
size_t len = strlen(pattern);
|
||||
uint16_t strval;
|
||||
@ -107,16 +91,16 @@ int check_uint16_param(const char *arg, const char *pattern, uint16_t *val)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int check_str_param(const char *arg, const char *pattern, char **val)
|
||||
static int check_str_param(const char *arg, const char *pattern, const char **val)
|
||||
{
|
||||
size_t len = strlen(pattern);
|
||||
if (strncmp(arg, pattern, len))
|
||||
return 0;
|
||||
*val = (char *)(arg + len);
|
||||
*val = (const char *)(arg + len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void usage(const char *message, const char *arg)
|
||||
static void usage(const char *message, const char *arg)
|
||||
{
|
||||
if (message && arg)
|
||||
fprintf(stderr, "%s: %s\n", message, arg);
|
||||
@ -128,10 +112,9 @@ void usage(const char *message, const char *arg)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char path[GIT_PATH_MAX];
|
||||
git_repository *repo = NULL;
|
||||
git_tree *t1 = NULL, *t2 = NULL;
|
||||
git_diff_options opts = {0};
|
||||
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
||||
git_diff_list *diff;
|
||||
int i, color = -1, compact = 0, cached = 0;
|
||||
char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL;
|
||||
@ -185,9 +168,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* open repo */
|
||||
|
||||
check(git_repository_discover(path, sizeof(path), dir, 0, "/"),
|
||||
"Could not discover repository");
|
||||
check(git_repository_open(&repo, path),
|
||||
check(git_repository_open_ext(&repo, dir, 0, NULL),
|
||||
"Could not open repository");
|
||||
|
||||
if (treeish1)
|
||||
@ -202,30 +183,30 @@ int main(int argc, char *argv[])
|
||||
/* nothing */
|
||||
|
||||
if (t1 && t2)
|
||||
check(git_diff_tree_to_tree(repo, &opts, t1, t2, &diff), "Diff");
|
||||
check(git_diff_tree_to_tree(&diff, repo, t1, t2, &opts), "Diff");
|
||||
else if (t1 && cached)
|
||||
check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
|
||||
check(git_diff_tree_to_index(&diff, repo, t1, NULL, &opts), "Diff");
|
||||
else if (t1) {
|
||||
git_diff_list *diff2;
|
||||
check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
|
||||
check(git_diff_workdir_to_index(repo, &opts, &diff2), "Diff");
|
||||
check(git_diff_tree_to_index(&diff, repo, t1, NULL, &opts), "Diff");
|
||||
check(git_diff_index_to_workdir(&diff2, repo, NULL, &opts), "Diff");
|
||||
check(git_diff_merge(diff, diff2), "Merge diffs");
|
||||
git_diff_list_free(diff2);
|
||||
}
|
||||
else if (cached) {
|
||||
check(resolve_to_tree(repo, "HEAD", &t1), "looking up HEAD");
|
||||
check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
|
||||
check(git_diff_tree_to_index(&diff, repo, t1, NULL, &opts), "Diff");
|
||||
}
|
||||
else
|
||||
check(git_diff_workdir_to_index(repo, &opts, &diff), "Diff");
|
||||
check(git_diff_index_to_workdir(&diff, repo, NULL, &opts), "Diff");
|
||||
|
||||
if (color >= 0)
|
||||
fputs(colors[0], stdout);
|
||||
|
||||
if (compact)
|
||||
check(git_diff_print_compact(diff, &color, printer), "Displaying diff");
|
||||
check(git_diff_print_compact(diff, printer, &color), "Displaying diff");
|
||||
else
|
||||
check(git_diff_print_patch(diff, &color, printer), "Displaying diff");
|
||||
check(git_diff_print_patch(diff, printer, &color), "Displaying diff");
|
||||
|
||||
if (color >= 0)
|
||||
fputs(colors[0], stdout);
|
||||
|
@ -1,64 +1,85 @@
|
||||
// [**libgit2**][lg] 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 write native speed custom Git applications in any language which
|
||||
// supports C bindings.
|
||||
// [**libgit2**][lg] 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 write native speed custom Git applications in any
|
||||
// language which supports C bindings.
|
||||
//
|
||||
// This file is an example of using that API in a real, compilable C file.
|
||||
// As the API is updated, this file will be updated to demonstrate the
|
||||
// new functionality.
|
||||
// As the API is updated, this file will be updated to demonstrate the new
|
||||
// functionality.
|
||||
//
|
||||
// If you're trying to write something in C using [libgit2][lg], you will also want
|
||||
// to check out the generated [API documentation][ap] and the [Usage Guide][ug]. We've
|
||||
// tried to link to the relevant sections of the API docs in each section in this file.
|
||||
// If you're trying to write something in C using [libgit2][lg], you should
|
||||
// also check out the generated [API documentation][ap]. We try to link to
|
||||
// the relevant sections of the API docs in each section in this file.
|
||||
//
|
||||
// **libgit2** only implements the core plumbing functions, not really the higher
|
||||
// level porcelain stuff. For a primer on Git Internals that you will need to know
|
||||
// to work with Git at this level, check out [Chapter 9][pg] of the Pro Git book.
|
||||
// **libgit2** (for the most part) only implements the core plumbing
|
||||
// functions, not really the higher level porcelain stuff. For a primer on
|
||||
// Git Internals that you will need to know to work with Git at this level,
|
||||
// check out [Chapter 9][pg] of the Pro Git book.
|
||||
//
|
||||
// [lg]: http://libgit2.github.com
|
||||
// [ap]: http://libgit2.github.com/libgit2
|
||||
// [ug]: http://libgit2.github.com/api.html
|
||||
// [pg]: http://progit.org/book/ch9-0.html
|
||||
|
||||
// ### Includes
|
||||
|
||||
// Including the `git2.h` header will include all the other libgit2 headers that you need.
|
||||
// It should be the only thing you need to include in order to compile properly and get
|
||||
// all the libgit2 API.
|
||||
// Including the `git2.h` header will include all the other libgit2 headers
|
||||
// that you need. It should be the only thing you need to include in order
|
||||
// to compile properly and get all the libgit2 API.
|
||||
#include <git2.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Almost all libgit2 functions return 0 on success or negative on error.
|
||||
// This is not production quality error checking, but should be sufficient
|
||||
// as an example.
|
||||
static void check_error(int error_code, const char *action)
|
||||
{
|
||||
if (!error_code)
|
||||
return;
|
||||
|
||||
const git_error *error = giterr_last();
|
||||
|
||||
printf("Error %d %s - %s\n", error_code, action,
|
||||
(error && error->message) ? error->message : "???");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
// ### Opening the Repository
|
||||
|
||||
// There are a couple of methods for opening a repository, this being the simplest.
|
||||
// There are also [methods][me] for specifying the index file and work tree locations, here
|
||||
// we are assuming they are in the normal places.
|
||||
// There are a couple of methods for opening a repository, this being the
|
||||
// simplest. There are also [methods][me] for specifying the index file
|
||||
// and work tree locations, here we assume they are in the normal places.
|
||||
//
|
||||
// (Try running this program against tests-clar/resources/testrepo.git.)
|
||||
//
|
||||
// [me]: http://libgit2.github.com/libgit2/#HEAD/group/repository
|
||||
int error;
|
||||
const char *repo_path = (argc > 1) ? argv[1] : "/opt/libgit2-test/.git";
|
||||
git_repository *repo;
|
||||
if (argc > 1) {
|
||||
git_repository_open(&repo, argv[1]);
|
||||
} else {
|
||||
git_repository_open(&repo, "/opt/libgit2-test/.git");
|
||||
}
|
||||
|
||||
error = git_repository_open(&repo, repo_path);
|
||||
check_error(error, "opening repository");
|
||||
|
||||
// ### SHA-1 Value Conversions
|
||||
|
||||
// For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.
|
||||
// For our first example, we will convert a 40 character hex value to the
|
||||
// 20 byte raw SHA1 value.
|
||||
printf("*Hex to Raw*\n");
|
||||
char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
|
||||
char hex[] = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045";
|
||||
|
||||
// The `git_oid` is the structure that keeps the SHA value. We will use this throughout the example
|
||||
// for storing the value of the current SHA key we're working with.
|
||||
// The `git_oid` is the structure that keeps the SHA value. We will use
|
||||
// this throughout the example for storing the value of the current SHA
|
||||
// key we're working with.
|
||||
git_oid oid;
|
||||
git_oid_fromstr(&oid, hex);
|
||||
|
||||
// Once we've converted the string into the oid value, we can get the raw value of the SHA.
|
||||
printf("Raw 20 bytes: [%.20s]\n", (&oid)->id);
|
||||
// Once we've converted the string into the oid value, we can get the raw
|
||||
// value of the SHA by accessing `oid.id`
|
||||
|
||||
// Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.
|
||||
// Next we will convert the 20 byte raw SHA1 value to a human readable 40
|
||||
// char hex value.
|
||||
printf("\n*Raw to Hex*\n");
|
||||
char out[41];
|
||||
out[40] = '\0';
|
||||
@ -68,10 +89,12 @@ int main (int argc, char** argv)
|
||||
printf("SHA hex string: %s\n", out);
|
||||
|
||||
// ### Working with the Object Database
|
||||
// **libgit2** provides [direct access][odb] to the object database.
|
||||
// The object database is where the actual objects are stored in Git. For
|
||||
|
||||
// **libgit2** provides [direct access][odb] to the object database. The
|
||||
// object database is where the actual objects are stored in Git. For
|
||||
// working with raw objects, we'll need to get this structure from the
|
||||
// repository.
|
||||
//
|
||||
// [odb]: http://libgit2.github.com/libgit2/#HEAD/group/odb
|
||||
git_odb *odb;
|
||||
git_repository_odb(&odb, repo);
|
||||
@ -83,84 +106,93 @@ int main (int argc, char** argv)
|
||||
git_otype otype;
|
||||
const unsigned char *data;
|
||||
const char *str_type;
|
||||
int error;
|
||||
|
||||
// We can read raw objects directly from the object database if we have the oid (SHA)
|
||||
// of the object. This allows us to access objects without knowing thier type and inspect
|
||||
// the raw bytes unparsed.
|
||||
// We can read raw objects directly from the object database if we have
|
||||
// the oid (SHA) of the object. This allows us to access objects without
|
||||
// knowing thier type and inspect the raw bytes unparsed.
|
||||
error = git_odb_read(&obj, odb, &oid);
|
||||
check_error(error, "finding object in repository");
|
||||
|
||||
// A raw object only has three properties - the type (commit, blob, tree or tag), the size
|
||||
// of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data
|
||||
// is human readable plain ASCII text. For a blob it is just file contents, so it could be
|
||||
// text or binary data. For a tree it is a special binary format, so it's unlikely to be
|
||||
// hugely helpful as a raw object.
|
||||
// A raw object only has three properties - the type (commit, blob, tree
|
||||
// or tag), the size of the raw data and the raw, unparsed data itself.
|
||||
// For a commit or tag, that raw data is human readable plain ASCII
|
||||
// text. For a blob it is just file contents, so it could be text or
|
||||
// binary data. For a tree it is a special binary format, so it's unlikely
|
||||
// to be hugely helpful as a raw object.
|
||||
data = (const unsigned char *)git_odb_object_data(obj);
|
||||
otype = git_odb_object_type(obj);
|
||||
|
||||
// We provide methods to convert from the object type which is an enum, to a string
|
||||
// representation of that value (and vice-versa).
|
||||
// We provide methods to convert from the object type which is an enum, to
|
||||
// a string representation of that value (and vice-versa).
|
||||
str_type = git_object_type2string(otype);
|
||||
printf("object length and type: %d, %s\n",
|
||||
(int)git_odb_object_size(obj),
|
||||
str_type);
|
||||
|
||||
// For proper memory management, close the object when you are done with it or it will leak
|
||||
// memory.
|
||||
// For proper memory management, close the object when you are done with
|
||||
// it or it will leak memory.
|
||||
git_odb_object_free(obj);
|
||||
|
||||
// #### Raw Object Writing
|
||||
|
||||
printf("\n*Raw Object Write*\n");
|
||||
|
||||
// You can also write raw object data to Git. This is pretty cool because it gives you
|
||||
// direct access to the key/value properties of Git. Here we'll write a new blob object
|
||||
// that just contains a simple string. Notice that we have to specify the object type as
|
||||
// the `git_otype` enum.
|
||||
// You can also write raw object data to Git. This is pretty cool because
|
||||
// it gives you direct access to the key/value properties of Git. Here
|
||||
// we'll write a new blob object that just contains a simple string.
|
||||
// Notice that we have to specify the object type as the `git_otype` enum.
|
||||
git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
|
||||
|
||||
// Now that we've written the object, we can check out what SHA1 was generated when the
|
||||
// object was written to our database.
|
||||
// Now that we've written the object, we can check out what SHA1 was
|
||||
// generated when the object was written to our database.
|
||||
git_oid_fmt(out, &oid);
|
||||
printf("Written Object: %s\n", out);
|
||||
|
||||
// ### Object Parsing
|
||||
// libgit2 has methods to parse every object type in Git so you don't have to work directly
|
||||
// with the raw data. This is much faster and simpler than trying to deal with the raw data
|
||||
// yourself.
|
||||
|
||||
// libgit2 has methods to parse every object type in Git so you don't have
|
||||
// to work directly with the raw data. This is much faster and simpler
|
||||
// than trying to deal with the raw data yourself.
|
||||
|
||||
// #### Commit Parsing
|
||||
// [Parsing commit objects][pco] is simple and gives you access to all the data in the commit
|
||||
// - the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).
|
||||
|
||||
// [Parsing commit objects][pco] is simple and gives you access to all the
|
||||
// data in the commit - the author (name, email, datetime), committer
|
||||
// (same), tree, message, encoding and parent(s).
|
||||
//
|
||||
// [pco]: http://libgit2.github.com/libgit2/#HEAD/group/commit
|
||||
|
||||
printf("\n*Commit Parsing*\n");
|
||||
|
||||
git_commit *commit;
|
||||
git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
|
||||
git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479");
|
||||
|
||||
error = git_commit_lookup(&commit, repo, &oid);
|
||||
check_error(error, "looking up commit");
|
||||
|
||||
const git_signature *author, *cmtter;
|
||||
const char *message;
|
||||
time_t ctime;
|
||||
unsigned int parents, p;
|
||||
|
||||
// Each of the properties of the commit object are accessible via methods, including commonly
|
||||
// needed variations, such as `git_commit_time` which returns the author time and `_message`
|
||||
// which gives you the commit message.
|
||||
// Each of the properties of the commit object are accessible via methods,
|
||||
// including commonly needed variations, such as `git_commit_time` which
|
||||
// returns the author time and `git_commit_message` which gives you the
|
||||
// commit message (as a NUL-terminated string).
|
||||
message = git_commit_message(commit);
|
||||
author = git_commit_author(commit);
|
||||
cmtter = git_commit_committer(commit);
|
||||
ctime = git_commit_time(commit);
|
||||
|
||||
// The author and committer methods return [git_signature] structures, which give you name, email
|
||||
// and `when`, which is a `git_time` structure, giving you a timestamp and timezone offset.
|
||||
// The author and committer methods return [git_signature] structures,
|
||||
// which give you name, email and `when`, which is a `git_time` structure,
|
||||
// giving you a timestamp and timezone offset.
|
||||
printf("Author: %s (%s)\n", author->name, author->email);
|
||||
|
||||
// Commits can have zero or more parents. The first (root) commit will have no parents, most commits
|
||||
// will have one, which is the commit it was based on, and merge commits will have two or more.
|
||||
// Commits can technically have any number, though it's pretty rare to have more than two.
|
||||
// Commits can have zero or more parents. The first (root) commit will
|
||||
// have no parents, most commits will have one (i.e. the commit it was
|
||||
// based on) and merge commits will have two or more. Commits can
|
||||
// technically have any number, though it's rare to have more than two.
|
||||
parents = git_commit_parentcount(commit);
|
||||
for (p = 0;p < parents;p++) {
|
||||
git_commit *parent;
|
||||
@ -170,15 +202,17 @@ int main (int argc, char** argv)
|
||||
git_commit_free(parent);
|
||||
}
|
||||
|
||||
// Don't forget to close the object to prevent memory leaks. You will have to do this for
|
||||
// all the objects you open and parse.
|
||||
// Don't forget to close the object to prevent memory leaks. You will have
|
||||
// to do this for all the objects you open and parse.
|
||||
git_commit_free(commit);
|
||||
|
||||
// #### Writing Commits
|
||||
|
||||
// libgit2 provides a couple of methods to create commit objects easily as
|
||||
// well. There are four different create signatures, we'll just show one
|
||||
// of them here. You can read about the other ones in the [commit API
|
||||
// docs][cd].
|
||||
//
|
||||
// libgit2 provides a couple of methods to create commit objects easily as well. There are four
|
||||
// different create signatures, we'll just show one of them here. You can read about the other
|
||||
// ones in the [commit API docs][cd].
|
||||
// [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit
|
||||
|
||||
printf("\n*Commit Writing*\n");
|
||||
@ -186,24 +220,27 @@ int main (int argc, char** argv)
|
||||
git_tree *tree;
|
||||
git_commit *parent;
|
||||
|
||||
// Creating signatures for an authoring identity and time is pretty simple - you will need to have
|
||||
// this to create a commit in order to specify who created it and when. Default values for the name
|
||||
// and email should be found in the `user.name` and `user.email` configuration options. See the `config`
|
||||
// section of this example file to see how to access config values.
|
||||
git_signature_new((git_signature **)&author, "Scott Chacon", "schacon@gmail.com",
|
||||
123456789, 60);
|
||||
git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "scott@github.com",
|
||||
987654321, 90);
|
||||
// Creating signatures for an authoring identity and time is simple. You
|
||||
// will need to do this to specify who created a commit and when. Default
|
||||
// values for the name and email should be found in the `user.name` and
|
||||
// `user.email` configuration options. See the `config` section of this
|
||||
// example file to see how to access config values.
|
||||
git_signature_new((git_signature **)&author,
|
||||
"Scott Chacon", "schacon@gmail.com", 123456789, 60);
|
||||
git_signature_new((git_signature **)&cmtter,
|
||||
"Scott A Chacon", "scott@github.com", 987654321, 90);
|
||||
|
||||
// Commit objects need a tree to point to and optionally one or more parents. Here we're creating oid
|
||||
// objects to create the commit with, but you can also use
|
||||
git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
|
||||
// Commit objects need a tree to point to and optionally one or more
|
||||
// parents. Here we're creating oid objects to create the commit with,
|
||||
// but you can also use
|
||||
git_oid_fromstr(&tree_id, "f60079018b664e4e79329a7ef9559c8d9e0378d1");
|
||||
git_tree_lookup(&tree, repo, &tree_id);
|
||||
git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
|
||||
git_oid_fromstr(&parent_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
|
||||
git_commit_lookup(&parent, repo, &parent_id);
|
||||
|
||||
// Here we actually create the commit object with a single call with all the values we need to create
|
||||
// the commit. The SHA key is written to the `commit_id` variable here.
|
||||
// Here we actually create the commit object with a single call with all
|
||||
// the values we need to create the commit. The SHA key is written to the
|
||||
// `commit_id` variable here.
|
||||
git_commit_create_v(
|
||||
&commit_id, /* out id */
|
||||
repo,
|
||||
@ -220,35 +257,42 @@ int main (int argc, char** argv)
|
||||
printf("New Commit: %s\n", out);
|
||||
|
||||
// #### Tag Parsing
|
||||
// You can parse and create tags with the [tag management API][tm], which functions very similarly
|
||||
// to the commit lookup, parsing and creation methods, since the objects themselves are very similar.
|
||||
|
||||
// You can parse and create tags with the [tag management API][tm], which
|
||||
// functions very similarly to the commit lookup, parsing and creation
|
||||
// methods, since the objects themselves are very similar.
|
||||
//
|
||||
// [tm]: http://libgit2.github.com/libgit2/#HEAD/group/tag
|
||||
printf("\n*Tag Parsing*\n");
|
||||
git_tag *tag;
|
||||
const char *tmessage, *tname;
|
||||
git_otype ttype;
|
||||
|
||||
// We create an oid for the tag object if we know the SHA and look it up in the repository the same
|
||||
// way that we would a commit (or any other) object.
|
||||
git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
|
||||
// We create an oid for the tag object if we know the SHA and look it up
|
||||
// the same way that we would a commit (or any other object).
|
||||
git_oid_fromstr(&oid, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
|
||||
|
||||
error = git_tag_lookup(&tag, repo, &oid);
|
||||
check_error(error, "looking up tag");
|
||||
|
||||
// Now that we have the tag object, we can extract the information it generally contains: the target
|
||||
// (usually a commit object), the type of the target object (usually 'commit'), the name ('v1.0'),
|
||||
// the tagger (a git_signature - name, email, timestamp), and the tag message.
|
||||
// Now that we have the tag object, we can extract the information it
|
||||
// generally contains: the target (usually a commit object), the type of
|
||||
// the target object (usually 'commit'), the name ('v1.0'), the tagger (a
|
||||
// git_signature - name, email, timestamp), and the tag message.
|
||||
git_tag_target((git_object **)&commit, tag);
|
||||
tname = git_tag_name(tag); // "test"
|
||||
ttype = git_tag_type(tag); // GIT_OBJ_COMMIT (otype enum)
|
||||
tmessage = git_tag_message(tag); // "tag message\n"
|
||||
tname = git_tag_name(tag); // "test"
|
||||
ttype = git_tag_target_type(tag); // GIT_OBJ_COMMIT (otype enum)
|
||||
tmessage = git_tag_message(tag); // "tag message\n"
|
||||
printf("Tag Message: %s\n", tmessage);
|
||||
|
||||
git_commit_free(commit);
|
||||
|
||||
// #### Tree Parsing
|
||||
// [Tree parsing][tp] is a bit different than the other objects, in that we have a subtype which is the
|
||||
// tree entry. This is not an actual object type in Git, but a useful structure for parsing and
|
||||
// traversing tree entries.
|
||||
|
||||
// [Tree parsing][tp] is a bit different than the other objects, in that
|
||||
// we have a subtype which is the tree entry. This is not an actual
|
||||
// object type in Git, but a useful structure for parsing and traversing
|
||||
// tree entries.
|
||||
//
|
||||
// [tp]: http://libgit2.github.com/libgit2/#HEAD/group/tree
|
||||
printf("\n*Tree Parsing*\n");
|
||||
@ -260,54 +304,61 @@ int main (int argc, char** argv)
|
||||
git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
|
||||
git_tree_lookup(&tree, repo, &oid);
|
||||
|
||||
// Getting the count of entries in the tree so you can iterate over them if you want to.
|
||||
int cnt = git_tree_entrycount(tree); // 3
|
||||
printf("tree entries: %d\n", cnt);
|
||||
// Getting the count of entries in the tree so you can iterate over them
|
||||
// if you want to.
|
||||
size_t cnt = git_tree_entrycount(tree); // 3
|
||||
printf("tree entries: %d\n", (int)cnt);
|
||||
|
||||
entry = git_tree_entry_byindex(tree, 0);
|
||||
printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
|
||||
|
||||
// You can also access tree entries by name if you know the name of the entry you're looking for.
|
||||
entry = git_tree_entry_byname(tree, "hello.c");
|
||||
// You can also access tree entries by name if you know the name of the
|
||||
// entry you're looking for.
|
||||
entry = git_tree_entry_byname(tree, "README");
|
||||
git_tree_entry_name(entry); // "hello.c"
|
||||
|
||||
// Once you have the entry object, you can access the content or subtree (or commit, in the case
|
||||
// of submodules) that it points to. You can also get the mode if you want.
|
||||
// Once you have the entry object, you can access the content or subtree
|
||||
// (or commit, in the case of submodules) that it points to. You can also
|
||||
// get the mode if you want.
|
||||
git_tree_entry_to_object(&objt, repo, entry); // blob
|
||||
|
||||
// Remember to close the looked-up object once you are done using it
|
||||
git_object_free(objt);
|
||||
|
||||
// #### Blob Parsing
|
||||
//
|
||||
// The last object type is the simplest and requires the least parsing help. Blobs are just file
|
||||
// contents and can contain anything, there is no structure to it. The main advantage to using the
|
||||
// [simple blob api][ba] is that when you're creating blobs you don't have to calculate the size
|
||||
// of the content. There is also a helper for reading a file from disk and writing it to the db and
|
||||
// getting the oid back so you don't have to do all those steps yourself.
|
||||
|
||||
// The last object type is the simplest and requires the least parsing
|
||||
// help. Blobs are just file contents and can contain anything, there is
|
||||
// no structure to it. The main advantage to using the [simple blob
|
||||
// api][ba] is that when you're creating blobs you don't have to calculate
|
||||
// the size of the content. There is also a helper for reading a file
|
||||
// from disk and writing it to the db and getting the oid back so you
|
||||
// don't have to do all those steps yourself.
|
||||
//
|
||||
// [ba]: http://libgit2.github.com/libgit2/#HEAD/group/blob
|
||||
|
||||
printf("\n*Blob Parsing*\n");
|
||||
git_blob *blob;
|
||||
|
||||
git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
|
||||
git_oid_fromstr(&oid, "1385f264afb75a56a5bec74243be9b367ba4ca08");
|
||||
git_blob_lookup(&blob, repo, &oid);
|
||||
|
||||
// You can access a buffer with the raw contents of the blob directly.
|
||||
// Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files):
|
||||
// do not consider the buffer a NULL-terminated string, and use the `git_blob_rawsize` attribute to
|
||||
// find out its exact size in bytes
|
||||
printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8
|
||||
// Note that this buffer may not be contain ASCII data for certain blobs
|
||||
// (e.g. binary files): do not consider the buffer a NULL-terminated
|
||||
// string, and use the `git_blob_rawsize` attribute to find out its exact
|
||||
// size in bytes
|
||||
printf("Blob Size: %ld\n", (long)git_blob_rawsize(blob)); // 8
|
||||
git_blob_rawcontent(blob); // "content"
|
||||
|
||||
// ### Revwalking
|
||||
//
|
||||
// The libgit2 [revision walking api][rw] provides methods to traverse the directed graph created
|
||||
// by the parent pointers of the commit objects. Since all commits point back to the commit that
|
||||
// came directly before them, you can walk this parentage as a graph and find all the commits that
|
||||
// were ancestors of (reachable from) a given starting point. This can allow you to create `git log`
|
||||
// type functionality.
|
||||
|
||||
// The libgit2 [revision walking api][rw] provides methods to traverse the
|
||||
// directed graph created by the parent pointers of the commit objects.
|
||||
// Since all commits point back to the commit that came directly before
|
||||
// them, you can walk this parentage as a graph and find all the commits
|
||||
// that were ancestors of (reachable from) a given starting point. This
|
||||
// can allow you to create `git log` type functionality.
|
||||
//
|
||||
// [rw]: http://libgit2.github.com/libgit2/#HEAD/group/revwalk
|
||||
|
||||
@ -315,13 +366,15 @@ int main (int argc, char** argv)
|
||||
git_revwalk *walk;
|
||||
git_commit *wcommit;
|
||||
|
||||
git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
|
||||
git_oid_fromstr(&oid, "5b5b025afb0b4c913b4c338a42934a3863bf3644");
|
||||
|
||||
// To use the revwalker, create a new walker, tell it how you want to sort the output and then push
|
||||
// one or more starting points onto the walker. If you want to emulate the output of `git log` you
|
||||
// would push the SHA of the commit that HEAD points to into the walker and then start traversing them.
|
||||
// You can also 'hide' commits that you want to stop at or not see any of their ancestors. So if you
|
||||
// want to emulate `git log branch1..branch2`, you would push the oid of `branch2` and hide the oid
|
||||
// To use the revwalker, create a new walker, tell it how you want to sort
|
||||
// the output and then push one or more starting points onto the walker.
|
||||
// If you want to emulate the output of `git log` you would push the SHA
|
||||
// of the commit that HEAD points to into the walker and then start
|
||||
// traversing them. You can also 'hide' commits that you want to stop at
|
||||
// or not see any of their ancestors. So if you want to emulate `git log
|
||||
// branch1..branch2`, you would push the oid of `branch2` and hide the oid
|
||||
// of `branch1`.
|
||||
git_revwalk_new(&walk, repo);
|
||||
git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
|
||||
@ -330,28 +383,32 @@ int main (int argc, char** argv)
|
||||
const git_signature *cauth;
|
||||
const char *cmsg;
|
||||
|
||||
// Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It
|
||||
// will return them in the sorting order we asked for as commit oids.
|
||||
// We can then lookup and parse the commited pointed at by the returned OID;
|
||||
// note that this operation is specially fast since the raw contents of the commit object will
|
||||
// be cached in memory
|
||||
// Now that we have the starting point pushed onto the walker, we start
|
||||
// asking for ancestors. It will return them in the sorting order we asked
|
||||
// for as commit oids. We can then lookup and parse the commited pointed
|
||||
// at by the returned OID; note that this operation is specially fast
|
||||
// since the raw contents of the commit object will be cached in memory
|
||||
while ((git_revwalk_next(&oid, walk)) == 0) {
|
||||
error = git_commit_lookup(&wcommit, repo, &oid);
|
||||
check_error(error, "looking up commit during revwalk");
|
||||
|
||||
cmsg = git_commit_message(wcommit);
|
||||
cauth = git_commit_author(wcommit);
|
||||
printf("%s (%s)\n", cmsg, cauth->email);
|
||||
|
||||
git_commit_free(wcommit);
|
||||
}
|
||||
|
||||
// Like the other objects, be sure to free the revwalker when you're done to prevent memory leaks.
|
||||
// Also, make sure that the repository being walked it not deallocated while the walk is in
|
||||
// progress, or it will result in undefined behavior
|
||||
// Like the other objects, be sure to free the revwalker when you're done
|
||||
// to prevent memory leaks. Also, make sure that the repository being
|
||||
// walked it not deallocated while the walk is in progress, or it will
|
||||
// result in undefined behavior
|
||||
git_revwalk_free(walk);
|
||||
|
||||
// ### Index File Manipulation
|
||||
//
|
||||
// The [index file API][gi] allows you to read, traverse, update and write the Git index file
|
||||
// (sometimes thought of as the staging area).
|
||||
|
||||
// The [index file API][gi] allows you to read, traverse, update and write
|
||||
// the Git index file (sometimes thought of as the staging area).
|
||||
//
|
||||
// [gi]: http://libgit2.github.com/libgit2/#HEAD/group/index
|
||||
|
||||
@ -360,18 +417,21 @@ int main (int argc, char** argv)
|
||||
git_index *index;
|
||||
unsigned int i, ecount;
|
||||
|
||||
// You can either open the index from the standard location in an open repository, as we're doing
|
||||
// here, or you can open and manipulate any index file with `git_index_open_bare()`. The index
|
||||
// for the repository will be located and loaded from disk.
|
||||
// You can either open the index from the standard location in an open
|
||||
// repository, as we're doing here, or you can open and manipulate any
|
||||
// index file with `git_index_open_bare()`. The index for the repository
|
||||
// will be located and loaded from disk.
|
||||
git_repository_index(&index, repo);
|
||||
|
||||
// For each entry in the index, you can get a bunch of information including the SHA (oid), path
|
||||
// and mode which map to the tree objects that are written out. It also has filesystem properties
|
||||
// to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags)
|
||||
// All these properties are exported publicly in the `git_index_entry` struct
|
||||
// For each entry in the index, you can get a bunch of information
|
||||
// including the SHA (oid), path and mode which map to the tree objects
|
||||
// that are written out. It also has filesystem properties to help
|
||||
// determine what to inspect for changes (ctime, mtime, dev, ino, uid,
|
||||
// gid, file_size and flags) All these properties are exported publicly in
|
||||
// the `git_index_entry` struct
|
||||
ecount = git_index_entrycount(index);
|
||||
for (i = 0; i < ecount; ++i) {
|
||||
git_index_entry *e = git_index_get(index, i);
|
||||
const git_index_entry *e = git_index_get_byindex(index, i);
|
||||
|
||||
printf("path: %s\n", e->path);
|
||||
printf("mtime: %d\n", (int)e->mtime.seconds);
|
||||
@ -381,36 +441,37 @@ int main (int argc, char** argv)
|
||||
git_index_free(index);
|
||||
|
||||
// ### References
|
||||
//
|
||||
// The [reference API][ref] allows you to list, resolve, create and update references such as
|
||||
// branches, tags and remote references (everything in the .git/refs directory).
|
||||
|
||||
// The [reference API][ref] allows you to list, resolve, create and update
|
||||
// references such as branches, tags and remote references (everything in
|
||||
// the .git/refs directory).
|
||||
//
|
||||
// [ref]: http://libgit2.github.com/libgit2/#HEAD/group/reference
|
||||
|
||||
printf("\n*Reference Listing*\n");
|
||||
|
||||
// Here we will implement something like `git for-each-ref` simply listing out all available
|
||||
// references and the object SHA they resolve to.
|
||||
// Here we will implement something like `git for-each-ref` simply listing
|
||||
// out all available references and the object SHA they resolve to.
|
||||
git_strarray ref_list;
|
||||
git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
|
||||
git_reference_list(&ref_list, repo, GIT_REF_LISTALL);
|
||||
|
||||
const char *refname;
|
||||
git_reference *ref;
|
||||
|
||||
// Now that we have the list of reference names, we can lookup each ref one at a time and
|
||||
// resolve them to the SHA, then print both values out.
|
||||
// Now that we have the list of reference names, we can lookup each ref
|
||||
// one at a time and resolve them to the SHA, then print both values out.
|
||||
for (i = 0; i < ref_list.count; ++i) {
|
||||
refname = ref_list.strings[i];
|
||||
git_reference_lookup(&ref, repo, refname);
|
||||
|
||||
switch (git_reference_type(ref)) {
|
||||
case GIT_REF_OID:
|
||||
git_oid_fmt(out, git_reference_oid(ref));
|
||||
git_oid_fmt(out, git_reference_target(ref));
|
||||
printf("%s [%s]\n", refname, out);
|
||||
break;
|
||||
|
||||
case GIT_REF_SYMBOLIC:
|
||||
printf("%s => %s\n", refname, git_reference_target(ref));
|
||||
printf("%s => %s\n", refname, git_reference_symbolic_target(ref));
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unexpected reference type\n");
|
||||
@ -421,9 +482,9 @@ int main (int argc, char** argv)
|
||||
git_strarray_free(&ref_list);
|
||||
|
||||
// ### Config Files
|
||||
//
|
||||
// The [config API][config] allows you to list and updatee config values in
|
||||
// any of the accessible config file locations (system, global, local).
|
||||
|
||||
// The [config API][config] allows you to list and updatee config values
|
||||
// in any of the accessible config file locations (system, global, local).
|
||||
//
|
||||
// [config]: http://libgit2.github.com/libgit2/#HEAD/group/config
|
||||
|
||||
@ -435,12 +496,14 @@ int main (int argc, char** argv)
|
||||
git_config *cfg;
|
||||
|
||||
// Open a config object so we can read global values from it.
|
||||
git_config_open_ondisk(&cfg, "~/.gitconfig");
|
||||
char config_path[256];
|
||||
sprintf(config_path, "%s/config", repo_path);
|
||||
check_error(git_config_open_ondisk(&cfg, config_path), "opening config");
|
||||
|
||||
git_config_get_int32(cfg, "help.autocorrect", &j);
|
||||
git_config_get_int32(&j, cfg, "help.autocorrect");
|
||||
printf("Autocorrect: %d\n", j);
|
||||
|
||||
git_config_get_string(cfg, "user.email", &email);
|
||||
git_config_get_string(&email, cfg, "user.email");
|
||||
printf("Email: %s\n", email);
|
||||
|
||||
// Finally, when you're done with the repository, you can free it as well.
|
||||
|
@ -2,13 +2,20 @@ default: all
|
||||
|
||||
CC = gcc
|
||||
CFLAGS += -g
|
||||
CFLAGS += -I../../include -L../../ -lgit2 -lpthread
|
||||
CFLAGS += -I../../include
|
||||
LDFLAGS += -L../../build -L../..
|
||||
LIBRARIES += -lgit2 -lpthread
|
||||
|
||||
OBJECTS = \
|
||||
git2.o \
|
||||
ls-remote.o \
|
||||
fetch.o \
|
||||
clone.o \
|
||||
index-pack.o
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) -o git2 $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o git2 $(OBJECTS) $(LIBRARIES)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS)
|
||||
$(RM) git2
|
||||
|
122
examples/network/clone.c
Normal file
122
examples/network/clone.c
Normal file
@ -0,0 +1,122 @@
|
||||
#include "common.h"
|
||||
#include <git2.h>
|
||||
#include <git2/clone.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
# include <pthread.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* Shamelessly borrowed from http://stackoverflow.com/questions/3417837/
|
||||
* with permission of the original author, Martin Pool.
|
||||
* http://sourcefrog.net/weblog/software/languages/C/unused.html
|
||||
*/
|
||||
#ifdef UNUSED
|
||||
#elif defined(__GNUC__)
|
||||
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
||||
#elif defined(__LCLINT__)
|
||||
# define UNUSED(x) /*@unused@*/ x
|
||||
#else
|
||||
# define UNUSED(x) x
|
||||
#endif
|
||||
|
||||
typedef struct progress_data {
|
||||
git_transfer_progress fetch_progress;
|
||||
size_t completed_steps;
|
||||
size_t total_steps;
|
||||
const char *path;
|
||||
} progress_data;
|
||||
|
||||
static void print_progress(const progress_data *pd)
|
||||
{
|
||||
int network_percent = (100*pd->fetch_progress.received_objects) / pd->fetch_progress.total_objects;
|
||||
int index_percent = (100*pd->fetch_progress.indexed_objects) / pd->fetch_progress.total_objects;
|
||||
int checkout_percent = pd->total_steps > 0
|
||||
? (100 * pd->completed_steps) / pd->total_steps
|
||||
: 0.f;
|
||||
int kbytes = pd->fetch_progress.received_bytes / 1024;
|
||||
|
||||
printf("net %3d%% (%4d kb, %5d/%5d) / idx %3d%% (%5d/%5d) / chk %3d%% (%4" PRIuZ "/%4" PRIuZ ") %s\n",
|
||||
network_percent, kbytes,
|
||||
pd->fetch_progress.received_objects, pd->fetch_progress.total_objects,
|
||||
index_percent, pd->fetch_progress.indexed_objects, pd->fetch_progress.total_objects,
|
||||
checkout_percent,
|
||||
pd->completed_steps, pd->total_steps,
|
||||
pd->path);
|
||||
}
|
||||
|
||||
static int fetch_progress(const git_transfer_progress *stats, void *payload)
|
||||
{
|
||||
progress_data *pd = (progress_data*)payload;
|
||||
pd->fetch_progress = *stats;
|
||||
print_progress(pd);
|
||||
return 0;
|
||||
}
|
||||
static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
|
||||
{
|
||||
progress_data *pd = (progress_data*)payload;
|
||||
pd->completed_steps = cur;
|
||||
pd->total_steps = tot;
|
||||
pd->path = path;
|
||||
print_progress(pd);
|
||||
}
|
||||
|
||||
static int cred_acquire(git_cred **out,
|
||||
const char * UNUSED(url),
|
||||
const char * UNUSED(username_from_url),
|
||||
unsigned int UNUSED(allowed_types),
|
||||
void * UNUSED(payload))
|
||||
{
|
||||
char username[128] = {0};
|
||||
char password[128] = {0};
|
||||
|
||||
printf("Username: ");
|
||||
scanf("%s", username);
|
||||
|
||||
/* Yup. Right there on your terminal. Careful where you copy/paste output. */
|
||||
printf("Password: ");
|
||||
scanf("%s", password);
|
||||
|
||||
return git_cred_userpass_plaintext_new(out, username, password);
|
||||
}
|
||||
|
||||
int do_clone(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
progress_data pd = {{0}};
|
||||
git_repository *cloned_repo = NULL;
|
||||
git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
|
||||
git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT;
|
||||
const char *url = argv[1];
|
||||
const char *path = argv[2];
|
||||
int error;
|
||||
|
||||
(void)repo; // unused
|
||||
|
||||
// Validate args
|
||||
if (argc < 3) {
|
||||
printf ("USAGE: %s <url> <path>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set up options
|
||||
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
|
||||
checkout_opts.progress_cb = checkout_progress;
|
||||
checkout_opts.progress_payload = &pd;
|
||||
clone_opts.checkout_opts = checkout_opts;
|
||||
clone_opts.fetch_progress_cb = &fetch_progress;
|
||||
clone_opts.fetch_progress_payload = &pd;
|
||||
clone_opts.cred_acquire_cb = cred_acquire;
|
||||
|
||||
// Do the clone
|
||||
error = git_clone(&cloned_repo, url, path, &clone_opts);
|
||||
printf("\n");
|
||||
if (error != 0) {
|
||||
const git_error *err = giterr_last();
|
||||
if (err) printf("ERROR %d: %s\n", err->klass, err->message);
|
||||
else printf("ERROR %d: no detailed info\n", error);
|
||||
}
|
||||
else if (cloned_repo) git_repository_free(cloned_repo);
|
||||
return error;
|
||||
}
|
@ -10,5 +10,15 @@ int parse_pkt_line(git_repository *repo, int argc, char **argv);
|
||||
int show_remote(git_repository *repo, int argc, char **argv);
|
||||
int fetch(git_repository *repo, int argc, char **argv);
|
||||
int index_pack(git_repository *repo, int argc, char **argv);
|
||||
int do_clone(git_repository *repo, int argc, char **argv);
|
||||
|
||||
#ifndef PRIuZ
|
||||
/* Define the printf format specifer to use for size_t output */
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# define PRIuZ "Iu"
|
||||
#else
|
||||
# define PRIuZ "zu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __COMMON_H__ */
|
||||
|
@ -3,23 +3,31 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#ifndef _WIN32
|
||||
# include <pthread.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
struct dl_data {
|
||||
git_remote *remote;
|
||||
git_off_t *bytes;
|
||||
git_indexer_stats *stats;
|
||||
int ret;
|
||||
int finished;
|
||||
};
|
||||
|
||||
static void progress_cb(const char *str, int len, void *data)
|
||||
{
|
||||
(void)data;
|
||||
printf("remote: %.*s", len, str);
|
||||
fflush(stdout); /* We don't have the \n to force the flush */
|
||||
}
|
||||
|
||||
static void *download(void *ptr)
|
||||
{
|
||||
struct dl_data *data = (struct dl_data *)ptr;
|
||||
|
||||
// Connect to the remote end specifying that we want to fetch
|
||||
// information from it.
|
||||
if (git_remote_connect(data->remote, GIT_DIR_FETCH) < 0) {
|
||||
if (git_remote_connect(data->remote, GIT_DIRECTION_FETCH) < 0) {
|
||||
data->ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
@ -27,7 +35,7 @@ static void *download(void *ptr)
|
||||
// Download the packfile and index it. This function updates the
|
||||
// amount of received data and the indexer stats which lets you
|
||||
// inform the user about progress.
|
||||
if (git_remote_download(data->remote, data->bytes, data->stats) < 0) {
|
||||
if (git_remote_download(data->remote, NULL, NULL) < 0) {
|
||||
data->ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
@ -36,13 +44,13 @@ static void *download(void *ptr)
|
||||
|
||||
exit:
|
||||
data->finished = 1;
|
||||
pthread_exit(&data->ret);
|
||||
return &data->ret;
|
||||
}
|
||||
|
||||
int update_cb(const char *refname, const git_oid *a, const git_oid *b)
|
||||
static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
|
||||
{
|
||||
const char *action;
|
||||
char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1];
|
||||
(void)data;
|
||||
|
||||
git_oid_fmt(b_str, b);
|
||||
b_str[GIT_OID_HEXSZ] = '\0';
|
||||
@ -60,54 +68,80 @@ int update_cb(const char *refname, const git_oid *a, const git_oid *b)
|
||||
|
||||
int fetch(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
git_remote *remote = NULL;
|
||||
git_off_t bytes = 0;
|
||||
git_indexer_stats stats;
|
||||
pthread_t worker;
|
||||
struct dl_data data;
|
||||
git_remote *remote = NULL;
|
||||
const git_transfer_progress *stats;
|
||||
struct dl_data data;
|
||||
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
|
||||
#ifndef _WIN32
|
||||
pthread_t worker;
|
||||
#endif
|
||||
|
||||
// Figure out whether it's a named remote or a URL
|
||||
printf("Fetching %s\n", argv[1]);
|
||||
if (git_remote_load(&remote, repo, argv[1]) < 0) {
|
||||
if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0)
|
||||
return -1;
|
||||
}
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Set up the information for the background worker thread
|
||||
data.remote = remote;
|
||||
data.bytes = &bytes;
|
||||
data.stats = &stats;
|
||||
data.ret = 0;
|
||||
data.finished = 0;
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
// Figure out whether it's a named remote or a URL
|
||||
printf("Fetching %s for repo %p\n", argv[1], repo);
|
||||
if (git_remote_load(&remote, repo, argv[1]) < 0) {
|
||||
if (git_remote_create_inmemory(&remote, repo, NULL, argv[1]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_create(&worker, NULL, download, &data);
|
||||
// Set up the callbacks (only update_tips for now)
|
||||
callbacks.update_tips = &update_cb;
|
||||
callbacks.progress = &progress_cb;
|
||||
git_remote_set_callbacks(remote, &callbacks);
|
||||
|
||||
// Loop while the worker thread is still running. Here we show processed
|
||||
// and total objects in the pack and the amount of received
|
||||
// data. Most frontends will probably want to show a percentage and
|
||||
// the download rate.
|
||||
do {
|
||||
usleep(10000);
|
||||
printf("\rReceived %d/%d objects in %d bytes", stats.processed, stats.total, bytes);
|
||||
} while (!data.finished);
|
||||
printf("\rReceived %d/%d objects in %d bytes\n", stats.processed, stats.total, bytes);
|
||||
// Set up the information for the background worker thread
|
||||
data.remote = remote;
|
||||
data.ret = 0;
|
||||
data.finished = 0;
|
||||
|
||||
// Disconnect the underlying connection to prevent from idling.
|
||||
git_remote_disconnect(remote);
|
||||
stats = git_remote_stats(remote);
|
||||
|
||||
// Update the references in the remote's namespace to point to the
|
||||
// right commits. This may be needed even if there was no packfile
|
||||
// to download, which can happen e.g. when the branches have been
|
||||
// changed but all the neede objects are available locally.
|
||||
if (git_remote_update_tips(remote, update_cb) < 0)
|
||||
return -1;
|
||||
#ifdef _WIN32
|
||||
download(&data);
|
||||
#else
|
||||
pthread_create(&worker, NULL, download, &data);
|
||||
|
||||
git_remote_free(remote);
|
||||
// Loop while the worker thread is still running. Here we show processed
|
||||
// and total objects in the pack and the amount of received
|
||||
// data. Most frontends will probably want to show a percentage and
|
||||
// the download rate.
|
||||
do {
|
||||
usleep(10000);
|
||||
|
||||
return 0;
|
||||
if (stats->total_objects > 0)
|
||||
printf("Received %d/%d objects (%d) in %" PRIuZ " bytes\r",
|
||||
stats->received_objects, stats->total_objects,
|
||||
stats->indexed_objects, stats->received_bytes);
|
||||
} while (!data.finished);
|
||||
|
||||
on_error:
|
||||
git_remote_free(remote);
|
||||
return -1;
|
||||
if (data.ret < 0)
|
||||
goto on_error;
|
||||
|
||||
pthread_join(worker, NULL);
|
||||
#endif
|
||||
|
||||
printf("\rReceived %d/%d objects in %zu bytes\n",
|
||||
stats->indexed_objects, stats->total_objects, stats->received_bytes);
|
||||
|
||||
// Disconnect the underlying connection to prevent from idling.
|
||||
git_remote_disconnect(remote);
|
||||
|
||||
// Update the references in the remote's namespace to point to the
|
||||
// right commits. This may be needed even if there was no packfile
|
||||
// to download, which can happen e.g. when the branches have been
|
||||
// changed but all the neede objects are available locally.
|
||||
if (git_remote_update_tips(remote) < 0)
|
||||
return -1;
|
||||
|
||||
git_remote_free(remote);
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_remote_free(remote);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@ -12,11 +13,12 @@ struct {
|
||||
} commands[] = {
|
||||
{"ls-remote", ls_remote},
|
||||
{"fetch", fetch},
|
||||
{"clone", do_clone},
|
||||
{"index-pack", index_pack},
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
int run_command(git_cb fn, int argc, char **argv)
|
||||
static int run_command(git_cb fn, int argc, char **argv)
|
||||
{
|
||||
int error;
|
||||
git_repository *repo;
|
||||
@ -45,7 +47,7 @@ int run_command(git_cb fn, int argc, char **argv)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, error;
|
||||
int i;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
|
||||
|
@ -2,101 +2,87 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
# include <io.h>
|
||||
# include <Windows.h>
|
||||
|
||||
# define open _open
|
||||
# define read _read
|
||||
# define close _close
|
||||
|
||||
#define ssize_t unsigned int
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
|
||||
// This could be run in the main loop whilst the application waits for
|
||||
// the indexing to finish in a worker thread
|
||||
int index_cb(const git_indexer_stats *stats, void *data)
|
||||
static int index_cb(const git_transfer_progress *stats, void *data)
|
||||
{
|
||||
printf("\rProcessing %d of %d", stats->processed, stats->total);
|
||||
(void)data;
|
||||
printf("\rProcessing %d of %d", stats->indexed_objects, stats->total_objects);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index_pack(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
git_indexer_stream *idx;
|
||||
git_indexer_stats stats = {0, 0};
|
||||
int error, fd;
|
||||
char hash[GIT_OID_HEXSZ + 1] = {0};
|
||||
ssize_t read_bytes;
|
||||
char buf[512];
|
||||
git_indexer_stream *idx;
|
||||
git_transfer_progress stats = {0, 0};
|
||||
int error;
|
||||
char hash[GIT_OID_HEXSZ + 1] = {0};
|
||||
int fd;
|
||||
ssize_t read_bytes;
|
||||
char buf[512];
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "I need a packfile\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
(void)repo;
|
||||
|
||||
if (git_indexer_stream_new(&idx, ".git") < 0) {
|
||||
puts("bad idx");
|
||||
return -1;
|
||||
}
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s index-pack <packfile>\n", argv[-1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ((fd = open(argv[1], 0)) < 0) {
|
||||
perror("open");
|
||||
return -1;
|
||||
}
|
||||
if (git_indexer_stream_new(&idx, ".", NULL, NULL) < 0) {
|
||||
puts("bad idx");
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
read_bytes = read(fd, buf, sizeof(buf));
|
||||
if (read_bytes < 0)
|
||||
break;
|
||||
if ((fd = open(argv[1], 0)) < 0) {
|
||||
perror("open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((error = git_indexer_stream_add(idx, buf, read_bytes, &stats)) < 0)
|
||||
goto cleanup;
|
||||
do {
|
||||
read_bytes = read(fd, buf, sizeof(buf));
|
||||
if (read_bytes < 0)
|
||||
break;
|
||||
|
||||
printf("\rIndexing %d of %d", stats.processed, stats.total);
|
||||
} while (read_bytes > 0);
|
||||
if ((error = git_indexer_stream_add(idx, buf, read_bytes, &stats)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (read_bytes < 0) {
|
||||
error = -1;
|
||||
perror("failed reading");
|
||||
goto cleanup;
|
||||
}
|
||||
index_cb(&stats, NULL);
|
||||
} while (read_bytes > 0);
|
||||
|
||||
if ((error = git_indexer_stream_finalize(idx, &stats)) < 0)
|
||||
goto cleanup;
|
||||
if (read_bytes < 0) {
|
||||
error = -1;
|
||||
perror("failed reading");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("\rIndexing %d of %d\n", stats.processed, stats.total);
|
||||
if ((error = git_indexer_stream_finalize(idx, &stats)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
git_oid_fmt(hash, git_indexer_stream_hash(idx));
|
||||
puts(hash);
|
||||
printf("\rIndexing %d of %d\n", stats.indexed_objects, stats.total_objects);
|
||||
|
||||
cleanup:
|
||||
close(fd);
|
||||
git_indexer_stream_free(idx);
|
||||
return error;
|
||||
}
|
||||
|
||||
int index_pack_old(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
git_indexer *indexer;
|
||||
git_indexer_stats stats;
|
||||
int error;
|
||||
char hash[GIT_OID_HEXSZ + 1] = {0};
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "I need a packfile\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Create a new indexer
|
||||
error = git_indexer_new(&indexer, argv[1]);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
// Index the packfile. This function can take a very long time and
|
||||
// should be run in a worker thread.
|
||||
error = git_indexer_run(indexer, &stats);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
// Write the information out to an index file
|
||||
error = git_indexer_write(indexer);
|
||||
|
||||
// Get the packfile's hash (which should become it's filename)
|
||||
git_oid_fmt(hash, git_indexer_hash(indexer));
|
||||
puts(hash);
|
||||
|
||||
git_indexer_free(indexer);
|
||||
|
||||
return 0;
|
||||
git_oid_fmt(hash, git_indexer_stream_hash(idx));
|
||||
puts(hash);
|
||||
|
||||
cleanup:
|
||||
close(fd);
|
||||
git_indexer_stream_free(idx);
|
||||
return error;
|
||||
}
|
||||
|
@ -7,25 +7,27 @@
|
||||
static int show_ref__cb(git_remote_head *head, void *payload)
|
||||
{
|
||||
char oid[GIT_OID_HEXSZ + 1] = {0};
|
||||
|
||||
(void)payload;
|
||||
git_oid_fmt(oid, &head->oid);
|
||||
printf("%s\t%s\n", oid, head->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int use_unnamed(git_repository *repo, const char *url)
|
||||
static int use_unnamed(git_repository *repo, const char *url)
|
||||
{
|
||||
git_remote *remote = NULL;
|
||||
int error;
|
||||
|
||||
// Create an instance of a remote from the URL. The transport to use
|
||||
// is detected from the URL
|
||||
error = git_remote_new(&remote, repo, NULL, url, NULL);
|
||||
error = git_remote_create_inmemory(&remote, repo, NULL, url);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
// When connecting, the underlying code needs to know wether we
|
||||
// want to push or fetch
|
||||
error = git_remote_connect(remote, GIT_DIR_FETCH);
|
||||
error = git_remote_connect(remote, GIT_DIRECTION_FETCH);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -37,7 +39,7 @@ cleanup:
|
||||
return error;
|
||||
}
|
||||
|
||||
int use_remote(git_repository *repo, char *name)
|
||||
static int use_remote(git_repository *repo, char *name)
|
||||
{
|
||||
git_remote *remote = NULL;
|
||||
int error;
|
||||
@ -47,7 +49,7 @@ int use_remote(git_repository *repo, char *name)
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = git_remote_connect(remote, GIT_DIR_FETCH);
|
||||
error = git_remote_connect(remote, GIT_DIRECTION_FETCH);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -63,7 +65,12 @@ cleanup:
|
||||
|
||||
int ls_remote(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
int error, i;
|
||||
int error;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s ls-remote <remote>\n", argv[-1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* If there's a ':' in the name, assume it's an URL */
|
||||
if (strchr(argv[1], ':') != NULL) {
|
||||
|
120
examples/rev-list.c
Normal file
120
examples/rev-list.c
Normal file
@ -0,0 +1,120 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <git2.h>
|
||||
|
||||
static void check_error(int error_code, const char *action)
|
||||
{
|
||||
if (!error_code)
|
||||
return;
|
||||
|
||||
const git_error *error = giterr_last();
|
||||
fprintf(stderr, "Error %d %s: %s\n", -error_code, action,
|
||||
(error && error->message) ? error->message : "???");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int push_commit(git_revwalk *walk, const git_oid *oid, int hide)
|
||||
{
|
||||
if (hide)
|
||||
return git_revwalk_hide(walk, oid);
|
||||
else
|
||||
return git_revwalk_push(walk, oid);
|
||||
}
|
||||
|
||||
static int push_spec(git_repository *repo, git_revwalk *walk, const char *spec, int hide)
|
||||
{
|
||||
int error;
|
||||
git_object *obj;
|
||||
|
||||
if ((error = git_revparse_single(&obj, repo, spec)) < 0)
|
||||
return error;
|
||||
|
||||
error = push_commit(walk, git_object_id(obj), hide);
|
||||
git_object_free(obj);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int push_range(git_repository *repo, git_revwalk *walk, const char *range, int hide)
|
||||
{
|
||||
git_revspec revspec;
|
||||
int error = 0;
|
||||
|
||||
if ((error = git_revparse(&revspec, repo, range)))
|
||||
return error;
|
||||
|
||||
if (revspec.flags & GIT_REVPARSE_MERGE_BASE) {
|
||||
/* TODO: support "<commit>...<commit>" */
|
||||
return GIT_EINVALIDSPEC;
|
||||
}
|
||||
|
||||
if ((error = push_commit(walk, git_object_id(revspec.from), !hide)))
|
||||
goto out;
|
||||
|
||||
error = push_commit(walk, git_object_id(revspec.to), hide);
|
||||
|
||||
out:
|
||||
git_object_free(revspec.from);
|
||||
git_object_free(revspec.to);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts)
|
||||
{
|
||||
int hide, i, error;
|
||||
unsigned int sorting = GIT_SORT_NONE;
|
||||
|
||||
hide = 0;
|
||||
for (i = 0; i < nopts; i++) {
|
||||
if (!strcmp(opts[i], "--topo-order")) {
|
||||
sorting = GIT_SORT_TOPOLOGICAL | (sorting & GIT_SORT_REVERSE);
|
||||
git_revwalk_sorting(walk, sorting);
|
||||
} else if (!strcmp(opts[i], "--date-order")) {
|
||||
sorting = GIT_SORT_TIME | (sorting & GIT_SORT_REVERSE);
|
||||
git_revwalk_sorting(walk, sorting);
|
||||
} else if (!strcmp(opts[i], "--reverse")) {
|
||||
sorting = (sorting & ~GIT_SORT_REVERSE)
|
||||
| ((sorting & GIT_SORT_REVERSE) ? 0 : GIT_SORT_REVERSE);
|
||||
git_revwalk_sorting(walk, sorting);
|
||||
} else if (!strcmp(opts[i], "--not")) {
|
||||
hide = !hide;
|
||||
} else if (opts[i][0] == '^') {
|
||||
if ((error = push_spec(repo, walk, opts[i] + 1, !hide)))
|
||||
return error;
|
||||
} else if (strstr(opts[i], "..")) {
|
||||
if ((error = push_range(repo, walk, opts[i], hide)))
|
||||
return error;
|
||||
} else {
|
||||
if ((error = push_spec(repo, walk, opts[i], hide)))
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int error;
|
||||
git_repository *repo;
|
||||
git_revwalk *walk;
|
||||
git_oid oid;
|
||||
char buf[41];
|
||||
|
||||
error = git_repository_open_ext(&repo, ".", 0, NULL);
|
||||
check_error(error, "opening repository");
|
||||
|
||||
error = git_revwalk_new(&walk, repo);
|
||||
check_error(error, "allocating revwalk");
|
||||
error = revwalk_parseopts(repo, walk, argc-1, argv+1);
|
||||
check_error(error, "parsing options");
|
||||
|
||||
while (!git_revwalk_next(&oid, walk)) {
|
||||
git_oid_fmt(buf, &oid);
|
||||
buf[40] = '\0';
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,43 +1,67 @@
|
||||
#include <git2.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
git_repository *repo;
|
||||
git_index *index;
|
||||
unsigned int i, e, ecount;
|
||||
git_index_entry **entries;
|
||||
git_oid oid;
|
||||
git_repository *repo = NULL;
|
||||
git_index *index;
|
||||
unsigned int i, ecount;
|
||||
char *dir = ".";
|
||||
size_t dirlen;
|
||||
char out[41];
|
||||
out[40] = '\0';
|
||||
|
||||
char out[41];
|
||||
out[40] = '\0';
|
||||
if (argc > 1)
|
||||
dir = argv[1];
|
||||
if (!dir || argc > 2) {
|
||||
fprintf(stderr, "usage: showindex [<repo-dir>]\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
git_repository_open(&repo, "/opt/libgit2-test/.git");
|
||||
dirlen = strlen(dir);
|
||||
if (dirlen > 5 && strcmp(dir + dirlen - 5, "index") == 0) {
|
||||
if (git_index_open(&index, dir) < 0) {
|
||||
fprintf(stderr, "could not open index: %s\n", dir);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (git_repository_open_ext(&repo, dir, 0, NULL) < 0) {
|
||||
fprintf(stderr, "could not open repository: %s\n", dir);
|
||||
return 1;
|
||||
}
|
||||
if (git_repository_index(&index, repo) < 0) {
|
||||
fprintf(stderr, "could not open repository index\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
git_repository_index(&index, repo);
|
||||
git_index_read(index);
|
||||
git_index_read(index);
|
||||
|
||||
ecount = git_index_entrycount(index);
|
||||
for (i = 0; i < ecount; ++i) {
|
||||
git_index_entry *e = git_index_get(index, i);
|
||||
ecount = git_index_entrycount(index);
|
||||
if (!ecount)
|
||||
printf("Empty index\n");
|
||||
|
||||
oid = e->oid;
|
||||
git_oid_fmt(out, &oid);
|
||||
for (i = 0; i < ecount; ++i) {
|
||||
const git_index_entry *e = git_index_get_byindex(index, i);
|
||||
|
||||
printf("File Path: %s\n", e->path);
|
||||
printf(" Blob SHA: %s\n", out);
|
||||
printf("File Size: %d\n", (int)e->file_size);
|
||||
printf(" Device: %d\n", (int)e->dev);
|
||||
printf(" Inode: %d\n", (int)e->ino);
|
||||
printf(" UID: %d\n", (int)e->uid);
|
||||
printf(" GID: %d\n", (int)e->gid);
|
||||
printf(" ctime: %d\n", (int)e->ctime.seconds);
|
||||
printf(" mtime: %d\n", (int)e->mtime.seconds);
|
||||
printf("\n");
|
||||
}
|
||||
git_oid_fmt(out, &e->oid);
|
||||
|
||||
git_index_free(index);
|
||||
printf("File Path: %s\n", e->path);
|
||||
printf(" Stage: %d\n", git_index_entry_stage(e));
|
||||
printf(" Blob SHA: %s\n", out);
|
||||
printf("File Mode: %07o\n", e->mode);
|
||||
printf("File Size: %d bytes\n", (int)e->file_size);
|
||||
printf("Dev/Inode: %d/%d\n", (int)e->dev, (int)e->ino);
|
||||
printf(" UID/GID: %d/%d\n", (int)e->uid, (int)e->gid);
|
||||
printf(" ctime: %d\n", (int)e->ctime.seconds);
|
||||
printf(" mtime: %d\n", (int)e->mtime.seconds);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
git_repository_free(repo);
|
||||
git_index_free(index);
|
||||
git_repository_free(repo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
95
examples/test/test-rev-list.sh
Executable file
95
examples/test/test-rev-list.sh
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
|
||||
THIS_FILE="$(readlink -f "$0")"
|
||||
ROOT="$(dirname "$(dirname "$(dirname "$THIS_FILE")")")"
|
||||
PROGRAM="$ROOT"/examples/rev-list
|
||||
LIBDIR="$ROOT"/build
|
||||
REPO="$ROOT"/tests-clar/resources/testrepo.git
|
||||
|
||||
cd "$REPO"
|
||||
|
||||
run () {
|
||||
LD_LIBRARY_PATH="$LIBDIR" "$PROGRAM" "$@"
|
||||
}
|
||||
|
||||
diff -u - <(run --date-order a4a7dce) <<EOF
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
EOF
|
||||
|
||||
out="$(run --topo-order a4a7dce)"
|
||||
diff -q - <(echo -n "$out") <<EOF >/dev/null ||
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
EOF
|
||||
diff -u - <(echo "$out") <<EOF
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
EOF
|
||||
|
||||
diff -u - <(run --date-order --reverse a4a7dce) <<EOF
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
EOF
|
||||
|
||||
out=$(run --topo-order --reverse a4a7dce)
|
||||
diff -q - <(echo -n "$out") <<EOF >/dev/null ||
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
EOF
|
||||
diff -u - <(echo "$out") <<EOF
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
EOF
|
||||
|
||||
out="$(run --date-order --topo-order --reverse --reverse a4a7dce)"
|
||||
diff -q - <(echo -n "$out") <<EOF >/dev/null ||
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
EOF
|
||||
diff -u - <(echo "$out") <<EOF
|
||||
a4a7dce85cf63874e984719f4fdd239f5145052f
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
c47800c7266a2be04c571c04d5a6614691ea99bd
|
||||
5b5b025afb0b4c913b4c338a42934a3863bf3644
|
||||
8496071c1b46c854b31185ea97743be6a8774479
|
||||
EOF
|
||||
|
||||
diff -u - <(run ^9fd738e~2 9fd738e) <<EOF
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
EOF
|
||||
|
||||
diff -u - <(run --not 9fd738e..9fd738e~2) <<EOF
|
||||
9fd738e8f7967c078dceed8190330fc8648ee56a
|
||||
4a202b346bb0fb0db7eff3cffeb3c70babbd2045
|
||||
EOF
|
@ -41,9 +41,12 @@
|
||||
ok Adam Simpkins <adam@adamsimpkins.net> (http transport)
|
||||
ok Andreas Ericsson <ae@op5.se>
|
||||
ok Boyd Lynn Gerber <gerberb@zenez.com>
|
||||
ok Brian Downing <bdowning@lavos.net>
|
||||
ok Brian Gernhardt <benji@silverinsanity.com>
|
||||
ok Christian Couder <chriscool@tuxfamily.org>
|
||||
ok Daniel Barkalow <barkalow@iabervon.org>
|
||||
ok Florian Forster <octo@verplant.org>
|
||||
ok Holger Weiss <holger@zedat.fu-berlin.de>
|
||||
ok Jeff King <peff@peff.net>
|
||||
ok Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
||||
ok Johannes Sixt <j6t@kdbg.org>
|
||||
@ -53,7 +56,7 @@ ok Linus Torvalds <torvalds@linux-foundation.org>
|
||||
ok Lukas Sandström <lukass@etek.chalmers.se>
|
||||
ok Matthieu Moy <Matthieu.Moy@imag.fr>
|
||||
ign Mike McCormack <mike@codeweavers.com> (imap-send)
|
||||
ok Nicolas Pitre <nico@cam.org>
|
||||
ok Nicolas Pitre <nico@fluxnic.net> <nico@cam.org>
|
||||
ok Paolo Bonzini <bonzini@gnu.org>
|
||||
ok Paul Kocher <paul@cryptography.com>
|
||||
ok Peter Hagervall <hager@cs.umu.se>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -23,8 +23,10 @@
|
||||
#include "git2/repository.h"
|
||||
#include "git2/revwalk.h"
|
||||
#include "git2/merge.h"
|
||||
#include "git2/graph.h"
|
||||
#include "git2/refs.h"
|
||||
#include "git2/reflog.h"
|
||||
#include "git2/revparse.h"
|
||||
|
||||
#include "git2/object.h"
|
||||
#include "git2/blob.h"
|
||||
@ -35,13 +37,24 @@
|
||||
|
||||
#include "git2/index.h"
|
||||
#include "git2/config.h"
|
||||
#include "git2/transport.h"
|
||||
#include "git2/remote.h"
|
||||
#include "git2/clone.h"
|
||||
#include "git2/checkout.h"
|
||||
#include "git2/push.h"
|
||||
|
||||
#include "git2/attr.h"
|
||||
#include "git2/ignore.h"
|
||||
#include "git2/branch.h"
|
||||
#include "git2/refspec.h"
|
||||
#include "git2/net.h"
|
||||
#include "git2/status.h"
|
||||
#include "git2/indexer.h"
|
||||
#include "git2/submodule.h"
|
||||
#include "git2/notes.h"
|
||||
#include "git2/reset.h"
|
||||
#include "git2/message.h"
|
||||
#include "git2/pack.h"
|
||||
#include "git2/stash.h"
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -30,7 +30,7 @@ GIT_BEGIN_DECL
|
||||
* Then for file `xyz.c` looking up attribute "foo" gives a value for
|
||||
* which `GIT_ATTR_TRUE(value)` is true.
|
||||
*/
|
||||
#define GIT_ATTR_TRUE(attr) ((attr) == git_attr__true)
|
||||
#define GIT_ATTR_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_TRUE_T)
|
||||
|
||||
/**
|
||||
* GIT_ATTR_FALSE checks if an attribute is set off. In core git
|
||||
@ -44,7 +44,7 @@ GIT_BEGIN_DECL
|
||||
* Then for file `zyx.h` looking up attribute "foo" gives a value for
|
||||
* which `GIT_ATTR_FALSE(value)` is true.
|
||||
*/
|
||||
#define GIT_ATTR_FALSE(attr) ((attr) == git_attr__false)
|
||||
#define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T)
|
||||
|
||||
/**
|
||||
* GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This
|
||||
@ -62,11 +62,11 @@ GIT_BEGIN_DECL
|
||||
* file `onefile.rb` or looking up "bar" on any file will all give
|
||||
* `GIT_ATTR_UNSPECIFIED(value)` of true.
|
||||
*/
|
||||
#define GIT_ATTR_UNSPECIFIED(attr) (!(attr) || (attr) == git_attr__unset)
|
||||
#define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T)
|
||||
|
||||
/**
|
||||
* GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as
|
||||
* opposied to TRUE, FALSE or UNSPECIFIED). This would be the case if
|
||||
* opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if
|
||||
* for a file with something like:
|
||||
*
|
||||
* *.txt eol=lf
|
||||
@ -74,13 +74,29 @@ GIT_BEGIN_DECL
|
||||
* Given this, looking up "eol" for `onefile.txt` will give back the
|
||||
* string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true.
|
||||
*/
|
||||
#define GIT_ATTR_HAS_VALUE(attr) \
|
||||
((attr) && (attr) != git_attr__unset && \
|
||||
(attr) != git_attr__true && (attr) != git_attr__false)
|
||||
#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T)
|
||||
|
||||
GIT_EXTERN(const char *) git_attr__true;
|
||||
GIT_EXTERN(const char *) git_attr__false;
|
||||
GIT_EXTERN(const char *) git_attr__unset;
|
||||
typedef enum {
|
||||
GIT_ATTR_UNSPECIFIED_T = 0,
|
||||
GIT_ATTR_TRUE_T,
|
||||
GIT_ATTR_FALSE_T,
|
||||
GIT_ATTR_VALUE_T,
|
||||
} git_attr_t;
|
||||
|
||||
/*
|
||||
* Return the value type for a given attribute.
|
||||
*
|
||||
* This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute
|
||||
* was not set at all), or `VALUE`, if the attribute was set to
|
||||
* an actual string.
|
||||
*
|
||||
* If the attribute has a `VALUE` string, it can be accessed normally
|
||||
* as a NULL-terminated C string.
|
||||
*
|
||||
* @param attr The attribute
|
||||
* @return the value type for the attribute
|
||||
*/
|
||||
GIT_EXTERN(git_attr_t) git_attr_value(const char *attr);
|
||||
|
||||
/**
|
||||
* Check attribute flags: Reading values from index and working directory.
|
||||
@ -167,29 +183,30 @@ GIT_EXTERN(int) git_attr_get_many(
|
||||
size_t num_attr,
|
||||
const char **names);
|
||||
|
||||
typedef int (*git_attr_foreach_cb)(const char *name, const char *value, void *payload);
|
||||
|
||||
/**
|
||||
* Loop over all the git attributes for a path.
|
||||
*
|
||||
* @param repo The repository containing the path.
|
||||
* @param flags A combination of GIT_ATTR_CHECK... flags.
|
||||
* @param path The path inside the repo to check attributes. This
|
||||
* does not have to exist, but if it does not, then
|
||||
* it will be treated as a plain file (i.e. not a directory).
|
||||
* @param callback The function that will be invoked on each attribute
|
||||
* and attribute value. The name parameter will be the name
|
||||
* of the attribute and the value will be the value it is
|
||||
* set to, including possibly NULL if the attribute is
|
||||
* explicitly set to UNSPECIFIED using the ! sign. This
|
||||
* will be invoked only once per attribute name, even if
|
||||
* there are multiple rules for a given file. The highest
|
||||
* priority rule will be used.
|
||||
* @param path Path inside the repo to check attributes. This does not have
|
||||
* to exist, but if it does not, then it will be treated as a
|
||||
* plain file (i.e. not a directory).
|
||||
* @param callback Function to invoke on each attribute name and value. The
|
||||
* value may be NULL is the attribute is explicitly set to
|
||||
* UNSPECIFIED using the '!' sign. Callback will be invoked
|
||||
* only once per attribute name, even if there are multiple
|
||||
* rules for a given file. The highest priority rule will be
|
||||
* used. Return a non-zero value from this to stop looping.
|
||||
* @param payload Passed on as extra parameter to callback function.
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_attr_foreach(
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *path,
|
||||
int (*callback)(const char *name, const char *value, void *payload),
|
||||
git_attr_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -46,7 +46,7 @@ GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git
|
||||
* @param len the length of the short identifier
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, unsigned int len)
|
||||
GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len)
|
||||
{
|
||||
return git_object_lookup_prefix((git_object **)blob, repo, id, len, GIT_OBJ_BLOB);
|
||||
}
|
||||
@ -68,6 +68,17 @@ GIT_INLINE(void) git_blob_free(git_blob *blob)
|
||||
git_object_free((git_object *) blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of a blob.
|
||||
*
|
||||
* @param blob a previously loaded blob.
|
||||
* @return SHA1 hash for this blob.
|
||||
*/
|
||||
GIT_INLINE(const git_oid *) git_blob_id(const git_blob *blob)
|
||||
{
|
||||
return git_object_id((const git_object *)blob);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a read-only buffer with the raw content of a blob.
|
||||
@ -80,7 +91,7 @@ GIT_INLINE(void) git_blob_free(git_blob *blob)
|
||||
* @param blob pointer to the blob
|
||||
* @return the pointer; NULL if the blob has no contents
|
||||
*/
|
||||
GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob);
|
||||
GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
|
||||
|
||||
/**
|
||||
* Get the size in bytes of the contents of a blob
|
||||
@ -88,34 +99,79 @@ GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob);
|
||||
* @param blob pointer to the blob
|
||||
* @return size on bytes
|
||||
*/
|
||||
GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob);
|
||||
GIT_EXTERN(git_off_t) git_blob_rawsize(const git_blob *blob);
|
||||
|
||||
/**
|
||||
* Read a file from the working folder of a repository
|
||||
* and write it to the Object Database as a loose blob
|
||||
*
|
||||
* @param oid return the id of the written blob
|
||||
* @param id return the id of the written blob
|
||||
* @param repo repository where the blob will be written.
|
||||
* this repository cannot be bare
|
||||
* @param path file from which the blob will be created,
|
||||
* @param relative_path file from which the blob will be created,
|
||||
* relative to the repository's working dir
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path);
|
||||
GIT_EXTERN(int) git_blob_create_fromworkdir(git_oid *id, git_repository *repo, const char *relative_path);
|
||||
|
||||
/**
|
||||
* Read a file from the filesystem and write its content
|
||||
* to the Object Database as a loose blob
|
||||
*
|
||||
* @param oid return the id of the written blob
|
||||
* @param id return the id of the written blob
|
||||
* @param repo repository where the blob will be written.
|
||||
* this repository can be bare or not
|
||||
* @param path file from which the blob will be created
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path);
|
||||
GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path);
|
||||
|
||||
|
||||
typedef int (*git_blob_chunk_cb)(char *content, size_t max_length, void *payload);
|
||||
|
||||
/**
|
||||
* Write a loose blob to the Object Database from a
|
||||
* provider of chunks of data.
|
||||
*
|
||||
* Provided the `hintpath` parameter is filled, its value
|
||||
* will help to determine what git filters should be applied
|
||||
* to the object before it can be placed to the object database.
|
||||
*
|
||||
*
|
||||
* The implementation of the callback has to respect the
|
||||
* following rules:
|
||||
*
|
||||
* - `content` will have to be filled by the consumer. The maximum number
|
||||
* of bytes that the buffer can accept per call is defined by the
|
||||
* `max_length` parameter. Allocation and freeing of the buffer will be taken
|
||||
* care of by the function.
|
||||
*
|
||||
* - The callback is expected to return the number of bytes
|
||||
* that `content` have been filled with.
|
||||
*
|
||||
* - When there is no more data to stream, the callback should
|
||||
* return 0. This will prevent it from being invoked anymore.
|
||||
*
|
||||
* - When an error occurs, the callback should return -1.
|
||||
*
|
||||
*
|
||||
* @param id Return the id of the written blob
|
||||
*
|
||||
* @param repo repository where the blob will be written.
|
||||
* This repository can be bare or not.
|
||||
*
|
||||
* @param hintpath if not NULL, will help selecting the filters
|
||||
* to apply onto the content of the blob to be created.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_fromchunks(
|
||||
git_oid *id,
|
||||
git_repository *repo,
|
||||
const char *hintpath,
|
||||
git_blob_chunk_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Write an in-memory buffer to the ODB as a blob
|
||||
*
|
||||
@ -127,6 +183,19 @@ GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, con
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len);
|
||||
|
||||
/**
|
||||
* Determine if the blob content is most certainly binary or not.
|
||||
*
|
||||
* The heuristic used to guess if a file is binary is taken from core git:
|
||||
* Searching for NUL bytes and looking for a reasonable ratio of printable
|
||||
* to non-printable characters among the first 4000 bytes.
|
||||
*
|
||||
* @param blob The blob which content should be analyzed
|
||||
* @return 1 if the content of the blob is detected
|
||||
* as binary; 0 otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_is_binary(git_blob *blob);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -8,6 +8,7 @@
|
||||
#define INCLUDE_git_branch_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "oid.h"
|
||||
#include "types.h"
|
||||
|
||||
/**
|
||||
@ -26,61 +27,53 @@ GIT_BEGIN_DECL
|
||||
* this target commit. If `force` is true and a reference
|
||||
* already exists with the given name, it'll be replaced.
|
||||
*
|
||||
* @param oid_out Pointer where to store the OID of the target commit.
|
||||
* The returned reference must be freed by the user.
|
||||
*
|
||||
* @param repo Repository where to store the branch.
|
||||
* The branch name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param out Pointer where to store the underlying reference.
|
||||
*
|
||||
* @param branch_name Name for the branch; this name is
|
||||
* validated for consistency. It should also not conflict with
|
||||
* an already existing branch name.
|
||||
*
|
||||
* @param target Object to which this branch should point. This object
|
||||
* must belong to the given `repo` and can either be a git_commit or a
|
||||
* git_tag. When a git_tag is being passed, it should be dereferencable
|
||||
* to a git_commit which oid will be used as the target of the branch.
|
||||
* @param target Commit to which this branch should point. This object
|
||||
* must belong to the given `repo`.
|
||||
*
|
||||
* @param force Overwrite existing branch.
|
||||
*
|
||||
* @return 0 or an error code.
|
||||
* @return 0, GIT_EINVALIDSPEC or an error code.
|
||||
* A proper reference is written in the refs/heads namespace
|
||||
* pointing to the provided target commit.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_create(
|
||||
git_oid *oid_out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
const git_object *target,
|
||||
int force);
|
||||
git_reference **out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
const git_commit *target,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Delete an existing branch reference.
|
||||
*
|
||||
* @param repo Repository where lives the branch.
|
||||
* If the branch is successfully deleted, the passed reference
|
||||
* object will be freed and invalidated.
|
||||
*
|
||||
* @param branch_name Name of the branch to be deleted;
|
||||
* this name is validated for consistency.
|
||||
*
|
||||
* @param branch_type Type of the considered branch. This should
|
||||
* be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
|
||||
*
|
||||
* @return 0 on success, GIT_ENOTFOUND if the branch
|
||||
* doesn't exist or an error code.
|
||||
* @param branch A valid reference representing a branch
|
||||
* @return 0 on success, or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_delete(
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
git_branch_t branch_type);
|
||||
GIT_EXTERN(int) git_branch_delete(git_reference *branch);
|
||||
|
||||
typedef int (*git_branch_foreach_cb)(
|
||||
const char *branch_name,
|
||||
git_branch_t branch_type,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Fill a list with all the branches in the Repository
|
||||
* Loop over all the branches and issue a callback for each one.
|
||||
*
|
||||
* The string array will be filled with the names of the
|
||||
* matching branches; these values are owned by the user and
|
||||
* should be free'd manually when no longer needed, using
|
||||
* `git_strarray_free`.
|
||||
*
|
||||
* @param branch_names Pointer to a git_strarray structure
|
||||
* where the branch names will be stored.
|
||||
* If the callback returns a non-zero value, this will stop looping.
|
||||
*
|
||||
* @param repo Repository where to find the branches.
|
||||
*
|
||||
@ -88,34 +81,171 @@ GIT_EXTERN(int) git_branch_delete(
|
||||
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
|
||||
* or a combination of the two.
|
||||
*
|
||||
* @return 0 or an error code.
|
||||
* @param branch_cb Callback to invoke per found branch.
|
||||
*
|
||||
* @param payload Extra parameter to callback function.
|
||||
*
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_list(
|
||||
git_strarray *branch_names,
|
||||
git_repository *repo,
|
||||
unsigned int list_flags);
|
||||
GIT_EXTERN(int) git_branch_foreach(
|
||||
git_repository *repo,
|
||||
unsigned int list_flags,
|
||||
git_branch_foreach_cb branch_cb,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Move/rename an existing branch reference.
|
||||
* Move/rename an existing local branch reference.
|
||||
*
|
||||
* @param repo Repository where lives the branch.
|
||||
* The new branch name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param old_branch_name Current name of the branch to be moved;
|
||||
* this name is validated for consistency.
|
||||
* @param branch Current underlying reference of the branch.
|
||||
*
|
||||
* @param new_branch_name Target name of the branch once the move
|
||||
* is performed; this name is validated for consistency.
|
||||
*
|
||||
* @param force Overwrite existing branch.
|
||||
*
|
||||
* @return 0 on success, GIT_ENOTFOUND if the branch
|
||||
* doesn't exist or an error code.
|
||||
* @return 0 on success, GIT_EINVALIDSPEC or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_move(
|
||||
git_repository *repo,
|
||||
const char *old_branch_name,
|
||||
const char *new_branch_name,
|
||||
int force);
|
||||
git_reference **out,
|
||||
git_reference *branch,
|
||||
const char *new_branch_name,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Lookup a branch by its name in a repository.
|
||||
*
|
||||
* The generated reference must be freed by the user.
|
||||
*
|
||||
* The branch name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param out pointer to the looked-up branch reference
|
||||
*
|
||||
* @param repo the repository to look up the branch
|
||||
*
|
||||
* @param branch_name Name of the branch to be looked-up;
|
||||
* this name is validated for consistency.
|
||||
*
|
||||
* @param branch_type Type of the considered branch. This should
|
||||
* be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
|
||||
*
|
||||
* @return 0 on success; GIT_ENOTFOUND when no matching branch
|
||||
* exists, GIT_EINVALIDSPEC, otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_lookup(
|
||||
git_reference **out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
git_branch_t branch_type);
|
||||
|
||||
/**
|
||||
* Return the name of the given local or remote branch.
|
||||
*
|
||||
* The name of the branch matches the definition of the name
|
||||
* for git_branch_lookup. That is, if the returned name is given
|
||||
* to git_branch_lookup() then the reference is returned that
|
||||
* was given to this function.
|
||||
*
|
||||
* @param out where the pointer of branch name is stored;
|
||||
* this is valid as long as the ref is not freed.
|
||||
* @param ref the reference ideally pointing to a branch
|
||||
*
|
||||
* @return 0 on success; otherwise an error code (e.g., if the
|
||||
* ref is no local or remote branch).
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_name(const char **out,
|
||||
git_reference *ref);
|
||||
|
||||
/**
|
||||
* Return the reference supporting the remote tracking branch,
|
||||
* given a local branch reference.
|
||||
*
|
||||
* @param out Pointer where to store the retrieved
|
||||
* reference.
|
||||
*
|
||||
* @param branch Current underlying reference of the branch.
|
||||
*
|
||||
* @return 0 on success; GIT_ENOTFOUND when no remote tracking
|
||||
* reference exists, otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_upstream(
|
||||
git_reference **out,
|
||||
git_reference *branch);
|
||||
|
||||
/**
|
||||
* Set the upstream configuration for a given local branch
|
||||
*
|
||||
* @param branch the branch to configure
|
||||
*
|
||||
* @param upstream_name remote-tracking or local branch to set as
|
||||
* upstream. Pass NULL to unset.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_set_upstream(git_reference *branch, const char *upstream_name);
|
||||
|
||||
/**
|
||||
* Return the name of the reference supporting the remote tracking branch,
|
||||
* given the name of a local branch reference.
|
||||
*
|
||||
* @param tracking_branch_name_out The user-allocated buffer which will be
|
||||
* filled with the name of the reference. Pass NULL if you just want to
|
||||
* get the needed size of the name of the reference as the output value.
|
||||
*
|
||||
* @param buffer_size Size of the `out` buffer in bytes.
|
||||
*
|
||||
* @param repo the repository where the branches live
|
||||
*
|
||||
* @param canonical_branch_name name of the local branch.
|
||||
*
|
||||
* @return number of characters in the reference name
|
||||
* including the trailing NUL byte; GIT_ENOTFOUND when no remote tracking
|
||||
* reference exists, otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_upstream_name(
|
||||
char *tracking_branch_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name);
|
||||
|
||||
/**
|
||||
* Determine if the current local branch is pointed at by HEAD.
|
||||
*
|
||||
* @param branch Current underlying reference of the branch.
|
||||
*
|
||||
* @return 1 if HEAD points at the branch, 0 if it isn't,
|
||||
* error code otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_is_head(
|
||||
git_reference *branch);
|
||||
|
||||
/**
|
||||
* Return the name of remote that the remote tracking branch belongs to.
|
||||
*
|
||||
* @param remote_name_out The user-allocated buffer which will be
|
||||
* filled with the name of the remote. Pass NULL if you just want to
|
||||
* get the needed size of the name of the remote as the output value.
|
||||
*
|
||||
* @param buffer_size Size of the `out` buffer in bytes.
|
||||
*
|
||||
* @param repo The repository where the branch lives.
|
||||
*
|
||||
* @param canonical_branch_name name of the remote tracking branch.
|
||||
*
|
||||
* @return Number of characters in the reference name
|
||||
* including the trailing NUL byte; GIT_ENOTFOUND
|
||||
* when no remote matching remote was gound,
|
||||
* GIT_EAMBIGUOUS when the branch maps to several remotes,
|
||||
* otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_remote_name(
|
||||
char *remote_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
285
include/git2/checkout.h
Normal file
285
include/git2/checkout.h
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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_git_checkout_h__
|
||||
#define INCLUDE_git_checkout_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "diff.h"
|
||||
|
||||
/**
|
||||
* @file git2/checkout.h
|
||||
* @brief Git checkout routines
|
||||
* @defgroup git_checkout Git checkout routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Checkout behavior flags
|
||||
*
|
||||
* In libgit2, checkout is used to update the working directory and index
|
||||
* to match a target tree. Unlike git checkout, it does not move the HEAD
|
||||
* commit for you - use `git_repository_set_head` or the like to do that.
|
||||
*
|
||||
* Checkout looks at (up to) four things: the "target" tree you want to
|
||||
* check out, the "baseline" tree of what was checked out previously, the
|
||||
* working directory for actual files, and the index for staged changes.
|
||||
*
|
||||
* You give checkout one of four strategies for update:
|
||||
*
|
||||
* - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts,
|
||||
* etc., but doesn't make any actual changes.
|
||||
*
|
||||
* - `GIT_CHECKOUT_FORCE` is at the opposite extreme, taking any action to
|
||||
* make the working directory match the target (including potentially
|
||||
* discarding modified files).
|
||||
*
|
||||
* In between those are `GIT_CHECKOUT_SAFE` and `GIT_CHECKOUT_SAFE_CREATE`
|
||||
* both of which only make modifications that will not lose changes.
|
||||
*
|
||||
* | target == baseline | target != baseline |
|
||||
* ---------------------|-----------------------|----------------------|
|
||||
* workdir == baseline | no action | create, update, or |
|
||||
* | | delete file |
|
||||
* ---------------------|-----------------------|----------------------|
|
||||
* workdir exists and | no action | conflict (notify |
|
||||
* is != baseline | notify dirty MODIFIED | and cancel checkout) |
|
||||
* ---------------------|-----------------------|----------------------|
|
||||
* workdir missing, | create if SAFE_CREATE | create file |
|
||||
* baseline present | notify dirty DELETED | |
|
||||
* ---------------------|-----------------------|----------------------|
|
||||
*
|
||||
* The only difference between SAFE and SAFE_CREATE is that SAFE_CREATE
|
||||
* will cause a file to be checked out if it is missing from the working
|
||||
* directory even if it is not modified between the target and baseline.
|
||||
*
|
||||
*
|
||||
* To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout
|
||||
* notification callback (see below) that displays information about dirty
|
||||
* files. The default behavior will cancel checkout on conflicts.
|
||||
*
|
||||
* To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE_CREATE` with a
|
||||
* notification callback that cancels the operation if a dirty-but-existing
|
||||
* file is found in the working directory. This core git command isn't
|
||||
* quite "force" but is sensitive about some types of changes.
|
||||
*
|
||||
* To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`.
|
||||
*
|
||||
* To emulate `git clone` use `GIT_CHECKOUT_SAFE_CREATE` in the options.
|
||||
*
|
||||
*
|
||||
* There are some additional flags to modified the behavior of checkout:
|
||||
*
|
||||
* - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates
|
||||
* even if there are conflicts (instead of cancelling the checkout).
|
||||
*
|
||||
* - GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not
|
||||
* in target, baseline, or index, and not ignored) from the working dir.
|
||||
*
|
||||
* - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also
|
||||
* untracked) from the working directory as well.
|
||||
*
|
||||
* - GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that
|
||||
* already exist. Files will not be created nor deleted. This just skips
|
||||
* applying adds, deletes, and typechanges.
|
||||
*
|
||||
* - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the
|
||||
* updated files' information to the index.
|
||||
*
|
||||
* - Normally, checkout will reload the index and git attributes from disk
|
||||
* before any operations. GIT_CHECKOUT_NO_REFRESH prevents this reload.
|
||||
*
|
||||
* - Unmerged index entries are conflicts. GIT_CHECKOUT_SKIP_UNMERGED skips
|
||||
* files with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and
|
||||
* GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the
|
||||
* stage 2 ("ours") or stage 3 ("theirs") version of files in the index.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_CHECKOUT_NONE = 0, /** default is a dry run, no actual updates */
|
||||
|
||||
/** Allow safe updates that cannot overwrite uncommitted data */
|
||||
GIT_CHECKOUT_SAFE = (1u << 0),
|
||||
|
||||
/** Allow safe updates plus creation of missing files */
|
||||
GIT_CHECKOUT_SAFE_CREATE = (1u << 1),
|
||||
|
||||
/** Allow all updates to force working directory to look like index */
|
||||
GIT_CHECKOUT_FORCE = (1u << 2),
|
||||
|
||||
|
||||
/** Allow checkout to make safe updates even if conflicts are found */
|
||||
GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4),
|
||||
|
||||
/** Remove untracked files not in index (that are not ignored) */
|
||||
GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5),
|
||||
|
||||
/** Remove ignored files not in index */
|
||||
GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6),
|
||||
|
||||
/** Only update existing files, don't create new ones */
|
||||
GIT_CHECKOUT_UPDATE_ONLY = (1u << 7),
|
||||
|
||||
/** Normally checkout updates index entries as it goes; this stops that */
|
||||
GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8),
|
||||
|
||||
/** Don't refresh index/config/etc before doing checkout */
|
||||
GIT_CHECKOUT_NO_REFRESH = (1u << 9),
|
||||
|
||||
/** Treat pathspec as simple list of exact match file paths */
|
||||
GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
|
||||
|
||||
/**
|
||||
* THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
|
||||
*/
|
||||
|
||||
/** Allow checkout to skip unmerged files (NOT IMPLEMENTED) */
|
||||
GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
|
||||
/** For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) */
|
||||
GIT_CHECKOUT_USE_OURS = (1u << 11),
|
||||
/** For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) */
|
||||
GIT_CHECKOUT_USE_THEIRS = (1u << 12),
|
||||
|
||||
/** Recursively checkout submodules with same options (NOT IMPLEMENTED) */
|
||||
GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16),
|
||||
/** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */
|
||||
GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17),
|
||||
|
||||
} git_checkout_strategy_t;
|
||||
|
||||
/**
|
||||
* Checkout notification flags
|
||||
*
|
||||
* Checkout will invoke an options notification callback (`notify_cb`) for
|
||||
* certain cases - you pick which ones via `notify_flags`:
|
||||
*
|
||||
* - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths.
|
||||
*
|
||||
* - GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that
|
||||
* do not need an update but no longer match the baseline. Core git
|
||||
* displays these files when checkout runs, but won't stop the checkout.
|
||||
*
|
||||
* - GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed.
|
||||
*
|
||||
* - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files.
|
||||
*
|
||||
* - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files.
|
||||
*
|
||||
* Returning a non-zero value from this callback will cancel the checkout.
|
||||
* Notification callbacks are made prior to modifying any files on disk.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_CHECKOUT_NOTIFY_NONE = 0,
|
||||
GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0),
|
||||
GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1),
|
||||
GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2),
|
||||
GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3),
|
||||
GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4),
|
||||
} git_checkout_notify_t;
|
||||
|
||||
/** Checkout notification callback function */
|
||||
typedef int (*git_checkout_notify_cb)(
|
||||
git_checkout_notify_t why,
|
||||
const char *path,
|
||||
const git_diff_file *baseline,
|
||||
const git_diff_file *target,
|
||||
const git_diff_file *workdir,
|
||||
void *payload);
|
||||
|
||||
/** Checkout progress notification function */
|
||||
typedef void (*git_checkout_progress_cb)(
|
||||
const char *path,
|
||||
size_t completed_steps,
|
||||
size_t total_steps,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Checkout options structure
|
||||
*
|
||||
* Zero out for defaults. Initialize with `GIT_CHECKOUT_OPTS_INIT` macro to
|
||||
* correctly set the `version` field. E.g.
|
||||
*
|
||||
* git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
|
||||
*/
|
||||
typedef struct git_checkout_opts {
|
||||
unsigned int version;
|
||||
|
||||
unsigned int checkout_strategy; /** default will be a dry run */
|
||||
|
||||
int disable_filters; /** don't apply filters like CRLF conversion */
|
||||
unsigned int dir_mode; /** default is 0755 */
|
||||
unsigned int file_mode; /** default is 0644 or 0755 as dictated by blob */
|
||||
int file_open_flags; /** default is O_CREAT | O_TRUNC | O_WRONLY */
|
||||
|
||||
unsigned int notify_flags; /** see `git_checkout_notify_t` above */
|
||||
git_checkout_notify_cb notify_cb;
|
||||
void *notify_payload;
|
||||
|
||||
/* Optional callback to notify the consumer of checkout progress. */
|
||||
git_checkout_progress_cb progress_cb;
|
||||
void *progress_payload;
|
||||
|
||||
/** When not zeroed out, array of fnmatch patterns specifying which
|
||||
* paths should be taken into account, otherwise all files. Use
|
||||
* GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as simple list.
|
||||
*/
|
||||
git_strarray paths;
|
||||
|
||||
git_tree *baseline; /** expected content of workdir, defaults to HEAD */
|
||||
} git_checkout_opts;
|
||||
|
||||
#define GIT_CHECKOUT_OPTS_VERSION 1
|
||||
#define GIT_CHECKOUT_OPTS_INIT {GIT_CHECKOUT_OPTS_VERSION}
|
||||
|
||||
/**
|
||||
* Updates files in the index and the working tree to match the content of
|
||||
* the commit pointed at by HEAD.
|
||||
*
|
||||
* @param repo repository to check out (must be non-bare)
|
||||
* @param opts specifies checkout options (may be NULL)
|
||||
* @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
|
||||
* branch, GIT_ERROR otherwise (use giterr_last for information
|
||||
* about the error)
|
||||
*/
|
||||
GIT_EXTERN(int) git_checkout_head(
|
||||
git_repository *repo,
|
||||
git_checkout_opts *opts);
|
||||
|
||||
/**
|
||||
* Updates files in the working tree to match the content of the index.
|
||||
*
|
||||
* @param repo repository into which to check out (must be non-bare)
|
||||
* @param index index to be checked out (or NULL to use repository index)
|
||||
* @param opts specifies checkout options (may be NULL)
|
||||
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
|
||||
* about the error)
|
||||
*/
|
||||
GIT_EXTERN(int) git_checkout_index(
|
||||
git_repository *repo,
|
||||
git_index *index,
|
||||
git_checkout_opts *opts);
|
||||
|
||||
/**
|
||||
* Updates files in the index and working tree to match the content of the
|
||||
* tree pointed at by the treeish.
|
||||
*
|
||||
* @param repo repository to check out (must be non-bare)
|
||||
* @param treeish a commit, tag or tree which content will be used to update
|
||||
* the working directory
|
||||
* @param opts specifies checkout options (may be NULL)
|
||||
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
|
||||
* about the error)
|
||||
*/
|
||||
GIT_EXTERN(int) git_checkout_tree(
|
||||
git_repository *repo,
|
||||
const git_object *treeish,
|
||||
git_checkout_opts *opts);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
107
include/git2/clone.h
Normal file
107
include/git2/clone.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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_git_clone_h__
|
||||
#define INCLUDE_git_clone_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "indexer.h"
|
||||
#include "checkout.h"
|
||||
#include "remote.h"
|
||||
|
||||
|
||||
/**
|
||||
* @file git2/clone.h
|
||||
* @brief Git cloning routines
|
||||
* @defgroup git_clone Git cloning routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Clone options structure
|
||||
*
|
||||
* Use zeros to indicate default settings. It's easiest to use the
|
||||
* `GIT_CLONE_OPTIONS_INIT` macro:
|
||||
*
|
||||
* git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
|
||||
*
|
||||
* - `checkout_opts` is options for the checkout step. To disable checkout,
|
||||
* set the `checkout_strategy` to GIT_CHECKOUT_DEFAULT.
|
||||
* - `bare` should be set to zero to create a standard repo, non-zero for
|
||||
* a bare repo
|
||||
* - `fetch_progress_cb` is optional callback for fetch progress. Be aware that
|
||||
* this is called inline with network and indexing operations, so performance
|
||||
* may be affected.
|
||||
* - `fetch_progress_payload` is payload for fetch_progress_cb
|
||||
*
|
||||
* ** "origin" remote options: **
|
||||
* - `remote_name` is the name given to the "origin" remote. The default is
|
||||
* "origin".
|
||||
* - `pushurl` is a URL to be used for pushing. NULL means use the fetch url.
|
||||
* - `fetch_spec` is the fetch specification to be used for fetching. NULL
|
||||
* results in the same behavior as GIT_REMOTE_DEFAULT_FETCH.
|
||||
* - `push_spec` is the fetch specification to be used for pushing. NULL means
|
||||
* use the same spec as for fetching.
|
||||
* - `cred_acquire_cb` is a callback to be used if credentials are required
|
||||
* during the initial fetch.
|
||||
* - `cred_acquire_payload` is the payload for the above callback.
|
||||
* - `transport` is a custom transport to be used for the initial fetch. NULL
|
||||
* means use the transport autodetected from the URL.
|
||||
* - `remote_callbacks` may be used to specify custom progress callbacks for
|
||||
* the origin remote before the fetch is initiated.
|
||||
* - `remote_autotag` may be used to specify the autotag setting before the
|
||||
* initial fetch. The default is GIT_REMOTE_DOWNLOAD_TAGS_ALL.
|
||||
* - `checkout_branch` gives the name of the branch to checkout. NULL means
|
||||
* use the remote's HEAD.
|
||||
*/
|
||||
|
||||
typedef struct git_clone_options {
|
||||
unsigned int version;
|
||||
|
||||
git_checkout_opts checkout_opts;
|
||||
int bare;
|
||||
git_transfer_progress_callback fetch_progress_cb;
|
||||
void *fetch_progress_payload;
|
||||
|
||||
const char *remote_name;
|
||||
const char *pushurl;
|
||||
const char *fetch_spec;
|
||||
const char *push_spec;
|
||||
git_cred_acquire_cb cred_acquire_cb;
|
||||
void *cred_acquire_payload;
|
||||
git_transport *transport;
|
||||
git_remote_callbacks *remote_callbacks;
|
||||
git_remote_autotag_option_t remote_autotag;
|
||||
const char* checkout_branch;
|
||||
} git_clone_options;
|
||||
|
||||
#define GIT_CLONE_OPTIONS_VERSION 1
|
||||
#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTS_VERSION, GIT_CHECKOUT_SAFE_CREATE}}
|
||||
|
||||
/**
|
||||
* Clone a remote repository, and checkout the branch pointed to by the remote
|
||||
* HEAD.
|
||||
*
|
||||
* @param out pointer that will receive the resulting repository object
|
||||
* @param url the remote repository to clone
|
||||
* @param local_path local directory to clone to
|
||||
* @param options configuration options for the clone. If NULL, the function
|
||||
* works as though GIT_OPTIONS_INIT were passed.
|
||||
* @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
|
||||
* about the error)
|
||||
*/
|
||||
GIT_EXTERN(int) git_clone(
|
||||
git_repository **out,
|
||||
const char *url,
|
||||
const char *local_path,
|
||||
const git_clone_options *options);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -48,7 +48,7 @@ GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, con
|
||||
* @param len the length of the short identifier
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, unsigned len)
|
||||
GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len)
|
||||
{
|
||||
return git_object_lookup_prefix((git_object **)commit, repo, id, len, GIT_OBJ_COMMIT);
|
||||
}
|
||||
@ -76,7 +76,10 @@ GIT_INLINE(void) git_commit_free(git_commit *commit)
|
||||
* @param commit a previously loaded commit.
|
||||
* @return object identity for the commit.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
|
||||
GIT_INLINE(const git_oid *) git_commit_id(const git_commit *commit)
|
||||
{
|
||||
return git_object_id((const git_object *)commit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encoding for the message of a commit,
|
||||
@ -88,7 +91,7 @@ GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return NULL, or the encoding
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit);
|
||||
GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the full message of a commit.
|
||||
@ -96,7 +99,7 @@ GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return the message of a commit
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_commit_message(git_commit *commit);
|
||||
GIT_EXTERN(const char *) git_commit_message(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the commit time (i.e. committer time) of a commit.
|
||||
@ -104,7 +107,7 @@ GIT_EXTERN(const char *) git_commit_message(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return the time of a commit
|
||||
*/
|
||||
GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit);
|
||||
GIT_EXTERN(git_time_t) git_commit_time(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the commit timezone offset (i.e. committer's preferred timezone) of a commit.
|
||||
@ -112,7 +115,7 @@ GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return positive or negative timezone offset, in minutes from UTC
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_time_offset(git_commit *commit);
|
||||
GIT_EXTERN(int) git_commit_time_offset(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the committer of a commit.
|
||||
@ -120,7 +123,7 @@ GIT_EXTERN(int) git_commit_time_offset(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return the committer of a commit
|
||||
*/
|
||||
GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit);
|
||||
GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the author of a commit.
|
||||
@ -128,7 +131,7 @@ GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return the author of a commit
|
||||
*/
|
||||
GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit);
|
||||
GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the tree pointed to by a commit.
|
||||
@ -137,7 +140,7 @@ GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit);
|
||||
GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the id of the tree pointed to by a commit. This differs from
|
||||
@ -147,7 +150,7 @@ GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return the id of tree pointed to by commit.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit);
|
||||
GIT_EXTERN(const git_oid *) git_commit_tree_id(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the number of parents of this commit
|
||||
@ -155,17 +158,17 @@ GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit);
|
||||
* @param commit a previously loaded commit.
|
||||
* @return integer of count of parents
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *commit);
|
||||
GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the specified parent of the commit.
|
||||
*
|
||||
* @param parent Pointer where to store the parent commit
|
||||
* @param out Pointer where to store the parent commit
|
||||
* @param commit a previously loaded commit.
|
||||
* @param n the position of the parent (from 0 to `parentcount`)
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n);
|
||||
GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned int n);
|
||||
|
||||
/**
|
||||
* Get the oid of a specified parent for a commit. This is different from
|
||||
@ -176,16 +179,35 @@ GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsig
|
||||
* @param n the position of the parent (from 0 to `parentcount`)
|
||||
* @return the id of the parent, NULL on error.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned int n);
|
||||
GIT_EXTERN(const git_oid *) git_commit_parent_id(git_commit *commit, unsigned int n);
|
||||
|
||||
/**
|
||||
* Get the commit object that is the <n>th generation ancestor
|
||||
* of the named commit object, following only the first parents.
|
||||
* The returned commit has to be freed by the caller.
|
||||
*
|
||||
* Passing `0` as the generation number returns another instance of the
|
||||
* base commit itself.
|
||||
*
|
||||
* @param ancestor Pointer where to store the ancestor commit
|
||||
* @param commit a previously loaded commit.
|
||||
* @param n the requested generation
|
||||
* @return 0 on success; GIT_ENOTFOUND if no matching ancestor exists
|
||||
* or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_nth_gen_ancestor(
|
||||
git_commit **ancestor,
|
||||
const git_commit *commit,
|
||||
unsigned int n);
|
||||
|
||||
/**
|
||||
* Create a new commit in the repository using `git_object`
|
||||
* instances as parameters.
|
||||
*
|
||||
* The message will be cleaned up from excess whitespace
|
||||
* it will be made sure that the last line ends with a '\n'.
|
||||
* The message will not be cleaned up. This can be achieved
|
||||
* through `git_message_prettify()`.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* @param id Pointer where to store the OID of the
|
||||
* newly created commit
|
||||
*
|
||||
* @param repo Repository where to store the commit
|
||||
@ -226,7 +248,7 @@ GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned i
|
||||
* the given reference will be updated to point to it
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_create(
|
||||
git_oid *oid,
|
||||
git_oid *id,
|
||||
git_repository *repo,
|
||||
const char *update_ref,
|
||||
const git_signature *author,
|
||||
@ -254,7 +276,7 @@ GIT_EXTERN(int) git_commit_create(
|
||||
* @see git_commit_create
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_create_v(
|
||||
git_oid *oid,
|
||||
git_oid *id,
|
||||
git_repository *repo,
|
||||
const char *update_ref,
|
||||
const git_signature *author,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -55,6 +55,10 @@
|
||||
#define GIT_WIN32 1
|
||||
#endif
|
||||
|
||||
#ifdef __amigaos4__
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file git2/common.h
|
||||
* @brief Git common platform definitions
|
||||
@ -81,13 +85,10 @@ GIT_BEGIN_DECL
|
||||
*/
|
||||
#define GIT_PATH_MAX 4096
|
||||
|
||||
typedef struct {
|
||||
char **strings;
|
||||
size_t count;
|
||||
} git_strarray;
|
||||
|
||||
GIT_EXTERN(void) git_strarray_free(git_strarray *array);
|
||||
GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
|
||||
/**
|
||||
* The string representation of the null object ID.
|
||||
*/
|
||||
#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000"
|
||||
|
||||
/**
|
||||
* Return the version of the libgit2 library
|
||||
@ -99,6 +100,91 @@ GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
|
||||
*/
|
||||
GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
|
||||
|
||||
/**
|
||||
* Combinations of these values describe the capabilities of libgit2.
|
||||
*/
|
||||
enum {
|
||||
GIT_CAP_THREADS = ( 1 << 0 ),
|
||||
GIT_CAP_HTTPS = ( 1 << 1 )
|
||||
};
|
||||
|
||||
/**
|
||||
* Query compile time options for libgit2.
|
||||
*
|
||||
* @return A combination of GIT_CAP_* values.
|
||||
*
|
||||
* - GIT_CAP_THREADS
|
||||
* Libgit2 was compiled with thread support. Note that thread support is still to be seen as a
|
||||
* 'work in progress'.
|
||||
*
|
||||
* - GIT_CAP_HTTPS
|
||||
* Libgit2 supports the https:// protocol. This requires the open ssl library to be
|
||||
* found when compiling libgit2.
|
||||
*/
|
||||
GIT_EXTERN(int) git_libgit2_capabilities(void);
|
||||
|
||||
|
||||
enum {
|
||||
GIT_OPT_GET_MWINDOW_SIZE,
|
||||
GIT_OPT_SET_MWINDOW_SIZE,
|
||||
GIT_OPT_GET_MWINDOW_MAPPED_LIMIT,
|
||||
GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
|
||||
GIT_OPT_GET_SEARCH_PATH,
|
||||
GIT_OPT_SET_SEARCH_PATH,
|
||||
GIT_OPT_GET_ODB_CACHE_SIZE,
|
||||
GIT_OPT_SET_ODB_CACHE_SIZE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Set or query a library global option
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *):
|
||||
* Get the maximum mmap window size
|
||||
*
|
||||
* opts(GIT_OPT_SET_MWINDOW_SIZE, size_t):
|
||||
* Set the maximum mmap window size
|
||||
*
|
||||
* opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *):
|
||||
* Get the maximum memory that will be mapped in total by the library
|
||||
*
|
||||
* opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t):
|
||||
* Set the maximum amount of memory that can be mapped at any time
|
||||
* by the library
|
||||
*
|
||||
* opts(GIT_OPT_GET_SEARCH_PATH, int level, char *out, size_t len)
|
||||
* Get the search path for a given level of config data. "level" must
|
||||
* be one of GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, or
|
||||
* GIT_CONFIG_LEVEL_XDG. The search path is written to the `out`
|
||||
* buffer up to size `len`. Returns GIT_EBUFS if buffer is too small.
|
||||
*
|
||||
* opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
|
||||
* Set the search path for a level of config data. The search path
|
||||
* applied to shared attributes and ignore files, too.
|
||||
* - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR.
|
||||
* Pass NULL to reset to the default (generally based on environment
|
||||
* variables). Use magic path `$PATH` to include the old value
|
||||
* of the path (if you want to prepend or append, for instance).
|
||||
* - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL,
|
||||
* or GIT_CONFIG_LEVEL_XDG.
|
||||
*
|
||||
* opts(GIT_OPT_GET_ODB_CACHE_SIZE):
|
||||
* Get the size of the libgit2 odb cache.
|
||||
*
|
||||
* opts(GIT_OPT_SET_ODB_CACHE_SIZE):
|
||||
* Set the size of the of the libgit2 odb cache. This needs
|
||||
* to be done before git_repository_open is called, since
|
||||
* git_repository_open initializes the odb layer. Defaults
|
||||
* to 128.
|
||||
*
|
||||
* @param option Option key
|
||||
* @param ... value to set the option
|
||||
* @return 0 on success, <0 on failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_libgit2_opts(int option, ...);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -19,23 +19,52 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Priority level of a config file.
|
||||
* These priority levels correspond to the natural escalation logic
|
||||
* (from higher to lower) when searching for config entries in git.git.
|
||||
*
|
||||
* git_config_open_default() and git_repository_config() honor those
|
||||
* priority levels as well.
|
||||
*/
|
||||
enum {
|
||||
GIT_CONFIG_LEVEL_SYSTEM = 1, /**< System-wide configuration file. */
|
||||
GIT_CONFIG_LEVEL_XDG = 2, /**< XDG compatible configuration file (.config/git/config). */
|
||||
GIT_CONFIG_LEVEL_GLOBAL = 3, /**< User-specific configuration file, also called Global configuration file. */
|
||||
GIT_CONFIG_LEVEL_LOCAL = 4, /**< Repository specific configuration file. */
|
||||
GIT_CONFIG_HIGHEST_LEVEL = -1, /**< Represents the highest level of a config file. */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *value;
|
||||
unsigned int level;
|
||||
} git_config_entry;
|
||||
|
||||
typedef int (*git_config_foreach_cb)(const git_config_entry *, void *);
|
||||
|
||||
|
||||
/**
|
||||
* Generic backend that implements the interface to
|
||||
* access a configuration file
|
||||
*/
|
||||
struct git_config_file {
|
||||
struct git_config_backend {
|
||||
unsigned int version;
|
||||
struct git_config *cfg;
|
||||
|
||||
/* Open means open the file/database and parse if necessary */
|
||||
int (*open)(struct git_config_file *);
|
||||
int (*get)(struct git_config_file *, const char *key, const char **value);
|
||||
int (*get_multivar)(struct git_config_file *, const char *key, const char *regexp, int (*fn)(const char *, void *), void *data);
|
||||
int (*set)(struct git_config_file *, const char *key, const char *value);
|
||||
int (*set_multivar)(git_config_file *cfg, const char *name, const char *regexp, const char *value);
|
||||
int (*del)(struct git_config_file *, const char *key);
|
||||
int (*foreach)(struct git_config_file *, int (*fn)(const char *, const char *, void *), void *data);
|
||||
void (*free)(struct git_config_file *);
|
||||
int (*open)(struct git_config_backend *, unsigned int level);
|
||||
int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry);
|
||||
int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload);
|
||||
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 (*del)(struct git_config_backend *, const char *key);
|
||||
int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload);
|
||||
int (*refresh)(struct git_config_backend *);
|
||||
void (*free)(struct git_config_backend *);
|
||||
};
|
||||
#define GIT_CONFIG_BACKEND_VERSION 1
|
||||
#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION}
|
||||
|
||||
typedef enum {
|
||||
GIT_CVAR_FALSE = 0,
|
||||
@ -61,11 +90,32 @@ typedef struct {
|
||||
* may be used on any `git_config` call to load the
|
||||
* global configuration file.
|
||||
*
|
||||
* @param global_config_path Buffer of GIT_PATH_MAX length to store the path
|
||||
* @return 0 if a global configuration file has been
|
||||
* This method will not guess the path to the xdg compatible
|
||||
* config file (.config/git/config).
|
||||
*
|
||||
* @param out Buffer to store the path in
|
||||
* @param length size of the buffer in bytes
|
||||
* @return 0 if a global configuration file has been found. Its path will be stored in `buffer`.
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_find_global(char *out, size_t length);
|
||||
|
||||
/**
|
||||
* Locate the path to the global xdg compatible configuration file
|
||||
*
|
||||
* The xdg compatible configuration file is usually
|
||||
* located in `$HOME/.config/git/config`.
|
||||
*
|
||||
* This method will try to guess the full path to that
|
||||
* file, if the file exists. The returned path
|
||||
* may be used on any `git_config` call to load the
|
||||
* xdg compatible configuration file.
|
||||
*
|
||||
* @param out Buffer to store the path in
|
||||
* @param length size of the buffer in bytes
|
||||
* @return 0 if a xdg compatible configuration file has been
|
||||
* found. Its path will be stored in `buffer`.
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length);
|
||||
GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length);
|
||||
|
||||
/**
|
||||
* Locate the path to the system configuration file
|
||||
@ -73,35 +123,24 @@ GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length);
|
||||
* If /etc/gitconfig doesn't exist, it will look for
|
||||
* %PROGRAMFILES%\Git\etc\gitconfig.
|
||||
|
||||
* @param system_config_path Buffer of GIT_PATH_MAX length to store the path
|
||||
* @param global_config_path Buffer to store the path in
|
||||
* @param length size of the buffer in bytes
|
||||
* @return 0 if a system configuration file has been
|
||||
* found. Its path will be stored in `buffer`.
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_find_system(char *system_config_path, size_t length);
|
||||
GIT_EXTERN(int) git_config_find_system(char *out, size_t length);
|
||||
|
||||
/**
|
||||
* Open the global configuration file
|
||||
* Open the global, XDG and system configuration files
|
||||
*
|
||||
* Utility wrapper that calls `git_config_find_global`
|
||||
* and opens the located file, if it exists.
|
||||
* Utility wrapper that finds the global, XDG and system configuration files
|
||||
* and opens them into a single prioritized config object that can be
|
||||
* used when accessing default config data outside a repository.
|
||||
*
|
||||
* @param out Pointer to store the config instance
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_global(git_config **out);
|
||||
|
||||
/**
|
||||
* Create a configuration file backend for ondisk files
|
||||
*
|
||||
* These are the normal `.gitconfig` files that Core Git
|
||||
* processes. Note that you first have to add this file to a
|
||||
* configuration object before you can query it for configuration
|
||||
* variables.
|
||||
*
|
||||
* @param out the new backend
|
||||
* @param path where the config file is located
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_file__ondisk(struct git_config_file **out, const char *path);
|
||||
GIT_EXTERN(int) git_config_open_default(git_config **out);
|
||||
|
||||
/**
|
||||
* Allocate a new configuration object
|
||||
@ -122,14 +161,21 @@ GIT_EXTERN(int) git_config_new(git_config **out);
|
||||
*
|
||||
* Further queries on this config object will access each
|
||||
* of the config file instances in order (instances with
|
||||
* a higher priority will be accessed first).
|
||||
* a higher priority level will be accessed first).
|
||||
*
|
||||
* @param cfg the configuration to add the file to
|
||||
* @param file the configuration file (backend) to add
|
||||
* @param priority the priority the backend should have
|
||||
* @return 0 or an error code
|
||||
* @param level the priority level of the backend
|
||||
* @param force if a config file already exists for the given
|
||||
* priority level, replace it
|
||||
* @return 0 on success, GIT_EEXISTS when adding more than one file
|
||||
* for a given priority level (and force_replace set to 0), or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_add_file(git_config *cfg, git_config_file *file, int priority);
|
||||
GIT_EXTERN(int) git_config_add_backend(
|
||||
git_config *cfg,
|
||||
git_config_backend *file,
|
||||
unsigned int level,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Add an on-disk config file instance to an existing config
|
||||
@ -143,15 +189,22 @@ GIT_EXTERN(int) git_config_add_file(git_config *cfg, git_config_file *file, int
|
||||
*
|
||||
* Further queries on this config object will access each
|
||||
* of the config file instances in order (instances with
|
||||
* a higher priority will be accessed first).
|
||||
* a higher priority level will be accessed first).
|
||||
*
|
||||
* @param cfg the configuration to add the file to
|
||||
* @param path path to the configuration file (backend) to add
|
||||
* @param priority the priority the backend should have
|
||||
* @return 0 or an error code
|
||||
* @param level the priority level of the backend
|
||||
* @param force if a config file already exists for the given
|
||||
* priority level, replace it
|
||||
* @return 0 on success, GIT_EEXISTS when adding more than one file
|
||||
* for a given priority level (and force_replace set to 0),
|
||||
* GIT_ENOTFOUND when the file doesn't exist or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_add_file_ondisk(git_config *cfg, const char *path, int priority);
|
||||
|
||||
GIT_EXTERN(int) git_config_add_file_ondisk(
|
||||
git_config *cfg,
|
||||
const char *path,
|
||||
unsigned int level,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Create a new config instance containing a single on-disk file
|
||||
@ -161,11 +214,46 @@ GIT_EXTERN(int) git_config_add_file_ondisk(git_config *cfg, const char *path, in
|
||||
* - git_config_new
|
||||
* - git_config_add_file_ondisk
|
||||
*
|
||||
* @param cfg The configuration instance to create
|
||||
* @param out The configuration instance to create
|
||||
* @param path Path to the on-disk file to open
|
||||
* @return 0 on success, GIT_ENOTFOUND when the file doesn't exist
|
||||
* or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path);
|
||||
|
||||
/**
|
||||
* Build a single-level focused config object from a multi-level one.
|
||||
*
|
||||
* The returned config object can be used to perform get/set/delete operations
|
||||
* on a single specific level.
|
||||
*
|
||||
* Getting several times the same level from the same parent multi-level config
|
||||
* will return different config instances, but containing the same config_file
|
||||
* instance.
|
||||
*
|
||||
* @param out The configuration instance to create
|
||||
* @param parent Multi-level config to search for the given level
|
||||
* @param level Configuration level to search for
|
||||
* @return 0, GIT_ENOTFOUND if the passed level cannot be found in the
|
||||
* multi-level parent config, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_level(
|
||||
git_config **out,
|
||||
const git_config *parent,
|
||||
unsigned int level);
|
||||
|
||||
/**
|
||||
* Reload changed config files
|
||||
*
|
||||
* A config file may be changed on disk out from under the in-memory
|
||||
* config object. This function causes us to look for files that have
|
||||
* been modified since we last loaded them and refresh the config with
|
||||
* the latest information.
|
||||
*
|
||||
* @param cfg The configuration to refresh
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path);
|
||||
GIT_EXTERN(int) git_config_refresh(git_config *cfg);
|
||||
|
||||
/**
|
||||
* Free the configuration and its associated memory and files
|
||||
@ -174,25 +262,49 @@ GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path);
|
||||
*/
|
||||
GIT_EXTERN(void) git_config_free(git_config *cfg);
|
||||
|
||||
/**
|
||||
* Get the git_config_entry of a config variable.
|
||||
*
|
||||
* The git_config_entry is owned by the config and should not be freed by the
|
||||
* user.
|
||||
|
||||
* @param out pointer to the variable git_config_entry
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_entry(
|
||||
const git_config_entry **out,
|
||||
const git_config *cfg,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of an integer config variable.
|
||||
*
|
||||
* All config files will be looked into, in the order of their
|
||||
* defined level. A higher level means a higher priority. The
|
||||
* first occurence of the variable will be returned here.
|
||||
*
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_int32(int32_t *out, git_config *cfg, const char *name);
|
||||
GIT_EXTERN(int) git_config_get_int32(int32_t *out, const git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a long integer config variable.
|
||||
*
|
||||
* All config files will be looked into, in the order of their
|
||||
* defined level. A higher level means a higher priority. The
|
||||
* first occurrence of the variable will be returned here.
|
||||
*
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *name);
|
||||
GIT_EXTERN(int) git_config_get_int64(int64_t *out, const git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a boolean config variable.
|
||||
@ -200,12 +312,16 @@ GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *
|
||||
* This function uses the usual C convention of 0 being false and
|
||||
* anything else true.
|
||||
*
|
||||
* All config files will be looked into, in the order of their
|
||||
* defined level. A higher level means a higher priority. The
|
||||
* first occurrence of the variable will be returned here.
|
||||
*
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name);
|
||||
GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a string config variable.
|
||||
@ -213,12 +329,16 @@ GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name)
|
||||
* The string is owned by the variable and should not be freed by the
|
||||
* user.
|
||||
*
|
||||
* All config files will be looked into, in the order of their
|
||||
* defined level. A higher level means a higher priority. The
|
||||
* first occurrence of the variable will be returned here.
|
||||
*
|
||||
* @param out pointer to the variable's value
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const char *name);
|
||||
GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get each value of a multivar.
|
||||
@ -232,10 +352,11 @@ GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const c
|
||||
* @param fn the function to be called on each value of the variable
|
||||
* @param data opaque pointer to pass to the callback
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const char *regexp, int (*fn)(const char *, void *), void *data);
|
||||
GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload);
|
||||
|
||||
/**
|
||||
* Set the value of an integer config variable.
|
||||
* Set the value of an integer config variable in the config file
|
||||
* with the highest level (usually the local one).
|
||||
*
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
@ -245,7 +366,8 @@ GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const
|
||||
GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value);
|
||||
|
||||
/**
|
||||
* Set the value of a long integer config variable.
|
||||
* Set the value of a long integer config variable in the config file
|
||||
* with the highest level (usually the local one).
|
||||
*
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
@ -255,7 +377,8 @@ GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t
|
||||
GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value);
|
||||
|
||||
/**
|
||||
* Set the value of a boolean config variable.
|
||||
* Set the value of a boolean config variable in the config file
|
||||
* with the highest level (usually the local one).
|
||||
*
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
@ -265,7 +388,8 @@ GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t
|
||||
GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value);
|
||||
|
||||
/**
|
||||
* Set the value of a string config variable.
|
||||
* Set the value of a string config variable in the config file
|
||||
* with the highest level (usually the local one).
|
||||
*
|
||||
* A copy of the string is made and the user is free to use it
|
||||
* afterwards.
|
||||
@ -277,9 +401,8 @@ GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value);
|
||||
|
||||
|
||||
/**
|
||||
* Set a multivar
|
||||
* Set a multivar in the local config file.
|
||||
*
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
@ -289,12 +412,13 @@ GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const c
|
||||
GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value);
|
||||
|
||||
/**
|
||||
* Delete a config variable
|
||||
* Delete a config variable from the config file
|
||||
* with the highest level (usually the local one).
|
||||
*
|
||||
* @param cfg the configuration
|
||||
* @param name the variable to delete
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name);
|
||||
GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Perform an operation on each config variable.
|
||||
@ -302,18 +426,36 @@ GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name);
|
||||
* The callback receives the normalized name and value of each variable
|
||||
* in the config backend, and the data pointer passed to this function.
|
||||
* As soon as one of the callback functions returns something other than 0,
|
||||
* this function returns that value.
|
||||
* this function stops iterating and returns `GIT_EUSER`.
|
||||
*
|
||||
* @param cfg where to get the variables from
|
||||
* @param callback the function to call on each variable
|
||||
* @param payload the data to pass to the callback
|
||||
* @return 0 or the return value of the callback which didn't return 0
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_foreach(
|
||||
git_config *cfg,
|
||||
int (*callback)(const char *var_name, const char *value, void *payload),
|
||||
const git_config *cfg,
|
||||
git_config_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Perform an operation on each config variable matching a regular expression.
|
||||
*
|
||||
* This behaviors like `git_config_foreach` with an additional filter of a
|
||||
* regular expression that filters which config keys are passed to the
|
||||
* callback.
|
||||
*
|
||||
* @param cfg where to get the variables from
|
||||
* @param regexp regular expression to match against config names
|
||||
* @param callback the function to call on each variable
|
||||
* @param payload the data to pass to the callback
|
||||
* @return 0 or the return value of the callback which didn't return 0
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_foreach_match(
|
||||
const git_config *cfg,
|
||||
const char *regexp,
|
||||
git_config_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Query the value of a config variable and return it mapped to
|
||||
@ -324,7 +466,7 @@ GIT_EXTERN(int) git_config_foreach(
|
||||
*
|
||||
* A mapping array looks as follows:
|
||||
*
|
||||
* git_cvar_map autocrlf_mapping[3] = {
|
||||
* git_cvar_map autocrlf_mapping[] = {
|
||||
* {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
|
||||
* {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
|
||||
* {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT},
|
||||
@ -349,7 +491,63 @@ GIT_EXTERN(int) git_config_foreach(
|
||||
* @param map_n number of mapping objects in `maps`
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_mapped(int *out, git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n);
|
||||
GIT_EXTERN(int) git_config_get_mapped(
|
||||
int *out,
|
||||
const git_config *cfg,
|
||||
const char *name,
|
||||
const git_cvar_map *maps,
|
||||
size_t map_n);
|
||||
|
||||
/**
|
||||
* Maps a string value to an integer constant
|
||||
*
|
||||
* @param out place to store the result of the parsing
|
||||
* @param maps array of `git_cvar_map` objects specifying the possible mappings
|
||||
* @param map_n number of mapping objects in `maps`
|
||||
* @param value value to parse
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_lookup_map_value(
|
||||
int *out,
|
||||
const git_cvar_map *maps,
|
||||
size_t map_n,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
* Parse a string value as a bool.
|
||||
*
|
||||
* Valid values for true are: 'true', 'yes', 'on', 1 or any
|
||||
* number different from 0
|
||||
* Valid values for false are: 'false', 'no', 'off', 0
|
||||
*
|
||||
* @param out place to store the result of the parsing
|
||||
* @param value value to parse
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value);
|
||||
|
||||
/**
|
||||
* Parse a string value as an int32.
|
||||
*
|
||||
* An optional value suffix of 'k', 'm', or 'g' will
|
||||
* cause the value to be multiplied by 1024, 1048576,
|
||||
* or 1073741824 prior to output.
|
||||
*
|
||||
* @param out place to store the result of the parsing
|
||||
* @param value value to parse
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value);
|
||||
|
||||
/**
|
||||
* Parse a string value as an int64.
|
||||
*
|
||||
* An optional value suffix of 'k', 'm', or 'g' will
|
||||
* cause the value to be multiplied by 1024, 1048576,
|
||||
* or 1073741824 prior to output.
|
||||
*
|
||||
* @param out place to store the result of the parsing
|
||||
* @param value value to parse
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
|
||||
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
53
include/git2/cred_helpers.h
Normal file
53
include/git2/cred_helpers.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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_git_cred_helpers_h__
|
||||
#define INCLUDE_git_cred_helpers_h__
|
||||
|
||||
#include "git2/transport.h"
|
||||
|
||||
/**
|
||||
* @file git2/cred_helpers.h
|
||||
* @brief Utility functions for credential management
|
||||
* @defgroup git_cred_helpers credential management helpers
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Payload for git_cred_stock_userpass_plaintext.
|
||||
*/
|
||||
typedef struct git_cred_userpass_payload {
|
||||
char *username;
|
||||
char *password;
|
||||
} git_cred_userpass_payload;
|
||||
|
||||
|
||||
/**
|
||||
* Stock callback usable as a git_cred_acquire_cb. This calls
|
||||
* git_cred_userpass_plaintext_new unless the protocol has not specified
|
||||
* GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type.
|
||||
*
|
||||
* @param cred The newly created credential object.
|
||||
* @param url The resource for which we are demanding a credential.
|
||||
* @param username_from_url The username that was embedded in a "user@host"
|
||||
* remote url, or NULL if not included.
|
||||
* @param allowed_types A bitmask stating which cred types are OK to return.
|
||||
* @param payload The payload provided when specifying this callback. (This is
|
||||
* interpreted as a `git_cred_userpass_payload*`.)
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_userpass(
|
||||
git_cred **cred,
|
||||
const char *url,
|
||||
const char *user_from_url,
|
||||
unsigned int allowed_types,
|
||||
void *payload);
|
||||
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -17,43 +17,6 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
#ifdef GIT_OLD_ERRORS
|
||||
enum {
|
||||
GIT_SUCCESS = 0,
|
||||
GIT_ENOTOID = -2,
|
||||
GIT_ENOTFOUND = -3,
|
||||
GIT_ENOMEM = -4,
|
||||
GIT_EOSERR = -5,
|
||||
GIT_EOBJTYPE = -6,
|
||||
GIT_ENOTAREPO = -7,
|
||||
GIT_EINVALIDTYPE = -8,
|
||||
GIT_EMISSINGOBJDATA = -9,
|
||||
GIT_EPACKCORRUPTED = -10,
|
||||
GIT_EFLOCKFAIL = -11,
|
||||
GIT_EZLIB = -12,
|
||||
GIT_EBUSY = -13,
|
||||
GIT_EBAREINDEX = -14,
|
||||
GIT_EINVALIDREFNAME = -15,
|
||||
GIT_EREFCORRUPTED = -16,
|
||||
GIT_ETOONESTEDSYMREF = -17,
|
||||
GIT_EPACKEDREFSCORRUPTED = -18,
|
||||
GIT_EINVALIDPATH = -19,
|
||||
GIT_EREVWALKOVER = -20,
|
||||
GIT_EINVALIDREFSTATE = -21,
|
||||
GIT_ENOTIMPLEMENTED = -22,
|
||||
GIT_EEXISTS = -23,
|
||||
GIT_EOVERFLOW = -24,
|
||||
GIT_ENOTNUM = -25,
|
||||
GIT_ESTREAM = -26,
|
||||
GIT_EINVALIDARGS = -27,
|
||||
GIT_EOBJCORRUPTED = -28,
|
||||
GIT_EAMBIGUOUS = -29,
|
||||
GIT_EPASSTHROUGH = -30,
|
||||
GIT_ENOMATCH = -31,
|
||||
GIT_ESHORTBUFFER = -32,
|
||||
};
|
||||
#endif
|
||||
|
||||
/** Generic return codes */
|
||||
enum {
|
||||
GIT_OK = 0,
|
||||
@ -62,9 +25,16 @@ enum {
|
||||
GIT_EEXISTS = -4,
|
||||
GIT_EAMBIGUOUS = -5,
|
||||
GIT_EBUFS = -6,
|
||||
GIT_EUSER = -7,
|
||||
GIT_EBAREREPO = -8,
|
||||
GIT_EORPHANEDHEAD = -9,
|
||||
GIT_EUNMERGED = -10,
|
||||
GIT_ENONFASTFORWARD = -11,
|
||||
GIT_EINVALIDSPEC = -12,
|
||||
GIT_EMERGECONFLICT = -13,
|
||||
|
||||
GIT_PASSTHROUGH = -30,
|
||||
GIT_REVWALKOVER = -31,
|
||||
GIT_ITEROVER = -31,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -72,6 +42,7 @@ typedef struct {
|
||||
int klass;
|
||||
} git_error;
|
||||
|
||||
/** Error classes */
|
||||
typedef enum {
|
||||
GITERR_NOMEMORY,
|
||||
GITERR_OS,
|
||||
@ -88,6 +59,13 @@ typedef enum {
|
||||
GITERR_TAG,
|
||||
GITERR_TREE,
|
||||
GITERR_INDEXER,
|
||||
GITERR_SSL,
|
||||
GITERR_SUBMODULE,
|
||||
GITERR_THREAD,
|
||||
GITERR_STASH,
|
||||
GITERR_CHECKOUT,
|
||||
GITERR_FETCHHEAD,
|
||||
GITERR_MERGE,
|
||||
} git_error_t;
|
||||
|
||||
/**
|
||||
@ -103,6 +81,40 @@ GIT_EXTERN(const git_error *) giterr_last(void);
|
||||
*/
|
||||
GIT_EXTERN(void) giterr_clear(void);
|
||||
|
||||
/**
|
||||
* Set the error message string for this thread.
|
||||
*
|
||||
* This function is public so that custom ODB backends and the like can
|
||||
* relay an error message through libgit2. Most regular users of libgit2
|
||||
* will never need to call this function -- actually, calling it in most
|
||||
* circumstances (for example, calling from within a callback function)
|
||||
* will just end up having the value overwritten by libgit2 internals.
|
||||
*
|
||||
* This error message is stored in thread-local storage and only applies
|
||||
* to the particular thread that this libgit2 call is made from.
|
||||
*
|
||||
* NOTE: Passing the `error_class` as GITERR_OS has a special behavior: we
|
||||
* attempt to append the system default error message for the last OS error
|
||||
* that occurred and then clear the last error. The specific implementation
|
||||
* of looking up and clearing this last OS error will vary by platform.
|
||||
*
|
||||
* @param error_class One of the `git_error_t` enum above describing the
|
||||
* general subsystem that is responsible for the error.
|
||||
* @param message The formatted error message to keep
|
||||
*/
|
||||
GIT_EXTERN(void) giterr_set_str(int error_class, const char *string);
|
||||
|
||||
/**
|
||||
* Set the error message to a special value for memory allocation failure.
|
||||
*
|
||||
* The normal `giterr_set_str()` function attempts to `strdup()` the string
|
||||
* that is passed in. This is not a good idea when the error in question
|
||||
* is a memory allocation failure. That circumstance has a special setter
|
||||
* function that sets the error string to a known and statically allocated
|
||||
* internal value.
|
||||
*/
|
||||
GIT_EXTERN(void) giterr_set_oom(void);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
41
include/git2/graph.h
Normal file
41
include/git2/graph.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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_git_graph_h__
|
||||
#define INCLUDE_git_graph_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
|
||||
/**
|
||||
* @file git2/graph.h
|
||||
* @brief Git graph traversal routines
|
||||
* @defgroup git_revwalk Git graph traversal routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Count the number of unique commits between two commit objects
|
||||
*
|
||||
* There is no need for branches containing the commits to have any
|
||||
* upstream relationship, but it helps to think of one as a branch and
|
||||
* the other as its upstream, the `ahead` and `behind` values will be
|
||||
* what git would report for the branches.
|
||||
*
|
||||
* @param ahead number of unique from commits in `upstream`
|
||||
* @param behind number of unique from commits in `local`
|
||||
* @param repo the repository where the commits exist
|
||||
* @param local the commit for local
|
||||
* @param upstream the commit for upstream
|
||||
*/
|
||||
GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
78
include/git2/ignore.h
Normal file
78
include/git2/ignore.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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_git_ignore_h__
|
||||
#define INCLUDE_git_ignore_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Add ignore rules for a repository.
|
||||
*
|
||||
* Excludesfile rules (i.e. .gitignore rules) are generally read from
|
||||
* .gitignore files in the repository tree or from a shared system file
|
||||
* only if a "core.excludesfile" config value is set. The library also
|
||||
* keeps a set of per-repository internal ignores that can be configured
|
||||
* in-memory and will not persist. This function allows you to add to
|
||||
* that internal rules list.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* error = git_ignore_add_rule(myrepo, "*.c\ndir/\nFile with space\n");
|
||||
*
|
||||
* This would add three rules to the ignores.
|
||||
*
|
||||
* @param repo The repository to add ignore rules to.
|
||||
* @param rules Text of rules, a la the contents of a .gitignore file.
|
||||
* It is okay to have multiple rules in the text; if so,
|
||||
* each rule should be terminated with a newline.
|
||||
* @return 0 on success
|
||||
*/
|
||||
GIT_EXTERN(int) git_ignore_add_rule(
|
||||
git_repository *repo,
|
||||
const char *rules);
|
||||
|
||||
/**
|
||||
* Clear ignore rules that were explicitly added.
|
||||
*
|
||||
* Resets to the default internal ignore rules. This will not turn off
|
||||
* rules in .gitignore files that actually exist in the filesystem.
|
||||
*
|
||||
* The default internal ignores ignore ".", ".." and ".git" entries.
|
||||
*
|
||||
* @param repo The repository to remove ignore rules from.
|
||||
* @return 0 on success
|
||||
*/
|
||||
GIT_EXTERN(int) git_ignore_clear_internal_rules(
|
||||
git_repository *repo);
|
||||
|
||||
/**
|
||||
* Test if the ignore rules apply to a given path.
|
||||
*
|
||||
* This function checks the ignore rules to see if they would apply to the
|
||||
* given file. This indicates if the file would be ignored regardless of
|
||||
* whether the file is already in the index or committed to the repository.
|
||||
*
|
||||
* One way to think of this is if you were to do "git add ." on the
|
||||
* directory containing the file, would it be added or not?
|
||||
*
|
||||
* @param ignored boolean returning 0 if the file is not ignored, 1 if it is
|
||||
* @param repo a repository object
|
||||
* @param path the file to check ignores for, relative to the repo's workdir.
|
||||
* @return 0 if ignore rules could be processed for the file (regardless
|
||||
* of whether it exists or not), or an error < 0 if they could not.
|
||||
*/
|
||||
GIT_EXTERN(int) git_ignore_path_is_ignored(
|
||||
int *ignored,
|
||||
git_repository *repo,
|
||||
const char *path);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -8,6 +8,7 @@
|
||||
#define INCLUDE_git_index_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "indexer.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
|
||||
@ -20,10 +21,10 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
#define GIT_IDXENTRY_NAMEMASK (0x0fff)
|
||||
#define GIT_IDXENTRY_NAMEMASK (0x0fff)
|
||||
#define GIT_IDXENTRY_STAGEMASK (0x3000)
|
||||
#define GIT_IDXENTRY_EXTENDED (0x4000)
|
||||
#define GIT_IDXENTRY_VALID (0x8000)
|
||||
#define GIT_IDXENTRY_EXTENDED (0x4000)
|
||||
#define GIT_IDXENTRY_VALID (0x8000)
|
||||
#define GIT_IDXENTRY_STAGESHIFT 12
|
||||
|
||||
/*
|
||||
@ -33,26 +34,26 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* In-memory only flags:
|
||||
*/
|
||||
#define GIT_IDXENTRY_UPDATE (1 << 0)
|
||||
#define GIT_IDXENTRY_REMOVE (1 << 1)
|
||||
#define GIT_IDXENTRY_UPTODATE (1 << 2)
|
||||
#define GIT_IDXENTRY_ADDED (1 << 3)
|
||||
#define GIT_IDXENTRY_UPDATE (1 << 0)
|
||||
#define GIT_IDXENTRY_REMOVE (1 << 1)
|
||||
#define GIT_IDXENTRY_UPTODATE (1 << 2)
|
||||
#define GIT_IDXENTRY_ADDED (1 << 3)
|
||||
|
||||
#define GIT_IDXENTRY_HASHED (1 << 4)
|
||||
#define GIT_IDXENTRY_UNHASHED (1 << 5)
|
||||
#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */
|
||||
#define GIT_IDXENTRY_CONFLICTED (1 << 7)
|
||||
#define GIT_IDXENTRY_HASHED (1 << 4)
|
||||
#define GIT_IDXENTRY_UNHASHED (1 << 5)
|
||||
#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */
|
||||
#define GIT_IDXENTRY_CONFLICTED (1 << 7)
|
||||
|
||||
#define GIT_IDXENTRY_UNPACKED (1 << 8)
|
||||
#define GIT_IDXENTRY_UNPACKED (1 << 8)
|
||||
#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
|
||||
|
||||
/*
|
||||
* Extended on-disk flags:
|
||||
*/
|
||||
#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
|
||||
#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
|
||||
#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
|
||||
#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
|
||||
/* GIT_IDXENTRY_EXTENDED2 is for future extension */
|
||||
#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
|
||||
#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
|
||||
|
||||
#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
|
||||
|
||||
@ -83,12 +84,26 @@ typedef struct git_index_entry {
|
||||
char *path;
|
||||
} git_index_entry;
|
||||
|
||||
/** Representation of an unmerged file entry in the index. */
|
||||
typedef struct git_index_entry_unmerged {
|
||||
/** Representation of a resolve undo entry in the index. */
|
||||
typedef struct git_index_reuc_entry {
|
||||
unsigned int mode[3];
|
||||
git_oid oid[3];
|
||||
char *path;
|
||||
} git_index_entry_unmerged;
|
||||
} git_index_reuc_entry;
|
||||
|
||||
/** Capabilities of system that affect index actions. */
|
||||
enum {
|
||||
GIT_INDEXCAP_IGNORE_CASE = 1,
|
||||
GIT_INDEXCAP_NO_FILEMODE = 2,
|
||||
GIT_INDEXCAP_NO_SYMLINKS = 4,
|
||||
GIT_INDEXCAP_FROM_OWNER = ~0u
|
||||
};
|
||||
|
||||
/** @name Index File Functions
|
||||
*
|
||||
* These functions work on the index file itself.
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* Create a new bare Git index object as a memory representation
|
||||
@ -104,20 +119,24 @@ typedef struct git_index_entry_unmerged {
|
||||
*
|
||||
* The index must be freed once it's no longer in use.
|
||||
*
|
||||
* @param index the pointer for the new index
|
||||
* @param out the pointer for the new index
|
||||
* @param index_path the path to the index file in disk
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path);
|
||||
GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path);
|
||||
|
||||
/**
|
||||
* Clear the contents (all the entries) of an index object.
|
||||
* This clears the index object in memory; changes must be manually
|
||||
* written to disk for them to take effect.
|
||||
* Create an in-memory index object.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* This index object cannot be read/written to the filesystem,
|
||||
* but may be used to perform in-memory index operations.
|
||||
*
|
||||
* The index must be freed once it's no longer in use.
|
||||
*
|
||||
* @param out the pointer for the new index
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(void) git_index_clear(git_index *index);
|
||||
GIT_EXTERN(int) git_index_new(git_index **out);
|
||||
|
||||
/**
|
||||
* Free an existing index object.
|
||||
@ -126,6 +145,35 @@ GIT_EXTERN(void) git_index_clear(git_index *index);
|
||||
*/
|
||||
GIT_EXTERN(void) git_index_free(git_index *index);
|
||||
|
||||
/**
|
||||
* Get the repository this index relates to
|
||||
*
|
||||
* @param index The index
|
||||
* @return A pointer to the repository
|
||||
*/
|
||||
GIT_EXTERN(git_repository *) git_index_owner(const git_index *index);
|
||||
|
||||
/**
|
||||
* Read index capabilities flags.
|
||||
*
|
||||
* @param index An existing index object
|
||||
* @return A combination of GIT_INDEXCAP values
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_index_caps(const git_index *index);
|
||||
|
||||
/**
|
||||
* Set index capabilities flags.
|
||||
*
|
||||
* If you pass `GIT_INDEXCAP_FROM_OWNER` for the caps, then the
|
||||
* capabilities will be read from the config of the owner object,
|
||||
* looking at `core.ignorecase`, `core.filemode`, `core.symlinks`.
|
||||
*
|
||||
* @param index An existing index object
|
||||
* @param caps A combination of GIT_INDEXCAP values
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_set_caps(git_index *index, unsigned int caps);
|
||||
|
||||
/**
|
||||
* Update the contents of an existing index object in memory
|
||||
* by reading from the hard disk.
|
||||
@ -145,24 +193,176 @@ GIT_EXTERN(int) git_index_read(git_index *index);
|
||||
GIT_EXTERN(int) git_index_write(git_index *index);
|
||||
|
||||
/**
|
||||
* Find the first index of any entries which point to given
|
||||
* path in the Git index.
|
||||
* Read a tree into the index file with stats
|
||||
*
|
||||
* The current index contents will be replaced by the specified tree.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param tree tree to read
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_read_tree(git_index *index, const git_tree *tree);
|
||||
|
||||
/**
|
||||
* Write the index as a tree
|
||||
*
|
||||
* This method will scan the index and write a representation
|
||||
* of its current state back to disk; it recursively creates
|
||||
* tree objects for each of the subtrees stored in the index,
|
||||
* but only returns the OID of the root tree. This is the OID
|
||||
* that can be used e.g. to create a commit.
|
||||
*
|
||||
* The index instance cannot be bare, and needs to be associated
|
||||
* to an existing repository.
|
||||
*
|
||||
* The index must not contain any file in conflict.
|
||||
*
|
||||
* @param out Pointer where to store the OID of the written tree
|
||||
* @param index Index to write
|
||||
* @return 0 on success, GIT_EUNMERGED when the index is not clean
|
||||
* or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index);
|
||||
|
||||
/**
|
||||
* Write the index as a tree to the given repository
|
||||
*
|
||||
* This method will do the same as `git_index_write_tree`, but
|
||||
* letting the user choose the repository where the tree will
|
||||
* be written.
|
||||
*
|
||||
* The index must not contain any file in conflict.
|
||||
*
|
||||
* @param out Pointer where to store OID of the the written tree
|
||||
* @param index Index to write
|
||||
* @param repo Repository where to write the tree
|
||||
* @return 0 on success, GIT_EUNMERGED when the index is not clean
|
||||
* or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_write_tree_to(git_oid *out, git_index *index, git_repository *repo);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** @name Raw Index Entry Functions
|
||||
*
|
||||
* These functions work on index entries, and allow for raw manipulation
|
||||
* of the entries.
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/* Index entry manipulation */
|
||||
|
||||
/**
|
||||
* Get the count of entries currently in the index
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return integer of count of current entries
|
||||
*/
|
||||
GIT_EXTERN(size_t) git_index_entrycount(const git_index *index);
|
||||
|
||||
/**
|
||||
* Clear the contents (all the entries) of an index object.
|
||||
* This clears the index object in memory; changes must be manually
|
||||
* written to disk for them to take effect.
|
||||
*
|
||||
* @param index an existing index object
|
||||
*/
|
||||
GIT_EXTERN(void) git_index_clear(git_index *index);
|
||||
|
||||
/**
|
||||
* Get a pointer to one of the entries in the index
|
||||
*
|
||||
* The values of this entry can be modified (except the path)
|
||||
* and the changes will be written back to disk on the next
|
||||
* write() call.
|
||||
*
|
||||
* The entry should not be freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param n the position of the entry
|
||||
* @return a pointer to the entry; NULL if out of bounds
|
||||
*/
|
||||
GIT_EXTERN(const git_index_entry *) git_index_get_byindex(
|
||||
git_index *index, size_t n);
|
||||
|
||||
/**
|
||||
* Get a pointer to one of the entries in the index
|
||||
*
|
||||
* The values of this entry can be modified (except the path)
|
||||
* and the changes will be written back to disk on the next
|
||||
* write() call.
|
||||
*
|
||||
* The entry should not be freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
* @return an index >= 0 if found, -1 otherwise
|
||||
* @param stage stage to search
|
||||
* @return a pointer to the entry; NULL if it was not found
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_find(git_index *index, const char *path);
|
||||
GIT_EXTERN(const git_index_entry *) git_index_get_bypath(
|
||||
git_index *index, const char *path, int stage);
|
||||
|
||||
/**
|
||||
* Remove all entries with equal path except last added
|
||||
* Remove an entry from the index
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
* @param stage stage to search
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(void) git_index_uniq(git_index *index);
|
||||
GIT_EXTERN(int) git_index_remove(git_index *index, const char *path, int stage);
|
||||
|
||||
/**
|
||||
* Add or update an index entry from a file in disk
|
||||
* Remove all entries from the index under a given directory
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param dir container directory path
|
||||
* @param stage stage to search
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_remove_directory(
|
||||
git_index *index, const char *dir, int stage);
|
||||
|
||||
/**
|
||||
* Add or update an index entry from an in-memory struct
|
||||
*
|
||||
* If a previous index entry exists that has the same path and stage
|
||||
* as the given 'source_entry', it will be replaced. Otherwise, the
|
||||
* 'source_entry' will be added.
|
||||
*
|
||||
* A full copy (including the 'path' string) of the given
|
||||
* 'source_entry' will be inserted on the index.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_entry);
|
||||
|
||||
/**
|
||||
* Return the stage number from a git index entry
|
||||
*
|
||||
* This entry is calculated from the entry's flag
|
||||
* attribute like this:
|
||||
*
|
||||
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
|
||||
*
|
||||
* @param entry The entry
|
||||
* @returns the stage number
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** @name Workdir Index Entry Functions
|
||||
*
|
||||
* These functions work on index entries specifically in the working
|
||||
* directory (ie, stage 0).
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* Add or update an index entry from a file on disk
|
||||
*
|
||||
* The file `path` must be relative to the repository's
|
||||
* working folder and must be readable.
|
||||
@ -173,148 +373,206 @@ GIT_EXTERN(void) git_index_uniq(git_index *index);
|
||||
* at gitignore rules. Those rules can be evaluated through
|
||||
* the git_status APIs (in status.h) before calling this.
|
||||
*
|
||||
* If this file currently is the result of a merge conflict, this
|
||||
* file will no longer be marked as conflicting. The data about
|
||||
* the conflict will be moved to the "resolve undo" (REUC) section.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path filename to add
|
||||
* @param stage stage for the entry
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
|
||||
GIT_EXTERN(int) git_index_add_bypath(git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Add or update an index entry from an in-memory struct
|
||||
*
|
||||
* A full copy (including the 'path' string) of the given
|
||||
* 'source_entry' will be inserted on the index.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry);
|
||||
|
||||
/**
|
||||
* Add (append) an index entry from a file in disk
|
||||
*
|
||||
* A new entry will always be inserted into the index;
|
||||
* if the index already contains an entry for such
|
||||
* path, the old entry will **not** be replaced.
|
||||
* Remove an index entry corresponding to a file on disk
|
||||
*
|
||||
* The file `path` must be relative to the repository's
|
||||
* working folder and must be readable.
|
||||
* working folder. It may exist.
|
||||
*
|
||||
* If this file currently is the result of a merge conflict, this
|
||||
* file will no longer be marked as conflicting. The data about
|
||||
* the conflict will be moved to the "resolve undo" (REUC) section.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path filename to remove
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_remove_bypath(git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Find the first position of any entries which point to given
|
||||
* path in the Git index.
|
||||
*
|
||||
* @param at_pos the address to which the position of the index entry is written (optional)
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
* @return a zero-based position in the index if found;
|
||||
* GIT_ENOTFOUND otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** @name Conflict Index Entry Functions
|
||||
*
|
||||
* These functions work on conflict index entries specifically (ie, stages 1-3)
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* Add or update index entries to represent a conflict
|
||||
*
|
||||
* The entries are the entries from the tree included in the merge. Any
|
||||
* entry may be null to indicate that that file was not present in the
|
||||
* trees during the merge. For example, ancestor_entry may be NULL to
|
||||
* indicate that a file was added in both branches and must be resolved.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param ancestor_entry the entry data for the ancestor of the conflict
|
||||
* @param our_entry the entry data for our side of the merge conflict
|
||||
* @param their_entry the entry data for their side of the merge conflict
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_conflict_add(
|
||||
git_index *index,
|
||||
const git_index_entry *ancestor_entry,
|
||||
const git_index_entry *our_entry,
|
||||
const git_index_entry *their_entry);
|
||||
|
||||
/**
|
||||
* Get the index entries that represent a conflict of a single file.
|
||||
*
|
||||
* The values of this entry can be modified (except the paths)
|
||||
* and the changes will be written back to disk on the next
|
||||
* write() call.
|
||||
*
|
||||
* @param ancestor_out Pointer to store the ancestor entry
|
||||
* @param our_out Pointer to store the our entry
|
||||
* @param their_out Pointer to store the their entry
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_conflict_get(git_index_entry **ancestor_out, git_index_entry **our_out, git_index_entry **their_out, git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Removes the index entries that represent a conflict of a single file.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path to search
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_conflict_remove(git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Remove all conflicts in the index (entries with a stage greater than 0.)
|
||||
*
|
||||
* @param index an existing index object
|
||||
*/
|
||||
GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index);
|
||||
|
||||
/**
|
||||
* Determine if the index contains entries representing file conflicts.
|
||||
*
|
||||
* @return 1 if at least one conflict is found, 0 otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_has_conflicts(const git_index *index);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** @name Resolve Undo (REUC) index entry manipulation.
|
||||
*
|
||||
* These functions work on the Resolve Undo index extension and contains
|
||||
* data about the original files that led to a merge conflict.
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* Get the count of resolve undo entries currently in the index.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return integer of count of current resolve undo entries
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_index_reuc_entrycount(git_index *index);
|
||||
|
||||
/**
|
||||
* Finds the resolve undo entry that points to the given path in the Git
|
||||
* index.
|
||||
*
|
||||
* @param at_pos the address to which the position of the reuc entry is written (optional)
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
* @return 0 if found, < 0 otherwise (GIT_ENOTFOUND)
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_reuc_find(size_t *at_pos, git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Get a resolve undo entry from the index.
|
||||
*
|
||||
* The returned entry is read-only and should not be modified
|
||||
* or freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
* @return the resolve undo entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Get a resolve undo entry from the index.
|
||||
*
|
||||
* The returned entry is read-only and should not be modified
|
||||
* or freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param n the position of the entry
|
||||
* @return a pointer to the resolve undo entry; NULL if out of bounds
|
||||
*/
|
||||
GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n);
|
||||
|
||||
/**
|
||||
* Adds a resolve undo entry for a file based on the given parameters.
|
||||
*
|
||||
* The resolve undo entry contains the OIDs of files that were involved
|
||||
* in a merge conflict after the conflict has been resolved. This allows
|
||||
* conflicts to be re-resolved later.
|
||||
*
|
||||
* If there exists a resolve undo entry for the given path in the index,
|
||||
* it will be removed.
|
||||
*
|
||||
* This method will fail in bare index instances.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path filename to add
|
||||
* @param stage stage for the entry
|
||||
* @param ancestor_mode mode of the ancestor file
|
||||
* @param ancestor_id oid of the ancestor file
|
||||
* @param our_mode mode of our file
|
||||
* @param our_id oid of our file
|
||||
* @param their_mode mode of their file
|
||||
* @param their_id oid of their file
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
|
||||
GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path,
|
||||
int ancestor_mode, git_oid *ancestor_id,
|
||||
int our_mode, git_oid *our_id,
|
||||
int their_mode, git_oid *their_id);
|
||||
|
||||
/**
|
||||
* Add (append) an index entry from an in-memory struct
|
||||
*
|
||||
* A new entry will always be inserted into the index;
|
||||
* if the index already contains an entry for the path
|
||||
* in the `entry` struct, the old entry will **not** be
|
||||
* replaced.
|
||||
*
|
||||
* A full copy (including the 'path' string) of the given
|
||||
* 'source_entry' will be inserted on the index.
|
||||
* Remove an resolve undo entry from the index
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @param n position of the resolve undo entry to remove
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry);
|
||||
GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n);
|
||||
|
||||
/**
|
||||
* Remove an entry from the index
|
||||
* Remove all resolve undo entries from the index
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param position position of the entry to remove
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_remove(git_index *index, int position);
|
||||
GIT_EXTERN(void) git_index_reuc_clear(git_index *index);
|
||||
|
||||
|
||||
/**
|
||||
* Get a pointer to one of the entries in the index
|
||||
*
|
||||
* This entry can be modified, and the changes will be written
|
||||
* back to disk on the next write() call.
|
||||
*
|
||||
* The entry should not be freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param n the position of the entry
|
||||
* @return a pointer to the entry; NULL if out of bounds
|
||||
*/
|
||||
GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, unsigned int n);
|
||||
|
||||
/**
|
||||
* Get the count of entries currently in the index
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return integer of count of current entries
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index);
|
||||
|
||||
/**
|
||||
* Get the count of unmerged entries currently in the index
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return integer of count of current unmerged entries
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_index_entrycount_unmerged(git_index *index);
|
||||
|
||||
/**
|
||||
* Get an unmerged entry from the index.
|
||||
*
|
||||
* The returned entry is read-only and should not be modified
|
||||
* of freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param path path to search
|
||||
* @return the unmerged entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_bypath(git_index *index, const char *path);
|
||||
|
||||
/**
|
||||
* Get an unmerged entry from the index.
|
||||
*
|
||||
* The returned entry is read-only and should not be modified
|
||||
* of freed by the caller.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param n the position of the entry
|
||||
* @return a pointer to the unmerged entry; NULL if out of bounds
|
||||
*/
|
||||
GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_index *index, unsigned int n);
|
||||
|
||||
/**
|
||||
* Return the stage number from a git index entry
|
||||
*
|
||||
* This entry is calculated from the entrie's flag
|
||||
* attribute like this:
|
||||
*
|
||||
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
|
||||
*
|
||||
* @param entry The entry
|
||||
* @returns the stage number
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
|
||||
|
||||
/**
|
||||
* Read a tree into the index file
|
||||
*
|
||||
* The current index contents will be replaced by the specified tree.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param tree tree to read
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree);
|
||||
/**@}*/
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -16,32 +16,48 @@ GIT_BEGIN_DECL
|
||||
* This is passed as the first argument to the callback to allow the
|
||||
* user to see the progress.
|
||||
*/
|
||||
typedef struct git_indexer_stats {
|
||||
unsigned int total;
|
||||
unsigned int processed;
|
||||
} git_indexer_stats;
|
||||
typedef struct git_transfer_progress {
|
||||
unsigned int total_objects;
|
||||
unsigned int indexed_objects;
|
||||
unsigned int received_objects;
|
||||
size_t received_bytes;
|
||||
} git_transfer_progress;
|
||||
|
||||
|
||||
typedef struct git_indexer git_indexer;
|
||||
/**
|
||||
* Type for progress callbacks during indexing. Return a value less than zero
|
||||
* to cancel the transfer.
|
||||
*
|
||||
* @param stats Structure containing information about the state of the transfer
|
||||
* @param payload Payload provided by caller
|
||||
*/
|
||||
typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload);
|
||||
|
||||
typedef struct git_indexer_stream git_indexer_stream;
|
||||
|
||||
/**
|
||||
* Create a new streaming indexer instance
|
||||
*
|
||||
* @param out where to store the inexer instance
|
||||
* @param path to the gitdir (metadata directory)
|
||||
* @param out where to store the indexer instance
|
||||
* @param path to the directory where the packfile should be stored
|
||||
* @param progress_cb function to call with progress information
|
||||
* @param progress_payload payload for the progress callback
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *gitdir);
|
||||
GIT_EXTERN(int) git_indexer_stream_new(
|
||||
git_indexer_stream **out,
|
||||
const char *path,
|
||||
git_transfer_progress_callback progress_cb,
|
||||
void *progress_cb_payload);
|
||||
|
||||
/**
|
||||
* Add data to the indexer
|
||||
*
|
||||
* @param idx the indexer
|
||||
* @param data the data to add
|
||||
* @param size the size of the data
|
||||
* @param size the size of the data in bytes
|
||||
* @param stats stat storage
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats);
|
||||
GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_transfer_progress *stats);
|
||||
|
||||
/**
|
||||
* Finalize the pack and index
|
||||
@ -50,7 +66,7 @@ GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data
|
||||
*
|
||||
* @param idx the indexer
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer_stats *stats);
|
||||
GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_transfer_progress *stats);
|
||||
|
||||
/**
|
||||
* Get the packfile's hash
|
||||
@ -60,7 +76,7 @@ GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer
|
||||
*
|
||||
* @param idx the indexer instance
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_indexer_stream_hash(git_indexer_stream *idx);
|
||||
GIT_EXTERN(const git_oid *) git_indexer_stream_hash(const git_indexer_stream *idx);
|
||||
|
||||
/**
|
||||
* Free the indexer and its resources
|
||||
@ -69,53 +85,6 @@ GIT_EXTERN(const git_oid *) git_indexer_stream_hash(git_indexer_stream *idx);
|
||||
*/
|
||||
GIT_EXTERN(void) git_indexer_stream_free(git_indexer_stream *idx);
|
||||
|
||||
/**
|
||||
* Create a new indexer instance
|
||||
*
|
||||
* @param out where to store the indexer instance
|
||||
* @param packname the absolute filename of the packfile to index
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_new(git_indexer **out, const char *packname);
|
||||
|
||||
/**
|
||||
* Iterate over the objects in the packfile and extract the information
|
||||
*
|
||||
* Indexing a packfile can be very expensive so this function is
|
||||
* expected to be run in a worker thread and the stats used to provide
|
||||
* feedback the user.
|
||||
*
|
||||
* @param idx the indexer instance
|
||||
* @param stats storage for the running state
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_run(git_indexer *idx, git_indexer_stats *stats);
|
||||
|
||||
/**
|
||||
* Write the index file to disk.
|
||||
*
|
||||
* The file will be stored as pack-$hash.idx in the same directory as
|
||||
* the packfile.
|
||||
*
|
||||
* @param idx the indexer instance
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_write(git_indexer *idx);
|
||||
|
||||
/**
|
||||
* Get the packfile's hash
|
||||
*
|
||||
* A packfile's name is derived from the sorted hashing of all object
|
||||
* names. This is only correct after the index has been written to disk.
|
||||
*
|
||||
* @param idx the indexer instance
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_indexer_hash(git_indexer *idx);
|
||||
|
||||
/**
|
||||
* Free the indexer and its resources
|
||||
*
|
||||
* @param idx the indexer to free
|
||||
*/
|
||||
GIT_EXTERN(void) git_indexer_free(git_indexer *idx);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -40,7 +40,11 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if _MSC_VER >= 1600
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
// 7.8 Format conversion of integer types
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -27,8 +27,28 @@ GIT_BEGIN_DECL
|
||||
* @param repo the repository where the commits exist
|
||||
* @param one one of the commits
|
||||
* @param two the other commit
|
||||
* @return Zero on success; GIT_ENOTFOUND or -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_base(git_oid *out, git_repository *repo, git_oid *one, git_oid *two);
|
||||
GIT_EXTERN(int) git_merge_base(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
const git_oid *one,
|
||||
const git_oid *two);
|
||||
|
||||
/**
|
||||
* Find a merge base given a list of commits
|
||||
*
|
||||
* @param out the OID of a merge base considering all the commits
|
||||
* @param repo the repository where the commits exist
|
||||
* @param input_array oids of the commits
|
||||
* @param length The number of commits in the provided `input_array`
|
||||
* @return Zero on success; GIT_ENOTFOUND or -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_base_many(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
const git_oid input_array[],
|
||||
size_t length);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
49
include/git2/message.h
Normal file
49
include/git2/message.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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_git_message_h__
|
||||
#define INCLUDE_git_message_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/message.h
|
||||
* @brief Git message management routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Clean up message from excess whitespace and make sure that the last line
|
||||
* ends with a '\n'.
|
||||
*
|
||||
* Optionally, can remove lines starting with a "#".
|
||||
*
|
||||
* @param out The user-allocated buffer which will be filled with the
|
||||
* cleaned up message. Pass NULL if you just want to get the needed
|
||||
* size of the prettified message as the output value.
|
||||
*
|
||||
* @param out_size Size of the `out` buffer in bytes.
|
||||
*
|
||||
* @param message The message to be prettified.
|
||||
*
|
||||
* @param strip_comments Non-zero to remove lines starting with "#", 0 to
|
||||
* leave them in.
|
||||
*
|
||||
* @return -1 on error, else number of characters in prettified message
|
||||
* including the trailing NUL byte
|
||||
*/
|
||||
GIT_EXTERN(int) git_message_prettify(
|
||||
char *out,
|
||||
size_t out_size,
|
||||
const char *message,
|
||||
int strip_comments);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif /* INCLUDE_git_message_h__ */
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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_net_h__
|
||||
#define INCLUDE_net_h__
|
||||
#ifndef INCLUDE_git_net_h__
|
||||
#define INCLUDE_git_net_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "oid.h"
|
||||
@ -27,15 +27,17 @@ GIT_BEGIN_DECL
|
||||
* gets called.
|
||||
*/
|
||||
|
||||
#define GIT_DIR_FETCH 0
|
||||
#define GIT_DIR_PUSH 1
|
||||
typedef enum {
|
||||
GIT_DIRECTION_FETCH = 0,
|
||||
GIT_DIRECTION_PUSH = 1
|
||||
} git_direction;
|
||||
|
||||
|
||||
/**
|
||||
* Remote head description, given out on `ls` calls.
|
||||
*/
|
||||
struct git_remote_head {
|
||||
int local:1; /* available locally */
|
||||
int local; /* available locally */
|
||||
git_oid oid;
|
||||
git_oid loid;
|
||||
char *name;
|
||||
@ -44,7 +46,7 @@ struct git_remote_head {
|
||||
/**
|
||||
* Callback for listing the remote heads
|
||||
*/
|
||||
typedef int (*git_headlist_cb)(git_remote_head *, void *);
|
||||
typedef int (*git_headlist_cb)(git_remote_head *rhead, void *payload);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -18,20 +18,83 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Callback for git_note_foreach.
|
||||
*
|
||||
* Receives:
|
||||
* - blob_id: Oid of the blob containing the message
|
||||
* - annotated_object_id: Oid of the git object being annotated
|
||||
* - payload: Payload data passed to `git_note_foreach`
|
||||
*/
|
||||
typedef int (*git_note_foreach_cb)(
|
||||
const git_oid *blob_id, const git_oid *annotated_object_id, void *payload);
|
||||
|
||||
/**
|
||||
* note iterator
|
||||
*/
|
||||
typedef struct git_iterator git_note_iterator;
|
||||
|
||||
/**
|
||||
* Creates a new iterator for notes
|
||||
*
|
||||
* The iterator must be freed manually by the user.
|
||||
*
|
||||
* @param out pointer to the iterator
|
||||
* @param repo repository where to look up the note
|
||||
* @param notes_ref canonical name of the reference to use (optional); defaults to
|
||||
* "refs/notes/commits"
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_iterator_new(
|
||||
git_note_iterator **out,
|
||||
git_repository *repo,
|
||||
const char *notes_ref);
|
||||
|
||||
/**
|
||||
* Frees an git_note_iterator
|
||||
*
|
||||
* @param it pointer to the iterator
|
||||
*/
|
||||
GIT_EXTERN(void) git_note_iterator_free(git_note_iterator *it);
|
||||
|
||||
/**
|
||||
* Returns the current item (note_id and annotated_id) and advance the iterator
|
||||
* internally to the next value
|
||||
*
|
||||
* The notes must not be freed manually by the user.
|
||||
*
|
||||
* @param it pointer to the iterator
|
||||
* @param note_id id of blob containing the message
|
||||
* @param annotated_id id of the git object being annotated
|
||||
*
|
||||
* @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code
|
||||
* (negative value)
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_next(
|
||||
git_oid* note_id,
|
||||
git_oid* annotated_id,
|
||||
git_note_iterator *it);
|
||||
|
||||
|
||||
/**
|
||||
* Read the note for an object
|
||||
*
|
||||
* The note must be freed manually by the user.
|
||||
*
|
||||
* @param note the note; NULL in case of error
|
||||
* @param repo the Git repository
|
||||
* @param notes_ref OID reference to use (optional); defaults to "refs/notes/commits"
|
||||
* @param oid OID of the object
|
||||
* @param out pointer to the read note; NULL in case of error
|
||||
* @param repo repository where to look up the note
|
||||
* @param notes_ref canonical name of the reference to use (optional); defaults to
|
||||
* "refs/notes/commits"
|
||||
* @param oid OID of the git object to read the note from
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo,
|
||||
const char *notes_ref, const git_oid *oid);
|
||||
GIT_EXTERN(int) git_note_read(
|
||||
git_note **out,
|
||||
git_repository *repo,
|
||||
const char *notes_ref,
|
||||
const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Get the note message
|
||||
@ -39,7 +102,7 @@ GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo,
|
||||
* @param note
|
||||
* @return the note message
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_note_message(git_note *note);
|
||||
GIT_EXTERN(const char *) git_note_message(const git_note *note);
|
||||
|
||||
|
||||
/**
|
||||
@ -48,42 +111,52 @@ GIT_EXTERN(const char *) git_note_message(git_note *note);
|
||||
* @param note
|
||||
* @return the note object OID
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_note_oid(git_note *note);
|
||||
|
||||
GIT_EXTERN(const git_oid *) git_note_oid(const git_note *note);
|
||||
|
||||
/**
|
||||
* Add a note for an object
|
||||
*
|
||||
* @param oid pointer to store the OID (optional); NULL in case of error
|
||||
* @param repo the Git repository
|
||||
* @param out pointer to store the OID (optional); NULL in case of error
|
||||
* @param repo repository where to store the note
|
||||
* @param author signature of the notes commit author
|
||||
* @param committer signature of the notes commit committer
|
||||
* @param notes_ref OID reference to update (optional); defaults to "refs/notes/commits"
|
||||
* @param oid The OID of the object
|
||||
* @param oid The note to add for object oid
|
||||
* @param notes_ref canonical name of the reference to use (optional);
|
||||
* defaults to "refs/notes/commits"
|
||||
* @param oid OID of the git object to decorate
|
||||
* @param note Content of the note to add for object oid
|
||||
* @param force Overwrite existing note
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_create(git_oid *out, git_repository *repo,
|
||||
git_signature *author, git_signature *committer,
|
||||
const char *notes_ref, const git_oid *oid,
|
||||
const char *note);
|
||||
GIT_EXTERN(int) git_note_create(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
const git_signature *author,
|
||||
const git_signature *committer,
|
||||
const char *notes_ref,
|
||||
const git_oid *oid,
|
||||
const char *note,
|
||||
int force);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the note for an object
|
||||
*
|
||||
* @param repo the Git repository
|
||||
* @param notes_ref OID reference to use (optional); defaults to "refs/notes/commits"
|
||||
* @param repo repository where the note lives
|
||||
* @param notes_ref canonical name of the reference to use (optional);
|
||||
* defaults to "refs/notes/commits"
|
||||
* @param author signature of the notes commit author
|
||||
* @param committer signature of the notes commit committer
|
||||
* @param oid the oid which note's to be removed
|
||||
* @param oid OID of the git object to remove the note from
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_remove(git_repository *repo, const char *notes_ref,
|
||||
git_signature *author, git_signature *committer,
|
||||
const git_oid *oid);
|
||||
GIT_EXTERN(int) git_note_remove(
|
||||
git_repository *repo,
|
||||
const char *notes_ref,
|
||||
const git_signature *author,
|
||||
const git_signature *committer,
|
||||
const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Free a git_note object
|
||||
@ -102,37 +175,27 @@ GIT_EXTERN(void) git_note_free(git_note *note);
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Basic components of a note
|
||||
*
|
||||
* - Oid of the blob containing the message
|
||||
* - Oid of the git object being annotated
|
||||
*/
|
||||
typedef struct {
|
||||
git_oid blob_oid;
|
||||
git_oid annotated_object_oid;
|
||||
} git_note_data;
|
||||
|
||||
/**
|
||||
* Loop over all the notes within a specified namespace
|
||||
* and issue a callback for each one.
|
||||
*
|
||||
* @param repo Repository where to find the notes.
|
||||
*
|
||||
* @param notes_ref OID reference to read from (optional); defaults to "refs/notes/commits".
|
||||
* @param notes_ref Reference to read from (optional); defaults to
|
||||
* "refs/notes/commits".
|
||||
*
|
||||
* @param note_cb Callback to invoke per found annotation.
|
||||
* @param note_cb Callback to invoke per found annotation. Return non-zero
|
||||
* to stop looping.
|
||||
*
|
||||
* @param payload Extra parameter to callback function.
|
||||
*
|
||||
* @return 0 or an error code.
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_foreach(
|
||||
git_repository *repo,
|
||||
const char *notes_ref,
|
||||
int (*note_cb)(git_note_data *note_data, void *payload),
|
||||
void *payload
|
||||
);
|
||||
git_repository *repo,
|
||||
const char *notes_ref,
|
||||
git_note_foreach_cb note_cb,
|
||||
void *payload);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -21,7 +21,7 @@
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Lookup a reference to one of the objects in a repostory.
|
||||
* Lookup a reference to one of the objects in a repository.
|
||||
*
|
||||
* The generated reference is owned by the repository and
|
||||
* should be closed with the `git_object_free` method
|
||||
@ -45,7 +45,7 @@ GIT_EXTERN(int) git_object_lookup(
|
||||
git_otype type);
|
||||
|
||||
/**
|
||||
* Lookup a reference to one of the objects in a repostory,
|
||||
* Lookup a reference to one of the objects in a repository,
|
||||
* given a prefix of its identifier (short id).
|
||||
*
|
||||
* The object obtained will be so that its identifier
|
||||
@ -75,7 +75,7 @@ GIT_EXTERN(int) git_object_lookup_prefix(
|
||||
git_object **object_out,
|
||||
git_repository *repo,
|
||||
const git_oid *id,
|
||||
unsigned int len,
|
||||
size_t len,
|
||||
git_otype type);
|
||||
|
||||
/**
|
||||
@ -114,7 +114,7 @@ GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
|
||||
* This method instructs the library to close an existing
|
||||
* object; note that git_objects are owned and cached by the repository
|
||||
* so the object may or may not be freed after this library call,
|
||||
* depending on how agressive is the caching mechanism used
|
||||
* depending on how aggressive is the caching mechanism used
|
||||
* by the repository.
|
||||
*
|
||||
* IMPORTANT:
|
||||
@ -167,6 +167,36 @@ GIT_EXTERN(int) git_object_typeisloose(git_otype type);
|
||||
*/
|
||||
GIT_EXTERN(size_t) git_object__size(git_otype type);
|
||||
|
||||
/**
|
||||
* Recursively peel an object until an object of the specified type is met.
|
||||
*
|
||||
* The retrieved `peeled` object is owned by the repository and should be
|
||||
* closed with the `git_object_free` method.
|
||||
*
|
||||
* If you pass `GIT_OBJ_ANY` as the target type, then the object will be
|
||||
* peeled until the type changes (e.g. a tag will be chased until the
|
||||
* referenced object is no longer a tag).
|
||||
*
|
||||
* @param peeled Pointer to the peeled git_object
|
||||
* @param object The object to be processed
|
||||
* @param target_type The type of the requested object (GIT_OBJ_COMMIT,
|
||||
* GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY).
|
||||
* @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_object_peel(
|
||||
git_object **peeled,
|
||||
const git_object *object,
|
||||
git_otype target_type);
|
||||
|
||||
/**
|
||||
* Create an in-memory copy of a Git object. The copy must be
|
||||
* explicitly free'd or it will leak.
|
||||
*
|
||||
* @param dest Pointer to store the copy of the object
|
||||
* @param source Original object to copy
|
||||
*/
|
||||
GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -11,6 +11,7 @@
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "odb_backend.h"
|
||||
#include "indexer.h"
|
||||
|
||||
/**
|
||||
* @file git2/odb.h
|
||||
@ -62,7 +63,7 @@ GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
|
||||
* @param odb database to add the backend to
|
||||
* @param backend pointer to a git_odb_backend instance
|
||||
* @param priority Value for ordering the backends queue
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
|
||||
|
||||
@ -83,10 +84,27 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int
|
||||
* @param odb database to add the backend to
|
||||
* @param backend pointer to a git_odb_backend instance
|
||||
* @param priority Value for ordering the backends queue
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
|
||||
|
||||
/**
|
||||
* Add an on-disk alternate to an existing Object DB.
|
||||
*
|
||||
* Note that the added path must point to an `objects`, not
|
||||
* to a full repository, to use it as an alternate store.
|
||||
*
|
||||
* Alternate backends are always checked for objects *after*
|
||||
* all the main backends have been exhausted.
|
||||
*
|
||||
* Writing is disabled on alternate backends.
|
||||
*
|
||||
* @param odb database to add the backend to
|
||||
* @param path path to the objects folder for the alternate
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_add_disk_alternate(git_odb *odb, const char *path);
|
||||
|
||||
/**
|
||||
* Close an open object database.
|
||||
*
|
||||
@ -135,11 +153,12 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i
|
||||
* @param db database to search for the object in.
|
||||
* @param short_id a prefix of the id of the object to read.
|
||||
* @param len the length of the prefix
|
||||
* @return 0 if the object was read;
|
||||
* GIT_ENOTFOUND if the object is not in the database.
|
||||
* GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)
|
||||
* @return
|
||||
* - 0 if the object was read;
|
||||
* - GIT_ENOTFOUND if the object is not in the database.
|
||||
* - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, unsigned int len);
|
||||
GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len);
|
||||
|
||||
/**
|
||||
* Read the header of an object from the database, without
|
||||
@ -151,15 +170,15 @@ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git
|
||||
* of an object, so the whole object will be read and then the
|
||||
* header will be returned.
|
||||
*
|
||||
* @param len_p pointer where to store the length
|
||||
* @param type_p pointer where to store the type
|
||||
* @param len_out pointer where to store the length
|
||||
* @param type_out pointer where to store the type
|
||||
* @param db database to search for the object in.
|
||||
* @param id identity of the object to read.
|
||||
* @return
|
||||
* - 0 if the object was read;
|
||||
* - GIT_ENOTFOUND if the object is not in the database.
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id);
|
||||
GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_odb *db, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Determine if the given object can be found in the object database.
|
||||
@ -172,6 +191,41 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *d
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Refresh the object database to load newly added files.
|
||||
*
|
||||
* If the object databases have changed on disk while the library
|
||||
* is running, this function will force a reload of the underlying
|
||||
* indexes.
|
||||
*
|
||||
* Use this function when you're confident that an external
|
||||
* application has tampered with the ODB.
|
||||
*
|
||||
* NOTE that it is not necessary to call this function at all. The
|
||||
* library will automatically attempt to refresh the ODB
|
||||
* when a lookup fails, to see if the looked up object exists
|
||||
* on disk but hasn't been loaded yet.
|
||||
*
|
||||
* @param db database to refresh
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_refresh(struct git_odb *db);
|
||||
|
||||
/**
|
||||
* List all objects available in the database
|
||||
*
|
||||
* The callback will be called for each object available in the
|
||||
* database. Note that the objects are likely to be returned in the index
|
||||
* order, which would make accessing the objects in that order inefficient.
|
||||
* Return a non-zero value from the callback to stop looping.
|
||||
*
|
||||
* @param db database to use
|
||||
* @param cb the callback to call for each object
|
||||
* @param payload data to pass to the callback
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload);
|
||||
|
||||
/**
|
||||
* Write an object directly into the ODB
|
||||
*
|
||||
@ -183,14 +237,14 @@ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
|
||||
* This method is provided for compatibility with custom backends
|
||||
* which are not able to support streaming writes
|
||||
*
|
||||
* @param oid pointer to store the OID result of the write
|
||||
* @param out pointer to store the OID result of the write
|
||||
* @param odb object database where to store the object
|
||||
* @param data buffer with the data to storr
|
||||
* @param data buffer with the data to store
|
||||
* @param len size of the buffer
|
||||
* @param type type of the data to store
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size_t len, git_otype type);
|
||||
GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size_t len, git_otype type);
|
||||
|
||||
/**
|
||||
* Open a stream to write an object into the ODB
|
||||
@ -213,13 +267,13 @@ GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size
|
||||
*
|
||||
* @see git_odb_stream
|
||||
*
|
||||
* @param stream pointer where to store the stream
|
||||
* @param out pointer where to store the stream
|
||||
* @param db object database where the stream will write
|
||||
* @param size final size of the object that will be written
|
||||
* @param type type of the object that will be written
|
||||
* @return 0 if the stream was created; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_otype type);
|
||||
GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, size_t size, git_otype type);
|
||||
|
||||
/**
|
||||
* Open a stream to read an object from the ODB
|
||||
@ -240,32 +294,58 @@ GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_
|
||||
*
|
||||
* @see git_odb_stream
|
||||
*
|
||||
* @param stream pointer where to store the stream
|
||||
* @param out pointer where to store the stream
|
||||
* @param db object database where 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
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid);
|
||||
GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Open a stream for writing a pack file to the ODB.
|
||||
*
|
||||
* If the ODB layer understands pack files, then the given
|
||||
* packfile will likely be streamed directly to disk (and a
|
||||
* corresponding index created). If the ODB layer does not
|
||||
* understand pack files, the objects will be stored in whatever
|
||||
* format the ODB layer uses.
|
||||
*
|
||||
* @see git_odb_writepack
|
||||
*
|
||||
* @param out pointer to the writepack functions
|
||||
* @param db object database where the stream will read from
|
||||
* @param progress_cb function to call with progress information.
|
||||
* Be aware that this is called inline with network and indexing operations,
|
||||
* so performance may be affected.
|
||||
* @param progress_payload payload for the progress callback
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_write_pack(
|
||||
git_odb_writepack **out,
|
||||
git_odb *db,
|
||||
git_transfer_progress_callback progress_cb,
|
||||
void *progress_payload);
|
||||
|
||||
/**
|
||||
* Determine the object-ID (sha1 hash) of a data buffer
|
||||
*
|
||||
* The resulting SHA-1 OID will the itentifier for the data
|
||||
* The resulting SHA-1 OID will be the identifier for the data
|
||||
* buffer as if the data buffer it were to written to the ODB.
|
||||
*
|
||||
* @param id the resulting object-ID.
|
||||
* @param out the resulting object-ID.
|
||||
* @param data data to hash
|
||||
* @param len size of the data
|
||||
* @param type of the data to hash
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type);
|
||||
GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_otype type);
|
||||
|
||||
/**
|
||||
* Read a file from disk and fill a git_oid with the object id
|
||||
* that the file would have if it were written to the Object
|
||||
* Database as an object of the given type. Similar functionality
|
||||
* to git.git's `git hash-object` without the `-w` flag.
|
||||
* Database as an object of the given type (w/o applying filters).
|
||||
* Similar functionality to git.git's `git hash-object` without
|
||||
* the `-w` flag, however, with the --no-filters flag.
|
||||
* If you need filters, see git_repository_hashfile.
|
||||
*
|
||||
* @param out oid structure the result is written into.
|
||||
* @param path file to read and determine object id for
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -10,6 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "indexer.h"
|
||||
|
||||
/**
|
||||
* @file git2/backend.h
|
||||
@ -21,11 +22,24 @@
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
struct git_odb_stream;
|
||||
struct git_odb_writepack;
|
||||
|
||||
/** An instance for a custom backend */
|
||||
/**
|
||||
* Function type for callbacks from git_odb_foreach.
|
||||
*/
|
||||
typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload);
|
||||
|
||||
/**
|
||||
* An instance for a custom backend
|
||||
*/
|
||||
struct git_odb_backend {
|
||||
unsigned int version;
|
||||
git_odb *odb;
|
||||
|
||||
/* read and read_prefix each return to libgit2 a buffer which
|
||||
* will be freed later. The buffer should be allocated using
|
||||
* the function git_odb_backend_malloc to ensure that it can
|
||||
* be safely freed later. */
|
||||
int (* read)(
|
||||
void **, size_t *, git_otype *,
|
||||
struct git_odb_backend *,
|
||||
@ -42,13 +56,17 @@ struct git_odb_backend {
|
||||
void **, size_t *, git_otype *,
|
||||
struct git_odb_backend *,
|
||||
const git_oid *,
|
||||
unsigned int);
|
||||
size_t);
|
||||
|
||||
int (* read_header)(
|
||||
size_t *, git_otype *,
|
||||
struct git_odb_backend *,
|
||||
const git_oid *);
|
||||
|
||||
/* The writer may assume that the object
|
||||
* has already been hashed and is passed
|
||||
* in the first parameter.
|
||||
*/
|
||||
int (* write)(
|
||||
git_oid *,
|
||||
struct git_odb_backend *,
|
||||
@ -71,9 +89,25 @@ struct git_odb_backend {
|
||||
struct git_odb_backend *,
|
||||
const git_oid *);
|
||||
|
||||
int (* refresh)(struct git_odb_backend *);
|
||||
|
||||
int (* foreach)(
|
||||
struct git_odb_backend *,
|
||||
git_odb_foreach_cb cb,
|
||||
void *payload);
|
||||
|
||||
int (* writepack)(
|
||||
struct git_odb_writepack **,
|
||||
struct git_odb_backend *,
|
||||
git_transfer_progress_callback progress_cb,
|
||||
void *progress_payload);
|
||||
|
||||
void (* free)(struct git_odb_backend *);
|
||||
};
|
||||
|
||||
#define GIT_ODB_BACKEND_VERSION 1
|
||||
#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
|
||||
|
||||
/** Streaming mode */
|
||||
enum {
|
||||
GIT_STREAM_RDONLY = (1 << 1),
|
||||
@ -84,7 +118,7 @@ enum {
|
||||
/** A stream to read/write from a backend */
|
||||
struct git_odb_stream {
|
||||
struct git_odb_backend *backend;
|
||||
int mode;
|
||||
unsigned int mode;
|
||||
|
||||
int (*read)(struct git_odb_stream *stream, char *buffer, size_t len);
|
||||
int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len);
|
||||
@ -92,8 +126,23 @@ struct git_odb_stream {
|
||||
void (*free)(struct git_odb_stream *stream);
|
||||
};
|
||||
|
||||
GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir);
|
||||
GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync);
|
||||
/** A stream to write a pack file to the ODB */
|
||||
struct git_odb_writepack {
|
||||
struct git_odb_backend *backend;
|
||||
|
||||
int (*add)(struct git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
|
||||
int (*commit)(struct git_odb_writepack *writepack, git_transfer_progress *stats);
|
||||
void (*free)(struct git_odb_writepack *writepack);
|
||||
};
|
||||
|
||||
GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
|
||||
|
||||
/**
|
||||
* Constructors for in-box ODB backends.
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir);
|
||||
GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync);
|
||||
GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -30,11 +30,10 @@ GIT_BEGIN_DECL
|
||||
#define GIT_OID_MINPREFIXLEN 4
|
||||
|
||||
/** Unique identity of any object (commit, tree, blob, tag). */
|
||||
typedef struct _git_oid git_oid;
|
||||
struct _git_oid {
|
||||
typedef struct git_oid {
|
||||
/** raw binary formatted id */
|
||||
unsigned char id[GIT_OID_RAWSZ];
|
||||
};
|
||||
} git_oid;
|
||||
|
||||
/**
|
||||
* Parse a hex formatted object id into a git_oid.
|
||||
@ -47,6 +46,16 @@ struct _git_oid {
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
|
||||
|
||||
/**
|
||||
* Parse a hex formatted null-terminated string into a git_oid.
|
||||
*
|
||||
* @param out oid structure the result is written into.
|
||||
* @param str input hex string; must be at least 4 characters
|
||||
* long and null-terminated.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str);
|
||||
|
||||
/**
|
||||
* Parse N characters of a hex formatted object id into a git_oid
|
||||
*
|
||||
@ -71,29 +80,29 @@ GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw);
|
||||
/**
|
||||
* Format a git_oid into a hex string.
|
||||
*
|
||||
* @param str output hex string; must be pointing at the start of
|
||||
* @param out output hex string; must be pointing at the start of
|
||||
* the hex sequence and have at least the number of bytes
|
||||
* needed for an oid encoded in hex (40 bytes). Only the
|
||||
* oid digits are written; a '\\0' terminator must be added
|
||||
* by the caller if it is required.
|
||||
* @param oid oid structure to format.
|
||||
*/
|
||||
GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid);
|
||||
GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a loose-object path string.
|
||||
*
|
||||
* The resulting string is "aa/...", where "aa" is the first two
|
||||
* hex digitis of the oid and "..." is the remaining 38 digits.
|
||||
* hex digits of the oid and "..." is the remaining 38 digits.
|
||||
*
|
||||
* @param str output hex string; must be pointing at the start of
|
||||
* @param out output hex string; must be pointing at the start of
|
||||
* the hex sequence and have at least the number of bytes
|
||||
* needed for an oid encoded in hex (41 bytes). Only the
|
||||
* oid digits are written; a '\\0' terminator must be added
|
||||
* by the caller if it is required.
|
||||
* @param oid oid structure to format.
|
||||
* @param id oid structure to format.
|
||||
*/
|
||||
GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid);
|
||||
GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a newly allocated c-string.
|
||||
@ -102,7 +111,7 @@ GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid);
|
||||
* @return the c-string; NULL if memory is exhausted. Caller must
|
||||
* deallocate the string with git__free().
|
||||
*/
|
||||
GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid);
|
||||
GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a buffer as a hex format c-string.
|
||||
@ -115,11 +124,11 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid);
|
||||
*
|
||||
* @param out the buffer into which the oid string is output.
|
||||
* @param n the size of the out buffer.
|
||||
* @param oid the oid structure to format.
|
||||
* @param id the oid structure to format.
|
||||
* @return the out buffer pointer, assuming no input parameter
|
||||
* errors, otherwise a pointer to an empty string.
|
||||
*/
|
||||
GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *oid);
|
||||
GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Copy an oid from one structure to another.
|
||||
@ -136,7 +145,31 @@ GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src);
|
||||
* @param b second oid structure.
|
||||
* @return <0, 0, >0 if a < b, a == b, a > b.
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
|
||||
GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b)
|
||||
{
|
||||
const unsigned char *sha1 = a->id;
|
||||
const unsigned char *sha2 = b->id;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) {
|
||||
if (*sha1 != *sha2)
|
||||
return *sha1 - *sha2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two oid structures for equality
|
||||
*
|
||||
* @param a first oid structure.
|
||||
* @param b second oid structure.
|
||||
* @return true if equal, false otherwise
|
||||
*/
|
||||
GIT_INLINE(int) git_oid_equal(const git_oid *a, const git_oid *b)
|
||||
{
|
||||
return !git_oid_cmp(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the first 'len' hexadecimal characters (packets of 4 bits)
|
||||
@ -147,22 +180,24 @@ GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
|
||||
* @param len the number of hex chars to compare
|
||||
* @return 0 in case of a match
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, unsigned int len);
|
||||
GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len);
|
||||
|
||||
/**
|
||||
* Check if an oid equals an hex formatted object id.
|
||||
*
|
||||
* @param a oid structure.
|
||||
* @param id oid structure.
|
||||
* @param str input hex string of an object id.
|
||||
* @return GIT_ENOTOID if str is not a valid hex string,
|
||||
* 0 in case of a match, GIT_ERROR otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str);
|
||||
GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str);
|
||||
|
||||
/**
|
||||
* Check is an oid is all zeros.
|
||||
*
|
||||
* @return 1 if all zeros, 0 otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_iszero(const git_oid *a);
|
||||
GIT_EXTERN(int) git_oid_iszero(const git_oid *id);
|
||||
|
||||
/**
|
||||
* OID Shortener object
|
||||
@ -204,12 +239,12 @@ GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
|
||||
* GIT_ENOMEM error
|
||||
*
|
||||
* @param os a `git_oid_shorten` instance
|
||||
* @param text_oid an OID in text form
|
||||
* @param text_id an OID in text form
|
||||
* @return the minimal length to uniquely identify all OIDs
|
||||
* added so far to the set; or an error code (<0) if an
|
||||
* error occurs.
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_oid);
|
||||
GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id);
|
||||
|
||||
/**
|
||||
* Free an OID shortener instance
|
||||
|
143
include/git2/pack.h
Normal file
143
include/git2/pack.h
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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_git_pack_h__
|
||||
#define INCLUDE_git_pack_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "oid.h"
|
||||
|
||||
/**
|
||||
* @file git2/pack.h
|
||||
* @brief Git pack management routines
|
||||
*
|
||||
* Packing objects
|
||||
* ---------------
|
||||
*
|
||||
* Creation of packfiles requires two steps:
|
||||
*
|
||||
* - First, insert all the objects you want to put into the packfile
|
||||
* using `git_packbuilder_insert` and `git_packbuilder_insert_tree`.
|
||||
* It's important to add the objects in recency order ("in the order
|
||||
* that they are 'reachable' from head").
|
||||
*
|
||||
* "ANY order will give you a working pack, ... [but it is] the thing
|
||||
* that gives packs good locality. It keeps the objects close to the
|
||||
* head (whether they are old or new, but they are _reachable_ from the
|
||||
* head) at the head of the pack. So packs actually have absolutely
|
||||
* _wonderful_ IO patterns." - Linus Torvalds
|
||||
* git.git/Documentation/technical/pack-heuristics.txt
|
||||
*
|
||||
* - Second, use `git_packbuilder_write` or `git_packbuilder_foreach` to
|
||||
* write the resulting packfile.
|
||||
*
|
||||
* libgit2 will take care of the delta ordering and generation.
|
||||
* `git_packbuilder_set_threads` can be used to adjust the number of
|
||||
* threads used for the process.
|
||||
*
|
||||
* See tests-clar/pack/packbuilder.c for an example.
|
||||
*
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Initialize a new packbuilder
|
||||
*
|
||||
* @param out The new packbuilder object
|
||||
* @param repo The repository
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_packbuilder_new(git_packbuilder **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Set number of threads to spawn
|
||||
*
|
||||
* By default, libgit2 won't spawn any threads at all;
|
||||
* when set to 0, libgit2 will autodetect the number of
|
||||
* CPUs.
|
||||
*
|
||||
* @param pb The packbuilder
|
||||
* @param n Number of threads to spawn
|
||||
* @return number of actual threads to be used
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n);
|
||||
|
||||
/**
|
||||
* Insert a single object
|
||||
*
|
||||
* For an optimal pack it's mandatory to insert objects in recency order,
|
||||
* commits followed by trees and blobs.
|
||||
*
|
||||
* @param pb The packbuilder
|
||||
* @param id The oid of the commit
|
||||
* @param name The name; might be NULL
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, const char *name);
|
||||
|
||||
/**
|
||||
* Insert a root tree object
|
||||
*
|
||||
* This will add the tree as well as all referenced trees and blobs.
|
||||
*
|
||||
* @param pb The packbuilder
|
||||
* @param id The oid of the root tree
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Write the new pack and the corresponding index to path
|
||||
*
|
||||
* @param pb The packbuilder
|
||||
* @param path Directory to store the new pack and index
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_packbuilder_write(git_packbuilder *pb, const char *file);
|
||||
|
||||
typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload);
|
||||
/**
|
||||
* Create the new pack and pass each object to the callback
|
||||
*
|
||||
* @param pb the packbuilder
|
||||
* @param cb the callback to call with each packed object's buffer
|
||||
* @param payload the callback's data
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload);
|
||||
|
||||
/**
|
||||
* Get the total number of objects the packbuilder will write out
|
||||
*
|
||||
* @param pb the packbuilder
|
||||
* @return
|
||||
*/
|
||||
GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb);
|
||||
|
||||
/**
|
||||
* Get the number of objects the packbuilder has already written out
|
||||
*
|
||||
* @param pb the packbuilder
|
||||
* @return
|
||||
*/
|
||||
GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb);
|
||||
|
||||
/**
|
||||
* Free the packbuilder and all associated data
|
||||
*
|
||||
* @param pb The packbuilder
|
||||
*/
|
||||
GIT_EXTERN(void) git_packbuilder_free(git_packbuilder *pb);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
131
include/git2/push.h
Normal file
131
include/git2/push.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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_git_push_h__
|
||||
#define INCLUDE_git_push_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/push.h
|
||||
* @brief Git push management functions
|
||||
* @defgroup git_push push management functions
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Controls the behavior of a git_push object.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int version;
|
||||
|
||||
/**
|
||||
* If the transport being used to push to the remote requires the creation
|
||||
* of a pack file, this controls the number of worker threads used by
|
||||
* the packbuilder when creating that pack file to be sent to the remote.
|
||||
*
|
||||
* If set to 0, the packbuilder will auto-detect the number of threads
|
||||
* to create. The default value is 1.
|
||||
*/
|
||||
unsigned int pb_parallelism;
|
||||
} git_push_options;
|
||||
|
||||
#define GIT_PUSH_OPTIONS_VERSION 1
|
||||
#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION }
|
||||
|
||||
/**
|
||||
* Create a new push object
|
||||
*
|
||||
* @param out New push object
|
||||
* @param remote Remote instance
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_new(git_push **out, git_remote *remote);
|
||||
|
||||
/**
|
||||
* Set options on a push object
|
||||
*
|
||||
* @param push The push object
|
||||
* @param opts The options to set on the push object
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_set_options(
|
||||
git_push *push,
|
||||
const git_push_options *opts);
|
||||
|
||||
/**
|
||||
* Add a refspec to be pushed
|
||||
*
|
||||
* @param push The push object
|
||||
* @param refspec Refspec string
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_add_refspec(git_push *push, const char *refspec);
|
||||
|
||||
/**
|
||||
* Update remote tips after a push
|
||||
*
|
||||
* @param push The push object
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_update_tips(git_push *push);
|
||||
|
||||
/**
|
||||
* Actually push all given refspecs
|
||||
*
|
||||
* Note: To check if the push was successful (i.e. all remote references
|
||||
* have been updated as requested), you need to call both
|
||||
* `git_push_unpack_ok` and `git_push_status_foreach`. The remote
|
||||
* repository might have refused to update some or all of the references.
|
||||
*
|
||||
* @param push The push object
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_finish(git_push *push);
|
||||
|
||||
/**
|
||||
* Check if remote side successfully unpacked
|
||||
*
|
||||
* @param push The push object
|
||||
*
|
||||
* @return true if equal, false otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_unpack_ok(git_push *push);
|
||||
|
||||
/**
|
||||
* Call callback `cb' on each status
|
||||
*
|
||||
* For each of the updated references, we receive a status report in the
|
||||
* form of `ok refs/heads/master` or `ng refs/heads/master <msg>`.
|
||||
* `msg != NULL` means the reference has not been updated for the given
|
||||
* reason.
|
||||
*
|
||||
* @param push The push object
|
||||
* @param cb The callback to call on each object
|
||||
*
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_status_foreach(git_push *push,
|
||||
int (*cb)(const char *ref, const char *msg, void *data),
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* Free the given push object
|
||||
*
|
||||
* @param push The push object
|
||||
*/
|
||||
GIT_EXTERN(void) git_push_free(git_push *push);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
98
include/git2/refdb.h
Normal file
98
include/git2/refdb.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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_git_refdb_h__
|
||||
#define INCLUDE_git_refdb_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "refs.h"
|
||||
|
||||
/**
|
||||
* @file git2/refdb.h
|
||||
* @brief Git custom refs backend functions
|
||||
* @defgroup git_refdb Git custom refs backend API
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Create a new reference. Either an oid or a symbolic target must be
|
||||
* specified.
|
||||
*
|
||||
* @param refdb the reference database to associate with this reference
|
||||
* @param name the reference name
|
||||
* @param oid the object id for a direct reference
|
||||
* @param symbolic the target for a symbolic reference
|
||||
* @return the created git_reference or NULL on error
|
||||
*/
|
||||
GIT_EXTERN(git_reference *) git_reference__alloc(
|
||||
git_refdb *refdb,
|
||||
const char *name,
|
||||
const git_oid *oid,
|
||||
const char *symbolic);
|
||||
|
||||
/**
|
||||
* Create a new reference database with no backends.
|
||||
*
|
||||
* Before the Ref DB can be used for read/writing, a custom database
|
||||
* backend must be manually set using `git_refdb_set_backend()`
|
||||
*
|
||||
* @param out location to store the database pointer, if opened.
|
||||
* Set to NULL if the open failed.
|
||||
* @param repo the repository
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_refdb_new(git_refdb **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Create a new reference database and automatically add
|
||||
* the default backends:
|
||||
*
|
||||
* - git_refdb_dir: read and write loose and packed refs
|
||||
* from disk, assuming the repository dir as the folder
|
||||
*
|
||||
* @param out location to store the database pointer, if opened.
|
||||
* Set to NULL if the open failed.
|
||||
* @param repo the repository
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_refdb_open(git_refdb **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Suggests that the given refdb compress or optimize its references.
|
||||
* This mechanism is implementation specific. For on-disk reference
|
||||
* databases, for example, this may pack all loose references.
|
||||
*/
|
||||
GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb);
|
||||
|
||||
/**
|
||||
* Close an open reference database.
|
||||
*
|
||||
* @param refdb reference database pointer or NULL
|
||||
*/
|
||||
GIT_EXTERN(void) git_refdb_free(git_refdb *refdb);
|
||||
|
||||
/**
|
||||
* Sets the custom backend to an existing reference DB
|
||||
*
|
||||
* Read <refdb_backends.h> for more information.
|
||||
*
|
||||
* @param refdb database to add the backend to
|
||||
* @param backend pointer to a git_refdb_backend instance
|
||||
* @param priority Value for ordering the backends queue
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_refdb_set_backend(
|
||||
git_refdb *refdb,
|
||||
git_refdb_backend *backend);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
109
include/git2/refdb_backend.h
Normal file
109
include/git2/refdb_backend.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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_git_refdb_backend_h__
|
||||
#define INCLUDE_git_refdb_backend_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
|
||||
/**
|
||||
* @file git2/refdb_backend.h
|
||||
* @brief Git custom refs backend functions
|
||||
* @defgroup git_refdb_backend Git custom refs backend API
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/** An instance for a custom backend */
|
||||
struct git_refdb_backend {
|
||||
unsigned int version;
|
||||
|
||||
/**
|
||||
* Queries the refdb backend to determine if the given ref_name
|
||||
* exists. A refdb implementation must provide this function.
|
||||
*/
|
||||
int (*exists)(
|
||||
int *exists,
|
||||
struct git_refdb_backend *backend,
|
||||
const char *ref_name);
|
||||
|
||||
/**
|
||||
* Queries the refdb backend for a given reference. A refdb
|
||||
* implementation must provide this function.
|
||||
*/
|
||||
int (*lookup)(
|
||||
git_reference **out,
|
||||
struct git_refdb_backend *backend,
|
||||
const char *ref_name);
|
||||
|
||||
/**
|
||||
* Enumerates each reference in the refdb. A refdb implementation must
|
||||
* provide this function.
|
||||
*/
|
||||
int (*foreach)(
|
||||
struct git_refdb_backend *backend,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Enumerates each reference in the refdb that matches the given
|
||||
* glob string. A refdb implementation may provide this function;
|
||||
* if it is not provided, foreach will be used and the results filtered
|
||||
* against the glob.
|
||||
*/
|
||||
int (*foreach_glob)(
|
||||
struct git_refdb_backend *backend,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Writes the given reference to the refdb. A refdb implementation
|
||||
* must provide this function.
|
||||
*/
|
||||
int (*write)(struct git_refdb_backend *backend, const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Deletes the given reference from the refdb. A refdb implementation
|
||||
* must provide this function.
|
||||
*/
|
||||
int (*delete)(struct git_refdb_backend *backend, const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Suggests that the given refdb compress or optimize its references.
|
||||
* This mechanism is implementation specific. (For on-disk reference
|
||||
* databases, this may pack all loose references.) A refdb
|
||||
* implementation may provide this function; if it is not provided,
|
||||
* nothing will be done.
|
||||
*/
|
||||
int (*compress)(struct git_refdb_backend *backend);
|
||||
|
||||
/**
|
||||
* Frees any resources held by the refdb. A refdb implementation may
|
||||
* provide this function; if it is not provided, nothing will be done.
|
||||
*/
|
||||
void (*free)(struct git_refdb_backend *backend);
|
||||
};
|
||||
|
||||
#define GIT_ODB_BACKEND_VERSION 1
|
||||
#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
|
||||
|
||||
/**
|
||||
* Constructors for default refdb backends.
|
||||
*/
|
||||
GIT_EXTERN(int) git_refdb_backend_fs(
|
||||
struct git_refdb_backend **backend_out,
|
||||
git_repository *repo,
|
||||
git_refdb *refdb);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -23,41 +23,54 @@ GIT_BEGIN_DECL
|
||||
/**
|
||||
* Read the reflog for the given reference
|
||||
*
|
||||
* If there is no reflog file for the given
|
||||
* reference yet, an empty reflog object will
|
||||
* be returned.
|
||||
*
|
||||
* The reflog must be freed manually by using
|
||||
* git_reflog_free().
|
||||
*
|
||||
* @param reflog pointer to reflog
|
||||
* @param out pointer to reflog
|
||||
* @param ref reference to read the reflog for
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref);
|
||||
GIT_EXTERN(int) git_reflog_read(git_reflog **out, const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Write a new reflog for the given reference
|
||||
* Write an existing in-memory reflog object back to disk
|
||||
* using an atomic file lock.
|
||||
*
|
||||
* If there is no reflog file for the given
|
||||
* reference yet, it will be created.
|
||||
*
|
||||
* `oid_old` may be NULL in case it's a new reference.
|
||||
* @param reflog an existing reflog object
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_write(git_reflog *reflog);
|
||||
|
||||
/**
|
||||
* Add a new entry to the reflog.
|
||||
*
|
||||
* `msg` is optional and can be NULL.
|
||||
*
|
||||
* @param ref the changed reference
|
||||
* @param oid_old the OID the reference was pointing to
|
||||
* @param reflog an existing reflog object
|
||||
* @param id the OID the reference is now pointing to
|
||||
* @param committer the signature of the committer
|
||||
* @param msg the reflog message
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_write(git_reference *ref, const git_oid *oid_old, const git_signature *committer, const char *msg);
|
||||
GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg);
|
||||
|
||||
/**
|
||||
* Rename the reflog for the given reference
|
||||
*
|
||||
* The reflog to be renamed is expected to already exist
|
||||
*
|
||||
* The new name will be checked for validity.
|
||||
* See `git_reference_create_symbolic()` for rules about valid names.
|
||||
*
|
||||
* @param ref the reference
|
||||
* @param new_name the new name of the reference
|
||||
* @return 0 or an error code
|
||||
* @param name the new name of the reference
|
||||
* @return 0 on success, GIT_EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *new_name);
|
||||
GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *name);
|
||||
|
||||
/**
|
||||
* Delete the reflog for the given reference
|
||||
@ -73,16 +86,42 @@ GIT_EXTERN(int) git_reflog_delete(git_reference *ref);
|
||||
* @param reflog the previously loaded reflog
|
||||
* @return the number of log entries
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_reflog_entrycount(git_reflog *reflog);
|
||||
GIT_EXTERN(size_t) git_reflog_entrycount(git_reflog *reflog);
|
||||
|
||||
/**
|
||||
* Lookup an entry by its index
|
||||
*
|
||||
* Requesting the reflog entry with an index of 0 (zero) will
|
||||
* return the most recently created entry.
|
||||
*
|
||||
* @param reflog a previously loaded reflog
|
||||
* @param idx the position to lookup
|
||||
* @param idx the position of the entry to lookup. Should be greater than or
|
||||
* equal to 0 (zero) and less than `git_reflog_entrycount()`.
|
||||
* @return the entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog, unsigned int idx);
|
||||
GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog, size_t idx);
|
||||
|
||||
/**
|
||||
* Remove an entry from the reflog by its index
|
||||
*
|
||||
* To ensure there's no gap in the log history, set `rewrite_previous_entry`
|
||||
* param value to 1. When deleting entry `n`, member old_oid of entry `n-1`
|
||||
* (if any) will be updated with the value of member new_oid of entry `n+1`.
|
||||
*
|
||||
* @param reflog a previously loaded reflog.
|
||||
*
|
||||
* @param idx the position of the entry to remove. Should be greater than or
|
||||
* equal to 0 (zero) and less than `git_reflog_entrycount()`.
|
||||
*
|
||||
* @param rewrite_previous_entry 1 to rewrite the history; 0 otherwise.
|
||||
*
|
||||
* @return 0 on success, GIT_ENOTFOUND if the entry doesn't exist
|
||||
* or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_drop(
|
||||
git_reflog *reflog,
|
||||
size_t idx,
|
||||
int rewrite_previous_entry);
|
||||
|
||||
/**
|
||||
* Get the old oid
|
||||
@ -90,7 +129,7 @@ GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog
|
||||
* @param entry a reflog entry
|
||||
* @return the old oid
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entry);
|
||||
GIT_EXTERN(const git_oid *) git_reflog_entry_id_old(const git_reflog_entry *entry);
|
||||
|
||||
/**
|
||||
* Get the new oid
|
||||
@ -98,7 +137,7 @@ GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entr
|
||||
* @param entry a reflog entry
|
||||
* @return the new oid at this time
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entry);
|
||||
GIT_EXTERN(const git_oid *) git_reflog_entry_id_new(const git_reflog_entry *entry);
|
||||
|
||||
/**
|
||||
* Get the committer of this entry
|
||||
@ -106,15 +145,15 @@ GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entr
|
||||
* @param entry a reflog entry
|
||||
* @return the committer
|
||||
*/
|
||||
GIT_EXTERN(git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry);
|
||||
GIT_EXTERN(const git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry);
|
||||
|
||||
/**
|
||||
* Get the log msg
|
||||
* Get the log message
|
||||
*
|
||||
* @param entry a reflog entry
|
||||
* @return the log msg
|
||||
*/
|
||||
GIT_EXTERN(char *) git_reflog_entry_msg(const git_reflog_entry *entry);
|
||||
GIT_EXTERN(const char *) git_reflog_entry_message(const git_reflog_entry *entry);
|
||||
|
||||
/**
|
||||
* Free the reflog
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -10,6 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "strarray.h"
|
||||
|
||||
/**
|
||||
* @file git2/refs.h
|
||||
@ -21,175 +22,221 @@
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Lookup a reference by its name in a repository.
|
||||
* Lookup a reference by name in a repository.
|
||||
*
|
||||
* The generated reference must be freed by the user.
|
||||
* The returned reference must be freed by the user.
|
||||
*
|
||||
* @param reference_out pointer to the looked-up reference
|
||||
* The name will be checked for validity.
|
||||
* See `git_reference_create_symbolic()` for rules about valid names.
|
||||
*
|
||||
* @param out pointer to the looked-up reference
|
||||
* @param repo the repository to look up the reference
|
||||
* @param name the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...)
|
||||
* @return 0 or an error code
|
||||
* @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...)
|
||||
* @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name);
|
||||
GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, const char *name);
|
||||
|
||||
/**
|
||||
* Lookup a reference by name and resolve immediately to OID.
|
||||
*
|
||||
* @param oid Pointer to oid to be filled in
|
||||
* This function provides a quick way to resolve a reference name straight
|
||||
* through to the object id that it refers to. This avoids having to
|
||||
* allocate or free any `git_reference` objects for simple situations.
|
||||
*
|
||||
* The name will be checked for validity.
|
||||
* See `git_reference_symbolic_create()` for rules about valid names.
|
||||
*
|
||||
* @param out Pointer to oid to be filled in
|
||||
* @param repo The repository in which to look up the reference
|
||||
* @param name The long name for the reference
|
||||
* @return 0 on success, -1 if name could not be resolved
|
||||
* @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_name_to_oid(
|
||||
GIT_EXTERN(int) git_reference_name_to_id(
|
||||
git_oid *out, git_repository *repo, const char *name);
|
||||
|
||||
/**
|
||||
* Create a new symbolic reference.
|
||||
*
|
||||
* The reference will be created in the repository and written
|
||||
* to the disk.
|
||||
* A symbolic reference is a reference name that refers to another
|
||||
* reference name. If the other name moves, the symbolic name will move,
|
||||
* too. As a simple example, the "HEAD" reference might refer to
|
||||
* "refs/heads/master" while on the "master" branch of a repository.
|
||||
*
|
||||
* The generated reference must be freed by the user.
|
||||
* The symbolic reference will be created in the repository and written to
|
||||
* the disk. The generated reference object must be freed by the user.
|
||||
*
|
||||
* If `force` is true and there already exists a reference
|
||||
* with the same name, it will be overwritten.
|
||||
* Valid reference names must follow one of two patterns:
|
||||
*
|
||||
* @param ref_out Pointer to the newly created reference
|
||||
* 1. Top-level names must contain only capital letters and underscores,
|
||||
* and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
||||
* 2. Names prefixed with "refs/" can be almost anything. You must avoid
|
||||
* the characters '~', '^', ':', '\\', '?', '[', and '*', and the
|
||||
* sequences ".." and "@{" which have special meaning to revparse.
|
||||
*
|
||||
* This function will return an error if a reference already exists with the
|
||||
* given name unless `force` is true, in which case it will be overwritten.
|
||||
*
|
||||
* @param out Pointer to the newly created reference
|
||||
* @param repo Repository where that reference will live
|
||||
* @param name The name of the reference
|
||||
* @param target The target of the reference
|
||||
* @param force Overwrite existing references
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, EEXISTS, EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force);
|
||||
GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force);
|
||||
|
||||
/**
|
||||
* Create a new object id reference.
|
||||
* Create a new direct reference.
|
||||
*
|
||||
* The reference will be created in the repository and written
|
||||
* to the disk.
|
||||
* A direct reference (also called an object id reference) refers directly
|
||||
* to a specific object id (a.k.a. OID or SHA) in the repository. The id
|
||||
* permanently refers to the object (although the reference itself can be
|
||||
* moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0"
|
||||
* refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
|
||||
*
|
||||
* The generated reference must be freed by the user.
|
||||
* The direct reference will be created in the repository and written to
|
||||
* the disk. The generated reference object must be freed by the user.
|
||||
*
|
||||
* If `force` is true and there already exists a reference
|
||||
* with the same name, it will be overwritten.
|
||||
* Valid reference names must follow one of two patterns:
|
||||
*
|
||||
* @param ref_out Pointer to the newly created reference
|
||||
* 1. Top-level names must contain only capital letters and underscores,
|
||||
* and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
||||
* 2. Names prefixed with "refs/" can be almost anything. You must avoid
|
||||
* the characters '~', '^', ':', '\\', '?', '[', and '*', and the
|
||||
* sequences ".." and "@{" which have special meaning to revparse.
|
||||
*
|
||||
* This function will return an error if a reference already exists with the
|
||||
* given name unless `force` is true, in which case it will be overwritten.
|
||||
*
|
||||
* @param out Pointer to the newly created reference
|
||||
* @param repo Repository where that reference will live
|
||||
* @param name The name of the reference
|
||||
* @param id The object id pointed to by the reference.
|
||||
* @param force Overwrite existing references
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, EEXISTS, EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force);
|
||||
GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force);
|
||||
|
||||
/**
|
||||
* Get the OID pointed to by a reference.
|
||||
* Get the OID pointed to by a direct reference.
|
||||
*
|
||||
* Only available if the reference is direct (i.e. not symbolic)
|
||||
* Only available if the reference is direct (i.e. an object id reference,
|
||||
* not a symbolic one).
|
||||
*
|
||||
* To find the OID of a symbolic ref, call `git_reference_resolve()` and
|
||||
* then this function (or maybe use `git_reference_name_to_id()` to
|
||||
* directly resolve a reference name all the way through to an OID).
|
||||
*
|
||||
* @param ref The reference
|
||||
* @return a pointer to the oid if available, NULL otherwise
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_reference_oid(git_reference *ref);
|
||||
GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Get full name to the reference pointed by this reference
|
||||
* Get full name to the reference pointed to by a symbolic reference.
|
||||
*
|
||||
* Only available if the reference is symbolic
|
||||
* Only available if the reference is symbolic.
|
||||
*
|
||||
* @param ref The reference
|
||||
* @return a pointer to the name if available, NULL otherwise
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_reference_target(git_reference *ref);
|
||||
GIT_EXTERN(const char *) git_reference_symbolic_target(const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Get the type of a reference
|
||||
* Get the type of a reference.
|
||||
*
|
||||
* Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC)
|
||||
*
|
||||
* @param ref The reference
|
||||
* @return the type
|
||||
*/
|
||||
GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref);
|
||||
GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Get the full name of a reference
|
||||
* Get the full name of a reference.
|
||||
*
|
||||
* See `git_reference_create_symbolic()` for rules about valid names.
|
||||
*
|
||||
* @param ref The reference
|
||||
* @return the full name for the ref
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_reference_name(git_reference *ref);
|
||||
GIT_EXTERN(const char *) git_reference_name(const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Resolve a symbolic reference
|
||||
* Resolve a symbolic reference to a direct reference.
|
||||
*
|
||||
* Thie method iteratively peels a symbolic reference
|
||||
* until it resolves to a direct reference to an OID.
|
||||
* This method iteratively peels a symbolic reference until it resolves to
|
||||
* a direct reference to an OID.
|
||||
*
|
||||
* The peeled reference is returned in the `resolved_ref`
|
||||
* argument, and must be freed manually once it's no longer
|
||||
* needed.
|
||||
* The peeled reference is returned in the `resolved_ref` argument, and
|
||||
* must be freed manually once it's no longer needed.
|
||||
*
|
||||
* If a direct reference is passed as an argument,
|
||||
* a copy of that reference is returned. This copy must
|
||||
* be manually freed too.
|
||||
* If a direct reference is passed as an argument, a copy of that
|
||||
* reference is returned. This copy must be manually freed too.
|
||||
*
|
||||
* @param resolved_ref Pointer to the peeled reference
|
||||
* @param ref The reference
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref);
|
||||
GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Get the repository where a reference resides
|
||||
* Get the repository where a reference resides.
|
||||
*
|
||||
* @param ref The reference
|
||||
* @return a pointer to the repo
|
||||
*/
|
||||
GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref);
|
||||
GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref);
|
||||
|
||||
/**
|
||||
* Set the symbolic target of a reference.
|
||||
* Create a new reference with the same name as the given reference but a
|
||||
* different symbolic target. The reference must be a symbolic reference,
|
||||
* otherwise this will fail.
|
||||
*
|
||||
* The reference must be a symbolic reference, otherwise
|
||||
* this method will fail.
|
||||
* The new reference will be written to disk, overwriting the given reference.
|
||||
*
|
||||
* The reference will be automatically updated in
|
||||
* memory and on disk.
|
||||
* The target name will be checked for validity.
|
||||
* See `git_reference_create_symbolic()` for rules about valid names.
|
||||
*
|
||||
* @param out Pointer to the newly created reference
|
||||
* @param ref The reference
|
||||
* @param target The new target for the reference
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target);
|
||||
GIT_EXTERN(int) git_reference_symbolic_set_target(
|
||||
git_reference **out,
|
||||
git_reference *ref,
|
||||
const char *target);
|
||||
|
||||
/**
|
||||
* Set the OID target of a reference.
|
||||
* Create a new reference with the same name as the given reference but a
|
||||
* different OID target. The reference must be a direct reference, otherwise
|
||||
* this will fail.
|
||||
*
|
||||
* The reference must be a direct reference, otherwise
|
||||
* this method will fail.
|
||||
*
|
||||
* The reference will be automatically updated in
|
||||
* memory and on disk.
|
||||
* The new reference will be written to disk, overwriting the given reference.
|
||||
*
|
||||
* @param out Pointer to the newly created reference
|
||||
* @param ref The reference
|
||||
* @param id The new target OID for the reference
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
|
||||
GIT_EXTERN(int) git_reference_set_target(
|
||||
git_reference **out,
|
||||
git_reference *ref,
|
||||
const git_oid *id);
|
||||
|
||||
/**
|
||||
* Rename an existing reference
|
||||
* Rename an existing reference.
|
||||
*
|
||||
* This method works for both direct and symbolic references.
|
||||
* The new name will be checked for validity and may be
|
||||
* modified into a normalized form.
|
||||
*
|
||||
* The given git_reference will be updated in place.
|
||||
* The new name will be checked for validity.
|
||||
* See `git_reference_create_symbolic()` for rules about valid names.
|
||||
*
|
||||
* The reference will be immediately renamed in-memory
|
||||
* and on disk.
|
||||
* On success, the given git_reference will be deleted from disk and a
|
||||
* new `git_reference` will be returned.
|
||||
*
|
||||
* The reference will be immediately renamed in-memory and on disk.
|
||||
*
|
||||
* If the `force` flag is not enabled, and there's already
|
||||
* a reference with the given name, the renaming will fail.
|
||||
@ -200,20 +247,23 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
|
||||
* the reflog if it exists.
|
||||
*
|
||||
* @param ref The reference to rename
|
||||
* @param new_name The new name for the reference
|
||||
* @param name The new name for the reference
|
||||
* @param force Overwrite an existing reference
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, EINVALIDSPEC, EEXISTS or an error code
|
||||
*
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force);
|
||||
GIT_EXTERN(int) git_reference_rename(
|
||||
git_reference **out,
|
||||
git_reference *ref,
|
||||
const char *new_name,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Delete an existing reference
|
||||
* Delete an existing reference.
|
||||
*
|
||||
* This method works for both direct and symbolic references.
|
||||
*
|
||||
* The reference will be immediately removed on disk and from
|
||||
* memory. The given reference pointer will no longer be valid.
|
||||
* This method works for both direct and symbolic references. The reference
|
||||
* will be immediately removed on disk but the memory will not be freed.
|
||||
* Callers must call `git_reference_free`.
|
||||
*
|
||||
* @param ref The reference to remove
|
||||
* @return 0 or an error code
|
||||
@ -221,95 +271,56 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, i
|
||||
GIT_EXTERN(int) git_reference_delete(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Pack all the loose references in the repository
|
||||
* Fill a list with all the references that can be found in a repository.
|
||||
*
|
||||
* This method will load into the cache all the loose
|
||||
* references on the repository and update the
|
||||
* `packed-refs` file with them.
|
||||
* Using the `list_flags` parameter, the listed references may be filtered
|
||||
* by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
|
||||
* `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
|
||||
* For convenience, use the value `GIT_REF_LISTALL` to obtain all
|
||||
* references, including packed ones.
|
||||
*
|
||||
* Once the `packed-refs` file has been written properly,
|
||||
* the loose references will be removed from disk.
|
||||
*
|
||||
* @param repo Repository where the loose refs will be packed
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_packall(git_repository *repo);
|
||||
|
||||
/**
|
||||
* Fill a list with all the references that can be found
|
||||
* in a repository.
|
||||
*
|
||||
* The listed references may be filtered by type, or using
|
||||
* a bitwise OR of several types. Use the magic value
|
||||
* `GIT_REF_LISTALL` to obtain all references, including
|
||||
* packed ones.
|
||||
*
|
||||
* The string array will be filled with the names of all
|
||||
* references; these values are owned by the user and
|
||||
* should be free'd manually when no longer needed, using
|
||||
* `git_strarray_free`.
|
||||
* The string array will be filled with the names of all references; these
|
||||
* values are owned by the user and should be free'd manually when no
|
||||
* longer needed, using `git_strarray_free()`.
|
||||
*
|
||||
* @param array Pointer to a git_strarray structure where
|
||||
* the reference names will be stored
|
||||
* @param repo Repository where to find the refs
|
||||
* @param list_flags Filtering flags for the reference
|
||||
* listing.
|
||||
* @param list_flags Filtering flags for the reference listing
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
|
||||
|
||||
typedef int (*git_reference_foreach_cb)(const char *refname, void *payload);
|
||||
|
||||
/**
|
||||
* Perform an operation on each reference in the repository
|
||||
* Perform a callback on each reference in the repository.
|
||||
*
|
||||
* The processed references may be filtered by type, or using
|
||||
* a bitwise OR of several types. Use the magic value
|
||||
* `GIT_REF_LISTALL` to obtain all references, including
|
||||
* packed ones.
|
||||
* Using the `list_flags` parameter, the references may be filtered by
|
||||
* type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
|
||||
* `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
|
||||
* For convenience, use the value `GIT_REF_LISTALL` to obtain all
|
||||
* references, including packed ones.
|
||||
*
|
||||
* The `callback` function will be called for each of the references
|
||||
* in the repository, and will receive the name of the reference and
|
||||
* the `payload` value passed to this method.
|
||||
* The `callback` function will be called for each reference in the
|
||||
* repository, receiving the name of the reference and the `payload` value
|
||||
* passed to this method. Returning a non-zero value from the callback
|
||||
* will terminate the iteration.
|
||||
*
|
||||
* @param repo Repository where to find the refs
|
||||
* @param list_flags Filtering flags for the reference
|
||||
* listing.
|
||||
* @param list_flags Filtering flags for the reference listing.
|
||||
* @param callback Function which will be called for every listed ref
|
||||
* @param payload Additional data to pass to the callback
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload);
|
||||
GIT_EXTERN(int) git_reference_foreach(
|
||||
git_repository *repo,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Check if a reference has been loaded from a packfile
|
||||
*
|
||||
* @param ref A git reference
|
||||
* @return 0 in case it's not packed; 1 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Reload a reference from disk
|
||||
*
|
||||
* Reference pointers may become outdated if the Git
|
||||
* repository is accessed simultaneously by other clients
|
||||
* whilt the library is open.
|
||||
*
|
||||
* This method forces a reload of the reference from disk,
|
||||
* to ensure that the provided information is still
|
||||
* reliable.
|
||||
*
|
||||
* If the reload fails (e.g. the reference no longer exists
|
||||
* on disk, or has become corrupted), an error code will be
|
||||
* returned and the reference pointer will be invalidated.
|
||||
*
|
||||
* @param ref The reference to reload
|
||||
* @return 0 on success, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_reload(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Free the given reference
|
||||
* Free the given reference.
|
||||
*
|
||||
* @param ref git_reference
|
||||
*/
|
||||
@ -324,6 +335,146 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref);
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
|
||||
|
||||
/**
|
||||
* Perform a callback on each reference in the repository whose name
|
||||
* matches the given pattern.
|
||||
*
|
||||
* This function acts like `git_reference_foreach()` with an additional
|
||||
* pattern match being applied to the reference name before issuing the
|
||||
* callback function. See that function for more information.
|
||||
*
|
||||
* The pattern is matched using fnmatch or "glob" style where a '*' matches
|
||||
* any sequence of letters, a '?' matches any letter, and square brackets
|
||||
* can be used to define character ranges (such as "[0-9]" for digits).
|
||||
*
|
||||
* @param repo Repository where to find the refs
|
||||
* @param glob Pattern to match (fnmatch-style) against reference name.
|
||||
* @param list_flags Filtering flags for the reference listing.
|
||||
* @param callback Function which will be called for every listed ref
|
||||
* @param payload Additional data to pass to the callback
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_foreach_glob(
|
||||
git_repository *repo,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Check if a reflog exists for the specified reference.
|
||||
*
|
||||
* @param ref A git reference
|
||||
*
|
||||
* @return 0 when no reflog can be found, 1 when it exists;
|
||||
* otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Check if a reference is a local branch.
|
||||
*
|
||||
* @param ref A git reference
|
||||
*
|
||||
* @return 1 when the reference lives in the refs/heads
|
||||
* namespace; 0 otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Check if a reference is a remote tracking branch
|
||||
*
|
||||
* @param ref A git reference
|
||||
*
|
||||
* @return 1 when the reference lives in the refs/remotes
|
||||
* namespace; 0 otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_is_remote(git_reference *ref);
|
||||
|
||||
|
||||
typedef enum {
|
||||
GIT_REF_FORMAT_NORMAL = 0,
|
||||
|
||||
/**
|
||||
* Control whether one-level refnames are accepted
|
||||
* (i.e., refnames that do not contain multiple /-separated
|
||||
* components). Those are expected to be written only using
|
||||
* uppercase letters and underscore (FETCH_HEAD, ...)
|
||||
*/
|
||||
GIT_REF_FORMAT_ALLOW_ONELEVEL = (1 << 0),
|
||||
|
||||
/**
|
||||
* Interpret the provided name as a reference pattern for a
|
||||
* refspec (as used with remote repositories). If this option
|
||||
* is enabled, the name is allowed to contain a single * (<star>)
|
||||
* in place of a one full pathname component
|
||||
* (e.g., foo/<star>/bar but not foo/bar<star>).
|
||||
*/
|
||||
GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1),
|
||||
} git_reference_normalize_t;
|
||||
|
||||
/**
|
||||
* Normalize reference name and check validity.
|
||||
*
|
||||
* This will normalize the reference name by removing any leading slash
|
||||
* '/' characters and collapsing runs of adjacent slashes between name
|
||||
* components into a single slash.
|
||||
*
|
||||
* Once normalized, if the reference name is valid, it will be returned in
|
||||
* the user allocated buffer.
|
||||
*
|
||||
* See `git_reference_create_symbolic()` for rules about valid names.
|
||||
*
|
||||
* @param buffer_out User allocated buffer to store normalized name
|
||||
* @param buffer_size Size of buffer_out
|
||||
* @param name Reference name to be checked.
|
||||
* @param flags Flags to constrain name validation rules - see the
|
||||
* GIT_REF_FORMAT constants above.
|
||||
* @return 0 on success, GIT_EBUFS if buffer is too small, EINVALIDSPEC
|
||||
* or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_normalize_name(
|
||||
char *buffer_out,
|
||||
size_t buffer_size,
|
||||
const char *name,
|
||||
unsigned int flags);
|
||||
|
||||
/**
|
||||
* Recursively peel reference until object of the specified type is found.
|
||||
*
|
||||
* The retrieved `peeled` object is owned by the repository
|
||||
* and should be closed with the `git_object_free` method.
|
||||
*
|
||||
* If you pass `GIT_OBJ_ANY` as the target type, then the object
|
||||
* will be peeled until a non-tag object is met.
|
||||
*
|
||||
* @param peeled Pointer to the peeled git_object
|
||||
* @param ref The reference to be processed
|
||||
* @param target_type The type of the requested object (GIT_OBJ_COMMIT,
|
||||
* GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY).
|
||||
* @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_peel(
|
||||
git_object **out,
|
||||
git_reference *ref,
|
||||
git_otype type);
|
||||
|
||||
/**
|
||||
* Ensure the reference name is well-formed.
|
||||
*
|
||||
* Valid reference names must follow one of two patterns:
|
||||
*
|
||||
* 1. Top-level names must contain only capital letters and underscores,
|
||||
* and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
||||
* 2. Names prefixed with "refs/" can be almost anything. You must avoid
|
||||
* the characters '~', '^', ':', '\\', '?', '[', and '*', and the
|
||||
* sequences ".." and "@{" which have special meaning to revparse.
|
||||
*
|
||||
* @param refname name to be checked.
|
||||
* @return 1 if the reference name is acceptable; 0 if it isn't
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_is_valid_name(const char *refname);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -35,6 +35,14 @@ GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec);
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
|
||||
|
||||
/**
|
||||
* Get the force update setting
|
||||
*
|
||||
* @param refspec the refspec
|
||||
* @return 1 if force update has been set, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec);
|
||||
|
||||
/**
|
||||
* Check if a refspec's source descriptor matches a reference
|
||||
*
|
||||
@ -44,17 +52,37 @@ GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
|
||||
*/
|
||||
GIT_EXTERN(int) git_refspec_src_matches(const git_refspec *refspec, const char *refname);
|
||||
|
||||
/**
|
||||
* Check if a refspec's destination descriptor matches a reference
|
||||
*
|
||||
* @param refspec the refspec
|
||||
* @param refname the name of the reference to check
|
||||
* @return 1 if the refspec matches, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_refspec_dst_matches(const git_refspec *refspec, const char *refname);
|
||||
|
||||
/**
|
||||
* Transform a reference to its target following the refspec's rules
|
||||
*
|
||||
* @param out where to store the target name
|
||||
* @param outlen the size ouf the `out` buffer
|
||||
* @param outlen the size of the `out` buffer
|
||||
* @param spec the refspec
|
||||
* @param name the name of the reference to transform
|
||||
* @return 0, GIT_EBUFS or another error
|
||||
*/
|
||||
GIT_EXTERN(int) git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name);
|
||||
|
||||
/**
|
||||
* Transform a target reference to its source reference following the refspec's rules
|
||||
*
|
||||
* @param out where to store the source reference name
|
||||
* @param outlen the size of the `out` buffer
|
||||
* @param spec the refspec
|
||||
* @param name the name of the reference to transform
|
||||
* @return 0, GIT_EBUFS or another error
|
||||
*/
|
||||
GIT_EXTERN(int) git_refspec_rtransform(char *out, size_t outlen, const git_refspec *spec, const char *name);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -12,6 +12,8 @@
|
||||
#include "refspec.h"
|
||||
#include "net.h"
|
||||
#include "indexer.h"
|
||||
#include "strarray.h"
|
||||
#include "transport.h"
|
||||
|
||||
/**
|
||||
* @file git2/remote.h
|
||||
@ -22,6 +24,7 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload);
|
||||
/*
|
||||
* TODO: This functions still need to be implemented:
|
||||
* - _listcb/_foreach
|
||||
@ -30,36 +33,65 @@ GIT_BEGIN_DECL
|
||||
* - _del (needs support from config)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a remote with the default fetch refspec to the repository's configuration. This
|
||||
* calls git_remote_save before returning.
|
||||
*
|
||||
* @param out the resulting remote
|
||||
* @param repo the repository in which to create the remote
|
||||
* @param name the remote's name
|
||||
* @param url the remote's url
|
||||
* @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_create(
|
||||
git_remote **out,
|
||||
git_repository *repo,
|
||||
const char *name,
|
||||
const char *url);
|
||||
|
||||
/**
|
||||
* Create a remote in memory
|
||||
*
|
||||
* Create a remote with the default refspecs in memory. You can use
|
||||
* this when you have a URL instead of a remote's name.
|
||||
* Create a remote with the given refspec in memory. You can use
|
||||
* this when you have a URL instead of a remote's name. Note that in-memory
|
||||
* remotes cannot be converted to persisted remotes.
|
||||
*
|
||||
* The name, when provided, will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param out pointer to the new remote object
|
||||
* @param repo the associtated repository
|
||||
* @param name the remote's name
|
||||
* @param repo the associated repository
|
||||
* @param fetch the fetch refspec to use for this remote. May be NULL for defaults.
|
||||
* @param url the remote repository's URL
|
||||
* @param fetch the fetch refspec to use for this remote
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch);
|
||||
GIT_EXTERN(int) git_remote_create_inmemory(
|
||||
git_remote **out,
|
||||
git_repository *repo,
|
||||
const char *fetch,
|
||||
const char *url);
|
||||
|
||||
/**
|
||||
* Get the information for a particular remote
|
||||
*
|
||||
* The name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param out pointer to the new remote object
|
||||
* @param cfg the repository's configuration
|
||||
* @param repo the associated repository
|
||||
* @param name the remote's name
|
||||
* @return 0 or an error code
|
||||
* @return 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const char *name);
|
||||
|
||||
/**
|
||||
* Save a remote to its repository's configuration
|
||||
*
|
||||
* One can't save a in-memory remote. Doing so will
|
||||
* result in a GIT_EINVALIDSPEC being returned.
|
||||
*
|
||||
* @param remote the remote to save to config
|
||||
* @return 0 or an error code
|
||||
* @return 0, GIT_EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_save(const git_remote *remote);
|
||||
|
||||
@ -67,9 +99,9 @@ GIT_EXTERN(int) git_remote_save(const git_remote *remote);
|
||||
* Get the remote's name
|
||||
*
|
||||
* @param remote the remote
|
||||
* @return a pointer to the name
|
||||
* @return a pointer to the name or NULL for in-memory remotes
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_remote_name(git_remote *remote);
|
||||
GIT_EXTERN(const char *) git_remote_name(const git_remote *remote);
|
||||
|
||||
/**
|
||||
* Get the remote's url
|
||||
@ -77,7 +109,37 @@ GIT_EXTERN(const char *) git_remote_name(git_remote *remote);
|
||||
* @param remote the remote
|
||||
* @return a pointer to the url
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_remote_url(git_remote *remote);
|
||||
GIT_EXTERN(const char *) git_remote_url(const git_remote *remote);
|
||||
|
||||
/**
|
||||
* Get the remote's url for pushing
|
||||
*
|
||||
* @param remote the remote
|
||||
* @return a pointer to the url or NULL if no special url for pushing is set
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote);
|
||||
|
||||
/**
|
||||
* Set the remote's url
|
||||
*
|
||||
* Existing connections will not be updated.
|
||||
*
|
||||
* @param remote the remote
|
||||
* @param url the url to set
|
||||
* @return 0 or an error value
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_url(git_remote *remote, const char* url);
|
||||
|
||||
/**
|
||||
* Set the remote's url for pushing
|
||||
*
|
||||
* Existing connections will not be updated.
|
||||
*
|
||||
* @param remote the remote
|
||||
* @param url the url to set or NULL to clear the pushurl
|
||||
* @return 0 or an error value
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url);
|
||||
|
||||
/**
|
||||
* Set the remote's fetch refspec
|
||||
@ -94,13 +156,13 @@ GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec);
|
||||
* @param remote the remote
|
||||
* @return a pointer to the fetch refspec or NULL if it doesn't exist
|
||||
*/
|
||||
GIT_EXTERN(const git_refspec *) git_remote_fetchspec(git_remote *remote);
|
||||
GIT_EXTERN(const git_refspec *) git_remote_fetchspec(const git_remote *remote);
|
||||
|
||||
/**
|
||||
* Set the remote's push refspec
|
||||
*
|
||||
* @param remote the remote
|
||||
* @apram spec the new push refspec
|
||||
* @param spec the new push refspec
|
||||
* @return 0 or an error value
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec);
|
||||
@ -112,7 +174,7 @@ GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec);
|
||||
* @return a pointer to the push refspec or NULL if it doesn't exist
|
||||
*/
|
||||
|
||||
GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote);
|
||||
GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote);
|
||||
|
||||
/**
|
||||
* Open a connection to a remote
|
||||
@ -125,7 +187,7 @@ GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote);
|
||||
* @param direction whether you want to receive or send data
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction);
|
||||
GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction);
|
||||
|
||||
/**
|
||||
* Get a list of refs at the remote
|
||||
@ -133,9 +195,13 @@ GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction);
|
||||
* The remote (or more exactly its transport) must be connected. The
|
||||
* memory belongs to the remote.
|
||||
*
|
||||
* @param refs where to store the refs
|
||||
* If you a return a non-zero value from the callback, this will stop
|
||||
* looping over the refs.
|
||||
*
|
||||
* @param remote the remote
|
||||
* @return 0 or an error code
|
||||
* @param list_cb function to call with each ref discovered at the remote
|
||||
* @param payload additional data to pass to the callback
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload);
|
||||
|
||||
@ -149,10 +215,16 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void
|
||||
* filename will be NULL and the function will return success.
|
||||
*
|
||||
* @param remote the remote to download from
|
||||
* @param filename where to store the temproray filename
|
||||
* @param progress_cb function to call with progress information. Be aware that
|
||||
* this is called inline with network and indexing operations, so performance
|
||||
* may be affected.
|
||||
* @param progress_payload payload for the progress callback
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats);
|
||||
GIT_EXTERN(int) git_remote_download(
|
||||
git_remote *remote,
|
||||
git_transfer_progress_callback progress_cb,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Check whether the remote is connected
|
||||
@ -160,10 +232,21 @@ GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_in
|
||||
* Check whether the remote's underlying transport is connected to the
|
||||
* remote host.
|
||||
*
|
||||
* @param remote the remote
|
||||
* @return 1 if it's connected, 0 otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_connected(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Cancel the operation
|
||||
*
|
||||
* At certain points in its operation, the network code checks whether
|
||||
* the operation has been cancelled and if so stops the operation.
|
||||
*
|
||||
* @param remote the remote
|
||||
*/
|
||||
GIT_EXTERN(void) git_remote_stop(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Disconnect from the remote
|
||||
*
|
||||
@ -188,14 +271,14 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote);
|
||||
* Update the tips to the new state
|
||||
*
|
||||
* @param remote the remote to update
|
||||
* @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b));
|
||||
GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Return whether a string is a valid remote URL
|
||||
*
|
||||
* @param tranport the url to check
|
||||
* @param url the url to check
|
||||
* @param 1 if the url is valid, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_valid_url(const char *url);
|
||||
@ -213,21 +296,167 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url);
|
||||
*
|
||||
* The string array must be freed by the user.
|
||||
*
|
||||
* @param remotes_list a string array with the names of the remotes
|
||||
* @param out a string array which receives the names of the remotes
|
||||
* @param repo the repository to query
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_list(git_strarray *remotes_list, git_repository *repo);
|
||||
GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Add a remote with the default fetch refspec to the repository's configuration
|
||||
* Choose whether to check the server's certificate (applies to HTTPS only)
|
||||
*
|
||||
* @param out the resulting remote
|
||||
* @param repo the repository in which to create the remote
|
||||
* @param name the remote's name
|
||||
* @param url the remote's url
|
||||
* @param remote the remote to configure
|
||||
* @param check whether to check the server's certificate (defaults to yes)
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url);
|
||||
GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check);
|
||||
|
||||
/**
|
||||
* Set a credentials acquisition callback for this remote. If the remote is
|
||||
* not available for anonymous access, then you must set this callback in order
|
||||
* to provide credentials to the transport at the time of authentication
|
||||
* failure so that retry can be performed.
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param cred_acquire_cb The credentials acquisition callback to use (defaults
|
||||
* to NULL)
|
||||
*/
|
||||
GIT_EXTERN(void) git_remote_set_cred_acquire_cb(
|
||||
git_remote *remote,
|
||||
git_cred_acquire_cb cred_acquire_cb,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Sets a custom transport for the remote. The caller can use this function
|
||||
* to bypass the automatic discovery of a transport by URL scheme (i.e.
|
||||
* http://, https://, git://) and supply their own transport to be used
|
||||
* instead. After providing the transport to a remote using this function,
|
||||
* the transport object belongs exclusively to that remote, and the remote will
|
||||
* free it when it is freed with git_remote_free.
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param transport the transport object for the remote to use
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_transport(
|
||||
git_remote *remote,
|
||||
git_transport *transport);
|
||||
|
||||
/**
|
||||
* Argument to the completion callback which tells it which operation
|
||||
* finished.
|
||||
*/
|
||||
typedef enum git_remote_completion_type {
|
||||
GIT_REMOTE_COMPLETION_DOWNLOAD,
|
||||
GIT_REMOTE_COMPLETION_INDEXING,
|
||||
GIT_REMOTE_COMPLETION_ERROR,
|
||||
} git_remote_completion_type;
|
||||
|
||||
/**
|
||||
* The callback settings structure
|
||||
*
|
||||
* Set the calbacks to be called by the remote.
|
||||
*/
|
||||
struct git_remote_callbacks {
|
||||
unsigned int version;
|
||||
void (*progress)(const char *str, int len, void *data);
|
||||
int (*completion)(git_remote_completion_type type, void *data);
|
||||
int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
|
||||
void *payload;
|
||||
};
|
||||
|
||||
#define GIT_REMOTE_CALLBACKS_VERSION 1
|
||||
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
|
||||
|
||||
/**
|
||||
* Set the callbacks for a remote
|
||||
*
|
||||
* Note that the remote keeps its own copy of the data and you need to
|
||||
* call this function again if you want to change the callbacks.
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param callbacks a pointer to the user's callback settings
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks);
|
||||
|
||||
/**
|
||||
* Get the statistics structure that is filled in by the fetch operation.
|
||||
*/
|
||||
GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote);
|
||||
|
||||
typedef enum {
|
||||
GIT_REMOTE_DOWNLOAD_TAGS_UNSET,
|
||||
GIT_REMOTE_DOWNLOAD_TAGS_NONE,
|
||||
GIT_REMOTE_DOWNLOAD_TAGS_AUTO,
|
||||
GIT_REMOTE_DOWNLOAD_TAGS_ALL
|
||||
} git_remote_autotag_option_t;
|
||||
|
||||
/**
|
||||
* Retrieve the tag auto-follow setting
|
||||
*
|
||||
* @param remote the remote to query
|
||||
* @return the auto-follow setting
|
||||
*/
|
||||
GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Set the tag auto-follow setting
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param value a GIT_REMOTE_DOWNLOAD_TAGS value
|
||||
*/
|
||||
GIT_EXTERN(void) git_remote_set_autotag(
|
||||
git_remote *remote,
|
||||
git_remote_autotag_option_t value);
|
||||
|
||||
/**
|
||||
* Give the remote a new name
|
||||
*
|
||||
* All remote-tracking branches and configuration settings
|
||||
* for the remote are updated.
|
||||
*
|
||||
* The new name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* A temporary in-memory remote cannot be given a name with this method.
|
||||
*
|
||||
* @param remote the remote to rename
|
||||
* @param new_name the new name the remote should bear
|
||||
* @param callback Optional callback to notify the consumer of fetch refspecs
|
||||
* that haven't been automatically updated and need potential manual tweaking.
|
||||
* @param payload Additional data to pass to the callback
|
||||
* @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_rename(
|
||||
git_remote *remote,
|
||||
const char *new_name,
|
||||
git_remote_rename_problem_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Retrieve the update FETCH_HEAD setting.
|
||||
*
|
||||
* @param remote the remote to query
|
||||
* @return the update FETCH_HEAD setting
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_update_fetchhead(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be
|
||||
* updated on every fetch. Set to 0 to disable.
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param value 0 to disable updating FETCH_HEAD
|
||||
*/
|
||||
GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value);
|
||||
|
||||
/**
|
||||
* Ensure the remote name is well-formed.
|
||||
*
|
||||
* @param remote_name name to be checked.
|
||||
* @return 1 if the reference name is acceptable; 0 if it isn't
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -29,11 +29,24 @@ GIT_BEGIN_DECL
|
||||
* The method will automatically detect if 'path' is a normal
|
||||
* or bare repository or fail is 'path' is neither.
|
||||
*
|
||||
* @param repository pointer to the repo which will be opened
|
||||
* @param out pointer to the repo which will be opened
|
||||
* @param path the path to the repository
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path);
|
||||
GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path);
|
||||
|
||||
/**
|
||||
* Create a "fake" repository to wrap an object database
|
||||
*
|
||||
* Create a repository object to wrap an object database to be used
|
||||
* with the API when all you have is an object database. This doesn't
|
||||
* have any paths associated with it, so use with care.
|
||||
*
|
||||
* @param out pointer to the repo
|
||||
* @param odb the object database to wrap
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb);
|
||||
|
||||
/**
|
||||
* Look for a git repository and copy its path in the given buffer.
|
||||
@ -45,10 +58,10 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat
|
||||
* The method will automatically detect if the repository is bare
|
||||
* (if there is a repository).
|
||||
*
|
||||
* @param repository_path The user allocated buffer which will
|
||||
* @param path_out The user allocated buffer which will
|
||||
* contain the found path.
|
||||
*
|
||||
* @param size repository_path size
|
||||
* @param path_size repository_path size
|
||||
*
|
||||
* @param start_path The base path where the lookup starts.
|
||||
*
|
||||
@ -64,24 +77,50 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_discover(
|
||||
char *repository_path,
|
||||
size_t size,
|
||||
char *path_out,
|
||||
size_t path_size,
|
||||
const char *start_path,
|
||||
int across_fs,
|
||||
const char *ceiling_dirs);
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Option flags for `git_repository_open_ext`.
|
||||
*
|
||||
* * GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be
|
||||
* immediately found in the start_path. Do not walk up from the
|
||||
* start_path looking at parent directories.
|
||||
* * GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not
|
||||
* continue searching across filesystem boundaries (i.e. when `st_dev`
|
||||
* changes from the `stat` system call). (E.g. Searching in a user's home
|
||||
* directory "/home/user/source/" will not return "/.git/" as the found
|
||||
* repo if "/" is a different filesystem than "/home".)
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
|
||||
GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
|
||||
};
|
||||
} git_repository_open_flag_t;
|
||||
|
||||
/**
|
||||
* Find and open a repository with extended controls.
|
||||
*
|
||||
* @param out Pointer to the repo which will be opened. This can
|
||||
* actually be NULL if you only want to use the error code to
|
||||
* see if a repo at this path could be opened.
|
||||
* @param path Path to open as git repository. If the flags
|
||||
* permit "searching", then this can be a path to a subdirectory
|
||||
* inside the working directory of the repository.
|
||||
* @param flags A combination of the GIT_REPOSITORY_OPEN flags above.
|
||||
* @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR delimited list of path
|
||||
* prefixes at which the search for a containing repository should
|
||||
* terminate.
|
||||
* @return 0 on success, GIT_ENOTFOUND if no repository could be found,
|
||||
* or -1 if there was a repository but open failed for some reason
|
||||
* (such as repo corruption or system errors).
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_open_ext(
|
||||
git_repository **repo,
|
||||
const char *start_path,
|
||||
uint32_t flags,
|
||||
git_repository **out,
|
||||
const char *path,
|
||||
unsigned int flags,
|
||||
const char *ceiling_dirs);
|
||||
|
||||
/**
|
||||
@ -103,25 +142,148 @@ GIT_EXTERN(void) git_repository_free(git_repository *repo);
|
||||
* TODO:
|
||||
* - Reinit the repository
|
||||
*
|
||||
* @param repo_out pointer to the repo which will be created or reinitialized
|
||||
* @param out pointer to the repo which will be created or reinitialized
|
||||
* @param path the path to the repository
|
||||
* @param is_bare if true, a Git repository without a working directory is created
|
||||
* at the pointed path. If false, provided path will be considered as the working
|
||||
* directory into which the .git directory will be created.
|
||||
* @param is_bare if true, a Git repository without a working directory is
|
||||
* created at the pointed path. If false, provided path will be
|
||||
* considered as the working directory into which the .git directory
|
||||
* will be created.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_init(git_repository **repo_out, const char *path, unsigned is_bare);
|
||||
GIT_EXTERN(int) git_repository_init(
|
||||
git_repository **out,
|
||||
const char *path,
|
||||
unsigned is_bare);
|
||||
|
||||
/**
|
||||
* Option flags for `git_repository_init_ext`.
|
||||
*
|
||||
* These flags configure extra behaviors to `git_repository_init_ext`.
|
||||
* In every case, the default behavior is the zero value (i.e. flag is
|
||||
* not set). Just OR the flag values together for the `flags` parameter
|
||||
* when initializing a new repo. Details of individual values are:
|
||||
*
|
||||
* * BARE - Create a bare repository with no working directory.
|
||||
* * NO_REINIT - Return an EEXISTS error if the repo_path appears to
|
||||
* already be an git repository.
|
||||
* * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo
|
||||
* path for non-bare repos (if it is not already there), but
|
||||
* passing this flag prevents that behavior.
|
||||
* * MKDIR - Make the repo_path (and workdir_path) as needed. Init is
|
||||
* always willing to create the ".git" directory even without this
|
||||
* flag. This flag tells init to create the trailing component of
|
||||
* the repo and workdir paths as needed.
|
||||
* * MKPATH - Recursively make all components of the repo and workdir
|
||||
* paths as necessary.
|
||||
* * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to
|
||||
* initialize a new repo. This flags enables external templates,
|
||||
* looking the "template_path" from the options if set, or the
|
||||
* `init.templatedir` global config if not, or falling back on
|
||||
* "/usr/share/git-core/templates" if it exists.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_REPOSITORY_INIT_BARE = (1u << 0),
|
||||
GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1),
|
||||
GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2),
|
||||
GIT_REPOSITORY_INIT_MKDIR = (1u << 3),
|
||||
GIT_REPOSITORY_INIT_MKPATH = (1u << 4),
|
||||
GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5),
|
||||
} git_repository_init_flag_t;
|
||||
|
||||
/**
|
||||
* Mode options for `git_repository_init_ext`.
|
||||
*
|
||||
* Set the mode field of the `git_repository_init_options` structure
|
||||
* either to the custom mode that you would like, or to one of the
|
||||
* following modes:
|
||||
*
|
||||
* * SHARED_UMASK - Use permissions configured by umask - the default.
|
||||
* * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo
|
||||
* to be group writable and "g+sx" for sticky group assignment.
|
||||
* * SHARED_ALL - Use "--shared=all" behavior, adding world readability.
|
||||
* * Anything else - Set to custom value.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_REPOSITORY_INIT_SHARED_UMASK = 0,
|
||||
GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775,
|
||||
GIT_REPOSITORY_INIT_SHARED_ALL = 0002777,
|
||||
} git_repository_init_mode_t;
|
||||
|
||||
/**
|
||||
* Extended options structure for `git_repository_init_ext`.
|
||||
*
|
||||
* This contains extra options for `git_repository_init_ext` that enable
|
||||
* additional initialization features. The fields are:
|
||||
*
|
||||
* * flags - Combination of GIT_REPOSITORY_INIT flags above.
|
||||
* * mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_...
|
||||
* constants above, or to a custom value that you would like.
|
||||
* * workdir_path - The path to the working dir or NULL for default (i.e.
|
||||
* repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH,
|
||||
* IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not
|
||||
* the "natural" working directory, a .git gitlink file will be
|
||||
* created here linking to the repo_path.
|
||||
* * description - If set, this will be used to initialize the "description"
|
||||
* file in the repository, instead of using the template content.
|
||||
* * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set,
|
||||
* this contains the path to use for the template directory. If
|
||||
* this is NULL, the config or default directory options will be
|
||||
* used instead.
|
||||
* * initial_head - The name of the head to point HEAD at. If NULL, then
|
||||
* this will be treated as "master" and the HEAD ref will be set
|
||||
* to "refs/heads/master". If this begins with "refs/" it will be
|
||||
* used verbatim; otherwise "refs/heads/" will be prefixed.
|
||||
* * origin_url - If this is non-NULL, then after the rest of the
|
||||
* repository initialization is completed, an "origin" remote
|
||||
* will be added pointing to this URL.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int version;
|
||||
uint32_t flags;
|
||||
uint32_t mode;
|
||||
const char *workdir_path;
|
||||
const char *description;
|
||||
const char *template_path;
|
||||
const char *initial_head;
|
||||
const char *origin_url;
|
||||
} git_repository_init_options;
|
||||
|
||||
#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1
|
||||
#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION}
|
||||
|
||||
/**
|
||||
* Create a new Git repository in the given folder with extended controls.
|
||||
*
|
||||
* This will initialize a new git repository (creating the repo_path
|
||||
* if requested by flags) and working directory as needed. It will
|
||||
* auto-detect the case sensitivity of the file system and if the
|
||||
* file system supports file mode bits correctly.
|
||||
*
|
||||
* @param out Pointer to the repo which will be created or reinitialized.
|
||||
* @param repo_path The path to the repository.
|
||||
* @param opts Pointer to git_repository_init_options struct.
|
||||
* @return 0 or an error code on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_init_ext(
|
||||
git_repository **out,
|
||||
const char *repo_path,
|
||||
git_repository_init_options *opts);
|
||||
|
||||
/**
|
||||
* Retrieve and resolve the reference pointed at by HEAD.
|
||||
*
|
||||
* @param head_out pointer to the reference which will be retrieved
|
||||
* The returned `git_reference` will be owned by caller and
|
||||
* `git_reference_free()` must be called when done with it to release the
|
||||
* allocated memory and prevent a leak.
|
||||
*
|
||||
* @param out pointer to the reference which will be retrieved
|
||||
* @param repo a repository object
|
||||
*
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
|
||||
* branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_head(git_reference **head_out, git_repository *repo);
|
||||
GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Check if a repository's HEAD is detached
|
||||
@ -130,7 +292,7 @@ GIT_EXTERN(int) git_repository_head(git_reference **head_out, git_repository *re
|
||||
* instead of a branch.
|
||||
*
|
||||
* @param repo Repo to test
|
||||
* @return 1 if HEAD is detached, 0 if i'ts not; error code if there
|
||||
* @return 1 if HEAD is detached, 0 if it's not; error code if there
|
||||
* was an error.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
|
||||
@ -143,7 +305,7 @@ GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
|
||||
*
|
||||
* @param repo Repo to test
|
||||
* @return 1 if the current branch is an orphan, 0 if it's not; error
|
||||
* code if therewas an error
|
||||
* code if there was an error
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo);
|
||||
|
||||
@ -151,7 +313,7 @@ GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo);
|
||||
* Check if a repository is empty
|
||||
*
|
||||
* An empty repository has just been initialized and contains
|
||||
* no commits.
|
||||
* no references.
|
||||
*
|
||||
* @param repo Repo to test
|
||||
* @return 1 if the repository is empty, 0 if it isn't, error code
|
||||
@ -194,9 +356,12 @@ GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @param workdir The path to a working directory
|
||||
* @param update_gitlink Create/update gitlink in workdir and set config
|
||||
* "core.worktree" (if workdir is not the parent of the .git directory)
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_set_workdir(git_repository *repo, const char *workdir);
|
||||
GIT_EXTERN(int) git_repository_set_workdir(
|
||||
git_repository *repo, const char *workdir, int update_gitlink);
|
||||
|
||||
/**
|
||||
* Check if a repository is bare
|
||||
@ -268,6 +433,39 @@ GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);
|
||||
*/
|
||||
GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
|
||||
|
||||
/**
|
||||
* Get the Reference Database Backend for this repository.
|
||||
*
|
||||
* If a custom refsdb has not been set, the default database for
|
||||
* the repository will be returned (the one that manipulates loose
|
||||
* and packed references in the `.git` directory).
|
||||
*
|
||||
* The refdb must be freed once it's no longer being used by
|
||||
* the user.
|
||||
*
|
||||
* @param out Pointer to store the loaded refdb
|
||||
* @param repo A repository object
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_refdb(git_refdb **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Set the Reference Database Backend for this repository
|
||||
*
|
||||
* The refdb will be used for all reference related operations
|
||||
* involving this repository.
|
||||
*
|
||||
* The repository will keep a reference to the refdb; the user
|
||||
* must still free the refdb object after setting it to the
|
||||
* repository, or it will leak.
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @param refdb An refdb object
|
||||
*/
|
||||
GIT_EXTERN(void) git_repository_set_refdb(
|
||||
git_repository *repo,
|
||||
git_refdb *refdb);
|
||||
|
||||
/**
|
||||
* Get the Index file for this repository.
|
||||
*
|
||||
@ -299,6 +497,184 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
|
||||
*/
|
||||
GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
|
||||
|
||||
/**
|
||||
* Retrieve git's prepared message
|
||||
*
|
||||
* Operations such as git revert/cherry-pick/merge with the -n option
|
||||
* stop just short of creating a commit with the changes and save
|
||||
* their prepared message in .git/MERGE_MSG so the next git-commit
|
||||
* execution can present it to the user for them to amend if they
|
||||
* wish.
|
||||
*
|
||||
* Use this function to get the contents of this file. Don't forget to
|
||||
* remove the file after you create the commit.
|
||||
*
|
||||
* @param out Buffer to write data into or NULL to just read required size
|
||||
* @param len Length of buffer in bytes
|
||||
* @param repo Repository to read prepared message from
|
||||
* @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Remove git's prepared message.
|
||||
*
|
||||
* Remove the message that `git_repository_message` retrieves.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_message_remove(git_repository *repo);
|
||||
|
||||
/**
|
||||
* Remove all the metadata associated with an ongoing git merge, including
|
||||
* MERGE_HEAD, MERGE_MSG, etc.
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @return 0 on success, or error
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_merge_cleanup(git_repository *repo);
|
||||
|
||||
typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name,
|
||||
const char *remote_url,
|
||||
const git_oid *oid,
|
||||
unsigned int is_merge,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Call callback 'callback' for each entry in the given FETCH_HEAD file.
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @param callback Callback function
|
||||
* @param payload Pointer to callback data (optional)
|
||||
* @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_fetchhead_foreach(git_repository *repo,
|
||||
git_repository_fetchhead_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* If a merge is in progress, call callback 'cb' for each commit ID in the
|
||||
* MERGE_HEAD file.
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @param callback Callback function
|
||||
* @param apyload Pointer to callback data (optional)
|
||||
* @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo,
|
||||
git_repository_mergehead_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Calculate hash of file using repository filtering rules.
|
||||
*
|
||||
* If you simply want to calculate the hash of a file on disk with no filters,
|
||||
* you can just use the `git_odb_hashfile()` API. However, if you want to
|
||||
* hash a file in the repository and you want to apply filtering rules (e.g.
|
||||
* crlf filters) before generating the SHA, then use this function.
|
||||
*
|
||||
* @param out Output value of calculated SHA
|
||||
* @param repo Repository pointer
|
||||
* @param path Path to file on disk whose contents should be hashed. If the
|
||||
* repository is not NULL, this can be a relative path.
|
||||
* @param type The object type to hash as (e.g. GIT_OBJ_BLOB)
|
||||
* @param as_path The path to use to look up filtering rules. If this is
|
||||
* NULL, then the `path` parameter will be used instead. If
|
||||
* this is passed as the empty string, then no filters will be
|
||||
* applied when calculating the hash.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_hashfile(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
const char *path,
|
||||
git_otype type,
|
||||
const char *as_path);
|
||||
|
||||
/**
|
||||
* Make the repository HEAD point to the specified reference.
|
||||
*
|
||||
* If the provided reference points to a Tree or a Blob, the HEAD is
|
||||
* unaltered and -1 is returned.
|
||||
*
|
||||
* If the provided reference points to a branch, the HEAD will point
|
||||
* to that branch, staying attached, or become attached if it isn't yet.
|
||||
* If the branch doesn't exist yet, no error will be return. The HEAD
|
||||
* will then be attached to an unborn branch.
|
||||
*
|
||||
* Otherwise, the HEAD will be detached and will directly point to
|
||||
* the Commit.
|
||||
*
|
||||
* @param repo Repository pointer
|
||||
* @param refname Canonical name of the reference the HEAD should point at
|
||||
* @return 0 on success, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_set_head(
|
||||
git_repository* repo,
|
||||
const char* refname);
|
||||
|
||||
/**
|
||||
* Make the repository HEAD directly point to the Commit.
|
||||
*
|
||||
* If the provided committish cannot be found in the repository, the HEAD
|
||||
* is unaltered and GIT_ENOTFOUND is returned.
|
||||
*
|
||||
* If the provided commitish cannot be peeled into a commit, the HEAD
|
||||
* is unaltered and -1 is returned.
|
||||
*
|
||||
* Otherwise, the HEAD will eventually be detached and will directly point to
|
||||
* the peeled Commit.
|
||||
*
|
||||
* @param repo Repository pointer
|
||||
* @param commitish Object id of the Commit the HEAD should point to
|
||||
* @return 0 on success, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_set_head_detached(
|
||||
git_repository* repo,
|
||||
const git_oid* commitish);
|
||||
|
||||
/**
|
||||
* Detach the HEAD.
|
||||
*
|
||||
* If the HEAD is already detached and points to a Commit, 0 is returned.
|
||||
*
|
||||
* If the HEAD is already detached and points to a Tag, the HEAD is
|
||||
* updated into making it point to the peeled Commit, and 0 is returned.
|
||||
*
|
||||
* If the HEAD is already detached and points to a non commitish, the HEAD is
|
||||
* unaltered, and -1 is returned.
|
||||
*
|
||||
* Otherwise, the HEAD will be detached and point to the peeled Commit.
|
||||
*
|
||||
* @param repo Repository pointer
|
||||
* @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing
|
||||
* branch or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_detach_head(
|
||||
git_repository* repo);
|
||||
|
||||
typedef enum {
|
||||
GIT_REPOSITORY_STATE_NONE,
|
||||
GIT_REPOSITORY_STATE_MERGE,
|
||||
GIT_REPOSITORY_STATE_REVERT,
|
||||
GIT_REPOSITORY_STATE_CHERRY_PICK,
|
||||
GIT_REPOSITORY_STATE_BISECT,
|
||||
GIT_REPOSITORY_STATE_REBASE,
|
||||
GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
|
||||
GIT_REPOSITORY_STATE_REBASE_MERGE,
|
||||
GIT_REPOSITORY_STATE_APPLY_MAILBOX,
|
||||
GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE,
|
||||
} git_repository_state_t;
|
||||
|
||||
/**
|
||||
* Determines the status of a git repository - ie, whether an operation
|
||||
* (merge, cherry-pick, etc) is in progress.
|
||||
*
|
||||
* @param repo Repository pointer
|
||||
* @return The state of the repository
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_state(git_repository *repo);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
81
include/git2/reset.h
Normal file
81
include/git2/reset.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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_git_reset_h__
|
||||
#define INCLUDE_git_reset_h__
|
||||
|
||||
/**
|
||||
* @file git2/reset.h
|
||||
* @brief Git reset management routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Kinds of reset operation
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_RESET_SOFT = 1, /** Move the head to the given commit */
|
||||
GIT_RESET_MIXED = 2, /** SOFT plus reset index to the commit */
|
||||
GIT_RESET_HARD = 3, /** MIXED plus changes in working tree discarded */
|
||||
} git_reset_t;
|
||||
|
||||
/**
|
||||
* Sets the current head to the specified commit oid and optionally
|
||||
* resets the index and working tree to match.
|
||||
*
|
||||
* SOFT reset means the Head will be moved to the commit.
|
||||
*
|
||||
* MIXED reset will trigger a SOFT reset, plus the index will be replaced
|
||||
* with the content of the commit tree.
|
||||
*
|
||||
* HARD reset will trigger a MIXED reset and the working directory will be
|
||||
* replaced with the content of the index. (Untracked and ignored files
|
||||
* will be left alone, however.)
|
||||
*
|
||||
* TODO: Implement remaining kinds of resets.
|
||||
*
|
||||
* @param repo Repository where to perform the reset operation.
|
||||
*
|
||||
* @param target Committish to which the Head should be moved to. This object
|
||||
* must belong to the given `repo` and can either be a git_commit or a
|
||||
* git_tag. When a git_tag is being passed, it should be dereferencable
|
||||
* to a git_commit which oid will be used as the target of the branch.
|
||||
*
|
||||
* @param reset_type Kind of reset operation to perform.
|
||||
*
|
||||
* @return 0 on success or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reset(
|
||||
git_repository *repo, git_object *target, git_reset_t reset_type);
|
||||
|
||||
/**
|
||||
* Updates some entries in the index from the target commit tree.
|
||||
*
|
||||
* The scope of the updated entries is determined by the paths
|
||||
* being passed in the `pathspec` parameters.
|
||||
*
|
||||
* Passing a NULL `target` will result in removing
|
||||
* entries in the index matching the provided pathspecs.
|
||||
*
|
||||
* @param repo Repository where to perform the reset operation.
|
||||
*
|
||||
* @param target The committish which content will be used to reset the content
|
||||
* of the index.
|
||||
*
|
||||
* @param pathspecs List of pathspecs to operate on.
|
||||
*
|
||||
* @return 0 on success or an error code < 0
|
||||
*/
|
||||
GIT_EXTERN(int) git_reset_default(
|
||||
git_repository *repo,
|
||||
git_object *target,
|
||||
git_strarray* pathspecs);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
80
include/git2/revparse.h
Normal file
80
include/git2/revparse.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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_git_revparse_h__
|
||||
#define INCLUDE_git_revparse_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
/**
|
||||
* @file git2/revparse.h
|
||||
* @brief Git revision parsing routines
|
||||
* @defgroup git_revparse Git revision parsing routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Find a single object, as specified by a revision string. See `man gitrevisions`,
|
||||
* or http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for
|
||||
* information on the syntax accepted.
|
||||
*
|
||||
* @param out pointer to output object
|
||||
* @param repo the repository to search in
|
||||
* @param spec the textual specification for an object
|
||||
* @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, GIT_EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revparse_single(git_object **out, git_repository *repo, const char *spec);
|
||||
|
||||
|
||||
/**
|
||||
* Revparse flags. These indicate the intended behavior of the spec passed to
|
||||
* git_revparse.
|
||||
*/
|
||||
typedef enum {
|
||||
/** The spec targeted a single object. */
|
||||
GIT_REVPARSE_SINGLE = 1 << 0,
|
||||
/** The spec targeted a range of commits. */
|
||||
GIT_REVPARSE_RANGE = 1 << 1,
|
||||
/** The spec used the '...' operator, which invokes special semantics. */
|
||||
GIT_REVPARSE_MERGE_BASE = 1 << 2,
|
||||
} git_revparse_mode_t;
|
||||
|
||||
/**
|
||||
* Git Revision Spec: output of a `git_revparse` operation
|
||||
*/
|
||||
typedef struct {
|
||||
/** The left element of the revspec; must be freed by the user */
|
||||
git_object *from;
|
||||
/** The right element of the revspec; must be freed by the user */
|
||||
git_object *to;
|
||||
/** The intent of the revspec */
|
||||
unsigned int flags;
|
||||
} git_revspec;
|
||||
|
||||
/**
|
||||
* Parse a revision string for `from`, `to`, and intent. See `man gitrevisions` or
|
||||
* http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions for information
|
||||
* on the syntax accepted.
|
||||
*
|
||||
* @param revspec Pointer to an user-allocated git_revspec struct where the result
|
||||
* of the rev-parse will be stored
|
||||
* @param repo the repository to search in
|
||||
* @param spec the rev-parse spec to parse
|
||||
* @return 0 on success, GIT_INVALIDSPEC, GIT_ENOTFOUND, GIT_EAMBIGUOUS or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revparse(
|
||||
git_revspec *revspec,
|
||||
git_repository *repo,
|
||||
const char *spec);
|
||||
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -63,11 +63,11 @@ GIT_BEGIN_DECL
|
||||
* it is possible to have several revision walkers in
|
||||
* several different threads walking the same repository.
|
||||
*
|
||||
* @param walker pointer to the new revision walker
|
||||
* @param out pointer to the new revision walker
|
||||
* @param repo the repo to walk through
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_new(git_revwalk **walker, git_repository *repo);
|
||||
GIT_EXTERN(int) git_revwalk_new(git_revwalk **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Reset the revision walker for reuse.
|
||||
@ -92,22 +92,22 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
|
||||
*
|
||||
* The given commit will be used as one of the roots
|
||||
* when starting the revision walk. At least one commit
|
||||
* must be pushed the repository before a walk can
|
||||
* must be pushed onto the walker before a walk can
|
||||
* be started.
|
||||
*
|
||||
* @param walk the walker being used for the traversal.
|
||||
* @param oid the oid of the commit to start from.
|
||||
* @param id the oid of the commit to start from.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid);
|
||||
GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Push matching references
|
||||
*
|
||||
* The OIDs pinted to by the references that match the given glob
|
||||
* The OIDs pointed to by the references that match the given glob
|
||||
* pattern will be pushed to the revision walker.
|
||||
*
|
||||
* A leading 'refs/' is implied it not present as well as a trailing
|
||||
* A leading 'refs/' is implied if not present as well as a trailing
|
||||
* '/ *' if the glob lacks '?', '*' or '['.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
@ -134,19 +134,19 @@ GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
|
||||
* output on the revision walk.
|
||||
*
|
||||
* @param walk the walker being used for the traversal.
|
||||
* @param oid the oid of commit that will be ignored during the traversal
|
||||
* @param commit_id the oid of commit that will be ignored during the traversal
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid);
|
||||
GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id);
|
||||
|
||||
/**
|
||||
* Hide matching references.
|
||||
*
|
||||
* The OIDs pinted to by the references that match the given glob
|
||||
* The OIDs pointed to by the references that match the given glob
|
||||
* pattern and their ancestors will be hidden from the output on the
|
||||
* revision walk.
|
||||
*
|
||||
* A leading 'refs/' is implied it not present as well as a trailing
|
||||
* A leading 'refs/' is implied if not present as well as a trailing
|
||||
* '/ *' if the glob lacks '?', '*' or '['.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
@ -169,7 +169,7 @@ GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
|
||||
* The reference must point to a commit.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param refname the referece to push
|
||||
* @param refname the reference to push
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
|
||||
@ -180,7 +180,7 @@ GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
|
||||
* The reference must point to a commit.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param refname the referece to hide
|
||||
* @param refname the reference to hide
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
|
||||
@ -198,12 +198,12 @@ GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
|
||||
*
|
||||
* The revision walker is reset when the walk is over.
|
||||
*
|
||||
* @param oid Pointer where to store the oid of the next commit
|
||||
* @param out Pointer where to store the oid of the next commit
|
||||
* @param walk the walker to pop the commit from.
|
||||
* @return 0 if the next commit was found;
|
||||
* GIT_REVWALKOVER if there are no commits left to iterate
|
||||
* GIT_ITEROVER if there are no commits left to iterate
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
|
||||
GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk);
|
||||
|
||||
/**
|
||||
* Change the sorting mode when iterating through the
|
||||
@ -216,6 +216,21 @@ GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
|
||||
*/
|
||||
GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode);
|
||||
|
||||
/**
|
||||
* Push and hide the respective endpoints of the given range.
|
||||
*
|
||||
* The range should be of the form
|
||||
* <commit>..<commit>
|
||||
* where each <commit> is in the form accepted by 'git_revparse_single'.
|
||||
* The left-hand commit will be hidden and the right-hand commit pushed.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param range the range
|
||||
* @return 0 or an error code
|
||||
*
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range);
|
||||
|
||||
/**
|
||||
* Free a revision walker previously allocated.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -20,41 +20,52 @@
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Create a new action signature. The signature must be freed
|
||||
* manually or using git_signature_free
|
||||
* Create a new action signature.
|
||||
*
|
||||
* @param sig_out new signature, in case of error NULL
|
||||
* Call `git_signature_free()` to free the data.
|
||||
*
|
||||
* Note: angle brackets ('<' and '>') characters are not allowed
|
||||
* to be used in either the `name` or the `email` parameter.
|
||||
*
|
||||
* @param out new signature, in case of error NULL
|
||||
* @param name name of the person
|
||||
* @param email email of the person
|
||||
* @param time time when the action happened
|
||||
* @param offset timezone offset in minutes for the time
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset);
|
||||
GIT_EXTERN(int) git_signature_new(git_signature **out, const char *name, const char *email, git_time_t time, int offset);
|
||||
|
||||
/**
|
||||
* Create a new action signature with a timestamp of 'now'. The
|
||||
* signature must be freed manually or using git_signature_free
|
||||
* Create a new action signature with a timestamp of 'now'.
|
||||
*
|
||||
* @param sig_out new signature, in case of error NULL
|
||||
* Call `git_signature_free()` to free the data.
|
||||
*
|
||||
* @param out new signature, in case of error NULL
|
||||
* @param name name of the person
|
||||
* @param email email of the person
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_signature_now(git_signature **sig_out, const char *name, const char *email);
|
||||
GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email);
|
||||
|
||||
|
||||
/**
|
||||
* Create a copy of an existing signature.
|
||||
* Create a copy of an existing signature. All internal strings are also
|
||||
* duplicated.
|
||||
*
|
||||
* Call `git_signature_free()` to free the data.
|
||||
*
|
||||
* All internal strings are also duplicated.
|
||||
* @param sig signature to duplicated
|
||||
* @return a copy of sig, NULL on out of memory
|
||||
*/
|
||||
GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig);
|
||||
|
||||
/**
|
||||
* Free an existing signature
|
||||
* Free an existing signature.
|
||||
*
|
||||
* Because the signature is not an opaque structure, it is legal to free it
|
||||
* manually, but be sure to free the "name" and "email" strings in addition
|
||||
* to the structure itself.
|
||||
*
|
||||
* @param sig signature to free
|
||||
*/
|
||||
|
121
include/git2/stash.h
Normal file
121
include/git2/stash.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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_git_stash_h__
|
||||
#define INCLUDE_git_stash_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
|
||||
/**
|
||||
* @file git2/stash.h
|
||||
* @brief Git stash management routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
typedef enum {
|
||||
GIT_STASH_DEFAULT = 0,
|
||||
|
||||
/* All changes already added to the index
|
||||
* are left intact in the working directory
|
||||
*/
|
||||
GIT_STASH_KEEP_INDEX = (1 << 0),
|
||||
|
||||
/* All untracked files are also stashed and then
|
||||
* cleaned up from the working directory
|
||||
*/
|
||||
GIT_STASH_INCLUDE_UNTRACKED = (1 << 1),
|
||||
|
||||
/* All ignored files are also stashed and then
|
||||
* cleaned up from the working directory
|
||||
*/
|
||||
GIT_STASH_INCLUDE_IGNORED = (1 << 2),
|
||||
} git_stash_flags;
|
||||
|
||||
/**
|
||||
* Save the local modifications to a new stash.
|
||||
*
|
||||
* @param out Object id of the commit containing the stashed state.
|
||||
* This commit is also the target of the direct reference refs/stash.
|
||||
*
|
||||
* @param repo The owning repository.
|
||||
*
|
||||
* @param stasher The identity of the person performing the stashing.
|
||||
*
|
||||
* @param message Optional description along with the stashed state.
|
||||
*
|
||||
* @param flags Flags to control the stashing process. (see GIT_STASH_* above)
|
||||
*
|
||||
* @return 0 on success, GIT_ENOTFOUND where there's nothing to stash,
|
||||
* or error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_stash_save(
|
||||
git_oid *out,
|
||||
git_repository *repo,
|
||||
git_signature *stasher,
|
||||
const char *message,
|
||||
unsigned int flags);
|
||||
|
||||
/**
|
||||
* When iterating over all the stashed states, callback that will be
|
||||
* issued per entry.
|
||||
*
|
||||
* @param index The position within the stash list. 0 points to the
|
||||
* most recent stashed state.
|
||||
*
|
||||
* @param message The stash message.
|
||||
*
|
||||
* @param stash_id The commit oid of the stashed state.
|
||||
*
|
||||
* @param payload Extra parameter to callback function.
|
||||
*
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
typedef int (*git_stash_cb)(
|
||||
size_t index,
|
||||
const char* message,
|
||||
const git_oid *stash_id,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Loop over all the stashed states and issue a callback for each one.
|
||||
*
|
||||
* If the callback returns a non-zero value, this will stop looping.
|
||||
*
|
||||
* @param repo Repository where to find the stash.
|
||||
*
|
||||
* @param callabck Callback to invoke per found stashed state. The most recent
|
||||
* stash state will be enumerated first.
|
||||
*
|
||||
* @param payload Extra parameter to callback function.
|
||||
*
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_stash_foreach(
|
||||
git_repository *repo,
|
||||
git_stash_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Remove a single stashed state from the stash list.
|
||||
*
|
||||
* @param repo The owning repository.
|
||||
*
|
||||
* @param index The position within the stash list. 0 points to the
|
||||
* most recent stashed state.
|
||||
*
|
||||
* @return 0 on success, or error code
|
||||
*/
|
||||
|
||||
GIT_EXTERN(int) git_stash_drop(
|
||||
git_repository *repo,
|
||||
size_t index);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -19,38 +19,67 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
enum {
|
||||
GIT_STATUS_CURRENT = 0,
|
||||
/**
|
||||
* Status flags for a single file.
|
||||
*
|
||||
* A combination of these values will be returned to indicate the status of
|
||||
* a file. Status compares the working directory, the index, and the
|
||||
* current HEAD of the repository. The `GIT_STATUS_INDEX` set of flags
|
||||
* represents the status of file in the index relative to the HEAD, and the
|
||||
* `GIT_STATUS_WT` set of flags represent the status of the file in the
|
||||
* working directory relative to the index.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_STATUS_CURRENT = 0,
|
||||
|
||||
GIT_STATUS_INDEX_NEW = (1 << 0),
|
||||
GIT_STATUS_INDEX_MODIFIED = (1 << 1),
|
||||
GIT_STATUS_INDEX_DELETED = (1 << 2),
|
||||
GIT_STATUS_INDEX_NEW = (1u << 0),
|
||||
GIT_STATUS_INDEX_MODIFIED = (1u << 1),
|
||||
GIT_STATUS_INDEX_DELETED = (1u << 2),
|
||||
GIT_STATUS_INDEX_RENAMED = (1u << 3),
|
||||
GIT_STATUS_INDEX_TYPECHANGE = (1u << 4),
|
||||
|
||||
GIT_STATUS_WT_NEW = (1 << 3),
|
||||
GIT_STATUS_WT_MODIFIED = (1 << 4),
|
||||
GIT_STATUS_WT_DELETED = (1 << 5),
|
||||
GIT_STATUS_WT_NEW = (1u << 7),
|
||||
GIT_STATUS_WT_MODIFIED = (1u << 8),
|
||||
GIT_STATUS_WT_DELETED = (1u << 9),
|
||||
GIT_STATUS_WT_TYPECHANGE = (1u << 10),
|
||||
|
||||
GIT_STATUS_IGNORED = (1 << 6),
|
||||
};
|
||||
GIT_STATUS_IGNORED = (1u << 14),
|
||||
} git_status_t;
|
||||
|
||||
/**
|
||||
* Function pointer to receive status on individual files
|
||||
*
|
||||
* `path` is the relative path to the file from the root of the repository.
|
||||
*
|
||||
* `status_flags` is a combination of `git_status_t` values that apply.
|
||||
*
|
||||
* `payload` is the value you passed to the foreach function as payload.
|
||||
*/
|
||||
typedef int (*git_status_cb)(
|
||||
const char *path, unsigned int status_flags, void *payload);
|
||||
|
||||
/**
|
||||
* Gather file statuses and run a callback for each one.
|
||||
*
|
||||
* The callback is passed the path of the file, the status and the data
|
||||
* pointer passed to this function. If the callback returns something other
|
||||
* than 0, this function will return that value.
|
||||
* The callback is passed the path of the file, the status (a combination of
|
||||
* the `git_status_t` values above) and the `payload` data pointer passed
|
||||
* into this function.
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @param callback the function to call on each file
|
||||
* @return 0 on success or the return value of the callback that was non-zero
|
||||
* If the callback returns a non-zero value, this function will stop looping
|
||||
* and return GIT_EUSER.
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @param callback The function to call on each file
|
||||
* @param payload Pointer to pass through to callback function
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_foreach(
|
||||
git_repository *repo,
|
||||
int (*callback)(const char *, unsigned int, void *),
|
||||
git_status_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Select the files on which to report status.
|
||||
* For extended status, select the files on which to report status.
|
||||
*
|
||||
* - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the
|
||||
* rough equivalent of `git status --porcelain` where each file
|
||||
@ -78,62 +107,108 @@ typedef enum {
|
||||
/**
|
||||
* Flags to control status callbacks
|
||||
*
|
||||
* - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should
|
||||
* be made on untracked files. These will only be made if the
|
||||
* workdir files are included in the status "show" option.
|
||||
* - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should
|
||||
* get callbacks. Again, these callbacks will only be made if
|
||||
* the workdir files are included in the status "show" option.
|
||||
* Right now, there is no option to include all files in
|
||||
* directories that are ignored completely.
|
||||
* - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback
|
||||
* should be made even on unmodified files.
|
||||
* - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories
|
||||
* which appear to be submodules should just be skipped over.
|
||||
* - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the
|
||||
* contents of untracked directories should be included in the
|
||||
* status. Normally if an entire directory is new, then just
|
||||
* the top-level directory will be included (with a trailing
|
||||
* slash on the entry name). Given this flag, the directory
|
||||
* itself will not be included, but all the files in it will.
|
||||
* - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made
|
||||
* on untracked files. These will only be made if the workdir files are
|
||||
* included in the status "show" option.
|
||||
* - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should get
|
||||
* callbacks. Again, these callbacks will only be made if the workdir
|
||||
* files are included in the status "show" option. Right now, there is
|
||||
* no option to include all files in directories that are ignored
|
||||
* completely.
|
||||
* - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be
|
||||
* made even on unmodified files.
|
||||
* - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories which
|
||||
* appear to be submodules should just be skipped over.
|
||||
* - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the contents of
|
||||
* untracked directories should be included in the status. Normally if
|
||||
* an entire directory is new, then just the top-level directory will be
|
||||
* included (with a trailing slash on the entry name). Given this flag,
|
||||
* the directory itself will not be included, but all the files in it
|
||||
* will.
|
||||
* - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path
|
||||
* will be treated as a literal path, and not as a pathspec.
|
||||
* - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS indicates that the contents of
|
||||
* ignored directories should be included in the status. This is like
|
||||
* doing `git ls-files -o -i --exclude-standard` with core git.
|
||||
*
|
||||
* Calling `git_status_foreach()` is like calling the extended version
|
||||
* with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
|
||||
* and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. Those options are bundled
|
||||
* together as `GIT_STATUS_OPT_DEFAULTS` if you want them as a baseline.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1u << 0),
|
||||
GIT_STATUS_OPT_INCLUDE_IGNORED = (1u << 1),
|
||||
GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1u << 2),
|
||||
GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1u << 3),
|
||||
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1u << 4),
|
||||
GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1u << 5),
|
||||
GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6),
|
||||
} git_status_opt_t;
|
||||
|
||||
enum {
|
||||
GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0),
|
||||
GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1),
|
||||
GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2),
|
||||
GIT_STATUS_OPT_EXCLUDE_SUBMODULED = (1 << 3),
|
||||
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4),
|
||||
};
|
||||
#define GIT_STATUS_OPT_DEFAULTS \
|
||||
(GIT_STATUS_OPT_INCLUDE_IGNORED | \
|
||||
GIT_STATUS_OPT_INCLUDE_UNTRACKED | \
|
||||
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS)
|
||||
|
||||
/**
|
||||
* Options to control how callbacks will be made by
|
||||
* `git_status_foreach_ext()`.
|
||||
* Options to control how `git_status_foreach_ext()` will issue callbacks.
|
||||
*
|
||||
* This structure is set so that zeroing it out will give you relatively
|
||||
* sane defaults.
|
||||
*
|
||||
* The `show` value is one of the `git_status_show_t` constants that
|
||||
* control which files to scan and in what order.
|
||||
*
|
||||
* The `flags` value is an OR'ed combination of the `git_status_opt_t`
|
||||
* values above.
|
||||
*
|
||||
* The `pathspec` is an array of path patterns to match (using
|
||||
* fnmatch-style matching), or just an array of paths to match exactly if
|
||||
* `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int version;
|
||||
git_status_show_t show;
|
||||
unsigned int flags;
|
||||
git_strarray pathspec;
|
||||
unsigned int flags;
|
||||
git_strarray pathspec;
|
||||
} git_status_options;
|
||||
|
||||
#define GIT_STATUS_OPTIONS_VERSION 1
|
||||
#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION}
|
||||
|
||||
/**
|
||||
* Gather file status information and run callbacks as requested.
|
||||
*
|
||||
* This is an extended version of the `git_status_foreach()` API that
|
||||
* allows for more granular control over which paths will be processed and
|
||||
* in what order. See the `git_status_options` structure for details
|
||||
* about the additional controls that this makes available.
|
||||
*
|
||||
* @param repo Repository object
|
||||
* @param opts Status options structure
|
||||
* @param callback The function to call on each file
|
||||
* @param payload Pointer to pass through to callback function
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_foreach_ext(
|
||||
git_repository *repo,
|
||||
const git_status_options *opts,
|
||||
int (*callback)(const char *, unsigned int, void *),
|
||||
git_status_cb callback,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Get file status for a single file
|
||||
* Get file status for a single file.
|
||||
*
|
||||
* @param status_flags the status value
|
||||
* @param repo a repository object
|
||||
* @param path the file to retrieve status for, rooted at the repo's workdir
|
||||
* @return GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when
|
||||
* the file doesn't exist in any of HEAD, the index or the worktree,
|
||||
* 0 otherwise
|
||||
* This is not quite the same as calling `git_status_foreach_ext()` with
|
||||
* the pathspec set to the specified path.
|
||||
*
|
||||
* @param status_flags The status value for the file
|
||||
* @param repo A repository object
|
||||
* @param path The file to retrieve status for, rooted at the repo's workdir
|
||||
* @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD,
|
||||
* index, and work tree, GIT_EINVALIDPATH if `path` points at a folder,
|
||||
* GIT_EAMBIGUOUS if "path" matches multiple files, -1 on other error.
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_file(
|
||||
unsigned int *status_flags,
|
||||
@ -143,14 +218,16 @@ GIT_EXTERN(int) git_status_file(
|
||||
/**
|
||||
* Test if the ignore rules apply to a given file.
|
||||
*
|
||||
* This function simply checks the ignore rules to see if they would apply
|
||||
* to the given file. Unlike git_status_file(), this indicates if the file
|
||||
* would be ignored regardless of whether the file is already in the index
|
||||
* or in the repository.
|
||||
* This function checks the ignore rules to see if they would apply to the
|
||||
* given file. This indicates if the file would be ignored regardless of
|
||||
* whether the file is already in the index or committed to the repository.
|
||||
*
|
||||
* @param ignored boolean returning 0 if the file is not ignored, 1 if it is
|
||||
* @param repo a repository object
|
||||
* @param path the file to check ignores for, rooted at the repo's workdir.
|
||||
* One way to think of this is if you were to do "git add ." on the
|
||||
* directory containing the file, would it be added or not?
|
||||
*
|
||||
* @param ignored Boolean returning 0 if the file is not ignored, 1 if it is
|
||||
* @param repo A repository object
|
||||
* @param path The file to check ignores for, rooted at the repo's workdir.
|
||||
* @return 0 if ignore rules could be processed for the file (regardless
|
||||
* of whether it exists or not), or an error < 0 if they could not.
|
||||
*/
|
||||
|
60
include/git2/strarray.h
Normal file
60
include/git2/strarray.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_git_strarray_h__
|
||||
#define INCLUDE_git_strarray_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/strarray.h
|
||||
* @brief Git string array routines
|
||||
* @defgroup git_strarray Git string array routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/** Array of strings */
|
||||
typedef struct git_strarray {
|
||||
char **strings;
|
||||
size_t count;
|
||||
} git_strarray;
|
||||
|
||||
/**
|
||||
* Close a string array object
|
||||
*
|
||||
* This method should be called on `git_strarray` objects where the strings
|
||||
* array is allocated and contains allocated strings, such as what you
|
||||
* would get from `git_strarray_copy()`. Not doing so, will result in a
|
||||
* memory leak.
|
||||
*
|
||||
* This does not free the `git_strarray` itself, since the library will
|
||||
* never allocate that object directly itself (it is more commonly embedded
|
||||
* inside another struct or created on the stack).
|
||||
*
|
||||
* @param array git_strarray from which to free string data
|
||||
*/
|
||||
GIT_EXTERN(void) git_strarray_free(git_strarray *array);
|
||||
|
||||
/**
|
||||
* Copy a string array object from source to target.
|
||||
*
|
||||
* Note: target is overwritten and hence should be empty, otherwise its
|
||||
* contents are leaked. Call git_strarray_free() if necessary.
|
||||
*
|
||||
* @param tgt target
|
||||
* @param src source
|
||||
* @return 0 on success, < 0 on allocation failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
|
||||
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -20,54 +20,177 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Opaque structure representing a submodule.
|
||||
*
|
||||
* Submodule support in libgit2 builds a list of known submodules and keeps
|
||||
* it in the repository. The list is built from the .gitmodules file, the
|
||||
* .git/config file, the index, and the HEAD tree. Items in the working
|
||||
* directory that look like submodules (i.e. a git repo) but are not
|
||||
* mentioned in those places won't be tracked.
|
||||
*/
|
||||
typedef struct git_submodule git_submodule;
|
||||
|
||||
/**
|
||||
* Values that could be specified for the update rule of a submodule.
|
||||
*
|
||||
* Use the DEFAULT value if you have altered the update value via
|
||||
* `git_submodule_set_update()` and wish to reset to the original default.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_SUBMODULE_UPDATE_DEFAULT = -1,
|
||||
GIT_SUBMODULE_UPDATE_CHECKOUT = 0,
|
||||
GIT_SUBMODULE_UPDATE_REBASE = 1,
|
||||
GIT_SUBMODULE_UPDATE_MERGE = 2
|
||||
GIT_SUBMODULE_UPDATE_MERGE = 2,
|
||||
GIT_SUBMODULE_UPDATE_NONE = 3
|
||||
} git_submodule_update_t;
|
||||
|
||||
/**
|
||||
* Values that could be specified for how closely to examine the
|
||||
* working directory when getting submodule status.
|
||||
*
|
||||
* Use the DEFUALT value if you have altered the ignore value via
|
||||
* `git_submodule_set_ignore()` and wish to reset to the original value.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_SUBMODULE_IGNORE_ALL = 0, /* never dirty */
|
||||
GIT_SUBMODULE_IGNORE_DIRTY = 1, /* only dirty if HEAD moved */
|
||||
GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /* dirty if tracked files change */
|
||||
GIT_SUBMODULE_IGNORE_NONE = 3 /* any change or untracked == dirty */
|
||||
GIT_SUBMODULE_IGNORE_DEFAULT = -1, /* reset to default */
|
||||
GIT_SUBMODULE_IGNORE_NONE = 0, /* any change or untracked == dirty */
|
||||
GIT_SUBMODULE_IGNORE_UNTRACKED = 1, /* dirty if tracked files change */
|
||||
GIT_SUBMODULE_IGNORE_DIRTY = 2, /* only dirty if HEAD moved */
|
||||
GIT_SUBMODULE_IGNORE_ALL = 3 /* never dirty */
|
||||
} git_submodule_ignore_t;
|
||||
|
||||
/**
|
||||
* Description of submodule
|
||||
* Return codes for submodule status.
|
||||
*
|
||||
* This record describes a submodule found in a repository. There
|
||||
* should be an entry for every submodule found in the HEAD and for
|
||||
* every submodule described in .gitmodules. The fields are as follows:
|
||||
* A combination of these flags will be returned to describe the status of a
|
||||
* submodule. Depending on the "ignore" property of the submodule, some of
|
||||
* the flags may never be returned because they indicate changes that are
|
||||
* supposed to be ignored.
|
||||
*
|
||||
* - `name` is the name of the submodule from .gitmodules.
|
||||
* - `path` is the path to the submodule from the repo working directory.
|
||||
* It is almost always the same as `name`.
|
||||
* - `url` is the url for the submodule.
|
||||
* - `oid` is the HEAD SHA1 for the submodule.
|
||||
* - `update` is a value from above - see gitmodules(5) update.
|
||||
* - `ignore` is a value from above - see gitmodules(5) ignore.
|
||||
* - `fetch_recurse` is 0 or 1 - see gitmodules(5) fetchRecurseSubmodules.
|
||||
* - `refcount` is for internal use.
|
||||
* Submodule info is contained in 4 places: the HEAD tree, the index, config
|
||||
* files (both .git/config and .gitmodules), and the working directory. Any
|
||||
* or all of those places might be missing information about the submodule
|
||||
* depending on what state the repo is in. We consider all four places to
|
||||
* build the combination of status flags.
|
||||
*
|
||||
* If the submodule has been added to .gitmodules but not yet git added,
|
||||
* then the `oid` will be zero. If the submodule has been deleted, but
|
||||
* the delete has not been committed yet, then the `oid` will be set, but
|
||||
* the `url` will be NULL.
|
||||
* There are four values that are not really status, but give basic info
|
||||
* about what sources of submodule data are available. These will be
|
||||
* returned even if ignore is set to "ALL".
|
||||
*
|
||||
* * IN_HEAD - superproject head contains submodule
|
||||
* * IN_INDEX - superproject index contains submodule
|
||||
* * IN_CONFIG - superproject gitmodules has submodule
|
||||
* * IN_WD - superproject workdir has submodule
|
||||
*
|
||||
* The following values will be returned so long as ignore is not "ALL".
|
||||
*
|
||||
* * INDEX_ADDED - in index, not in head
|
||||
* * INDEX_DELETED - in head, not in index
|
||||
* * INDEX_MODIFIED - index and head don't match
|
||||
* * WD_UNINITIALIZED - workdir contains empty directory
|
||||
* * WD_ADDED - in workdir, not index
|
||||
* * WD_DELETED - in index, not workdir
|
||||
* * WD_MODIFIED - index and workdir head don't match
|
||||
*
|
||||
* The following can only be returned if ignore is "NONE" or "UNTRACKED".
|
||||
*
|
||||
* * WD_INDEX_MODIFIED - submodule workdir index is dirty
|
||||
* * WD_WD_MODIFIED - submodule workdir has modified files
|
||||
*
|
||||
* Lastly, the following will only be returned for ignore "NONE".
|
||||
*
|
||||
* * WD_UNTRACKED - wd contains untracked files
|
||||
*/
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *path;
|
||||
char *url;
|
||||
git_oid oid; /* sha1 of submodule HEAD ref or zero if not committed */
|
||||
git_submodule_update_t update;
|
||||
git_submodule_ignore_t ignore;
|
||||
int fetch_recurse;
|
||||
int refcount;
|
||||
} git_submodule;
|
||||
typedef enum {
|
||||
GIT_SUBMODULE_STATUS_IN_HEAD = (1u << 0),
|
||||
GIT_SUBMODULE_STATUS_IN_INDEX = (1u << 1),
|
||||
GIT_SUBMODULE_STATUS_IN_CONFIG = (1u << 2),
|
||||
GIT_SUBMODULE_STATUS_IN_WD = (1u << 3),
|
||||
GIT_SUBMODULE_STATUS_INDEX_ADDED = (1u << 4),
|
||||
GIT_SUBMODULE_STATUS_INDEX_DELETED = (1u << 5),
|
||||
GIT_SUBMODULE_STATUS_INDEX_MODIFIED = (1u << 6),
|
||||
GIT_SUBMODULE_STATUS_WD_UNINITIALIZED = (1u << 7),
|
||||
GIT_SUBMODULE_STATUS_WD_ADDED = (1u << 8),
|
||||
GIT_SUBMODULE_STATUS_WD_DELETED = (1u << 9),
|
||||
GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10),
|
||||
GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11),
|
||||
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12),
|
||||
GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13),
|
||||
} git_submodule_status_t;
|
||||
|
||||
#define GIT_SUBMODULE_STATUS__IN_FLAGS \
|
||||
(GIT_SUBMODULE_STATUS_IN_HEAD | \
|
||||
GIT_SUBMODULE_STATUS_IN_INDEX | \
|
||||
GIT_SUBMODULE_STATUS_IN_CONFIG | \
|
||||
GIT_SUBMODULE_STATUS_IN_WD)
|
||||
|
||||
#define GIT_SUBMODULE_STATUS__INDEX_FLAGS \
|
||||
(GIT_SUBMODULE_STATUS_INDEX_ADDED | \
|
||||
GIT_SUBMODULE_STATUS_INDEX_DELETED | \
|
||||
GIT_SUBMODULE_STATUS_INDEX_MODIFIED)
|
||||
|
||||
#define GIT_SUBMODULE_STATUS__WD_FLAGS \
|
||||
~(GIT_SUBMODULE_STATUS__IN_FLAGS | GIT_SUBMODULE_STATUS__INDEX_FLAGS)
|
||||
|
||||
#define GIT_SUBMODULE_STATUS_IS_UNMODIFIED(S) \
|
||||
(((S) & ~GIT_SUBMODULE_STATUS__IN_FLAGS) == 0)
|
||||
|
||||
#define GIT_SUBMODULE_STATUS_IS_INDEX_UNMODIFIED(S) \
|
||||
(((S) & GIT_SUBMODULE_STATUS__INDEX_FLAGS) == 0)
|
||||
|
||||
#define GIT_SUBMODULE_STATUS_IS_WD_UNMODIFIED(S) \
|
||||
(((S) & GIT_SUBMODULE_STATUS__WD_FLAGS) == 0)
|
||||
|
||||
#define GIT_SUBMODULE_STATUS_IS_WD_DIRTY(S) \
|
||||
(((S) & (GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED | \
|
||||
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED | \
|
||||
GIT_SUBMODULE_STATUS_WD_UNTRACKED)) != 0)
|
||||
|
||||
/**
|
||||
* Iterate over all submodules of a repository.
|
||||
* Lookup submodule information by name or path.
|
||||
*
|
||||
* Given either the submodule name or path (they are usually the same), this
|
||||
* returns a structure describing the submodule.
|
||||
*
|
||||
* There are two expected error scenarios:
|
||||
*
|
||||
* - The submodule is not mentioned in the HEAD, the index, and the config,
|
||||
* but does "exist" in the working directory (i.e. there is a subdirectory
|
||||
* that is a valid self-contained git repo). In this case, this function
|
||||
* returns GIT_EEXISTS to indicate the the submodule exists but not in a
|
||||
* state where a git_submodule can be instantiated.
|
||||
* - The submodule is not mentioned in the HEAD, index, or config and the
|
||||
* working directory doesn't contain a value git repo at that path.
|
||||
* There may or may not be anything else at that path, but nothing that
|
||||
* looks like a submodule. In this case, this returns GIT_ENOTFOUND.
|
||||
*
|
||||
* The submodule object is owned by the containing repo and will be freed
|
||||
* when the repo is freed. The caller need not free the submodule.
|
||||
*
|
||||
* @param submodule Pointer to submodule description object pointer..
|
||||
* @param repo The repository.
|
||||
* @param name The name of the submodule. Trailing slashes will be ignored.
|
||||
* @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
|
||||
* GIT_EEXISTS if submodule exists in working directory only, -1 on
|
||||
* other errors.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_lookup(
|
||||
git_submodule **submodule,
|
||||
git_repository *repo,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Iterate over all tracked submodules of a repository.
|
||||
*
|
||||
* See the note on `git_submodule` above. This iterates over the tracked
|
||||
* submodules as decribed therein.
|
||||
*
|
||||
* If you are concerned about items in the working directory that look like
|
||||
* submodules but are not tracked, the diff API will generate a diff record
|
||||
* for workdir items that look like submodules but are not tracked, showing
|
||||
* them as added in the workdir. Also, the status API will treat the entire
|
||||
* subdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item.
|
||||
*
|
||||
* @param repo The repository
|
||||
* @param callback Function to be called with the name of each submodule.
|
||||
@ -77,26 +200,344 @@ typedef struct {
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_foreach(
|
||||
git_repository *repo,
|
||||
int (*callback)(const char *name, void *payload),
|
||||
int (*callback)(git_submodule *sm, const char *name, void *payload),
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Lookup submodule information by name or path.
|
||||
* Set up a new git submodule for checkout.
|
||||
*
|
||||
* Given either the submodule name or path (they are ususally the same),
|
||||
* this returns a structure describing the submodule. If the submodule
|
||||
* does not exist, this will return GIT_ENOTFOUND and set the submodule
|
||||
* pointer to NULL.
|
||||
* This does "git submodule add" up to the fetch and checkout of the
|
||||
* submodule contents. It preps a new submodule, creates an entry in
|
||||
* .gitmodules and creates an empty initialized repository either at the
|
||||
* given path in the working directory or in .git/modules with a gitlink
|
||||
* from the working directory to the new repo.
|
||||
*
|
||||
* @param submodule Pointer to submodule description object pointer..
|
||||
* @param repo The repository.
|
||||
* @param name The name of the submodule. Trailing slashes will be ignored.
|
||||
* @return 0 on success, GIT_ENOTFOUND if submodule does not exist, -1 on error
|
||||
* To fully emulate "git submodule add" call this function, then open the
|
||||
* submodule repo and perform the clone step as needed. Lastly, call
|
||||
* `git_submodule_add_finalize()` to wrap up adding the new submodule and
|
||||
* .gitmodules to the index to be ready to commit.
|
||||
*
|
||||
* @param submodule The newly created submodule ready to open for clone
|
||||
* @param repo Superproject repository to contain the new submodule
|
||||
* @param url URL for the submodules remote
|
||||
* @param path Path at which the submodule should be created
|
||||
* @param use_gitlink Should workdir contain a gitlink to the repo in
|
||||
* .git/modules vs. repo directly in workdir.
|
||||
* @return 0 on success, GIT_EEXISTS if submodule already exists,
|
||||
* -1 on other errors.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_lookup(
|
||||
GIT_EXTERN(int) git_submodule_add_setup(
|
||||
git_submodule **submodule,
|
||||
git_repository *repo,
|
||||
const char *name);
|
||||
const char *url,
|
||||
const char *path,
|
||||
int use_gitlink);
|
||||
|
||||
/**
|
||||
* Resolve the setup of a new git submodule.
|
||||
*
|
||||
* This should be called on a submodule once you have called add setup
|
||||
* and done the clone of the submodule. This adds the .gitmodules file
|
||||
* and the newly cloned submodule to the index to be ready to be committed
|
||||
* (but doesn't actually do the commit).
|
||||
*
|
||||
* @param submodule The submodule to finish adding.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_add_finalize(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Add current submodule HEAD commit to index of superproject.
|
||||
*
|
||||
* @param submodule The submodule to add to the index
|
||||
* @param write_index Boolean if this should immediately write the index
|
||||
* file. If you pass this as false, you will have to get the
|
||||
* git_index and explicitly call `git_index_write()` on it to
|
||||
* save the change.
|
||||
* @return 0 on success, <0 on failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_add_to_index(
|
||||
git_submodule *submodule,
|
||||
int write_index);
|
||||
|
||||
/**
|
||||
* Write submodule settings to .gitmodules file.
|
||||
*
|
||||
* This commits any in-memory changes to the submodule to the gitmodules
|
||||
* file on disk. You may also be interested in `git_submodule_init()` which
|
||||
* writes submodule info to ".git/config" (which is better for local changes
|
||||
* to submodule settings) and/or `git_submodule_sync()` which writes
|
||||
* settings about remotes to the actual submodule repository.
|
||||
*
|
||||
* @param submodule The submodule to write.
|
||||
* @return 0 on success, <0 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_save(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the containing repository for a submodule.
|
||||
*
|
||||
* This returns a pointer to the repository that contains the submodule.
|
||||
* This is a just a reference to the repository that was passed to the
|
||||
* original `git_submodule_lookup()` call, so if that repository has been
|
||||
* freed, then this may be a dangling reference.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to `git_repository`
|
||||
*/
|
||||
GIT_EXTERN(git_repository *) git_submodule_owner(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the name of submodule.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to the submodule name
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_submodule_name(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the path to the submodule.
|
||||
*
|
||||
* The path is almost always the same as the submodule name, but the
|
||||
* two are actually not required to match.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to the submodule path
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the URL for the submodule.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to the submodule url
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Set the URL for the submodule.
|
||||
*
|
||||
* This sets the URL in memory for the submodule. This will be used for
|
||||
* any following submodule actions while this submodule data is in memory.
|
||||
*
|
||||
* After calling this, you may wish to call `git_submodule_save()` to write
|
||||
* the changes back to the ".gitmodules" file and `git_submodule_sync()` to
|
||||
* write the changes to the checked out submodule repository.
|
||||
*
|
||||
* @param submodule Pointer to the submodule object
|
||||
* @param url URL that should be used for the submodule
|
||||
* @return 0 on success, <0 on failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_set_url(git_submodule *submodule, const char *url);
|
||||
|
||||
/**
|
||||
* Get the OID for the submodule in the index.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to git_oid or NULL if submodule is not in index.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_submodule_index_id(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the OID for the submodule in the current HEAD tree.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to git_oid or NULL if submodule is not in the HEAD.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_submodule_head_id(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the OID for the submodule in the current working directory.
|
||||
*
|
||||
* This returns the OID that corresponds to looking up 'HEAD' in the checked
|
||||
* out submodule. If there are pending changes in the index or anything
|
||||
* else, this won't notice that. You should call `git_submodule_status()`
|
||||
* for a more complete picture about the state of the working directory.
|
||||
*
|
||||
* @param submodule Pointer to submodule object
|
||||
* @return Pointer to git_oid or NULL if submodule is not checked out.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the ignore rule for the submodule.
|
||||
*
|
||||
* There are four ignore values:
|
||||
*
|
||||
* - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents
|
||||
* of the submodule from a clean checkout to be dirty, including the
|
||||
* addition of untracked files. This is the default if unspecified.
|
||||
* - **GIT_SUBMODULE_IGNORE_UNTRACKED** examines the contents of the
|
||||
* working tree (i.e. call `git_status_foreach()` on the submodule) but
|
||||
* UNTRACKED files will not count as making the submodule dirty.
|
||||
* - **GIT_SUBMODULE_IGNORE_DIRTY** means to only check if the HEAD of the
|
||||
* submodule has moved for status. This is fast since it does not need to
|
||||
* scan the working tree of the submodule at all.
|
||||
* - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo.
|
||||
* The working directory will be consider clean so long as there is a
|
||||
* checked out version present.
|
||||
*/
|
||||
GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
|
||||
git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Set the ignore rule for the submodule.
|
||||
*
|
||||
* This sets the ignore rule in memory for the submodule. This will be used
|
||||
* for any following actions (such as `git_submodule_status()`) while the
|
||||
* submodule is in memory. You should call `git_submodule_save()` if you
|
||||
* want to persist the new ignore role.
|
||||
*
|
||||
* Calling this again with GIT_SUBMODULE_IGNORE_DEFAULT or calling
|
||||
* `git_submodule_reload()` will revert the rule to the value that was in the
|
||||
* original config.
|
||||
*
|
||||
* @return old value for ignore
|
||||
*/
|
||||
GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore(
|
||||
git_submodule *submodule,
|
||||
git_submodule_ignore_t ignore);
|
||||
|
||||
/**
|
||||
* Get the update rule for the submodule.
|
||||
*/
|
||||
GIT_EXTERN(git_submodule_update_t) git_submodule_update(
|
||||
git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Set the update rule for the submodule.
|
||||
*
|
||||
* This sets the update rule in memory for the submodule. You should call
|
||||
* `git_submodule_save()` if you want to persist the new update rule.
|
||||
*
|
||||
* Calling this again with GIT_SUBMODULE_UPDATE_DEFAULT or calling
|
||||
* `git_submodule_reload()` will revert the rule to the value that was in the
|
||||
* original config.
|
||||
*
|
||||
* @return old value for update
|
||||
*/
|
||||
GIT_EXTERN(git_submodule_update_t) git_submodule_set_update(
|
||||
git_submodule *submodule,
|
||||
git_submodule_update_t update);
|
||||
|
||||
/**
|
||||
* Read the fetchRecurseSubmodules rule for a submodule.
|
||||
*
|
||||
* This accesses the submodule.<name>.fetchRecurseSubmodules value for
|
||||
* the submodule that controls fetching behavior for the submodule.
|
||||
*
|
||||
* Note that at this time, libgit2 does not honor this setting and the
|
||||
* fetch functionality current ignores submodules.
|
||||
*
|
||||
* @return 0 if fetchRecurseSubmodules is false, 1 if true
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_fetch_recurse_submodules(
|
||||
git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Set the fetchRecurseSubmodules rule for a submodule.
|
||||
*
|
||||
* This sets the submodule.<name>.fetchRecurseSubmodules value for
|
||||
* the submodule. You should call `git_submodule_save()` if you want
|
||||
* to persist the new value.
|
||||
*
|
||||
* @param submodule The submodule to modify
|
||||
* @param fetch_recurse_submodules Boolean value
|
||||
* @return old value for fetchRecurseSubmodules
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules(
|
||||
git_submodule *submodule,
|
||||
int fetch_recurse_submodules);
|
||||
|
||||
/**
|
||||
* Copy submodule info into ".git/config" file.
|
||||
*
|
||||
* Just like "git submodule init", this copies information about the
|
||||
* submodule into ".git/config". You can use the accessor functions
|
||||
* above to alter the in-memory git_submodule object and control what
|
||||
* is written to the config, overriding what is in .gitmodules.
|
||||
*
|
||||
* @param submodule The submodule to write into the superproject config
|
||||
* @param overwrite By default, existing entries will not be overwritten,
|
||||
* but setting this to true forces them to be updated.
|
||||
* @return 0 on success, <0 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_init(git_submodule *submodule, int overwrite);
|
||||
|
||||
/**
|
||||
* Copy submodule remote info into submodule repo.
|
||||
*
|
||||
* This copies the information about the submodules URL into the checked out
|
||||
* submodule config, acting like "git submodule sync". This is useful if
|
||||
* you have altered the URL for the submodule (or it has been altered by a
|
||||
* fetch of upstream changes) and you need to update your local repo.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Open the repository for a submodule.
|
||||
*
|
||||
* This is a newly opened repository object. The caller is responsible for
|
||||
* calling `git_repository_free()` on it when done. Multiple calls to this
|
||||
* function will return distinct `git_repository` objects. This will only
|
||||
* work if the submodule is checked out into the working directory.
|
||||
*
|
||||
* @param subrepo Pointer to the submodule repo which was opened
|
||||
* @param submodule Submodule to be opened
|
||||
* @return 0 on success, <0 if submodule repo could not be opened.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_open(
|
||||
git_repository **repo,
|
||||
git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Reread submodule info from config, index, and HEAD.
|
||||
*
|
||||
* Call this to reread cached submodule information for this submodule if
|
||||
* you have reason to believe that it has changed.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Reread all submodule info.
|
||||
*
|
||||
* Call this to reload all cached submodule information for the repo.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo);
|
||||
|
||||
/**
|
||||
* Get the status for a submodule.
|
||||
*
|
||||
* This looks at a submodule and tries to determine the status. It
|
||||
* will return a combination of the `GIT_SUBMODULE_STATUS` values above.
|
||||
* How deeply it examines the working directory to do this will depend
|
||||
* on the `git_submodule_ignore_t` value for the submodule - which can be
|
||||
* set either temporarily or permanently with `git_submodule_set_ignore()`.
|
||||
*
|
||||
* @param status Combination of `GIT_SUBMODULE_STATUS` flags
|
||||
* @param submodule Submodule for which to get status
|
||||
* @return 0 on success, <0 on error
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_status(
|
||||
unsigned int *status,
|
||||
git_submodule *submodule);
|
||||
|
||||
/**
|
||||
* Get the locations of submodule information.
|
||||
*
|
||||
* This is a bit like a very lightweight version of `git_submodule_status`.
|
||||
* It just returns a made of the first four submodule status values (i.e.
|
||||
* the ones like GIT_SUBMODULE_STATUS_IN_HEAD, etc) that tell you where the
|
||||
* submodule data comes from (i.e. the HEAD commit, gitmodules file, etc.).
|
||||
* This can be useful if you want to know if the submodule is present in the
|
||||
* working directory at this point in time, etc.
|
||||
*
|
||||
* @param status Combination of first four `GIT_SUBMODULE_STATUS` flags
|
||||
* @param submodule Submodule for which to get status
|
||||
* @return 0 on success, <0 on error
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_location(
|
||||
unsigned int *location_status,
|
||||
git_submodule *submodule);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -11,6 +11,7 @@
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "object.h"
|
||||
#include "strarray.h"
|
||||
|
||||
/**
|
||||
* @file git2/tag.h
|
||||
@ -24,14 +25,16 @@ GIT_BEGIN_DECL
|
||||
/**
|
||||
* Lookup a tag object from the repository.
|
||||
*
|
||||
* @param tag pointer to the looked up tag
|
||||
* @param out pointer to the looked up tag
|
||||
* @param repo the repo to use when locating the tag.
|
||||
* @param id identity of the tag to locate.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oid *id)
|
||||
GIT_INLINE(int) git_tag_lookup(
|
||||
git_tag **out, git_repository *repo, const git_oid *id)
|
||||
{
|
||||
return git_object_lookup((git_object **)tag, repo, id, (git_otype)GIT_OBJ_TAG);
|
||||
return git_object_lookup(
|
||||
(git_object **)out, repo, id, (git_otype)GIT_OBJ_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,32 +43,33 @@ GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oi
|
||||
*
|
||||
* @see git_object_lookup_prefix
|
||||
*
|
||||
* @param tag pointer to the looked up tag
|
||||
* @param out pointer to the looked up tag
|
||||
* @param repo the repo to use when locating the tag.
|
||||
* @param id identity of the tag to locate.
|
||||
* @param len the length of the short identifier
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tag_lookup_prefix(git_tag **tag, git_repository *repo, const git_oid *id, unsigned int len)
|
||||
GIT_INLINE(int) git_tag_lookup_prefix(
|
||||
git_tag **out, git_repository *repo, const git_oid *id, size_t len)
|
||||
{
|
||||
return git_object_lookup_prefix((git_object **)tag, repo, id, len, (git_otype)GIT_OBJ_TAG);
|
||||
return git_object_lookup_prefix(
|
||||
(git_object **)out, repo, id, len, (git_otype)GIT_OBJ_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close an open tag
|
||||
*
|
||||
* This is a wrapper around git_object_free()
|
||||
* You can no longer use the git_tag pointer after this call.
|
||||
*
|
||||
* IMPORTANT:
|
||||
* It *is* necessary to call this method when you stop
|
||||
* using a tag. Failure to do so will cause a memory leak.
|
||||
* IMPORTANT: You MUST call this method when you are through with a tag to
|
||||
* release memory. Failure to do so will cause a memory leak.
|
||||
*
|
||||
* @param tag the tag to close
|
||||
*/
|
||||
|
||||
GIT_INLINE(void) git_tag_free(git_tag *tag)
|
||||
{
|
||||
git_object_free((git_object *) tag);
|
||||
git_object_free((git_object *)tag);
|
||||
}
|
||||
|
||||
|
||||
@ -75,7 +79,7 @@ GIT_INLINE(void) git_tag_free(git_tag *tag)
|
||||
* @param tag a previously loaded tag.
|
||||
* @return object identity for the tag.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag);
|
||||
GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the tagged object of a tag
|
||||
@ -83,11 +87,11 @@ GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag);
|
||||
* This method performs a repository lookup for the
|
||||
* given object and returns it
|
||||
*
|
||||
* @param target pointer where to store the target
|
||||
* @param target_out pointer where to store the target
|
||||
* @param tag a previously loaded tag.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag);
|
||||
GIT_EXTERN(int) git_tag_target(git_object **target_out, const git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the OID of the tagged object of a tag
|
||||
@ -95,7 +99,7 @@ GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return pointer to the OID
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag);
|
||||
GIT_EXTERN(const git_oid *) git_tag_target_id(const git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the type of a tag's tagged object
|
||||
@ -103,7 +107,7 @@ GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return type of the tagged object
|
||||
*/
|
||||
GIT_EXTERN(git_otype) git_tag_type(git_tag *tag);
|
||||
GIT_EXTERN(git_otype) git_tag_target_type(const git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the name of a tag
|
||||
@ -111,23 +115,23 @@ GIT_EXTERN(git_otype) git_tag_type(git_tag *tag);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return name of the tag
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_tag_name(git_tag *tag);
|
||||
GIT_EXTERN(const char *) git_tag_name(const git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the tagger (author) of a tag
|
||||
*
|
||||
* @param tag a previously loaded tag.
|
||||
* @return reference to the tag's author
|
||||
* @return reference to the tag's author or NULL when unspecified
|
||||
*/
|
||||
GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *tag);
|
||||
GIT_EXTERN(const git_signature *) git_tag_tagger(const git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the message of a tag
|
||||
*
|
||||
* @param tag a previously loaded tag.
|
||||
* @return message of the tag
|
||||
* @return message of the tag or NULL when unspecified
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
GIT_EXTERN(const char *) git_tag_message(const git_tag *tag);
|
||||
|
||||
|
||||
/**
|
||||
@ -137,8 +141,12 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
* this tag object. If `force` is true and a reference
|
||||
* already exists with the given name, it'll be replaced.
|
||||
*
|
||||
* The message will be cleaned up from excess whitespace
|
||||
* it will be made sure that the last line ends with a '\n'.
|
||||
* The message will not be cleaned up. This can be achieved
|
||||
* through `git_message_prettify()`.
|
||||
*
|
||||
* The tag name will be checked for validity. You must avoid
|
||||
* the characters '~', '^', ':', '\\', '?', '[', and '*', and the
|
||||
* sequences ".." and "@{" which have special meaning to revparse.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* newly created tag. If the tag already exists, this parameter
|
||||
@ -161,18 +169,18 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
*
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, GIT_EINVALIDSPEC or an error code
|
||||
* A tag object is written to the ODB, and a proper reference
|
||||
* is written in the /refs/tags folder, pointing to it
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message,
|
||||
int force);
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from a buffer
|
||||
@ -181,13 +189,13 @@ GIT_EXTERN(int) git_tag_create(
|
||||
* @param repo Repository where to store the tag
|
||||
* @param buffer Raw tag data
|
||||
* @param force Overwrite existing tags
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_frombuffer(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *buffer,
|
||||
int force);
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *buffer,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Create a new lightweight tag pointing at a target object
|
||||
@ -196,6 +204,9 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
|
||||
* this target object. If `force` is true and a reference
|
||||
* already exists with the given name, it'll be replaced.
|
||||
*
|
||||
* The tag name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the provided
|
||||
* target object. If the tag already exists, this parameter
|
||||
* will be filled with the oid of the existing pointed object
|
||||
@ -212,30 +223,33 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
|
||||
*
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, GIT_EINVALIDSPEC or an error code
|
||||
* A proper reference is written in the /refs/tags folder,
|
||||
* pointing to the provided target object
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_lightweight(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
int force);
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Delete an existing tag reference.
|
||||
*
|
||||
* The tag name will be checked for validity.
|
||||
* See `git_tag_create()` for rules about valid names.
|
||||
*
|
||||
* @param repo Repository where lives the tag
|
||||
*
|
||||
* @param tag_name Name of the tag to be deleted;
|
||||
* this name is validated for consistency.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
* @return 0 on success, GIT_EINVALIDSPEC or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_delete(
|
||||
git_repository *repo,
|
||||
const char *tag_name);
|
||||
git_repository *repo,
|
||||
const char *tag_name);
|
||||
|
||||
/**
|
||||
* Fill a list with all the tags in the Repository
|
||||
@ -251,8 +265,8 @@ GIT_EXTERN(int) git_tag_delete(
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_list(
|
||||
git_strarray *tag_names,
|
||||
git_repository *repo);
|
||||
git_strarray *tag_names,
|
||||
git_repository *repo);
|
||||
|
||||
/**
|
||||
* Fill a list with all the tags in the Repository
|
||||
@ -273,24 +287,39 @@ GIT_EXTERN(int) git_tag_list(
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_list_match(
|
||||
git_strarray *tag_names,
|
||||
const char *pattern,
|
||||
git_repository *repo);
|
||||
git_strarray *tag_names,
|
||||
const char *pattern,
|
||||
git_repository *repo);
|
||||
|
||||
|
||||
typedef int (*git_tag_foreach_cb)(const char *name, git_oid *oid, void *payload);
|
||||
|
||||
/**
|
||||
* Recursively peel a tag until a non tag git_object
|
||||
* is met
|
||||
* Call callback `cb' for each tag in the repository
|
||||
*
|
||||
* @param repo Repository
|
||||
* @param callback Callback function
|
||||
* @param payload Pointer to callback data (optional)
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_foreach(
|
||||
git_repository *repo,
|
||||
git_tag_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
|
||||
/**
|
||||
* Recursively peel a tag until a non tag git_object is found
|
||||
*
|
||||
* The retrieved `tag_target` object is owned by the repository
|
||||
* and should be closed with the `git_object_free` method.
|
||||
*
|
||||
* @param tag_target Pointer to the peeled git_object
|
||||
* @param tag_target_out Pointer to the peeled git_object
|
||||
* @param tag The tag to be processed
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_peel(
|
||||
git_object **tag_target,
|
||||
git_tag *tag);
|
||||
git_object **tag_target_out,
|
||||
const git_tag *tag);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -27,8 +27,10 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* If libgit2 has been built without GIT_THREADS
|
||||
* support, this function is a no-op.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(void) git_threads_init(void);
|
||||
GIT_EXTERN(int) git_threads_init(void);
|
||||
|
||||
/**
|
||||
* Shutdown the threading system.
|
||||
|
68
include/git2/trace.h
Normal file
68
include/git2/trace.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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_git_trace_h__
|
||||
#define INCLUDE_git_trace_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
|
||||
/**
|
||||
* @file git2/trace.h
|
||||
* @brief Git tracing configuration routines
|
||||
* @defgroup git_trace Git tracing configuration routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Available tracing levels. When tracing is set to a particular level,
|
||||
* callers will be provided tracing at the given level and all lower levels.
|
||||
*/
|
||||
typedef enum {
|
||||
/** No tracing will be performed. */
|
||||
GIT_TRACE_NONE = 0,
|
||||
|
||||
/** Severe errors that may impact the program's execution */
|
||||
GIT_TRACE_FATAL = 1,
|
||||
|
||||
/** Errors that do not impact the program's execution */
|
||||
GIT_TRACE_ERROR = 2,
|
||||
|
||||
/** Warnings that suggest abnormal data */
|
||||
GIT_TRACE_WARN = 3,
|
||||
|
||||
/** Informational messages about program execution */
|
||||
GIT_TRACE_INFO = 4,
|
||||
|
||||
/** Detailed data that allows for debugging */
|
||||
GIT_TRACE_DEBUG = 5,
|
||||
|
||||
/** Exceptionally detailed debugging data */
|
||||
GIT_TRACE_TRACE = 6
|
||||
} git_trace_level_t;
|
||||
|
||||
/**
|
||||
* An instance for a tracing function
|
||||
*/
|
||||
typedef void (*git_trace_callback)(git_trace_level_t level, const char *msg);
|
||||
|
||||
/**
|
||||
* Sets the system tracing configuration to the specified level with the
|
||||
* specified callback. When system events occur at a level equal to, or
|
||||
* lower than, the given level they will be reported to the given callback.
|
||||
*
|
||||
* @param level Level to set tracing to
|
||||
* @param cb Function to call with trace data
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_trace_set(git_trace_level_t level, git_trace_callback cb);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
328
include/git2/transport.h
Normal file
328
include/git2/transport.h
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* 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_git_transport_h__
|
||||
#define INCLUDE_git_transport_h__
|
||||
|
||||
#include "indexer.h"
|
||||
#include "net.h"
|
||||
#include "types.h"
|
||||
|
||||
/**
|
||||
* @file git2/transport.h
|
||||
* @brief Git transport interfaces and functions
|
||||
* @defgroup git_transport interfaces and functions
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/*
|
||||
*** Begin interface for credentials acquisition ***
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* git_cred_userpass_plaintext */
|
||||
GIT_CREDTYPE_USERPASS_PLAINTEXT = 1,
|
||||
} git_credtype_t;
|
||||
|
||||
/* The base structure for all credential types */
|
||||
typedef struct git_cred {
|
||||
git_credtype_t credtype;
|
||||
void (*free)(
|
||||
struct git_cred *cred);
|
||||
} git_cred;
|
||||
|
||||
/* A plaintext username and password */
|
||||
typedef struct git_cred_userpass_plaintext {
|
||||
git_cred parent;
|
||||
char *username;
|
||||
char *password;
|
||||
} git_cred_userpass_plaintext;
|
||||
|
||||
/**
|
||||
* Creates a new plain-text username and password credential object.
|
||||
* The supplied credential parameter will be internally duplicated.
|
||||
*
|
||||
* @param out The newly created credential object.
|
||||
* @param username The username of the credential.
|
||||
* @param password The password of the credential.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_userpass_plaintext_new(
|
||||
git_cred **out,
|
||||
const char *username,
|
||||
const char *password);
|
||||
|
||||
/**
|
||||
* Signature of a function which acquires a credential object.
|
||||
*
|
||||
* @param cred The newly created credential object.
|
||||
* @param url The resource for which we are demanding a credential.
|
||||
* @param username_from_url The username that was embedded in a "user@host"
|
||||
* remote url, or NULL if not included.
|
||||
* @param allowed_types A bitmask stating which cred types are OK to return.
|
||||
* @param payload The payload provided when specifying this callback.
|
||||
* @return 0 for success or an error code for failure
|
||||
*/
|
||||
typedef int (*git_cred_acquire_cb)(
|
||||
git_cred **cred,
|
||||
const char *url,
|
||||
const char *username_from_url,
|
||||
unsigned int allowed_types,
|
||||
void *payload);
|
||||
|
||||
/*
|
||||
*** End interface for credentials acquisition ***
|
||||
*** Begin base transport interface ***
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
GIT_TRANSPORTFLAGS_NONE = 0,
|
||||
/* If the connection is secured with SSL/TLS, the authenticity
|
||||
* of the server certificate should not be verified. */
|
||||
GIT_TRANSPORTFLAGS_NO_CHECK_CERT = 1
|
||||
} git_transport_flags_t;
|
||||
|
||||
typedef void (*git_transport_message_cb)(const char *str, int len, void *data);
|
||||
|
||||
typedef struct git_transport {
|
||||
unsigned int version;
|
||||
/* Set progress and error callbacks */
|
||||
int (*set_callbacks)(struct git_transport *transport,
|
||||
git_transport_message_cb progress_cb,
|
||||
git_transport_message_cb error_cb,
|
||||
void *payload);
|
||||
|
||||
/* Connect the transport to the remote repository, using the given
|
||||
* direction. */
|
||||
int (*connect)(struct git_transport *transport,
|
||||
const char *url,
|
||||
git_cred_acquire_cb cred_acquire_cb,
|
||||
void *cred_acquire_payload,
|
||||
int direction,
|
||||
int flags);
|
||||
|
||||
/* This function may be called after a successful call to connect(). The
|
||||
* provided callback is invoked for each ref discovered on the remote
|
||||
* end. */
|
||||
int (*ls)(struct git_transport *transport,
|
||||
git_headlist_cb list_cb,
|
||||
void *payload);
|
||||
|
||||
/* Executes the push whose context is in the git_push object. */
|
||||
int (*push)(struct git_transport *transport, git_push *push);
|
||||
|
||||
/* This function may be called after a successful call to connect(), when
|
||||
* the direction is FETCH. The function performs a negotiation to calculate
|
||||
* the wants list for the fetch. */
|
||||
int (*negotiate_fetch)(struct git_transport *transport,
|
||||
git_repository *repo,
|
||||
const git_remote_head * const *refs,
|
||||
size_t count);
|
||||
|
||||
/* This function may be called after a successful call to negotiate_fetch(),
|
||||
* when the direction is FETCH. This function retrieves the pack file for
|
||||
* the fetch from the remote end. */
|
||||
int (*download_pack)(struct git_transport *transport,
|
||||
git_repository *repo,
|
||||
git_transfer_progress *stats,
|
||||
git_transfer_progress_callback progress_cb,
|
||||
void *progress_payload);
|
||||
|
||||
/* Checks to see if the transport is connected */
|
||||
int (*is_connected)(struct git_transport *transport);
|
||||
|
||||
/* Reads the flags value previously passed into connect() */
|
||||
int (*read_flags)(struct git_transport *transport, int *flags);
|
||||
|
||||
/* Cancels any outstanding transport operation */
|
||||
void (*cancel)(struct git_transport *transport);
|
||||
|
||||
/* This function is the reverse of connect() -- it terminates the
|
||||
* connection to the remote end. */
|
||||
int (*close)(struct git_transport *transport);
|
||||
|
||||
/* Frees/destructs the git_transport object. */
|
||||
void (*free)(struct git_transport *transport);
|
||||
} git_transport;
|
||||
|
||||
#define GIT_TRANSPORT_VERSION 1
|
||||
#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
|
||||
|
||||
/**
|
||||
* Function to use to create a transport from a URL. The transport database
|
||||
* is scanned to find a transport that implements the scheme of the URI (i.e.
|
||||
* git:// or http://) and a transport object is returned to the caller.
|
||||
*
|
||||
* @param out The newly created transport (out)
|
||||
* @param owner The git_remote which will own this transport
|
||||
* @param url The URL to connect to
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url);
|
||||
|
||||
/* Signature of a function which creates a transport */
|
||||
typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
|
||||
|
||||
/* Transports which come with libgit2 (match git_transport_cb). The expected
|
||||
* value for "param" is listed in-line below. */
|
||||
|
||||
/**
|
||||
* Create an instance of the dummy transport.
|
||||
*
|
||||
* @param out The newly created transport (out)
|
||||
* @param owner The git_remote which will own this transport
|
||||
* @param payload You must pass NULL for this parameter.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_dummy(
|
||||
git_transport **out,
|
||||
git_remote *owner,
|
||||
/* NULL */ void *payload);
|
||||
|
||||
/**
|
||||
* Create an instance of the local transport.
|
||||
*
|
||||
* @param out The newly created transport (out)
|
||||
* @param owner The git_remote which will own this transport
|
||||
* @param payload You must pass NULL for this parameter.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_local(
|
||||
git_transport **out,
|
||||
git_remote *owner,
|
||||
/* NULL */ void *payload);
|
||||
|
||||
/**
|
||||
* Create an instance of the smart transport.
|
||||
*
|
||||
* @param out The newly created transport (out)
|
||||
* @param owner The git_remote which will own this transport
|
||||
* @param payload A pointer to a git_smart_subtransport_definition
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_smart(
|
||||
git_transport **out,
|
||||
git_remote *owner,
|
||||
/* (git_smart_subtransport_definition *) */ void *payload);
|
||||
|
||||
/*
|
||||
*** End of base transport interface ***
|
||||
*** Begin interface for subtransports for the smart transport ***
|
||||
*/
|
||||
|
||||
/* The smart transport knows how to speak the git protocol, but it has no
|
||||
* knowledge of how to establish a connection between it and another endpoint,
|
||||
* or how to move data back and forth. For this, a subtransport interface is
|
||||
* declared, and the smart transport delegates this work to the subtransports.
|
||||
* Three subtransports are implemented: git, http, and winhttp. (The http and
|
||||
* winhttp transports each implement both http and https.) */
|
||||
|
||||
/* Subtransports can either be RPC = 0 (persistent connection) or RPC = 1
|
||||
* (request/response). The smart transport handles the differences in its own
|
||||
* logic. The git subtransport is RPC = 0, while http and winhttp are both
|
||||
* RPC = 1. */
|
||||
|
||||
/* Actions that the smart transport can ask
|
||||
* a subtransport to perform */
|
||||
typedef enum {
|
||||
GIT_SERVICE_UPLOADPACK_LS = 1,
|
||||
GIT_SERVICE_UPLOADPACK = 2,
|
||||
GIT_SERVICE_RECEIVEPACK_LS = 3,
|
||||
GIT_SERVICE_RECEIVEPACK = 4,
|
||||
} git_smart_service_t;
|
||||
|
||||
struct git_smart_subtransport;
|
||||
|
||||
/* A stream used by the smart transport to read and write data
|
||||
* from a subtransport */
|
||||
typedef struct git_smart_subtransport_stream {
|
||||
/* The owning subtransport */
|
||||
struct git_smart_subtransport *subtransport;
|
||||
|
||||
int (*read)(
|
||||
struct git_smart_subtransport_stream *stream,
|
||||
char *buffer,
|
||||
size_t buf_size,
|
||||
size_t *bytes_read);
|
||||
|
||||
int (*write)(
|
||||
struct git_smart_subtransport_stream *stream,
|
||||
const char *buffer,
|
||||
size_t len);
|
||||
|
||||
void (*free)(
|
||||
struct git_smart_subtransport_stream *stream);
|
||||
} git_smart_subtransport_stream;
|
||||
|
||||
/* An implementation of a subtransport which carries data for the
|
||||
* smart transport */
|
||||
typedef struct git_smart_subtransport {
|
||||
int (* action)(
|
||||
git_smart_subtransport_stream **out,
|
||||
struct git_smart_subtransport *transport,
|
||||
const char *url,
|
||||
git_smart_service_t action);
|
||||
|
||||
/* Subtransports are guaranteed a call to close() between
|
||||
* calls to action(), except for the following two "natural" progressions
|
||||
* of actions against a constant URL.
|
||||
*
|
||||
* 1. UPLOADPACK_LS -> UPLOADPACK
|
||||
* 2. RECEIVEPACK_LS -> RECEIVEPACK */
|
||||
int (* close)(struct git_smart_subtransport *transport);
|
||||
|
||||
void (* free)(struct git_smart_subtransport *transport);
|
||||
} git_smart_subtransport;
|
||||
|
||||
/* A function which creates a new subtransport for the smart transport */
|
||||
typedef int (*git_smart_subtransport_cb)(
|
||||
git_smart_subtransport **out,
|
||||
git_transport* owner);
|
||||
|
||||
typedef struct git_smart_subtransport_definition {
|
||||
/* The function to use to create the git_smart_subtransport */
|
||||
git_smart_subtransport_cb callback;
|
||||
|
||||
/* True if the protocol is stateless; false otherwise. For example,
|
||||
* http:// is stateless, but git:// is not. */
|
||||
unsigned rpc;
|
||||
} git_smart_subtransport_definition;
|
||||
|
||||
/* Smart transport subtransports that come with libgit2 */
|
||||
|
||||
/**
|
||||
* Create an instance of the http subtransport. This subtransport
|
||||
* also supports https. On Win32, this subtransport may be implemented
|
||||
* using the WinHTTP library.
|
||||
*
|
||||
* @param out The newly created subtransport
|
||||
* @param owner The smart transport to own this subtransport
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_smart_subtransport_http(
|
||||
git_smart_subtransport **out,
|
||||
git_transport* owner);
|
||||
|
||||
/**
|
||||
* Create an instance of the git subtransport.
|
||||
*
|
||||
* @param out The newly created subtransport
|
||||
* @param owner The smart transport to own this subtransport
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_smart_subtransport_git(
|
||||
git_smart_subtransport **out,
|
||||
git_transport* owner);
|
||||
|
||||
/*
|
||||
*** End interface for subtransports for the smart transport ***
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -24,14 +24,15 @@ GIT_BEGIN_DECL
|
||||
/**
|
||||
* Lookup a tree object from the repository.
|
||||
*
|
||||
* @param tree pointer to the looked up tree
|
||||
* @param repo the repo to use when locating the tree.
|
||||
* @param id identity of the tree to locate.
|
||||
* @param out Pointer to the looked up tree
|
||||
* @param repo The repo to use when locating the tree.
|
||||
* @param id Identity of the tree to locate.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git_oid *id)
|
||||
GIT_INLINE(int) git_tree_lookup(
|
||||
git_tree **out, git_repository *repo, const git_oid *id)
|
||||
{
|
||||
return git_object_lookup((git_object **)tree, repo, id, GIT_OBJ_TREE);
|
||||
return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TREE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,36 +47,46 @@ GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git
|
||||
* @param len the length of the short identifier
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tree_lookup_prefix(git_tree **tree, git_repository *repo, const git_oid *id, unsigned int len)
|
||||
GIT_INLINE(int) git_tree_lookup_prefix(
|
||||
git_tree **out,
|
||||
git_repository *repo,
|
||||
const git_oid *id,
|
||||
size_t len)
|
||||
{
|
||||
return git_object_lookup_prefix((git_object **)tree, repo, id, len, GIT_OBJ_TREE);
|
||||
return git_object_lookup_prefix(
|
||||
(git_object **)out, repo, id, len, GIT_OBJ_TREE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close an open tree
|
||||
*
|
||||
* This is a wrapper around git_object_free()
|
||||
* You can no longer use the git_tree pointer after this call.
|
||||
*
|
||||
* IMPORTANT:
|
||||
* It *is* necessary to call this method when you stop
|
||||
* using a tree. Failure to do so will cause a memory leak.
|
||||
* IMPORTANT: You MUST call this method when you stop using a tree to
|
||||
* release memory. Failure to do so will cause a memory leak.
|
||||
*
|
||||
* @param tree the tree to close
|
||||
* @param tree The tree to close
|
||||
*/
|
||||
|
||||
GIT_INLINE(void) git_tree_free(git_tree *tree)
|
||||
{
|
||||
git_object_free((git_object *) tree);
|
||||
git_object_free((git_object *)tree);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the id of a tree.
|
||||
*
|
||||
* @param tree a previously loaded tree.
|
||||
* @return object identity for the tree.
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree);
|
||||
GIT_EXTERN(const git_oid *) git_tree_id(const git_tree *tree);
|
||||
|
||||
/**
|
||||
* Get the repository that contains the tree.
|
||||
*
|
||||
* @param tree A previously loaded tree.
|
||||
* @return Repository that contains this tree.
|
||||
*/
|
||||
GIT_EXTERN(git_repository *) git_tree_owner(const git_tree *tree);
|
||||
|
||||
/**
|
||||
* Get the number of entries listed in a tree
|
||||
@ -83,33 +94,87 @@ GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree);
|
||||
* @param tree a previously loaded tree.
|
||||
* @return the number of entries in the tree
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_tree_entrycount(git_tree *tree);
|
||||
GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree);
|
||||
|
||||
/**
|
||||
* Lookup a tree entry by its filename
|
||||
*
|
||||
* This returns a git_tree_entry that is owned by the git_tree. You don't
|
||||
* have to free it, but you must not use it after the git_tree is released.
|
||||
*
|
||||
* @param tree a previously loaded tree.
|
||||
* @param filename the filename of the desired entry
|
||||
* @return the tree entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(git_tree *tree, const char *filename);
|
||||
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(
|
||||
git_tree *tree, const char *filename);
|
||||
|
||||
/**
|
||||
* Lookup a tree entry by its position in the tree
|
||||
*
|
||||
* This returns a git_tree_entry that is owned by the git_tree. You don't
|
||||
* have to free it, but you must not use it after the git_tree is released.
|
||||
*
|
||||
* @param tree a previously loaded tree.
|
||||
* @param idx the position in the entry list
|
||||
* @return the tree entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(git_tree *tree, unsigned int idx);
|
||||
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(
|
||||
git_tree *tree, size_t idx);
|
||||
|
||||
/**
|
||||
* Get the UNIX file attributes of a tree entry
|
||||
* Lookup a tree entry by SHA value.
|
||||
*
|
||||
* @param entry a tree entry
|
||||
* @return attributes as an integer
|
||||
* This returns a git_tree_entry that is owned by the git_tree. You don't
|
||||
* have to free it, but you must not use it after the git_tree is released.
|
||||
*
|
||||
* Warning: this must examine every entry in the tree, so it is not fast.
|
||||
*
|
||||
* @param tree a previously loaded tree.
|
||||
* @param oid the sha being looked for
|
||||
* @return the tree entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_tree_entry_attributes(const git_tree_entry *entry);
|
||||
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid(
|
||||
const git_tree *tree, const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Retrieve a tree entry contained in a tree or in any of its subtrees,
|
||||
* given its relative path.
|
||||
*
|
||||
* Unlike the other lookup functions, the returned tree entry is owned by
|
||||
* the user and must be freed explicitly with `git_tree_entry_free()`.
|
||||
*
|
||||
* @param out Pointer where to store the tree entry
|
||||
* @param root Previously loaded tree which is the root of the relative path
|
||||
* @param subtree_path Path to the contained entry
|
||||
* @return 0 on success; GIT_ENOTFOUND if the path does not exist
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_entry_bypath(
|
||||
git_tree_entry **out,
|
||||
git_tree *root,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Duplicate a tree entry
|
||||
*
|
||||
* Create a copy of a tree entry. The returned copy is owned by the user,
|
||||
* and must be freed explicitly with `git_tree_entry_free()`.
|
||||
*
|
||||
* @param entry A tree entry to duplicate
|
||||
* @return a copy of the original entry or NULL on error (alloc failure)
|
||||
*/
|
||||
GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Free a user-owned tree entry
|
||||
*
|
||||
* IMPORTANT: This function is only needed for tree entries owned by the
|
||||
* user, such as the ones returned by `git_tree_entry_dup()` or
|
||||
* `git_tree_entry_bypath()`.
|
||||
*
|
||||
* @param entry The entry to free
|
||||
*/
|
||||
GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Get the filename of a tree entry
|
||||
@ -135,52 +200,56 @@ GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry);
|
||||
*/
|
||||
GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Get the UNIX file attributes of a tree entry
|
||||
*
|
||||
* @param entry a tree entry
|
||||
* @return filemode as an integer
|
||||
*/
|
||||
GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Compare two tree entries
|
||||
*
|
||||
* @param e1 first tree entry
|
||||
* @param e2 second tree entry
|
||||
* @return <0 if e1 is before e2, 0 if e1 == e2, >0 if e1 is after e2
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2);
|
||||
|
||||
/**
|
||||
* Convert a tree entry to the git_object it points too.
|
||||
*
|
||||
* You must call `git_object_free()` on the object when you are done with it.
|
||||
*
|
||||
* @param object pointer to the converted object
|
||||
* @param repo repository where to lookup the pointed object
|
||||
* @param entry a tree entry
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_entry_to_object(git_object **object_out, git_repository *repo, const git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Write a tree to the ODB from the index file
|
||||
*
|
||||
* This method will scan the index and write a representation
|
||||
* of its current state back to disk; it recursively creates
|
||||
* tree objects for each of the subtrees stored in the index,
|
||||
* but only returns the OID of the root tree. This is the OID
|
||||
* that can be used e.g. to create a commit.
|
||||
*
|
||||
* The index instance cannot be bare, and needs to be associated
|
||||
* to an existing repository.
|
||||
*
|
||||
* @param oid Pointer where to store the written tree
|
||||
* @param index Index to write
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index);
|
||||
GIT_EXTERN(int) git_tree_entry_to_object(
|
||||
git_object **object_out,
|
||||
git_repository *repo,
|
||||
const git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Create a new tree builder.
|
||||
*
|
||||
* The tree builder can be used to create or modify
|
||||
* trees in memory and write them as tree objects to the
|
||||
* database.
|
||||
* The tree builder can be used to create or modify trees in memory and
|
||||
* write them as tree objects to the database.
|
||||
*
|
||||
* If the `source` parameter is not NULL, the tree builder
|
||||
* will be initialized with the entries of the given tree.
|
||||
* If the `source` parameter is not NULL, the tree builder will be
|
||||
* initialized with the entries of the given tree.
|
||||
*
|
||||
* If the `source` parameter is NULL, the tree builder will
|
||||
* have no entries and will have to be filled manually.
|
||||
* If the `source` parameter is NULL, the tree builder will start with no
|
||||
* entries and will have to be filled manually.
|
||||
*
|
||||
* @param builder_p Pointer where to store the tree builder
|
||||
* @param out Pointer where to store the tree builder
|
||||
* @param source Source tree to initialize the builder (optional)
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source);
|
||||
GIT_EXTERN(int) git_treebuilder_create(
|
||||
git_treebuilder **out, const git_tree *source);
|
||||
|
||||
/**
|
||||
* Clear all the entires in the builder
|
||||
@ -189,6 +258,14 @@ GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tr
|
||||
*/
|
||||
GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld);
|
||||
|
||||
/**
|
||||
* Get the number of entries listed in a treebuilder
|
||||
*
|
||||
* @param tree a previously loaded treebuilder.
|
||||
* @return the number of entries in the treebuilder
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) git_treebuilder_entrycount(git_treebuilder *bld);
|
||||
|
||||
/**
|
||||
* Free a tree builder
|
||||
*
|
||||
@ -210,7 +287,8 @@ GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld);
|
||||
* @param filename Name of the entry
|
||||
* @return pointer to the entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, const char *filename);
|
||||
GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
|
||||
git_treebuilder *bld, const char *filename);
|
||||
|
||||
/**
|
||||
* Add or update an entry to the builder
|
||||
@ -218,20 +296,31 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con
|
||||
* Insert a new entry for `filename` in the builder with the
|
||||
* given attributes.
|
||||
*
|
||||
* if an entry named `filename` already exists, its attributes
|
||||
* If an entry named `filename` already exists, its attributes
|
||||
* will be updated with the given ones.
|
||||
*
|
||||
* The optional pointer `entry_out` can be used to retrieve a
|
||||
* pointer to the newly created/updated entry.
|
||||
* The optional pointer `out` can be used to retrieve a pointer to
|
||||
* the newly created/updated entry. Pass NULL if you do not need it.
|
||||
*
|
||||
* @param entry_out Pointer to store the entry (optional)
|
||||
* No attempt is being made to ensure that the provided oid points
|
||||
* to an existing git object in the object database, nor that the
|
||||
* attributes make sense regarding the type of the pointed at object.
|
||||
*
|
||||
* @param out Pointer to store the entry (optional)
|
||||
* @param bld Tree builder
|
||||
* @param filename Filename of the entry
|
||||
* @param id SHA1 oid of the entry
|
||||
* @param attributes Folder attributes of the entry
|
||||
* @param filemode Folder attributes of the entry. This parameter must
|
||||
* be valued with one of the following entries: 0040000, 0100644,
|
||||
* 0100755, 0120000 or 0160000.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes);
|
||||
GIT_EXTERN(int) git_treebuilder_insert(
|
||||
const git_tree_entry **out,
|
||||
git_treebuilder *bld,
|
||||
const char *filename,
|
||||
const git_oid *id,
|
||||
git_filemode_t filemode);
|
||||
|
||||
/**
|
||||
* Remove an entry from the builder by its filename
|
||||
@ -239,78 +328,75 @@ GIT_EXTERN(int) git_treebuilder_insert(git_tree_entry **entry_out, git_treebuild
|
||||
* @param bld Tree builder
|
||||
* @param filename Filename of the entry to remove
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_remove(git_treebuilder *bld, const char *filename);
|
||||
GIT_EXTERN(int) git_treebuilder_remove(
|
||||
git_treebuilder *bld, const char *filename);
|
||||
|
||||
typedef int (*git_treebuilder_filter_cb)(
|
||||
const git_tree_entry *entry, void *payload);
|
||||
|
||||
/**
|
||||
* Filter the entries in the tree
|
||||
*
|
||||
* The `filter` callback will be called for each entry
|
||||
* in the tree with a pointer to the entry and the
|
||||
* provided `payload`: if the callback returns 1, the
|
||||
* entry will be filtered (removed from the builder).
|
||||
* The `filter` callback will be called for each entry in the tree with a
|
||||
* pointer to the entry and the provided `payload`; if the callback returns
|
||||
* non-zero, the entry will be filtered (removed from the builder).
|
||||
*
|
||||
* @param bld Tree builder
|
||||
* @param filter Callback to filter entries
|
||||
* @param payload Extra data to pass to filter
|
||||
*/
|
||||
GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(const git_tree_entry *, void *), void *payload);
|
||||
GIT_EXTERN(void) git_treebuilder_filter(
|
||||
git_treebuilder *bld,
|
||||
git_treebuilder_filter_cb filter,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Write the contents of the tree builder as a tree object
|
||||
*
|
||||
* The tree builder will be written to the given `repo`, and
|
||||
* it's identifying SHA1 hash will be stored in the `oid`
|
||||
* pointer.
|
||||
* The tree builder will be written to the given `repo`, and its
|
||||
* identifying SHA1 hash will be stored in the `id` pointer.
|
||||
*
|
||||
* @param oid Pointer where to store the written OID
|
||||
* @param repo Repository where to store the object
|
||||
* @param id Pointer to store the OID of the newly written tree
|
||||
* @param repo Repository in which to store the object
|
||||
* @param bld Tree builder to write
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld);
|
||||
GIT_EXTERN(int) git_treebuilder_write(
|
||||
git_oid *id, git_repository *repo, git_treebuilder *bld);
|
||||
|
||||
/**
|
||||
* Retrieve a subtree contained in a tree, given its
|
||||
* relative path.
|
||||
*
|
||||
* The returned tree is owned by the repository and
|
||||
* should be closed with the `git_object_free` method.
|
||||
*
|
||||
* @param subtree Pointer where to store the subtree
|
||||
* @param root A previously loaded tree which will be the root of the relative path
|
||||
* @param subtree_path Path to the contained subtree
|
||||
* @return 0 on success; GIT_ENOTFOUND if the path does not lead to a subtree
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_get_subtree(git_tree **subtree, git_tree *root, const char *subtree_path);
|
||||
|
||||
/** Callback for the tree traversal method */
|
||||
typedef int (*git_treewalk_cb)(const char *root, git_tree_entry *entry, void *payload);
|
||||
typedef int (*git_treewalk_cb)(
|
||||
const char *root, const git_tree_entry *entry, void *payload);
|
||||
|
||||
/** Tree traversal modes */
|
||||
enum git_treewalk_mode {
|
||||
typedef enum {
|
||||
GIT_TREEWALK_PRE = 0, /* Pre-order */
|
||||
GIT_TREEWALK_POST = 1, /* Post-order */
|
||||
};
|
||||
} git_treewalk_mode;
|
||||
|
||||
/**
|
||||
* Traverse the entries in a tree and its subtrees in
|
||||
* post or pre order
|
||||
* Traverse the entries in a tree and its subtrees in post or pre order.
|
||||
*
|
||||
* The entries will be traversed in the specified order,
|
||||
* children subtrees will be automatically loaded as required,
|
||||
* and the `callback` will be called once per entry with
|
||||
* the current (relative) root for the entry and the entry
|
||||
* data itself.
|
||||
* The entries will be traversed in the specified order, children subtrees
|
||||
* will be automatically loaded as required, and the `callback` will be
|
||||
* called once per entry with the current (relative) root for the entry and
|
||||
* the entry data itself.
|
||||
*
|
||||
* If the callback returns a negative value, the passed entry
|
||||
* will be skiped on the traversal.
|
||||
* If the callback returns a positive value, the passed entry will be
|
||||
* skipped on the traversal (in pre mode). A negative value stops the walk.
|
||||
*
|
||||
* @param tree The tree to walk
|
||||
* @param callback Function to call on each tree entry
|
||||
* @param mode Traversal mode (pre or post-order)
|
||||
* @param callback Function to call on each tree entry
|
||||
* @param payload Opaque pointer to be passed on each callback
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payload);
|
||||
GIT_EXTERN(int) git_tree_walk(
|
||||
const git_tree *tree,
|
||||
git_treewalk_mode mode,
|
||||
git_treewalk_cb callback,
|
||||
void *payload);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -32,6 +32,9 @@ GIT_BEGIN_DECL
|
||||
* stat() functions, for all platforms.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#ifdef __amigaos4__
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
@ -86,6 +89,15 @@ typedef struct git_odb_object git_odb_object;
|
||||
/** A stream to read/write from the ODB */
|
||||
typedef struct git_odb_stream git_odb_stream;
|
||||
|
||||
/** A stream to write a packfile to the ODB */
|
||||
typedef struct git_odb_writepack git_odb_writepack;
|
||||
|
||||
/** An open refs database handle. */
|
||||
typedef struct git_refdb git_refdb;
|
||||
|
||||
/** A custom backend for refs */
|
||||
typedef struct git_refdb_backend git_refdb_backend;
|
||||
|
||||
/**
|
||||
* Representation of an existing git repository,
|
||||
* including all its object contents
|
||||
@ -123,7 +135,7 @@ typedef struct git_index git_index;
|
||||
typedef struct git_config git_config;
|
||||
|
||||
/** Interface to access a configuration file */
|
||||
typedef struct git_config_file git_config_file;
|
||||
typedef struct git_config_backend git_config_backend;
|
||||
|
||||
/** Representation of a reference log entry */
|
||||
typedef struct git_reflog_entry git_reflog_entry;
|
||||
@ -134,6 +146,9 @@ typedef struct git_reflog git_reflog;
|
||||
/** Representation of a git note */
|
||||
typedef struct git_note git_note;
|
||||
|
||||
/** Representation of a git packbuilder */
|
||||
typedef struct git_packbuilder git_packbuilder;
|
||||
|
||||
/** Time in a signature */
|
||||
typedef struct git_time {
|
||||
git_time_t time; /** time in seconds from epoch */
|
||||
@ -155,9 +170,7 @@ typedef enum {
|
||||
GIT_REF_INVALID = 0, /** Invalid reference */
|
||||
GIT_REF_OID = 1, /** A reference which points at an object id */
|
||||
GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */
|
||||
GIT_REF_PACKED = 4,
|
||||
GIT_REF_HAS_PEEL = 8,
|
||||
GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
|
||||
GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC,
|
||||
} git_ref_t;
|
||||
|
||||
/** Basic type of any Git branch. */
|
||||
@ -166,10 +179,22 @@ typedef enum {
|
||||
GIT_BRANCH_REMOTE = 2,
|
||||
} git_branch_t;
|
||||
|
||||
/** Valid modes for index and tree entries. */
|
||||
typedef enum {
|
||||
GIT_FILEMODE_NEW = 0000000,
|
||||
GIT_FILEMODE_TREE = 0040000,
|
||||
GIT_FILEMODE_BLOB = 0100644,
|
||||
GIT_FILEMODE_BLOB_EXECUTABLE = 0100755,
|
||||
GIT_FILEMODE_LINK = 0120000,
|
||||
GIT_FILEMODE_COMMIT = 0160000,
|
||||
} git_filemode_t;
|
||||
|
||||
typedef struct git_refspec git_refspec;
|
||||
typedef struct git_remote git_remote;
|
||||
typedef struct git_push git_push;
|
||||
|
||||
typedef struct git_remote_head git_remote_head;
|
||||
typedef struct git_remote_callbacks git_remote_callbacks;
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -7,9 +7,9 @@
|
||||
#ifndef INCLUDE_git_version_h__
|
||||
#define INCLUDE_git_version_h__
|
||||
|
||||
#define LIBGIT2_VERSION "0.17.0"
|
||||
#define LIBGIT2_VERSION "0.18.0"
|
||||
#define LIBGIT2_VER_MAJOR 0
|
||||
#define LIBGIT2_VER_MINOR 17
|
||||
#define LIBGIT2_VER_MINOR 18
|
||||
#define LIBGIT2_VER_REVISION 0
|
||||
|
||||
#endif
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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_git_windows_h__
|
||||
#define INCLUDE_git_windows_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/windows.h
|
||||
* @brief Windows-specific functions
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Set the active codepage for Windows syscalls
|
||||
*
|
||||
* All syscalls performed by the library will assume
|
||||
* this codepage when converting paths and strings
|
||||
* to use by the Windows kernel.
|
||||
*
|
||||
* The default value of UTF-8 will work automatically
|
||||
* with most Git repositories created on Unix systems.
|
||||
*
|
||||
* This settings needs only be changed when working
|
||||
* with repositories that contain paths in specific,
|
||||
* non-UTF codepages.
|
||||
*
|
||||
* A full list of all available codepage identifiers may
|
||||
* be found at:
|
||||
*
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
|
||||
*
|
||||
* @param codepage numeric codepage identifier
|
||||
*/
|
||||
GIT_EXTERN(void) gitwin_set_codepage(unsigned int codepage);
|
||||
|
||||
/**
|
||||
* Return the active codepage for Windows syscalls
|
||||
*
|
||||
* @return numeric codepage identifier
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) gitwin_get_codepage(void);
|
||||
|
||||
/**
|
||||
* Set the active Windows codepage to UTF-8 (this is
|
||||
* the default value)
|
||||
*/
|
||||
GIT_EXTERN(void) gitwin_set_utf8(void);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
libdir=@CMAKE_INSTALL_PREFIX@/@INSTALL_LIB@
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/@INSTALL_INC@
|
||||
libdir=@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/@INCLUDE_INSTALL_DIR@
|
||||
|
||||
Name: libgit2
|
||||
Description: The git library, take 2
|
||||
|
49
libgit2_clar.supp
Normal file
49
libgit2_clar.supp
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
ignore-zlib-errors-cond
|
||||
Memcheck:Cond
|
||||
obj:*libz.so*
|
||||
}
|
||||
|
||||
{
|
||||
ignore-giterr-set-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:giterr_set
|
||||
}
|
||||
|
||||
{
|
||||
ignore-git-global-state-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:git__global_state
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-ssl-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*libssl.so*
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-crypto-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*libcrypto.so*
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-crypto-cond
|
||||
Memcheck:Cond
|
||||
obj:*libcrypto.so*
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-glibc-getaddrinfo-cache
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:__check_pf
|
||||
}
|
@ -65,7 +65,7 @@ to compile and develop applications that use libgit2.
|
||||
cmake . \
|
||||
-DCMAKE_C_FLAGS:STRING="%{optflags}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%{_prefix} \
|
||||
-DINSTALL_LIB:PATH=%{_libdir}
|
||||
-DLIB_INSTALL_DIR:PATH=%{_libdir}S
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
|
48
src/amiga/map.c
Normal file
48
src/amiga/map.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#include <git2/common.h>
|
||||
|
||||
#ifndef GIT_WIN32
|
||||
|
||||
#include "posix.h"
|
||||
#include "map.h"
|
||||
#include <errno.h>
|
||||
|
||||
int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset)
|
||||
{
|
||||
GIT_MMAP_VALIDATE(out, len, prot, flags);
|
||||
|
||||
out->data = NULL;
|
||||
out->len = 0;
|
||||
|
||||
if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) {
|
||||
giterr_set(GITERR_OS, "Trying to map shared-writeable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
out->data = malloc(len);
|
||||
GITERR_CHECK_ALLOC(out->data);
|
||||
|
||||
if ((p_lseek(fd, offset, SEEK_SET) < 0) || ((size_t)p_read(fd, out->data, len) != len)) {
|
||||
giterr_set(GITERR_OS, "mmap emulation failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
out->len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p_munmap(git_map *map)
|
||||
{
|
||||
assert(map != NULL);
|
||||
free(map->data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
162
src/attr.c
162
src/attr.c
@ -1,10 +1,32 @@
|
||||
#include "repository.h"
|
||||
#include "fileops.h"
|
||||
#include "config.h"
|
||||
#include "attr.h"
|
||||
#include "ignore.h"
|
||||
#include "git2/oid.h"
|
||||
#include <ctype.h>
|
||||
|
||||
GIT__USE_STRMAP;
|
||||
|
||||
const char *git_attr__true = "[internal]__TRUE__";
|
||||
const char *git_attr__false = "[internal]__FALSE__";
|
||||
const char *git_attr__unset = "[internal]__UNSET__";
|
||||
|
||||
git_attr_t git_attr_value(const char *attr)
|
||||
{
|
||||
if (attr == NULL || attr == git_attr__unset)
|
||||
return GIT_ATTR_UNSPECIFIED_T;
|
||||
|
||||
if (attr == git_attr__true)
|
||||
return GIT_ATTR_TRUE_T;
|
||||
|
||||
if (attr == git_attr__false)
|
||||
return GIT_ATTR_FALSE_T;
|
||||
|
||||
return GIT_ATTR_VALUE_T;
|
||||
}
|
||||
|
||||
|
||||
static int collect_attr_files(
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
@ -22,7 +44,7 @@ int git_attr_get(
|
||||
int error;
|
||||
git_attr_path path;
|
||||
git_vector files = GIT_VECTOR_INIT;
|
||||
unsigned int i, j;
|
||||
size_t i, j;
|
||||
git_attr_file *file;
|
||||
git_attr_name attr;
|
||||
git_attr_rule *rule;
|
||||
@ -41,8 +63,9 @@ int git_attr_get(
|
||||
git_vector_foreach(&files, i, file) {
|
||||
|
||||
git_attr_file__foreach_matching_rule(file, &path, j, rule) {
|
||||
int pos = git_vector_bsearch(&rule->assigns, &attr);
|
||||
if (pos >= 0) {
|
||||
size_t pos;
|
||||
|
||||
if (!git_vector_bsearch(&pos, &rule->assigns, &attr)) {
|
||||
*value = ((git_attr_assignment *)git_vector_get(
|
||||
&rule->assigns, pos))->value;
|
||||
goto cleanup;
|
||||
@ -74,7 +97,7 @@ int git_attr_get_many(
|
||||
int error;
|
||||
git_attr_path path;
|
||||
git_vector files = GIT_VECTOR_INIT;
|
||||
unsigned int i, j, k;
|
||||
size_t i, j, k;
|
||||
git_attr_file *file;
|
||||
git_attr_rule *rule;
|
||||
attr_get_many_info *info = NULL;
|
||||
@ -96,7 +119,7 @@ int git_attr_get_many(
|
||||
git_attr_file__foreach_matching_rule(file, &path, j, rule) {
|
||||
|
||||
for (k = 0; k < num_attr; k++) {
|
||||
int pos;
|
||||
size_t pos;
|
||||
|
||||
if (info[k].found != NULL) /* already found assignment */
|
||||
continue;
|
||||
@ -106,8 +129,7 @@ int git_attr_get_many(
|
||||
info[k].name.name_hash = git_attr_file__name_hash(names[k]);
|
||||
}
|
||||
|
||||
pos = git_vector_bsearch(&rule->assigns, &info[k].name);
|
||||
if (pos >= 0) {
|
||||
if (!git_vector_bsearch(&pos, &rule->assigns, &info[k].name)) {
|
||||
info[k].found = (git_attr_assignment *)
|
||||
git_vector_get(&rule->assigns, pos);
|
||||
values[k] = info[k].found->value;
|
||||
@ -138,7 +160,7 @@ int git_attr_foreach(
|
||||
int error;
|
||||
git_attr_path path;
|
||||
git_vector files = GIT_VECTOR_INIT;
|
||||
unsigned int i, j, k;
|
||||
size_t i, j, k;
|
||||
git_attr_file *file;
|
||||
git_attr_rule *rule;
|
||||
git_attr_assignment *assign;
|
||||
@ -163,11 +185,15 @@ int git_attr_foreach(
|
||||
continue;
|
||||
|
||||
git_strmap_insert(seen, assign->name, assign, error);
|
||||
if (error >= 0)
|
||||
error = callback(assign->name, assign->value, payload);
|
||||
|
||||
if (error != 0)
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = callback(assign->name, assign->value, payload);
|
||||
if (error) {
|
||||
giterr_clear();
|
||||
error = GIT_EUSER;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,30 +263,30 @@ bool git_attr_cache__is_cached(
|
||||
|
||||
static int load_attr_file(
|
||||
const char **data,
|
||||
git_attr_file_stat_sig *sig,
|
||||
git_futils_filestamp *stamp,
|
||||
const char *filename)
|
||||
{
|
||||
int error;
|
||||
git_buf content = GIT_BUF_INIT;
|
||||
struct stat st;
|
||||
|
||||
if (p_stat(filename, &st) < 0)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if (sig != NULL &&
|
||||
(git_time_t)st.st_mtime == sig->seconds &&
|
||||
(git_off_t)st.st_size == sig->size &&
|
||||
(unsigned int)st.st_ino == sig->ino)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
error = git_futils_readbuffer_updated(&content, filename, NULL, NULL);
|
||||
error = git_futils_filestamp_check(stamp, filename);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (sig != NULL) {
|
||||
sig->seconds = (git_time_t)st.st_mtime;
|
||||
sig->size = (git_off_t)st.st_size;
|
||||
sig->ino = (unsigned int)st.st_ino;
|
||||
/* if error == 0, then file is up to date. By returning GIT_ENOTFOUND,
|
||||
* we tell the caller not to reparse this file...
|
||||
*/
|
||||
if (!error)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
error = git_futils_readbuffer(&content, filename);
|
||||
if (error < 0) {
|
||||
/* convert error into ENOTFOUND so failed permissions / invalid
|
||||
* file type don't actually stop the operation in progress.
|
||||
*/
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
/* TODO: once warnings are available, issue a warning callback */
|
||||
}
|
||||
|
||||
*data = git_buf_detach(&content);
|
||||
@ -276,14 +302,15 @@ static int load_attr_blob_from_index(
|
||||
const char *relfile)
|
||||
{
|
||||
int error;
|
||||
size_t pos;
|
||||
git_index *index;
|
||||
git_index_entry *entry;
|
||||
const git_index_entry *entry;
|
||||
|
||||
if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
|
||||
(error = git_index_find(index, relfile)) < 0)
|
||||
(error = git_index_find(&pos, index, relfile)) < 0)
|
||||
return error;
|
||||
|
||||
entry = git_index_get(index, error);
|
||||
entry = git_index_get_byindex(index, pos);
|
||||
|
||||
if (old_oid && git_oid_cmp(old_oid, &entry->oid) == 0)
|
||||
return GIT_ENOTFOUND;
|
||||
@ -352,6 +379,7 @@ int git_attr_cache__push_file(
|
||||
const char *filename,
|
||||
git_attr_file_source source,
|
||||
git_attr_file_parser parse,
|
||||
void* parsedata,
|
||||
git_vector *stack)
|
||||
{
|
||||
int error = 0;
|
||||
@ -361,7 +389,7 @@ int git_attr_cache__push_file(
|
||||
git_attr_cache *cache = git_repository_attr_cache(repo);
|
||||
git_attr_file *file = NULL;
|
||||
git_blob *blob = NULL;
|
||||
git_attr_file_stat_sig st;
|
||||
git_futils_filestamp stamp;
|
||||
|
||||
assert(filename && stack);
|
||||
|
||||
@ -383,12 +411,10 @@ int git_attr_cache__push_file(
|
||||
/* if not in cache, load data, parse, and cache */
|
||||
|
||||
if (source == GIT_ATTR_FILE_FROM_FILE) {
|
||||
if (file)
|
||||
memcpy(&st, &file->cache_data.st, sizeof(st));
|
||||
else
|
||||
memset(&st, 0, sizeof(st));
|
||||
git_futils_filestamp_set(
|
||||
&stamp, file ? &file->cache_data.stamp : NULL);
|
||||
|
||||
error = load_attr_file(&content, &st, filename);
|
||||
error = load_attr_file(&content, &stamp, filename);
|
||||
} else {
|
||||
error = load_attr_blob_from_index(&content, &blob,
|
||||
repo, file ? &file->cache_data.oid : NULL, relfile);
|
||||
@ -403,14 +429,19 @@ int git_attr_cache__push_file(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!file &&
|
||||
(error = git_attr_file__new(&file, source, relfile, &cache->pool)) < 0)
|
||||
/* if we got here, we have to parse and/or reparse the file */
|
||||
if (file)
|
||||
git_attr_file__clear_rules(file);
|
||||
else {
|
||||
error = git_attr_file__new(&file, source, relfile, &cache->pool);
|
||||
if (error < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (parse && (error = parse(repo, parsedata, content, file)) < 0)
|
||||
goto finish;
|
||||
|
||||
if (parse && (error = parse(repo, content, file)) < 0)
|
||||
goto finish;
|
||||
|
||||
git_strmap_insert(cache->files, file->key, file, error);
|
||||
git_strmap_insert(cache->files, file->key, file, error); //-V595
|
||||
if (error > 0)
|
||||
error = 0;
|
||||
|
||||
@ -418,7 +449,7 @@ int git_attr_cache__push_file(
|
||||
if (blob)
|
||||
git_oid_cpy(&file->cache_data.oid, git_object_id((git_object *)blob));
|
||||
else
|
||||
memcpy(&file->cache_data.st, &st, sizeof(st));
|
||||
git_futils_filestamp_set(&file->cache_data.stamp, &stamp);
|
||||
|
||||
finish:
|
||||
/* push file onto vector if we found one*/
|
||||
@ -439,7 +470,7 @@ finish:
|
||||
}
|
||||
|
||||
#define push_attr_file(R,S,B,F) \
|
||||
git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,git_attr_file__parse_buffer,(S))
|
||||
git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,git_attr_file__parse_buffer,NULL,(S))
|
||||
|
||||
typedef struct {
|
||||
git_repository *repo;
|
||||
@ -488,7 +519,7 @@ static int push_one_attr(void *ref, git_buf *path)
|
||||
for (i = 0; !error && i < n_src; ++i)
|
||||
error = git_attr_cache__push_file(
|
||||
info->repo, path->ptr, GIT_ATTR_FILE, src[i],
|
||||
git_attr_file__parse_buffer, info->files);
|
||||
git_attr_file__parse_buffer, NULL, info->files);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -550,8 +581,10 @@ static int collect_attr_files(
|
||||
error = git_futils_find_system_file(&dir, GIT_ATTR_FILE_SYSTEM);
|
||||
if (!error)
|
||||
error = push_attr_file(repo, files, NULL, dir.ptr);
|
||||
else if (error == GIT_ENOTFOUND)
|
||||
else if (error == GIT_ENOTFOUND) {
|
||||
giterr_clear();
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@ -562,6 +595,29 @@ static int collect_attr_files(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int attr_cache__lookup_path(
|
||||
const char **out, git_config *cfg, const char *key, const char *fallback)
|
||||
{
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
int error;
|
||||
|
||||
if (!(error = git_config_get_string(out, cfg, key)))
|
||||
return 0;
|
||||
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
giterr_clear();
|
||||
error = 0;
|
||||
|
||||
if (!git_futils_find_xdg_file(&buf, fallback))
|
||||
*out = git_buf_detach(&buf);
|
||||
else
|
||||
*out = NULL;
|
||||
|
||||
git_buf_free(&buf);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_attr_cache__init(git_repository *repo)
|
||||
{
|
||||
@ -576,16 +632,16 @@ int git_attr_cache__init(git_repository *repo)
|
||||
if (git_repository_config__weakptr(&cfg, repo) < 0)
|
||||
return -1;
|
||||
|
||||
ret = git_config_get_string(&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
ret = attr_cache__lookup_path(
|
||||
&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG, GIT_ATTR_FILE_XDG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = git_config_get_string(&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
ret = attr_cache__lookup_path(
|
||||
&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG, GIT_IGNORE_FILE_XDG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
giterr_clear();
|
||||
|
||||
/* allocate hashtable for attribute and ignore file contents */
|
||||
if (cache->files == NULL) {
|
||||
cache->files = git_strmap_alloc();
|
||||
|
21
src/attr.h
21
src/attr.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -8,24 +8,12 @@
|
||||
#define INCLUDE_attr_h__
|
||||
|
||||
#include "attr_file.h"
|
||||
#include "strmap.h"
|
||||
|
||||
#define GIT_ATTR_CONFIG "core.attributesfile"
|
||||
#define GIT_IGNORE_CONFIG "core.excludesfile"
|
||||
|
||||
typedef struct {
|
||||
int initialized;
|
||||
git_pool pool;
|
||||
git_strmap *files; /* hash path to git_attr_file of rules */
|
||||
git_strmap *macros; /* hash name to vector<git_attr_assignment> */
|
||||
const char *cfg_attr_file; /* cached value of core.attributesfile */
|
||||
const char *cfg_excl_file; /* cached value of core.excludesfile */
|
||||
} git_attr_cache;
|
||||
#define GIT_ATTR_CONFIG "core.attributesfile"
|
||||
#define GIT_IGNORE_CONFIG "core.excludesfile"
|
||||
|
||||
typedef int (*git_attr_file_parser)(
|
||||
git_repository *, const char *, git_attr_file *);
|
||||
|
||||
extern int git_attr_cache__init(git_repository *repo);
|
||||
git_repository *, void *, const char *, git_attr_file *);
|
||||
|
||||
extern int git_attr_cache__insert_macro(
|
||||
git_repository *repo, git_attr_rule *macro);
|
||||
@ -39,6 +27,7 @@ extern int git_attr_cache__push_file(
|
||||
const char *filename,
|
||||
git_attr_file_source source,
|
||||
git_attr_file_parser parse,
|
||||
void *parsedata, /* passed through to parse function */
|
||||
git_vector *stack);
|
||||
|
||||
extern int git_attr_cache__internal_file(
|
||||
|
108
src/attr_file.c
108
src/attr_file.c
@ -1,16 +1,17 @@
|
||||
#include "common.h"
|
||||
#include "repository.h"
|
||||
#include "filebuf.h"
|
||||
#include "attr.h"
|
||||
#include "git2/blob.h"
|
||||
#include "git2/tree.h"
|
||||
#include <ctype.h>
|
||||
|
||||
const char *git_attr__true = "[internal]__TRUE__";
|
||||
const char *git_attr__false = "[internal]__FALSE__";
|
||||
const char *git_attr__unset = "[internal]__UNSET__";
|
||||
|
||||
static int sort_by_hash_and_name(const void *a_raw, const void *b_raw);
|
||||
static void git_attr_rule__clear(git_attr_rule *rule);
|
||||
static bool parse_optimized_patterns(
|
||||
git_attr_fnmatch *spec,
|
||||
git_pool *pool,
|
||||
const char *pattern);
|
||||
|
||||
int git_attr_file__new(
|
||||
git_attr_file **attrs_ptr,
|
||||
@ -57,13 +58,15 @@ fail:
|
||||
}
|
||||
|
||||
int git_attr_file__parse_buffer(
|
||||
git_repository *repo, const char *buffer, git_attr_file *attrs)
|
||||
git_repository *repo, void *parsedata, const char *buffer, git_attr_file *attrs)
|
||||
{
|
||||
int error = 0;
|
||||
const char *scan = NULL;
|
||||
char *context = NULL;
|
||||
git_attr_rule *rule = NULL;
|
||||
|
||||
GIT_UNUSED(parsedata);
|
||||
|
||||
assert(buffer && attrs);
|
||||
|
||||
scan = buffer;
|
||||
@ -127,7 +130,7 @@ int git_attr_file__new_and_load(
|
||||
|
||||
if (!(error = git_futils_readbuffer(&content, path)))
|
||||
error = git_attr_file__parse_buffer(
|
||||
NULL, git_buf_cstr(&content), *attrs_ptr);
|
||||
NULL, NULL, git_buf_cstr(&content), *attrs_ptr);
|
||||
|
||||
git_buf_free(&content);
|
||||
|
||||
@ -139,18 +142,23 @@ int git_attr_file__new_and_load(
|
||||
return error;
|
||||
}
|
||||
|
||||
void git_attr_file__free(git_attr_file *file)
|
||||
void git_attr_file__clear_rules(git_attr_file *file)
|
||||
{
|
||||
unsigned int i;
|
||||
git_attr_rule *rule;
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
git_vector_foreach(&file->rules, i, rule)
|
||||
git_attr_rule__free(rule);
|
||||
|
||||
git_vector_free(&file->rules);
|
||||
}
|
||||
|
||||
void git_attr_file__free(git_attr_file *file)
|
||||
{
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
git_attr_file__clear_rules(file);
|
||||
|
||||
if (file->pool_is_allocated) {
|
||||
git_pool_clear(file->pool);
|
||||
@ -178,7 +186,7 @@ int git_attr_file__lookup_one(
|
||||
const char *attr,
|
||||
const char **value)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t i;
|
||||
git_attr_name name;
|
||||
git_attr_rule *rule;
|
||||
|
||||
@ -188,9 +196,9 @@ int git_attr_file__lookup_one(
|
||||
name.name_hash = git_attr_file__name_hash(attr);
|
||||
|
||||
git_attr_file__foreach_matching_rule(file, path, i, rule) {
|
||||
int pos = git_vector_bsearch(&rule->assigns, &name);
|
||||
size_t pos;
|
||||
|
||||
if (pos >= 0) {
|
||||
if (!git_vector_bsearch(&pos, &rule->assigns, &name)) {
|
||||
*value = ((git_attr_assignment *)
|
||||
git_vector_get(&rule->assigns, pos))->value;
|
||||
break;
|
||||
@ -206,16 +214,17 @@ bool git_attr_fnmatch__match(
|
||||
const git_attr_path *path)
|
||||
{
|
||||
int fnm;
|
||||
int icase_flags = (match->flags & GIT_ATTR_FNMATCH_ICASE) ? FNM_CASEFOLD : 0;
|
||||
|
||||
if (match->flags & GIT_ATTR_FNMATCH_DIRECTORY && !path->is_dir)
|
||||
return false;
|
||||
|
||||
if (match->flags & GIT_ATTR_FNMATCH_FULLPATH)
|
||||
fnm = p_fnmatch(match->pattern, path->path, FNM_PATHNAME);
|
||||
fnm = p_fnmatch(match->pattern, path->path, FNM_PATHNAME | icase_flags);
|
||||
else if (path->is_dir)
|
||||
fnm = p_fnmatch(match->pattern, path->basename, FNM_LEADING_DIR);
|
||||
fnm = p_fnmatch(match->pattern, path->basename, FNM_LEADING_DIR | icase_flags);
|
||||
else
|
||||
fnm = p_fnmatch(match->pattern, path->basename, 0);
|
||||
fnm = p_fnmatch(match->pattern, path->basename, icase_flags);
|
||||
|
||||
return (fnm == FNM_NOMATCH) ? false : true;
|
||||
}
|
||||
@ -236,31 +245,29 @@ bool git_attr_rule__match(
|
||||
git_attr_assignment *git_attr_rule__lookup_assignment(
|
||||
git_attr_rule *rule, const char *name)
|
||||
{
|
||||
int pos;
|
||||
size_t pos;
|
||||
git_attr_name key;
|
||||
key.name = name;
|
||||
key.name_hash = git_attr_file__name_hash(name);
|
||||
|
||||
pos = git_vector_bsearch(&rule->assigns, &key);
|
||||
if (git_vector_bsearch(&pos, &rule->assigns, &key))
|
||||
return NULL;
|
||||
|
||||
return (pos >= 0) ? git_vector_get(&rule->assigns, pos) : NULL;
|
||||
return git_vector_get(&rule->assigns, pos);
|
||||
}
|
||||
|
||||
int git_attr_path__init(
|
||||
git_attr_path *info, const char *path, const char *base)
|
||||
{
|
||||
ssize_t root;
|
||||
|
||||
/* build full path as best we can */
|
||||
git_buf_init(&info->full, 0);
|
||||
|
||||
if (base != NULL && git_path_root(path) < 0) {
|
||||
if (git_buf_joinpath(&info->full, base, path) < 0)
|
||||
return -1;
|
||||
info->path = info->full.ptr + strlen(base);
|
||||
} else {
|
||||
if (git_buf_sets(&info->full, path) < 0)
|
||||
return -1;
|
||||
info->path = info->full.ptr;
|
||||
}
|
||||
if (git_path_join_unrooted(&info->full, path, base, &root) < 0)
|
||||
return -1;
|
||||
|
||||
info->path = info->full.ptr + root;
|
||||
|
||||
/* remove trailing slashes */
|
||||
while (info->full.size > 0) {
|
||||
@ -293,7 +300,6 @@ void git_attr_path__free(git_attr_path *info)
|
||||
info->basename = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* From gitattributes(5):
|
||||
*
|
||||
@ -338,10 +344,16 @@ int git_attr_fnmatch__parse(
|
||||
const char **base)
|
||||
{
|
||||
const char *pattern, *scan;
|
||||
int slash_count;
|
||||
int slash_count, allow_space;
|
||||
|
||||
assert(spec && base && *base);
|
||||
|
||||
if (parse_optimized_patterns(spec, pool, *base))
|
||||
return 0;
|
||||
|
||||
spec->flags = (spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE);
|
||||
allow_space = (spec->flags != 0);
|
||||
|
||||
pattern = *base;
|
||||
|
||||
while (git__isspace(*pattern)) pattern++;
|
||||
@ -350,8 +362,6 @@ int git_attr_fnmatch__parse(
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
spec->flags = 0;
|
||||
|
||||
if (*pattern == '[') {
|
||||
if (strncmp(pattern, "[attr]", 6) == 0) {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_MACRO;
|
||||
@ -368,8 +378,10 @@ int git_attr_fnmatch__parse(
|
||||
slash_count = 0;
|
||||
for (scan = pattern; *scan != '\0'; ++scan) {
|
||||
/* scan until (non-escaped) white space */
|
||||
if (git__isspace(*scan) && *(scan - 1) != '\\')
|
||||
break;
|
||||
if (git__isspace(*scan) && *(scan - 1) != '\\') {
|
||||
if (!allow_space || (*scan != ' ' && *scan != '\t'))
|
||||
break;
|
||||
}
|
||||
|
||||
if (*scan == '/') {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH;
|
||||
@ -418,22 +430,28 @@ int git_attr_fnmatch__parse(
|
||||
return -1;
|
||||
} else {
|
||||
/* strip '\' that might have be used for internal whitespace */
|
||||
char *to = spec->pattern;
|
||||
for (scan = spec->pattern; *scan; to++, scan++) {
|
||||
if (*scan == '\\')
|
||||
scan++; /* skip '\' but include next char */
|
||||
if (to != scan)
|
||||
*to = *scan;
|
||||
}
|
||||
if (to != scan) {
|
||||
*to = '\0';
|
||||
spec->length = (to - spec->pattern);
|
||||
}
|
||||
spec->length = git__unescape(spec->pattern);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool parse_optimized_patterns(
|
||||
git_attr_fnmatch *spec,
|
||||
git_pool *pool,
|
||||
const char *pattern)
|
||||
{
|
||||
if (!pattern[1] && (pattern[0] == '*' || pattern[0] == '.')) {
|
||||
spec->flags = GIT_ATTR_FNMATCH_MATCH_ALL;
|
||||
spec->pattern = git_pool_strndup(pool, pattern, 1);
|
||||
spec->length = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int sort_by_hash_and_name(const void *a_raw, const void *b_raw)
|
||||
{
|
||||
const git_attr_name *a = a_raw;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -7,14 +7,17 @@
|
||||
#ifndef INCLUDE_attr_file_h__
|
||||
#define INCLUDE_attr_file_h__
|
||||
|
||||
#include "git2/oid.h"
|
||||
#include "git2/attr.h"
|
||||
#include "vector.h"
|
||||
#include "pool.h"
|
||||
#include "buffer.h"
|
||||
#include "fileops.h"
|
||||
|
||||
#define GIT_ATTR_FILE ".gitattributes"
|
||||
#define GIT_ATTR_FILE_INREPO "info/attributes"
|
||||
#define GIT_ATTR_FILE_SYSTEM "gitattributes"
|
||||
#define GIT_ATTR_FILE_XDG "attributes"
|
||||
|
||||
#define GIT_ATTR_FNMATCH_NEGATIVE (1U << 0)
|
||||
#define GIT_ATTR_FNMATCH_DIRECTORY (1U << 1)
|
||||
@ -22,6 +25,13 @@
|
||||
#define GIT_ATTR_FNMATCH_MACRO (1U << 3)
|
||||
#define GIT_ATTR_FNMATCH_IGNORE (1U << 4)
|
||||
#define GIT_ATTR_FNMATCH_HASWILD (1U << 5)
|
||||
#define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6)
|
||||
#define GIT_ATTR_FNMATCH_ICASE (1U << 7)
|
||||
#define GIT_ATTR_FNMATCH_MATCH_ALL (1U << 8)
|
||||
|
||||
extern const char *git_attr__true;
|
||||
extern const char *git_attr__false;
|
||||
extern const char *git_attr__unset;
|
||||
|
||||
typedef struct {
|
||||
char *pattern;
|
||||
@ -47,12 +57,6 @@ typedef struct {
|
||||
const char *value;
|
||||
} git_attr_assignment;
|
||||
|
||||
typedef struct {
|
||||
git_time_t seconds;
|
||||
git_off_t size;
|
||||
unsigned int ino;
|
||||
} git_attr_file_stat_sig;
|
||||
|
||||
typedef struct {
|
||||
char *key; /* cache "source#path" this was loaded from */
|
||||
git_vector rules; /* vector of <rule*> or <fnmatch*> */
|
||||
@ -60,15 +64,15 @@ typedef struct {
|
||||
bool pool_is_allocated;
|
||||
union {
|
||||
git_oid oid;
|
||||
git_attr_file_stat_sig st;
|
||||
git_futils_filestamp stamp;
|
||||
} cache_data;
|
||||
} git_attr_file;
|
||||
|
||||
typedef struct {
|
||||
git_buf full;
|
||||
const char *path;
|
||||
const char *basename;
|
||||
int is_dir;
|
||||
git_buf full;
|
||||
char *path;
|
||||
char *basename;
|
||||
int is_dir;
|
||||
} git_attr_path;
|
||||
|
||||
typedef enum {
|
||||
@ -88,8 +92,10 @@ extern int git_attr_file__new_and_load(
|
||||
|
||||
extern void git_attr_file__free(git_attr_file *file);
|
||||
|
||||
extern void git_attr_file__clear_rules(git_attr_file *file);
|
||||
|
||||
extern int git_attr_file__parse_buffer(
|
||||
git_repository *repo, const char *buf, git_attr_file *file);
|
||||
git_repository *repo, void *parsedata, const char *buf, git_attr_file *file);
|
||||
|
||||
extern int git_attr_file__lookup_one(
|
||||
git_attr_file *file,
|
||||
|
24
src/attrcache.h
Normal file
24
src/attrcache.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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_attrcache_h__
|
||||
#define INCLUDE_attrcache_h__
|
||||
|
||||
#include "pool.h"
|
||||
#include "strmap.h"
|
||||
|
||||
typedef struct {
|
||||
int initialized;
|
||||
git_pool pool;
|
||||
git_strmap *files; /* hash path to git_attr_file of rules */
|
||||
git_strmap *macros; /* hash name to vector<git_attr_assignment> */
|
||||
const char *cfg_attr_file; /* cached value of core.attributesfile */
|
||||
const char *cfg_excl_file; /* cached value of core.excludesfile */
|
||||
} git_attr_cache;
|
||||
|
||||
extern int git_attr_cache__init(git_repository *repo);
|
||||
|
||||
#endif
|
136
src/blob.c
136
src/blob.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -12,17 +12,18 @@
|
||||
#include "common.h"
|
||||
#include "blob.h"
|
||||
#include "filter.h"
|
||||
#include "buf_text.h"
|
||||
|
||||
const void *git_blob_rawcontent(git_blob *blob)
|
||||
const void *git_blob_rawcontent(const git_blob *blob)
|
||||
{
|
||||
assert(blob);
|
||||
return blob->odb_object->raw.data;
|
||||
}
|
||||
|
||||
size_t git_blob_rawsize(git_blob *blob)
|
||||
git_off_t git_blob_rawsize(const git_blob *blob)
|
||||
{
|
||||
assert(blob);
|
||||
return blob->odb_object->raw.len;
|
||||
return (git_off_t)blob->odb_object->raw.len;
|
||||
}
|
||||
|
||||
int git_blob__getbuf(git_buf *buffer, git_blob *blob)
|
||||
@ -68,6 +69,7 @@ static int write_file_stream(
|
||||
int fd, error;
|
||||
char buffer[4096];
|
||||
git_odb_stream *stream = NULL;
|
||||
ssize_t read_len = -1, written = 0;
|
||||
|
||||
if ((error = git_odb_open_wstream(
|
||||
&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0)
|
||||
@ -78,20 +80,18 @@ static int write_file_stream(
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!error && file_size > 0) {
|
||||
ssize_t read_len = p_read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (read_len < 0) {
|
||||
giterr_set(
|
||||
GITERR_OS, "Failed to create blob. Can't read whole file");
|
||||
error = -1;
|
||||
}
|
||||
else if (!(error = stream->write(stream, buffer, read_len)))
|
||||
file_size -= read_len;
|
||||
while (!error && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
|
||||
error = stream->write(stream, buffer, read_len);
|
||||
written += read_len;
|
||||
}
|
||||
|
||||
p_close(fd);
|
||||
|
||||
if (written != file_size || read_len < 0) {
|
||||
giterr_set(GITERR_OS, "Failed to read file into stream");
|
||||
error = -1;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
error = stream->finalize_write(oid, stream);
|
||||
|
||||
@ -148,27 +148,31 @@ static int write_symlink(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int blob_create_internal(git_oid *oid, git_repository *repo, const char *path)
|
||||
static int blob_create_internal(git_oid *oid, git_repository *repo, const char *content_path, const char *hint_path, bool try_load_filters)
|
||||
{
|
||||
int error;
|
||||
struct stat st;
|
||||
git_odb *odb = NULL;
|
||||
git_off_t size;
|
||||
|
||||
if ((error = git_path_lstat(path, &st)) < 0 || (error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
assert(hint_path || !try_load_filters);
|
||||
|
||||
if ((error = git_path_lstat(content_path, &st)) < 0 || (error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
return error;
|
||||
|
||||
size = st.st_size;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
error = write_symlink(oid, odb, path, (size_t)size);
|
||||
error = write_symlink(oid, odb, content_path, (size_t)size);
|
||||
} else {
|
||||
git_vector write_filters = GIT_VECTOR_INIT;
|
||||
int filter_count;
|
||||
int filter_count = 0;
|
||||
|
||||
/* Load the filters for writing this file to the ODB */
|
||||
filter_count = git_filters_load(
|
||||
&write_filters, repo, path, GIT_FILTER_TO_ODB);
|
||||
if (try_load_filters) {
|
||||
/* Load the filters for writing this file to the ODB */
|
||||
filter_count = git_filters_load(
|
||||
&write_filters, repo, hint_path, GIT_FILTER_TO_ODB);
|
||||
}
|
||||
|
||||
if (filter_count < 0) {
|
||||
/* Negative value means there was a critical error */
|
||||
@ -176,10 +180,10 @@ static int blob_create_internal(git_oid *oid, git_repository *repo, const char *
|
||||
} else if (filter_count == 0) {
|
||||
/* No filters need to be applied to the document: we can stream
|
||||
* directly from disk */
|
||||
error = write_file_stream(oid, odb, path, size);
|
||||
error = write_file_stream(oid, odb, content_path, size);
|
||||
} else {
|
||||
/* We need to apply one or more filters */
|
||||
error = write_file_filtered(oid, odb, path, &write_filters);
|
||||
error = write_file_filtered(oid, odb, content_path, &write_filters);
|
||||
}
|
||||
|
||||
git_filters_free(&write_filters);
|
||||
@ -202,21 +206,25 @@ static int blob_create_internal(git_oid *oid, git_repository *repo, const char *
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
|
||||
int git_blob_create_fromworkdir(git_oid *oid, git_repository *repo, const char *path)
|
||||
{
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
const char *workdir;
|
||||
int error;
|
||||
|
||||
if ((error = git_repository__ensure_not_bare(repo, "create blob from file")) < 0)
|
||||
return error;
|
||||
|
||||
workdir = git_repository_workdir(repo);
|
||||
assert(workdir); /* error to call this on bare repo */
|
||||
|
||||
if (git_buf_joinpath(&full_path, workdir, path) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path));
|
||||
error = blob_create_internal(
|
||||
oid, repo, git_buf_cstr(&full_path),
|
||||
git_buf_cstr(&full_path) + strlen(workdir), true);
|
||||
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
@ -226,14 +234,88 @@ int git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *pat
|
||||
{
|
||||
int error;
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
const char *workdir, *hintpath;
|
||||
|
||||
if ((error = git_path_prettify(&full_path, path, NULL)) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path));
|
||||
hintpath = git_buf_cstr(&full_path);
|
||||
workdir = git_repository_workdir(repo);
|
||||
|
||||
if (workdir && !git__prefixcmp(hintpath, workdir))
|
||||
hintpath += strlen(workdir);
|
||||
|
||||
error = blob_create_internal(
|
||||
oid, repo, git_buf_cstr(&full_path), hintpath, true);
|
||||
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
int git_blob_create_fromchunks(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *hintpath,
|
||||
int (*source_cb)(char *content, size_t max_length, void *payload),
|
||||
void *payload)
|
||||
{
|
||||
int error = -1, read_bytes;
|
||||
char *content = NULL;
|
||||
git_filebuf file = GIT_FILEBUF_INIT;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
if (git_buf_join_n(
|
||||
&path, '/', 3,
|
||||
git_repository_path(repo),
|
||||
GIT_OBJECTS_DIR,
|
||||
"streamed") < 0)
|
||||
goto cleanup;
|
||||
|
||||
content = git__malloc(BUFFER_SIZE);
|
||||
GITERR_CHECK_ALLOC(content);
|
||||
|
||||
if (git_filebuf_open(&file, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY) < 0)
|
||||
goto cleanup;
|
||||
|
||||
while (1) {
|
||||
read_bytes = source_cb(content, BUFFER_SIZE, payload);
|
||||
|
||||
assert(read_bytes <= BUFFER_SIZE);
|
||||
|
||||
if (read_bytes <= 0)
|
||||
break;
|
||||
|
||||
if (git_filebuf_write(&file, content, read_bytes) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (read_bytes < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_filebuf_flush(&file) < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = blob_create_internal(oid, repo, file.path_lock, hintpath, hintpath != NULL);
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&path);
|
||||
git_filebuf_cleanup(&file);
|
||||
git__free(content);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_is_binary(git_blob *blob)
|
||||
{
|
||||
git_buf content;
|
||||
|
||||
assert(blob);
|
||||
|
||||
content.ptr = blob->odb_object->raw.data;
|
||||
content.size = min(blob->odb_object->raw.len, 4000);
|
||||
|
||||
return git_buf_text_is_binary(&content);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
|
587
src/branch.c
587
src/branch.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -7,8 +7,12 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "commit.h"
|
||||
#include "branch.h"
|
||||
#include "tag.h"
|
||||
#include "config.h"
|
||||
#include "refspec.h"
|
||||
#include "refs.h"
|
||||
|
||||
#include "git2/branch.h"
|
||||
|
||||
static int retrieve_branch_reference(
|
||||
git_reference **branch_reference_out,
|
||||
@ -41,168 +45,539 @@ cleanup:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int create_error_invalid(const char *msg)
|
||||
static int not_a_local_branch(const char *reference_name)
|
||||
{
|
||||
giterr_set(GITERR_INVALID, "Cannot create branch - %s", msg);
|
||||
giterr_set(
|
||||
GITERR_INVALID,
|
||||
"Reference '%s' is not a local branch.", reference_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_branch_create(
|
||||
git_oid *oid_out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
const git_object *target,
|
||||
int force)
|
||||
git_reference **ref_out,
|
||||
git_repository *repository,
|
||||
const char *branch_name,
|
||||
const git_commit *commit,
|
||||
int force)
|
||||
{
|
||||
git_otype target_type = GIT_OBJ_BAD;
|
||||
git_object *commit = NULL;
|
||||
git_reference *branch = NULL;
|
||||
git_buf canonical_branch_name = GIT_BUF_INIT;
|
||||
int error = -1;
|
||||
|
||||
assert(repo && branch_name && target && oid_out);
|
||||
|
||||
if (git_object_owner(target) != repo)
|
||||
return create_error_invalid("The given target does not belong to this repository");
|
||||
|
||||
target_type = git_object_type(target);
|
||||
|
||||
switch (target_type)
|
||||
{
|
||||
case GIT_OBJ_TAG:
|
||||
if (git_tag_peel(&commit, (git_tag *)target) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_object_type(commit) != GIT_OBJ_COMMIT) {
|
||||
create_error_invalid("The given target does not resolve to a commit");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIT_OBJ_COMMIT:
|
||||
commit = (git_object *)target;
|
||||
break;
|
||||
|
||||
default:
|
||||
return create_error_invalid("Only git_tag and git_commit objects are valid targets.");
|
||||
}
|
||||
assert(branch_name && commit && ref_out);
|
||||
assert(git_object_owner((const git_object *)commit) == repository);
|
||||
|
||||
if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_reference_create_oid(&branch, repo, git_buf_cstr(&canonical_branch_name), git_object_id(commit), force) < 0)
|
||||
goto cleanup;
|
||||
error = git_reference_create(&branch, repository,
|
||||
git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force);
|
||||
|
||||
git_oid_cpy(oid_out, git_reference_oid(branch));
|
||||
error = 0;
|
||||
if (!error)
|
||||
*ref_out = branch;
|
||||
|
||||
cleanup:
|
||||
if (target_type == GIT_OBJ_TAG)
|
||||
git_object_free(commit);
|
||||
|
||||
git_reference_free(branch);
|
||||
git_buf_free(&canonical_branch_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_t branch_type)
|
||||
int git_branch_delete(git_reference *branch)
|
||||
{
|
||||
git_reference *branch = NULL;
|
||||
git_reference *head = NULL;
|
||||
int error;
|
||||
int is_head;
|
||||
git_buf config_section = GIT_BUF_INIT;
|
||||
int error = -1;
|
||||
|
||||
assert((branch_type == GIT_BRANCH_LOCAL) || (branch_type == GIT_BRANCH_REMOTE));
|
||||
assert(branch);
|
||||
|
||||
if ((error = retrieve_branch_reference(&branch, repo, branch_name, branch_type == GIT_BRANCH_REMOTE)) < 0)
|
||||
return error;
|
||||
if (!git_reference_is_branch(branch) &&
|
||||
!git_reference_is_remote(branch)) {
|
||||
giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.", git_reference_name(branch));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) {
|
||||
giterr_set(GITERR_REFERENCE, "Cannot locate HEAD.");
|
||||
if ((is_head = git_branch_is_head(branch)) < 0)
|
||||
return is_head;
|
||||
|
||||
if (is_head) {
|
||||
giterr_set(GITERR_REFERENCE,
|
||||
"Cannot delete branch '%s' as it is the current HEAD of the repository.", git_reference_name(branch));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_buf_printf(&config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if ((git_reference_type(head) == GIT_REF_SYMBOLIC)
|
||||
&& (strcmp(git_reference_target(head), git_reference_name(branch)) == 0)) {
|
||||
giterr_set(GITERR_REFERENCE,
|
||||
"Cannot delete branch '%s' as it is the current HEAD of the repository.", branch_name);
|
||||
if (git_config_rename_section(
|
||||
git_reference_owner(branch),
|
||||
git_buf_cstr(&config_section),
|
||||
NULL) < 0)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if (git_reference_delete(branch) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_reference_free(head);
|
||||
return 0;
|
||||
error = 0;
|
||||
|
||||
on_error:
|
||||
git_reference_free(head);
|
||||
git_reference_free(branch);
|
||||
return -1;
|
||||
git_buf_free(&config_section);
|
||||
return error;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
git_vector *branchlist;
|
||||
git_branch_foreach_cb branch_cb;
|
||||
void *callback_payload;
|
||||
unsigned int branch_type;
|
||||
} branch_filter_data;
|
||||
} branch_foreach_filter;
|
||||
|
||||
static int branch_list_cb(const char *branch_name, void *payload)
|
||||
static int branch_foreach_cb(const char *branch_name, void *payload)
|
||||
{
|
||||
branch_filter_data *filter = (branch_filter_data *)payload;
|
||||
branch_foreach_filter *filter = (branch_foreach_filter *)payload;
|
||||
|
||||
if ((filter->branch_type & GIT_BRANCH_LOCAL && git__prefixcmp(branch_name, GIT_REFS_HEADS_DIR) == 0)
|
||||
|| (filter->branch_type & GIT_BRANCH_REMOTE && git__prefixcmp(branch_name, GIT_REFS_REMOTES_DIR) == 0))
|
||||
return git_vector_insert(filter->branchlist, git__strdup(branch_name));
|
||||
if (filter->branch_type & GIT_BRANCH_LOCAL &&
|
||||
git__prefixcmp(branch_name, GIT_REFS_HEADS_DIR) == 0)
|
||||
return filter->branch_cb(branch_name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, filter->callback_payload);
|
||||
|
||||
if (filter->branch_type & GIT_BRANCH_REMOTE &&
|
||||
git__prefixcmp(branch_name, GIT_REFS_REMOTES_DIR) == 0)
|
||||
return filter->branch_cb(branch_name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, filter->callback_payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_branch_list(git_strarray *branch_names, git_repository *repo, unsigned int list_flags)
|
||||
int git_branch_foreach(
|
||||
git_repository *repo,
|
||||
unsigned int list_flags,
|
||||
git_branch_foreach_cb branch_cb,
|
||||
void *payload)
|
||||
{
|
||||
int error;
|
||||
branch_filter_data filter;
|
||||
git_vector branchlist;
|
||||
branch_foreach_filter filter;
|
||||
|
||||
assert(branch_names && repo);
|
||||
|
||||
if (git_vector_init(&branchlist, 8, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
filter.branchlist = &branchlist;
|
||||
filter.branch_cb = branch_cb;
|
||||
filter.branch_type = list_flags;
|
||||
filter.callback_payload = payload;
|
||||
|
||||
error = git_reference_foreach(repo, GIT_REF_LISTALL, &branch_list_cb, (void *)&filter);
|
||||
if (error < 0) {
|
||||
git_vector_free(&branchlist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
branch_names->strings = (char **)branchlist.contents;
|
||||
branch_names->count = branchlist.length;
|
||||
return 0;
|
||||
return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
|
||||
}
|
||||
|
||||
int git_branch_move(git_repository *repo, const char *old_branch_name, const char *new_branch_name, int force)
|
||||
int git_branch_move(
|
||||
git_reference **out,
|
||||
git_reference *branch,
|
||||
const char *new_branch_name,
|
||||
int force)
|
||||
{
|
||||
git_reference *reference = NULL;
|
||||
git_buf old_reference_name = GIT_BUF_INIT, new_reference_name = GIT_BUF_INIT;
|
||||
int error = 0;
|
||||
git_buf new_reference_name = GIT_BUF_INIT,
|
||||
old_config_section = GIT_BUF_INIT,
|
||||
new_config_section = GIT_BUF_INIT;
|
||||
int error;
|
||||
|
||||
if ((error = git_buf_joinpath(&old_reference_name, GIT_REFS_HEADS_DIR, old_branch_name)) < 0)
|
||||
goto cleanup;
|
||||
assert(branch && new_branch_name);
|
||||
|
||||
/* We need to be able to return GIT_ENOTFOUND */
|
||||
if ((error = git_reference_lookup(&reference, repo, git_buf_cstr(&old_reference_name))) < 0)
|
||||
goto cleanup;
|
||||
if (!git_reference_is_branch(branch))
|
||||
return not_a_local_branch(git_reference_name(branch));
|
||||
|
||||
if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
|
||||
goto cleanup;
|
||||
if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0 ||
|
||||
(error = git_buf_printf(&old_config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR))) < 0 ||
|
||||
(error = git_buf_printf(&new_config_section, "branch.%s", new_branch_name)) < 0)
|
||||
goto done;
|
||||
|
||||
error = git_reference_rename(reference, git_buf_cstr(&new_reference_name), force);
|
||||
if ((error = git_config_rename_section(git_reference_owner(branch),
|
||||
git_buf_cstr(&old_config_section),
|
||||
git_buf_cstr(&new_config_section))) < 0)
|
||||
goto done;
|
||||
|
||||
if ((error = git_reference_rename(out, branch, git_buf_cstr(&new_reference_name), force)) < 0)
|
||||
goto done;
|
||||
|
||||
cleanup:
|
||||
git_reference_free(reference);
|
||||
git_buf_free(&old_reference_name);
|
||||
done:
|
||||
git_buf_free(&new_reference_name);
|
||||
git_buf_free(&old_config_section);
|
||||
git_buf_free(&new_config_section);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_lookup(
|
||||
git_reference **ref_out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
git_branch_t branch_type)
|
||||
{
|
||||
assert(ref_out && repo && branch_name);
|
||||
|
||||
return retrieve_branch_reference(ref_out, repo, branch_name, branch_type == GIT_BRANCH_REMOTE);
|
||||
}
|
||||
|
||||
int git_branch_name(const char **out, git_reference *ref)
|
||||
{
|
||||
const char *branch_name;
|
||||
|
||||
assert(out && ref);
|
||||
|
||||
branch_name = ref->name;
|
||||
|
||||
if (git_reference_is_branch(ref)) {
|
||||
branch_name += strlen(GIT_REFS_HEADS_DIR);
|
||||
} else if (git_reference_is_remote(ref)) {
|
||||
branch_name += strlen(GIT_REFS_REMOTES_DIR);
|
||||
} else {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Reference '%s' is neither a local nor a remote branch.", ref->name);
|
||||
return -1;
|
||||
}
|
||||
*out = branch_name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int retrieve_upstream_configuration(
|
||||
const char **out,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name,
|
||||
const char *format)
|
||||
{
|
||||
git_config *config;
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
int error;
|
||||
|
||||
if (git_repository_config__weakptr(&config, repo) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_buf_printf(&buf, format,
|
||||
canonical_branch_name + strlen(GIT_REFS_HEADS_DIR)) < 0)
|
||||
return -1;
|
||||
|
||||
error = git_config_get_string(out, config, git_buf_cstr(&buf));
|
||||
git_buf_free(&buf);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_upstream__name(
|
||||
git_buf *tracking_name,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name)
|
||||
{
|
||||
const char *remote_name, *merge_name;
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
int error = -1;
|
||||
git_remote *remote = NULL;
|
||||
const git_refspec *refspec;
|
||||
|
||||
assert(tracking_name && canonical_branch_name);
|
||||
|
||||
if (!git_reference__is_branch(canonical_branch_name))
|
||||
return not_a_local_branch(canonical_branch_name);
|
||||
|
||||
if ((error = retrieve_upstream_configuration(
|
||||
&remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = retrieve_upstream_configuration(
|
||||
&merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!*remote_name || !*merge_name) {
|
||||
error = GIT_ENOTFOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp(".", remote_name) != 0) {
|
||||
if ((error = git_remote_load(&remote, repo, remote_name)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
refspec = git_remote_fetchspec(remote);
|
||||
if (refspec == NULL
|
||||
|| refspec->src == NULL
|
||||
|| refspec->dst == NULL) {
|
||||
error = GIT_ENOTFOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (git_refspec_transform_r(&buf, refspec, merge_name) < 0)
|
||||
goto cleanup;
|
||||
} else
|
||||
if (git_buf_sets(&buf, merge_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = git_buf_set(tracking_name, git_buf_cstr(&buf), git_buf_len(&buf));
|
||||
|
||||
cleanup:
|
||||
git_remote_free(remote);
|
||||
git_buf_free(&buf);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int remote_name(git_buf *buf, git_repository *repo, const char *canonical_branch_name)
|
||||
{
|
||||
git_strarray remote_list = {0};
|
||||
size_t i;
|
||||
git_remote *remote;
|
||||
const git_refspec *fetchspec;
|
||||
int error = 0;
|
||||
char *remote_name = NULL;
|
||||
|
||||
assert(buf && repo && canonical_branch_name);
|
||||
|
||||
/* Verify that this is a remote branch */
|
||||
if (!git_reference__is_remote(canonical_branch_name)) {
|
||||
giterr_set(GITERR_INVALID, "Reference '%s' is not a remote branch.",
|
||||
canonical_branch_name);
|
||||
error = GIT_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get the remotes */
|
||||
if ((error = git_remote_list(&remote_list, repo)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Find matching remotes */
|
||||
for (i = 0; i < remote_list.count; i++) {
|
||||
if ((error = git_remote_load(&remote, repo, remote_list.strings[i])) < 0)
|
||||
continue;
|
||||
|
||||
fetchspec = git_remote_fetchspec(remote);
|
||||
|
||||
/* Defensivly check that we have a fetchspec */
|
||||
if (fetchspec &&
|
||||
git_refspec_dst_matches(fetchspec, canonical_branch_name)) {
|
||||
/* If we have not already set out yet, then set
|
||||
* it to the matching remote name. Otherwise
|
||||
* multiple remotes match this reference, and it
|
||||
* is ambiguous. */
|
||||
if (!remote_name) {
|
||||
remote_name = remote_list.strings[i];
|
||||
} else {
|
||||
git_remote_free(remote);
|
||||
error = GIT_EAMBIGUOUS;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
git_remote_free(remote);
|
||||
}
|
||||
|
||||
if (remote_name) {
|
||||
git_buf_clear(buf);
|
||||
error = git_buf_puts(buf, remote_name);
|
||||
} else {
|
||||
error = GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_strarray_free(&remote_list);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_remote_name(char *buffer, size_t buffer_len, git_repository *repo, const char *refname)
|
||||
{
|
||||
int ret;
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
|
||||
if ((ret = remote_name(&buf, repo, refname)) < 0)
|
||||
return ret;
|
||||
|
||||
if (buffer)
|
||||
git_buf_copy_cstr(buffer, buffer_len, &buf);
|
||||
|
||||
ret = git_buf_len(&buf) + 1;
|
||||
git_buf_free(&buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int git_branch_upstream_name(
|
||||
char *tracking_branch_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name)
|
||||
{
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
int error;
|
||||
|
||||
assert(canonical_branch_name);
|
||||
|
||||
if (tracking_branch_name_out && buffer_size)
|
||||
*tracking_branch_name_out = '\0';
|
||||
|
||||
if ((error = git_branch_upstream__name(
|
||||
&buf, repo, canonical_branch_name)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (tracking_branch_name_out && buf.size + 1 > buffer_size) { /* +1 for NUL byte */
|
||||
giterr_set(
|
||||
GITERR_INVALID,
|
||||
"Buffer too short to hold the tracked reference name.");
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (tracking_branch_name_out)
|
||||
git_buf_copy_cstr(tracking_branch_name_out, buffer_size, &buf);
|
||||
|
||||
error = (int)buf.size + 1;
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&buf);
|
||||
return (int)error;
|
||||
}
|
||||
|
||||
int git_branch_upstream(
|
||||
git_reference **tracking_out,
|
||||
git_reference *branch)
|
||||
{
|
||||
int error;
|
||||
git_buf tracking_name = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_branch_upstream__name(&tracking_name,
|
||||
git_reference_owner(branch), git_reference_name(branch))) < 0)
|
||||
return error;
|
||||
|
||||
error = git_reference_lookup(
|
||||
tracking_out,
|
||||
git_reference_owner(branch),
|
||||
git_buf_cstr(&tracking_name));
|
||||
|
||||
git_buf_free(&tracking_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int unset_upstream(git_config *config, const char *shortname)
|
||||
{
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
|
||||
if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_buf_clear(&buf);
|
||||
if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_buf_free(&buf);
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_buf_free(&buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_branch_set_upstream(git_reference *branch, const char *upstream_name)
|
||||
{
|
||||
git_buf key = GIT_BUF_INIT, value = GIT_BUF_INIT;
|
||||
git_reference *upstream;
|
||||
git_repository *repo;
|
||||
git_remote *remote = NULL;
|
||||
git_config *config;
|
||||
const char *name, *shortname;
|
||||
int local;
|
||||
const git_refspec *fetchspec;
|
||||
|
||||
name = git_reference_name(branch);
|
||||
if (!git_reference__is_branch(name))
|
||||
return not_a_local_branch(name);
|
||||
|
||||
if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0)
|
||||
return -1;
|
||||
|
||||
shortname = name + strlen(GIT_REFS_HEADS_DIR);
|
||||
|
||||
if (upstream_name == NULL)
|
||||
return unset_upstream(config, shortname);
|
||||
|
||||
repo = git_reference_owner(branch);
|
||||
|
||||
/* First we need to figure out whether it's a branch or remote-tracking */
|
||||
if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_LOCAL) == 0)
|
||||
local = 1;
|
||||
else if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_REMOTE) == 0)
|
||||
local = 0;
|
||||
else
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
/*
|
||||
* If it's local, the remote is "." and the branch name is
|
||||
* simply the refname. Otherwise we need to figure out what
|
||||
* the remote-tracking branch's name on the remote is and use
|
||||
* that.
|
||||
*/
|
||||
if (local)
|
||||
git_buf_puts(&value, ".");
|
||||
else
|
||||
remote_name(&value, repo, git_reference_name(upstream));
|
||||
|
||||
if (git_buf_printf(&key, "branch.%s.remote", shortname) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (local) {
|
||||
if (git_buf_puts(&value, git_reference_name(branch)) < 0)
|
||||
goto on_error;
|
||||
} else {
|
||||
/* Get the remoe-tracking branch's refname in its repo */
|
||||
if (git_remote_load(&remote, repo, git_buf_cstr(&value)) < 0)
|
||||
goto on_error;
|
||||
|
||||
fetchspec = git_remote_fetchspec(remote);
|
||||
git_buf_clear(&value);
|
||||
if (git_refspec_transform_l(&value, fetchspec, git_reference_name(upstream)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_remote_free(remote);
|
||||
remote = NULL;
|
||||
}
|
||||
|
||||
git_buf_clear(&key);
|
||||
if (git_buf_printf(&key, "branch.%s.merge", shortname) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_reference_free(upstream);
|
||||
git_buf_free(&key);
|
||||
git_buf_free(&value);
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_reference_free(upstream);
|
||||
git_buf_free(&key);
|
||||
git_buf_free(&value);
|
||||
git_remote_free(remote);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_branch_is_head(
|
||||
git_reference *branch)
|
||||
{
|
||||
git_reference *head;
|
||||
bool is_same = false;
|
||||
int error;
|
||||
|
||||
assert(branch);
|
||||
|
||||
if (!git_reference_is_branch(branch))
|
||||
return false;
|
||||
|
||||
error = git_repository_head(&head, git_reference_owner(branch));
|
||||
|
||||
if (error == GIT_EORPHANEDHEAD || error == GIT_ENOTFOUND)
|
||||
return false;
|
||||
|
||||
if (error < 0)
|
||||
return -1;
|
||||
|
||||
is_same = strcmp(
|
||||
git_reference_name(branch),
|
||||
git_reference_name(head)) == 0;
|
||||
|
||||
git_reference_free(head);
|
||||
|
||||
return is_same;
|
||||
}
|
||||
|
12
src/branch.h
12
src/branch.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
@ -7,11 +7,11 @@
|
||||
#ifndef INCLUDE_branch_h__
|
||||
#define INCLUDE_branch_h__
|
||||
|
||||
#include "git2/branch.h"
|
||||
#include "buffer.h"
|
||||
|
||||
struct git_branch {
|
||||
char *remote; /* TODO: Make this a git_remote */
|
||||
char *merge;
|
||||
};
|
||||
int git_branch_upstream__name(
|
||||
git_buf *tracking_name,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name);
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
* 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.
|
||||
|
291
src/buf_text.c
Normal file
291
src/buf_text.c
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* 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 "buf_text.h"
|
||||
|
||||
int git_buf_text_puts_escaped(
|
||||
git_buf *buf,
|
||||
const char *string,
|
||||
const char *esc_chars,
|
||||
const char *esc_with)
|
||||
{
|
||||
const char *scan;
|
||||
size_t total = 0, esc_len = strlen(esc_with), count;
|
||||
|
||||
if (!string)
|
||||
return 0;
|
||||
|
||||
for (scan = string; *scan; ) {
|
||||
/* count run of non-escaped characters */
|
||||
count = strcspn(scan, esc_chars);
|
||||
total += count;
|
||||
scan += count;
|
||||
/* count run of escaped characters */
|
||||
count = strspn(scan, esc_chars);
|
||||
total += count * (esc_len + 1);
|
||||
scan += count;
|
||||
}
|
||||
|
||||
if (git_buf_grow(buf, buf->size + total + 1) < 0)
|
||||
return -1;
|
||||
|
||||
for (scan = string; *scan; ) {
|
||||
count = strcspn(scan, esc_chars);
|
||||
|
||||
memmove(buf->ptr + buf->size, scan, count);
|
||||
scan += count;
|
||||
buf->size += count;
|
||||
|
||||
for (count = strspn(scan, esc_chars); count > 0; --count) {
|
||||
/* copy escape sequence */
|
||||
memmove(buf->ptr + buf->size, esc_with, esc_len);
|
||||
buf->size += esc_len;
|
||||
/* copy character to be escaped */
|
||||
buf->ptr[buf->size] = *scan;
|
||||
buf->size++;
|
||||
scan++;
|
||||
}
|
||||
}
|
||||
|
||||
buf->ptr[buf->size] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_buf_text_unescape(git_buf *buf)
|
||||
{
|
||||
buf->size = git__unescape(buf->ptr);
|
||||
}
|
||||
|
||||
int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src)
|
||||
{
|
||||
const char *scan = src->ptr;
|
||||
const char *scan_end = src->ptr + src->size;
|
||||
const char *next = memchr(scan, '\r', src->size);
|
||||
char *out;
|
||||
|
||||
assert(tgt != src);
|
||||
|
||||
if (!next)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
/* reduce reallocs while in the loop */
|
||||
if (git_buf_grow(tgt, src->size) < 0)
|
||||
return -1;
|
||||
out = tgt->ptr;
|
||||
tgt->size = 0;
|
||||
|
||||
/* Find the next \r and copy whole chunk up to there to tgt */
|
||||
for (; next; scan = next + 1, next = memchr(scan, '\r', scan_end - scan)) {
|
||||
if (next > scan) {
|
||||
size_t copylen = next - scan;
|
||||
memcpy(out, scan, copylen);
|
||||
out += copylen;
|
||||
}
|
||||
|
||||
/* Do not drop \r unless it is followed by \n */
|
||||
if (next[1] != '\n')
|
||||
*out++ = '\r';
|
||||
}
|
||||
|
||||
/* Copy remaining input into dest */
|
||||
memcpy(out, scan, scan_end - scan + 1); /* +1 for NUL byte */
|
||||
out += (scan_end - scan);
|
||||
tgt->size = out - tgt->ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
|
||||
{
|
||||
const char *start = src->ptr;
|
||||
const char *end = start + src->size;
|
||||
const char *scan = start;
|
||||
const char *next = memchr(scan, '\n', src->size);
|
||||
|
||||
assert(tgt != src);
|
||||
|
||||
if (!next)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
/* attempt to reduce reallocs while in the loop */
|
||||
if (git_buf_grow(tgt, src->size + (src->size >> 4) + 1) < 0)
|
||||
return -1;
|
||||
tgt->size = 0;
|
||||
|
||||
for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
|
||||
size_t copylen = next - scan;
|
||||
/* don't convert existing \r\n to \r\r\n */
|
||||
size_t extralen = (next > start && next[-1] == '\r') ? 1 : 2;
|
||||
size_t needsize = tgt->size + copylen + extralen + 1;
|
||||
|
||||
if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0)
|
||||
return -1;
|
||||
|
||||
if (next > scan) {
|
||||
memcpy(tgt->ptr + tgt->size, scan, copylen);
|
||||
tgt->size += copylen;
|
||||
}
|
||||
if (extralen == 2)
|
||||
tgt->ptr[tgt->size++] = '\r';
|
||||
tgt->ptr[tgt->size++] = '\n';
|
||||
}
|
||||
|
||||
return git_buf_put(tgt, scan, end - scan);
|
||||
}
|
||||
|
||||
int git_buf_text_common_prefix(git_buf *buf, const git_strarray *strings)
|
||||
{
|
||||
size_t i;
|
||||
const char *str, *pfx;
|
||||
|
||||
git_buf_clear(buf);
|
||||
|
||||
if (!strings || !strings->count)
|
||||
return 0;
|
||||
|
||||
/* initialize common prefix to first string */
|
||||
if (git_buf_sets(buf, strings->strings[0]) < 0)
|
||||
return -1;
|
||||
|
||||
/* go through the rest of the strings, truncating to shared prefix */
|
||||
for (i = 1; i < strings->count; ++i) {
|
||||
|
||||
for (str = strings->strings[i], pfx = buf->ptr;
|
||||
*str && *str == *pfx; str++, pfx++)
|
||||
/* scanning */;
|
||||
|
||||
git_buf_truncate(buf, pfx - buf->ptr);
|
||||
|
||||
if (!buf->size)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool git_buf_text_is_binary(const git_buf *buf)
|
||||
{
|
||||
const char *scan = buf->ptr, *end = buf->ptr + buf->size;
|
||||
int printable = 0, nonprintable = 0;
|
||||
|
||||
while (scan < end) {
|
||||
unsigned char c = *scan++;
|
||||
|
||||
if (c > 0x1F && c < 0x7F)
|
||||
printable++;
|
||||
else if (c == '\0')
|
||||
return true;
|
||||
else if (!git__isspace(c))
|
||||
nonprintable++;
|
||||
}
|
||||
|
||||
return ((printable >> 7) < nonprintable);
|
||||
}
|
||||
|
||||
bool git_buf_text_contains_nul(const git_buf *buf)
|
||||
{
|
||||
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)
|
||||
{
|
||||
const char *ptr;
|
||||
size_t len;
|
||||
|
||||
*bom = GIT_BOM_NONE;
|
||||
/* need at least 2 bytes after offset to look for any BOM */
|
||||
if (buf->size < offset + 2)
|
||||
return 0;
|
||||
|
||||
ptr = buf->ptr + offset;
|
||||
len = buf->size - offset;
|
||||
|
||||
switch (*ptr++) {
|
||||
case 0:
|
||||
if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') {
|
||||
*bom = GIT_BOM_UTF32_BE;
|
||||
return 4;
|
||||
}
|
||||
break;
|
||||
case '\xEF':
|
||||
if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') {
|
||||
*bom = GIT_BOM_UTF8;
|
||||
return 3;
|
||||
}
|
||||
break;
|
||||
case '\xFE':
|
||||
if (*ptr == '\xFF') {
|
||||
*bom = GIT_BOM_UTF16_BE;
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
case '\xFF':
|
||||
if (*ptr != '\xFE')
|
||||
break;
|
||||
if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) {
|
||||
*bom = GIT_BOM_UTF32_LE;
|
||||
return 4;
|
||||
} else {
|
||||
*bom = GIT_BOM_UTF16_LE;
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool git_buf_text_gather_stats(
|
||||
git_buf_text_stats *stats, const git_buf *buf, bool skip_bom)
|
||||
{
|
||||
const char *scan = buf->ptr, *end = buf->ptr + buf->size;
|
||||
int skip;
|
||||
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
|
||||
/* BOM detection */
|
||||
skip = git_buf_text_detect_bom(&stats->bom, buf, 0);
|
||||
if (skip_bom)
|
||||
scan += skip;
|
||||
|
||||
/* Ignore EOF character */
|
||||
if (buf->size > 0 && end[-1] == '\032')
|
||||
end--;
|
||||
|
||||
/* Counting loop */
|
||||
while (scan < end) {
|
||||
unsigned char c = *scan++;
|
||||
|
||||
if ((c > 0x1F && c < 0x7F) || c > 0x9f)
|
||||
stats->printable++;
|
||||
else switch (c) {
|
||||
case '\0':
|
||||
stats->nul++;
|
||||
stats->nonprintable++;
|
||||
break;
|
||||
case '\n':
|
||||
stats->lf++;
|
||||
break;
|
||||
case '\r':
|
||||
stats->cr++;
|
||||
if (scan < end && *scan == '\n')
|
||||
stats->crlf++;
|
||||
break;
|
||||
case '\t': case '\f': case '\v': case '\b': case 0x1b: /*ESC*/
|
||||
stats->printable++;
|
||||
break;
|
||||
default:
|
||||
stats->nonprintable++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (stats->nul > 0 ||
|
||||
((stats->printable >> 7) < stats->nonprintable));
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user