mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-02 14:37:30 +00:00
Merge remote-tracking branch 'upstream/master' into cmn/describe
This commit is contained in:
commit
af6cc38fc0
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@ -0,0 +1,14 @@
|
||||
; Check http://editorconfig.org/ for more informations
|
||||
; Top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
; tab indentation
|
||||
[*]
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
; 4-column space indentation
|
||||
[*.md]
|
||||
indent_style = space
|
||||
indent_size = 4
|
27
.travis.yml
27
.travis.yml
@ -3,6 +3,10 @@
|
||||
|
||||
language: c
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
@ -17,17 +21,27 @@ env:
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
include:
|
||||
- compiler: i586-mingw32msvc-gcc
|
||||
env: OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON"
|
||||
env: OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON -DUSE_SSH=OFF"
|
||||
os: linux
|
||||
- compiler: gcc
|
||||
env: COVERITY=1
|
||||
os: linux
|
||||
- compiler: gcc
|
||||
env:
|
||||
- VALGRIND=1
|
||||
OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=Debug"
|
||||
os: linux
|
||||
allow_failures:
|
||||
- env: COVERITY=1
|
||||
- env: VALGRIND=1
|
||||
|
||||
install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get -qq install cmake libssh2-1-dev openssh-client openssh-server
|
||||
- ./script/install-deps-${TRAVIS_OS_NAME}.sh
|
||||
|
||||
# Run the Build script and tests
|
||||
script:
|
||||
@ -35,13 +49,14 @@ script:
|
||||
|
||||
# Run Tests
|
||||
after_success:
|
||||
- sudo apt-get -qq install valgrind
|
||||
- valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" -a -n "$VALGRIND" ]; then sudo apt-get -qq install valgrind; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" -a -n "$VALGRIND" ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline; fi
|
||||
|
||||
# Only watch the development branch
|
||||
# Only watch the development and master branches
|
||||
branches:
|
||||
only:
|
||||
- development
|
||||
- master
|
||||
|
||||
# Notify development list when needed
|
||||
notifications:
|
||||
|
1
AUTHORS
1
AUTHORS
@ -6,6 +6,7 @@ Alexei Sholik
|
||||
Andreas Ericsson
|
||||
Anton "antong" Gyllenberg
|
||||
Ankur Sethi
|
||||
Arthur Schreiber
|
||||
Ben Noordhuis
|
||||
Ben Straub
|
||||
Benjamin C Meyer
|
||||
|
60
CHANGELOG.md
Normal file
60
CHANGELOG.md
Normal file
@ -0,0 +1,60 @@
|
||||
v0.21 + 1
|
||||
------
|
||||
|
||||
* File unlocks are atomic again via rename. Read-only files on Windows are
|
||||
made read-write if necessary.
|
||||
|
||||
* Share open packfiles across repositories to share descriptors and mmaps.
|
||||
|
||||
* Use a map for the treebuilder, making insertion O(1)
|
||||
|
||||
* LF -> CRLF filter refuses to handle mixed-EOL files
|
||||
|
||||
* LF -> CRLF filter now runs when * text = auto (with Git for Windows 1.9.4)
|
||||
|
||||
* The git_transport structure definition has moved into the sys/transport.h
|
||||
file.
|
||||
|
||||
* The ssh transport supports asking the remote host for accepted
|
||||
credential types as well as multiple challeges using a single
|
||||
connection. This requires to know which username you want to connect
|
||||
as, so this introduces the USERNAME credential type which the ssh
|
||||
transport will use to ask for the username.
|
||||
|
||||
* The git_transport_register function no longer takes a priority and takes
|
||||
a URL scheme name (eg "http") instead of a prefix like "http://"
|
||||
|
||||
* The git_remote_set_transport function now sets a transport factory function,
|
||||
rather than a pre-existing transport instance.
|
||||
|
||||
* A factory function for ssh has been added which allows to change the
|
||||
path of the programs to execute for receive-pack and upload-pack on
|
||||
the server, git_transport_ssh_with_paths.
|
||||
|
||||
* The git_clone_options struct no longer provides the ignore_cert_errors or
|
||||
remote_name members for remote customization.
|
||||
|
||||
Instead, the git_clone_options struct has two new members, remote_cb and
|
||||
remote_cb_payload, which allow the caller to completely override the remote
|
||||
creation process. If needed, the caller can use this callback to give their
|
||||
remote a name other than the default (origin) or disable cert checking.
|
||||
|
||||
The remote_callbacks member has been preserved for convenience, although it
|
||||
is not used when a remote creation callback is supplied.
|
||||
|
||||
* The git_clone_options struct now provides repository_cb and
|
||||
repository_cb_payload to allow the user to create a repository with
|
||||
custom options.
|
||||
|
||||
* The option to ignore certificate errors via git_remote_cert_check()
|
||||
is no longer present. Instead, git_remote_callbacks has gained a new
|
||||
entry which lets the user perform their own certificate checks.
|
||||
|
||||
* git_clone_into and git_clone_local_into have been removed from the
|
||||
public API in favour of git_clone callbacks
|
||||
|
||||
* Add support for refspecs with the asterisk in the middle of a
|
||||
pattern.
|
||||
|
||||
* Introduce git_merge_bases() and the git_oidarray type to expose all
|
||||
merge bases between two commits.
|
@ -36,6 +36,7 @@ OPTION( ANDROID "Build for android NDK" OFF )
|
||||
|
||||
OPTION( USE_ICONV "Link with and use iconv library" OFF )
|
||||
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
|
||||
OPTION( USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF )
|
||||
OPTION( VALGRIND "Configure build for valgrind" OFF )
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
@ -127,6 +128,9 @@ STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_V
|
||||
STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}")
|
||||
SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
|
||||
|
||||
FILE(STRINGS "include/git2/version.h" GIT2_HEADER_SOVERSION REGEX "^#define LIBGIT2_SOVERSION [0-9]+$")
|
||||
STRING(REGEX REPLACE "^.*LIBGIT2_SOVERSION ([0-9]+)$" "\\1" LIBGIT2_SOVERSION "${GIT2_HEADER_SOVERSION}")
|
||||
|
||||
# Find required dependencies
|
||||
INCLUDE_DIRECTORIES(src include)
|
||||
|
||||
@ -139,7 +143,7 @@ ELSE ()
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
ENDIF ()
|
||||
|
||||
FIND_PACKAGE(HTTP_Parser QUIET)
|
||||
FIND_PACKAGE(HTTP_Parser)
|
||||
IF (HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2)
|
||||
INCLUDE_DIRECTORIES(${HTTP_PARSER_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${HTTP_PARSER_LIBRARIES})
|
||||
@ -157,7 +161,11 @@ IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin")
|
||||
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
|
||||
ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin")
|
||||
ADD_DEFINITIONS(-DOPENSSL_SHA1)
|
||||
SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} openssl")
|
||||
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} -lssl")
|
||||
ELSE()
|
||||
SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} openssl")
|
||||
ENDIF ()
|
||||
ELSE()
|
||||
FILE(GLOB SRC_SHA1 src/hash/hash_generic.c)
|
||||
ENDIF()
|
||||
@ -168,25 +176,21 @@ IF (ENABLE_TRACE STREQUAL "ON")
|
||||
ENDIF()
|
||||
|
||||
# Include POSIX regex when it is required
|
||||
IF(WIN32 OR AMIGA OR ANDROID)
|
||||
IF(WIN32 OR AMIGA OR ANDROID OR CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
INCLUDE_DIRECTORIES(deps/regex)
|
||||
SET(SRC_REGEX deps/regex/regex.c)
|
||||
ENDIF()
|
||||
|
||||
# Optional external dependency: zlib
|
||||
# It's optional, but FIND_PACKAGE gives a warning that looks more like an
|
||||
# error.
|
||||
FIND_PACKAGE(ZLIB QUIET)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
IF (ZLIB_FOUND)
|
||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${ZLIB_LIBRARIES})
|
||||
IF(APPLE)
|
||||
IF(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} -lz")
|
||||
ELSE()
|
||||
SET(LIBGIT2_PC_REQUIRES "${LIBGIT2_PC_REQUIRES} zlib")
|
||||
ENDIF()
|
||||
# Fake the message CMake would have shown
|
||||
MESSAGE(STATUS "Found zlib: ${ZLIB_LIBRARY}")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." )
|
||||
INCLUDE_DIRECTORIES(deps/zlib)
|
||||
@ -195,8 +199,8 @@ ELSE()
|
||||
ENDIF()
|
||||
|
||||
# Optional external dependency: libssh2
|
||||
IF (USE_SSH AND NOT MINGW)
|
||||
FIND_PACKAGE(LIBSSH2 QUIET)
|
||||
IF (USE_SSH)
|
||||
FIND_PACKAGE(LIBSSH2)
|
||||
ENDIF()
|
||||
IF (LIBSSH2_FOUND)
|
||||
ADD_DEFINITIONS(-DGIT_SSH)
|
||||
@ -205,9 +209,17 @@ IF (LIBSSH2_FOUND)
|
||||
SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
# Optional external dependency: libgssapi
|
||||
IF (USE_GSSAPI)
|
||||
FIND_PACKAGE(GSSAPI)
|
||||
ENDIF()
|
||||
IF (GSSAPI_FOUND)
|
||||
ADD_DEFINITIONS(-DGIT_GSSAPI)
|
||||
ENDIF()
|
||||
|
||||
# Optional external dependency: iconv
|
||||
IF (USE_ICONV)
|
||||
FIND_PACKAGE(ICONV QUIET)
|
||||
FIND_PACKAGE(Iconv)
|
||||
ENDIF()
|
||||
IF (ICONV_FOUND)
|
||||
ADD_DEFINITIONS(-DGIT_USE_ICONV)
|
||||
@ -290,6 +302,10 @@ IF (MSVC)
|
||||
ELSE ()
|
||||
SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -Wall -Wextra ${CMAKE_C_FLAGS}")
|
||||
|
||||
IF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
SET(CMAKE_C_FLAGS "-std=c99 -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}")
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32 AND NOT CYGWIN)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-D_DEBUG")
|
||||
ENDIF ()
|
||||
@ -380,6 +396,7 @@ ENDIF()
|
||||
ADD_LIBRARY(git2 ${SRC_H} ${SRC_GIT2} ${SRC_OS} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC})
|
||||
TARGET_LINK_LIBRARIES(git2 ${SSL_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(git2 ${SSH_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(git2 ${GSSAPI_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(git2 ${ICONV_LIBRARIES})
|
||||
TARGET_OS_LIBRARIES(git2)
|
||||
|
||||
@ -393,7 +410,7 @@ MSVC_SPLIT_SOURCES(git2)
|
||||
|
||||
IF (SONAME)
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING})
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_VERSION_MAJOR})
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_SOVERSION})
|
||||
IF (LIBGIT2_FILENAME)
|
||||
ADD_DEFINITIONS(-DLIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\")
|
||||
SET_TARGET_PROPERTIES(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME})
|
||||
@ -446,6 +463,7 @@ IF (BUILD_CLAR)
|
||||
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ${SSL_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ${SSH_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ${GSSAPI_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(libgit2_clar ${ICONV_LIBRARIES})
|
||||
TARGET_OS_LIBRARIES(libgit2_clar)
|
||||
MSVC_SPLIT_SOURCES(libgit2_clar)
|
||||
|
@ -22,17 +22,25 @@ Also, feel free to open an
|
||||
about any concerns you have. We like to use Issues for that so there is an
|
||||
easily accessible permanent record of the conversation.
|
||||
|
||||
## Libgit2 Versions
|
||||
|
||||
The `master` branch is the main branch where development happens.
|
||||
Releases are tagged
|
||||
(e.g. [v0.21.0](https://github.com/libgit2/libgit2/releases/tag/v0.21.0) )
|
||||
and when a critical bug fix needs to be backported, it will be done on a
|
||||
`<tag>-maint` maintenance branch.
|
||||
|
||||
## 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.
|
||||
[v0.17.0](https://github.com/libgit2/libgit2/releases/tag/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.
|
||||
). 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,
|
||||
If you're not running against the latest `master` branch version,
|
||||
please compile and test against that to avoid re-reporting an issue that's
|
||||
already been fixed.
|
||||
|
||||
@ -44,25 +52,33 @@ 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").
|
||||
Our work flow is a [typical GitHub flow](https://guides.github.com/introduction/flow/index.html),
|
||||
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").
|
||||
Pull requests should usually be targeted at the `master` branch.
|
||||
|
||||
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.
|
||||
(i.e. fork, named branch, submit PR). If you use your fork's `master`
|
||||
branch directly, 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.
|
||||
Please include a nice description of your changes when you submit 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.
|
||||
|
||||
If you are working on a particular area then feel free to submit a PR that
|
||||
highlights your work in progress (and flag in the PR title that it's not
|
||||
ready to merge). This will help in getting visibility for your fix, allow
|
||||
others to comment early on the changes and also let others know that you
|
||||
are currently working on something.
|
||||
If you are starting to work on a particular area, feel free to submit a PR
|
||||
that highlights your work in progress (and note in the PR title that it's
|
||||
not ready to merge). These early PRs are welcome and will help in getting
|
||||
visibility for your fix, allow others to comment early on the changes and
|
||||
also let others know that you are currently working on something.
|
||||
|
||||
Before wrapping up a PR, you should be sure to:
|
||||
|
||||
* Write tests to cover any functional changes (ideally tests that would
|
||||
have failed before the PR and now pass)
|
||||
* Update documentation for any changed public APIs
|
||||
* Add to the [`CHANGELOG.md`](CHANGELOG.md) file describing any major changes
|
||||
|
||||
## Porting Code From Other Open-Source Projects
|
||||
|
||||
@ -80,10 +96,10 @@ 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.
|
||||
|
||||
If you are pulling in code from core Git, another project or code you've
|
||||
pulled from a forum / Stack Overflow then please flag this in your PR and
|
||||
also make sure you've given proper credit to the original author in the
|
||||
code snippet.
|
||||
If your pull request uses code from core Git, another project, or code
|
||||
from a forum / Stack Overflow, then *please* flag this in your PR and make
|
||||
sure you've given proper credit to the original author in the code
|
||||
snippet.
|
||||
|
||||
## Style Guide
|
||||
|
||||
|
53
PROJECTS.md
53
PROJECTS.md
@ -10,10 +10,11 @@ ideas that no one is actively working on.
|
||||
|
||||
## Before You Start
|
||||
|
||||
Please start by reading the README.md, CONTRIBUTING.md, and CONVENTIONS.md
|
||||
files before diving into one of these projects. Those will explain our
|
||||
work flow and coding conventions to help ensure that your work will be
|
||||
easily integrated into libgit2.
|
||||
Please start by reading the [README.md](README.md),
|
||||
[CONTRIBUTING.md](CONTRIBUTING.md), and [CONVENTIONS.md](CONVENTIONS.md)
|
||||
files before diving into one of these projects. Those explain our work
|
||||
flow and coding conventions to help ensure that your work will be easily
|
||||
integrated into libgit2.
|
||||
|
||||
Next, work through the build instructions and make sure you can clone the
|
||||
repository, compile it, and run the tests successfully. That will make
|
||||
@ -27,7 +28,7 @@ These are good small projects to get started with libgit2.
|
||||
* Look at the `examples/` programs, find an existing one that mirrors a
|
||||
core Git command and add a missing command-line option. There are many
|
||||
gaps right now and this helps demonstrate how to use the library. Here
|
||||
are some specific ideas:
|
||||
are some specific ideas (though there are many more):
|
||||
* Fix the `examples/diff.c` implementation of the `-B`
|
||||
(a.k.a. `--break-rewrites`) command line option to actually look for
|
||||
the optional `[<n>][/<m>]` configuration values. There is an
|
||||
@ -39,12 +40,6 @@ These are good small projects to get started with libgit2.
|
||||
the data is available, you would just need to add the code into the
|
||||
`print_commit()` routine (along with a way of passing the option
|
||||
into that function).
|
||||
* For `examples/log.c`, implement any one of `--author=<...>`,
|
||||
`--committer=<...>`, or `--grep=<...>` but just use simple string
|
||||
match with `strstr()` instead of full regular expression
|
||||
matching. (I.e. I'm suggesting implementing this as if
|
||||
`--fixed-strings` was always turned on, because it will be a simpler
|
||||
project.)
|
||||
* As an extension to the matching idea for `examples/log.c`, add the
|
||||
`-i` option to use `strcasestr()` for matches.
|
||||
* For `examples/log.c`, implement the `--first-parent` option now that
|
||||
@ -58,9 +53,6 @@ These are good small projects to get started with libgit2.
|
||||
* 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.
|
||||
* Add support for the symref protocol extension, so we don't guess
|
||||
what the remote's default branch is
|
||||
[#2006](https://github.com/libgit2/libgit2/issues/2006)
|
||||
|
||||
If none of these appeal to you, take a look at our issues list to see if
|
||||
there are any unresolved issues you'd like to jump in on.
|
||||
@ -73,19 +65,44 @@ into one of these as a first project for libgit2 - we'd rather get to
|
||||
know you first by successfully shipping your work on one of the smaller
|
||||
projects above.
|
||||
|
||||
Some of these projects are broken down into subprojects and/or have
|
||||
some incremental steps listed towards the larger goal. Those steps
|
||||
might make good smaller projects by themselves.
|
||||
|
||||
* Port part of the Git test suite to run against the command line emulation
|
||||
in examples/
|
||||
* Pick a Git command that is emulated in our examples/ area
|
||||
* Extract the Git tests that exercise that command
|
||||
* Convert the tests to call our emulation
|
||||
* These tests could go in examples/tests/...
|
||||
* Fix symlink support for files in the .git directory (i.e. don't overwrite
|
||||
the symlinks when writing the file contents back out)
|
||||
* Implement a 'git describe' like API
|
||||
* Add hooks API to enumerate and manage hooks (not run them at this point)
|
||||
* Enumeration of available hooks
|
||||
* Lookup API to see which hooks have a script and get the script
|
||||
* Read/write API to load a hook script and write a hook script
|
||||
* Eventually, callback API to invoke a hook callback when libgit2
|
||||
executes the action in question
|
||||
* Isolate logic of ignore evaluation into a standalone API
|
||||
* Upgrade internal libxdiff code to latest from core Git
|
||||
* Add a hashtable lookup for files in the index instead of binary search
|
||||
every time
|
||||
* Improve index internals with hashtable lookup for files instead of
|
||||
using binary search every time
|
||||
* Make the index write the cache out to disk (with tests to gain
|
||||
confidence that the caching invalidation works correctly)
|
||||
* Have the tree builder use a hash table when building instead of a
|
||||
list.
|
||||
* Tree builder improvements:
|
||||
* Use a hash table when building instead of a list
|
||||
* Extend to allow building a tree hierarchy
|
||||
* Move the tagopt mechanism to the newer git 1.9 interpretation of
|
||||
--tags [#2120](https://github.com/libgit2/libgit2/issues/2120)
|
||||
* Apply-patch API
|
||||
* Add a patch editing API to enable "git add -p" type operations
|
||||
* Textconv API to filter binary data before generating diffs (something
|
||||
like the current Filter API, probably).
|
||||
* Performance profiling and improvement
|
||||
* Build in handling of "empty tree" and "empty blob" SHAs
|
||||
* Support "git replace" ref replacements
|
||||
* Include conflicts in diff results and in status
|
||||
* GIT_DELTA_CONFLICT for items in conflict (with multiple files)
|
||||
* Appropriate flags for status
|
||||
* Support sparse checkout (i.e. "core.sparsecheckout" and ".git/info/sparse-checkout")
|
||||
|
13
README.md
13
README.md
@ -55,7 +55,7 @@ dependencies, it can make use of a few libraries to add to it:
|
||||
|
||||
- pthreads (non-Windows) to enable threadsafe access as well as multi-threaded pack generation
|
||||
- OpenSSL (non-Windows) to talk over HTTPS and provide the SHA-1 functions
|
||||
- LibSSH2 to enable the ssh transport
|
||||
- LibSSH2 to enable the SSH transport
|
||||
- iconv (OSX) to handle the HFS+ path encoding peculiarities
|
||||
|
||||
Building libgit2 - Using CMake
|
||||
@ -119,8 +119,7 @@ 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)
|
||||
See [the website](https://libgit2.github.com/docs/guides/build-and-link)
|
||||
for more detailed instructions.
|
||||
|
||||
Android
|
||||
@ -168,6 +167,8 @@ Here are the bindings to libgit2 that are currently available:
|
||||
* hgit2 <https://github.com/fpco/gitlib>
|
||||
* Java
|
||||
* Jagged <https://github.com/ethomson/jagged>
|
||||
* Julia
|
||||
* LibGit2.jl <https://github.com/jakebolewski/LibGit2.jl>
|
||||
* Lua
|
||||
* luagit2 <https://github.com/libgit2/luagit2>
|
||||
* .NET
|
||||
@ -182,15 +183,19 @@ Here are the bindings to libgit2 that are currently available:
|
||||
* Parrot Virtual Machine
|
||||
* parrot-libgit2 <https://github.com/letolabs/parrot-libgit2>
|
||||
* Perl
|
||||
* Git-Raw <https://github.com/ghedo/p5-Git-Raw>
|
||||
* Git-Raw <https://github.com/jacquesg/p5-Git-Raw>
|
||||
* PHP
|
||||
* php-git <https://github.com/libgit2/php-git>
|
||||
* PowerShell
|
||||
* GitPowerShell <https://github.com/ethomson/gitpowershell>
|
||||
* Python
|
||||
* pygit2 <https://github.com/libgit2/pygit2>
|
||||
* R
|
||||
* git2r <https://github.com/ropensci/git2r>
|
||||
* Ruby
|
||||
* Rugged <https://github.com/libgit2/rugged>
|
||||
* Rust
|
||||
* git2-rs <https://github.com/alexcrichton/git2-rs>
|
||||
* Vala
|
||||
* libgit2.vapi <https://github.com/apmasell/vapis/blob/master/libgit2.vapi>
|
||||
|
||||
|
324
cmake/Modules/FindGSSAPI.cmake
Normal file
324
cmake/Modules/FindGSSAPI.cmake
Normal file
@ -0,0 +1,324 @@
|
||||
# - Try to find GSSAPI
|
||||
# Once done this will define
|
||||
#
|
||||
# KRB5_CONFIG - Path to krb5-config
|
||||
# GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI
|
||||
#
|
||||
# Read-Only variables:
|
||||
# GSSAPI_FLAVOR_MIT - set to TURE if MIT Kerberos has been found
|
||||
# GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Keberos has been found
|
||||
# GSSAPI_FOUND - system has GSSAPI
|
||||
# GSSAPI_INCLUDE_DIR - the GSSAPI include directory
|
||||
# GSSAPI_LIBRARIES - Link these to use GSSAPI
|
||||
# GSSAPI_DEFINITIONS - Compiler switches required for using GSSAPI
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
find_path(GSSAPI_ROOT_DIR
|
||||
NAMES
|
||||
include/gssapi.h
|
||||
include/gssapi/gssapi.h
|
||||
HINTS
|
||||
${_GSSAPI_ROOT_HINTS}
|
||||
PATHS
|
||||
${_GSSAPI_ROOT_PATHS}
|
||||
)
|
||||
mark_as_advanced(GSSAPI_ROOT_DIR)
|
||||
|
||||
if (UNIX)
|
||||
find_program(KRB5_CONFIG
|
||||
NAMES
|
||||
krb5-config
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/bin
|
||||
/opt/local/bin)
|
||||
mark_as_advanced(KRB5_CONFIG)
|
||||
|
||||
if (KRB5_CONFIG)
|
||||
# Check if we have MIT KRB5
|
||||
execute_process(
|
||||
COMMAND
|
||||
${KRB5_CONFIG} --vendor
|
||||
RESULT_VARIABLE
|
||||
_GSSAPI_VENDOR_RESULT
|
||||
OUTPUT_VARIABLE
|
||||
_GSSAPI_VENDOR_STRING)
|
||||
|
||||
if (_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*")
|
||||
set(GSSAPI_FLAVOR_MIT TRUE)
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND
|
||||
${KRB5_CONFIG} --libs gssapi
|
||||
RESULT_VARIABLE
|
||||
_GSSAPI_LIBS_RESULT
|
||||
OUTPUT_VARIABLE
|
||||
_GSSAPI_LIBS_STRING)
|
||||
|
||||
if (_GSSAPI_LIBS_STRING MATCHES ".*roken.*")
|
||||
set(GSSAPI_FLAVOR_HEIMDAL TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Get the include dir
|
||||
execute_process(
|
||||
COMMAND
|
||||
${KRB5_CONFIG} --cflags gssapi
|
||||
RESULT_VARIABLE
|
||||
_GSSAPI_INCLUDE_RESULT
|
||||
OUTPUT_VARIABLE
|
||||
_GSSAPI_INCLUDE_STRING)
|
||||
string(REGEX REPLACE "(\r?\n)+$" "" _GSSAPI_INCLUDE_STRING "${_GSSAPI_INCLUDE_STRING}")
|
||||
string(REGEX REPLACE " *-I" "" _GSSAPI_INCLUDEDIR "${_GSSAPI_INCLUDE_STRING}")
|
||||
endif()
|
||||
|
||||
if (NOT GSSAPI_FLAVOR_MIT AND NOT GSSAPI_FLAVOR_HEIMDAL)
|
||||
# Check for HEIMDAL
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_GSSAPI heimdal-gssapi)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
|
||||
if (_GSSAPI_FOUND)
|
||||
set(GSSAPI_FLAVOR_HEIMDAL TRUE)
|
||||
else()
|
||||
find_path(_GSSAPI_ROKEN
|
||||
NAMES
|
||||
roken.h
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/include
|
||||
${_GSSAPI_INCLUDEDIR})
|
||||
if (_GSSAPI_ROKEN)
|
||||
set(GSSAPI_FLAVOR_HEIMDAL TRUE)
|
||||
endif()
|
||||
endif ()
|
||||
endif()
|
||||
endif (UNIX)
|
||||
|
||||
find_path(GSSAPI_INCLUDE_DIR
|
||||
NAMES
|
||||
gssapi.h
|
||||
gssapi/gssapi.h
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/include
|
||||
${_GSSAPI_INCLUDEDIR}
|
||||
)
|
||||
|
||||
if (GSSAPI_FLAVOR_MIT)
|
||||
find_library(GSSAPI_LIBRARY
|
||||
NAMES
|
||||
gssapi_krb5
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(KRB5_LIBRARY
|
||||
NAMES
|
||||
krb5
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(K5CRYPTO_LIBRARY
|
||||
NAMES
|
||||
k5crypto
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(COM_ERR_LIBRARY
|
||||
NAMES
|
||||
com_err
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
if (GSSAPI_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${GSSAPI_LIBRARY}
|
||||
)
|
||||
endif (GSSAPI_LIBRARY)
|
||||
|
||||
if (KRB5_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${KRB5_LIBRARY}
|
||||
)
|
||||
endif (KRB5_LIBRARY)
|
||||
|
||||
if (K5CRYPTO_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${K5CRYPTO_LIBRARY}
|
||||
)
|
||||
endif (K5CRYPTO_LIBRARY)
|
||||
|
||||
if (COM_ERR_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${COM_ERR_LIBRARY}
|
||||
)
|
||||
endif (COM_ERR_LIBRARY)
|
||||
endif (GSSAPI_FLAVOR_MIT)
|
||||
|
||||
if (GSSAPI_FLAVOR_HEIMDAL)
|
||||
find_library(GSSAPI_LIBRARY
|
||||
NAMES
|
||||
gssapi
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(KRB5_LIBRARY
|
||||
NAMES
|
||||
krb5
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(HCRYPTO_LIBRARY
|
||||
NAMES
|
||||
hcrypto
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(COM_ERR_LIBRARY
|
||||
NAMES
|
||||
com_err
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(HEIMNTLM_LIBRARY
|
||||
NAMES
|
||||
heimntlm
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(HX509_LIBRARY
|
||||
NAMES
|
||||
hx509
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(ASN1_LIBRARY
|
||||
NAMES
|
||||
asn1
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(WIND_LIBRARY
|
||||
NAMES
|
||||
wind
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
find_library(ROKEN_LIBRARY
|
||||
NAMES
|
||||
roken
|
||||
PATHS
|
||||
${GSSAPI_ROOT_DIR}/lib
|
||||
${_GSSAPI_LIBDIR}
|
||||
)
|
||||
|
||||
if (GSSAPI_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${GSSAPI_LIBRARY}
|
||||
)
|
||||
endif (GSSAPI_LIBRARY)
|
||||
|
||||
if (KRB5_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${KRB5_LIBRARY}
|
||||
)
|
||||
endif (KRB5_LIBRARY)
|
||||
|
||||
if (HCRYPTO_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${HCRYPTO_LIBRARY}
|
||||
)
|
||||
endif (HCRYPTO_LIBRARY)
|
||||
|
||||
if (COM_ERR_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${COM_ERR_LIBRARY}
|
||||
)
|
||||
endif (COM_ERR_LIBRARY)
|
||||
|
||||
if (HEIMNTLM_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${HEIMNTLM_LIBRARY}
|
||||
)
|
||||
endif (HEIMNTLM_LIBRARY)
|
||||
|
||||
if (HX509_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${HX509_LIBRARY}
|
||||
)
|
||||
endif (HX509_LIBRARY)
|
||||
|
||||
if (ASN1_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${ASN1_LIBRARY}
|
||||
)
|
||||
endif (ASN1_LIBRARY)
|
||||
|
||||
if (WIND_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${WIND_LIBRARY}
|
||||
)
|
||||
endif (WIND_LIBRARY)
|
||||
|
||||
if (ROKEN_LIBRARY)
|
||||
set(GSSAPI_LIBRARIES
|
||||
${GSSAPI_LIBRARIES}
|
||||
${WIND_LIBRARY}
|
||||
)
|
||||
endif (ROKEN_LIBRARY)
|
||||
endif (GSSAPI_FLAVOR_HEIMDAL)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(GSSAPI DEFAULT_MSG GSSAPI_LIBRARIES GSSAPI_INCLUDE_DIR)
|
||||
|
||||
if (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES)
|
||||
set(GSSAPI_FOUND TRUE)
|
||||
endif (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES)
|
||||
|
||||
# show the GSSAPI_INCLUDE_DIRS and GSSAPI_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(GSSAPI_INCLUDE_DIRS GSSAPI_LIBRARIES)
|
2
deps/http-parser/http_parser.h
vendored
2
deps/http-parser/http_parser.h
vendored
@ -40,6 +40,8 @@ typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef SIZE_T size_t;
|
||||
typedef SSIZE_T ssize_t;
|
||||
#elif defined(__sun) || defined(__sun__)
|
||||
#include <sys/inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
68
deps/zlib/adler32.c
vendored
68
deps/zlib/adler32.c
vendored
@ -1,5 +1,5 @@
|
||||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2007 Mark Adler
|
||||
* Copyright (C) 1995-2011 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
|
||||
#define local static
|
||||
|
||||
local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
|
||||
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
|
||||
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
#define BASE 65521 /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||
try it both ways to see which is faster */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||
(thank you to John Reiser for pointing this out) */
|
||||
# define CHOP(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
unsigned long tmp = a >> 16; \
|
||||
a &= 0xffffUL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
} while (0)
|
||||
# define MOD28(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD4(a) \
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
CHOP(a); \
|
||||
MOD28(a); \
|
||||
} while (0)
|
||||
# define MOD63(a) \
|
||||
do { /* this assumes a is not negative */ \
|
||||
z_off64_t tmp = a >> 32; \
|
||||
a &= 0xffffffffL; \
|
||||
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD4(a) a %= BASE
|
||||
# define MOD28(a) a %= BASE
|
||||
# define MOD63(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
MOD28(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2)
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||
if (len2 < 0)
|
||||
return 0xffffffffUL;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
rem = (unsigned)(len2 % BASE);
|
||||
MOD63(len2); /* assumes len2 >= 0 */
|
||||
rem = (unsigned)len2;
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
|
83
deps/zlib/crc32.c
vendored
83
deps/zlib/crc32.c
vendored
@ -1,5 +1,5 @@
|
||||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-2006, 2010 Mark Adler
|
||||
* Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*
|
||||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||
@ -17,6 +17,8 @@
|
||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
||||
first call get_crc_table() to initialize the tables before allowing more than
|
||||
one thread to use crc32().
|
||||
|
||||
DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
|
||||
*/
|
||||
|
||||
#ifdef MAKECRCH
|
||||
@ -30,31 +32,11 @@
|
||||
|
||||
#define local static
|
||||
|
||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
||||
#ifndef NOBYFOUR
|
||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
||||
# include <limits.h>
|
||||
# define BYFOUR
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int u4;
|
||||
# else
|
||||
# if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long u4;
|
||||
# else
|
||||
# if (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short u4;
|
||||
# else
|
||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif /* STDC */
|
||||
#endif /* !NOBYFOUR */
|
||||
|
||||
/* Definitions for doing the crc four data bytes at a time. */
|
||||
#if !defined(NOBYFOUR) && defined(Z_U4)
|
||||
# define BYFOUR
|
||||
#endif
|
||||
#ifdef BYFOUR
|
||||
# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
|
||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
||||
local unsigned long crc32_little OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
local unsigned long crc32_big OF((unsigned long,
|
||||
@ -68,16 +50,16 @@
|
||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||
unsigned long vec));
|
||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||
local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
|
||||
local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
|
||||
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
|
||||
local volatile int crc_table_empty = 1;
|
||||
local unsigned long FAR crc_table[TBLS][256];
|
||||
local z_crc_t FAR crc_table[TBLS][256];
|
||||
local void make_crc_table OF((void));
|
||||
#ifdef MAKECRCH
|
||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
||||
local void write_table OF((FILE *, const z_crc_t FAR *));
|
||||
#endif /* MAKECRCH */
|
||||
/*
|
||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
@ -107,9 +89,9 @@ local void make_crc_table OF((void));
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
unsigned long c;
|
||||
z_crc_t c;
|
||||
int n, k;
|
||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
||||
z_crc_t poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static volatile int first = 1; /* flag to limit concurrent making */
|
||||
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
@ -121,13 +103,13 @@ local void make_crc_table()
|
||||
first = 0;
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||
poly = 0UL;
|
||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
||||
poly |= 1UL << (31 - p[n]);
|
||||
poly = 0;
|
||||
for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
|
||||
poly |= (z_crc_t)1 << (31 - p[n]);
|
||||
|
||||
/* generate a crc for every 8-bit value */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long)n;
|
||||
c = (z_crc_t)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[0][n] = c;
|
||||
@ -138,11 +120,11 @@ local void make_crc_table()
|
||||
and then the byte reversal of those as well as the first table */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = crc_table[0][n];
|
||||
crc_table[4][n] = REV(c);
|
||||
crc_table[4][n] = ZSWAP32(c);
|
||||
for (k = 1; k < 4; k++) {
|
||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||
crc_table[k][n] = c;
|
||||
crc_table[k + 4][n] = REV(c);
|
||||
crc_table[k + 4][n] = ZSWAP32(c);
|
||||
}
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
@ -164,7 +146,7 @@ local void make_crc_table()
|
||||
if (out == NULL) return;
|
||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||
fprintf(out, "local const unsigned long FAR ");
|
||||
fprintf(out, "local const z_crc_t FAR ");
|
||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||
write_table(out, crc_table[0]);
|
||||
# ifdef BYFOUR
|
||||
@ -184,12 +166,13 @@ local void make_crc_table()
|
||||
#ifdef MAKECRCH
|
||||
local void write_table(out, table)
|
||||
FILE *out;
|
||||
const unsigned long FAR *table;
|
||||
const z_crc_t FAR *table;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
|
||||
(unsigned long)(table[n]),
|
||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
@ -204,13 +187,13 @@ local void write_table(out, table)
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
const z_crc_t FAR * ZEXPORT get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
return (const unsigned long FAR *)crc_table;
|
||||
return (const z_crc_t FAR *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -232,7 +215,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
|
||||
#ifdef BYFOUR
|
||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||
u4 endian;
|
||||
z_crc_t endian;
|
||||
|
||||
endian = 1;
|
||||
if (*((unsigned char *)(&endian)))
|
||||
@ -266,17 +249,17 @@ local unsigned long crc32_little(crc, buf, len)
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
register z_crc_t c;
|
||||
register const z_crc_t FAR *buf4;
|
||||
|
||||
c = (u4)crc;
|
||||
c = (z_crc_t)crc;
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOLIT32;
|
||||
len -= 32;
|
||||
@ -306,17 +289,17 @@ local unsigned long crc32_big(crc, buf, len)
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
register z_crc_t c;
|
||||
register const z_crc_t FAR *buf4;
|
||||
|
||||
c = REV((u4)crc);
|
||||
c = ZSWAP32((z_crc_t)crc);
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||
buf4--;
|
||||
while (len >= 32) {
|
||||
DOBIG32;
|
||||
@ -333,7 +316,7 @@ local unsigned long crc32_big(crc, buf, len)
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)(REV(c));
|
||||
return (unsigned long)(ZSWAP32(c));
|
||||
}
|
||||
|
||||
#endif /* BYFOUR */
|
||||
|
2
deps/zlib/crc32.h
vendored
2
deps/zlib/crc32.h
vendored
@ -2,7 +2,7 @@
|
||||
* Generated automatically by crc32.c
|
||||
*/
|
||||
|
||||
local const unsigned long FAR crc_table[TBLS][256] =
|
||||
local const z_crc_t FAR crc_table[TBLS][256] =
|
||||
{
|
||||
{
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
|
261
deps/zlib/deflate.c
vendored
261
deps/zlib/deflate.c
vendored
@ -1,5 +1,5 @@
|
||||
/* deflate.c -- compress data using the deflation algorithm
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
* REFERENCES
|
||||
*
|
||||
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
||||
* Available in http://www.ietf.org/rfc/rfc1951.txt
|
||||
* Available in http://tools.ietf.org/html/rfc1951
|
||||
*
|
||||
* A description of the Rabin and Karp algorithm is given in the book
|
||||
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
||||
@ -52,7 +52,7 @@
|
||||
#include "deflate.h"
|
||||
|
||||
const char deflate_copyright[] =
|
||||
" deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
|
||||
" deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@ -155,6 +155,9 @@ local const config configuration_table[10] = {
|
||||
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
|
||||
#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
|
||||
|
||||
/* ===========================================================================
|
||||
* Update a hash value with the given input byte
|
||||
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
||||
@ -235,10 +238,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
|
||||
strm->msg = Z_NULL;
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
#endif
|
||||
}
|
||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
||||
if (strm->zfree == (free_func)0)
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zfree = zcfree;
|
||||
#endif
|
||||
|
||||
#ifdef FASTEST
|
||||
if (level != 0) level = 1;
|
||||
@ -293,7 +305,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||
s->pending_buf == Z_NULL) {
|
||||
s->status = FINISH_STATE;
|
||||
strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
|
||||
strm->msg = ERR_MSG(Z_MEM_ERROR);
|
||||
deflateEnd (strm);
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
@ -314,43 +326,70 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
||||
uInt dictLength;
|
||||
{
|
||||
deflate_state *s;
|
||||
uInt length = dictLength;
|
||||
uInt n;
|
||||
IPos hash_head = 0;
|
||||
uInt str, n;
|
||||
int wrap;
|
||||
unsigned avail;
|
||||
z_const unsigned char *next;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
||||
strm->state->wrap == 2 ||
|
||||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
s = strm->state;
|
||||
wrap = s->wrap;
|
||||
if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
s = strm->state;
|
||||
if (s->wrap)
|
||||
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
|
||||
if (wrap == 1)
|
||||
strm->adler = adler32(strm->adler, dictionary, dictLength);
|
||||
s->wrap = 0; /* avoid computing Adler-32 in read_buf */
|
||||
|
||||
if (length < MIN_MATCH) return Z_OK;
|
||||
if (length > s->w_size) {
|
||||
length = s->w_size;
|
||||
dictionary += dictLength - length; /* use the tail of the dictionary */
|
||||
/* if dictionary would fill window, just replace the history */
|
||||
if (dictLength >= s->w_size) {
|
||||
if (wrap == 0) { /* already empty otherwise */
|
||||
CLEAR_HASH(s);
|
||||
s->strstart = 0;
|
||||
s->block_start = 0L;
|
||||
s->insert = 0;
|
||||
}
|
||||
dictionary += dictLength - s->w_size; /* use the tail */
|
||||
dictLength = s->w_size;
|
||||
}
|
||||
zmemcpy(s->window, dictionary, length);
|
||||
s->strstart = length;
|
||||
s->block_start = (long)length;
|
||||
|
||||
/* Insert all strings in the hash table (except for the last two bytes).
|
||||
* s->lookahead stays null, so s->ins_h will be recomputed at the next
|
||||
* call of fill_window.
|
||||
*/
|
||||
s->ins_h = s->window[0];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[1]);
|
||||
for (n = 0; n <= length - MIN_MATCH; n++) {
|
||||
INSERT_STRING(s, n, hash_head);
|
||||
/* insert dictionary into window and hash */
|
||||
avail = strm->avail_in;
|
||||
next = strm->next_in;
|
||||
strm->avail_in = dictLength;
|
||||
strm->next_in = (z_const Bytef *)dictionary;
|
||||
fill_window(s);
|
||||
while (s->lookahead >= MIN_MATCH) {
|
||||
str = s->strstart;
|
||||
n = s->lookahead - (MIN_MATCH-1);
|
||||
do {
|
||||
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
||||
#ifndef FASTEST
|
||||
s->prev[str & s->w_mask] = s->head[s->ins_h];
|
||||
#endif
|
||||
s->head[s->ins_h] = (Pos)str;
|
||||
str++;
|
||||
} while (--n);
|
||||
s->strstart = str;
|
||||
s->lookahead = MIN_MATCH-1;
|
||||
fill_window(s);
|
||||
}
|
||||
if (hash_head) hash_head = 0; /* to make compiler happy */
|
||||
s->strstart += s->lookahead;
|
||||
s->block_start = (long)s->strstart;
|
||||
s->insert = s->lookahead;
|
||||
s->lookahead = 0;
|
||||
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||
s->match_available = 0;
|
||||
strm->next_in = next;
|
||||
strm->avail_in = avail;
|
||||
s->wrap = wrap;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateReset (strm)
|
||||
int ZEXPORT deflateResetKeep (strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
deflate_state *s;
|
||||
@ -380,11 +419,22 @@ int ZEXPORT deflateReset (strm)
|
||||
s->last_flush = Z_NO_FLUSH;
|
||||
|
||||
_tr_init(s);
|
||||
lm_init(s);
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateReset (strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = deflateResetKeep(strm);
|
||||
if (ret == Z_OK)
|
||||
lm_init(strm->state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateSetHeader (strm, head)
|
||||
z_streamp strm;
|
||||
@ -396,15 +446,43 @@ int ZEXPORT deflateSetHeader (strm, head)
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflatePending (strm, pending, bits)
|
||||
unsigned *pending;
|
||||
int *bits;
|
||||
z_streamp strm;
|
||||
{
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (pending != Z_NULL)
|
||||
*pending = strm->state->pending;
|
||||
if (bits != Z_NULL)
|
||||
*bits = strm->state->bi_valid;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflatePrime (strm, bits, value)
|
||||
z_streamp strm;
|
||||
int bits;
|
||||
int value;
|
||||
{
|
||||
deflate_state *s;
|
||||
int put;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
strm->state->bi_valid = bits;
|
||||
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
|
||||
s = strm->state;
|
||||
if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
return Z_BUF_ERROR;
|
||||
do {
|
||||
put = Buf_size - s->bi_valid;
|
||||
if (put > bits)
|
||||
put = bits;
|
||||
s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
|
||||
s->bi_valid += put;
|
||||
_tr_flush_bits(s);
|
||||
value >>= put;
|
||||
bits -= put;
|
||||
} while (bits);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
@ -435,6 +513,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
|
||||
strm->total_in != 0) {
|
||||
/* Flush the last buffer: */
|
||||
err = deflate(strm, Z_BLOCK);
|
||||
if (err == Z_BUF_ERROR && s->pending == 0)
|
||||
err = Z_OK;
|
||||
}
|
||||
if (s->level != level) {
|
||||
s->level = level;
|
||||
@ -562,19 +642,22 @@ local void putShortMSB (s, b)
|
||||
local void flush_pending(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
unsigned len = strm->state->pending;
|
||||
unsigned len;
|
||||
deflate_state *s = strm->state;
|
||||
|
||||
_tr_flush_bits(s);
|
||||
len = s->pending;
|
||||
if (len > strm->avail_out) len = strm->avail_out;
|
||||
if (len == 0) return;
|
||||
|
||||
zmemcpy(strm->next_out, strm->state->pending_out, len);
|
||||
zmemcpy(strm->next_out, s->pending_out, len);
|
||||
strm->next_out += len;
|
||||
strm->state->pending_out += len;
|
||||
s->pending_out += len;
|
||||
strm->total_out += len;
|
||||
strm->avail_out -= len;
|
||||
strm->state->pending -= len;
|
||||
if (strm->state->pending == 0) {
|
||||
strm->state->pending_out = strm->state->pending_buf;
|
||||
s->pending -= len;
|
||||
if (s->pending == 0) {
|
||||
s->pending_out = s->pending_buf;
|
||||
}
|
||||
}
|
||||
|
||||
@ -801,7 +884,7 @@ int ZEXPORT deflate (strm, flush)
|
||||
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
||||
* returning Z_STREAM_END instead of Z_BUF_ERROR.
|
||||
*/
|
||||
} else if (strm->avail_in == 0 && flush <= old_flush &&
|
||||
} else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
|
||||
flush != Z_FINISH) {
|
||||
ERR_RETURN(strm, Z_BUF_ERROR);
|
||||
}
|
||||
@ -850,6 +933,7 @@ int ZEXPORT deflate (strm, flush)
|
||||
if (s->lookahead == 0) {
|
||||
s->strstart = 0;
|
||||
s->block_start = 0L;
|
||||
s->insert = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -945,12 +1029,12 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
|
||||
ss = source->state;
|
||||
|
||||
zmemcpy(dest, source, sizeof(z_stream));
|
||||
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||
|
||||
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
||||
if (ds == Z_NULL) return Z_MEM_ERROR;
|
||||
dest->state = (struct internal_state FAR *) ds;
|
||||
zmemcpy(ds, ss, sizeof(deflate_state));
|
||||
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
|
||||
ds->strm = dest;
|
||||
|
||||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||
@ -966,8 +1050,8 @@ int ZEXPORT deflateCopy (dest, source)
|
||||
}
|
||||
/* following zmemcpy do not work for 16-bit MSDOS */
|
||||
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
||||
zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
|
||||
zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
||||
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
|
||||
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
|
||||
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
||||
|
||||
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||||
@ -1001,15 +1085,15 @@ local int read_buf(strm, buf, size)
|
||||
|
||||
strm->avail_in -= len;
|
||||
|
||||
zmemcpy(buf, strm->next_in, len);
|
||||
if (strm->state->wrap == 1) {
|
||||
strm->adler = adler32(strm->adler, strm->next_in, len);
|
||||
strm->adler = adler32(strm->adler, buf, len);
|
||||
}
|
||||
#ifdef GZIP
|
||||
else if (strm->state->wrap == 2) {
|
||||
strm->adler = crc32(strm->adler, strm->next_in, len);
|
||||
strm->adler = crc32(strm->adler, buf, len);
|
||||
}
|
||||
#endif
|
||||
zmemcpy(buf, strm->next_in, len);
|
||||
strm->next_in += len;
|
||||
strm->total_in += len;
|
||||
|
||||
@ -1036,6 +1120,7 @@ local void lm_init (s)
|
||||
s->strstart = 0;
|
||||
s->block_start = 0L;
|
||||
s->lookahead = 0;
|
||||
s->insert = 0;
|
||||
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||
s->match_available = 0;
|
||||
s->ins_h = 0;
|
||||
@ -1310,6 +1395,8 @@ local void fill_window(s)
|
||||
unsigned more; /* Amount of free space at the end of the window. */
|
||||
uInt wsize = s->w_size;
|
||||
|
||||
Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
|
||||
|
||||
do {
|
||||
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
||||
|
||||
@ -1362,7 +1449,7 @@ local void fill_window(s)
|
||||
#endif
|
||||
more += wsize;
|
||||
}
|
||||
if (s->strm->avail_in == 0) return;
|
||||
if (s->strm->avail_in == 0) break;
|
||||
|
||||
/* If there was no sliding:
|
||||
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
||||
@ -1381,12 +1468,24 @@ local void fill_window(s)
|
||||
s->lookahead += n;
|
||||
|
||||
/* Initialize the hash value now that we have some input: */
|
||||
if (s->lookahead >= MIN_MATCH) {
|
||||
s->ins_h = s->window[s->strstart];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
||||
if (s->lookahead + s->insert >= MIN_MATCH) {
|
||||
uInt str = s->strstart - s->insert;
|
||||
s->ins_h = s->window[str];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
|
||||
#if MIN_MATCH != 3
|
||||
Call UPDATE_HASH() MIN_MATCH-3 more times
|
||||
#endif
|
||||
while (s->insert) {
|
||||
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
||||
#ifndef FASTEST
|
||||
s->prev[str & s->w_mask] = s->head[s->ins_h];
|
||||
#endif
|
||||
s->head[s->ins_h] = (Pos)str;
|
||||
str++;
|
||||
s->insert--;
|
||||
if (s->lookahead + s->insert < MIN_MATCH)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
||||
* but this is not important since only literal bytes will be emitted.
|
||||
@ -1427,6 +1526,9 @@ local void fill_window(s)
|
||||
s->high_water += init;
|
||||
}
|
||||
}
|
||||
|
||||
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||
"not enough room for search");
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -1506,8 +1608,14 @@ local block_state deflate_stored(s, flush)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
s->insert = 0;
|
||||
if (flush == Z_FINISH) {
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if ((long)s->strstart > s->block_start)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -1603,8 +1711,14 @@ local block_state deflate_fast(s, flush)
|
||||
}
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||
if (flush == Z_FINISH) {
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
||||
#ifndef FASTEST
|
||||
@ -1728,8 +1842,14 @@ local block_state deflate_slow(s, flush)
|
||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||
s->match_available = 0;
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||
if (flush == Z_FINISH) {
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
#endif /* FASTEST */
|
||||
|
||||
@ -1749,11 +1869,11 @@ local block_state deflate_rle(s, flush)
|
||||
for (;;) {
|
||||
/* Make sure that we always have enough lookahead, except
|
||||
* at the end of the input file. We need MAX_MATCH bytes
|
||||
* for the longest encodable run.
|
||||
* for the longest run, plus one for the unrolled loop.
|
||||
*/
|
||||
if (s->lookahead < MAX_MATCH) {
|
||||
if (s->lookahead <= MAX_MATCH) {
|
||||
fill_window(s);
|
||||
if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
|
||||
if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
|
||||
return need_more;
|
||||
}
|
||||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
@ -1776,6 +1896,7 @@ local block_state deflate_rle(s, flush)
|
||||
if (s->match_length > s->lookahead)
|
||||
s->match_length = s->lookahead;
|
||||
}
|
||||
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
||||
}
|
||||
|
||||
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||||
@ -1796,8 +1917,14 @@ local block_state deflate_rle(s, flush)
|
||||
}
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
s->insert = 0;
|
||||
if (flush == Z_FINISH) {
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -1829,6 +1956,12 @@ local block_state deflate_huff(s, flush)
|
||||
s->strstart++;
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
s->insert = 0;
|
||||
if (flush == Z_FINISH) {
|
||||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
12
deps/zlib/deflate.h
vendored
12
deps/zlib/deflate.h
vendored
@ -1,5 +1,5 @@
|
||||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -48,6 +48,9 @@
|
||||
#define MAX_BITS 15
|
||||
/* All codes must not exceed MAX_BITS bits */
|
||||
|
||||
#define Buf_size 16
|
||||
/* size of bit buffer in bi_buf */
|
||||
|
||||
#define INIT_STATE 42
|
||||
#define EXTRA_STATE 69
|
||||
#define NAME_STATE 73
|
||||
@ -101,7 +104,7 @@ typedef struct internal_state {
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
gz_headerp gzhead; /* gzip header information to write */
|
||||
uInt gzindex; /* where in extra, name, or comment */
|
||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
||||
Byte method; /* can only be DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
@ -188,7 +191,7 @@ typedef struct internal_state {
|
||||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
||||
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||
@ -244,7 +247,7 @@ typedef struct internal_state {
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
uInt matches; /* number of string matches in current block */
|
||||
int last_eob_len; /* bit length of EOB code for last block */
|
||||
uInt insert; /* bytes at end of window left to insert */
|
||||
|
||||
#ifdef DEBUG
|
||||
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||
@ -294,6 +297,7 @@ void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
|
||||
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
|
||||
ulg stored_len, int last));
|
||||
void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
|
||||
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
|
||||
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||
ulg stored_len, int last));
|
||||
|
640
deps/zlib/infback.c
vendored
Normal file
640
deps/zlib/infback.c
vendored
Normal file
@ -0,0 +1,640 @@
|
||||
/* infback.c -- inflate using a call-back interface
|
||||
* Copyright (C) 1995-2011 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/*
|
||||
This code is largely copied from inflate.c. Normally either infback.o or
|
||||
inflate.o would be linked into an application--not both. The interface
|
||||
with inffast.c is retained so that optimized assembler-coded versions of
|
||||
inflate_fast() can be used with either inflate.c or infback.c.
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
|
||||
/* function prototypes */
|
||||
local void fixedtables OF((struct inflate_state FAR *state));
|
||||
|
||||
/*
|
||||
strm provides memory allocation functions in zalloc and zfree, or
|
||||
Z_NULL to use the library memory allocation functions.
|
||||
|
||||
windowBits is in the range 8..15, and window is a user-supplied
|
||||
window and output buffer that is 2**windowBits bytes.
|
||||
*/
|
||||
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
unsigned char FAR *window;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||
stream_size != (int)(sizeof(z_stream)))
|
||||
return Z_VERSION_ERROR;
|
||||
if (strm == Z_NULL || window == Z_NULL ||
|
||||
windowBits < 8 || windowBits > 15)
|
||||
return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
#endif
|
||||
}
|
||||
if (strm->zfree == (free_func)0)
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zfree = zcfree;
|
||||
#endif
|
||||
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
|
||||
sizeof(struct inflate_state));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
Tracev((stderr, "inflate: allocated\n"));
|
||||
strm->state = (struct internal_state FAR *)state;
|
||||
state->dmax = 32768U;
|
||||
state->wbits = windowBits;
|
||||
state->wsize = 1U << windowBits;
|
||||
state->window = window;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Return state with length and distance decoding tables and index sizes set to
|
||||
fixed code decoding. Normally this returns fixed tables from inffixed.h.
|
||||
If BUILDFIXED is defined, then instead this routine builds the tables the
|
||||
first time it's called, and returns those tables the first time and
|
||||
thereafter. This reduces the size of the code by about 2K bytes, in
|
||||
exchange for a little execution time. However, BUILDFIXED should not be
|
||||
used for threaded applications, since the rewriting of the tables and virgin
|
||||
may not be thread-safe.
|
||||
*/
|
||||
local void fixedtables(state)
|
||||
struct inflate_state FAR *state;
|
||||
{
|
||||
#ifdef BUILDFIXED
|
||||
static int virgin = 1;
|
||||
static code *lenfix, *distfix;
|
||||
static code fixed[544];
|
||||
|
||||
/* build fixed huffman tables if first call (may not be thread safe) */
|
||||
if (virgin) {
|
||||
unsigned sym, bits;
|
||||
static code *next;
|
||||
|
||||
/* literal/length table */
|
||||
sym = 0;
|
||||
while (sym < 144) state->lens[sym++] = 8;
|
||||
while (sym < 256) state->lens[sym++] = 9;
|
||||
while (sym < 280) state->lens[sym++] = 7;
|
||||
while (sym < 288) state->lens[sym++] = 8;
|
||||
next = fixed;
|
||||
lenfix = next;
|
||||
bits = 9;
|
||||
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
|
||||
|
||||
/* distance table */
|
||||
sym = 0;
|
||||
while (sym < 32) state->lens[sym++] = 5;
|
||||
distfix = next;
|
||||
bits = 5;
|
||||
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
|
||||
|
||||
/* do this just once */
|
||||
virgin = 0;
|
||||
}
|
||||
#else /* !BUILDFIXED */
|
||||
# include "inffixed.h"
|
||||
#endif /* BUILDFIXED */
|
||||
state->lencode = lenfix;
|
||||
state->lenbits = 9;
|
||||
state->distcode = distfix;
|
||||
state->distbits = 5;
|
||||
}
|
||||
|
||||
/* Macros for inflateBack(): */
|
||||
|
||||
/* Load returned state from inflate_fast() */
|
||||
#define LOAD() \
|
||||
do { \
|
||||
put = strm->next_out; \
|
||||
left = strm->avail_out; \
|
||||
next = strm->next_in; \
|
||||
have = strm->avail_in; \
|
||||
hold = state->hold; \
|
||||
bits = state->bits; \
|
||||
} while (0)
|
||||
|
||||
/* Set state from registers for inflate_fast() */
|
||||
#define RESTORE() \
|
||||
do { \
|
||||
strm->next_out = put; \
|
||||
strm->avail_out = left; \
|
||||
strm->next_in = next; \
|
||||
strm->avail_in = have; \
|
||||
state->hold = hold; \
|
||||
state->bits = bits; \
|
||||
} while (0)
|
||||
|
||||
/* Clear the input bit accumulator */
|
||||
#define INITBITS() \
|
||||
do { \
|
||||
hold = 0; \
|
||||
bits = 0; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that some input is available. If input is requested, but denied,
|
||||
then return a Z_BUF_ERROR from inflateBack(). */
|
||||
#define PULL() \
|
||||
do { \
|
||||
if (have == 0) { \
|
||||
have = in(in_desc, &next); \
|
||||
if (have == 0) { \
|
||||
next = Z_NULL; \
|
||||
ret = Z_BUF_ERROR; \
|
||||
goto inf_leave; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Get a byte of input into the bit accumulator, or return from inflateBack()
|
||||
with an error if there is no input available. */
|
||||
#define PULLBYTE() \
|
||||
do { \
|
||||
PULL(); \
|
||||
have--; \
|
||||
hold += (unsigned long)(*next++) << bits; \
|
||||
bits += 8; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that there are at least n bits in the bit accumulator. If there is
|
||||
not enough available input to do that, then return from inflateBack() with
|
||||
an error. */
|
||||
#define NEEDBITS(n) \
|
||||
do { \
|
||||
while (bits < (unsigned)(n)) \
|
||||
PULLBYTE(); \
|
||||
} while (0)
|
||||
|
||||
/* Return the low n bits of the bit accumulator (n < 16) */
|
||||
#define BITS(n) \
|
||||
((unsigned)hold & ((1U << (n)) - 1))
|
||||
|
||||
/* Remove n bits from the bit accumulator */
|
||||
#define DROPBITS(n) \
|
||||
do { \
|
||||
hold >>= (n); \
|
||||
bits -= (unsigned)(n); \
|
||||
} while (0)
|
||||
|
||||
/* Remove zero to seven bits as needed to go to a byte boundary */
|
||||
#define BYTEBITS() \
|
||||
do { \
|
||||
hold >>= bits & 7; \
|
||||
bits -= bits & 7; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that some output space is available, by writing out the window
|
||||
if it's full. If the write fails, return from inflateBack() with a
|
||||
Z_BUF_ERROR. */
|
||||
#define ROOM() \
|
||||
do { \
|
||||
if (left == 0) { \
|
||||
put = state->window; \
|
||||
left = state->wsize; \
|
||||
state->whave = left; \
|
||||
if (out(out_desc, put, left)) { \
|
||||
ret = Z_BUF_ERROR; \
|
||||
goto inf_leave; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
strm provides the memory allocation functions and window buffer on input,
|
||||
and provides information on the unused input on return. For Z_DATA_ERROR
|
||||
returns, strm will also provide an error message.
|
||||
|
||||
in() and out() are the call-back input and output functions. When
|
||||
inflateBack() needs more input, it calls in(). When inflateBack() has
|
||||
filled the window with output, or when it completes with data in the
|
||||
window, it calls out() to write out the data. The application must not
|
||||
change the provided input until in() is called again or inflateBack()
|
||||
returns. The application must not change the window/output buffer until
|
||||
inflateBack() returns.
|
||||
|
||||
in() and out() are called with a descriptor parameter provided in the
|
||||
inflateBack() call. This parameter can be a structure that provides the
|
||||
information required to do the read or write, as well as accumulated
|
||||
information on the input and output such as totals and check values.
|
||||
|
||||
in() should return zero on failure. out() should return non-zero on
|
||||
failure. If either in() or out() fails, than inflateBack() returns a
|
||||
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
|
||||
was in() or out() that caused in the error. Otherwise, inflateBack()
|
||||
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
|
||||
error, or Z_MEM_ERROR if it could not allocate memory for the state.
|
||||
inflateBack() can also return Z_STREAM_ERROR if the input parameters
|
||||
are not correct, i.e. strm is Z_NULL or the state was not initialized.
|
||||
*/
|
||||
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
|
||||
z_streamp strm;
|
||||
in_func in;
|
||||
void FAR *in_desc;
|
||||
out_func out;
|
||||
void FAR *out_desc;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
z_const unsigned char FAR *next; /* next input */
|
||||
unsigned char FAR *put; /* next output */
|
||||
unsigned have, left; /* available input and output */
|
||||
unsigned long hold; /* bit buffer */
|
||||
unsigned bits; /* bits in bit buffer */
|
||||
unsigned copy; /* number of stored or match bytes to copy */
|
||||
unsigned char FAR *from; /* where to copy match bytes from */
|
||||
code here; /* current decoding table entry */
|
||||
code last; /* parent table entry */
|
||||
unsigned len; /* length to copy for repeats, bits to drop */
|
||||
int ret; /* return code */
|
||||
static const unsigned short order[19] = /* permutation of code lengths */
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
/* Check that the strm exists and that the state was initialized */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
/* Reset the state */
|
||||
strm->msg = Z_NULL;
|
||||
state->mode = TYPE;
|
||||
state->last = 0;
|
||||
state->whave = 0;
|
||||
next = strm->next_in;
|
||||
have = next != Z_NULL ? strm->avail_in : 0;
|
||||
hold = 0;
|
||||
bits = 0;
|
||||
put = state->window;
|
||||
left = state->wsize;
|
||||
|
||||
/* Inflate until end of block marked as last */
|
||||
for (;;)
|
||||
switch (state->mode) {
|
||||
case TYPE:
|
||||
/* determine and dispatch block type */
|
||||
if (state->last) {
|
||||
BYTEBITS();
|
||||
state->mode = DONE;
|
||||
break;
|
||||
}
|
||||
NEEDBITS(3);
|
||||
state->last = BITS(1);
|
||||
DROPBITS(1);
|
||||
switch (BITS(2)) {
|
||||
case 0: /* stored block */
|
||||
Tracev((stderr, "inflate: stored block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = STORED;
|
||||
break;
|
||||
case 1: /* fixed block */
|
||||
fixedtables(state);
|
||||
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = LEN; /* decode codes */
|
||||
break;
|
||||
case 2: /* dynamic block */
|
||||
Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = TABLE;
|
||||
break;
|
||||
case 3:
|
||||
strm->msg = (char *)"invalid block type";
|
||||
state->mode = BAD;
|
||||
}
|
||||
DROPBITS(2);
|
||||
break;
|
||||
|
||||
case STORED:
|
||||
/* get and verify stored block length */
|
||||
BYTEBITS(); /* go to byte boundary */
|
||||
NEEDBITS(32);
|
||||
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
|
||||
strm->msg = (char *)"invalid stored block lengths";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->length = (unsigned)hold & 0xffff;
|
||||
Tracev((stderr, "inflate: stored length %u\n",
|
||||
state->length));
|
||||
INITBITS();
|
||||
|
||||
/* copy stored block from input to output */
|
||||
while (state->length != 0) {
|
||||
copy = state->length;
|
||||
PULL();
|
||||
ROOM();
|
||||
if (copy > have) copy = have;
|
||||
if (copy > left) copy = left;
|
||||
zmemcpy(put, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
left -= copy;
|
||||
put += copy;
|
||||
state->length -= copy;
|
||||
}
|
||||
Tracev((stderr, "inflate: stored end\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
|
||||
case TABLE:
|
||||
/* get dynamic table entries descriptor */
|
||||
NEEDBITS(14);
|
||||
state->nlen = BITS(5) + 257;
|
||||
DROPBITS(5);
|
||||
state->ndist = BITS(5) + 1;
|
||||
DROPBITS(5);
|
||||
state->ncode = BITS(4) + 4;
|
||||
DROPBITS(4);
|
||||
#ifndef PKZIP_BUG_WORKAROUND
|
||||
if (state->nlen > 286 || state->ndist > 30) {
|
||||
strm->msg = (char *)"too many length or distance symbols";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
Tracev((stderr, "inflate: table sizes ok\n"));
|
||||
|
||||
/* get code length code lengths (not a typo) */
|
||||
state->have = 0;
|
||||
while (state->have < state->ncode) {
|
||||
NEEDBITS(3);
|
||||
state->lens[order[state->have++]] = (unsigned short)BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
while (state->have < 19)
|
||||
state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid code lengths set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: code lengths ok\n"));
|
||||
|
||||
/* get length and distance code code lengths */
|
||||
state->have = 0;
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (here.val < 16) {
|
||||
DROPBITS(here.bits);
|
||||
state->lens[state->have++] = here.val;
|
||||
}
|
||||
else {
|
||||
if (here.val == 16) {
|
||||
NEEDBITS(here.bits + 2);
|
||||
DROPBITS(here.bits);
|
||||
if (state->have == 0) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
len = (unsigned)(state->lens[state->have - 1]);
|
||||
copy = 3 + BITS(2);
|
||||
DROPBITS(2);
|
||||
}
|
||||
else if (here.val == 17) {
|
||||
NEEDBITS(here.bits + 3);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 3 + BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
else {
|
||||
NEEDBITS(here.bits + 7);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 11 + BITS(7);
|
||||
DROPBITS(7);
|
||||
}
|
||||
if (state->have + copy > state->nlen + state->ndist) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
while (copy--)
|
||||
state->lens[state->have++] = (unsigned short)len;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle error breaks in while */
|
||||
if (state->mode == BAD) break;
|
||||
|
||||
/* check for end-of-block code (better have one) */
|
||||
if (state->lens[256] == 0) {
|
||||
strm->msg = (char *)"invalid code -- missing end-of-block";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* build code tables -- note: do not change the lenbits or distbits
|
||||
values here (9 and 6) without reading the comments in inftrees.h
|
||||
concerning the ENOUGH constants, which depend on those values */
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lenbits = 9;
|
||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid literal/lengths set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->distcode = (code const FAR *)(state->next);
|
||||
state->distbits = 6;
|
||||
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||
&(state->next), &(state->distbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid distances set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: codes ok\n"));
|
||||
state->mode = LEN;
|
||||
|
||||
case LEN:
|
||||
/* use inflate_fast() if we have enough input and output */
|
||||
if (have >= 6 && left >= 258) {
|
||||
RESTORE();
|
||||
if (state->whave < state->wsize)
|
||||
state->whave = state->wsize - left;
|
||||
inflate_fast(strm, state->wsize);
|
||||
LOAD();
|
||||
break;
|
||||
}
|
||||
|
||||
/* get a literal, length, or end-of-block code */
|
||||
for (;;) {
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (here.op && (here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
here = state->lencode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(here.bits);
|
||||
state->length = (unsigned)here.val;
|
||||
|
||||
/* process literal */
|
||||
if (here.op == 0) {
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
ROOM();
|
||||
*put++ = (unsigned char)(state->length);
|
||||
left--;
|
||||
state->mode = LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* process end of block */
|
||||
if (here.op & 32) {
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* invalid code */
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* length code -- get extra bits, if any */
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
if (state->extra != 0) {
|
||||
NEEDBITS(state->extra);
|
||||
state->length += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", state->length));
|
||||
|
||||
/* get distance code */
|
||||
for (;;) {
|
||||
here = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if ((here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
here = state->distcode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(here.bits);
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->offset = (unsigned)here.val;
|
||||
|
||||
/* get distance extra bits, if any */
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
if (state->extra != 0) {
|
||||
NEEDBITS(state->extra);
|
||||
state->offset += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
}
|
||||
if (state->offset > state->wsize - (state->whave < state->wsize ?
|
||||
left : 0)) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||
|
||||
/* copy match from window to output */
|
||||
do {
|
||||
ROOM();
|
||||
copy = state->wsize - state->offset;
|
||||
if (copy < left) {
|
||||
from = put + copy;
|
||||
copy = left - copy;
|
||||
}
|
||||
else {
|
||||
from = put - state->offset;
|
||||
copy = left;
|
||||
}
|
||||
if (copy > state->length) copy = state->length;
|
||||
state->length -= copy;
|
||||
left -= copy;
|
||||
do {
|
||||
*put++ = *from++;
|
||||
} while (--copy);
|
||||
} while (state->length != 0);
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
/* inflate stream terminated properly -- write leftover output */
|
||||
ret = Z_STREAM_END;
|
||||
if (left < state->wsize) {
|
||||
if (out(out_desc, state->window, state->wsize - left))
|
||||
ret = Z_BUF_ERROR;
|
||||
}
|
||||
goto inf_leave;
|
||||
|
||||
case BAD:
|
||||
ret = Z_DATA_ERROR;
|
||||
goto inf_leave;
|
||||
|
||||
default: /* can't happen, but makes compilers happy */
|
||||
ret = Z_STREAM_ERROR;
|
||||
goto inf_leave;
|
||||
}
|
||||
|
||||
/* Return unused input */
|
||||
inf_leave:
|
||||
strm->next_in = next;
|
||||
strm->avail_in = have;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateBackEnd(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
|
||||
return Z_STREAM_ERROR;
|
||||
ZFREE(strm, strm->state);
|
||||
strm->state = Z_NULL;
|
||||
Tracev((stderr, "inflate: end\n"));
|
||||
return Z_OK;
|
||||
}
|
6
deps/zlib/inffast.c
vendored
6
deps/zlib/inffast.c
vendored
@ -1,5 +1,5 @@
|
||||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2008, 2010 Mark Adler
|
||||
* Copyright (C) 1995-2008, 2010, 2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -69,8 +69,8 @@ z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *in; /* local strm->next_in */
|
||||
unsigned char FAR *last; /* while in < last, enough input available */
|
||||
z_const unsigned char FAR *in; /* local strm->next_in */
|
||||
z_const unsigned char FAR *last; /* have enough input while in < last */
|
||||
unsigned char FAR *out; /* local strm->next_out */
|
||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char FAR *end; /* while out < end, enough space available */
|
||||
|
6
deps/zlib/inffixed.h
vendored
6
deps/zlib/inffixed.h
vendored
@ -2,9 +2,9 @@
|
||||
* Generated automatically by makefixed().
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It
|
||||
is part of the implementation of the compression library and
|
||||
is subject to change. Applications should only use zlib.h.
|
||||
/* WARNING: this file should *not* be used by applications.
|
||||
It is part of the implementation of this library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
static const code lenfix[512] = {
|
||||
|
136
deps/zlib/inflate.c
vendored
136
deps/zlib/inflate.c
vendored
@ -1,5 +1,5 @@
|
||||
/* inflate.c -- zlib decompression
|
||||
* Copyright (C) 1995-2010 Mark Adler
|
||||
* Copyright (C) 1995-2012 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -93,14 +93,15 @@
|
||||
|
||||
/* function prototypes */
|
||||
local void fixedtables OF((struct inflate_state FAR *state));
|
||||
local int updatewindow OF((z_streamp strm, unsigned out));
|
||||
local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
|
||||
unsigned copy));
|
||||
#ifdef BUILDFIXED
|
||||
void makefixed OF((void));
|
||||
#endif
|
||||
local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
|
||||
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
|
||||
unsigned len));
|
||||
|
||||
int ZEXPORT inflateReset(strm)
|
||||
int ZEXPORT inflateResetKeep(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
@ -109,15 +110,13 @@ z_streamp strm;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
strm->total_in = strm->total_out = state->total = 0;
|
||||
strm->msg = Z_NULL;
|
||||
strm->adler = 1; /* to support ill-conceived Java test suite */
|
||||
if (state->wrap) /* to support ill-conceived Java test suite */
|
||||
strm->adler = state->wrap & 1;
|
||||
state->mode = HEAD;
|
||||
state->last = 0;
|
||||
state->havedict = 0;
|
||||
state->dmax = 32768U;
|
||||
state->head = Z_NULL;
|
||||
state->wsize = 0;
|
||||
state->whave = 0;
|
||||
state->wnext = 0;
|
||||
state->hold = 0;
|
||||
state->bits = 0;
|
||||
state->lencode = state->distcode = state->next = state->codes;
|
||||
@ -127,6 +126,19 @@ z_streamp strm;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateReset(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
state->wsize = 0;
|
||||
state->whave = 0;
|
||||
state->wnext = 0;
|
||||
return inflateResetKeep(strm);
|
||||
}
|
||||
|
||||
int ZEXPORT inflateReset2(strm, windowBits)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
@ -180,10 +192,19 @@ int stream_size;
|
||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
#endif
|
||||
}
|
||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
||||
if (strm->zfree == (free_func)0)
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zfree = zcfree;
|
||||
#endif
|
||||
state = (struct inflate_state FAR *)
|
||||
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
@ -321,8 +342,8 @@ void makefixed()
|
||||
low = 0;
|
||||
for (;;) {
|
||||
if ((low % 7) == 0) printf("\n ");
|
||||
printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
|
||||
state.lencode[low].val);
|
||||
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
|
||||
state.lencode[low].bits, state.lencode[low].val);
|
||||
if (++low == size) break;
|
||||
putchar(',');
|
||||
}
|
||||
@ -355,12 +376,13 @@ void makefixed()
|
||||
output will fall in the output data, making match copies simpler and faster.
|
||||
The advantage may be dependent on the size of the processor's data caches.
|
||||
*/
|
||||
local int updatewindow(strm, out)
|
||||
local int updatewindow(strm, end, copy)
|
||||
z_streamp strm;
|
||||
unsigned out;
|
||||
const Bytef *end;
|
||||
unsigned copy;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned copy, dist;
|
||||
unsigned dist;
|
||||
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
@ -380,19 +402,18 @@ unsigned out;
|
||||
}
|
||||
|
||||
/* copy state->wsize or less output bytes into the circular window */
|
||||
copy = out - strm->avail_out;
|
||||
if (copy >= state->wsize) {
|
||||
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
|
||||
zmemcpy(state->window, end - state->wsize, state->wsize);
|
||||
state->wnext = 0;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
dist = state->wsize - state->wnext;
|
||||
if (dist > copy) dist = copy;
|
||||
zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
|
||||
zmemcpy(state->window + state->wnext, end - copy, dist);
|
||||
copy -= dist;
|
||||
if (copy) {
|
||||
zmemcpy(state->window, strm->next_out - copy, copy);
|
||||
zmemcpy(state->window, end - copy, copy);
|
||||
state->wnext = copy;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
@ -499,11 +520,6 @@ unsigned out;
|
||||
bits -= bits & 7; \
|
||||
} while (0)
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define REVERSE(q) \
|
||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
/*
|
||||
inflate() uses a state machine to process as much input data and generate as
|
||||
much output data as possible before returning. The state machine is
|
||||
@ -591,7 +607,7 @@ z_streamp strm;
|
||||
int flush;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *next; /* next input */
|
||||
z_const unsigned char FAR *next; /* next input */
|
||||
unsigned char FAR *put; /* next output */
|
||||
unsigned have, left; /* available input and output */
|
||||
unsigned long hold; /* bit buffer */
|
||||
@ -797,7 +813,7 @@ int flush;
|
||||
#endif
|
||||
case DICTID:
|
||||
NEEDBITS(32);
|
||||
strm->adler = state->check = REVERSE(hold);
|
||||
strm->adler = state->check = ZSWAP32(hold);
|
||||
INITBITS();
|
||||
state->mode = DICT;
|
||||
case DICT:
|
||||
@ -905,7 +921,7 @@ int flush;
|
||||
while (state->have < 19)
|
||||
state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lencode = (const code FAR *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
@ -925,7 +941,6 @@ int flush;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (here.val < 16) {
|
||||
NEEDBITS(here.bits);
|
||||
DROPBITS(here.bits);
|
||||
state->lens[state->have++] = here.val;
|
||||
}
|
||||
@ -980,7 +995,7 @@ int flush;
|
||||
values here (9 and 6) without reading the comments in inftrees.h
|
||||
concerning the ENOUGH constants, which depend on those values */
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lencode = (const code FAR *)(state->next);
|
||||
state->lenbits = 9;
|
||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
@ -989,7 +1004,7 @@ int flush;
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->distcode = (code const FAR *)(state->next);
|
||||
state->distcode = (const code FAR *)(state->next);
|
||||
state->distbits = 6;
|
||||
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||
&(state->next), &(state->distbits), state->work);
|
||||
@ -1170,7 +1185,7 @@ int flush;
|
||||
#ifdef GUNZIP
|
||||
state->flags ? hold :
|
||||
#endif
|
||||
REVERSE(hold)) != state->check) {
|
||||
ZSWAP32(hold)) != state->check) {
|
||||
strm->msg = (char *)"incorrect data check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
@ -1214,8 +1229,9 @@ int flush;
|
||||
*/
|
||||
inf_leave:
|
||||
RESTORE();
|
||||
if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
|
||||
if (updatewindow(strm, out)) {
|
||||
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
|
||||
(state->mode < CHECK || flush != Z_FINISH)))
|
||||
if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
|
||||
state->mode = MEM;
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
@ -1249,13 +1265,37 @@ z_streamp strm;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
Bytef *dictionary;
|
||||
uInt *dictLength;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
/* check state */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
/* copy dictionary */
|
||||
if (state->whave && dictionary != Z_NULL) {
|
||||
zmemcpy(dictionary, state->window + state->wnext,
|
||||
state->whave - state->wnext);
|
||||
zmemcpy(dictionary + state->whave - state->wnext,
|
||||
state->window, state->wnext);
|
||||
}
|
||||
if (dictLength != Z_NULL)
|
||||
*dictLength = state->whave;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
const Bytef *dictionary;
|
||||
uInt dictLength;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned long id;
|
||||
unsigned long dictid;
|
||||
int ret;
|
||||
|
||||
/* check state */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
@ -1263,29 +1303,21 @@ uInt dictLength;
|
||||
if (state->wrap != 0 && state->mode != DICT)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check for correct dictionary id */
|
||||
/* check for correct dictionary identifier */
|
||||
if (state->mode == DICT) {
|
||||
id = adler32(0L, Z_NULL, 0);
|
||||
id = adler32(id, dictionary, dictLength);
|
||||
if (id != state->check)
|
||||
dictid = adler32(0L, Z_NULL, 0);
|
||||
dictid = adler32(dictid, dictionary, dictLength);
|
||||
if (dictid != state->check)
|
||||
return Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* copy dictionary to window */
|
||||
if (updatewindow(strm, strm->avail_out)) {
|
||||
/* copy dictionary to window using updatewindow(), which will amend the
|
||||
existing dictionary if appropriate */
|
||||
ret = updatewindow(strm, dictionary + dictLength, dictLength);
|
||||
if (ret) {
|
||||
state->mode = MEM;
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
if (dictLength > state->wsize) {
|
||||
zmemcpy(state->window, dictionary + dictLength - state->wsize,
|
||||
state->wsize);
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
zmemcpy(state->window + state->wsize - dictLength, dictionary,
|
||||
dictLength);
|
||||
state->whave = dictLength;
|
||||
}
|
||||
state->havedict = 1;
|
||||
Tracev((stderr, "inflate: dictionary set\n"));
|
||||
return Z_OK;
|
||||
@ -1321,7 +1353,7 @@ gz_headerp head;
|
||||
*/
|
||||
local unsigned syncsearch(have, buf, len)
|
||||
unsigned FAR *have;
|
||||
unsigned char FAR *buf;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
unsigned got;
|
||||
@ -1433,8 +1465,8 @@ z_streamp source;
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
zmemcpy(dest, source, sizeof(z_stream));
|
||||
zmemcpy(copy, state, sizeof(struct inflate_state));
|
||||
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
|
||||
if (state->lencode >= state->codes &&
|
||||
state->lencode <= state->codes + ENOUGH - 1) {
|
||||
copy->lencode = copy->codes + (state->lencode - state->codes);
|
||||
|
54
deps/zlib/inftrees.c
vendored
54
deps/zlib/inftrees.c
vendored
@ -1,5 +1,5 @@
|
||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2010 Mark Adler
|
||||
* Copyright (C) 1995-2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
|
||||
" inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@ -62,7 +62,7 @@ unsigned short FAR *work;
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
@ -208,8 +208,8 @@ unsigned short FAR *work;
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if ((type == LENS && used >= ENOUGH_LENS) ||
|
||||
(type == DISTS && used >= ENOUGH_DISTS))
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
@ -277,8 +277,8 @@ unsigned short FAR *work;
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if ((type == LENS && used >= ENOUGH_LENS) ||
|
||||
(type == DISTS && used >= ENOUGH_DISTS))
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
@ -289,38 +289,14 @@ unsigned short FAR *work;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
||||
loop above in incrementing huff for table indices. It is assumed that
|
||||
len is equal to curr + drop, so there is no loop needed to increment
|
||||
through high index bits. When the current sub-table is filled, the loop
|
||||
drops back to the root table to fill in any remaining entries there.
|
||||
*/
|
||||
here.op = (unsigned char)64; /* invalid code marker */
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
here.val = (unsigned short)0;
|
||||
while (huff != 0) {
|
||||
/* when done with sub-table, drop back to root table */
|
||||
if (drop != 0 && (huff & mask) != low) {
|
||||
drop = 0;
|
||||
len = root;
|
||||
next = *table;
|
||||
here.bits = (unsigned char)len;
|
||||
}
|
||||
|
||||
/* put invalid code marker in table */
|
||||
next[huff >> drop] = here;
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||
at most one remaining entry, since if the code is incomplete, the
|
||||
maximum code length that was allowed to get this far is one bit) */
|
||||
if (huff != 0) {
|
||||
here.op = (unsigned char)64; /* invalid code marker */
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
here.val = (unsigned short)0;
|
||||
next[huff] = here;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
|
54
deps/zlib/trees.c
vendored
54
deps/zlib/trees.c
vendored
@ -1,5 +1,5 @@
|
||||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
@ -74,11 +74,6 @@ local const uch bl_order[BL_CODES]
|
||||
* probability, to avoid transmitting the lengths for unused bit length codes.
|
||||
*/
|
||||
|
||||
#define Buf_size (8 * 2*sizeof(char))
|
||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
||||
* more than 16 bits on some systems.)
|
||||
*/
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data. These are initialized only once.
|
||||
*/
|
||||
@ -151,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
|
||||
local int build_bl_tree OF((deflate_state *s));
|
||||
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
|
||||
int blcodes));
|
||||
local void compress_block OF((deflate_state *s, ct_data *ltree,
|
||||
ct_data *dtree));
|
||||
local void compress_block OF((deflate_state *s, const ct_data *ltree,
|
||||
const ct_data *dtree));
|
||||
local int detect_data_type OF((deflate_state *s));
|
||||
local unsigned bi_reverse OF((unsigned value, int length));
|
||||
local void bi_windup OF((deflate_state *s));
|
||||
@ -399,7 +394,6 @@ void ZLIB_INTERNAL _tr_init(s)
|
||||
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
||||
#ifdef DEBUG
|
||||
s->compressed_len = 0L;
|
||||
s->bits_sent = 0L;
|
||||
@ -882,16 +876,18 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
||||
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
|
||||
*/
|
||||
void ZLIB_INTERNAL _tr_flush_bits(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
bi_flush(s);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Send one empty static block to give enough lookahead for inflate.
|
||||
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
||||
* The current inflate code requires 9 bits of lookahead. If the
|
||||
* last two codes for the previous block (real code plus EOB) were coded
|
||||
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
||||
* the last real code. In this case we send two empty static blocks instead
|
||||
* of one. (There are no problems if the previous block is stored or fixed.)
|
||||
* To simplify the code, we assume the worst case of last real code encoded
|
||||
* on one bit only.
|
||||
*/
|
||||
void ZLIB_INTERNAL _tr_align(s)
|
||||
deflate_state *s;
|
||||
@ -902,20 +898,6 @@ void ZLIB_INTERNAL _tr_align(s)
|
||||
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
||||
#endif
|
||||
bi_flush(s);
|
||||
/* Of the 10 bits for the empty block, we have already sent
|
||||
* (10 - bi_valid) bits. The lookahead for the last real code (before
|
||||
* the EOB of the previous block) was thus at least one plus the length
|
||||
* of the EOB plus what we have just sent of the empty static block.
|
||||
*/
|
||||
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
|
||||
send_bits(s, STATIC_TREES<<1, 3);
|
||||
send_code(s, END_BLOCK, static_ltree);
|
||||
#ifdef DEBUG
|
||||
s->compressed_len += 10L;
|
||||
#endif
|
||||
bi_flush(s);
|
||||
}
|
||||
s->last_eob_len = 7;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -990,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
|
||||
#endif
|
||||
send_bits(s, (STATIC_TREES<<1)+last, 3);
|
||||
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
|
||||
compress_block(s, (const ct_data *)static_ltree,
|
||||
(const ct_data *)static_dtree);
|
||||
#ifdef DEBUG
|
||||
s->compressed_len += 3 + s->static_len;
|
||||
#endif
|
||||
@ -998,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
send_bits(s, (DYN_TREES<<1)+last, 3);
|
||||
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
||||
max_blindex+1);
|
||||
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
|
||||
compress_block(s, (const ct_data *)s->dyn_ltree,
|
||||
(const ct_data *)s->dyn_dtree);
|
||||
#ifdef DEBUG
|
||||
s->compressed_len += 3 + s->opt_len;
|
||||
#endif
|
||||
@ -1075,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
*/
|
||||
local void compress_block(s, ltree, dtree)
|
||||
deflate_state *s;
|
||||
ct_data *ltree; /* literal tree */
|
||||
ct_data *dtree; /* distance tree */
|
||||
const ct_data *ltree; /* literal tree */
|
||||
const ct_data *dtree; /* distance tree */
|
||||
{
|
||||
unsigned dist; /* distance of matched string */
|
||||
int lc; /* match length or unmatched char (if dist == 0) */
|
||||
@ -1118,7 +1102,6 @@ local void compress_block(s, ltree, dtree)
|
||||
} while (lx < s->last_lit);
|
||||
|
||||
send_code(s, END_BLOCK, ltree);
|
||||
s->last_eob_len = ltree[END_BLOCK].Len;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -1226,7 +1209,6 @@ local void copy_block(s, buf, len, header)
|
||||
int header; /* true if block header must be written */
|
||||
{
|
||||
bi_windup(s); /* align on byte boundary */
|
||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
||||
|
||||
if (header) {
|
||||
put_short(s, (ush)len);
|
||||
|
4
deps/zlib/zconf.h
vendored
4
deps/zlib/zconf.h
vendored
@ -14,6 +14,7 @@
|
||||
* forms, we didn't write zlib */
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable : 4131 )
|
||||
# pragma warning( disable : 4142 ) /* benign redefinition of type */
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
@ -33,10 +34,12 @@
|
||||
# define FAR
|
||||
#endif
|
||||
#define OF(args) args
|
||||
#define Z_ARG(args) args
|
||||
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
typedef unsigned long z_crc_t;
|
||||
|
||||
typedef Byte FAR Bytef;
|
||||
typedef char FAR charf;
|
||||
@ -50,5 +53,6 @@ typedef void *voidp;
|
||||
|
||||
#define z_off_t git_off_t
|
||||
#define z_off64_t z_off_t
|
||||
#define z_const const
|
||||
|
||||
#endif /* ZCONF_H */
|
||||
|
343
deps/zlib/zlib.h
vendored
343
deps/zlib/zlib.h
vendored
@ -1,7 +1,7 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.5, April 19th, 2010
|
||||
version 1.2.8, April 28th, 2013
|
||||
|
||||
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -24,8 +24,8 @@
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
|
||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||||
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
|
||||
*/
|
||||
|
||||
#ifndef ZLIB_H
|
||||
@ -37,11 +37,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.2.5"
|
||||
#define ZLIB_VERNUM 0x1250
|
||||
#define ZLIB_VERSION "1.2.8"
|
||||
#define ZLIB_VERNUM 0x1280
|
||||
#define ZLIB_VER_MAJOR 1
|
||||
#define ZLIB_VER_MINOR 2
|
||||
#define ZLIB_VER_REVISION 5
|
||||
#define ZLIB_VER_REVISION 8
|
||||
#define ZLIB_VER_SUBREVISION 0
|
||||
|
||||
/*
|
||||
@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
|
||||
struct internal_state;
|
||||
|
||||
typedef struct z_stream_s {
|
||||
Bytef *next_in; /* next input byte */
|
||||
z_const Bytef *next_in; /* next input byte */
|
||||
uInt avail_in; /* number of bytes available at next_in */
|
||||
uLong total_in; /* total nb of input bytes read so far */
|
||||
uLong total_in; /* total number of input bytes read so far */
|
||||
|
||||
Bytef *next_out; /* next output byte should be put there */
|
||||
uInt avail_out; /* remaining free space at next_out */
|
||||
uLong total_out; /* total nb of bytes output so far */
|
||||
uLong total_out; /* total number of bytes output so far */
|
||||
|
||||
char *msg; /* last error message, NULL if no error */
|
||||
z_const char *msg; /* last error message, NULL if no error */
|
||||
struct internal_state FAR *state; /* not visible by applications */
|
||||
|
||||
alloc_func zalloc; /* used to allocate the internal state */
|
||||
@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
|
||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||
is to be done in a single step. In this case, avail_out must be at least the
|
||||
value returned by deflateBound (see below). If deflate does not return
|
||||
Z_STREAM_END, then it must be called again as described above.
|
||||
value returned by deflateBound (see below). Then deflate is guaranteed to
|
||||
return Z_STREAM_END. If not enough output space is provided, deflate will
|
||||
not return Z_STREAM_END, and it must be called again as described above.
|
||||
|
||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||
so far (that is, total_in bytes).
|
||||
@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
error. However if all decompression is to be performed in a single step (a
|
||||
single call of inflate), the parameter flush should be set to Z_FINISH. In
|
||||
this case all pending input is processed and all pending output is flushed;
|
||||
avail_out must be large enough to hold all the uncompressed data. (The size
|
||||
of the uncompressed data may have been saved by the compressor for this
|
||||
purpose.) The next operation on this stream must be inflateEnd to deallocate
|
||||
the decompression state. The use of Z_FINISH is never required, but can be
|
||||
used to inform inflate that a faster approach may be used for the single
|
||||
inflate() call.
|
||||
avail_out must be large enough to hold all of the uncompressed data for the
|
||||
operation to complete. (The size of the uncompressed data may have been
|
||||
saved by the compressor for this purpose.) The use of Z_FINISH is not
|
||||
required to perform an inflation in one step. However it may be used to
|
||||
inform inflate that a faster approach can be used for the single inflate()
|
||||
call. Z_FINISH also informs inflate to not maintain a sliding window if the
|
||||
stream completes, which reduces inflate's memory footprint. If the stream
|
||||
does not complete, either because not all of the stream is provided or not
|
||||
enough output space is provided, then a sliding window will be allocated and
|
||||
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
|
||||
been used.
|
||||
|
||||
In this implementation, inflate() always flushes as much output as
|
||||
possible to the output buffer, and always uses the faster approach on the
|
||||
first call. So the only effect of the flush parameter in this implementation
|
||||
is on the return value of inflate(), as noted below, or when it returns early
|
||||
because Z_BLOCK or Z_TREES is used.
|
||||
first call. So the effects of the flush parameter in this implementation are
|
||||
on the return value of inflate() as noted below, when inflate() returns early
|
||||
when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
|
||||
memory for a sliding window when Z_FINISH is used.
|
||||
|
||||
If a preset dictionary is needed after this call (see inflateSetDictionary
|
||||
below), inflate sets strm->adler to the adler32 checksum of the dictionary
|
||||
below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
|
||||
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
||||
strm->adler to the adler32 checksum of all output produced so far (that is,
|
||||
strm->adler to the Adler-32 checksum of all output produced so far (that is,
|
||||
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
||||
below. At the end of the stream, inflate() checks that its computed adler32
|
||||
checksum is equal to that saved by the compressor and returns Z_STREAM_END
|
||||
@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
initializing with inflateInit2(). Any information contained in the gzip
|
||||
header is not retained, so applications that need that information should
|
||||
instead use raw inflate, see inflateInit2() below, or inflateBack() and
|
||||
perform their own processing of the gzip header and trailer.
|
||||
perform their own processing of the gzip header and trailer. When processing
|
||||
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
|
||||
producted so far. The CRC-32 is checked against the gzip trailer.
|
||||
|
||||
inflate() returns Z_OK if some progress has been made (more input processed
|
||||
or more output produced), Z_STREAM_END if the end of the compressed data has
|
||||
@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the compression dictionary from the given byte sequence
|
||||
without producing any compressed output. This function must be called
|
||||
immediately after deflateInit, deflateInit2 or deflateReset, before any call
|
||||
of deflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see inflateSetDictionary).
|
||||
without producing any compressed output. When using the zlib format, this
|
||||
function must be called immediately after deflateInit, deflateInit2 or
|
||||
deflateReset, and before any call of deflate. When doing raw deflate, this
|
||||
function must be called either before any call of deflate, or immediately
|
||||
after the completion of a deflate block, i.e. after all input has been
|
||||
consumed and all output has been delivered when using any of the flush
|
||||
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
|
||||
compressor and decompressor must use exactly the same dictionary (see
|
||||
inflateSetDictionary).
|
||||
|
||||
The dictionary should consist of strings (byte sequences) that are likely
|
||||
to be encountered later in the data to be compressed, with the most commonly
|
||||
@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||
inconsistent (for example if deflate has already been called for this stream
|
||||
or if the compression method is bsort). deflateSetDictionary does not
|
||||
perform any compression: this will be done by deflate().
|
||||
or if not at a block boundary for raw deflate). deflateSetDictionary does
|
||||
not perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
||||
@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
||||
deflation of sourceLen bytes. It must be called after deflateInit() or
|
||||
deflateInit2(), and after deflateSetHeader(), if used. This would be used
|
||||
to allocate an output buffer for deflation in a single pass, and so would be
|
||||
called before deflate().
|
||||
called before deflate(). If that first deflate() call is provided the
|
||||
sourceLen input bytes, an output buffer allocated to the size returned by
|
||||
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
|
||||
to return Z_STREAM_END. Note that it is possible for the compressed size to
|
||||
be larger than the value returned by deflateBound() if flush options other
|
||||
than Z_FINISH or Z_NO_FLUSH are used.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
|
||||
unsigned *pending,
|
||||
int *bits));
|
||||
/*
|
||||
deflatePending() returns the number of bytes and bits of output that have
|
||||
been generated, but not yet provided in the available output. The bytes not
|
||||
provided would be due to the available output space having being consumed.
|
||||
The number of bits of output not provided are between 0 and 7, where they
|
||||
await more bits to join them in order to fill out a full byte. If pending
|
||||
or bits are Z_NULL, then those values are not set.
|
||||
|
||||
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||
int bits,
|
||||
int value));
|
||||
@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||
than or equal to 16, and that many of the least significant bits of value
|
||||
will be inserted in the output.
|
||||
|
||||
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent.
|
||||
deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
|
||||
room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
|
||||
source stream state was inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
||||
@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||
can be determined from the adler32 value returned by that call of inflate.
|
||||
The compressor and decompressor must use exactly the same dictionary (see
|
||||
deflateSetDictionary). For raw inflate, this function can be called
|
||||
immediately after inflateInit2() or inflateReset() and before any call of
|
||||
inflate() to set the dictionary. The application must insure that the
|
||||
dictionary that was used for compression is provided.
|
||||
deflateSetDictionary). For raw inflate, this function can be called at any
|
||||
time to set the dictionary. If the provided dictionary is smaller than the
|
||||
window and there is already data in the window, then the provided dictionary
|
||||
will amend what's there. The application must insure that the dictionary
|
||||
that was used for compression is provided.
|
||||
|
||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||
@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
inflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
|
||||
Bytef *dictionary,
|
||||
uInt *dictLength));
|
||||
/*
|
||||
Returns the sliding dictionary being maintained by inflate. dictLength is
|
||||
set to the number of bytes in the dictionary, and that many bytes are copied
|
||||
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||
always enough. If inflateGetDictionary() is called with dictionary equal to
|
||||
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||
Similary, if dictLength is Z_NULL, then it is not set.
|
||||
|
||||
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
|
||||
stream state is inconsistent.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
||||
/*
|
||||
Skips invalid compressed data until a full flush point (see above the
|
||||
description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||
Skips invalid compressed data until a possible full flush point (see above
|
||||
for the description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||
available input is skipped. No output is provided.
|
||||
|
||||
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
||||
if no more input was provided, Z_DATA_ERROR if no flush point has been
|
||||
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
|
||||
success case, the application may save the current current value of total_in
|
||||
which indicates where valid compressed data was found. In the error case,
|
||||
the application may repeatedly call inflateSync, providing more input each
|
||||
time, until success or end of the input data.
|
||||
inflateSync searches for a 00 00 FF FF pattern in the compressed data.
|
||||
All full flush points have this pattern, but not all occurrences of this
|
||||
pattern are full flush points.
|
||||
|
||||
inflateSync returns Z_OK if a possible full flush point has been found,
|
||||
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
|
||||
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
|
||||
In the success case, the application may save the current current value of
|
||||
total_in which indicates where valid compressed data was found. In the
|
||||
error case, the application may repeatedly call inflateSync, providing more
|
||||
input each time, until success or end of the input data.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
|
||||
@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
||||
See inflateBack() for the usage of these routines.
|
||||
|
||||
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
|
||||
the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
|
||||
the parameters are invalid, Z_MEM_ERROR if the internal state could not be
|
||||
allocated, or Z_VERSION_ERROR if the version of the library does not match
|
||||
the version of the header file.
|
||||
*/
|
||||
|
||||
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
|
||||
typedef unsigned (*in_func) OF((void FAR *,
|
||||
z_const unsigned char FAR * FAR *));
|
||||
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
||||
|
||||
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||
@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
||||
out_func out, void FAR *out_desc));
|
||||
/*
|
||||
inflateBack() does a raw inflate with a single call using a call-back
|
||||
interface for input and output. This is more efficient than inflate() for
|
||||
file i/o applications in that it avoids copying between the output and the
|
||||
sliding window by simply making the window itself the output buffer. This
|
||||
function trusts the application to not change the output buffer passed by
|
||||
the output function, at least until inflateBack() returns.
|
||||
interface for input and output. This is potentially more efficient than
|
||||
inflate() for file i/o applications, in that it avoids copying between the
|
||||
output and the sliding window by simply making the window itself the output
|
||||
buffer. inflate() can be faster on modern CPUs when used with large
|
||||
buffers. inflateBack() trusts the application to not change the output
|
||||
buffer passed by the output function, at least until inflateBack() returns.
|
||||
|
||||
inflateBackInit() must be called first to allocate the internal state
|
||||
and to initialize the state with the user-provided window buffer.
|
||||
@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
|
||||
27-31: 0 (reserved)
|
||||
*/
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
/* utility functions */
|
||||
|
||||
@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
|
||||
the case where there is not enough room, uncompress() will fill the output
|
||||
buffer with the uncompressed data up to that point.
|
||||
*/
|
||||
|
||||
|
||||
/* gzip file access functions */
|
||||
|
||||
/*
|
||||
@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
||||
*/
|
||||
|
||||
typedef voidp gzFile; /* opaque gzip file descriptor */
|
||||
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
|
||||
|
||||
/*
|
||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||
@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
||||
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
||||
for fixed code compression as in "wb9F". (See the description of
|
||||
deflateInit2 for more information about the strategy parameter.) Also "a"
|
||||
can be used instead of "w" to request that the gzip stream that will be
|
||||
written be appended to the file. "+" will result in an error, since reading
|
||||
and writing to the same gzip file is not supported.
|
||||
deflateInit2 for more information about the strategy parameter.) 'T' will
|
||||
request transparent writing or appending with no compression and not using
|
||||
the gzip format.
|
||||
|
||||
"a" can be used instead of "w" to request that the gzip stream that will
|
||||
be written be appended to the file. "+" will result in an error, since
|
||||
reading and writing to the same gzip file is not supported. The addition of
|
||||
"x" when writing will create the file exclusively, which fails if the file
|
||||
already exists. On systems that support it, the addition of "e" when
|
||||
reading or writing will set the flag to close the file on an execve() call.
|
||||
|
||||
These functions, as well as gzip, will read and decode a sequence of gzip
|
||||
streams in a file. The append function of gzopen() can be used to create
|
||||
such a file. (Also see gzflush() for another way to do this.) When
|
||||
appending, gzopen does not test whether the file begins with a gzip stream,
|
||||
nor does it look for the end of the gzip streams to begin appending. gzopen
|
||||
will simply append a gzip stream to the existing file.
|
||||
|
||||
gzopen can be used to read a file which is not in gzip format; in this
|
||||
case gzread will directly read from the file without decompression.
|
||||
case gzread will directly read from the file without decompression. When
|
||||
reading, this will be detected automatically by looking for the magic two-
|
||||
byte gzip header.
|
||||
|
||||
gzopen returns NULL if the file could not be opened, if there was
|
||||
insufficient memory to allocate the gzFile state, or if an invalid mode was
|
||||
@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
||||
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
||||
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
|
||||
mode);. The duplicated descriptor should be saved to avoid a leak, since
|
||||
gzdopen does not close fd if it fails.
|
||||
gzdopen does not close fd if it fails. If you are using fileno() to get the
|
||||
file descriptor from a FILE *, then you will have to use dup() to avoid
|
||||
double-close()ing the file descriptor. Both gzclose() and fclose() will
|
||||
close the associated file descriptor, so they need to have different file
|
||||
descriptors.
|
||||
|
||||
gzdopen returns NULL if there was insufficient memory to allocate the
|
||||
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
|
||||
@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
||||
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
||||
/*
|
||||
Reads the given number of uncompressed bytes from the compressed file. If
|
||||
the input file was not in gzip format, gzread copies the given number of
|
||||
bytes into the buffer.
|
||||
the input file is not in gzip format, gzread copies the given number of
|
||||
bytes into the buffer directly from the file.
|
||||
|
||||
After reaching the end of a gzip stream in the input, gzread will continue
|
||||
to read, looking for another gzip stream, or failing that, reading the rest
|
||||
of the input file directly without decompression. The entire input file
|
||||
will be read if gzread is called until it returns less than the requested
|
||||
len.
|
||||
to read, looking for another gzip stream. Any number of gzip streams may be
|
||||
concatenated in the input file, and will all be decompressed by gzread().
|
||||
If something other than a gzip stream is encountered after a gzip stream,
|
||||
that remaining trailing garbage is ignored (and no error is returned).
|
||||
|
||||
gzread can be used to read a gzip file that is being concurrently written.
|
||||
Upon reaching the end of the input, gzread will return with the available
|
||||
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
|
||||
gzclearerr can be used to clear the end of file indicator in order to permit
|
||||
gzread to be tried again. Z_OK indicates that a gzip stream was completed
|
||||
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
|
||||
middle of a gzip stream. Note that gzread does not return -1 in the event
|
||||
of an incomplete gzip stream. This error is deferred until gzclose(), which
|
||||
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
|
||||
stream. Alternatively, gzerror can be used before gzclose to detect this
|
||||
case.
|
||||
|
||||
gzread returns the number of uncompressed bytes actually read, less than
|
||||
len for end of file, or -1 for error.
|
||||
@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
||||
error.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
|
||||
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
|
||||
/*
|
||||
Converts, formats, and writes the arguments to the compressed file under
|
||||
control of the format string, as in fprintf. gzprintf returns the number of
|
||||
@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
||||
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||
/*
|
||||
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
||||
in case of end of file or error.
|
||||
in case of end of file or error. This is implemented as a macro for speed.
|
||||
As such, it does not do all of the checking the other functions do. I.e.
|
||||
it does not check to see if file is NULL, nor whether the structure file
|
||||
points to has been clobbered or not.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
||||
@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||
/*
|
||||
Returns true (1) if file is being copied directly while reading, or false
|
||||
(0) if file is a gzip stream being decompressed. This state can change from
|
||||
false to true while reading the input file if the end of a gzip stream is
|
||||
reached, but is followed by data that is not another gzip stream.
|
||||
(0) if file is a gzip stream being decompressed.
|
||||
|
||||
If the input file is empty, gzdirect() will return true, since the input
|
||||
does not contain a gzip stream.
|
||||
@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||
cause buffers to be allocated to allow reading the file to determine if it
|
||||
is a gzip file. Therefore if gzbuffer() is used, it should be called before
|
||||
gzdirect().
|
||||
|
||||
When writing, gzdirect() returns true (1) if transparent writing was
|
||||
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
|
||||
gzdirect() is not needed when writing. Transparent writing must be
|
||||
explicitly requested, so the application already knows the answer. When
|
||||
linking statically, using gzdirect() will include all of the zlib code for
|
||||
gzip file reading and decompression, which may not be desired.)
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
must not be called more than once on the same allocation.
|
||||
|
||||
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
|
||||
file operation error, or Z_OK on success.
|
||||
file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
|
||||
last read ended in the middle of a gzip stream, or Z_OK on success.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
|
||||
@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
||||
file that is being written concurrently.
|
||||
*/
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
||||
/* checksum functions */
|
||||
|
||||
@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
||||
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
||||
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
||||
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
|
||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
|
||||
that the z_off_t type (like off_t) is a signed integer. If len2 is
|
||||
negative, the result has no meaning or utility.
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
||||
updated CRC-32. If buf is Z_NULL, this function returns the required
|
||||
initial value for the for the crc. Pre- and post-conditioning (one's
|
||||
complement) is performed within this function so it shouldn't be done by the
|
||||
application.
|
||||
initial value for the crc. Pre- and post-conditioning (one's complement) is
|
||||
performed within this function so it shouldn't be done by the application.
|
||||
|
||||
Usage example:
|
||||
|
||||
@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
const char *version,
|
||||
int stream_size));
|
||||
#define deflateInit(strm, level) \
|
||||
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
||||
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
#define inflateInit(strm) \
|
||||
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
||||
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
||||
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
||||
(strategy), ZLIB_VERSION, sizeof(z_stream))
|
||||
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
#define inflateInit2(strm, windowBits) \
|
||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
|
||||
(int)sizeof(z_stream))
|
||||
#define inflateBackInit(strm, windowBits, window) \
|
||||
inflateBackInit_((strm), (windowBits), (window), \
|
||||
ZLIB_VERSION, sizeof(z_stream))
|
||||
ZLIB_VERSION, (int)sizeof(z_stream))
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
/* gzgetc() macro and its supporting function and exposed data structure. Note
|
||||
* that the real internal state is much larger than the exposed structure.
|
||||
* This abbreviated structure exposes just enough for the gzgetc() macro. The
|
||||
* user should not mess with these exposed elements, since their names or
|
||||
* behavior could change in the future, perhaps even capriciously. They can
|
||||
* only be used by the gzgetc() macro. You have been warned.
|
||||
*/
|
||||
struct gzFile_s {
|
||||
unsigned have;
|
||||
unsigned char *next;
|
||||
z_off64_t pos;
|
||||
};
|
||||
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
||||
#ifdef Z_PREFIX_SET
|
||||
# undef z_gzgetc
|
||||
# define z_gzgetc(g) \
|
||||
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||
#else
|
||||
# define gzgetc(g) \
|
||||
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||
#endif
|
||||
|
||||
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
|
||||
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
|
||||
@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
* functions are changed to 64 bits) -- in case these are set on systems
|
||||
* without large file support, _LFS64_LARGEFILE must also be true
|
||||
*/
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
#ifdef Z_LARGE64
|
||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||
@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
|
||||
#endif
|
||||
|
||||
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
|
||||
# define gzopen gzopen64
|
||||
# define gzseek gzseek64
|
||||
# define gztell gztell64
|
||||
# define gzoffset gzoffset64
|
||||
# define adler32_combine adler32_combine64
|
||||
# define crc32_combine crc32_combine64
|
||||
# ifdef _LARGEFILE64_SOURCE
|
||||
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
|
||||
# ifdef Z_PREFIX_SET
|
||||
# define z_gzopen z_gzopen64
|
||||
# define z_gzseek z_gzseek64
|
||||
# define z_gztell z_gztell64
|
||||
# define z_gzoffset z_gzoffset64
|
||||
# define z_adler32_combine z_adler32_combine64
|
||||
# define z_crc32_combine z_crc32_combine64
|
||||
# else
|
||||
# define gzopen gzopen64
|
||||
# define gzseek gzseek64
|
||||
# define gztell gztell64
|
||||
# define gzoffset gzoffset64
|
||||
# define adler32_combine adler32_combine64
|
||||
# define crc32_combine crc32_combine64
|
||||
# endif
|
||||
# ifndef Z_LARGE64
|
||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
|
||||
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
|
||||
@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||
#endif
|
||||
|
||||
#else /* Z_SOLO */
|
||||
|
||||
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
||||
/* hack for buggy compilers */
|
||||
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
|
||||
struct internal_state {int dummy;};
|
||||
@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||
/* undocumented functions */
|
||||
ZEXTERN const char * ZEXPORT zError OF((int));
|
||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
||||
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
|
||||
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
||||
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
|
||||
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
|
||||
#if defined(_WIN32) && !defined(Z_SOLO)
|
||||
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
|
||||
const char *mode));
|
||||
#endif
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifndef Z_SOLO
|
||||
ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
|
||||
const char *format,
|
||||
va_list va));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
23
deps/zlib/zutil.c
vendored
23
deps/zlib/zutil.c
vendored
@ -1,5 +1,5 @@
|
||||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
const char * const z_errmsg[10] = {
|
||||
z_const char * const z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
@ -85,27 +85,27 @@ uLong ZEXPORT zlibCompileFlags()
|
||||
#ifdef FASTEST
|
||||
flags += 1L << 21;
|
||||
#endif
|
||||
#ifdef STDC
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifdef NO_vsnprintf
|
||||
flags += 1L << 25;
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_vsprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_vsnprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
flags += 1L << 24;
|
||||
flags += 1L << 24;
|
||||
# ifdef NO_snprintf
|
||||
flags += 1L << 25;
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_sprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_snprintf_void
|
||||
flags += 1L << 26;
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@ -181,6 +181,7 @@ void ZLIB_INTERNAL zmemzero(dest, len)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
#ifdef SYS16BIT
|
||||
|
||||
@ -316,3 +317,5 @@ void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||
}
|
||||
|
||||
#endif /* MY_ZCALLOC */
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
103
deps/zlib/zutil.h
vendored
103
deps/zlib/zutil.h
vendored
@ -1,5 +1,5 @@
|
||||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2013 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
|
||||
#ifdef HAVE_HIDDEN
|
||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||
#else
|
||||
# define ZLIB_INTERNAL
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef STDC
|
||||
#if defined(STDC) && !defined(Z_SOLO)
|
||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
@ -29,6 +29,10 @@
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
@ -40,13 +44,13 @@ typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = (char*)ERR_MSG(err), (err))
|
||||
return (strm->msg = ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
@ -78,16 +82,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -107,18 +113,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# ifdef M_I86
|
||||
# if defined(M_I86) && !defined(Z_SOLO)
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef Z_SOLO
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@ -153,14 +161,15 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
#if defined(__BORLANDC__) && !defined(MSDOS)
|
||||
#pragma warn -8004
|
||||
#pragma warn -8008
|
||||
#pragma warn -8066
|
||||
#endif
|
||||
|
||||
/* provide prototypes for these when building zlib without LFS */
|
||||
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
|
||||
#if !defined(_WIN32) && \
|
||||
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
#endif
|
||||
@ -177,42 +186,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
|
||||
/* functions */
|
||||
|
||||
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__CYGWIN__)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
# ifdef MSDOS
|
||||
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||||
but for now we just assume it doesn't. */
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef __TURBOC__
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef WIN32
|
||||
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
||||
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
||||
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __SASC
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
#ifdef VMS
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(pyr)
|
||||
#if defined(pyr) || defined(Z_SOLO)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
@ -261,14 +235,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||
unsigned size));
|
||||
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||
#ifndef Z_SOLO
|
||||
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||
unsigned size));
|
||||
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||
#endif
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
#endif /* ZUTIL_H */
|
||||
|
1
examples/.gitignore
vendored
1
examples/.gitignore
vendored
@ -9,4 +9,5 @@ log
|
||||
rev-parse
|
||||
status
|
||||
tag
|
||||
for-each-ref
|
||||
*.dSYM
|
||||
|
@ -4,6 +4,7 @@ CC = gcc
|
||||
CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
|
||||
LFLAGS = -L../build -lgit2 -lz
|
||||
APPS = general showindex diff rev-list cat-file status log rev-parse init blame tag
|
||||
APPS += for-each-ref
|
||||
|
||||
all: $(APPS)
|
||||
|
||||
|
46
examples/for-each-ref.c
Normal file
46
examples/for-each-ref.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <git2.h>
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
|
||||
static int show_ref(git_reference *ref, void *data)
|
||||
{
|
||||
git_repository *repo = data;
|
||||
git_reference *resolved = NULL;
|
||||
char hex[GIT_OID_HEXSZ+1];
|
||||
const git_oid *oid;
|
||||
git_object *obj;
|
||||
|
||||
if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
|
||||
check_lg2(git_reference_resolve(&resolved, ref),
|
||||
"Unable to resolve symbolic reference",
|
||||
git_reference_name(ref));
|
||||
|
||||
oid = git_reference_target(resolved ? resolved : ref);
|
||||
git_oid_fmt(hex, oid);
|
||||
hex[GIT_OID_HEXSZ] = 0;
|
||||
check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJ_ANY),
|
||||
"Unable to lookup object", hex);
|
||||
|
||||
printf("%s %-6s\t%s\n",
|
||||
hex,
|
||||
git_object_type2string(git_object_type(obj)),
|
||||
git_reference_name(ref));
|
||||
|
||||
if (resolved)
|
||||
git_reference_free(resolved);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
git_repository *repo;
|
||||
|
||||
if (argc != 1 || argv[1] /* silence -Wunused-parameter */)
|
||||
fatal("Sorry, no for-each-ref options supported yet", NULL);
|
||||
|
||||
check_lg2(git_repository_open(&repo, "."),
|
||||
"Could not open repository", NULL);
|
||||
check_lg2(git_reference_foreach(repo, show_ref, repo),
|
||||
"Could not iterate over references", NULL);
|
||||
return 0;
|
||||
}
|
@ -94,8 +94,8 @@ int main (int argc, char** argv)
|
||||
// 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';
|
||||
char out[GIT_OID_HEXSZ+1];
|
||||
out[GIT_OID_HEXSZ] = '\0';
|
||||
|
||||
// If you have a oid, you can easily get the hex value of the SHA as well.
|
||||
git_oid_fmt(out, &oid);
|
||||
|
@ -54,8 +54,9 @@ struct log_options {
|
||||
int min_parents, max_parents;
|
||||
git_time_t before;
|
||||
git_time_t after;
|
||||
char *author;
|
||||
char *committer;
|
||||
const char *author;
|
||||
const char *committer;
|
||||
const char *grep;
|
||||
};
|
||||
|
||||
/** utility functions that parse options and help with log output */
|
||||
@ -65,6 +66,9 @@ static void print_time(const git_time *intime, const char *prefix);
|
||||
static void print_commit(git_commit *commit);
|
||||
static int match_with_parent(git_commit *commit, int i, git_diff_options *);
|
||||
|
||||
/** utility functions for filtering */
|
||||
static int signature_matches(const git_signature *sig, const char *filter);
|
||||
static int log_message_matches(const git_commit *commit, const char *filter);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -128,6 +132,15 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!signature_matches(git_commit_author(commit), opt.author))
|
||||
continue;
|
||||
|
||||
if (!signature_matches(git_commit_committer(commit), opt.committer))
|
||||
continue;
|
||||
|
||||
if (!log_message_matches(commit, opt.grep))
|
||||
continue;
|
||||
|
||||
if (count++ < opt.skip)
|
||||
continue;
|
||||
if (opt.limit != -1 && printed++ >= opt.limit) {
|
||||
@ -172,6 +185,32 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Determine if the given git_signature does not contain the filter text. */
|
||||
static int signature_matches(const git_signature *sig, const char *filter) {
|
||||
if (filter == NULL)
|
||||
return 1;
|
||||
|
||||
if (sig != NULL &&
|
||||
(strstr(sig->name, filter) != NULL ||
|
||||
strstr(sig->email, filter) != NULL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int log_message_matches(const git_commit *commit, const char *filter) {
|
||||
const char *message = NULL;
|
||||
|
||||
if (filter == NULL)
|
||||
return 1;
|
||||
|
||||
if ((message = git_commit_message(commit)) != NULL &&
|
||||
strstr(message, filter) != NULL)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Push object (for hide or show) onto revwalker. */
|
||||
static void push_rev(struct log_state *s, git_object *obj, int hide)
|
||||
{
|
||||
@ -401,6 +440,12 @@ static int parse_options(
|
||||
set_sorting(s, GIT_SORT_TOPOLOGICAL);
|
||||
else if (!strcmp(a, "--reverse"))
|
||||
set_sorting(s, GIT_SORT_REVERSE);
|
||||
else if (match_str_arg(&opt->author, &args, "--author"))
|
||||
/** Found valid --author */;
|
||||
else if (match_str_arg(&opt->committer, &args, "--committer"))
|
||||
/** Found valid --committer */;
|
||||
else if (match_str_arg(&opt->grep, &args, "--grep"))
|
||||
/** Found valid --grep */;
|
||||
else if (match_str_arg(&s->repodir, &args, "--git-dir"))
|
||||
/** Found git-dir. */;
|
||||
else if (match_int_arg(&opt->skip, &args, "--skip", 0))
|
||||
|
@ -155,7 +155,7 @@ int fetch(git_repository *repo, int argc, char **argv)
|
||||
// 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.
|
||||
// changed but all the needed objects are available locally.
|
||||
if (git_remote_update_tips(remote, NULL, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -22,7 +22,7 @@ int main (int argc, char **argv)
|
||||
git_repository *repo;
|
||||
git_revwalk *walk;
|
||||
git_oid oid;
|
||||
char buf[41];
|
||||
char buf[GIT_OID_HEXSZ+1];
|
||||
|
||||
git_threads_init();
|
||||
|
||||
@ -32,7 +32,7 @@ int main (int argc, char **argv)
|
||||
|
||||
while (!git_revwalk_next(&oid, walk)) {
|
||||
git_oid_fmt(buf, &oid);
|
||||
buf[40] = '\0';
|
||||
buf[GIT_OID_HEXSZ] = '\0';
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@ int main (int argc, char** argv)
|
||||
unsigned int i, ecount;
|
||||
char *dir = ".";
|
||||
size_t dirlen;
|
||||
char out[41];
|
||||
out[40] = '\0';
|
||||
char out[GIT_OID_HEXSZ+1];
|
||||
out[GIT_OID_HEXSZ] = '\0';
|
||||
|
||||
git_threads_init();
|
||||
|
||||
|
@ -13,7 +13,12 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
# include <Windows.h>
|
||||
# define sleep(a) Sleep(a * 1000)
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This example demonstrates the use of the libgit2 status APIs,
|
||||
|
@ -236,7 +236,7 @@ static void action_create_tag(tag_state *state)
|
||||
git_signature_free(tagger);
|
||||
}
|
||||
|
||||
static void print_usage()
|
||||
static void print_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: see `git help tag`\n");
|
||||
exit(1);
|
||||
|
@ -76,25 +76,28 @@ GIT_BEGIN_DECL
|
||||
*/
|
||||
#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T)
|
||||
|
||||
/**
|
||||
* Possible states for an attribute
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_ATTR_UNSPECIFIED_T = 0,
|
||||
GIT_ATTR_TRUE_T,
|
||||
GIT_ATTR_FALSE_T,
|
||||
GIT_ATTR_VALUE_T,
|
||||
GIT_ATTR_UNSPECIFIED_T = 0, /**< The attribute has been left unspecified */
|
||||
GIT_ATTR_TRUE_T, /**< The attribute has been set */
|
||||
GIT_ATTR_FALSE_T, /**< The attribute has been unset */
|
||||
GIT_ATTR_VALUE_T, /**< This attribute has a value */
|
||||
} git_attr_t;
|
||||
|
||||
/*
|
||||
* Return the value type for a given attribute.
|
||||
/**
|
||||
* 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.
|
||||
* 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.
|
||||
* 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
|
||||
* @param attr The attribute
|
||||
* @return the value type for the attribute
|
||||
*/
|
||||
GIT_EXTERN(git_attr_t) git_attr_value(const char *attr);
|
||||
|
||||
|
@ -83,17 +83,16 @@ typedef struct git_blame_options {
|
||||
#define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION}
|
||||
|
||||
/**
|
||||
* Initializes a `git_blame_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_BLAME_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_blame_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_BLAME_OPTIONS_VERSION` here.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
* Initializes a `git_blame_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_BLAME_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts The `git_blame_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_BLAME_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_blame_init_options(
|
||||
git_blame_options* opts,
|
||||
int version);
|
||||
git_blame_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Structure that represents a blame hunk.
|
||||
|
@ -210,7 +210,7 @@ GIT_EXTERN(int) git_blob_create_frombuffer(
|
||||
*
|
||||
* 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.
|
||||
* to non-printable characters among the first 8000 bytes.
|
||||
*
|
||||
* @param blob The blob which content should be analyzed
|
||||
* @return 1 if the content of the blob is detected
|
||||
|
@ -105,6 +105,22 @@ GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size);
|
||||
GIT_EXTERN(int) git_buf_set(
|
||||
git_buf *buffer, const void *data, size_t datalen);
|
||||
|
||||
/**
|
||||
* Check quickly if buffer looks like it contains binary data
|
||||
*
|
||||
* @param buf Buffer to check
|
||||
* @return 1 if buffer looks like non-text data
|
||||
*/
|
||||
GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf);
|
||||
|
||||
/**
|
||||
* Check quickly if buffer contains a NUL byte
|
||||
*
|
||||
* @param buf Buffer to check
|
||||
* @return 1 if buffer contains a NUL byte
|
||||
*/
|
||||
GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
/** @} */
|
||||
|
@ -43,17 +43,17 @@ GIT_BEGIN_DECL
|
||||
* 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 | |
|
||||
* ---------------------|-----------------------|----------------------|
|
||||
* | 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
|
||||
@ -106,7 +106,7 @@ GIT_BEGIN_DECL
|
||||
* target contains that file.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_CHECKOUT_NONE = 0, /** default is a dry run, no actual updates */
|
||||
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),
|
||||
@ -233,18 +233,18 @@ typedef void (*git_checkout_progress_cb)(
|
||||
typedef struct git_checkout_options {
|
||||
unsigned int version;
|
||||
|
||||
unsigned int checkout_strategy; /** default will be a dry run */
|
||||
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 */
|
||||
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 */
|
||||
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. */
|
||||
/** Optional callback to notify the consumer of checkout progress. */
|
||||
git_checkout_progress_cb progress_cb;
|
||||
void *progress_payload;
|
||||
|
||||
@ -254,13 +254,13 @@ typedef struct git_checkout_options {
|
||||
*/
|
||||
git_strarray paths;
|
||||
|
||||
git_tree *baseline; /** expected content of workdir, defaults to HEAD */
|
||||
git_tree *baseline; /**< expected content of workdir, defaults to HEAD */
|
||||
|
||||
const char *target_directory; /** alternative checkout path to workdir */
|
||||
const char *target_directory; /**< alternative checkout path to workdir */
|
||||
|
||||
const char *ancestor_label; /** the name of the common ancestor side of conflicts */
|
||||
const char *our_label; /** the name of the "our" side of conflicts */
|
||||
const char *their_label; /** the name of the "their" side of conflicts */
|
||||
const char *ancestor_label; /**< the name of the common ancestor side of conflicts */
|
||||
const char *our_label; /**< the name of the "our" side of conflicts */
|
||||
const char *their_label; /**< the name of the "their" side of conflicts */
|
||||
} git_checkout_options;
|
||||
|
||||
#define GIT_CHECKOUT_OPTIONS_VERSION 1
|
||||
@ -270,14 +270,13 @@ typedef struct git_checkout_options {
|
||||
* Initializes a `git_checkout_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_CHECKOUT_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_checkout_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_CHECKOUT_OPTIONS_VERSION` here.
|
||||
* @param opts the `git_checkout_options` struct to initialize.
|
||||
* @param version Version of struct; pass `GIT_CHECKOUT_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_checkout_init_opts(
|
||||
git_checkout_options* opts,
|
||||
int version);
|
||||
GIT_EXTERN(int) git_checkout_init_options(
|
||||
git_checkout_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Updates files in the index and the working tree to match the content of
|
||||
|
@ -28,23 +28,22 @@ typedef struct {
|
||||
|
||||
git_merge_options merge_opts;
|
||||
git_checkout_options checkout_opts;
|
||||
} git_cherry_pick_options;
|
||||
} git_cherrypick_options;
|
||||
|
||||
#define GIT_CHERRY_PICK_OPTIONS_VERSION 1
|
||||
#define GIT_CHERRY_PICK_OPTIONS_INIT {GIT_CHERRY_PICK_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
|
||||
#define GIT_CHERRYPICK_OPTIONS_VERSION 1
|
||||
#define GIT_CHERRYPICK_OPTIONS_INIT {GIT_CHERRYPICK_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
|
||||
|
||||
/**
|
||||
* Initializes a `git_cherry_pick_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_CHERRY_PICK_OPTIONS_INIT.
|
||||
* Initializes a `git_cherrypick_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_CHERRYPICK_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_cherry_pick_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_CHERRY_PICK_OPTIONS_VERSION` here.
|
||||
* @param opts the `git_cherrypick_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_CHERRYPICK_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cherry_pick_init_opts(
|
||||
git_cherry_pick_options* opts,
|
||||
int version);
|
||||
GIT_EXTERN(int) git_cherrypick_init_options(
|
||||
git_cherrypick_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Cherry-picks the given commit against the given "our" commit, producing an
|
||||
@ -54,16 +53,16 @@ GIT_EXTERN(int) git_cherry_pick_init_opts(
|
||||
*
|
||||
* @param out pointer to store the index result in
|
||||
* @param repo the repository that contains the given commits
|
||||
* @param cherry_pick_commit the commit to cherry-pick
|
||||
* @param cherrypick_commit the commit to cherry-pick
|
||||
* @param our_commit the commit to revert against (eg, HEAD)
|
||||
* @param mainline the parent of the revert commit, if it is a merge
|
||||
* @param merge_tree_opts the merge tree options (or null for defaults)
|
||||
* @param merge_options the merge options (or null for defaults)
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cherry_pick_commit(
|
||||
GIT_EXTERN(int) git_cherrypick_commit(
|
||||
git_index **out,
|
||||
git_repository *repo,
|
||||
git_commit *cherry_pick_commit,
|
||||
git_commit *cherrypick_commit,
|
||||
git_commit *our_commit,
|
||||
unsigned int mainline,
|
||||
const git_merge_options *merge_options);
|
||||
@ -73,13 +72,13 @@ GIT_EXTERN(int) git_cherry_pick_commit(
|
||||
*
|
||||
* @param repo the repository to cherry-pick
|
||||
* @param commit the commit to cherry-pick
|
||||
* @param cherry_pick_options the cherry-pick options (or null for defaults)
|
||||
* @param cherrypick_options the cherry-pick options (or null for defaults)
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cherry_pick(
|
||||
GIT_EXTERN(int) git_cherrypick(
|
||||
git_repository *repo,
|
||||
git_commit *commit,
|
||||
const git_cherry_pick_options *cherry_pick_options);
|
||||
const git_cherrypick_options *cherrypick_options);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "indexer.h"
|
||||
#include "checkout.h"
|
||||
#include "remote.h"
|
||||
#include "transport.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -23,67 +24,176 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Options for bypassing the git-aware transport on clone. Bypassing
|
||||
* it means that instead of a fetch, libgit2 will copy the object
|
||||
* database directory instead of figuring out what it needs, which is
|
||||
* faster. If possible, it will hardlink the files to save space.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Auto-detect (default), libgit2 will bypass the git-aware
|
||||
* transport for local paths, but use a normal fetch for
|
||||
* `file://` urls.
|
||||
*/
|
||||
GIT_CLONE_LOCAL_AUTO,
|
||||
/**
|
||||
* Bypass the git-aware transport even for a `file://` url.
|
||||
*/
|
||||
GIT_CLONE_LOCAL,
|
||||
/**
|
||||
* Do no bypass the git-aware transport
|
||||
*/
|
||||
GIT_CLONE_NO_LOCAL,
|
||||
/**
|
||||
* Bypass the git-aware transport, but do not try to use
|
||||
* hardlinks.
|
||||
*/
|
||||
GIT_CLONE_LOCAL_NO_LINKS,
|
||||
} git_clone_local_t;
|
||||
|
||||
/**
|
||||
* The signature of a function matching git_remote_create, with an additional
|
||||
* void* as a callback payload.
|
||||
*
|
||||
* Callers of git_clone may provide a function matching this signature to override
|
||||
* the remote creation and customization process during a clone operation.
|
||||
*
|
||||
* @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 payload an opaque payload
|
||||
* @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
|
||||
*/
|
||||
typedef int (*git_remote_create_cb)(
|
||||
git_remote **out,
|
||||
git_repository *repo,
|
||||
const char *name,
|
||||
const char *url,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* The signature of a function matchin git_repository_init, with an
|
||||
* aditional void * as callback payload.
|
||||
*
|
||||
* Callers of git_clone my provide a function matching this signature
|
||||
* to override the repository creation and customization process
|
||||
* during a clone operation.
|
||||
*
|
||||
* @param out the resulting repository
|
||||
* @param path path in which to create the repository
|
||||
* @param bare whether the repository is bare. This is the value from the clone options
|
||||
* @param payload payload specified by the options
|
||||
* @return 0, or a negative value to indicate error
|
||||
*/
|
||||
typedef int (*git_repository_create_cb)(
|
||||
git_repository **out,
|
||||
const char *path,
|
||||
int bare,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Clone options structure
|
||||
*
|
||||
* Use the GIT_CLONE_OPTIONS_INIT to get the default settings, like this:
|
||||
*
|
||||
* git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
|
||||
*
|
||||
* - `checkout_opts` are option passed to the checkout step. To disable
|
||||
* checkout, set the `checkout_strategy` to GIT_CHECKOUT_NONE.
|
||||
* Generally you will want the use GIT_CHECKOUT_SAFE_CREATE to create
|
||||
* all files in the working directory for the newly cloned repository.
|
||||
* - `bare` should be set to zero (false) to create a standard repo,
|
||||
* or non-zero for a bare repo
|
||||
* - `ignore_cert_errors` should be set to 1 if errors validating the
|
||||
* remote host's certificate should be ignored.
|
||||
*
|
||||
* ** "origin" remote options: **
|
||||
*
|
||||
* - `remote_name` is the name to be given to the "origin" remote. The
|
||||
* default is "origin".
|
||||
* - `checkout_branch` gives the name of the branch to checkout. NULL
|
||||
* means use the remote's HEAD.
|
||||
* - `signature` is the identity used when updating the reflog. NULL means to
|
||||
* use the default signature using the config.
|
||||
*/
|
||||
|
||||
typedef struct git_clone_options {
|
||||
unsigned int version;
|
||||
|
||||
/**
|
||||
* These options are passed to the checkout step. To disable
|
||||
* checkout, set the `checkout_strategy` to
|
||||
* `GIT_CHECKOUT_NONE`. Generally you will want the use
|
||||
* GIT_CHECKOUT_SAFE_CREATE to create all files in the working
|
||||
* directory for the newly cloned repository.
|
||||
*/
|
||||
git_checkout_options checkout_opts;
|
||||
|
||||
/**
|
||||
* Callbacks to use for reporting fetch progress, and for acquiring
|
||||
* credentials in the event they are needed. This parameter is ignored if
|
||||
* the remote_cb parameter is set; if you provide a remote creation
|
||||
* callback, then you have the opportunity to configure remote callbacks in
|
||||
* provided function.
|
||||
*/
|
||||
git_remote_callbacks remote_callbacks;
|
||||
|
||||
/**
|
||||
* Set to zero (false) to create a standard repo, or non-zero
|
||||
* for a bare repo
|
||||
*/
|
||||
int bare;
|
||||
int ignore_cert_errors;
|
||||
const char *remote_name;
|
||||
|
||||
/**
|
||||
* Whether to use a fetch or copy the object database.
|
||||
*/
|
||||
git_clone_local_t local;
|
||||
|
||||
/**
|
||||
* The name of the branch to checkout. NULL means use the
|
||||
* remote's default branch.
|
||||
*/
|
||||
const char* checkout_branch;
|
||||
|
||||
/**
|
||||
* The identity used when updating the reflog. NULL means to
|
||||
* use the default signature using the config.
|
||||
*/
|
||||
git_signature *signature;
|
||||
|
||||
/**
|
||||
* A callback used to create the new repository into which to
|
||||
* clone. If NULL, the 'bare' field will be used to determine
|
||||
* whether to create a bare repository.
|
||||
*/
|
||||
git_repository_create_cb repository_cb;
|
||||
|
||||
/**
|
||||
* An opaque payload to pass to the git_repository creation callback.
|
||||
* This parameter is ignored unless repository_cb is non-NULL.
|
||||
*/
|
||||
void *repository_cb_payload;
|
||||
|
||||
/**
|
||||
* A callback used to create the git_remote, prior to its being
|
||||
* used to perform the clone operation. See the documentation for
|
||||
* git_remote_create_cb for details. This parameter may be NULL,
|
||||
* indicating that git_clone should provide default behavior.
|
||||
*/
|
||||
git_remote_create_cb remote_cb;
|
||||
|
||||
/**
|
||||
* An opaque payload to pass to the git_remote creation callback.
|
||||
* This parameter is ignored unless remote_cb is non-NULL.
|
||||
*/
|
||||
void *remote_cb_payload;
|
||||
} git_clone_options;
|
||||
|
||||
#define GIT_CLONE_OPTIONS_VERSION 1
|
||||
#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE_CREATE}, GIT_REMOTE_CALLBACKS_INIT}
|
||||
|
||||
/**
|
||||
* Initializes a `git_clone_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_CLONE_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_clone_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_CLONE_OPTIONS_VERSION` here.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
* Initializes a `git_clone_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_CLONE_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts The `git_clone_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_CLONE_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_clone_init_options(
|
||||
git_clone_options* opts,
|
||||
int version);
|
||||
git_clone_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Clone a remote repository.
|
||||
*
|
||||
* This version handles the simple case. If you'd like to create the
|
||||
* repository or remote with non-default settings, you can create and
|
||||
* configure them and then use `git_clone_into()`.
|
||||
* By default this creates its repository and initial remote to match
|
||||
* git's defaults. You can use the options in the callback to
|
||||
* customize how these are created.
|
||||
*
|
||||
* @param out pointer that will receive the resulting repository object
|
||||
* @param url the remote repository to clone
|
||||
@ -100,30 +210,6 @@ GIT_EXTERN(int) git_clone(
|
||||
const char *local_path,
|
||||
const git_clone_options *options);
|
||||
|
||||
/**
|
||||
* Clone into a repository
|
||||
*
|
||||
* After creating the repository and remote and configuring them for
|
||||
* paths and callbacks respectively, you can call this function to
|
||||
* perform the clone operation and optionally checkout files.
|
||||
*
|
||||
* @param repo the repository to use
|
||||
* @param remote the remote repository to clone from
|
||||
* @param co_opts options to use during checkout
|
||||
* @param branch the branch to checkout after the clone, pass NULL for the
|
||||
* remote's default branch
|
||||
* @param signature The identity used when updating the reflog.
|
||||
* @return 0 on success, any non-zero return value from a callback
|
||||
* function, or a negative value to indicate an error (use
|
||||
* `giterr_last` for a detailed error message)
|
||||
*/
|
||||
GIT_EXTERN(int) git_clone_into(
|
||||
git_repository *repo,
|
||||
git_remote *remote,
|
||||
const git_checkout_options *co_opts,
|
||||
const char *branch,
|
||||
const git_signature *signature);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -254,7 +254,8 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
|
||||
* is not direct, it will be resolved to a direct reference.
|
||||
* Use "HEAD" to update the HEAD of the current branch and
|
||||
* make it point to this commit. If the reference doesn't
|
||||
* exist yet, it will be created.
|
||||
* exist yet, it will be created. If it does exist, the first
|
||||
* parent must be the tip of this branch.
|
||||
*
|
||||
* @param author Signature with author and author time of commit
|
||||
*
|
||||
@ -329,7 +330,7 @@ GIT_EXTERN(int) git_commit_create_v(
|
||||
*
|
||||
* The `update_ref` value works as in the regular `git_commit_create()`,
|
||||
* updating the ref to point to the newly rewritten commit. If you want
|
||||
* to amend a commit that is not currently the HEAD of the branch and then
|
||||
* to amend a commit that is not currently the tip of the branch and then
|
||||
* rewrite the following commits to reach a ref, pass this as NULL and
|
||||
* update the rest of the commit chain and ref separately.
|
||||
*
|
||||
|
@ -226,6 +226,22 @@ GIT_EXTERN(int) git_config_open_level(
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config);
|
||||
|
||||
/**
|
||||
* Create a snapshot of the configuration
|
||||
*
|
||||
* Create a snapshot of the current state of a configuration, which
|
||||
* allows you to look into a consistent view of the configuration for
|
||||
* looking up complex values (e.g. a remote, submodule).
|
||||
*
|
||||
* The string returned when querying such a config object is valid
|
||||
* until it is freed.
|
||||
*
|
||||
* @param out pointer in which to store the snapshot config object
|
||||
* @param config configuration to snapshot
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_snapshot(git_config **out, git_config *config);
|
||||
|
||||
|
||||
/**
|
||||
* Reload changed config files
|
||||
@ -312,7 +328,8 @@ GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char
|
||||
* Get the value of a string config variable.
|
||||
*
|
||||
* The string is owned by the variable and should not be freed by the
|
||||
* user.
|
||||
* user. The pointer will be valid until the next operation on this
|
||||
* config object.
|
||||
*
|
||||
* All config files will be looked into, in the order of their
|
||||
* defined level. A higher level means a higher priority. The
|
||||
@ -353,6 +370,9 @@ GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, cons
|
||||
/**
|
||||
* Return the current entry and advance the iterator
|
||||
*
|
||||
* The pointers returned by this function are valid until the iterator
|
||||
* is freed.
|
||||
*
|
||||
* @param entry pointer to store the entry
|
||||
* @param iter the iterator
|
||||
* @return 0 or an error code. GIT_ITEROVER if the iteration has completed
|
||||
@ -451,6 +471,9 @@ GIT_EXTERN(int) git_config_delete_multivar(git_config *cfg, const char *name, co
|
||||
* If the callback returns a non-zero value, the function stops iterating
|
||||
* and returns that value to the caller.
|
||||
*
|
||||
* The pointers passed to the callback are only valid as long as the
|
||||
* iteration is ongoing.
|
||||
*
|
||||
* @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
|
||||
@ -491,6 +514,9 @@ GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const gi
|
||||
* regular expression that filters which config keys are passed to the
|
||||
* callback.
|
||||
*
|
||||
* The pointers passed to the callback are only valid as long as the
|
||||
* iteration is ongoing.
|
||||
*
|
||||
* @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
|
||||
|
@ -145,6 +145,19 @@ typedef enum {
|
||||
*/
|
||||
GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = (1u << 14),
|
||||
|
||||
/** When diff finds a file in the working directory with stat
|
||||
* information different from the index, but the OID ends up being the
|
||||
* same, write the correct stat information into the index. Note:
|
||||
* without this flag, diff will always leave the index untouched.
|
||||
*/
|
||||
GIT_DIFF_UPDATE_INDEX = (1u << 15),
|
||||
|
||||
/** Include unreadable files in the diff */
|
||||
GIT_DIFF_INCLUDE_UNREADABLE = (1u << 16),
|
||||
|
||||
/** Include unreadable files in the diff */
|
||||
GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 17),
|
||||
|
||||
/*
|
||||
* Options controlling how output will be generated
|
||||
*/
|
||||
@ -205,9 +218,9 @@ typedef struct git_diff git_diff;
|
||||
* considered reserved for internal or future use.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_DIFF_FLAG_BINARY = (1u << 0), /** file(s) treated as binary data */
|
||||
GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /** file(s) treated as text data */
|
||||
GIT_DIFF_FLAG_VALID_ID = (1u << 2), /** `id` value is known correct */
|
||||
GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */
|
||||
GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */
|
||||
GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */
|
||||
} git_diff_flag_t;
|
||||
|
||||
/**
|
||||
@ -221,15 +234,16 @@ typedef enum {
|
||||
* DELETED pairs).
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_DELTA_UNMODIFIED = 0, /** no changes */
|
||||
GIT_DELTA_ADDED = 1, /** entry does not exist in old version */
|
||||
GIT_DELTA_DELETED = 2, /** entry does not exist in new version */
|
||||
GIT_DELTA_MODIFIED = 3, /** entry content changed between old and new */
|
||||
GIT_DELTA_RENAMED = 4, /** entry was renamed between old and new */
|
||||
GIT_DELTA_COPIED = 5, /** entry was copied from another old entry */
|
||||
GIT_DELTA_IGNORED = 6, /** entry is ignored item in workdir */
|
||||
GIT_DELTA_UNTRACKED = 7, /** entry is untracked item in workdir */
|
||||
GIT_DELTA_TYPECHANGE = 8, /** type of entry changed between old and new */
|
||||
GIT_DELTA_UNMODIFIED = 0, /**< no changes */
|
||||
GIT_DELTA_ADDED = 1, /**< entry does not exist in old version */
|
||||
GIT_DELTA_DELETED = 2, /**< entry does not exist in new version */
|
||||
GIT_DELTA_MODIFIED = 3, /**< entry content changed between old and new */
|
||||
GIT_DELTA_RENAMED = 4, /**< entry was renamed between old and new */
|
||||
GIT_DELTA_COPIED = 5, /**< entry was copied from another old entry */
|
||||
GIT_DELTA_IGNORED = 6, /**< entry is ignored item in workdir */
|
||||
GIT_DELTA_UNTRACKED = 7, /**< entry is untracked item in workdir */
|
||||
GIT_DELTA_TYPECHANGE = 8, /**< type of entry changed between old and new */
|
||||
GIT_DELTA_UNREADABLE = 9, /**< entry is unreadable */
|
||||
} git_delta_t;
|
||||
|
||||
/**
|
||||
@ -381,17 +395,16 @@ typedef struct {
|
||||
{GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_DEFAULT, {NULL,0}, NULL, NULL, 3}
|
||||
|
||||
/**
|
||||
* Initializes a `git_diff_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_DIFF_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_diff_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_DIFF_OPTIONS_VERSION` here.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
* Initializes a `git_diff_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_DIFF_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts The `git_diff_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_DIFF_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_diff_init_options(
|
||||
git_diff_options* opts,
|
||||
int version);
|
||||
git_diff_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* When iterating over a diff, callback that will be made per file.
|
||||
@ -410,12 +423,12 @@ typedef int (*git_diff_file_cb)(
|
||||
*/
|
||||
typedef struct git_diff_hunk git_diff_hunk;
|
||||
struct git_diff_hunk {
|
||||
int old_start; /** Starting line number in old_file */
|
||||
int old_lines; /** Number of lines in old_file */
|
||||
int new_start; /** Starting line number in new_file */
|
||||
int new_lines; /** Number of lines in new_file */
|
||||
size_t header_len; /** Number of bytes in header text */
|
||||
char header[128]; /** Header text, NUL-byte terminated */
|
||||
int old_start; /**< Starting line number in old_file */
|
||||
int old_lines; /**< Number of lines in old_file */
|
||||
int new_start; /**< Starting line number in new_file */
|
||||
int new_lines; /**< Number of lines in new_file */
|
||||
size_t header_len; /**< Number of bytes in header text */
|
||||
char header[128]; /**< Header text, NUL-byte terminated */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -458,13 +471,13 @@ typedef enum {
|
||||
*/
|
||||
typedef struct git_diff_line git_diff_line;
|
||||
struct git_diff_line {
|
||||
char origin; /** A git_diff_line_t value */
|
||||
int old_lineno; /** Line number in old file or -1 for added line */
|
||||
int new_lineno; /** Line number in new file or -1 for deleted line */
|
||||
int num_lines; /** Number of newline characters in content */
|
||||
size_t content_len; /** Number of bytes of data */
|
||||
git_off_t content_offset; /** Offset in the original file to the content */
|
||||
const char *content; /** Pointer to diff text, not NUL-byte terminated */
|
||||
char origin; /**< A git_diff_line_t value */
|
||||
int old_lineno; /**< Line number in old file or -1 for added line */
|
||||
int new_lineno; /**< Line number in new file or -1 for deleted line */
|
||||
int num_lines; /**< Number of newline characters in content */
|
||||
size_t content_len; /**< Number of bytes of data */
|
||||
git_off_t content_offset; /**< Offset in the original file to the content */
|
||||
const char *content; /**< Pointer to diff text, not NUL-byte terminated */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -476,10 +489,10 @@ struct git_diff_line {
|
||||
* of lines of file and hunk headers.
|
||||
*/
|
||||
typedef int (*git_diff_line_cb)(
|
||||
const git_diff_delta *delta, /** delta that contains this data */
|
||||
const git_diff_hunk *hunk, /** hunk containing this data */
|
||||
const git_diff_line *line, /** line data */
|
||||
void *payload); /** user reference data */
|
||||
const git_diff_delta *delta, /**< delta that contains this data */
|
||||
const git_diff_hunk *hunk, /**< hunk containing this data */
|
||||
const git_diff_line *line, /**< line data */
|
||||
void *payload); /**< user reference data */
|
||||
|
||||
/**
|
||||
* Flags to control the behavior of diff rename/copy detection.
|
||||
@ -622,17 +635,16 @@ typedef struct {
|
||||
#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION}
|
||||
|
||||
/**
|
||||
* Initializes a `git_diff_find_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_DIFF_FIND_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_diff_find_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_DIFF_FIND_OPTIONS_VERSION` here.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
* Initializes a `git_diff_find_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_DIFF_FIND_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts The `git_diff_find_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_DIFF_FIND_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_diff_find_init_options(
|
||||
git_diff_find_options* opts,
|
||||
int version);
|
||||
git_diff_find_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/** @name Diff Generator Functions
|
||||
*
|
||||
@ -804,23 +816,6 @@ GIT_EXTERN(int) git_diff_find_similar(
|
||||
git_diff *diff,
|
||||
const git_diff_find_options *options);
|
||||
|
||||
/**
|
||||
* Initialize diff options structure
|
||||
*
|
||||
* In most cases, you can probably just use `GIT_DIFF_OPTIONS_INIT` to
|
||||
* initialize the diff options structure, but in some cases that is not
|
||||
* going to work. You can call this function instead. Note that you
|
||||
* must pass both a pointer to the structure to be initialized and the
|
||||
* `GIT_DIFF_OPTIONS_VERSION` value from the header you compiled with.
|
||||
*
|
||||
* @param options Pointer to git_diff_options memory to be initialized
|
||||
* @param version Should be `GIT_DIFF_OPTIONS_VERSION`
|
||||
* @return 0 on success, negative on failure (such as unsupported version)
|
||||
*/
|
||||
GIT_EXTERN(int) git_diff_options_init(
|
||||
git_diff_options *options,
|
||||
unsigned int version);
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
@ -1233,17 +1228,17 @@ GIT_EXTERN(int) git_diff_commit_as_email(
|
||||
const git_diff_options *diff_opts);
|
||||
|
||||
/**
|
||||
* Initializes a `git_diff_format_email_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_diff_format_email_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION` here.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
* Initializes a `git_diff_format_email_options` with default values.
|
||||
*
|
||||
* Equivalent to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts The `git_diff_format_email_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_diff_format_email_init_options(
|
||||
git_diff_format_email_options *opts,
|
||||
int version);
|
||||
unsigned int version);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
|
@ -19,13 +19,13 @@ GIT_BEGIN_DECL
|
||||
|
||||
/** Generic return codes */
|
||||
typedef enum {
|
||||
GIT_OK = 0, /*< No error */
|
||||
GIT_OK = 0, /**< No error */
|
||||
|
||||
GIT_ERROR = -1, /*< Generic error */
|
||||
GIT_ENOTFOUND = -3, /*< Requested object could not be found */
|
||||
GIT_EEXISTS = -4, /*< Object exists preventing operation */
|
||||
GIT_EAMBIGUOUS = -5, /*< More than one object matches */
|
||||
GIT_EBUFS = -6, /*< Output buffer too short to hold data */
|
||||
GIT_ERROR = -1, /**< Generic error */
|
||||
GIT_ENOTFOUND = -3, /**< Requested object could not be found */
|
||||
GIT_EEXISTS = -4, /**< Object exists preventing operation */
|
||||
GIT_EAMBIGUOUS = -5, /**< More than one object matches */
|
||||
GIT_EBUFS = -6, /**< Output buffer too short to hold data */
|
||||
|
||||
/* GIT_EUSER is a special error that is never generated by libgit2
|
||||
* code. You can return it from a callback (e.g to stop an iteration)
|
||||
@ -33,17 +33,19 @@ typedef enum {
|
||||
*/
|
||||
GIT_EUSER = -7,
|
||||
|
||||
GIT_EBAREREPO = -8, /*< Operation not allowed on bare repository */
|
||||
GIT_EUNBORNBRANCH = -9, /*< HEAD refers to branch with no commits */
|
||||
GIT_EUNMERGED = -10, /*< Merge in progress prevented operation */
|
||||
GIT_ENONFASTFORWARD = -11, /*< Reference was not fast-forwardable */
|
||||
GIT_EINVALIDSPEC = -12, /*< Name/ref spec was not in a valid format */
|
||||
GIT_EMERGECONFLICT = -13, /*< Merge conflicts prevented operation */
|
||||
GIT_ELOCKED = -14, /*< Lock file prevented operation */
|
||||
GIT_EMODIFIED = -15, /*< Reference value does not match expected */
|
||||
GIT_EBAREREPO = -8, /**< Operation not allowed on bare repository */
|
||||
GIT_EUNBORNBRANCH = -9, /**< HEAD refers to branch with no commits */
|
||||
GIT_EUNMERGED = -10, /**< Merge in progress prevented operation */
|
||||
GIT_ENONFASTFORWARD = -11, /**< Reference was not fast-forwardable */
|
||||
GIT_EINVALIDSPEC = -12, /**< Name/ref spec was not in a valid format */
|
||||
GIT_EMERGECONFLICT = -13, /**< Merge conflicts prevented operation */
|
||||
GIT_ELOCKED = -14, /**< Lock file prevented operation */
|
||||
GIT_EMODIFIED = -15, /**< Reference value does not match expected */
|
||||
GIT_EAUTH = -16, /**< Authentication error */
|
||||
GIT_ECERTIFICATE = -17, /**< Server certificate is invalid */
|
||||
|
||||
GIT_PASSTHROUGH = -30, /*< Internal only */
|
||||
GIT_ITEROVER = -31, /*< Signals end of iteration with iterator */
|
||||
GIT_PASSTHROUGH = -30, /**< Internal only */
|
||||
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
|
||||
} git_error_code;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +35,11 @@ typedef enum {
|
||||
GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB,
|
||||
} git_filter_mode_t;
|
||||
|
||||
typedef enum {
|
||||
GIT_FILTER_OPT_DEFAULT = 0u,
|
||||
GIT_FILTER_OPT_ALLOW_UNSAFE = (1u << 0),
|
||||
} git_filter_opt_t;
|
||||
|
||||
/**
|
||||
* A filter that can transform file data
|
||||
*
|
||||
@ -75,6 +80,7 @@ typedef struct git_filter_list git_filter_list;
|
||||
* @param blob The blob to which the filter will be applied (if known)
|
||||
* @param path Relative path of the file to be filtered
|
||||
* @param mode Filtering direction (WT->ODB or ODB->WT)
|
||||
* @param options Combination of `git_filter_opt_t` flags
|
||||
* @return 0 on success (which could still return NULL if no filters are
|
||||
* needed for the requested file), <0 on error
|
||||
*/
|
||||
@ -83,7 +89,8 @@ GIT_EXTERN(int) git_filter_list_load(
|
||||
git_repository *repo,
|
||||
git_blob *blob, /* can be NULL */
|
||||
const char *path,
|
||||
git_filter_mode_t mode);
|
||||
git_filter_mode_t mode,
|
||||
uint32_t options);
|
||||
|
||||
/**
|
||||
* Apply filter list to a data buffer.
|
||||
|
@ -61,7 +61,7 @@ typedef struct git_index_entry {
|
||||
unsigned short flags;
|
||||
unsigned short flags_extended;
|
||||
|
||||
char *path;
|
||||
const char *path;
|
||||
} git_index_entry;
|
||||
|
||||
/**
|
||||
@ -73,10 +73,13 @@ typedef struct git_index_entry {
|
||||
*/
|
||||
#define GIT_IDXENTRY_NAMEMASK (0x0fff)
|
||||
#define GIT_IDXENTRY_STAGEMASK (0x3000)
|
||||
#define GIT_IDXENTRY_EXTENDED (0x4000)
|
||||
#define GIT_IDXENTRY_VALID (0x8000)
|
||||
#define GIT_IDXENTRY_STAGESHIFT 12
|
||||
|
||||
typedef enum {
|
||||
GIT_IDXENTRY_EXTENDED = (0x4000),
|
||||
GIT_IDXENTRY_VALID = (0x8000),
|
||||
} git_indxentry_flag_t;
|
||||
|
||||
#define GIT_IDXENTRY_STAGE(E) \
|
||||
(((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
|
||||
|
||||
@ -92,36 +95,36 @@ typedef struct git_index_entry {
|
||||
* in-memory only and used by libgit2. Only the flags in
|
||||
* `GIT_IDXENTRY_EXTENDED_FLAGS` will get saved on-disk.
|
||||
*
|
||||
* These bitmasks match the three fields in the `git_index_entry`
|
||||
* `flags_extended` value that belong on disk. You can use them to
|
||||
* interpret the data in the `flags_extended`.
|
||||
*/
|
||||
#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13)
|
||||
#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14)
|
||||
/* GIT_IDXENTRY_EXTENDED2 is reserved for future extension */
|
||||
#define GIT_IDXENTRY_EXTENDED2 (1 << 15)
|
||||
|
||||
#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
|
||||
|
||||
/**
|
||||
* Bitmasks for in-memory only fields of `git_index_entry`'s `flags_extended`
|
||||
*
|
||||
* These bitmasks match the other fields in the `git_index_entry`
|
||||
* `flags_extended` value that are only used in-memory by libgit2. You
|
||||
* Thee first three bitmasks match the three fields in the
|
||||
* `git_index_entry` `flags_extended` value that belong on disk. You
|
||||
* can use them to interpret the data in the `flags_extended`.
|
||||
*
|
||||
* The rest of the bitmasks match the other fields in the `git_index_entry`
|
||||
* `flags_extended` value that are only used in-memory by libgit2.
|
||||
* You can use them to interpret the data in the `flags_extended`.
|
||||
*
|
||||
*/
|
||||
#define GIT_IDXENTRY_UPDATE (1 << 0)
|
||||
#define GIT_IDXENTRY_REMOVE (1 << 1)
|
||||
#define GIT_IDXENTRY_UPTODATE (1 << 2)
|
||||
#define GIT_IDXENTRY_ADDED (1 << 3)
|
||||
typedef enum {
|
||||
|
||||
#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)
|
||||
GIT_IDXENTRY_INTENT_TO_ADD = (1 << 13),
|
||||
GIT_IDXENTRY_SKIP_WORKTREE = (1 << 14),
|
||||
/** Reserved for future extension */
|
||||
GIT_IDXENTRY_EXTENDED2 = (1 << 15),
|
||||
|
||||
#define GIT_IDXENTRY_UNPACKED (1 << 8)
|
||||
#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9)
|
||||
GIT_IDXENTRY_EXTENDED_FLAGS = (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE),
|
||||
GIT_IDXENTRY_UPDATE = (1 << 0),
|
||||
GIT_IDXENTRY_REMOVE = (1 << 1),
|
||||
GIT_IDXENTRY_UPTODATE = (1 << 2),
|
||||
GIT_IDXENTRY_ADDED = (1 << 3),
|
||||
|
||||
GIT_IDXENTRY_HASHED = (1 << 4),
|
||||
GIT_IDXENTRY_UNHASHED = (1 << 5),
|
||||
GIT_IDXENTRY_WT_REMOVE = (1 << 6), /**< remove in work directory */
|
||||
GIT_IDXENTRY_CONFLICTED = (1 << 7),
|
||||
|
||||
GIT_IDXENTRY_UNPACKED = (1 << 8),
|
||||
GIT_IDXENTRY_NEW_SKIP_WORKTREE = (1 << 9),
|
||||
} git_idxentry_extended_flag_t;
|
||||
|
||||
/** Capabilities of system that affect index actions. */
|
||||
typedef enum {
|
||||
@ -412,10 +415,10 @@ GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_en
|
||||
*
|
||||
* This entry is calculated from the entry's flag attribute like this:
|
||||
*
|
||||
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
|
||||
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
|
||||
*
|
||||
* @param entry The entry
|
||||
* @returns the stage number
|
||||
* @return the stage number
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "oidarray.h"
|
||||
#include "checkout.h"
|
||||
#include "index.h"
|
||||
|
||||
@ -57,11 +58,11 @@ typedef struct {
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_file_init_input(
|
||||
git_merge_file_input *opts,
|
||||
int version);
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Flags for `git_merge_tree` options. A combination of these flags can be
|
||||
* passed in via the `flags` value in the `git_merge_tree_opts`.
|
||||
* passed in via the `flags` value in the `git_merge_options`.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
@ -73,7 +74,7 @@ typedef enum {
|
||||
} git_merge_tree_flag_t;
|
||||
|
||||
/**
|
||||
* Merge file favor options for `git_merge_trees_opts` instruct the file-level
|
||||
* Merge file favor options for `git_merge_options` instruct the file-level
|
||||
* merging functionality how to deal with conflicting regions of the files.
|
||||
*/
|
||||
typedef enum {
|
||||
@ -164,7 +165,7 @@ typedef struct {
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_file_init_options(
|
||||
git_merge_file_options *opts,
|
||||
int version);
|
||||
unsigned int version);
|
||||
|
||||
typedef struct {
|
||||
/**
|
||||
@ -232,7 +233,7 @@ typedef struct {
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_init_options(
|
||||
git_merge_options *opts,
|
||||
int version);
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* The results of `git_merge_analysis` indicate the merge opportunities.
|
||||
@ -268,6 +269,26 @@ typedef enum {
|
||||
GIT_MERGE_ANALYSIS_UNBORN = (1 << 3),
|
||||
} git_merge_analysis_t;
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* No configuration was found that suggests a preferred behavior for
|
||||
* merge.
|
||||
*/
|
||||
GIT_MERGE_PREFERENCE_NONE = 0,
|
||||
|
||||
/**
|
||||
* There is a `merge.ff=false` configuration setting, suggesting that
|
||||
* the user does not want to allow a fast-forward merge.
|
||||
*/
|
||||
GIT_MERGE_PREFERENCE_NO_FASTFORWARD = (1 << 0),
|
||||
|
||||
/**
|
||||
* There is a `merge.ff=only` configuration setting, suggesting that
|
||||
* the user only wants fast-forward merges.
|
||||
*/
|
||||
GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1),
|
||||
} git_merge_preference_t;
|
||||
|
||||
/**
|
||||
* Analyzes the given branch(es) and determines the opportunities for
|
||||
* merging them into the HEAD of the repository.
|
||||
@ -280,6 +301,7 @@ typedef enum {
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_analysis(
|
||||
git_merge_analysis_t *analysis_out,
|
||||
git_merge_preference_t *preference_out,
|
||||
git_repository *repo,
|
||||
const git_merge_head **their_heads,
|
||||
size_t their_heads_len);
|
||||
@ -299,6 +321,21 @@ GIT_EXTERN(int) git_merge_base(
|
||||
const git_oid *one,
|
||||
const git_oid *two);
|
||||
|
||||
/**
|
||||
* Find merge bases between two commits
|
||||
*
|
||||
* @param out array in which to store the resulting ids
|
||||
* @param repo the repository where the commits exist
|
||||
* @param one one of the commits
|
||||
* @param two the other commit
|
||||
* @return 0 on success, GIT_ENOTFOUND if not found or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_bases(
|
||||
git_oidarray *out,
|
||||
git_repository *repo,
|
||||
const git_oid *one,
|
||||
const git_oid *two);
|
||||
|
||||
/**
|
||||
* Find a merge base given a list of commits
|
||||
*
|
||||
@ -378,8 +415,8 @@ GIT_EXTERN(int) git_merge_head_from_id(
|
||||
/**
|
||||
* Gets the commit ID that the given `git_merge_head` refers to.
|
||||
*
|
||||
* @param id pointer to commit id to be filled in
|
||||
* @param head the given merge head
|
||||
* @return commit id
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_merge_head_id(
|
||||
const git_merge_head *head);
|
||||
@ -424,8 +461,8 @@ GIT_EXTERN(int) git_merge_file(
|
||||
* @param out The git_merge_file_result to be filled in
|
||||
* @param repo The repository
|
||||
* @param ancestor The index entry for the ancestor file (stage level 1)
|
||||
* @param our_path The index entry for our file (stage level 2)
|
||||
* @param their_path The index entry for their file (stage level 3)
|
||||
* @param ours The index entry for our file (stage level 2)
|
||||
* @param theirs The index entry for their file (stage level 3)
|
||||
* @param opts The merge file options or NULL
|
||||
* @return 0 on success or error code
|
||||
*/
|
||||
@ -497,8 +534,8 @@ GIT_EXTERN(int) git_merge_commits(
|
||||
* completes, resolve any conflicts and prepare a commit.
|
||||
*
|
||||
* @param repo the repository to merge
|
||||
* @param merge_heads the heads to merge into
|
||||
* @param merge_heads_len the number of heads to merge
|
||||
* @param their_heads the heads to merge into
|
||||
* @param their_heads_len the number of heads to merge
|
||||
* @param merge_opts merge options
|
||||
* @param checkout_opts checkout options
|
||||
* @return 0 on success or error code
|
||||
|
@ -29,12 +29,14 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param message The message to be prettified.
|
||||
*
|
||||
* @param strip_comments Non-zero to remove lines starting with "#", 0 to
|
||||
* leave them in.
|
||||
* @param strip_comments Non-zero to remove comment lines, 0 to leave them in.
|
||||
*
|
||||
* @param comment_char Comment character. Lines starting with this character
|
||||
* are considered to be comments and removed if `strip_comments` is non-zero.
|
||||
*
|
||||
* @return 0 or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments);
|
||||
GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -41,6 +41,11 @@ struct git_remote_head {
|
||||
git_oid oid;
|
||||
git_oid loid;
|
||||
char *name;
|
||||
/**
|
||||
* If the server send a symref mapping for this ref, this will
|
||||
* point to the target.
|
||||
*/
|
||||
char *symref_target;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,11 @@ GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj);
|
||||
/**
|
||||
* Get a short abbreviated OID string for the object
|
||||
*
|
||||
* This starts at the "core.abbrev" length (default 7 characters) and
|
||||
* iteratively extends to a longer string if that length is ambiguous.
|
||||
* The result will be unambiguous (at least until new objects are added to
|
||||
* the repository).
|
||||
*
|
||||
* @param out Buffer to write string into
|
||||
* @param obj The object to get an ID for
|
||||
* @return 0 on success, <0 for error
|
||||
|
@ -116,13 +116,17 @@ GIT_EXTERN(void) git_oid_nfmt(char *out, size_t n, const git_oid *id);
|
||||
GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a newly allocated c-string.
|
||||
* Format a git_oid into a statically allocated c-string.
|
||||
*
|
||||
* The c-string is owned by the library and should not be freed
|
||||
* by the user. If libgit2 is built with thread support, the string
|
||||
* will be stored in TLS (i.e. one buffer per thread) to allow for
|
||||
* concurrent calls of the function.
|
||||
*
|
||||
* @param id the oid structure to format
|
||||
* @return the c-string; NULL if memory is exhausted. Caller must
|
||||
* deallocate the string with git__free().
|
||||
* @return the c-string
|
||||
*/
|
||||
GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id);
|
||||
GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a buffer as a hex format c-string.
|
||||
|
40
include/git2/oidarray.h
Normal file
40
include/git2/oidarray.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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_oidarray_h__
|
||||
#define INCLUDE_git_oidarray_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "oid.h"
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/** Array of object ids */
|
||||
typedef struct git_oidarray {
|
||||
git_oid *ids;
|
||||
size_t count;
|
||||
} git_oidarray;
|
||||
|
||||
/**
|
||||
* Free the OID array
|
||||
*
|
||||
* This method must (and must only) be called on `git_oidarray`
|
||||
* objects where the array is allocated by the library. Not doing so,
|
||||
* will result in a memory leak.
|
||||
*
|
||||
* This does not free the `git_oidarray` 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_oidarray from which to free oid data
|
||||
*/
|
||||
GIT_EXTERN(void) git_oidarray_free(git_oidarray *array);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "strarray.h"
|
||||
#include "diff.h"
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Compiled pathspec
|
||||
*/
|
||||
@ -257,4 +259,5 @@ GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
|
||||
GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
|
||||
const git_pathspec_match_list *m, size_t pos);
|
||||
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -49,8 +49,8 @@ typedef struct {
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_push_init_options(
|
||||
git_push_options* opts,
|
||||
int version);
|
||||
git_push_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/** Push network progress notification function */
|
||||
typedef int (*git_push_transfer_progress)(
|
||||
|
@ -69,7 +69,7 @@ GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const g
|
||||
*
|
||||
* @param repo the repository
|
||||
* @param old_name the old name of the reference
|
||||
* @param new_name the new name of the reference
|
||||
* @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_repository *repo, const char *old_name, const char *name);
|
||||
|
@ -178,7 +178,6 @@ GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repositor
|
||||
* @param name The name of the reference
|
||||
* @param id The object id pointed to by the reference.
|
||||
* @param force Overwrite existing references
|
||||
* @param force Overwrite existing references
|
||||
* @param signature The identity that will used to populate the reflog entry
|
||||
* @param log_message The one line long message to be appended to the reflog
|
||||
* @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
|
||||
@ -221,7 +220,6 @@ GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo,
|
||||
* @param name The name of the reference
|
||||
* @param id The object id pointed to by the reference.
|
||||
* @param force Overwrite existing references
|
||||
* @param force Overwrite existing references
|
||||
* @param current_id The expected value of the reference at the time of update
|
||||
* @param signature The identity that will used to populate the reflog entry
|
||||
* @param log_message The one line long message to be appended to the reflog
|
||||
@ -415,7 +413,7 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
|
||||
* This method removes the named reference from the repository without
|
||||
* looking at its old value.
|
||||
*
|
||||
* @param ref The reference to remove
|
||||
* @param name The reference to remove
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_remove(git_repository *repo, const char *name);
|
||||
@ -525,6 +523,17 @@ GIT_EXTERN(int) git_reference_iterator_glob_new(
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter);
|
||||
|
||||
/**
|
||||
* Get the next reference's name
|
||||
*
|
||||
* This function is provided for convenience in case only the names
|
||||
* are interesting as it avoids the allocation of the `git_reference`
|
||||
* object which `git_reference_next()` needs.
|
||||
*
|
||||
* @param out pointer in which to store the string
|
||||
* @param iter the iterator
|
||||
* @return 0, GIT_ITEROVER if there are no more; or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter);
|
||||
|
||||
/**
|
||||
|
@ -384,15 +384,12 @@ GIT_EXTERN(int) git_remote_fetch(
|
||||
const char *reflog_message);
|
||||
|
||||
/**
|
||||
* Return whether a string is a valid remote URL
|
||||
*
|
||||
* @param url the url to check
|
||||
* @return 1 if the url is valid, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_valid_url(const char *url);
|
||||
|
||||
/**
|
||||
* Return whether the passed URL is supported by this version of the library.
|
||||
* Return whether the library supports a particular URL scheme
|
||||
*
|
||||
* Both the built-in and externally-registered transport lists are
|
||||
* searched for a transport which supports the scheme of the given
|
||||
* URL.
|
||||
*
|
||||
* @param url the url to check
|
||||
* @return 1 if the url is supported, 0 otherwise
|
||||
@ -410,30 +407,6 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url);
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Choose whether to check the server's certificate (applies to HTTPS only)
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param check whether to check the server's certificate (defaults to yes)
|
||||
*/
|
||||
GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -474,6 +447,14 @@ struct git_remote_callbacks {
|
||||
*/
|
||||
git_cred_acquire_cb credentials;
|
||||
|
||||
/**
|
||||
* If cert verification fails, this will be called to let the
|
||||
* user make the final decision of whether to allow the
|
||||
* connection to proceed. Returns 1 to allow the connection, 0
|
||||
* to disallow it or a negative value to indicate an error.
|
||||
*/
|
||||
git_transport_certificate_check_cb certificate_check;
|
||||
|
||||
/**
|
||||
* During the download of new data, this will be regularly
|
||||
* called with the current count of progress done by the
|
||||
@ -501,14 +482,13 @@ struct git_remote_callbacks {
|
||||
* Initializes a `git_remote_callbacks` with default values. Equivalent to
|
||||
* creating an instance with GIT_REMOTE_CALLBACKS_INIT.
|
||||
*
|
||||
* @param opts the `git_remote_callbacks` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_REMOTE_CALLBACKS_VERSION` here.
|
||||
* @param opts the `git_remote_callbacks` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_REMOTE_CALLBACKS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_init_callbacks(
|
||||
git_remote_callbacks* opts,
|
||||
int version);
|
||||
git_remote_callbacks *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Set the callbacks for a remote
|
||||
@ -573,18 +553,17 @@ GIT_EXTERN(void) git_remote_set_autotag(
|
||||
*
|
||||
* A temporary in-memory remote cannot be given a name with this method.
|
||||
*
|
||||
* @param problems non-default refspecs cannot be renamed and will be
|
||||
* stored here for further processing by the caller. Always free this
|
||||
* strarray on succesful return.
|
||||
* @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_strarray *problems,
|
||||
git_remote *remote,
|
||||
const char *new_name,
|
||||
git_remote_rename_problem_cb callback,
|
||||
void *payload);
|
||||
const char *new_name);
|
||||
|
||||
/**
|
||||
* Retrieve the update FETCH_HEAD setting.
|
||||
@ -611,6 +590,35 @@ GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value);
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name);
|
||||
|
||||
/**
|
||||
* Delete an existing persisted remote.
|
||||
*
|
||||
* All remote-tracking branches and configuration settings
|
||||
* for the remote will be removed.
|
||||
*
|
||||
* @param remote A valid remote
|
||||
* @return 0 on success, or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_delete(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Retrieve the name of the remote's default branch
|
||||
*
|
||||
* The default branch of a repository is the branch which HEAD points
|
||||
* to. If the remote does not support reporting this information
|
||||
* directly, it performs the guess as git does; that is, if there are
|
||||
* multiple branches which point to the same commit, the first one is
|
||||
* chosen. If the master branch is a candidate, it wins.
|
||||
*
|
||||
* This function must only be called after connecting.
|
||||
*
|
||||
* @param out the buffern in which to store the reference name
|
||||
* @param remote the remote
|
||||
* @return 0, GIT_ENOTFOUND if the remote does not have any references
|
||||
* or none of them point to HEAD's commit, or an error message.
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_default_branch(git_buf *out, git_remote *remote);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -196,6 +196,8 @@ GIT_EXTERN(int) git_repository_init(
|
||||
* 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.
|
||||
* * GIT_REPOSITORY_INIT_RELATIVE_GITLINK - If an alternate workdir is
|
||||
* specified, use relative paths for the gitdir and core.worktree.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_REPOSITORY_INIT_BARE = (1u << 0),
|
||||
@ -204,6 +206,7 @@ typedef enum {
|
||||
GIT_REPOSITORY_INIT_MKDIR = (1u << 3),
|
||||
GIT_REPOSITORY_INIT_MKPATH = (1u << 4),
|
||||
GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5),
|
||||
GIT_REPOSITORY_INIT_RELATIVE_GITLINK = (1u << 6),
|
||||
} git_repository_init_flag_t;
|
||||
|
||||
/**
|
||||
@ -271,14 +274,13 @@ typedef struct {
|
||||
* Initializes a `git_repository_init_options` with default values. Equivalent
|
||||
* to creating an instance with GIT_REPOSITORY_INIT_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_repository_init_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_REPOSITORY_INIT_OPTIONS_VERSION` here.
|
||||
* @param opts the `git_repository_init_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_REPOSITORY_INIT_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_init_init_options(
|
||||
git_repository_init_options* opts,
|
||||
int version);
|
||||
git_repository_init_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Create a new Git repository in the given folder with extended controls.
|
||||
@ -409,12 +411,28 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
|
||||
* The configuration file must be freed once it's no longer
|
||||
* being used by the user.
|
||||
*
|
||||
* @param out Pointer to store the loaded config file
|
||||
* @param out Pointer to store the loaded configuration
|
||||
* @param repo A repository object
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Get a snapshot of the repository's configuration
|
||||
*
|
||||
* Convenience function to take a snapshot from the repository's
|
||||
* configuration. The contents of this snapshot will not change,
|
||||
* even if the underlying config files are modified.
|
||||
*
|
||||
* The configuration file must be freed once it's no longer
|
||||
* being used by the user.
|
||||
*
|
||||
* @param out Pointer to store the loaded configuration
|
||||
* @param repo the repository
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_config_snapshot(git_config **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Get the Object Database for this repository.
|
||||
*
|
||||
@ -547,6 +565,10 @@ GIT_EXTERN(int) git_repository_mergehead_foreach(
|
||||
* 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.
|
||||
*
|
||||
* Note: if the repository has `core.safecrlf` set to fail and the
|
||||
* filtering triggers that failure, then this function will return an
|
||||
* error and not calculate the hash of the file.
|
||||
*
|
||||
* @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
|
||||
@ -556,6 +578,7 @@ GIT_EXTERN(int) git_repository_mergehead_foreach(
|
||||
* 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.
|
||||
* @return 0 on success, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_hashfile(
|
||||
git_oid *out,
|
||||
@ -629,7 +652,7 @@ GIT_EXTERN(int) git_repository_set_head_detached(
|
||||
*
|
||||
* @param repo Repository pointer
|
||||
* @param signature The identity that will used to populate the reflog entry
|
||||
* @param log_message The one line long message to be appended to the reflog
|
||||
* @param reflog_message The one line long message to be appended to the reflog
|
||||
* @return 0 on success, GIT_EUNBORNBRANCH when HEAD points to a non existing
|
||||
* branch or an error code
|
||||
*/
|
||||
@ -642,7 +665,7 @@ typedef enum {
|
||||
GIT_REPOSITORY_STATE_NONE,
|
||||
GIT_REPOSITORY_STATE_MERGE,
|
||||
GIT_REPOSITORY_STATE_REVERT,
|
||||
GIT_REPOSITORY_STATE_CHERRY_PICK,
|
||||
GIT_REPOSITORY_STATE_CHERRYPICK,
|
||||
GIT_REPOSITORY_STATE_BISECT,
|
||||
GIT_REPOSITORY_STATE_REBASE,
|
||||
GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
|
||||
|
@ -7,6 +7,10 @@
|
||||
#ifndef INCLUDE_git_reset_h__
|
||||
#define INCLUDE_git_reset_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "strarray.h"
|
||||
|
||||
/**
|
||||
* @file git2/reset.h
|
||||
* @brief Git reset management routines
|
||||
@ -19,9 +23,9 @@ 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_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;
|
||||
|
||||
/**
|
||||
|
@ -37,14 +37,13 @@ typedef struct {
|
||||
* Initializes a `git_revert_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_REVERT_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_revert_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_REVERT_OPTIONS_VERSION` here.
|
||||
* @param opts the `git_revert_options` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_REVERT_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_revert_init_opts(
|
||||
git_revert_options* opts,
|
||||
int version);
|
||||
GIT_EXTERN(int) git_revert_init_options(
|
||||
git_revert_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Reverts the given commit against the given "our" commit, producing an
|
||||
@ -57,10 +56,10 @@ GIT_EXTERN(int) git_revert_init_opts(
|
||||
* @param revert_commit the commit to revert
|
||||
* @param our_commit the commit to revert against (eg, HEAD)
|
||||
* @param mainline the parent of the revert commit, if it is a merge
|
||||
* @param merge_tree_opts the merge tree options (or null for defaults)
|
||||
* @param merge_options the merge options (or null for defaults)
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
int git_revert_commit(
|
||||
GIT_EXTERN(int) git_revert_commit(
|
||||
git_index **out,
|
||||
git_repository *repo,
|
||||
git_commit *revert_commit,
|
||||
@ -72,9 +71,8 @@ int git_revert_commit(
|
||||
* Reverts the given commit, producing changes in the working directory.
|
||||
*
|
||||
* @param repo the repository to revert
|
||||
* @param commits the commits to revert
|
||||
* @param commits_len the number of commits to revert
|
||||
* @param flags merge flags
|
||||
* @param commit the commit to revert
|
||||
* @param given_opts merge flags
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_revert(
|
||||
|
@ -69,7 +69,7 @@ GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo)
|
||||
* Call `git_signature_free()` to free the data.
|
||||
*
|
||||
* @param dest pointer where to store the copy
|
||||
* @param entry signature to duplicate
|
||||
* @param sig signature to duplicate
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_signature_dup(git_signature **dest, const git_signature *sig);
|
||||
|
@ -43,6 +43,7 @@ typedef enum {
|
||||
GIT_STATUS_WT_DELETED = (1u << 9),
|
||||
GIT_STATUS_WT_TYPECHANGE = (1u << 10),
|
||||
GIT_STATUS_WT_RENAMED = (1u << 11),
|
||||
GIT_STATUS_WT_UNREADABLE = (1u << 12),
|
||||
|
||||
GIT_STATUS_IGNORED = (1u << 14),
|
||||
} git_status_t;
|
||||
@ -121,6 +122,11 @@ typedef enum {
|
||||
* - GIT_STATUS_OPT_NO_REFRESH bypasses the default status behavior of
|
||||
* doing a "soft" index reload (i.e. reloading the index data if the
|
||||
* file on disk has been modified outside libgit2).
|
||||
* - GIT_STATUS_OPT_UPDATE_INDEX tells libgit2 to refresh the stat cache
|
||||
* in the index for files that are unchanged but have out of date stat
|
||||
* information in the index. It will result in less work being done on
|
||||
* subsequent calls to get status. This is mutually exclusive with the
|
||||
* NO_REFRESH option.
|
||||
*
|
||||
* Calling `git_status_foreach()` is like calling the extended version
|
||||
* with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED,
|
||||
@ -128,19 +134,22 @@ typedef enum {
|
||||
* 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_RENAMES_HEAD_TO_INDEX = (1u << 7),
|
||||
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8),
|
||||
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9),
|
||||
GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10),
|
||||
GIT_STATUS_OPT_RENAMES_FROM_REWRITES = (1u << 11),
|
||||
GIT_STATUS_OPT_NO_REFRESH = (1u << 12),
|
||||
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_RENAMES_HEAD_TO_INDEX = (1u << 7),
|
||||
GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8),
|
||||
GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9),
|
||||
GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10),
|
||||
GIT_STATUS_OPT_RENAMES_FROM_REWRITES = (1u << 11),
|
||||
GIT_STATUS_OPT_NO_REFRESH = (1u << 12),
|
||||
GIT_STATUS_OPT_UPDATE_INDEX = (1u << 13),
|
||||
GIT_STATUS_OPT_INCLUDE_UNREADABLE = (1u << 14),
|
||||
GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 15),
|
||||
} git_status_opt_t;
|
||||
|
||||
#define GIT_STATUS_OPT_DEFAULTS \
|
||||
@ -178,14 +187,13 @@ typedef struct {
|
||||
* Initializes a `git_status_options` with default values. Equivalent to
|
||||
* creating an instance with GIT_STATUS_OPTIONS_INIT.
|
||||
*
|
||||
* @param opts the `git_status_options` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_STATUS_OPTIONS_VERSION` here.
|
||||
* @param opts The `git_status_options` instance to initialize.
|
||||
* @param version Version of struct; pass `GIT_STATUS_OPTIONS_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_init_options(
|
||||
git_status_options* opts,
|
||||
int version);
|
||||
git_status_options *opts,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* A status entry, providing the differences between the file as it exists
|
||||
|
@ -283,7 +283,7 @@ GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule);
|
||||
* Resolve a submodule url relative to the given repository.
|
||||
*
|
||||
* @param out buffer to store the absolute submodule url in
|
||||
* @param repository Pointer to repository object
|
||||
* @param repo Pointer to repository object
|
||||
* @param url Relative url
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
@ -470,6 +470,24 @@ GIT_EXTERN(git_submodule_recurse_t) git_submodule_set_fetch_recurse_submodules(
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_init(git_submodule *submodule, int overwrite);
|
||||
|
||||
/**
|
||||
* Set up the subrepository for a submodule in preparation for clone.
|
||||
*
|
||||
* This function can be called to init and set up a submodule
|
||||
* repository from a submodule in preparation to clone it from
|
||||
* its remote.
|
||||
*
|
||||
* @param out Output pointer to the created git repository.
|
||||
* @param sm The submodule to create a new subrepository from.
|
||||
* @param use_gitlink Should the workdir contain a gitlink to
|
||||
* the repo in .git/modules vs. repo directly in workdir.
|
||||
* @return 0 on success, <0 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_repo_init(
|
||||
git_repository **out,
|
||||
const git_submodule *sm,
|
||||
int use_gitlink);
|
||||
|
||||
/**
|
||||
* Copy submodule remote info into submodule repo.
|
||||
*
|
||||
|
@ -57,13 +57,15 @@ struct git_config_backend {
|
||||
|
||||
/* Open means open the file/database and parse if necessary */
|
||||
int (*open)(struct git_config_backend *, git_config_level_t level);
|
||||
int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry);
|
||||
int (*get)(struct git_config_backend *, const char *key, const git_config_entry **entry);
|
||||
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 (*del_multivar)(struct git_config_backend *, const char *key, const char *regexp);
|
||||
int (*iterator)(git_config_iterator **, struct git_config_backend *);
|
||||
int (*refresh)(struct git_config_backend *);
|
||||
/** Produce a read-only version of this backend */
|
||||
int (*snapshot)(struct git_config_backend **, struct git_config_backend *);
|
||||
void (*free)(struct git_config_backend *);
|
||||
};
|
||||
#define GIT_CONFIG_BACKEND_VERSION 1
|
||||
@ -73,14 +75,13 @@ struct git_config_backend {
|
||||
* Initializes a `git_config_backend` with default values. Equivalent to
|
||||
* creating an instance with GIT_CONFIG_BACKEND_INIT.
|
||||
*
|
||||
* @param opts the `git_config_backend` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_CONFIG_BACKEND_VERSION` here.
|
||||
* @param opts the `git_config_backend` struct to initialize.
|
||||
* @param version Version of struct; pass `GIT_CONFIG_BACKEND_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_init_backend(
|
||||
git_config_backend* backend,
|
||||
int version);
|
||||
git_config_backend *backend,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Add a generic config file instance to an existing config
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "git2/common.h"
|
||||
#include "git2/types.h"
|
||||
#include "git2/oid.h"
|
||||
#include "git2/diff.h"
|
||||
#include "git2/status.h"
|
||||
|
||||
/**
|
||||
* @file git2/sys/diff.h
|
||||
@ -58,6 +60,32 @@ GIT_EXTERN(int) git_diff_print_callback__to_file_handle(
|
||||
const git_diff_line *line,
|
||||
void *payload); /*< payload must be a `FILE *` */
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int version;
|
||||
size_t stat_calls;
|
||||
size_t oid_calculations;
|
||||
} git_diff_perfdata;
|
||||
|
||||
#define GIT_DIFF_PERFDATA_VERSION 1
|
||||
#define GIT_DIFF_PERFDATA_INIT {GIT_DIFF_PERFDATA_VERSION,0,0}
|
||||
|
||||
/**
|
||||
* Get performance data for a diff object.
|
||||
*
|
||||
* @param out Structure to be filled with diff performance data
|
||||
* @param diff Diff to read performance data from
|
||||
* @return 0 for success, <0 for error
|
||||
*/
|
||||
GIT_EXTERN(int) git_diff_get_perfdata(
|
||||
git_diff_perfdata *out, const git_diff *diff);
|
||||
|
||||
/**
|
||||
* Get performance data for diffs from a git_status_list
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_list_get_perfdata(
|
||||
git_diff_perfdata *out, const git_status_list *status);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -55,7 +55,10 @@ GIT_EXTERN(git_filter *) git_filter_lookup(const char *name);
|
||||
* your own chains of filters.
|
||||
*/
|
||||
GIT_EXTERN(int) git_filter_list_new(
|
||||
git_filter_list **out, git_repository *repo, git_filter_mode_t mode);
|
||||
git_filter_list **out,
|
||||
git_repository *repo,
|
||||
git_filter_mode_t mode,
|
||||
uint32_t options);
|
||||
|
||||
/**
|
||||
* Add a filter to a filter list with the given payload.
|
||||
@ -115,10 +118,15 @@ GIT_EXTERN(uint16_t) git_filter_source_filemode(const git_filter_source *src);
|
||||
GIT_EXTERN(const git_oid *) git_filter_source_id(const git_filter_source *src);
|
||||
|
||||
/**
|
||||
* Get the git_filter_mode_t to be applied
|
||||
* Get the git_filter_mode_t to be used
|
||||
*/
|
||||
GIT_EXTERN(git_filter_mode_t) git_filter_source_mode(const git_filter_source *src);
|
||||
|
||||
/**
|
||||
* Get the combination git_filter_opt_t options to be applied
|
||||
*/
|
||||
GIT_EXTERN(uint32_t) git_filter_source_options(const git_filter_source *src);
|
||||
|
||||
/*
|
||||
* struct git_filter
|
||||
*
|
||||
|
@ -93,14 +93,13 @@ struct git_odb_backend {
|
||||
* Initializes a `git_odb_backend` with default values. Equivalent to
|
||||
* creating an instance with GIT_ODB_BACKEND_INIT.
|
||||
*
|
||||
* @param opts the `git_odb_backend` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_ODB_BACKEND_VERSION` here.
|
||||
* @param opts the `git_odb_backend` struct to initialize.
|
||||
* @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_init_backend(
|
||||
git_odb_backend* backend,
|
||||
int version);
|
||||
git_odb_backend *backend,
|
||||
unsigned int version);
|
||||
|
||||
GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
|
||||
|
||||
|
@ -162,14 +162,13 @@ struct git_refdb_backend {
|
||||
* Initializes a `git_refdb_backend` with default values. Equivalent to
|
||||
* creating an instance with GIT_REFDB_BACKEND_INIT.
|
||||
*
|
||||
* @param opts the `git_refdb_backend` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_REFDB_BACKEND_VERSION` here.
|
||||
* @param opts the `git_refdb_backend` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_REFDB_BACKEND_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_refdb_init_backend(
|
||||
git_refdb_backend* backend,
|
||||
int version);
|
||||
git_refdb_backend *backend,
|
||||
unsigned int version);
|
||||
|
||||
/**
|
||||
* Constructors for default filesystem-based refdb backend
|
||||
|
@ -119,6 +119,19 @@ GIT_EXTERN(void) git_repository_set_refdb(git_repository *repo, git_refdb *refdb
|
||||
*/
|
||||
GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
|
||||
|
||||
/**
|
||||
* Set a repository to be bare.
|
||||
*
|
||||
* Clear the working directory and set core.bare to true. You may also
|
||||
* want to call `git_repository_set_index(repo, NULL)` since a bare repo
|
||||
* typically does not have an index, but this function will not do that
|
||||
* for you.
|
||||
*
|
||||
* @param repo Repo to make bare
|
||||
* @return 0 on success, <0 on failure
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_set_bare(git_repository *repo);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
352
include/git2/sys/transport.h
Normal file
352
include/git2/sys/transport.h
Normal file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_sys_git_transport_h
|
||||
#define INCLUDE_sys_git_transport_h
|
||||
|
||||
#include "git2/net.h"
|
||||
#include "git2/types.h"
|
||||
|
||||
/**
|
||||
* @file git2/sys/transport.h
|
||||
* @brief Git custom transport registration interfaces and functions
|
||||
* @defgroup git_transport Git custom transport registration
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
typedef enum {
|
||||
GIT_TRANSPORTFLAGS_NONE = 0,
|
||||
} git_transport_flags_t;
|
||||
|
||||
typedef struct git_transport git_transport;
|
||||
|
||||
struct git_transport {
|
||||
unsigned int version;
|
||||
/* Set progress and error callbacks */
|
||||
int (*set_callbacks)(
|
||||
git_transport *transport,
|
||||
git_transport_message_cb progress_cb,
|
||||
git_transport_message_cb error_cb,
|
||||
git_transport_certificate_check_cb certificate_check_cb,
|
||||
void *payload);
|
||||
|
||||
/* Connect the transport to the remote repository, using the given
|
||||
* direction. */
|
||||
int (*connect)(
|
||||
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 array returned is owned by the transport and
|
||||
* is guranteed until the next call of a transport function. */
|
||||
int (*ls)(
|
||||
const git_remote_head ***out,
|
||||
size_t *size,
|
||||
git_transport *transport);
|
||||
|
||||
/* Executes the push whose context is in the git_push object. */
|
||||
int (*push)(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)(
|
||||
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)(
|
||||
git_transport *transport,
|
||||
git_repository *repo,
|
||||
git_transfer_progress *stats,
|
||||
git_transfer_progress_cb progress_cb,
|
||||
void *progress_payload);
|
||||
|
||||
/* Checks to see if the transport is connected */
|
||||
int (*is_connected)(git_transport *transport);
|
||||
|
||||
/* Reads the flags value previously passed into connect() */
|
||||
int (*read_flags)(git_transport *transport, int *flags);
|
||||
|
||||
/* Cancels any outstanding transport operation */
|
||||
void (*cancel)(git_transport *transport);
|
||||
|
||||
/* This function is the reverse of connect() -- it terminates the
|
||||
* connection to the remote end. */
|
||||
int (*close)(git_transport *transport);
|
||||
|
||||
/* Frees/destructs the git_transport object. */
|
||||
void (*free)(git_transport *transport);
|
||||
};
|
||||
|
||||
#define GIT_TRANSPORT_VERSION 1
|
||||
#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
|
||||
|
||||
/**
|
||||
* Initializes a `git_transport` with default values. Equivalent to
|
||||
* creating an instance with GIT_TRANSPORT_INIT.
|
||||
*
|
||||
* @param opts the `git_transport` struct to initialize
|
||||
* @param version Version of struct; pass `GIT_TRANSPORT_VERSION`
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_init(
|
||||
git_transport *opts,
|
||||
unsigned int 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);
|
||||
|
||||
/**
|
||||
* Create an ssh transport with custom git command paths
|
||||
*
|
||||
* This is a factory function suitable for setting as the transport
|
||||
* callback in a remote (or for a clone in the options).
|
||||
*
|
||||
* The payload argument must be a strarray pointer with the paths for
|
||||
* the `git-upload-pack` and `git-receive-pack` at index 0 and 1.
|
||||
*
|
||||
* @param out the resulting transport
|
||||
* @param owner the owning remote
|
||||
* @param payload a strarray with the paths
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload);
|
||||
|
||||
/* Signature of a function which creates a transport */
|
||||
typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
|
||||
|
||||
/**
|
||||
* Add a custom transport definition, to be used in addition to the built-in
|
||||
* set of transports that come with libgit2.
|
||||
*
|
||||
* The caller is responsible for synchronizing calls to git_transport_register
|
||||
* and git_transport_unregister with other calls to the library that
|
||||
* instantiate transports.
|
||||
*
|
||||
* @param prefix The scheme (ending in "://") to match, i.e. "git://"
|
||||
* @param cb The callback used to create an instance of the transport
|
||||
* @param param A fixed parameter to pass to cb at creation time
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_register(
|
||||
const char *prefix,
|
||||
git_transport_cb cb,
|
||||
void *param);
|
||||
|
||||
/**
|
||||
*
|
||||
* Unregister a custom transport definition which was previously registered
|
||||
* with git_transport_register.
|
||||
*
|
||||
* @param prefix From the previous call to git_transport_register
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_unregister(
|
||||
const char *prefix);
|
||||
|
||||
/* 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;
|
||||
|
||||
typedef struct git_smart_subtransport git_smart_subtransport;
|
||||
typedef struct git_smart_subtransport_stream git_smart_subtransport_stream;
|
||||
|
||||
/* A stream used by the smart transport to read and write data
|
||||
* from a subtransport */
|
||||
struct git_smart_subtransport_stream {
|
||||
/* The owning subtransport */
|
||||
git_smart_subtransport *subtransport;
|
||||
|
||||
int (*read)(
|
||||
git_smart_subtransport_stream *stream,
|
||||
char *buffer,
|
||||
size_t buf_size,
|
||||
size_t *bytes_read);
|
||||
|
||||
int (*write)(
|
||||
git_smart_subtransport_stream *stream,
|
||||
const char *buffer,
|
||||
size_t len);
|
||||
|
||||
void (*free)(
|
||||
git_smart_subtransport_stream *stream);
|
||||
};
|
||||
|
||||
/* An implementation of a subtransport which carries data for the
|
||||
* smart transport */
|
||||
struct git_smart_subtransport {
|
||||
int (* action)(
|
||||
git_smart_subtransport_stream **out,
|
||||
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)(git_smart_subtransport *transport);
|
||||
|
||||
void (*free)(git_smart_subtransport *transport);
|
||||
};
|
||||
|
||||
/* 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);
|
||||
|
||||
/**
|
||||
* Create an instance of the ssh 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_ssh(
|
||||
git_smart_subtransport **out,
|
||||
git_transport* owner);
|
||||
|
||||
/**
|
||||
* Sets a custom transport factory for the remote. The caller can use this
|
||||
* function to override the transport used for this remote when performing
|
||||
* network operations.
|
||||
*
|
||||
* @param remote the remote to configure
|
||||
* @param transport_cb the function to use to create a transport
|
||||
* @param payload opaque parameter passed to transport_cb
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_transport(
|
||||
git_remote *remote,
|
||||
git_transport_cb transport_cb,
|
||||
void *payload);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -11,10 +11,6 @@
|
||||
#include "net.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifdef GIT_SSH
|
||||
#include <libssh2.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file git2/transport.h
|
||||
* @brief Git transport interfaces and functions
|
||||
@ -24,6 +20,63 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Type of SSH host fingerprint
|
||||
*/
|
||||
typedef enum {
|
||||
/** MD5 is available */
|
||||
GIT_CERT_SSH_MD5 = (1 << 0),
|
||||
/** SHA-1 is available */
|
||||
GIT_CERT_SSH_SHA1 = (1 << 1),
|
||||
} git_cert_ssh_t;
|
||||
|
||||
/**
|
||||
* Hostkey information taken from libssh2
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Type of certificate. Here to share the header with
|
||||
* `git_cert`.
|
||||
*/
|
||||
git_cert_t cert_type;
|
||||
/**
|
||||
* A hostkey type from libssh2, either
|
||||
* `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
|
||||
*/
|
||||
git_cert_ssh_t type;
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
|
||||
* have the MD5 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_md5[16];
|
||||
|
||||
/**
|
||||
* Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
|
||||
* have the SHA-1 hash of the hostkey.
|
||||
*/
|
||||
unsigned char hash_sha1[20];
|
||||
} git_cert_hostkey;
|
||||
|
||||
/**
|
||||
* X.509 certificate information
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Type of certificate. Here to share the header with
|
||||
* `git_cert`.
|
||||
*/
|
||||
git_cert_t cert_type;
|
||||
/**
|
||||
* Pointer to the X.509 certificate data
|
||||
*/
|
||||
void *data;
|
||||
/**
|
||||
* Length of the memory block pointed to by `data`.
|
||||
*/
|
||||
size_t len;
|
||||
} git_cert_x509;
|
||||
|
||||
/*
|
||||
*** Begin interface for credentials acquisition ***
|
||||
*/
|
||||
@ -44,6 +97,14 @@ typedef enum {
|
||||
|
||||
/* git_cred_ssh_interactive */
|
||||
GIT_CREDTYPE_SSH_INTERACTIVE = (1u << 4),
|
||||
|
||||
/**
|
||||
* Username-only information
|
||||
*
|
||||
* If the SSH transport does not know which username to use,
|
||||
* it will ask via this credential type.
|
||||
*/
|
||||
GIT_CREDTYPE_USERNAME = (1u << 5),
|
||||
} git_credtype_t;
|
||||
|
||||
/* The base structure for all credential types */
|
||||
@ -61,14 +122,20 @@ typedef struct {
|
||||
char *password;
|
||||
} git_cred_userpass_plaintext;
|
||||
|
||||
#ifdef GIT_SSH
|
||||
typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));
|
||||
typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback));
|
||||
#else
|
||||
typedef int (*git_cred_sign_callback)(void *, ...);
|
||||
typedef int (*git_cred_ssh_interactive_callback)(void *, ...);
|
||||
|
||||
/*
|
||||
* If the user hasn't included libssh2.h before git2.h, we need to
|
||||
* define a few types for the callback signatures.
|
||||
*/
|
||||
#ifndef LIBSSH2_VERSION
|
||||
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
|
||||
#endif
|
||||
|
||||
typedef int (*git_cred_sign_callback)(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);
|
||||
typedef void (*git_cred_ssh_interactive_callback)(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract);
|
||||
|
||||
/**
|
||||
* A ssh key from disk
|
||||
*/
|
||||
@ -105,6 +172,12 @@ typedef struct git_cred_ssh_custom {
|
||||
/** A key for NTLM/Kerberos "default" credentials */
|
||||
typedef struct git_cred git_cred_default;
|
||||
|
||||
/** Username-only credential information */
|
||||
typedef struct git_cred_username {
|
||||
git_cred parent;
|
||||
char username[1];
|
||||
} git_cred_username;
|
||||
|
||||
/**
|
||||
* Check whether a credential object contains username information.
|
||||
*
|
||||
@ -206,6 +279,14 @@ GIT_EXTERN(int) git_cred_ssh_custom_new(
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_default_new(git_cred **out);
|
||||
|
||||
/**
|
||||
* Create a credential to specify a username.
|
||||
*
|
||||
* This is used with ssh authentication to query for the username if
|
||||
* none is specified in the url.
|
||||
*/
|
||||
GIT_EXTERN(int) git_cred_username_new(git_cred **cred, const char *username);
|
||||
|
||||
/**
|
||||
* Signature of a function which acquires a credential object.
|
||||
*
|
||||
@ -225,320 +306,6 @@ typedef int (*git_cred_acquire_cb)(
|
||||
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 int (*git_transport_message_cb)(const char *str, int len, void *data);
|
||||
|
||||
typedef struct git_transport git_transport;
|
||||
|
||||
struct git_transport {
|
||||
unsigned int version;
|
||||
/* Set progress and error callbacks */
|
||||
int (*set_callbacks)(
|
||||
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)(
|
||||
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 array returned is owned by the transport and
|
||||
* is guranteed until the next call of a transport function. */
|
||||
int (*ls)(
|
||||
const git_remote_head ***out,
|
||||
size_t *size,
|
||||
git_transport *transport);
|
||||
|
||||
/* Executes the push whose context is in the git_push object. */
|
||||
int (*push)(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)(
|
||||
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)(
|
||||
git_transport *transport,
|
||||
git_repository *repo,
|
||||
git_transfer_progress *stats,
|
||||
git_transfer_progress_cb progress_cb,
|
||||
void *progress_payload);
|
||||
|
||||
/* Checks to see if the transport is connected */
|
||||
int (*is_connected)(git_transport *transport);
|
||||
|
||||
/* Reads the flags value previously passed into connect() */
|
||||
int (*read_flags)(git_transport *transport, int *flags);
|
||||
|
||||
/* Cancels any outstanding transport operation */
|
||||
void (*cancel)(git_transport *transport);
|
||||
|
||||
/* This function is the reverse of connect() -- it terminates the
|
||||
* connection to the remote end. */
|
||||
int (*close)(git_transport *transport);
|
||||
|
||||
/* Frees/destructs the git_transport object. */
|
||||
void (*free)(git_transport *transport);
|
||||
};
|
||||
|
||||
#define GIT_TRANSPORT_VERSION 1
|
||||
#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION}
|
||||
|
||||
/**
|
||||
* Initializes a `git_transport` with default values. Equivalent to
|
||||
* creating an instance with GIT_TRANSPORT_INIT.
|
||||
*
|
||||
* @param opts the `git_transport` instance to initialize.
|
||||
* @param version the version of the struct; you should pass
|
||||
* `GIT_TRANSPORT_VERSION` here.
|
||||
* @return Zero on success; -1 on failure.
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_init(
|
||||
git_transport* opts,
|
||||
int 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);
|
||||
|
||||
/**
|
||||
* Add a custom transport definition, to be used in addition to the built-in
|
||||
* set of transports that come with libgit2.
|
||||
*
|
||||
* The caller is responsible for synchronizing calls to git_transport_register
|
||||
* and git_transport_unregister with other calls to the library that
|
||||
* instantiate transports.
|
||||
*
|
||||
* @param prefix The scheme (ending in "://") to match, i.e. "git://"
|
||||
* @param priority The priority of this transport relative to others with
|
||||
* the same prefix. Built-in transports have a priority of 1.
|
||||
* @param cb The callback used to create an instance of the transport
|
||||
* @param param A fixed parameter to pass to cb at creation time
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_register(
|
||||
const char *prefix,
|
||||
unsigned priority,
|
||||
git_transport_cb cb,
|
||||
void *param);
|
||||
|
||||
/**
|
||||
*
|
||||
* Unregister a custom transport definition which was previously registered
|
||||
* with git_transport_register.
|
||||
*
|
||||
* @param prefix From the previous call to git_transport_register
|
||||
* @param priority From the previous call to git_transport_register
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_transport_unregister(
|
||||
const char *prefix,
|
||||
unsigned priority);
|
||||
|
||||
/* 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;
|
||||
|
||||
typedef struct git_smart_subtransport git_smart_subtransport;
|
||||
typedef struct git_smart_subtransport_stream git_smart_subtransport_stream;
|
||||
|
||||
/* A stream used by the smart transport to read and write data
|
||||
* from a subtransport */
|
||||
struct git_smart_subtransport_stream {
|
||||
/* The owning subtransport */
|
||||
git_smart_subtransport *subtransport;
|
||||
|
||||
int (*read)(
|
||||
git_smart_subtransport_stream *stream,
|
||||
char *buffer,
|
||||
size_t buf_size,
|
||||
size_t *bytes_read);
|
||||
|
||||
int (*write)(
|
||||
git_smart_subtransport_stream *stream,
|
||||
const char *buffer,
|
||||
size_t len);
|
||||
|
||||
void (*free)(
|
||||
git_smart_subtransport_stream *stream);
|
||||
};
|
||||
|
||||
/* An implementation of a subtransport which carries data for the
|
||||
* smart transport */
|
||||
struct git_smart_subtransport {
|
||||
int (* action)(
|
||||
git_smart_subtransport_stream **out,
|
||||
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)(git_smart_subtransport *transport);
|
||||
|
||||
void (*free)(git_smart_subtransport *transport);
|
||||
};
|
||||
|
||||
/* 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);
|
||||
|
||||
/**
|
||||
* Create an instance of the ssh 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_ssh(
|
||||
git_smart_subtransport **out,
|
||||
git_transport* owner);
|
||||
|
||||
/*
|
||||
*** End interface for subtransports for the smart transport ***
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -151,7 +151,7 @@ GIT_EXTERN(int) git_tree_entry_bypath(
|
||||
* and must be freed explicitly with `git_tree_entry_free()`.
|
||||
*
|
||||
* @param dest pointer where to store the copy
|
||||
* @param entry tree entry to duplicate
|
||||
* @param source tree entry to duplicate
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source);
|
||||
@ -301,8 +301,10 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
|
||||
* If an entry named `filename` already exists, its attributes
|
||||
* will be updated with the given ones.
|
||||
*
|
||||
* 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.
|
||||
* 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. The
|
||||
* pointer may not be valid past the next operation in this
|
||||
* builder. Duplicate the entry if you want to keep it.
|
||||
*
|
||||
* No attempt is being made to ensure that the provided oid points
|
||||
* to an existing git object in the object database, nor that the
|
||||
|
@ -154,15 +154,15 @@ typedef struct git_packbuilder git_packbuilder;
|
||||
|
||||
/** Time in a signature */
|
||||
typedef struct git_time {
|
||||
git_time_t time; /** time in seconds from epoch */
|
||||
int offset; /** timezone offset, in minutes */
|
||||
git_time_t time; /**< time in seconds from epoch */
|
||||
int offset; /**< timezone offset, in minutes */
|
||||
} git_time;
|
||||
|
||||
/** An action signature (e.g. for committers, taggers, etc) */
|
||||
typedef struct git_signature {
|
||||
char *name; /** full name of the author */
|
||||
char *email; /** email of the author */
|
||||
git_time when; /** time when the action happened */
|
||||
char *name; /**< full name of the author */
|
||||
char *email; /**< email of the author */
|
||||
git_time when; /**< time when the action happened */
|
||||
} git_signature;
|
||||
|
||||
/** In-memory representation of a reference. */
|
||||
@ -183,9 +183,9 @@ typedef struct git_status_list git_status_list;
|
||||
|
||||
/** Basic type of any Git reference. */
|
||||
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_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_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC,
|
||||
} git_ref_t;
|
||||
|
||||
@ -198,12 +198,12 @@ typedef enum {
|
||||
|
||||
/** 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_UNREADABLE = 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;
|
||||
@ -243,6 +243,54 @@ typedef struct git_transfer_progress {
|
||||
*/
|
||||
typedef int (*git_transfer_progress_cb)(const git_transfer_progress *stats, void *payload);
|
||||
|
||||
/**
|
||||
* Type for messages delivered by the transport. Return a negative value
|
||||
* to cancel the network operation.
|
||||
*
|
||||
* @param str The message from the transport
|
||||
* @param len The length of the message
|
||||
* @param payload Payload provided by the caller
|
||||
*/
|
||||
typedef int (*git_transport_message_cb)(const char *str, int len, void *payload);
|
||||
|
||||
/**
|
||||
* Type of host certificate structure that is passed to the check callback
|
||||
*/
|
||||
typedef enum git_cert_t {
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to
|
||||
* the DER-encoded data.
|
||||
*/
|
||||
GIT_CERT_X509,
|
||||
/**
|
||||
* The `data` argument to the callback will be a pointer to a
|
||||
* `git_cert_hostkey` structure.
|
||||
*/
|
||||
GIT_CERT_HOSTKEY_LIBSSH2,
|
||||
} git_cert_t;
|
||||
|
||||
/**
|
||||
* Parent type for `git_cert_hostkey` and `git_cert_x509`.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Type of certificate. A `GIT_CERT_` value.
|
||||
*/
|
||||
git_cert_t cert_type;
|
||||
} git_cert;
|
||||
|
||||
/**
|
||||
* Callback for the user's custom certificate checks.
|
||||
*
|
||||
* @param type The type of certificate or host info, SSH or X.509
|
||||
* @param data The data for the certificate or host info
|
||||
* @param len The size of the certificate or host info
|
||||
* @param valid Whether the libgit2 checks (OpenSSL or WinHTTP) think
|
||||
* this certificate is valid
|
||||
* @param payload Payload provided by the caller
|
||||
*/
|
||||
typedef int (*git_transport_certificate_check_cb)(git_cert *cert, int valid, void *payload);
|
||||
|
||||
/**
|
||||
* Opaque structure representing a submodule.
|
||||
*/
|
||||
@ -314,12 +362,12 @@ typedef enum {
|
||||
* when we don't want any particular ignore rule to be specified.
|
||||
*/
|
||||
typedef enum {
|
||||
GIT_SUBMODULE_IGNORE_RESET = -1, /* reset to on-disk value */
|
||||
GIT_SUBMODULE_IGNORE_RESET = -1, /**< reset to on-disk value */
|
||||
|
||||
GIT_SUBMODULE_IGNORE_NONE = 1, /* any change or untracked == dirty */
|
||||
GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /* dirty if tracked files change */
|
||||
GIT_SUBMODULE_IGNORE_DIRTY = 3, /* only dirty if HEAD moved */
|
||||
GIT_SUBMODULE_IGNORE_ALL = 4, /* never dirty */
|
||||
GIT_SUBMODULE_IGNORE_NONE = 1, /**< any change or untracked == dirty */
|
||||
GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /**< dirty if tracked files change */
|
||||
GIT_SUBMODULE_IGNORE_DIRTY = 3, /**< only dirty if HEAD moved */
|
||||
GIT_SUBMODULE_IGNORE_ALL = 4, /**< never dirty */
|
||||
|
||||
GIT_SUBMODULE_IGNORE_DEFAULT = 0
|
||||
} git_submodule_ignore_t;
|
||||
|
@ -7,9 +7,11 @@
|
||||
#ifndef INCLUDE_git_version_h__
|
||||
#define INCLUDE_git_version_h__
|
||||
|
||||
#define LIBGIT2_VERSION "0.20.0"
|
||||
#define LIBGIT2_VERSION "0.21.0"
|
||||
#define LIBGIT2_VER_MAJOR 0
|
||||
#define LIBGIT2_VER_MINOR 20
|
||||
#define LIBGIT2_VER_MINOR 21
|
||||
#define LIBGIT2_VER_REVISION 0
|
||||
|
||||
#define LIBGIT2_SOVERSION 21
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$COVERITY" -eq 1 ];
|
||||
if [ -n "$COVERITY" ];
|
||||
then
|
||||
./script/coverity.sh;
|
||||
exit $?;
|
||||
@ -15,18 +15,27 @@ export GITTEST_REMOTE_URL="git://localhost/test.git"
|
||||
mkdir _build
|
||||
cd _build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS || exit $?
|
||||
cmake --build . --target install || exit $?
|
||||
make -j2 install || exit $?
|
||||
ctest -V . || exit $?
|
||||
|
||||
# Now that we've tested the raw git protocol, let's set up ssh to we
|
||||
# can do the push tests over it
|
||||
|
||||
killall git-daemon
|
||||
sudo start ssh
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
echo 'PasswordAuthentication yes' | sudo tee -a /etc/sshd_config
|
||||
else
|
||||
sudo start ssh
|
||||
fi
|
||||
|
||||
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N "" -q
|
||||
cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
|
||||
ssh-keyscan -t rsa localhost >>~/.ssh/known_hosts
|
||||
|
||||
# Get the fingerprint for localhost and remove the colons so we can parse it as a hex number
|
||||
export GITTEST_REMOTE_SSH_FINGERPRINT=$(ssh-keygen -F localhost -l | tail -n 1 | cut -d ' ' -f 2 | tr -d ':')
|
||||
|
||||
export GITTEST_REMOTE_URL="ssh://localhost/$HOME/_temp/test.git"
|
||||
export GITTEST_REMOTE_USER=$USER
|
||||
export GITTEST_REMOTE_SSH_KEY="$HOME/.ssh/id_rsa"
|
||||
@ -34,5 +43,6 @@ export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub"
|
||||
export GITTEST_REMOTE_SSH_PASSPHRASE=""
|
||||
|
||||
if [ -e ./libgit2_clar ]; then
|
||||
./libgit2_clar -sonline::push -sonline::clone::cred_callback_failure
|
||||
./libgit2_clar -sonline::push -sonline::clone::cred_callback -sonline::clone::ssh_cert &&
|
||||
./libgit2_clar -sonline::clone::ssh_with_paths
|
||||
fi
|
||||
|
6
script/install-deps-linux.sh
Executable file
6
script/install-deps-linux.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
|
||||
sudo apt-get -qq update &&
|
||||
sudo apt-get -qq install cmake libssh2-1-dev openssh-client openssh-server
|
5
script/install-deps-osx.sh
Executable file
5
script/install-deps-osx.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
|
||||
brew install libssh2 cmake
|
@ -44,7 +44,7 @@ typedef git_array_t(char) git_array_generic_t;
|
||||
/* use a generic array for growth so this can return the new item */
|
||||
GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
|
||||
{
|
||||
git_array_generic_t *a = _a;
|
||||
volatile git_array_generic_t *a = _a;
|
||||
uint32_t new_size = (a->size < 8) ? 8 : a->asize * 3 / 2;
|
||||
char *new_array = git__realloc(a->ptr, new_size * item_size);
|
||||
if (!new_array) {
|
||||
|
12
src/attr.c
12
src/attr.c
@ -377,7 +377,7 @@ static int push_attr_file(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int push_one_attr(void *ref, git_buf *path)
|
||||
static int push_one_attr(void *ref, const char *path)
|
||||
{
|
||||
int error = 0, n_src, i;
|
||||
attr_walk_up_info *info = (attr_walk_up_info *)ref;
|
||||
@ -388,7 +388,7 @@ static int push_one_attr(void *ref, git_buf *path)
|
||||
|
||||
for (i = 0; !error && i < n_src; ++i)
|
||||
error = push_attr_file(
|
||||
info->repo, info->files, src[i], path->ptr, GIT_ATTR_FILE);
|
||||
info->repo, info->files, src[i], path, GIT_ATTR_FILE);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -411,7 +411,7 @@ static int collect_attr_files(
|
||||
const char *path,
|
||||
git_vector *files)
|
||||
{
|
||||
int error;
|
||||
int error = 0;
|
||||
git_buf dir = GIT_BUF_INIT;
|
||||
const char *workdir = git_repository_workdir(repo);
|
||||
attr_walk_up_info info = { NULL };
|
||||
@ -447,7 +447,11 @@ static int collect_attr_files(
|
||||
giterr_clear(); /* no error even if there is no index */
|
||||
info.files = files;
|
||||
|
||||
error = git_path_walk_up(&dir, workdir, push_one_attr, &info);
|
||||
if (!strcmp(dir.ptr, "."))
|
||||
error = push_one_attr(&info, "");
|
||||
else
|
||||
error = git_path_walk_up(&dir, workdir, push_one_attr, &info);
|
||||
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
@ -281,7 +281,7 @@ uint32_t git_attr_file__name_hash(const char *name)
|
||||
|
||||
int git_attr_file__lookup_one(
|
||||
git_attr_file *file,
|
||||
const git_attr_path *path,
|
||||
git_attr_path *path,
|
||||
const char *attr,
|
||||
const char **value)
|
||||
{
|
||||
@ -342,14 +342,11 @@ int git_attr_file__load_standalone(git_attr_file **out, const char *path)
|
||||
|
||||
bool git_attr_fnmatch__match(
|
||||
git_attr_fnmatch *match,
|
||||
const git_attr_path *path)
|
||||
git_attr_path *path)
|
||||
{
|
||||
const char *filename;
|
||||
int flags = 0;
|
||||
|
||||
if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir)
|
||||
return false;
|
||||
|
||||
if (match->flags & GIT_ATTR_FNMATCH_ICASE)
|
||||
flags |= FNM_CASEFOLD;
|
||||
if (match->flags & GIT_ATTR_FNMATCH_LEADINGDIR)
|
||||
@ -365,12 +362,40 @@ bool git_attr_fnmatch__match(
|
||||
flags |= FNM_LEADING_DIR;
|
||||
}
|
||||
|
||||
if ((match->flags & GIT_ATTR_FNMATCH_DIRECTORY) && !path->is_dir) {
|
||||
int matchval;
|
||||
|
||||
/* for attribute checks or root ignore checks, fail match */
|
||||
if (!(match->flags & GIT_ATTR_FNMATCH_IGNORE) ||
|
||||
path->basename == path->path)
|
||||
return false;
|
||||
|
||||
/* for ignore checks, use container of current item for check */
|
||||
path->basename[-1] = '\0';
|
||||
flags |= FNM_LEADING_DIR;
|
||||
matchval = p_fnmatch(match->pattern, path->path, flags);
|
||||
path->basename[-1] = '/';
|
||||
return (matchval != FNM_NOMATCH);
|
||||
}
|
||||
|
||||
/* if path is a directory prefix of a negated pattern, then match */
|
||||
if ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) && path->is_dir) {
|
||||
size_t pathlen = strlen(path->path);
|
||||
bool prefixed = (pathlen <= match->length) &&
|
||||
((match->flags & GIT_ATTR_FNMATCH_ICASE) ?
|
||||
!strncasecmp(match->pattern, path->path, pathlen) :
|
||||
!strncmp(match->pattern, path->path, pathlen));
|
||||
|
||||
if (prefixed && git_path_at_end_of_segment(&match->pattern[pathlen]))
|
||||
return true;
|
||||
}
|
||||
|
||||
return (p_fnmatch(match->pattern, filename, flags) != FNM_NOMATCH);
|
||||
}
|
||||
|
||||
bool git_attr_rule__match(
|
||||
git_attr_rule *rule,
|
||||
const git_attr_path *path)
|
||||
git_attr_path *path)
|
||||
{
|
||||
bool matched = git_attr_fnmatch__match(&rule->match, path);
|
||||
|
||||
@ -509,7 +534,8 @@ int git_attr_fnmatch__parse(
|
||||
}
|
||||
|
||||
if (*pattern == '!' && (spec->flags & GIT_ATTR_FNMATCH_ALLOWNEG) != 0) {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_NEGATIVE;
|
||||
spec->flags = spec->flags |
|
||||
GIT_ATTR_FNMATCH_NEGATIVE | GIT_ATTR_FNMATCH_LEADINGDIR;
|
||||
pattern++;
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ int git_attr_file__clear_rules(
|
||||
|
||||
int git_attr_file__lookup_one(
|
||||
git_attr_file *file,
|
||||
const git_attr_path *path,
|
||||
git_attr_path *path,
|
||||
const char *attr,
|
||||
const char **value);
|
||||
|
||||
@ -162,13 +162,13 @@ extern int git_attr_fnmatch__parse(
|
||||
|
||||
extern bool git_attr_fnmatch__match(
|
||||
git_attr_fnmatch *rule,
|
||||
const git_attr_path *path);
|
||||
git_attr_path *path);
|
||||
|
||||
extern void git_attr_rule__free(git_attr_rule *rule);
|
||||
|
||||
extern bool git_attr_rule__match(
|
||||
git_attr_rule *rule,
|
||||
const git_attr_path *path);
|
||||
git_attr_path *path);
|
||||
|
||||
extern git_attr_assignment *git_attr_rule__lookup_assignment(
|
||||
git_attr_rule *rule, const char *name);
|
||||
|
@ -53,7 +53,7 @@ int git_attr_cache__alloc_file_entry(
|
||||
cachesize++;
|
||||
}
|
||||
|
||||
ce = git_pool_mallocz(pool, cachesize);
|
||||
ce = git_pool_mallocz(pool, (uint32_t)cachesize);
|
||||
GITERR_CHECK_ALLOC(ce);
|
||||
|
||||
if (baselen) {
|
||||
@ -349,14 +349,11 @@ int git_attr_cache__do_init(git_repository *repo)
|
||||
{
|
||||
int ret = 0;
|
||||
git_attr_cache *cache = git_repository_attr_cache(repo);
|
||||
git_config *cfg;
|
||||
git_config *cfg = NULL;
|
||||
|
||||
if (cache)
|
||||
return 0;
|
||||
|
||||
if ((ret = git_repository_config__weakptr(&cfg, repo)) < 0)
|
||||
return ret;
|
||||
|
||||
cache = git__calloc(1, sizeof(git_attr_cache));
|
||||
GITERR_CHECK_ALLOC(cache);
|
||||
|
||||
@ -367,6 +364,9 @@ int git_attr_cache__do_init(git_repository *repo)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ret = git_repository_config_snapshot(&cfg, repo)) < 0)
|
||||
goto cancel;
|
||||
|
||||
/* cache config settings for attributes and ignores */
|
||||
ret = attr_cache__lookup_path(
|
||||
&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG, GIT_ATTR_FILE_XDG);
|
||||
@ -390,11 +390,14 @@ int git_attr_cache__do_init(git_repository *repo)
|
||||
if (cache)
|
||||
goto cancel; /* raced with another thread, free this but no error */
|
||||
|
||||
git_config_free(cfg);
|
||||
|
||||
/* insert default macros */
|
||||
return git_attr_add_macro(repo, "binary", "-diff -crlf -text");
|
||||
|
||||
cancel:
|
||||
attr_cache__free(cache);
|
||||
git_config_free(cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
14
src/blame.c
14
src/blame.c
@ -316,7 +316,6 @@ static int blame_internal(git_blame *blame)
|
||||
ent->suspect = o;
|
||||
|
||||
blame->ent = ent;
|
||||
blame->path = blame->path;
|
||||
|
||||
git_blame__like_git(blame, blame->options.flags);
|
||||
|
||||
@ -480,14 +479,9 @@ int git_blame_buffer(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_blame_init_options(git_blame_options* opts, int version)
|
||||
int git_blame_init_options(git_blame_options *opts, unsigned int version)
|
||||
{
|
||||
if (version != GIT_BLAME_OPTIONS_VERSION) {
|
||||
giterr_set(GITERR_INVALID, "Invalid version %d for git_blame_options", version);
|
||||
return -1;
|
||||
} else {
|
||||
git_blame_options o = GIT_BLAME_OPTIONS_INIT;
|
||||
memcpy(opts, &o, sizeof(o));
|
||||
return 0;
|
||||
}
|
||||
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
|
||||
opts, version, git_blame_options, GIT_BLAME_OPTIONS_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
@ -198,7 +198,8 @@ int git_blob__create_from_paths(
|
||||
if (try_load_filters)
|
||||
/* Load the filters for writing this file to the ODB */
|
||||
error = git_filter_list_load(
|
||||
&fl, repo, NULL, hint_path, GIT_FILTER_TO_ODB);
|
||||
&fl, repo, NULL, hint_path,
|
||||
GIT_FILTER_TO_ODB, GIT_FILTER_OPT_DEFAULT);
|
||||
|
||||
if (error < 0)
|
||||
/* well, that didn't work */;
|
||||
@ -333,7 +334,8 @@ int git_blob_is_binary(const git_blob *blob)
|
||||
assert(blob);
|
||||
|
||||
content.ptr = blob->odb_object->buffer;
|
||||
content.size = min(blob->odb_object->cached.size, 4000);
|
||||
content.size =
|
||||
min(blob->odb_object->cached.size, GIT_FILTER_BYTES_TO_CHECK_NUL);
|
||||
content.asize = 0;
|
||||
|
||||
return git_buf_text_is_binary(&content);
|
||||
@ -356,7 +358,8 @@ int git_blob_filtered_content(
|
||||
return 0;
|
||||
|
||||
if (!(error = git_filter_list_load(
|
||||
&fl, git_blob_owner(blob), blob, path, GIT_FILTER_TO_WORKTREE))) {
|
||||
&fl, git_blob_owner(blob), blob, path,
|
||||
GIT_FILTER_TO_WORKTREE, GIT_FILTER_OPT_DEFAULT))) {
|
||||
|
||||
error = git_filter_list_apply_to_blob(out, fl, blob);
|
||||
|
||||
|
15
src/branch.c
15
src/branch.c
@ -306,17 +306,13 @@ int git_branch_name(
|
||||
|
||||
static int retrieve_upstream_configuration(
|
||||
const char **out,
|
||||
git_repository *repo,
|
||||
const git_config *config,
|
||||
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;
|
||||
@ -336,6 +332,7 @@ int git_branch_upstream_name(
|
||||
int error = -1;
|
||||
git_remote *remote = NULL;
|
||||
const git_refspec *refspec;
|
||||
git_config *config;
|
||||
|
||||
assert(out && refname);
|
||||
|
||||
@ -344,12 +341,15 @@ int git_branch_upstream_name(
|
||||
if (!git_reference__is_branch(refname))
|
||||
return not_a_local_branch(refname);
|
||||
|
||||
if ((error = git_repository_config_snapshot(&config, repo)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = retrieve_upstream_configuration(
|
||||
&remote_name, repo, refname, "branch.%s.remote")) < 0)
|
||||
&remote_name, config, refname, "branch.%s.remote")) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = retrieve_upstream_configuration(
|
||||
&merge_name, repo, refname, "branch.%s.merge")) < 0)
|
||||
&merge_name, config, refname, "branch.%s.merge")) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!*remote_name || !*merge_name) {
|
||||
@ -378,6 +378,7 @@ int git_branch_upstream_name(
|
||||
error = git_buf_set(out, git_buf_cstr(&buf), git_buf_len(&buf));
|
||||
|
||||
cleanup:
|
||||
git_config_free(config);
|
||||
git_remote_free(remote);
|
||||
git_buf_free(&buf);
|
||||
return error;
|
||||
|
@ -123,9 +123,13 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
|
||||
|
||||
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;
|
||||
size_t needsize = tgt->size + copylen + 2 + 1;
|
||||
|
||||
/* if we find mixed line endings, bail */
|
||||
if (next > start && next[-1] == '\r') {
|
||||
git_buf_free(tgt);
|
||||
return GIT_PASSTHROUGH;
|
||||
}
|
||||
|
||||
if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0)
|
||||
return -1;
|
||||
@ -134,8 +138,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
|
||||
memcpy(tgt->ptr + tgt->size, scan, copylen);
|
||||
tgt->size += copylen;
|
||||
}
|
||||
if (extralen == 2)
|
||||
tgt->ptr[tgt->size++] = '\r';
|
||||
|
||||
tgt->ptr[tgt->size++] = '\r';
|
||||
tgt->ptr[tgt->size++] = '\n';
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,10 @@ GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string)
|
||||
extern void git_buf_text_unescape(git_buf *buf);
|
||||
|
||||
/**
|
||||
* Replace all \r\n with \n. Does not modify \r without trailing \n.
|
||||
* Replace all \r\n with \n.
|
||||
*
|
||||
* @return 0 on success, -1 on memory error
|
||||
* @return 0 on success, -1 on memory error, GIT_PASSTHROUGH if the
|
||||
* source buffer has mixed line endings.
|
||||
*/
|
||||
extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src);
|
||||
|
||||
|
114
src/buffer.c
114
src/buffer.c
@ -7,6 +7,7 @@
|
||||
#include "buffer.h"
|
||||
#include "posix.h"
|
||||
#include "git2/buffer.h"
|
||||
#include "buf_text.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* Used as default value for git_buf->ptr so that people can always
|
||||
@ -104,17 +105,20 @@ void git_buf_free(git_buf *buf)
|
||||
void git_buf_sanitize(git_buf *buf)
|
||||
{
|
||||
if (buf->ptr == NULL) {
|
||||
assert (buf->size == 0 && buf->asize == 0);
|
||||
assert(buf->size == 0 && buf->asize == 0);
|
||||
buf->ptr = git_buf__initbuf;
|
||||
}
|
||||
} else if (buf->asize > buf->size)
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
|
||||
void git_buf_clear(git_buf *buf)
|
||||
{
|
||||
buf->size = 0;
|
||||
|
||||
if (!buf->ptr)
|
||||
if (!buf->ptr) {
|
||||
buf->ptr = git_buf__initbuf;
|
||||
buf->asize = 0;
|
||||
}
|
||||
|
||||
if (buf->asize > 0)
|
||||
buf->ptr[0] = '\0';
|
||||
@ -129,12 +133,25 @@ int git_buf_set(git_buf *buf, const void *data, size_t len)
|
||||
ENSURE_SIZE(buf, len + 1);
|
||||
memmove(buf->ptr, data, len);
|
||||
}
|
||||
|
||||
buf->size = len;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
if (buf->asize > buf->size)
|
||||
buf->ptr[buf->size] = '\0';
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_is_binary(const git_buf *buf)
|
||||
{
|
||||
return git_buf_text_is_binary(buf);
|
||||
}
|
||||
|
||||
int git_buf_contains_nul(const git_buf *buf)
|
||||
{
|
||||
return git_buf_text_contains_nul(buf);
|
||||
}
|
||||
|
||||
int git_buf_sets(git_buf *buf, const char *string)
|
||||
{
|
||||
return git_buf_set(buf, string, string ? strlen(string) : 0);
|
||||
@ -172,10 +189,10 @@ int git_buf_puts(git_buf *buf, const char *string)
|
||||
return git_buf_put(buf, string, strlen(string));
|
||||
}
|
||||
|
||||
static const char b64str[] =
|
||||
static const char base64_encode[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
int git_buf_put_base64(git_buf *buf, const char *data, size_t len)
|
||||
int git_buf_encode_base64(git_buf *buf, const char *data, size_t len)
|
||||
{
|
||||
size_t extra = len % 3;
|
||||
uint8_t *write, a, b, c;
|
||||
@ -190,19 +207,19 @@ int git_buf_put_base64(git_buf *buf, const char *data, size_t len)
|
||||
b = *read++;
|
||||
c = *read++;
|
||||
|
||||
*write++ = b64str[a >> 2];
|
||||
*write++ = b64str[(a & 0x03) << 4 | b >> 4];
|
||||
*write++ = b64str[(b & 0x0f) << 2 | c >> 6];
|
||||
*write++ = b64str[c & 0x3f];
|
||||
*write++ = base64_encode[a >> 2];
|
||||
*write++ = base64_encode[(a & 0x03) << 4 | b >> 4];
|
||||
*write++ = base64_encode[(b & 0x0f) << 2 | c >> 6];
|
||||
*write++ = base64_encode[c & 0x3f];
|
||||
}
|
||||
|
||||
if (extra > 0) {
|
||||
a = *read++;
|
||||
b = (extra > 1) ? *read++ : 0;
|
||||
|
||||
*write++ = b64str[a >> 2];
|
||||
*write++ = b64str[(a & 0x03) << 4 | b >> 4];
|
||||
*write++ = (extra > 1) ? b64str[(b & 0x0f) << 2] : '=';
|
||||
*write++ = base64_encode[a >> 2];
|
||||
*write++ = base64_encode[(a & 0x03) << 4 | b >> 4];
|
||||
*write++ = (extra > 1) ? base64_encode[(b & 0x0f) << 2] : '=';
|
||||
*write++ = '=';
|
||||
}
|
||||
|
||||
@ -212,10 +229,56 @@ int git_buf_put_base64(git_buf *buf, const char *data, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The inverse of base64_encode, offset by '+' == 43. */
|
||||
static const int8_t base64_decode[] = {
|
||||
62,
|
||||
-1, -1, -1,
|
||||
63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
|
||||
-1, -1, -1, 0, -1, -1, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||
-1, -1, -1, -1, -1, -1,
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
};
|
||||
|
||||
#define BASE64_DECODE_VALUE(c) (((c) < 43 || (c) > 122) ? -1 : base64_decode[c - 43])
|
||||
|
||||
int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int8_t a, b, c, d;
|
||||
size_t orig_size = buf->size;
|
||||
|
||||
assert(len % 4 == 0);
|
||||
ENSURE_SIZE(buf, buf->size + (len / 4 * 3) + 1);
|
||||
|
||||
for (i = 0; i < len; i += 4) {
|
||||
if ((a = BASE64_DECODE_VALUE(base64[i])) < 0 ||
|
||||
(b = BASE64_DECODE_VALUE(base64[i+1])) < 0 ||
|
||||
(c = BASE64_DECODE_VALUE(base64[i+2])) < 0 ||
|
||||
(d = BASE64_DECODE_VALUE(base64[i+3])) < 0) {
|
||||
buf->size = orig_size;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
|
||||
giterr_set(GITERR_INVALID, "Invalid base64 input");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf->ptr[buf->size++] = ((a << 2) | (b & 0x30) >> 4);
|
||||
buf->ptr[buf->size++] = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
|
||||
buf->ptr[buf->size++] = (c & 0x03) << 6 | (d & 0x3f);
|
||||
}
|
||||
|
||||
buf->ptr[buf->size] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char b85str[] =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
|
||||
|
||||
int git_buf_put_base85(git_buf *buf, const char *data, size_t len)
|
||||
int git_buf_encode_base85(git_buf *buf, const char *data, size_t len)
|
||||
{
|
||||
ENSURE_SIZE(buf, buf->size + (5 * ((len / 4) + !!(len % 4))) + 1);
|
||||
|
||||
@ -326,19 +389,20 @@ void git_buf_consume(git_buf *buf, const char *end)
|
||||
|
||||
void git_buf_truncate(git_buf *buf, size_t len)
|
||||
{
|
||||
if (len < buf->size) {
|
||||
buf->size = len;
|
||||
if (len >= buf->size)
|
||||
return;
|
||||
|
||||
buf->size = len;
|
||||
if (buf->size < buf->asize)
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void git_buf_shorten(git_buf *buf, size_t amount)
|
||||
{
|
||||
if (amount > buf->size)
|
||||
amount = buf->size;
|
||||
|
||||
buf->size = buf->size - amount;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
if (buf->size > amount)
|
||||
git_buf_truncate(buf, buf->size - amount);
|
||||
else
|
||||
git_buf_clear(buf);
|
||||
}
|
||||
|
||||
void git_buf_rtruncate_at_char(git_buf *buf, char separator)
|
||||
@ -574,7 +638,8 @@ void git_buf_rtrim(git_buf *buf)
|
||||
buf->size--;
|
||||
}
|
||||
|
||||
buf->ptr[buf->size] = '\0';
|
||||
if (buf->asize > buf->size)
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
|
||||
int git_buf_cmp(const git_buf *a, const git_buf *b)
|
||||
@ -598,8 +663,7 @@ int git_buf_splice(
|
||||
/* Ported from git.git
|
||||
* https://github.com/git/git/blob/16eed7c/strbuf.c#L159-176
|
||||
*/
|
||||
if (git_buf_grow(buf, git_buf_len(buf) + nb_to_insert - nb_to_remove) < 0)
|
||||
return -1;
|
||||
ENSURE_SIZE(buf, buf->size + nb_to_insert - nb_to_insert + 1);
|
||||
|
||||
memmove(buf->ptr + where + nb_to_insert,
|
||||
buf->ptr + where + nb_to_remove,
|
||||
|
@ -156,10 +156,12 @@ void git_buf_rtrim(git_buf *buf);
|
||||
int git_buf_cmp(const git_buf *a, const git_buf *b);
|
||||
|
||||
/* Write data as base64 encoded in buffer */
|
||||
int git_buf_put_base64(git_buf *buf, const char *data, size_t len);
|
||||
int git_buf_encode_base64(git_buf *buf, const char *data, size_t len);
|
||||
/* Decode the given bas64 and write the result to the buffer */
|
||||
int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len);
|
||||
|
||||
/* Write data as "base85" encoded in buffer */
|
||||
int git_buf_put_base85(git_buf *buf, const char *data, size_t len);
|
||||
int git_buf_encode_base85(git_buf *buf, const char *data, size_t len);
|
||||
|
||||
/*
|
||||
* Insert, remove or replace a portion of the buffer.
|
||||
|
18
src/cache.c
18
src/cache.c
@ -68,8 +68,8 @@ int git_cache_init(git_cache *cache)
|
||||
{
|
||||
memset(cache, 0, sizeof(*cache));
|
||||
cache->map = git_oidmap_alloc();
|
||||
if (git_mutex_init(&cache->lock)) {
|
||||
giterr_set(GITERR_OS, "Failed to initialize cache mutex");
|
||||
if (git_rwlock_init(&cache->lock)) {
|
||||
giterr_set(GITERR_OS, "Failed to initialize cache rwlock");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -94,19 +94,19 @@ static void clear_cache(git_cache *cache)
|
||||
|
||||
void git_cache_clear(git_cache *cache)
|
||||
{
|
||||
if (git_mutex_lock(&cache->lock) < 0)
|
||||
if (git_rwlock_wrlock(&cache->lock) < 0)
|
||||
return;
|
||||
|
||||
clear_cache(cache);
|
||||
|
||||
git_mutex_unlock(&cache->lock);
|
||||
git_rwlock_wrunlock(&cache->lock);
|
||||
}
|
||||
|
||||
void git_cache_free(git_cache *cache)
|
||||
{
|
||||
git_cache_clear(cache);
|
||||
git_oidmap_free(cache->map);
|
||||
git_mutex_free(&cache->lock);
|
||||
git_rwlock_free(&cache->lock);
|
||||
git__memzero(cache, sizeof(*cache));
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags)
|
||||
khiter_t pos;
|
||||
git_cached_obj *entry = NULL;
|
||||
|
||||
if (!git_cache__enabled || git_mutex_lock(&cache->lock) < 0)
|
||||
if (!git_cache__enabled || git_rwlock_rdlock(&cache->lock) < 0)
|
||||
return NULL;
|
||||
|
||||
pos = kh_get(oid, cache->map, oid);
|
||||
@ -166,7 +166,7 @@ static void *cache_get(git_cache *cache, const git_oid *oid, unsigned int flags)
|
||||
}
|
||||
}
|
||||
|
||||
git_mutex_unlock(&cache->lock);
|
||||
git_rwlock_rdunlock(&cache->lock);
|
||||
|
||||
return entry;
|
||||
}
|
||||
@ -185,7 +185,7 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
|
||||
if (!cache_should_store(entry->type, entry->size))
|
||||
return entry;
|
||||
|
||||
if (git_mutex_lock(&cache->lock) < 0)
|
||||
if (git_rwlock_wrlock(&cache->lock) < 0)
|
||||
return entry;
|
||||
|
||||
/* soften the load on the cache */
|
||||
@ -227,7 +227,7 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
|
||||
}
|
||||
}
|
||||
|
||||
git_mutex_unlock(&cache->lock);
|
||||
git_rwlock_wrunlock(&cache->lock);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
git_oidmap *map;
|
||||
git_mutex lock;
|
||||
git_rwlock lock;
|
||||
ssize_t used_memory;
|
||||
} git_cache;
|
||||
|
||||
|
@ -35,6 +35,14 @@
|
||||
# define GIT_TYPEOF(x)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define GIT_ALIGN(x,size) x __attribute__ ((aligned(size)))
|
||||
#elif defined(_MSC_VER)
|
||||
# define GIT_ALIGN(x,size) __declspec(align(size)) x
|
||||
#else
|
||||
# define GIT_ALIGN(x,size) x
|
||||
#endif
|
||||
|
||||
#define GIT_UNUSED(x) ((void)(x))
|
||||
|
||||
/* Define the printf format specifer to use for size_t output */
|
||||
|
161
src/checkout.c
161
src/checkout.c
@ -46,6 +46,7 @@ enum {
|
||||
|
||||
typedef struct {
|
||||
git_repository *repo;
|
||||
git_iterator *target;
|
||||
git_diff *diff;
|
||||
git_checkout_options opts;
|
||||
bool opts_free_baseline;
|
||||
@ -54,6 +55,8 @@ typedef struct {
|
||||
git_pool pool;
|
||||
git_vector removes;
|
||||
git_vector conflicts;
|
||||
git_vector *reuc;
|
||||
git_vector *names;
|
||||
git_buf path;
|
||||
size_t workdir_len;
|
||||
git_buf tmp;
|
||||
@ -116,6 +119,7 @@ static int checkout_notify(
|
||||
case GIT_DELTA_ADDED:
|
||||
case GIT_DELTA_IGNORED:
|
||||
case GIT_DELTA_UNTRACKED:
|
||||
case GIT_DELTA_UNREADABLE:
|
||||
target = &delta->new_file;
|
||||
break;
|
||||
case GIT_DELTA_DELETED:
|
||||
@ -138,6 +142,7 @@ static int checkout_notify(
|
||||
static bool checkout_is_workdir_modified(
|
||||
checkout_data *data,
|
||||
const git_diff_file *baseitem,
|
||||
const git_diff_file *newitem,
|
||||
const git_index_entry *wditem)
|
||||
{
|
||||
git_oid oid;
|
||||
@ -169,13 +174,16 @@ static bool checkout_is_workdir_modified(
|
||||
|
||||
/* Look at the cache to decide if the workdir is modified. If not,
|
||||
* we can simply compare the oid in the cache to the baseitem instead
|
||||
* of hashing the file.
|
||||
* of hashing the file. If so, we allow the checkout to proceed if the
|
||||
* oid is identical (ie, the staged item is what we're trying to check
|
||||
* out.)
|
||||
*/
|
||||
if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) {
|
||||
if (wditem->mtime.seconds == ie->mtime.seconds &&
|
||||
wditem->mtime.nanoseconds == ie->mtime.nanoseconds &&
|
||||
wditem->file_size == ie->file_size)
|
||||
return (git_oid__cmp(&baseitem->id, &ie->id) != 0);
|
||||
return (git_oid__cmp(&baseitem->id, &ie->id) != 0 &&
|
||||
git_oid_cmp(&newitem->id, &ie->id) != 0);
|
||||
}
|
||||
|
||||
/* depending on where base is coming from, we may or may not know
|
||||
@ -184,9 +192,7 @@ static bool checkout_is_workdir_modified(
|
||||
if (baseitem->size && wditem->file_size != baseitem->size)
|
||||
return true;
|
||||
|
||||
if (git_diff__oid_for_file(
|
||||
data->repo, wditem->path, wditem->mode,
|
||||
wditem->file_size, &oid) < 0)
|
||||
if (git_diff__oid_for_entry(&oid, data->diff, wditem, NULL) < 0)
|
||||
return false;
|
||||
|
||||
return (git_oid__cmp(&baseitem->id, &oid) != 0);
|
||||
@ -403,7 +409,7 @@ static int checkout_action_with_wd(
|
||||
|
||||
switch (delta->status) {
|
||||
case GIT_DELTA_UNMODIFIED: /* case 14/15 or 33 */
|
||||
if (checkout_is_workdir_modified(data, &delta->old_file, wd)) {
|
||||
if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd)) {
|
||||
GITERR_CHECK_ERROR(
|
||||
checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd) );
|
||||
*action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, NONE);
|
||||
@ -416,13 +422,13 @@ static int checkout_action_with_wd(
|
||||
*action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
|
||||
break;
|
||||
case GIT_DELTA_DELETED: /* case 9 or 10 (or 26 but not really) */
|
||||
if (checkout_is_workdir_modified(data, &delta->old_file, wd))
|
||||
if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
|
||||
*action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
|
||||
else
|
||||
*action = CHECKOUT_ACTION_IF(SAFE, REMOVE, NONE);
|
||||
break;
|
||||
case GIT_DELTA_MODIFIED: /* case 16, 17, 18 (or 36 but not really) */
|
||||
if (checkout_is_workdir_modified(data, &delta->old_file, wd))
|
||||
if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
|
||||
*action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
|
||||
else
|
||||
*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
|
||||
@ -445,7 +451,7 @@ static int checkout_action_with_wd(
|
||||
} else
|
||||
*action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
|
||||
}
|
||||
else if (checkout_is_workdir_modified(data, &delta->old_file, wd))
|
||||
else if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
|
||||
*action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
|
||||
else
|
||||
*action = CHECKOUT_ACTION_IF(SAFE, REMOVE_AND_UPDATE, NONE);
|
||||
@ -790,11 +796,16 @@ done:
|
||||
static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, git_vector *pathspec)
|
||||
{
|
||||
git_index_conflict_iterator *iterator = NULL;
|
||||
git_index *index;
|
||||
const git_index_entry *ancestor, *ours, *theirs;
|
||||
checkout_conflictdata *conflict;
|
||||
int error = 0;
|
||||
|
||||
if ((error = git_index_conflict_iterator_new(&iterator, data->index)) < 0)
|
||||
/* Only write conficts from sources that have them: indexes. */
|
||||
if ((index = git_iterator_get_index(data->target)) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((error = git_index_conflict_iterator_new(&iterator, index)) < 0)
|
||||
goto done;
|
||||
|
||||
data->conflicts._cmp = checkout_conflictdata_cmp;
|
||||
@ -821,6 +832,10 @@ static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, g
|
||||
git_vector_insert(&data->conflicts, conflict);
|
||||
}
|
||||
|
||||
/* Collect the REUC and NAME entries */
|
||||
data->reuc = &index->reuc;
|
||||
data->names = &index->names;
|
||||
|
||||
if (error == GIT_ITEROVER)
|
||||
error = 0;
|
||||
|
||||
@ -959,16 +974,20 @@ done:
|
||||
static int checkout_conflicts_coalesce_renames(
|
||||
checkout_data *data)
|
||||
{
|
||||
git_index *index;
|
||||
const git_index_name_entry *name_entry;
|
||||
checkout_conflictdata *ancestor_conflict, *our_conflict, *their_conflict;
|
||||
size_t i, names;
|
||||
int error = 0;
|
||||
|
||||
if ((index = git_iterator_get_index(data->target)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Juggle entries based on renames */
|
||||
names = git_index_name_entrycount(data->index);
|
||||
names = git_index_name_entrycount(index);
|
||||
|
||||
for (i = 0; i < names; i++) {
|
||||
name_entry = git_index_name_get_byindex(data->index, i);
|
||||
name_entry = git_index_name_get_byindex(index, i);
|
||||
|
||||
if ((error = checkout_conflicts_load_byname_entry(
|
||||
&ancestor_conflict, &our_conflict, &their_conflict,
|
||||
@ -1012,13 +1031,17 @@ done:
|
||||
static int checkout_conflicts_mark_directoryfile(
|
||||
checkout_data *data)
|
||||
{
|
||||
git_index *index;
|
||||
checkout_conflictdata *conflict;
|
||||
const git_index_entry *entry;
|
||||
size_t i, j, len;
|
||||
const char *path;
|
||||
int prefixed, error = 0;
|
||||
|
||||
len = git_index_entrycount(data->index);
|
||||
if ((index = git_iterator_get_index(data->target)) == NULL)
|
||||
return 0;
|
||||
|
||||
len = git_index_entrycount(index);
|
||||
|
||||
/* Find d/f conflicts */
|
||||
git_vector_foreach(&data->conflicts, i, conflict) {
|
||||
@ -1029,7 +1052,7 @@ static int checkout_conflicts_mark_directoryfile(
|
||||
path = conflict->ours ?
|
||||
conflict->ours->path : conflict->theirs->path;
|
||||
|
||||
if ((error = git_index_find(&j, data->index, path)) < 0) {
|
||||
if ((error = git_index_find(&j, index, path)) < 0) {
|
||||
if (error == GIT_ENOTFOUND)
|
||||
giterr_set(GITERR_INDEX,
|
||||
"Index inconsistency, could not find entry for expected conflict '%s'", path);
|
||||
@ -1038,7 +1061,7 @@ static int checkout_conflicts_mark_directoryfile(
|
||||
}
|
||||
|
||||
for (; j < len; j++) {
|
||||
if ((entry = git_index_get_byindex(data->index, j)) == NULL) {
|
||||
if ((entry = git_index_get_byindex(index, j)) == NULL) {
|
||||
giterr_set(GITERR_INDEX,
|
||||
"Index inconsistency, truncated index while loading expected conflict '%s'", path);
|
||||
error = -1;
|
||||
@ -1214,7 +1237,8 @@ static int blob_content_to_file(
|
||||
|
||||
if (!opts->disable_filters)
|
||||
error = git_filter_list_load(
|
||||
&fl, git_blob_owner(blob), blob, hint_path, GIT_FILTER_TO_WORKTREE);
|
||||
&fl, git_blob_owner(blob), blob, hint_path,
|
||||
GIT_FILTER_TO_WORKTREE, GIT_FILTER_OPT_DEFAULT);
|
||||
|
||||
if (!error)
|
||||
error = git_filter_list_apply_to_blob(&out, fl, blob);
|
||||
@ -1803,6 +1827,24 @@ done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int checkout_conflict_update_index(
|
||||
checkout_data *data,
|
||||
checkout_conflictdata *conflict)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (conflict->ancestor)
|
||||
error = git_index_add(data->index, conflict->ancestor);
|
||||
|
||||
if (!error && conflict->ours)
|
||||
error = git_index_add(data->index, conflict->ours);
|
||||
|
||||
if (!error && conflict->theirs)
|
||||
error = git_index_add(data->index, conflict->theirs);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int checkout_create_conflicts(checkout_data *data)
|
||||
{
|
||||
checkout_conflictdata *conflict;
|
||||
@ -1865,6 +1907,12 @@ static int checkout_create_conflicts(checkout_data *data)
|
||||
else if (!error)
|
||||
error = checkout_write_merge(data, conflict);
|
||||
|
||||
/* Update the index extensions (REUC and NAME) if we're checking
|
||||
* out a different index. (Otherwise just leave them there.)
|
||||
*/
|
||||
if (!error && (data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0)
|
||||
error = checkout_conflict_update_index(data, conflict);
|
||||
|
||||
if (error)
|
||||
break;
|
||||
|
||||
@ -1877,6 +1925,37 @@ static int checkout_create_conflicts(checkout_data *data)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int checkout_extensions_update_index(checkout_data *data)
|
||||
{
|
||||
const git_index_reuc_entry *reuc_entry;
|
||||
const git_index_name_entry *name_entry;
|
||||
size_t i;
|
||||
int error = 0;
|
||||
|
||||
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0)
|
||||
return 0;
|
||||
|
||||
if (data->reuc) {
|
||||
git_vector_foreach(data->reuc, i, reuc_entry) {
|
||||
if ((error = git_index_reuc_add(data->index, reuc_entry->path,
|
||||
reuc_entry->mode[0], &reuc_entry->oid[0],
|
||||
reuc_entry->mode[1], &reuc_entry->oid[1],
|
||||
reuc_entry->mode[2], &reuc_entry->oid[2])) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->names) {
|
||||
git_vector_foreach(data->names, i, name_entry) {
|
||||
if ((error = git_index_name_add(data->index, name_entry->ancestor,
|
||||
name_entry->ours, name_entry->theirs)) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static void checkout_data_clear(checkout_data *data)
|
||||
{
|
||||
@ -1920,6 +1999,7 @@ static int checkout_data_init(
|
||||
return error;
|
||||
|
||||
data->repo = repo;
|
||||
data->target = target;
|
||||
|
||||
GITERR_CHECK_VERSION(
|
||||
proposed, GIT_CHECKOUT_OPTIONS_VERSION, "git_checkout_options");
|
||||
@ -1944,15 +2024,15 @@ static int checkout_data_init(
|
||||
(error = git_config_refresh(cfg)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* if we are checking out the index, don't reload,
|
||||
* otherwise get index and force reload
|
||||
/* Get the repository index and reload it (unless we're checking
|
||||
* out the index; then it has the changes we're trying to check
|
||||
* out and those should not be overwritten.)
|
||||
*/
|
||||
if ((data->index = git_iterator_get_index(target)) != NULL) {
|
||||
GIT_REFCOUNT_INC(data->index);
|
||||
} else {
|
||||
/* otherwise, grab and reload the index */
|
||||
if ((error = git_repository_index(&data->index, data->repo)) < 0 ||
|
||||
(error = git_index_read(data->index, true)) < 0)
|
||||
if ((error = git_repository_index(&data->index, data->repo)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (data->index != git_iterator_get_index(target)) {
|
||||
if ((error = git_index_read(data->index, true)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* cannot checkout if unresolved conflicts exist */
|
||||
@ -1964,7 +2044,7 @@ static int checkout_data_init(
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* clean conflict data when doing a tree or commit checkout */
|
||||
/* clean conflict data in the current index */
|
||||
git_index_name_clear(data->index);
|
||||
git_index_reuc_clear(data->index);
|
||||
}
|
||||
@ -2064,6 +2144,7 @@ int git_checkout_iterator(
|
||||
|
||||
diff_opts.flags =
|
||||
GIT_DIFF_INCLUDE_UNMODIFIED |
|
||||
GIT_DIFF_INCLUDE_UNREADABLE |
|
||||
GIT_DIFF_INCLUDE_UNTRACKED |
|
||||
GIT_DIFF_RECURSE_UNTRACKED_DIRS | /* needed to match baseline */
|
||||
GIT_DIFF_INCLUDE_IGNORED |
|
||||
@ -2133,6 +2214,10 @@ int git_checkout_iterator(
|
||||
(error = checkout_create_conflicts(&data)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (data.index != git_iterator_get_index(target) &&
|
||||
(error = checkout_extensions_update_index(&data)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
assert(data.completed_steps == data.total_steps);
|
||||
|
||||
cleanup:
|
||||
@ -2155,7 +2240,7 @@ int git_checkout_index(
|
||||
git_index *index,
|
||||
const git_checkout_options *opts)
|
||||
{
|
||||
int error;
|
||||
int error, owned = 0;
|
||||
git_iterator *index_i;
|
||||
|
||||
if (!index && !repo) {
|
||||
@ -2163,10 +2248,16 @@ int git_checkout_index(
|
||||
"Must provide either repository or index to checkout");
|
||||
return -1;
|
||||
}
|
||||
if (index && repo && git_index_owner(index) != repo) {
|
||||
|
||||
if (index && repo &&
|
||||
git_index_owner(index) &&
|
||||
git_index_owner(index) != repo) {
|
||||
giterr_set(GITERR_CHECKOUT,
|
||||
"Index to checkout does not match repository");
|
||||
return -1;
|
||||
} else if(index && repo && !git_index_owner(index)) {
|
||||
GIT_REFCOUNT_OWN(index, repo);
|
||||
owned = 1;
|
||||
}
|
||||
|
||||
if (!repo)
|
||||
@ -2179,6 +2270,9 @@ int git_checkout_index(
|
||||
if (!(error = git_iterator_for_index(&index_i, index, 0, NULL, NULL)))
|
||||
error = git_checkout_iterator(index_i, opts);
|
||||
|
||||
if (owned)
|
||||
GIT_REFCOUNT_OWN(index, NULL);
|
||||
|
||||
git_iterator_free(index_i);
|
||||
git_index_free(index);
|
||||
|
||||
@ -2242,14 +2336,9 @@ int git_checkout_head(
|
||||
return git_checkout_tree(repo, NULL, opts);
|
||||
}
|
||||
|
||||
int git_checkout_init_opts(git_checkout_options* opts, int version)
|
||||
int git_checkout_init_options(git_checkout_options *opts, unsigned int version)
|
||||
{
|
||||
if (version != GIT_CHECKOUT_OPTIONS_VERSION) {
|
||||
giterr_set(GITERR_INVALID, "Invalid version %d for git_checkout_options", version);
|
||||
return -1;
|
||||
} else {
|
||||
git_checkout_options o = GIT_CHECKOUT_OPTIONS_INIT;
|
||||
memcpy(opts, &o, sizeof(o));
|
||||
return 0;
|
||||
}
|
||||
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
|
||||
opts, version, git_checkout_options, GIT_CHECKOUT_OPTIONS_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include "git2/commit.h"
|
||||
#include "git2/sys/commit.h"
|
||||
|
||||
#define GIT_CHERRY_PICK_FILE_MODE 0666
|
||||
#define GIT_CHERRYPICK_FILE_MODE 0666
|
||||
|
||||
static int write_cherry_pick_head(
|
||||
static int write_cherrypick_head(
|
||||
git_repository *repo,
|
||||
const char *commit_oidstr)
|
||||
{
|
||||
@ -27,8 +27,8 @@ static int write_cherry_pick_head(
|
||||
git_buf file_path = GIT_BUF_INIT;
|
||||
int error = 0;
|
||||
|
||||
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_CHERRY_PICK_HEAD_FILE)) >= 0 &&
|
||||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRY_PICK_FILE_MODE)) >= 0 &&
|
||||
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_CHERRYPICK_HEAD_FILE)) >= 0 &&
|
||||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) >= 0 &&
|
||||
(error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
|
||||
error = git_filebuf_commit(&file);
|
||||
|
||||
@ -49,7 +49,7 @@ static int write_merge_msg(
|
||||
int error = 0;
|
||||
|
||||
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
|
||||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRY_PICK_FILE_MODE)) < 0 ||
|
||||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) < 0 ||
|
||||
(error = git_filebuf_printf(&file, "%s", commit_msg)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -64,10 +64,10 @@ cleanup:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int cherry_pick_normalize_opts(
|
||||
static int cherrypick_normalize_opts(
|
||||
git_repository *repo,
|
||||
git_cherry_pick_options *opts,
|
||||
const git_cherry_pick_options *given,
|
||||
git_cherrypick_options *opts,
|
||||
const git_cherrypick_options *given,
|
||||
const char *their_label)
|
||||
{
|
||||
int error = 0;
|
||||
@ -77,10 +77,10 @@ static int cherry_pick_normalize_opts(
|
||||
GIT_UNUSED(repo);
|
||||
|
||||
if (given != NULL)
|
||||
memcpy(opts, given, sizeof(git_cherry_pick_options));
|
||||
memcpy(opts, given, sizeof(git_cherrypick_options));
|
||||
else {
|
||||
git_cherry_pick_options default_opts = GIT_CHERRY_PICK_OPTIONS_INIT;
|
||||
memcpy(opts, &default_opts, sizeof(git_cherry_pick_options));
|
||||
git_cherrypick_options default_opts = GIT_CHERRYPICK_OPTIONS_INIT;
|
||||
memcpy(opts, &default_opts, sizeof(git_cherrypick_options));
|
||||
}
|
||||
|
||||
if (!opts->checkout_opts.checkout_strategy)
|
||||
@ -95,14 +95,14 @@ static int cherry_pick_normalize_opts(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int cherry_pick_state_cleanup(git_repository *repo)
|
||||
static int cherrypick_state_cleanup(git_repository *repo)
|
||||
{
|
||||
const char *state_files[] = { GIT_CHERRY_PICK_HEAD_FILE, GIT_MERGE_MSG_FILE };
|
||||
const char *state_files[] = { GIT_CHERRYPICK_HEAD_FILE, GIT_MERGE_MSG_FILE };
|
||||
|
||||
return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
|
||||
}
|
||||
|
||||
static int cherry_pick_seterr(git_commit *commit, const char *fmt)
|
||||
static int cherrypick_seterr(git_commit *commit, const char *fmt)
|
||||
{
|
||||
char commit_oidstr[GIT_OID_HEXSZ + 1];
|
||||
|
||||
@ -112,71 +112,71 @@ static int cherry_pick_seterr(git_commit *commit, const char *fmt)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_cherry_pick_commit(
|
||||
int git_cherrypick_commit(
|
||||
git_index **out,
|
||||
git_repository *repo,
|
||||
git_commit *cherry_pick_commit,
|
||||
git_commit *cherrypick_commit,
|
||||
git_commit *our_commit,
|
||||
unsigned int mainline,
|
||||
const git_merge_options *merge_opts)
|
||||
{
|
||||
git_commit *parent_commit = NULL;
|
||||
git_tree *parent_tree = NULL, *our_tree = NULL, *cherry_pick_tree = NULL;
|
||||
git_tree *parent_tree = NULL, *our_tree = NULL, *cherrypick_tree = NULL;
|
||||
int parent = 0, error = 0;
|
||||
|
||||
assert(out && repo && cherry_pick_commit && our_commit);
|
||||
assert(out && repo && cherrypick_commit && our_commit);
|
||||
|
||||
if (git_commit_parentcount(cherry_pick_commit) > 1) {
|
||||
if (git_commit_parentcount(cherrypick_commit) > 1) {
|
||||
if (!mainline)
|
||||
return cherry_pick_seterr(cherry_pick_commit,
|
||||
return cherrypick_seterr(cherrypick_commit,
|
||||
"Mainline branch is not specified but %s is a merge commit");
|
||||
|
||||
parent = mainline;
|
||||
} else {
|
||||
if (mainline)
|
||||
return cherry_pick_seterr(cherry_pick_commit,
|
||||
return cherrypick_seterr(cherrypick_commit,
|
||||
"Mainline branch specified but %s is not a merge commit");
|
||||
|
||||
parent = git_commit_parentcount(cherry_pick_commit);
|
||||
parent = git_commit_parentcount(cherrypick_commit);
|
||||
}
|
||||
|
||||
if (parent &&
|
||||
((error = git_commit_parent(&parent_commit, cherry_pick_commit, (parent - 1))) < 0 ||
|
||||
((error = git_commit_parent(&parent_commit, cherrypick_commit, (parent - 1))) < 0 ||
|
||||
(error = git_commit_tree(&parent_tree, parent_commit)) < 0))
|
||||
goto done;
|
||||
|
||||
if ((error = git_commit_tree(&cherry_pick_tree, cherry_pick_commit)) < 0 ||
|
||||
if ((error = git_commit_tree(&cherrypick_tree, cherrypick_commit)) < 0 ||
|
||||
(error = git_commit_tree(&our_tree, our_commit)) < 0)
|
||||
goto done;
|
||||
|
||||
error = git_merge_trees(out, repo, parent_tree, our_tree, cherry_pick_tree, merge_opts);
|
||||
error = git_merge_trees(out, repo, parent_tree, our_tree, cherrypick_tree, merge_opts);
|
||||
|
||||
done:
|
||||
git_tree_free(parent_tree);
|
||||
git_tree_free(our_tree);
|
||||
git_tree_free(cherry_pick_tree);
|
||||
git_tree_free(cherrypick_tree);
|
||||
git_commit_free(parent_commit);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_cherry_pick(
|
||||
int git_cherrypick(
|
||||
git_repository *repo,
|
||||
git_commit *commit,
|
||||
const git_cherry_pick_options *given_opts)
|
||||
const git_cherrypick_options *given_opts)
|
||||
{
|
||||
git_cherry_pick_options opts;
|
||||
git_cherrypick_options opts;
|
||||
git_reference *our_ref = NULL;
|
||||
git_commit *our_commit = NULL;
|
||||
char commit_oidstr[GIT_OID_HEXSZ + 1];
|
||||
const char *commit_msg, *commit_summary;
|
||||
git_buf their_label = GIT_BUF_INIT;
|
||||
git_index *index_new = NULL, *index_repo = NULL;
|
||||
git_index *index_new = NULL;
|
||||
int error = 0;
|
||||
|
||||
assert(repo && commit);
|
||||
|
||||
GITERR_CHECK_VERSION(given_opts, GIT_CHERRY_PICK_OPTIONS_VERSION, "git_cherry_pick_options");
|
||||
GITERR_CHECK_VERSION(given_opts, GIT_CHERRYPICK_OPTIONS_VERSION, "git_cherrypick_options");
|
||||
|
||||
if ((error = git_repository__ensure_not_bare(repo, "cherry-pick")) < 0)
|
||||
return error;
|
||||
@ -191,25 +191,22 @@ int git_cherry_pick(
|
||||
|
||||
if ((error = write_merge_msg(repo, commit_msg)) < 0 ||
|
||||
(error = git_buf_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 ||
|
||||
(error = cherry_pick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 ||
|
||||
(error = write_cherry_pick_head(repo, commit_oidstr)) < 0 ||
|
||||
(error = cherrypick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 ||
|
||||
(error = write_cherrypick_head(repo, commit_oidstr)) < 0 ||
|
||||
(error = git_repository_head(&our_ref, repo)) < 0 ||
|
||||
(error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
|
||||
(error = git_cherry_pick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
|
||||
(error = git_merge__indexes(repo, index_new)) < 0 ||
|
||||
(error = git_repository_index(&index_repo, repo)) < 0 ||
|
||||
(error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
|
||||
(error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
|
||||
(error = git_cherrypick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
|
||||
(error = git_merge__check_result(repo, index_new)) < 0 ||
|
||||
(error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
|
||||
(error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0)
|
||||
goto on_error;
|
||||
|
||||
goto done;
|
||||
|
||||
on_error:
|
||||
cherry_pick_state_cleanup(repo);
|
||||
cherrypick_state_cleanup(repo);
|
||||
|
||||
done:
|
||||
git_index_free(index_new);
|
||||
git_index_free(index_repo);
|
||||
git_commit_free(our_commit);
|
||||
git_reference_free(our_ref);
|
||||
git_buf_free(&their_label);
|
||||
@ -217,14 +214,10 @@ done:
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_cherry_pick_init_opts(git_cherry_pick_options* opts, int version)
|
||||
int git_cherrypick_init_options(
|
||||
git_cherrypick_options *opts, unsigned int version)
|
||||
{
|
||||
if (version != GIT_CHERRY_PICK_OPTIONS_VERSION) {
|
||||
giterr_set(GITERR_INVALID, "Invalid version %d for git_cherry_pick_options", version);
|
||||
return -1;
|
||||
} else {
|
||||
git_cherry_pick_options o = GIT_CHERRY_PICK_OPTIONS_INIT;
|
||||
memcpy(opts, &o, sizeof(o));
|
||||
return 0;
|
||||
}
|
||||
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
|
||||
opts, version, git_cherrypick_options, GIT_CHERRYPICK_OPTIONS_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
396
src/clone.c
396
src/clone.c
@ -22,6 +22,9 @@
|
||||
#include "refs.h"
|
||||
#include "path.h"
|
||||
#include "repository.h"
|
||||
#include "odb.h"
|
||||
|
||||
static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature);
|
||||
|
||||
static int create_branch(
|
||||
git_reference **branch,
|
||||
@ -105,54 +108,6 @@ static int create_tracking_branch(
|
||||
git_reference_name(*branch));
|
||||
}
|
||||
|
||||
struct head_info {
|
||||
git_repository *repo;
|
||||
git_oid remote_head_oid;
|
||||
git_buf branchname;
|
||||
const git_refspec *refspec;
|
||||
bool found;
|
||||
};
|
||||
|
||||
static int reference_matches_remote_head(
|
||||
const char *reference_name,
|
||||
void *payload)
|
||||
{
|
||||
struct head_info *head_info = (struct head_info *)payload;
|
||||
git_oid oid;
|
||||
int error;
|
||||
|
||||
/* TODO: Should we guard against references
|
||||
* which name doesn't start with refs/heads/ ?
|
||||
*/
|
||||
|
||||
error = git_reference_name_to_id(&oid, head_info->repo, reference_name);
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
/* If the reference doesn't exists, it obviously cannot match the
|
||||
* expected oid. */
|
||||
giterr_clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!error && !git_oid__cmp(&head_info->remote_head_oid, &oid)) {
|
||||
/* Determine the local reference name from the remote tracking one */
|
||||
error = git_refspec_rtransform(
|
||||
&head_info->branchname, head_info->refspec, reference_name);
|
||||
|
||||
if (!error &&
|
||||
git_buf_len(&head_info->branchname) > 0 &&
|
||||
!(error = git_buf_sets(
|
||||
&head_info->branchname,
|
||||
git_buf_cstr(&head_info->branchname) +
|
||||
strlen(GIT_REFS_HEADS_DIR))))
|
||||
{
|
||||
head_info->found = true;
|
||||
error = GIT_ITEROVER;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int update_head_to_new_branch(
|
||||
git_repository *repo,
|
||||
const git_oid *target,
|
||||
@ -161,7 +116,12 @@ static int update_head_to_new_branch(
|
||||
const char *reflog_message)
|
||||
{
|
||||
git_reference *tracking_branch = NULL;
|
||||
int error = create_tracking_branch(&tracking_branch, repo, target, name,
|
||||
int error;
|
||||
|
||||
if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR))
|
||||
name += strlen(GIT_REFS_HEADS_DIR);
|
||||
|
||||
error = create_tracking_branch(&tracking_branch, repo, target, name,
|
||||
signature, reflog_message);
|
||||
|
||||
if (!error)
|
||||
@ -171,6 +131,10 @@ static int update_head_to_new_branch(
|
||||
|
||||
git_reference_free(tracking_branch);
|
||||
|
||||
/* if it already existed, then the user's refspec created it for us, ignore it' */
|
||||
if (error == GIT_EEXISTS)
|
||||
error = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -182,76 +146,58 @@ static int update_head_to_remote(
|
||||
{
|
||||
int error = 0;
|
||||
size_t refs_len;
|
||||
git_refspec dummy_spec;
|
||||
git_refspec *refspec;
|
||||
const git_remote_head *remote_head, **refs;
|
||||
struct head_info head_info;
|
||||
const git_oid *remote_head_id;
|
||||
git_buf remote_master_name = GIT_BUF_INIT;
|
||||
git_buf branch = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0)
|
||||
return error;
|
||||
|
||||
/* Did we just clone an empty repository? */
|
||||
if (refs_len == 0)
|
||||
/* We cloned an empty repository or one with an unborn HEAD */
|
||||
if (refs_len == 0 || strcmp(refs[0]->name, GIT_HEAD_FILE))
|
||||
return setup_tracking_config(
|
||||
repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE);
|
||||
|
||||
/* Get the remote's HEAD. This is always the first ref in the list. */
|
||||
/* We know we have HEAD, let's see where it points */
|
||||
remote_head = refs[0];
|
||||
assert(remote_head);
|
||||
|
||||
memset(&head_info, 0, sizeof(head_info));
|
||||
git_oid_cpy(&head_info.remote_head_oid, &remote_head->oid);
|
||||
head_info.repo = repo;
|
||||
head_info.refspec =
|
||||
git_remote__matching_refspec(remote, GIT_REFS_HEADS_MASTER_FILE);
|
||||
remote_head_id = &remote_head->oid;
|
||||
|
||||
if (head_info.refspec == NULL) {
|
||||
memset(&dummy_spec, 0, sizeof(git_refspec));
|
||||
head_info.refspec = &dummy_spec;
|
||||
error = git_remote_default_branch(&branch, remote);
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
error = git_repository_set_head_detached(
|
||||
repo, remote_head_id, signature, reflog_message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch));
|
||||
|
||||
if (refspec == NULL) {
|
||||
giterr_set(GITERR_NET, "the remote's default branch does not fit the refspec configuration");
|
||||
error = GIT_EINVALIDSPEC;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Determine the remote tracking reference name from the local master */
|
||||
if ((error = git_refspec_transform(
|
||||
&remote_master_name,
|
||||
head_info.refspec,
|
||||
GIT_REFS_HEADS_MASTER_FILE)) < 0)
|
||||
return error;
|
||||
|
||||
/* Check to see if the remote HEAD points to the remote master */
|
||||
error = reference_matches_remote_head(
|
||||
git_buf_cstr(&remote_master_name), &head_info);
|
||||
if (error < 0 && error != GIT_ITEROVER)
|
||||
refspec,
|
||||
git_buf_cstr(&branch))) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (head_info.found) {
|
||||
error = update_head_to_new_branch(
|
||||
repo,
|
||||
&head_info.remote_head_oid,
|
||||
git_buf_cstr(&head_info.branchname),
|
||||
signature, reflog_message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Not master. Check all the other refs. */
|
||||
error = git_reference_foreach_name(
|
||||
repo, reference_matches_remote_head, &head_info);
|
||||
if (error < 0 && error != GIT_ITEROVER)
|
||||
goto cleanup;
|
||||
|
||||
if (head_info.found) {
|
||||
error = update_head_to_new_branch(
|
||||
repo,
|
||||
&head_info.remote_head_oid,
|
||||
git_buf_cstr(&head_info.branchname),
|
||||
signature, reflog_message);
|
||||
} else {
|
||||
error = git_repository_set_head_detached(
|
||||
repo, &head_info.remote_head_oid, signature, reflog_message);
|
||||
}
|
||||
error = update_head_to_new_branch(
|
||||
repo,
|
||||
remote_head_id,
|
||||
git_buf_cstr(&branch),
|
||||
signature, reflog_message);
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&remote_master_name);
|
||||
git_buf_free(&head_info.branchname);
|
||||
git_buf_free(&branch);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -284,6 +230,29 @@ cleanup:
|
||||
return retcode;
|
||||
}
|
||||
|
||||
static int default_repository_create(git_repository **out, const char *path, int bare, void *payload)
|
||||
{
|
||||
GIT_UNUSED(payload);
|
||||
|
||||
return git_repository_init(out, path, bare);
|
||||
}
|
||||
|
||||
static int default_remote_create(
|
||||
git_remote **out,
|
||||
git_repository *repo,
|
||||
const char *name,
|
||||
const char *url,
|
||||
void *payload)
|
||||
{
|
||||
int error;
|
||||
git_remote_callbacks *callbacks = payload;
|
||||
|
||||
if ((error = git_remote_create(out, repo, name, url)) < 0)
|
||||
return error;
|
||||
|
||||
return git_remote_set_callbacks(*out, callbacks);
|
||||
}
|
||||
|
||||
/*
|
||||
* submodules?
|
||||
*/
|
||||
@ -296,16 +265,24 @@ static int create_and_configure_origin(
|
||||
{
|
||||
int error;
|
||||
git_remote *origin = NULL;
|
||||
const char *name;
|
||||
char buf[GIT_PATH_MAX];
|
||||
git_remote_create_cb remote_create = options->remote_cb;
|
||||
void *payload = options->remote_cb_payload;
|
||||
|
||||
name = options->remote_name ? options->remote_name : "origin";
|
||||
if ((error = git_remote_create(&origin, repo, name, url)) < 0)
|
||||
goto on_error;
|
||||
/* If the path exists and is a dir, the url should be the absolute path */
|
||||
if (git_path_root(url) < 0 && git_path_exists(url) && git_path_isdir(url)) {
|
||||
if (p_realpath(url, buf) == NULL)
|
||||
return -1;
|
||||
|
||||
if (options->ignore_cert_errors)
|
||||
git_remote_check_cert(origin, 0);
|
||||
url = buf;
|
||||
}
|
||||
|
||||
if ((error = git_remote_set_callbacks(origin, &options->remote_callbacks)) < 0)
|
||||
if (!remote_create) {
|
||||
remote_create = default_remote_create;
|
||||
payload = (void *)&options->remote_callbacks;
|
||||
}
|
||||
|
||||
if ((error = remote_create(&origin, repo, "origin", url, payload)) < 0)
|
||||
goto on_error;
|
||||
|
||||
if ((error = git_remote_save(origin)) < 0)
|
||||
@ -336,59 +313,89 @@ static bool should_checkout(
|
||||
return !git_repository_head_unborn(repo);
|
||||
}
|
||||
|
||||
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
|
||||
static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature, const char *reflog_message)
|
||||
{
|
||||
int error = 0, old_fetchhead;
|
||||
git_strarray refspecs;
|
||||
git_buf reflog_message = GIT_BUF_INIT;
|
||||
int error;
|
||||
|
||||
assert(repo && remote);
|
||||
if (branch)
|
||||
error = update_head_to_branch(repo, git_remote_name(remote), branch,
|
||||
signature, reflog_message);
|
||||
/* Point HEAD to the same ref as the remote's head */
|
||||
else
|
||||
error = update_head_to_remote(repo, remote, signature, reflog_message);
|
||||
|
||||
if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
|
||||
error = git_checkout_head(repo, co_opts);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
|
||||
{
|
||||
int error;
|
||||
git_buf reflog_message = GIT_BUF_INIT;
|
||||
git_remote *remote;
|
||||
const git_remote_callbacks *callbacks;
|
||||
|
||||
assert(repo && _remote);
|
||||
|
||||
if (!git_repository_is_empty(repo)) {
|
||||
giterr_set(GITERR_INVALID, "the repository is not empty");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((error = git_remote_get_fetch_refspecs(&refspecs, remote)) < 0)
|
||||
if ((error = git_remote_dup(&remote, _remote)) < 0)
|
||||
return error;
|
||||
|
||||
callbacks = git_remote_get_callbacks(_remote);
|
||||
if (!giterr__check_version(callbacks, 1, "git_remote_callbacks") &&
|
||||
(error = git_remote_set_callbacks(remote, callbacks)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
|
||||
return error;
|
||||
goto cleanup;
|
||||
|
||||
old_fetchhead = git_remote_update_fetchhead(remote);
|
||||
git_remote_set_update_fetchhead(remote, 0);
|
||||
git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
|
||||
|
||||
if ((error = git_remote_fetch(remote, signature, git_buf_cstr(&reflog_message))) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (branch)
|
||||
error = update_head_to_branch(repo, git_remote_name(remote), branch,
|
||||
signature, git_buf_cstr(&reflog_message));
|
||||
/* Point HEAD to the same ref as the remote's head */
|
||||
else
|
||||
error = update_head_to_remote(repo, remote, signature, git_buf_cstr(&reflog_message));
|
||||
|
||||
if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
|
||||
error = git_checkout_head(repo, co_opts);
|
||||
error = checkout_branch(repo, remote, co_opts, branch, signature, git_buf_cstr(&reflog_message));
|
||||
|
||||
cleanup:
|
||||
git_remote_set_update_fetchhead(remote, old_fetchhead);
|
||||
|
||||
/* Go back to the original refspecs */
|
||||
{
|
||||
int error_alt = git_remote_set_fetch_refspecs(remote, &refspecs);
|
||||
if (!error)
|
||||
error = error_alt;
|
||||
}
|
||||
|
||||
git_strarray_free(&refspecs);
|
||||
git_remote_free(remote);
|
||||
git_buf_free(&reflog_message);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t local)
|
||||
{
|
||||
git_buf fromurl = GIT_BUF_INIT;
|
||||
const char *path = url_or_path;
|
||||
bool is_url, is_local;
|
||||
|
||||
if (local == GIT_CLONE_NO_LOCAL)
|
||||
return 0;
|
||||
|
||||
if ((is_url = git_path_is_local_file_url(url_or_path)) != 0) {
|
||||
if (git_path_fromurl(&fromurl, url_or_path) < 0) {
|
||||
is_local = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
path = fromurl.ptr;
|
||||
}
|
||||
|
||||
is_local = (!is_url || local != GIT_CLONE_LOCAL_AUTO) &&
|
||||
git_path_isdir(path);
|
||||
|
||||
done:
|
||||
git_buf_free(&fromurl);
|
||||
return is_local;
|
||||
}
|
||||
|
||||
int git_clone(
|
||||
git_repository **out,
|
||||
const char *url,
|
||||
@ -400,6 +407,7 @@ int git_clone(
|
||||
git_remote *origin;
|
||||
git_clone_options options = GIT_CLONE_OPTIONS_INIT;
|
||||
uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES;
|
||||
git_repository_create_cb repository_cb;
|
||||
|
||||
assert(out && url && local_path);
|
||||
|
||||
@ -419,12 +427,28 @@ int git_clone(
|
||||
if (git_path_exists(local_path))
|
||||
rmdir_flags |= GIT_RMDIR_SKIP_ROOT;
|
||||
|
||||
if ((error = git_repository_init(&repo, local_path, options.bare)) < 0)
|
||||
if (options.repository_cb)
|
||||
repository_cb = options.repository_cb;
|
||||
else
|
||||
repository_cb = default_repository_create;
|
||||
|
||||
if ((error = repository_cb(&repo, local_path, options.bare, options.repository_cb_payload)) < 0)
|
||||
return error;
|
||||
|
||||
if (!(error = create_and_configure_origin(&origin, repo, url, &options))) {
|
||||
error = git_clone_into(
|
||||
repo, origin, &options.checkout_opts, options.checkout_branch, options.signature);
|
||||
int clone_local = git_clone__should_clone_local(url, options.local);
|
||||
int link = options.local != GIT_CLONE_LOCAL_NO_LINKS;
|
||||
|
||||
if (clone_local == 1)
|
||||
error = clone_local_into(
|
||||
repo, origin, &options.checkout_opts,
|
||||
options.checkout_branch, link, options.signature);
|
||||
else if (clone_local == 0)
|
||||
error = clone_into(
|
||||
repo, origin, &options.checkout_opts,
|
||||
options.checkout_branch, options.signature);
|
||||
else
|
||||
error = -1;
|
||||
|
||||
git_remote_free(origin);
|
||||
}
|
||||
@ -445,14 +469,100 @@ int git_clone(
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_clone_init_options(git_clone_options* opts, int version)
|
||||
int git_clone_init_options(git_clone_options *opts, unsigned int version)
|
||||
{
|
||||
if (version != GIT_CLONE_OPTIONS_VERSION) {
|
||||
giterr_set(GITERR_INVALID, "Invalid version %d for git_clone_options", version);
|
||||
return -1;
|
||||
} else {
|
||||
git_clone_options o = GIT_CLONE_OPTIONS_INIT;
|
||||
memcpy(opts, &o, sizeof(o));
|
||||
return 0;
|
||||
}
|
||||
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
|
||||
opts, version, git_clone_options, GIT_CLONE_OPTIONS_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *repository_base(git_repository *repo)
|
||||
{
|
||||
if (git_repository_is_bare(repo))
|
||||
return git_repository_path(repo);
|
||||
|
||||
return git_repository_workdir(repo);
|
||||
}
|
||||
|
||||
static bool can_link(const char *src, const char *dst, int link)
|
||||
{
|
||||
#ifdef GIT_WIN32
|
||||
GIT_UNUSED(src);
|
||||
GIT_UNUSED(dst);
|
||||
GIT_UNUSED(link);
|
||||
return false;
|
||||
#else
|
||||
|
||||
struct stat st_src, st_dst;
|
||||
|
||||
if (!link)
|
||||
return false;
|
||||
|
||||
if (p_stat(src, &st_src) < 0)
|
||||
return false;
|
||||
|
||||
if (p_stat(dst, &st_dst) < 0)
|
||||
return false;
|
||||
|
||||
return st_src.st_dev == st_dst.st_dev;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature)
|
||||
{
|
||||
int error, flags;
|
||||
git_repository *src;
|
||||
git_buf src_odb = GIT_BUF_INIT, dst_odb = GIT_BUF_INIT, src_path = GIT_BUF_INIT;
|
||||
git_buf reflog_message = GIT_BUF_INIT;
|
||||
|
||||
assert(repo && remote);
|
||||
|
||||
if (!git_repository_is_empty(repo)) {
|
||||
giterr_set(GITERR_INVALID, "the repository is not empty");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's figure out what path we should use for the source
|
||||
* repo, if it's not rooted, the path should be relative to
|
||||
* the repository's worktree/gitdir.
|
||||
*/
|
||||
if ((error = git_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0)
|
||||
return error;
|
||||
|
||||
/* Copy .git/objects/ from the source to the target */
|
||||
if ((error = git_repository_open(&src, git_buf_cstr(&src_path))) < 0) {
|
||||
git_buf_free(&src_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
git_buf_joinpath(&src_odb, git_repository_path(src), GIT_OBJECTS_DIR);
|
||||
git_buf_joinpath(&dst_odb, git_repository_path(repo), GIT_OBJECTS_DIR);
|
||||
if (git_buf_oom(&src_odb) || git_buf_oom(&dst_odb)) {
|
||||
error = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
if (can_link(git_repository_path(src), git_repository_path(repo), link))
|
||||
flags |= GIT_CPDIR_LINK_FILES;
|
||||
|
||||
if ((error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb),
|
||||
flags, GIT_OBJECT_DIR_MODE)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
|
||||
|
||||
if ((error = git_remote_fetch(remote, signature, git_buf_cstr(&reflog_message))) != 0)
|
||||
goto cleanup;
|
||||
|
||||
error = checkout_branch(repo, remote, co_opts, branch, signature, git_buf_cstr(&reflog_message));
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&reflog_message);
|
||||
git_buf_free(&src_path);
|
||||
git_buf_free(&src_odb);
|
||||
git_buf_free(&dst_odb);
|
||||
git_repository_free(src);
|
||||
return error;
|
||||
}
|
||||
|
12
src/clone.h
Normal file
12
src/clone.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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_clone_h__
|
||||
#define INCLUDE_clone_h__
|
||||
|
||||
extern int git_clone__should_clone_local(const char *url, git_clone_local_t local);
|
||||
|
||||
#endif
|
99
src/commit.c
99
src/commit.c
@ -34,6 +34,35 @@ void git_commit__free(void *_commit)
|
||||
git__free(commit);
|
||||
}
|
||||
|
||||
static int update_ref_for_commit(git_repository *repo, git_reference *ref, const char *update_ref, const git_oid *id, const git_signature *committer)
|
||||
{
|
||||
git_reference *ref2 = NULL;
|
||||
int error;
|
||||
git_commit *c;
|
||||
const char *shortmsg;
|
||||
git_buf reflog_msg = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_commit_lookup(&c, repo, id)) < 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
shortmsg = git_commit_summary(c);
|
||||
git_buf_printf(&reflog_msg, "commit%s: %s",
|
||||
git_commit_parentcount(c) == 0 ? " (initial)" : "",
|
||||
shortmsg);
|
||||
git_commit_free(c);
|
||||
|
||||
if (ref) {
|
||||
error = git_reference_set_target(&ref2, ref, id, committer, git_buf_cstr(&reflog_msg));
|
||||
git_reference_free(ref2);
|
||||
} else {
|
||||
error = git_reference__update_terminal(repo, update_ref, id, committer, git_buf_cstr(&reflog_msg));
|
||||
}
|
||||
|
||||
git_buf_free(&reflog_msg);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_commit_create_from_callback(
|
||||
git_oid *id,
|
||||
git_repository *repo,
|
||||
@ -46,6 +75,9 @@ int git_commit_create_from_callback(
|
||||
git_commit_parent_callback parent_cb,
|
||||
void *parent_payload)
|
||||
{
|
||||
git_reference *ref = NULL;
|
||||
int error = 0, matched_parent = 0;
|
||||
const git_oid *current_id = NULL;
|
||||
git_buf commit = GIT_BUF_INIT;
|
||||
size_t i = 0;
|
||||
git_odb *odb;
|
||||
@ -53,10 +85,31 @@ int git_commit_create_from_callback(
|
||||
|
||||
assert(id && repo && tree && parent_cb);
|
||||
|
||||
if (update_ref) {
|
||||
error = git_reference_lookup_resolved(&ref, repo, update_ref, 10);
|
||||
if (error < 0 && error != GIT_ENOTFOUND)
|
||||
return error;
|
||||
}
|
||||
giterr_clear();
|
||||
|
||||
if (ref)
|
||||
current_id = git_reference_target(ref);
|
||||
|
||||
git_oid__writebuf(&commit, "tree ", tree);
|
||||
|
||||
while ((parent = parent_cb(i++, parent_payload)) != NULL)
|
||||
while ((parent = parent_cb(i, parent_payload)) != NULL) {
|
||||
git_oid__writebuf(&commit, "parent ", parent);
|
||||
if (i == 0 && current_id && git_oid_equal(current_id, parent))
|
||||
matched_parent = 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (ref && !matched_parent) {
|
||||
git_reference_free(ref);
|
||||
git_buf_free(&commit);
|
||||
giterr_set(GITERR_OBJECT, "failed to create commit: current tip is not the first parent");
|
||||
return GIT_EMODIFIED;
|
||||
}
|
||||
|
||||
git_signature__writebuf(&commit, "author ", author);
|
||||
git_signature__writebuf(&commit, "committer ", committer);
|
||||
@ -78,24 +131,8 @@ int git_commit_create_from_callback(
|
||||
git_buf_free(&commit);
|
||||
|
||||
if (update_ref != NULL) {
|
||||
int error;
|
||||
git_commit *c;
|
||||
const char *shortmsg;
|
||||
git_buf reflog_msg = GIT_BUF_INIT;
|
||||
|
||||
if (git_commit_lookup(&c, repo, id) < 0)
|
||||
goto on_error;
|
||||
|
||||
shortmsg = git_commit_summary(c);
|
||||
git_buf_printf(&reflog_msg, "commit%s: %s",
|
||||
git_commit_parentcount(c) == 0 ? " (initial)" : "",
|
||||
shortmsg);
|
||||
git_commit_free(c);
|
||||
|
||||
error = git_reference__update_terminal(repo, update_ref, id,
|
||||
committer, git_buf_cstr(&reflog_msg));
|
||||
|
||||
git_buf_free(&reflog_msg);
|
||||
error = update_ref_for_commit(repo, ref, update_ref, id, committer);
|
||||
git_reference_free(ref);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -242,6 +279,8 @@ int git_commit_amend(
|
||||
{
|
||||
git_repository *repo;
|
||||
git_oid tree_id;
|
||||
git_reference *ref;
|
||||
int error;
|
||||
|
||||
assert(id && commit_to_amend);
|
||||
|
||||
@ -266,9 +305,27 @@ int git_commit_amend(
|
||||
git_oid_cpy(&tree_id, git_tree_id(tree));
|
||||
}
|
||||
|
||||
return git_commit_create_from_callback(
|
||||
id, repo, update_ref, author, committer, message_encoding, message,
|
||||
if (update_ref) {
|
||||
if ((error = git_reference_lookup_resolved(&ref, repo, update_ref, 5)) < 0)
|
||||
return error;
|
||||
|
||||
if (git_oid_cmp(git_commit_id(commit_to_amend), git_reference_target(ref))) {
|
||||
git_reference_free(ref);
|
||||
giterr_set(GITERR_REFERENCE, "commit to amend is not the tip of the given branch");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
error = git_commit_create_from_callback(
|
||||
id, repo, NULL, author, committer, message_encoding, message,
|
||||
&tree_id, commit_parent_for_amend, (void *)commit_to_amend);
|
||||
|
||||
if (!error && update_ref) {
|
||||
error = update_ref_for_commit(repo, ref, NULL, id, committer);
|
||||
git_reference_free(ref);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_commit__parse(void *_commit, git_odb_object *odb_obj)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#else
|
||||
|
||||
# include <unistd.h>
|
||||
# include <strings.h>
|
||||
# ifdef GIT_THREADS
|
||||
# include <pthread.h>
|
||||
# include <sched.h>
|
||||
@ -169,6 +170,11 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
|
||||
}
|
||||
#define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V)
|
||||
|
||||
#define GIT_INIT_STRUCTURE_FROM_TEMPLATE(PTR,VERSION,TYPE,TPL) do { \
|
||||
TYPE _tmpl = TPL; \
|
||||
GITERR_CHECK_VERSION(&(VERSION), _tmpl.version, #TYPE); \
|
||||
memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0)
|
||||
|
||||
/* NOTE: other giterr functions are in the public errors.h header file */
|
||||
|
||||
#include "util.h"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user