mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-05 16:51:42 +00:00
Merge branch 'development' into rev-parse
Conflicts: src/util.h tests-clar/refs/branches/listall.c
This commit is contained in:
commit
56a5000d58
@ -7,7 +7,8 @@ language: erlang
|
||||
# Settings to try
|
||||
env:
|
||||
- OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release"
|
||||
- OPTIONS="-DBUILD_CLAR=ON"
|
||||
- OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=ON"
|
||||
- CC=i586-mingw32msvc-gcc OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON"
|
||||
|
||||
# Make sure CMake is installed
|
||||
install:
|
||||
|
@ -52,7 +52,9 @@ SET(INSTALL_INC include CACHE PATH "Where to install headers to.")
|
||||
OPTION (BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON)
|
||||
OPTION (THREADSAFE "Build libgit2 as threadsafe" OFF)
|
||||
OPTION (BUILD_CLAR "Build Tests using the Clar suite" ON)
|
||||
OPTION (BUILD_EXAMPLES "Build library usage example apps" OFF)
|
||||
OPTION (TAGS "Generate tags" OFF)
|
||||
OPTION (PROFILE "Generate profiling information" OFF)
|
||||
|
||||
# Platform specific compilation flags
|
||||
IF (MSVC)
|
||||
@ -71,8 +73,14 @@ IF (MSVC)
|
||||
ELSE ()
|
||||
SET(CMAKE_C_FLAGS "-O2 -g -D_GNU_SOURCE -Wall -Wextra -Wno-missing-field-initializers -Wstrict-aliasing=2 -Wstrict-prototypes -Wmissing-prototypes ${CMAKE_C_FLAGS}")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
|
||||
IF (NOT MINGW) # MinGW always does PIC and complains if we tell it to
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
IF (MINGW) # MinGW always does PIC and complains if we tell it to
|
||||
STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||
ELSE ()
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fPIC")
|
||||
ENDIF ()
|
||||
IF (PROFILE)
|
||||
SET(CMAKE_C_FLAGS "-pg ${CMAKE_C_FLAGS}")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-pg ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
|
||||
@ -97,7 +105,9 @@ FILE(GLOB SRC_H include/git2/*.h)
|
||||
# On Windows use specific platform sources
|
||||
IF (WIN32 AND NOT CYGWIN)
|
||||
ADD_DEFINITIONS(-DWIN32 -D_DEBUG -D_WIN32_WINNT=0x0501)
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/win32/*.c)
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/win32/*.c src/compat/*.c)
|
||||
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c src/compat/*.c)
|
||||
ELSE()
|
||||
FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c)
|
||||
ENDIF ()
|
||||
@ -176,3 +186,18 @@ IF (TAGS)
|
||||
DEPENDS tags
|
||||
)
|
||||
ENDIF ()
|
||||
|
||||
IF (BUILD_EXAMPLES)
|
||||
FILE(GLOB_RECURSE EXAMPLE_SRC examples/network/*.c)
|
||||
ADD_EXECUTABLE(cgit2 ${EXAMPLE_SRC})
|
||||
TARGET_LINK_LIBRARIES(cgit2 git2 pthread)
|
||||
|
||||
ADD_EXECUTABLE(git-diff examples/diff.c)
|
||||
TARGET_LINK_LIBRARIES(git-diff git2)
|
||||
|
||||
ADD_EXECUTABLE(git-general examples/general.c)
|
||||
TARGET_LINK_LIBRARIES(git-general git2)
|
||||
|
||||
ADD_EXECUTABLE(git-showindex examples/showindex.c)
|
||||
TARGET_LINK_LIBRARIES(git-showindex git2)
|
||||
ENDIF ()
|
||||
|
@ -49,7 +49,7 @@ Functions should prefer to return a 'int' to indicate success or
|
||||
failure and supply any output through the first argument (or first
|
||||
few arguments if multiple outputs are supplied).
|
||||
|
||||
int status codes are 0 for GIT_SUCCESS and < 0 for an error.
|
||||
int status codes are 0 for GIT_OK and < 0 for an error.
|
||||
This permits common POSIX result testing:
|
||||
|
||||
----
|
||||
@ -58,7 +58,7 @@ This permits common POSIX result testing:
|
||||
----
|
||||
|
||||
Functions returning a pointer may return NULL instead of an int
|
||||
if there is only one type of failure (ENOMEM).
|
||||
if there is only one type of failure (GIT_ENOMEM).
|
||||
|
||||
Functions returning a pointer may also return NULL if the common
|
||||
case needed by the application is strictly success/failure and a
|
||||
|
@ -6,10 +6,10 @@ LIBNAME=libgit2.a
|
||||
|
||||
INCLUDES= -I. -Isrc -Iinclude -Ideps/http-parser -Ideps/zlib
|
||||
|
||||
DEFINES= $(INCLUDES) -DNO_VIZ -DSTDC -DNO_GZIP -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
|
||||
CFLAGS= -g $(DEFINES) -Wall -Wextra -fPIC -O2
|
||||
DEFINES= $(INCLUDES) -DNO_VIZ -DSTDC -DNO_GZIP -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(EXTRA_DEFINES)
|
||||
CFLAGS= -g $(DEFINES) -Wall -Wextra -fPIC -O2 $(EXTRA_CFLAGS)
|
||||
|
||||
SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/unix/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c)
|
||||
SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/unix/*.c) $(wildcard src/xdiff/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c)
|
||||
OBJS = $(patsubst %.c,%.o,$(SRCS))
|
||||
|
||||
%.c.o:
|
||||
|
@ -124,7 +124,9 @@ How Can I Contribute?
|
||||
==================================
|
||||
|
||||
Fork libgit2/libgit2 on GitHub, add your improvement, push it to a branch
|
||||
in your fork named for the topic, send a pull request.
|
||||
in your fork named for the topic, send a pull request. If you change the
|
||||
API or make other large changes, make a note of it in docs/rel-notes/ in a
|
||||
file named after the next release.
|
||||
|
||||
You can also file bugs or feature requests under the libgit2 project on
|
||||
GitHub, or join us on the mailing list by sending an email to:
|
||||
|
@ -29,7 +29,7 @@ The simple error API
|
||||
- `void giterr_set(git_error **, int, const char *, ...)`: the main function used to set an error. It allocates a new error object and stores it in the passed error pointer. It has no return value. The arguments for `giterr_set` are as follows:
|
||||
|
||||
- `git_error **error_ptr`: the pointer where the error will be created.
|
||||
- `int error_class`: the class for the error. This is **not** an error code: this is an speficic enum that specifies the error family. The point is to map these families 1-1 with Exception types on higher level languages (e.g. GitRepositoryException)
|
||||
- `int error_class`: the class for the error. This is **not** an error code: this is an specific enum that specifies the error family. The point is to map these families 1-1 with Exception types on higher level languages (e.g. GitRepositoryException)
|
||||
- `const char *error_str, ...`: the error string, with optional formatting arguments
|
||||
|
||||
- `void giterr_free(git_error *)`: takes an error and frees it. This function is available in the external API.
|
||||
@ -56,7 +56,7 @@ Here are some guidelines when writing error messages:
|
||||
|
||||
- Use short, direct and objective messages. **One line, max**. libgit2 is a low level library: think that all the messages reported will be thrown as Ruby or Python exceptions. Think how long are common exception messages in those languages.
|
||||
|
||||
- **Do not add redundant information to the error message**, specially information that can be infered from the context.
|
||||
- **Do not add redundant information to the error message**, specially information that can be inferred from the context.
|
||||
|
||||
E.g. in `git_repository_open`, do not report a message like "Failed to open repository: path not found". Somebody is
|
||||
calling that function. If it fails, he already knows that the repository failed to open!
|
||||
|
@ -61,7 +61,13 @@ char *colors[] = {
|
||||
"\033[36m" /* cyan */
|
||||
};
|
||||
|
||||
int printer(void *data, char usage, const char *line)
|
||||
int printer(
|
||||
void *data,
|
||||
git_diff_delta *delta,
|
||||
git_diff_range *range,
|
||||
char usage,
|
||||
const char *line,
|
||||
size_t line_len)
|
||||
{
|
||||
int *last_color = data, color = 0;
|
||||
|
||||
|
@ -273,7 +273,7 @@ int main (int argc, char** argv)
|
||||
|
||||
// Once you have the entry object, you can access the content or subtree (or commit, in the case
|
||||
// of submodules) that it points to. You can also get the mode if you want.
|
||||
git_tree_entry_2object(&objt, repo, entry); // blob
|
||||
git_tree_entry_to_object(&objt, repo, entry); // blob
|
||||
|
||||
// Remember to close the looked-up object once you are done using it
|
||||
git_object_free(objt);
|
||||
@ -335,7 +335,7 @@ int main (int argc, char** argv)
|
||||
// We can then lookup and parse the commited pointed at by the returned OID;
|
||||
// note that this operation is specially fast since the raw contents of the commit object will
|
||||
// be cached in memory
|
||||
while ((git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
|
||||
while ((git_revwalk_next(&oid, walk)) == 0) {
|
||||
error = git_commit_lookup(&wcommit, repo, &oid);
|
||||
cmsg = git_commit_message(wcommit);
|
||||
cauth = git_commit_author(wcommit);
|
||||
@ -392,7 +392,7 @@ int main (int argc, char** argv)
|
||||
// Here we will implement something like `git for-each-ref` simply listing out all available
|
||||
// references and the object SHA they resolve to.
|
||||
git_strarray ref_list;
|
||||
git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
|
||||
git_reference_list(&ref_list, repo, GIT_REF_LISTALL);
|
||||
|
||||
const char *refname;
|
||||
git_reference *ref;
|
||||
|
@ -107,7 +107,7 @@ int fetch(git_repository *repo, int argc, char **argv)
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
on_error:
|
||||
git_remote_free(remote);
|
||||
return -1;
|
||||
}
|
||||
|
@ -25,16 +25,17 @@ int run_command(git_cb fn, int argc, char **argv)
|
||||
// repository and pass it to the function.
|
||||
|
||||
error = git_repository_open(&repo, ".git");
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
repo = NULL;
|
||||
|
||||
// Run the command. If something goes wrong, print the error message to stderr
|
||||
error = fn(repo, argc, argv);
|
||||
if (error < GIT_SUCCESS) {
|
||||
if (error < 0) {
|
||||
if (giterr_last() == NULL)
|
||||
fprintf(stderr, "Error without message");
|
||||
else
|
||||
fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message);
|
||||
}
|
||||
|
||||
if(repo)
|
||||
git_repository_free(repo);
|
||||
|
@ -60,7 +60,7 @@ int index_pack(git_repository *repo, int argc, char **argv)
|
||||
git_oid_fmt(hash, git_indexer_stream_hash(idx));
|
||||
puts(hash);
|
||||
|
||||
cleanup:
|
||||
cleanup:
|
||||
close(fd);
|
||||
git_indexer_stream_free(idx);
|
||||
return error;
|
||||
@ -80,13 +80,13 @@ int index_pack_old(git_repository *repo, int argc, char **argv)
|
||||
|
||||
// Create a new indexer
|
||||
error = git_indexer_new(&indexer, argv[1]);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
// Index the packfile. This function can take a very long time and
|
||||
// should be run in a worker thread.
|
||||
error = git_indexer_run(indexer, &stats);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
// Write the information out to an index file
|
||||
@ -98,5 +98,5 @@ int index_pack_old(git_repository *repo, int argc, char **argv)
|
||||
|
||||
git_indexer_free(indexer);
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ static int show_ref__cb(git_remote_head *head, void *payload)
|
||||
char oid[GIT_OID_HEXSZ + 1] = {0};
|
||||
git_oid_fmt(oid, &head->oid);
|
||||
printf("%s\t%s\n", oid, head->name);
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int use_unnamed(git_repository *repo, const char *url)
|
||||
@ -20,13 +20,13 @@ int use_unnamed(git_repository *repo, const char *url)
|
||||
// Create an instance of a remote from the URL. The transport to use
|
||||
// is detected from the URL
|
||||
error = git_remote_new(&remote, repo, NULL, url, NULL);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
// When connecting, the underlying code needs to know wether we
|
||||
// want to push or fetch
|
||||
error = git_remote_connect(remote, GIT_DIR_FETCH);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
// With git_remote_ls we can retrieve the advertised heads
|
||||
@ -44,11 +44,11 @@ int use_remote(git_repository *repo, char *name)
|
||||
|
||||
// Find the remote by name
|
||||
error = git_remote_load(&remote, repo, name);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = git_remote_connect(remote, GIT_DIR_FETCH);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = git_remote_ls(remote, &show_ref__cb, NULL);
|
||||
|
@ -65,8 +65,8 @@ GIT_BEGIN_DECL
|
||||
#define GIT_ATTR_UNSPECIFIED(attr) (!(attr) || (attr) == git_attr__unset)
|
||||
|
||||
/**
|
||||
* GIT_ATTR_SET_TO_VALUE checks if an attribute is set to a value (as
|
||||
* opposied to TRUE, FALSE or UNSPECIFIED). This would be the case if
|
||||
* GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as
|
||||
* opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if
|
||||
* for a file with something like:
|
||||
*
|
||||
* *.txt eol=lf
|
||||
@ -74,7 +74,7 @@ GIT_BEGIN_DECL
|
||||
* Given this, looking up "eol" for `onefile.txt` will give back the
|
||||
* string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true.
|
||||
*/
|
||||
#define GIT_ATTR_SET_TO_VALUE(attr) \
|
||||
#define GIT_ATTR_HAS_VALUE(attr) \
|
||||
((attr) && (attr) != git_attr__unset && \
|
||||
(attr) != git_attr__true && (attr) != git_attr__false)
|
||||
|
||||
@ -111,6 +111,10 @@ GIT_EXTERN(const char *) git_attr__unset;
|
||||
/**
|
||||
* Look up the value of one git attribute for path.
|
||||
*
|
||||
* @param value_out Output of the value of the attribute. Use the GIT_ATTR_...
|
||||
* macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just
|
||||
* use the string value for attributes set to a value. You
|
||||
* should NOT modify or free this value.
|
||||
* @param repo The repository containing the path.
|
||||
* @param flags A combination of GIT_ATTR_CHECK... flags.
|
||||
* @param path The path to check for attributes. Relative paths are
|
||||
@ -118,17 +122,13 @@ GIT_EXTERN(const char *) git_attr__unset;
|
||||
* not have to exist, but if it does not, then it will be
|
||||
* treated as a plain file (not a directory).
|
||||
* @param name The name of the attribute to look up.
|
||||
* @param value Output of the value of the attribute. Use the GIT_ATTR_...
|
||||
* macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just
|
||||
* use the string value for attributes set to a value. You
|
||||
* should NOT modify or free this value.
|
||||
*/
|
||||
GIT_EXTERN(int) git_attr_get(
|
||||
const char **value_out,
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *path,
|
||||
const char *name,
|
||||
const char **value);
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Look up a list of git attributes for path.
|
||||
@ -141,11 +141,16 @@ GIT_EXTERN(int) git_attr_get(
|
||||
*
|
||||
* const char *attrs[] = { "crlf", "diff", "foo" };
|
||||
* const char **values[3];
|
||||
* git_attr_get_many(repo, 0, "my/fun/file.c", 3, attrs, values);
|
||||
* git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs);
|
||||
*
|
||||
* Then you could loop through the 3 values to get the settings for
|
||||
* the three attributes you asked about.
|
||||
*
|
||||
* @param values An array of num_attr entries that will have string
|
||||
* pointers written into it for the values of the attributes.
|
||||
* You should not modify or free the values that are written
|
||||
* into this array (although of course, you should free the
|
||||
* array itself if you allocated it).
|
||||
* @param repo The repository containing the path.
|
||||
* @param flags A combination of GIT_ATTR_CHECK... flags.
|
||||
* @param path The path inside the repo to check attributes. This
|
||||
@ -153,19 +158,14 @@ GIT_EXTERN(int) git_attr_get(
|
||||
* it will be treated as a plain file (i.e. not a directory).
|
||||
* @param num_attr The number of attributes being looked up
|
||||
* @param names An array of num_attr strings containing attribute names.
|
||||
* @param values An array of num_attr entries that will have string
|
||||
* pointers written into it for the values of the attributes.
|
||||
* You should not modify or free the values that are written
|
||||
* into this array (although of course, you should free the
|
||||
* array itself if you allocated it).
|
||||
*/
|
||||
GIT_EXTERN(int) git_attr_get_many(
|
||||
const char **values_out,
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *path,
|
||||
size_t num_attr,
|
||||
const char **names,
|
||||
const char **values);
|
||||
const char **names);
|
||||
|
||||
/**
|
||||
* Loop over all the git attributes for a path.
|
||||
|
@ -27,7 +27,7 @@ GIT_BEGIN_DECL
|
||||
* @param blob pointer to the looked up blob
|
||||
* @param repo the repo to use when locating the blob.
|
||||
* @param id identity of the blob to locate.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id)
|
||||
{
|
||||
@ -44,7 +44,7 @@ GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git
|
||||
* @param repo the repo to use when locating the blob.
|
||||
* @param id identity of the blob to locate.
|
||||
* @param len the length of the short identifier
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, unsigned int len)
|
||||
{
|
||||
@ -99,10 +99,22 @@ GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob);
|
||||
* this repository cannot be bare
|
||||
* @param path file from which the blob will be created,
|
||||
* relative to the repository's working dir
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path);
|
||||
|
||||
/**
|
||||
* Read a file from the filesystem and write its content
|
||||
* to the Object Database as a loose blob
|
||||
*
|
||||
* @param oid return the id of the written blob
|
||||
* @param repo repository where the blob will be written.
|
||||
* this repository can be bare or not
|
||||
* @param path file from which the blob will be created
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path);
|
||||
|
||||
|
||||
/**
|
||||
* Write an in-memory buffer to the ODB as a blob
|
||||
@ -111,7 +123,7 @@ GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, con
|
||||
* @param repo repository where to blob will be written
|
||||
* @param buffer data to be written into the blob
|
||||
* @param len length of the data
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len);
|
||||
|
||||
|
@ -41,7 +41,7 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param force Overwrite existing branch.
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code.
|
||||
* @return 0 or an error code.
|
||||
* A proper reference is written in the refs/heads namespace
|
||||
* pointing to the provided target commit.
|
||||
*/
|
||||
@ -63,13 +63,13 @@ GIT_EXTERN(int) git_branch_create(
|
||||
* @param branch_type Type of the considered branch. This should
|
||||
* be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
|
||||
*
|
||||
* @return GIT_SUCCESS on success, GIT_ENOTFOUND if the branch
|
||||
* @return 0 on success, GIT_ENOTFOUND if the branch
|
||||
* doesn't exist or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_delete(
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
git_branch_type branch_type);
|
||||
git_branch_t branch_type);
|
||||
|
||||
/**
|
||||
* Fill a list with all the branches in the Repository
|
||||
@ -88,7 +88,7 @@ GIT_EXTERN(int) git_branch_delete(
|
||||
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
|
||||
* or a combination of the two.
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code.
|
||||
* @return 0 or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_list(
|
||||
git_strarray *branch_names,
|
||||
@ -108,7 +108,7 @@ GIT_EXTERN(int) git_branch_list(
|
||||
*
|
||||
* @param force Overwrite existing branch.
|
||||
*
|
||||
* @return GIT_SUCCESS on success, GIT_ENOTFOUND if the branch
|
||||
* @return 0 on success, GIT_ENOTFOUND if the branch
|
||||
* doesn't exist or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_move(
|
||||
|
@ -28,7 +28,7 @@ GIT_BEGIN_DECL
|
||||
* @param repo the repo to use when locating the commit.
|
||||
* @param id identity of the commit to locate. If the object is
|
||||
* an annotated tag it will be peeled back to the commit.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id)
|
||||
{
|
||||
@ -46,7 +46,7 @@ GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, con
|
||||
* @param id identity of the commit to locate. If the object is
|
||||
* an annotated tag it will be peeled back to the commit.
|
||||
* @param len the length of the short identifier
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, unsigned len)
|
||||
{
|
||||
@ -135,7 +135,7 @@ GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit);
|
||||
*
|
||||
* @param tree_out pointer where to store the tree object
|
||||
* @param commit a previously loaded commit.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit);
|
||||
|
||||
@ -163,7 +163,7 @@ GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *commit);
|
||||
* @param parent Pointer where to store the parent commit
|
||||
* @param commit a previously loaded commit.
|
||||
* @param n the position of the parent (from 0 to `parentcount`)
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n);
|
||||
|
||||
@ -221,7 +221,7 @@ GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned i
|
||||
* array may be NULL if `parent_count` is 0 (root commit). All the
|
||||
* given commits must be owned by the `repo`.
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
* The created commit will be written to the Object Database and
|
||||
* the given reference will be updated to point to it
|
||||
*/
|
||||
|
@ -77,7 +77,7 @@ GIT_BEGIN_DECL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The maximum length of a git valid git path.
|
||||
* The maximum length of a valid git path.
|
||||
*/
|
||||
#define GIT_PATH_MAX 4096
|
||||
|
||||
|
@ -62,10 +62,10 @@ typedef struct {
|
||||
* global configuration file.
|
||||
*
|
||||
* @param global_config_path Buffer of GIT_PATH_MAX length to store the path
|
||||
* @return GIT_SUCCESS if a global configuration file has been
|
||||
* @return 0 if a global configuration file has been
|
||||
* found. Its path will be stored in `buffer`.
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_find_global(char *global_config_path);
|
||||
GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length);
|
||||
|
||||
/**
|
||||
* Locate the path to the system configuration file
|
||||
@ -74,10 +74,10 @@ GIT_EXTERN(int) git_config_find_global(char *global_config_path);
|
||||
* %PROGRAMFILES%\Git\etc\gitconfig.
|
||||
|
||||
* @param system_config_path Buffer of GIT_PATH_MAX length to store the path
|
||||
* @return GIT_SUCCESS if a system configuration file has been
|
||||
* @return 0 if a system configuration file has been
|
||||
* found. Its path will be stored in `buffer`.
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_find_system(char *system_config_path);
|
||||
GIT_EXTERN(int) git_config_find_system(char *system_config_path, size_t length);
|
||||
|
||||
/**
|
||||
* Open the global configuration file
|
||||
@ -86,7 +86,7 @@ GIT_EXTERN(int) git_config_find_system(char *system_config_path);
|
||||
* and opens the located file, if it exists.
|
||||
*
|
||||
* @param out Pointer to store the config instance
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_global(git_config **out);
|
||||
|
||||
@ -110,7 +110,7 @@ GIT_EXTERN(int) git_config_file__ondisk(struct git_config_file **out, const char
|
||||
* can do anything with it.
|
||||
*
|
||||
* @param out pointer to the new configuration
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_new(git_config **out);
|
||||
|
||||
@ -127,7 +127,7 @@ GIT_EXTERN(int) git_config_new(git_config **out);
|
||||
* @param cfg the configuration to add the file to
|
||||
* @param file the configuration file (backend) to add
|
||||
* @param priority the priority the backend should have
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_add_file(git_config *cfg, git_config_file *file, int priority);
|
||||
|
||||
@ -148,7 +148,7 @@ GIT_EXTERN(int) git_config_add_file(git_config *cfg, git_config_file *file, int
|
||||
* @param cfg the configuration to add the file to
|
||||
* @param path path to the configuration file (backend) to add
|
||||
* @param priority the priority the backend should have
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_add_file_ondisk(git_config *cfg, const char *path, int priority);
|
||||
|
||||
@ -163,7 +163,7 @@ GIT_EXTERN(int) git_config_add_file_ondisk(git_config *cfg, const char *path, in
|
||||
*
|
||||
* @param cfg The configuration instance to create
|
||||
* @param path Path to the on-disk file to open
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path);
|
||||
|
||||
@ -177,22 +177,22 @@ GIT_EXTERN(void) git_config_free(git_config *cfg);
|
||||
/**
|
||||
* Get the value of an integer config variable.
|
||||
*
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_int32(git_config *cfg, const char *name, int32_t *out);
|
||||
GIT_EXTERN(int) git_config_get_int32(int32_t *out, git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a long integer config variable.
|
||||
*
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_int64(git_config *cfg, const char *name, int64_t *out);
|
||||
GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a boolean config variable.
|
||||
@ -200,12 +200,12 @@ GIT_EXTERN(int) git_config_get_int64(git_config *cfg, const char *name, int64_t
|
||||
* This function uses the usual C convention of 0 being false and
|
||||
* anything else true.
|
||||
*
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_bool(git_config *cfg, const char *name, int *out);
|
||||
GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a string config variable.
|
||||
@ -213,12 +213,12 @@ GIT_EXTERN(int) git_config_get_bool(git_config *cfg, const char *name, int *out)
|
||||
* The string is owned by the variable and should not be freed by the
|
||||
* user.
|
||||
*
|
||||
* @param out pointer to the variable's value
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param out pointer to the variable's value
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_string(git_config *cfg, const char *name, const char **out);
|
||||
GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get each value of a multivar.
|
||||
@ -240,7 +240,7 @@ GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param value Integer value for the variable
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value);
|
||||
|
||||
@ -250,7 +250,7 @@ GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param value Long integer value for the variable
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value);
|
||||
|
||||
@ -260,7 +260,7 @@ GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param value the value to store
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value);
|
||||
|
||||
@ -273,7 +273,7 @@ GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param value the string to store.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value);
|
||||
|
||||
@ -307,7 +307,7 @@ GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name);
|
||||
* @param cfg where to get the variables from
|
||||
* @param callback the function to call on each variable
|
||||
* @param payload the data to pass to the callback
|
||||
* @return GIT_SUCCESS or the return value of the callback which didn't return 0
|
||||
* @return 0 or the return value of the callback which didn't return 0
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_foreach(
|
||||
git_config *cfg,
|
||||
@ -342,14 +342,14 @@ GIT_EXTERN(int) git_config_foreach(
|
||||
* If not a single match can be made to store in `out`, an error code will be
|
||||
* returned.
|
||||
*
|
||||
* @param out place to store the result of the mapping
|
||||
* @param cfg config file to get the variables from
|
||||
* @param name name of the config variable to lookup
|
||||
* @param maps array of `git_cvar_map` objects specifying the possible mappings
|
||||
* @param map_n number of mapping objects in `maps`
|
||||
* @param out place to store the result of the mapping
|
||||
* @return GIT_SUCCESS on success, error code otherwise
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n, int *out);
|
||||
GIT_EXTERN(int) git_config_get_mapped(int *out, git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -155,7 +155,7 @@ typedef int (*git_diff_hunk_fn)(
|
||||
*
|
||||
* These values describe where a line came from and will be passed to
|
||||
* the git_diff_data_fn when iterating over a diff. There are some
|
||||
* special origin contants at the end that are used for the text
|
||||
* special origin constants at the end that are used for the text
|
||||
* output callbacks to demarcate lines that are actually part of
|
||||
* the file or hunk headers.
|
||||
*/
|
||||
|
@ -17,30 +17,55 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
typedef enum {
|
||||
#ifdef GIT_OLD_ERRORS
|
||||
enum {
|
||||
GIT_SUCCESS = 0,
|
||||
GIT_ERROR = -1,
|
||||
|
||||
/** Input does not exist in the scope searched. */
|
||||
GIT_ENOTOID = -2,
|
||||
GIT_ENOTFOUND = -3,
|
||||
|
||||
/** A reference with this name already exists */
|
||||
GIT_ENOMEM = -4,
|
||||
GIT_EOSERR = -5,
|
||||
GIT_EOBJTYPE = -6,
|
||||
GIT_ENOTAREPO = -7,
|
||||
GIT_EINVALIDTYPE = -8,
|
||||
GIT_EMISSINGOBJDATA = -9,
|
||||
GIT_EPACKCORRUPTED = -10,
|
||||
GIT_EFLOCKFAIL = -11,
|
||||
GIT_EZLIB = -12,
|
||||
GIT_EBUSY = -13,
|
||||
GIT_EBAREINDEX = -14,
|
||||
GIT_EINVALIDREFNAME = -15,
|
||||
GIT_EREFCORRUPTED = -16,
|
||||
GIT_ETOONESTEDSYMREF = -17,
|
||||
GIT_EPACKEDREFSCORRUPTED = -18,
|
||||
GIT_EINVALIDPATH = -19,
|
||||
GIT_EREVWALKOVER = -20,
|
||||
GIT_EINVALIDREFSTATE = -21,
|
||||
GIT_ENOTIMPLEMENTED = -22,
|
||||
GIT_EEXISTS = -23,
|
||||
|
||||
/** The given integer literal is too large to be parsed */
|
||||
GIT_EOVERFLOW = -24,
|
||||
|
||||
/** The given short oid is ambiguous */
|
||||
GIT_ENOTNUM = -25,
|
||||
GIT_ESTREAM = -26,
|
||||
GIT_EINVALIDARGS = -27,
|
||||
GIT_EOBJCORRUPTED = -28,
|
||||
GIT_EAMBIGUOUS = -29,
|
||||
|
||||
/** Skip and passthrough the given ODB backend */
|
||||
GIT_EPASSTHROUGH = -30,
|
||||
|
||||
/** The buffer is too short to satisfy the request */
|
||||
GIT_ENOMATCH = -31,
|
||||
GIT_ESHORTBUFFER = -32,
|
||||
};
|
||||
#endif
|
||||
|
||||
GIT_EREVWALKOVER = -33,
|
||||
} git_error_t;
|
||||
/** Generic return codes */
|
||||
enum {
|
||||
GIT_OK = 0,
|
||||
GIT_ERROR = -1,
|
||||
GIT_ENOTFOUND = -3,
|
||||
GIT_EEXISTS = -4,
|
||||
GIT_EAMBIGUOUS = -5,
|
||||
GIT_EBUFS = -6,
|
||||
|
||||
GIT_PASSTHROUGH = -30,
|
||||
GIT_REVWALKOVER = -31,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *message;
|
||||
@ -62,7 +87,8 @@ typedef enum {
|
||||
GITERR_NET,
|
||||
GITERR_TAG,
|
||||
GITERR_TREE,
|
||||
} git_error_class;
|
||||
GITERR_INDEXER,
|
||||
} git_error_t;
|
||||
|
||||
/**
|
||||
* Return the last `git_error` object that was generated for the
|
||||
|
@ -106,7 +106,7 @@ typedef struct git_index_entry_unmerged {
|
||||
*
|
||||
* @param index the pointer for the new index
|
||||
* @param index_path the path to the index file in disk
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path);
|
||||
|
||||
@ -131,7 +131,7 @@ GIT_EXTERN(void) git_index_free(git_index *index);
|
||||
* by reading from the hard disk.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_read(git_index *index);
|
||||
|
||||
@ -140,7 +140,7 @@ GIT_EXTERN(int) git_index_read(git_index *index);
|
||||
* using an atomic file lock.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_write(git_index *index);
|
||||
|
||||
@ -176,7 +176,7 @@ GIT_EXTERN(void) git_index_uniq(git_index *index);
|
||||
* @param index an existing index object
|
||||
* @param path filename to add
|
||||
* @param stage stage for the entry
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
|
||||
|
||||
@ -188,7 +188,7 @@ GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry);
|
||||
|
||||
@ -207,7 +207,7 @@ GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_e
|
||||
* @param index an existing index object
|
||||
* @param path filename to add
|
||||
* @param stage stage for the entry
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
|
||||
|
||||
@ -224,7 +224,7 @@ GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry);
|
||||
|
||||
@ -233,7 +233,7 @@ GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *sourc
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param position position of the entry to remove
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_remove(git_index *index, int position);
|
||||
|
||||
@ -295,7 +295,7 @@ GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_
|
||||
/**
|
||||
* Return the stage number from a git index entry
|
||||
*
|
||||
* This entry is calculated from the entrie's flag
|
||||
* This entry is calculated from the entry's flag
|
||||
* attribute like this:
|
||||
*
|
||||
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
|
||||
@ -312,7 +312,7 @@ GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param tree tree to read
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree);
|
||||
|
||||
|
@ -28,7 +28,7 @@ typedef struct git_indexer_stream git_indexer_stream;
|
||||
/**
|
||||
* Create a new streaming indexer instance
|
||||
*
|
||||
* @param out where to store the inexer instance
|
||||
* @param out where to store the indexer instance
|
||||
* @param path to the gitdir (metadata directory)
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *gitdir);
|
||||
|
@ -28,7 +28,7 @@ GIT_BEGIN_DECL
|
||||
* @param notes_ref OID reference to use (optional); defaults to "refs/notes/commits"
|
||||
* @param oid OID of the object
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo,
|
||||
const char *notes_ref, const git_oid *oid);
|
||||
@ -62,7 +62,7 @@ GIT_EXTERN(const git_oid *) git_note_oid(git_note *note);
|
||||
* @param oid The OID of the object
|
||||
* @param oid The note to add for object oid
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_create(git_oid *out, git_repository *repo,
|
||||
git_signature *author, git_signature *committer,
|
||||
@ -79,7 +79,7 @@ GIT_EXTERN(int) git_note_create(git_oid *out, git_repository *repo,
|
||||
* @param committer signature of the notes commit committer
|
||||
* @param oid the oid which note's to be removed
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_remove(git_repository *repo, const char *notes_ref,
|
||||
git_signature *author, git_signature *committer,
|
||||
@ -98,10 +98,42 @@ GIT_EXTERN(void) git_note_free(git_note *note);
|
||||
* @param out Pointer to the default notes reference
|
||||
* @param repo The Git repository
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Basic components of a note
|
||||
*
|
||||
* - Oid of the blob containing the message
|
||||
* - Oid of the git object being annotated
|
||||
*/
|
||||
typedef struct {
|
||||
git_oid blob_oid;
|
||||
git_oid annotated_object_oid;
|
||||
} git_note_data;
|
||||
|
||||
/**
|
||||
* Loop over all the notes within a specified namespace
|
||||
* and issue a callback for each one.
|
||||
*
|
||||
* @param repo Repository where to find the notes.
|
||||
*
|
||||
* @param notes_ref OID reference to read from (optional); defaults to "refs/notes/commits".
|
||||
*
|
||||
* @param note_cb Callback to invoke per found annotation.
|
||||
*
|
||||
* @param payload Extra parameter to callback function.
|
||||
*
|
||||
* @return 0 or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_note_foreach(
|
||||
git_repository *repo,
|
||||
const char *notes_ref,
|
||||
int (*note_cb)(git_note_data *note_data, void *payload),
|
||||
void *payload
|
||||
);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -21,7 +21,7 @@
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Lookup a reference to one of the objects in a repostory.
|
||||
* Lookup a reference to one of the objects in a repository.
|
||||
*
|
||||
* The generated reference is owned by the repository and
|
||||
* should be closed with the `git_object_free` method
|
||||
@ -45,7 +45,7 @@ GIT_EXTERN(int) git_object_lookup(
|
||||
git_otype type);
|
||||
|
||||
/**
|
||||
* Lookup a reference to one of the objects in a repostory,
|
||||
* Lookup a reference to one of the objects in a repository,
|
||||
* given a prefix of its identifier (short id).
|
||||
*
|
||||
* The object obtained will be so that its identifier
|
||||
@ -69,7 +69,7 @@ GIT_EXTERN(int) git_object_lookup(
|
||||
* @param id a short identifier for the object
|
||||
* @param len the length of the short identifier
|
||||
* @param type the type of the object
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_object_lookup_prefix(
|
||||
git_object **object_out,
|
||||
@ -114,7 +114,7 @@ GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
|
||||
* This method instructs the library to close an existing
|
||||
* object; note that git_objects are owned and cached by the repository
|
||||
* so the object may or may not be freed after this library call,
|
||||
* depending on how agressive is the caching mechanism used
|
||||
* depending on how aggressive is the caching mechanism used
|
||||
* by the repository.
|
||||
*
|
||||
* IMPORTANT:
|
||||
|
@ -29,7 +29,7 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param out location to store the database pointer, if opened.
|
||||
* Set to NULL if the open failed.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_new(git_odb **out);
|
||||
|
||||
@ -47,7 +47,7 @@ GIT_EXTERN(int) git_odb_new(git_odb **out);
|
||||
* @param out location to store the database pointer, if opened.
|
||||
* Set to NULL if the open failed.
|
||||
* @param objects_dir path of the backends' "objects" directory.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
|
||||
|
||||
@ -62,7 +62,7 @@ GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
|
||||
* @param odb database to add the backend to
|
||||
* @param backend pointer to a git_odb_backend instance
|
||||
* @param priority Value for ordering the backends queue
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
|
||||
|
||||
@ -83,7 +83,7 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int
|
||||
* @param odb database to add the backend to
|
||||
* @param backend pointer to a git_odb_backend instance
|
||||
* @param priority Value for ordering the backends queue
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
|
||||
|
||||
@ -108,7 +108,7 @@ GIT_EXTERN(void) git_odb_free(git_odb *db);
|
||||
* @param db database to search for the object in.
|
||||
* @param id identity of the object to read.
|
||||
* @return
|
||||
* - GIT_SUCCESS if the object was read;
|
||||
* - 0 if the object was read;
|
||||
* - GIT_ENOTFOUND if the object is not in the database.
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id);
|
||||
@ -135,7 +135,7 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i
|
||||
* @param db database to search for the object in.
|
||||
* @param short_id a prefix of the id of the object to read.
|
||||
* @param len the length of the prefix
|
||||
* @return GIT_SUCCESS if the object was read;
|
||||
* @return 0 if the object was read;
|
||||
* GIT_ENOTFOUND if the object is not in the database.
|
||||
* GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)
|
||||
*/
|
||||
@ -156,7 +156,7 @@ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git
|
||||
* @param db database to search for the object in.
|
||||
* @param id identity of the object to read.
|
||||
* @return
|
||||
* - GIT_SUCCESS if the object was read;
|
||||
* - 0 if the object was read;
|
||||
* - GIT_ENOTFOUND if the object is not in the database.
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id);
|
||||
@ -185,10 +185,10 @@ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
|
||||
*
|
||||
* @param oid pointer to store the OID result of the write
|
||||
* @param odb object database where to store the object
|
||||
* @param data buffer with the data to storr
|
||||
* @param data buffer with the data to store
|
||||
* @param len size of the buffer
|
||||
* @param type type of the data to store
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size_t len, git_otype type);
|
||||
|
||||
@ -250,14 +250,14 @@ GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const
|
||||
/**
|
||||
* Determine the object-ID (sha1 hash) of a data buffer
|
||||
*
|
||||
* The resulting SHA-1 OID will the itentifier for the data
|
||||
* The resulting SHA-1 OID will be the identifier for the data
|
||||
* buffer as if the data buffer it were to written to the ODB.
|
||||
*
|
||||
* @param id the resulting object-ID.
|
||||
* @param data data to hash
|
||||
* @param len size of the data
|
||||
* @param type of the data to hash
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type);
|
||||
|
||||
@ -270,7 +270,7 @@ GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otyp
|
||||
* @param out oid structure the result is written into.
|
||||
* @param path file to read and determine object id for
|
||||
* @param type the type of the object that will be hashed
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_otype type);
|
||||
|
||||
|
@ -74,6 +74,13 @@ struct git_odb_backend {
|
||||
void (* free)(struct git_odb_backend *);
|
||||
};
|
||||
|
||||
/** Streaming mode */
|
||||
enum {
|
||||
GIT_STREAM_RDONLY = (1 << 1),
|
||||
GIT_STREAM_WRONLY = (1 << 2),
|
||||
GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
|
||||
};
|
||||
|
||||
/** A stream to read/write from a backend */
|
||||
struct git_odb_stream {
|
||||
struct git_odb_backend *backend;
|
||||
@ -85,13 +92,6 @@ struct git_odb_stream {
|
||||
void (*free)(struct git_odb_stream *stream);
|
||||
};
|
||||
|
||||
/** Streaming mode */
|
||||
typedef enum {
|
||||
GIT_STREAM_RDONLY = (1 << 1),
|
||||
GIT_STREAM_WRONLY = (1 << 2),
|
||||
GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
|
||||
} git_odb_streammode;
|
||||
|
||||
GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir);
|
||||
GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync);
|
||||
|
||||
|
@ -43,7 +43,7 @@ struct _git_oid {
|
||||
* @param str input hex string; must be pointing at the start of
|
||||
* the hex sequence and have at least the number of bytes
|
||||
* needed for an oid encoded in hex (40 bytes).
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
|
||||
|
||||
@ -56,7 +56,7 @@ GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
|
||||
* @param out oid structure the result is written into.
|
||||
* @param str input hex string of at least size `length`
|
||||
* @param length length of the input string
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length);
|
||||
|
||||
@ -84,7 +84,7 @@ GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid);
|
||||
* Format a git_oid into a loose-object path string.
|
||||
*
|
||||
* The resulting string is "aa/...", where "aa" is the first two
|
||||
* hex digitis of the oid and "..." is the remaining 38 digits.
|
||||
* hex digits of the oid and "..." is the remaining 38 digits.
|
||||
*
|
||||
* @param str output hex string; must be pointing at the start of
|
||||
* the hex sequence and have at least the number of bytes
|
||||
@ -155,7 +155,7 @@ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, unsigned int le
|
||||
* @param a oid structure.
|
||||
* @param str input hex string of an object id.
|
||||
* @return GIT_ENOTOID if str is not a valid hex string,
|
||||
* GIT_SUCCESS in case of a match, GIT_ERROR otherwise.
|
||||
* 0 in case of a match, GIT_ERROR otherwise.
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str);
|
||||
|
||||
@ -183,7 +183,7 @@ typedef struct git_oid_shorten git_oid_shorten;
|
||||
* be unique.
|
||||
* @return a `git_oid_shorten` instance, NULL if OOM
|
||||
*/
|
||||
git_oid_shorten *git_oid_shorten_new(size_t min_length);
|
||||
GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
|
||||
|
||||
/**
|
||||
* Add a new OID to set of shortened OIDs and calculate
|
||||
@ -209,14 +209,14 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length);
|
||||
* added so far to the set; or an error code (<0) if an
|
||||
* error occurs.
|
||||
*/
|
||||
int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid);
|
||||
GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_oid);
|
||||
|
||||
/**
|
||||
* Free an OID shortener instance
|
||||
*
|
||||
* @param os a `git_oid_shorten` instance
|
||||
*/
|
||||
void git_oid_shorten_free(git_oid_shorten *os);
|
||||
GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -28,7 +28,7 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param reflog pointer to reflog
|
||||
* @param ref reference to read the reflog for
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref);
|
||||
|
||||
@ -46,7 +46,7 @@ GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref);
|
||||
* @param oid_old the OID the reference was pointing to
|
||||
* @param committer the signature of the committer
|
||||
* @param msg the reflog message
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_write(git_reference *ref, const git_oid *oid_old, const git_signature *committer, const char *msg);
|
||||
|
||||
@ -55,7 +55,7 @@ GIT_EXTERN(int) git_reflog_write(git_reference *ref, const git_oid *oid_old, con
|
||||
*
|
||||
* @param ref the reference
|
||||
* @param new_name the new name of the reference
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *new_name);
|
||||
|
||||
@ -63,7 +63,7 @@ GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *new_name);
|
||||
* Delete the reflog for the given reference
|
||||
*
|
||||
* @param ref the reference
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reflog_delete(git_reference *ref);
|
||||
|
||||
|
@ -28,7 +28,7 @@ GIT_BEGIN_DECL
|
||||
* @param reference_out pointer to the looked-up reference
|
||||
* @param repo the repository to look up the reference
|
||||
* @param name the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...)
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name);
|
||||
|
||||
@ -59,7 +59,7 @@ GIT_EXTERN(int) git_reference_name_to_oid(
|
||||
* @param name The name of the reference
|
||||
* @param target The target of the reference
|
||||
* @param force Overwrite existing references
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force);
|
||||
|
||||
@ -79,7 +79,7 @@ GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repos
|
||||
* @param name The name of the reference
|
||||
* @param id The object id pointed to by the reference.
|
||||
* @param force Overwrite existing references
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force);
|
||||
|
||||
@ -111,7 +111,7 @@ GIT_EXTERN(const char *) git_reference_target(git_reference *ref);
|
||||
* @param ref The reference
|
||||
* @return the type
|
||||
*/
|
||||
GIT_EXTERN(git_rtype) git_reference_type(git_reference *ref);
|
||||
GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Get the full name of a reference
|
||||
@ -124,7 +124,7 @@ GIT_EXTERN(const char *) git_reference_name(git_reference *ref);
|
||||
/**
|
||||
* Resolve a symbolic reference
|
||||
*
|
||||
* Thie method iteratively peels a symbolic reference
|
||||
* This method iteratively peels a symbolic reference
|
||||
* until it resolves to a direct reference to an OID.
|
||||
*
|
||||
* The peeled reference is returned in the `resolved_ref`
|
||||
@ -137,7 +137,7 @@ GIT_EXTERN(const char *) git_reference_name(git_reference *ref);
|
||||
*
|
||||
* @param resolved_ref Pointer to the peeled reference
|
||||
* @param ref The reference
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref);
|
||||
|
||||
@ -160,7 +160,7 @@ GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref);
|
||||
*
|
||||
* @param ref The reference
|
||||
* @param target The new target for the reference
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target);
|
||||
|
||||
@ -175,7 +175,7 @@ GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target)
|
||||
*
|
||||
* @param ref The reference
|
||||
* @param id The new target OID for the reference
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
|
||||
|
||||
@ -202,7 +202,7 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
|
||||
* @param ref The reference to rename
|
||||
* @param new_name The new name for the reference
|
||||
* @param force Overwrite an existing reference
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force);
|
||||
@ -216,7 +216,7 @@ GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, i
|
||||
* memory. The given reference pointer will no longer be valid.
|
||||
*
|
||||
* @param ref The reference to remove
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_delete(git_reference *ref);
|
||||
|
||||
@ -231,7 +231,7 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
|
||||
* the loose references will be removed from disk.
|
||||
*
|
||||
* @param repo Repository where the loose refs will be packed
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_packall(git_repository *repo);
|
||||
|
||||
@ -254,9 +254,9 @@ GIT_EXTERN(int) git_reference_packall(git_repository *repo);
|
||||
* @param repo Repository where to find the refs
|
||||
* @param list_flags Filtering flags for the reference
|
||||
* listing.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo, unsigned int list_flags);
|
||||
GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
|
||||
|
||||
|
||||
/**
|
||||
@ -276,7 +276,7 @@ GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo,
|
||||
* listing.
|
||||
* @param callback Function which will be called for every listed ref
|
||||
* @param payload Additional data to pass to the callback
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload);
|
||||
|
||||
@ -293,7 +293,7 @@ GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
|
||||
*
|
||||
* Reference pointers may become outdated if the Git
|
||||
* repository is accessed simultaneously by other clients
|
||||
* whilt the library is open.
|
||||
* while the library is open.
|
||||
*
|
||||
* This method forces a reload of the reference from disk,
|
||||
* to ensure that the provided information is still
|
||||
@ -304,7 +304,7 @@ GIT_EXTERN(int) git_reference_is_packed(git_reference *ref);
|
||||
* returned and the reference pointer will be invalidated.
|
||||
*
|
||||
* @param ref The reference to reload
|
||||
* @return GIT_SUCCESS on success, or an error code
|
||||
* @return 0 on success, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_reload(git_reference *ref);
|
||||
|
||||
@ -320,7 +320,7 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref);
|
||||
*
|
||||
* @param ref1 The first git_reference
|
||||
* @param ref2 The second git_reference
|
||||
* @return GIT_SUCCESS if the same, else a stable but meaningless ordering.
|
||||
* @return 0 if the same, else a stable but meaningless ordering.
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
|
||||
|
||||
|
@ -25,7 +25,7 @@ GIT_BEGIN_DECL
|
||||
* @param refspec the refspec
|
||||
* @return the refspec's source specifier
|
||||
*/
|
||||
const char *git_refspec_src(const git_refspec *refspec);
|
||||
GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec);
|
||||
|
||||
/**
|
||||
* Get the destination specifier
|
||||
@ -33,7 +33,15 @@ const char *git_refspec_src(const git_refspec *refspec);
|
||||
* @param refspec the refspec
|
||||
* @return the refspec's destination specifier
|
||||
*/
|
||||
const char *git_refspec_dst(const git_refspec *refspec);
|
||||
GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec);
|
||||
|
||||
/**
|
||||
* Get the force update setting
|
||||
*
|
||||
* @param refspec the refspec
|
||||
* @return 1 if force update has been set, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec);
|
||||
|
||||
/**
|
||||
* Check if a refspec's source descriptor matches a reference
|
||||
@ -42,7 +50,7 @@ const char *git_refspec_dst(const git_refspec *refspec);
|
||||
* @param refname the name of the reference to check
|
||||
* @return 1 if the refspec matches, 0 otherwise
|
||||
*/
|
||||
int git_refspec_src_matches(const git_refspec *refspec, const char *refname);
|
||||
GIT_EXTERN(int) git_refspec_src_matches(const git_refspec *refspec, const char *refname);
|
||||
|
||||
/**
|
||||
* Transform a reference to its target following the refspec's rules
|
||||
@ -51,9 +59,9 @@ int git_refspec_src_matches(const git_refspec *refspec, const char *refname);
|
||||
* @param outlen the size ouf the `out` buffer
|
||||
* @param spec the refspec
|
||||
* @param name the name of the reference to transform
|
||||
* @return GIT_SUCCESS, GIT_ESHORTBUFFER or another error
|
||||
* @return 0, GIT_EBUFS or another error
|
||||
*/
|
||||
int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name);
|
||||
GIT_EXTERN(int) git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
|
@ -37,11 +37,11 @@ GIT_BEGIN_DECL
|
||||
* this when you have a URL instead of a remote's name.
|
||||
*
|
||||
* @param out pointer to the new remote object
|
||||
* @param repo the associtated repository
|
||||
* @param repo the associated repository
|
||||
* @param name the remote's name
|
||||
* @param url the remote repository's URL
|
||||
* @param fetch the fetch refspec to use for this remote
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch);
|
||||
|
||||
@ -51,7 +51,7 @@ GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const cha
|
||||
* @param out pointer to the new remote object
|
||||
* @param cfg the repository's configuration
|
||||
* @param name the remote's name
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const char *name);
|
||||
|
||||
@ -59,7 +59,7 @@ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const ch
|
||||
* Save a remote to its repository's configuration
|
||||
*
|
||||
* @param remote the remote to save to config
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_save(const git_remote *remote);
|
||||
|
||||
@ -84,7 +84,7 @@ GIT_EXTERN(const char *) git_remote_url(git_remote *remote);
|
||||
*
|
||||
* @param remote the remote
|
||||
* @apram spec the new fetch refspec
|
||||
* @return GIT_SUCCESS or an error value
|
||||
* @return 0 or an error value
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec);
|
||||
|
||||
@ -100,8 +100,8 @@ GIT_EXTERN(const git_refspec *) git_remote_fetchspec(git_remote *remote);
|
||||
* Set the remote's push refspec
|
||||
*
|
||||
* @param remote the remote
|
||||
* @apram spec the new push refspec
|
||||
* @return GIT_SUCCESS or an error value
|
||||
* @param spec the new push refspec
|
||||
* @return 0 or an error value
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec);
|
||||
|
||||
@ -123,7 +123,7 @@ GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote);
|
||||
*
|
||||
* @param remote the remote to connect to
|
||||
* @param direction whether you want to receive or send data
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction);
|
||||
|
||||
@ -135,7 +135,7 @@ GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction);
|
||||
*
|
||||
* @param refs where to store the refs
|
||||
* @param remote the remote
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload);
|
||||
|
||||
@ -149,8 +149,8 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void
|
||||
* filename will be NULL and the function will return success.
|
||||
*
|
||||
* @param remote the remote to download from
|
||||
* @param filename where to store the temproray filename
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @param filename where to store the temporary filename
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats);
|
||||
|
||||
@ -195,7 +195,7 @@ GIT_EXTERN(int) git_remote_update_tips(git_remote *remote, int (*cb)(const char
|
||||
/**
|
||||
* Return whether a string is a valid remote URL
|
||||
*
|
||||
* @param tranport the url to check
|
||||
* @param url the url to check
|
||||
* @param 1 if the url is valid, 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_valid_url(const char *url);
|
||||
@ -215,7 +215,7 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url);
|
||||
*
|
||||
* @param remotes_list a string array with the names of the remotes
|
||||
* @param repo the repository to query
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_list(git_strarray *remotes_list, git_repository *repo);
|
||||
|
||||
|
@ -31,7 +31,7 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param repository pointer to the repo which will be opened
|
||||
* @param path the path to the repository
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path);
|
||||
|
||||
@ -61,7 +61,7 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat
|
||||
* start_path no matter start_path appears in ceiling_dirs ceiling_dirs
|
||||
* might be NULL (which is equivalent to an empty string)
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_discover(
|
||||
char *repository_path,
|
||||
@ -109,7 +109,7 @@ GIT_EXTERN(void) git_repository_free(git_repository *repo);
|
||||
* at the pointed path. If false, provided path will be considered as the working
|
||||
* directory into which the .git directory will be created.
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_init(git_repository **repo_out, const char *path, unsigned is_bare);
|
||||
|
||||
@ -130,7 +130,7 @@ GIT_EXTERN(int) git_repository_head(git_reference **head_out, git_repository *re
|
||||
* instead of a branch.
|
||||
*
|
||||
* @param repo Repo to test
|
||||
* @return 1 if HEAD is detached, 0 if i'ts not; error code if there
|
||||
* @return 1 if HEAD is detached, 0 if it's not; error code if there
|
||||
* was an error.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
|
||||
@ -143,7 +143,7 @@ GIT_EXTERN(int) git_repository_head_detached(git_repository *repo);
|
||||
*
|
||||
* @param repo Repo to test
|
||||
* @return 1 if the current branch is an orphan, 0 if it's not; error
|
||||
* code if therewas an error
|
||||
* code if there was an error
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo);
|
||||
|
||||
@ -194,7 +194,7 @@ GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo);
|
||||
*
|
||||
* @param repo A repository object
|
||||
* @param workdir The path to a working directory
|
||||
* @return GIT_SUCCESS, or an error code
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_set_workdir(git_repository *repo, const char *workdir);
|
||||
|
||||
@ -218,7 +218,7 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
|
||||
*
|
||||
* @param out Pointer to store the loaded config file
|
||||
* @param repo A repository object
|
||||
* @return GIT_SUCCESS, or an error code
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo);
|
||||
|
||||
@ -249,7 +249,7 @@ GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *con
|
||||
*
|
||||
* @param out Pointer to store the loaded ODB
|
||||
* @param repo A repository object
|
||||
* @return GIT_SUCCESS, or an error code
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);
|
||||
|
||||
@ -280,7 +280,7 @@ GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
|
||||
*
|
||||
* @param out Pointer to store the loaded index
|
||||
* @param repo A repository object
|
||||
* @return GIT_SUCCESS, or an error code
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
|
||||
|
||||
|
@ -65,7 +65,7 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param walker pointer to the new revision walker
|
||||
* @param repo the repo to walk through
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_new(git_revwalk **walker, git_repository *repo);
|
||||
|
||||
@ -97,14 +97,14 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
|
||||
*
|
||||
* @param walk the walker being used for the traversal.
|
||||
* @param oid the oid of the commit to start from.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Push matching references
|
||||
*
|
||||
* The OIDs pinted to by the references that match the given glob
|
||||
* The OIDs pointed to by the references that match the given glob
|
||||
* pattern will be pushed to the revision walker.
|
||||
*
|
||||
* A leading 'refs/' is implied it not present as well as a trailing
|
||||
@ -112,7 +112,7 @@ GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid);
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param glob the glob pattern references should match
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob);
|
||||
|
||||
@ -120,7 +120,7 @@ GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob);
|
||||
* Push the repository's HEAD
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
|
||||
|
||||
@ -135,14 +135,14 @@ GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk);
|
||||
*
|
||||
* @param walk the walker being used for the traversal.
|
||||
* @param oid the oid of commit that will be ignored during the traversal
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid);
|
||||
|
||||
/**
|
||||
* Hide matching references.
|
||||
*
|
||||
* The OIDs pinted to by the references that match the given glob
|
||||
* The OIDs pointed to by the references that match the given glob
|
||||
* pattern and their ancestors will be hidden from the output on the
|
||||
* revision walk.
|
||||
*
|
||||
@ -151,7 +151,7 @@ GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid);
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param glob the glob pattern references should match
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob);
|
||||
|
||||
@ -159,7 +159,7 @@ GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob);
|
||||
* Hide the repository's HEAD
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
|
||||
|
||||
@ -169,8 +169,8 @@ GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
|
||||
* The reference must point to a commit.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param refname the referece to push
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @param refname the reference to push
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
|
||||
|
||||
@ -180,8 +180,8 @@ GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
|
||||
* The reference must point to a commit.
|
||||
*
|
||||
* @param walk the walker being used for the traversal
|
||||
* @param refname the referece to hide
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @param refname the reference to hide
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
|
||||
|
||||
@ -200,8 +200,8 @@ GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
|
||||
*
|
||||
* @param oid Pointer where to store the oid of the next commit
|
||||
* @param walk the walker to pop the commit from.
|
||||
* @return GIT_SUCCESS if the next commit was found;
|
||||
* GIT_EREVWALKOVER if there are no commits left to iterate
|
||||
* @return 0 if the next commit was found;
|
||||
* GIT_REVWALKOVER if there are no commits left to iterate
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
|
||||
|
||||
|
@ -28,7 +28,7 @@ GIT_BEGIN_DECL
|
||||
* @param email email of the person
|
||||
* @param time time when the action happened
|
||||
* @param offset timezone offset in minutes for the time
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset);
|
||||
|
||||
@ -39,7 +39,7 @@ GIT_EXTERN(int) git_signature_new(git_signature **sig_out, const char *name, con
|
||||
* @param sig_out new signature, in case of error NULL
|
||||
* @param name name of the person
|
||||
* @param email email of the person
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_signature_now(git_signature **sig_out, const char *name, const char *email);
|
||||
|
||||
|
@ -19,32 +19,35 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
#define GIT_STATUS_CURRENT 0
|
||||
enum {
|
||||
GIT_STATUS_CURRENT = 0,
|
||||
|
||||
/** Flags for index status */
|
||||
#define GIT_STATUS_INDEX_NEW (1 << 0)
|
||||
#define GIT_STATUS_INDEX_MODIFIED (1 << 1)
|
||||
#define GIT_STATUS_INDEX_DELETED (1 << 2)
|
||||
GIT_STATUS_INDEX_NEW = (1 << 0),
|
||||
GIT_STATUS_INDEX_MODIFIED = (1 << 1),
|
||||
GIT_STATUS_INDEX_DELETED = (1 << 2),
|
||||
|
||||
/** Flags for worktree status */
|
||||
#define GIT_STATUS_WT_NEW (1 << 3)
|
||||
#define GIT_STATUS_WT_MODIFIED (1 << 4)
|
||||
#define GIT_STATUS_WT_DELETED (1 << 5)
|
||||
GIT_STATUS_WT_NEW = (1 << 3),
|
||||
GIT_STATUS_WT_MODIFIED = (1 << 4),
|
||||
GIT_STATUS_WT_DELETED = (1 << 5),
|
||||
|
||||
#define GIT_STATUS_IGNORED (1 << 6)
|
||||
GIT_STATUS_IGNORED = (1 << 6),
|
||||
};
|
||||
|
||||
/**
|
||||
* Gather file statuses and run a callback for each one.
|
||||
*
|
||||
* The callback is passed the path of the file, the status and the data pointer
|
||||
* passed to this function. If the callback returns something other than
|
||||
* GIT_SUCCESS, this function will return that value.
|
||||
* The callback is passed the path of the file, the status and the data
|
||||
* pointer passed to this function. If the callback returns something other
|
||||
* than 0, this function will return that value.
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @param callback the function to call on each file
|
||||
* @return GIT_SUCCESS or the return value of the callback which did not return GIT_SUCCESS
|
||||
* @return 0 on success or the return value of the callback that was non-zero
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_foreach(git_repository *repo, int (*callback)(const char *, unsigned int, void *), void *payload);
|
||||
GIT_EXTERN(int) git_status_foreach(
|
||||
git_repository *repo,
|
||||
int (*callback)(const char *, unsigned int, void *),
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Select the files on which to report status.
|
||||
@ -94,11 +97,14 @@ typedef enum {
|
||||
* slash on the entry name). Given this flag, the directory
|
||||
* itself will not be included, but all the files in it will.
|
||||
*/
|
||||
#define GIT_STATUS_OPT_INCLUDE_UNTRACKED (1 << 0)
|
||||
#define GIT_STATUS_OPT_INCLUDE_IGNORED (1 << 1)
|
||||
#define GIT_STATUS_OPT_INCLUDE_UNMODIFIED (1 << 2)
|
||||
#define GIT_STATUS_OPT_EXCLUDE_SUBMODULES (1 << 3)
|
||||
#define GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS (1 << 4)
|
||||
|
||||
enum {
|
||||
GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0),
|
||||
GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1),
|
||||
GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2),
|
||||
GIT_STATUS_OPT_EXCLUDE_SUBMODULED = (1 << 3),
|
||||
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4),
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control how callbacks will be made by
|
||||
@ -115,7 +121,7 @@ typedef struct {
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_foreach_ext(
|
||||
git_repository *repo,
|
||||
git_status_options *opts,
|
||||
const git_status_options *opts,
|
||||
int (*callback)(const char *, unsigned int, void *),
|
||||
void *payload);
|
||||
|
||||
@ -127,9 +133,12 @@ GIT_EXTERN(int) git_status_foreach_ext(
|
||||
* @param path the file to retrieve status for, rooted at the repo's workdir
|
||||
* @return GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when
|
||||
* the file doesn't exist in any of HEAD, the index or the worktree,
|
||||
* GIT_SUCCESS otherwise
|
||||
* 0 otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_file(unsigned int *status_flags, git_repository *repo, const char *path);
|
||||
GIT_EXTERN(int) git_status_file(
|
||||
unsigned int *status_flags,
|
||||
git_repository *repo,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Test if the ignore rules apply to a given file.
|
||||
@ -139,13 +148,16 @@ GIT_EXTERN(int) git_status_file(unsigned int *status_flags, git_repository *repo
|
||||
* would be ignored regardless of whether the file is already in the index
|
||||
* or in the repository.
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @param path the file to check ignores for, rooted at the repo's workdir
|
||||
* @param ignored boolean returning 0 if the file is not ignored, 1 if it is
|
||||
* @return GIT_SUCCESS if the ignore rules could be processed for the file
|
||||
* (regardless of whether it exists or not), or an error < 0 if they could not.
|
||||
* @param repo a repository object
|
||||
* @param path the file to check ignores for, rooted at the repo's workdir.
|
||||
* @return 0 if ignore rules could be processed for the file (regardless
|
||||
* of whether it exists or not), or an error < 0 if they could not.
|
||||
*/
|
||||
GIT_EXTERN(int) git_status_should_ignore(git_repository *repo, const char *path, int *ignored);
|
||||
GIT_EXTERN(int) git_status_should_ignore(
|
||||
int *ignored,
|
||||
git_repository *repo,
|
||||
const char *path);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -83,7 +83,7 @@ GIT_EXTERN(int) git_submodule_foreach(
|
||||
/**
|
||||
* Lookup submodule information by name or path.
|
||||
*
|
||||
* Given either the submodule name or path (they are ususally the same),
|
||||
* Given either the submodule name or path (they are usually the same),
|
||||
* this returns a structure describing the submodule. If the submodule
|
||||
* does not exist, this will return GIT_ENOTFOUND and set the submodule
|
||||
* pointer to NULL.
|
||||
|
@ -27,7 +27,7 @@ GIT_BEGIN_DECL
|
||||
* @param tag pointer to the looked up tag
|
||||
* @param repo the repo to use when locating the tag.
|
||||
* @param id identity of the tag to locate.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oid *id)
|
||||
{
|
||||
@ -44,7 +44,7 @@ GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oi
|
||||
* @param repo the repo to use when locating the tag.
|
||||
* @param id identity of the tag to locate.
|
||||
* @param len the length of the short identifier
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tag_lookup_prefix(git_tag **tag, git_repository *repo, const git_oid *id, unsigned int len)
|
||||
{
|
||||
@ -85,7 +85,7 @@ GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag);
|
||||
*
|
||||
* @param target pointer where to store the target
|
||||
* @param tag a previously loaded tag.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag);
|
||||
|
||||
@ -161,7 +161,7 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
*
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
* A tag object is written to the ODB, and a proper reference
|
||||
* is written in the /refs/tags folder, pointing to it
|
||||
*/
|
||||
@ -181,7 +181,7 @@ GIT_EXTERN(int) git_tag_create(
|
||||
* @param repo Repository where to store the tag
|
||||
* @param buffer Raw tag data
|
||||
* @param force Overwrite existing tags
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_frombuffer(
|
||||
git_oid *oid,
|
||||
@ -212,7 +212,7 @@ GIT_EXTERN(int) git_tag_create_frombuffer(
|
||||
*
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
* A proper reference is written in the /refs/tags folder,
|
||||
* pointing to the provided target object
|
||||
*/
|
||||
@ -231,7 +231,7 @@ GIT_EXTERN(int) git_tag_create_lightweight(
|
||||
* @param tag_name Name of the tag to be deleted;
|
||||
* this name is validated for consistency.
|
||||
*
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_delete(
|
||||
git_repository *repo,
|
||||
@ -248,7 +248,7 @@ GIT_EXTERN(int) git_tag_delete(
|
||||
* @param tag_names Pointer to a git_strarray structure where
|
||||
* the tag names will be stored
|
||||
* @param repo Repository where to find the tags
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_list(
|
||||
git_strarray *tag_names,
|
||||
@ -270,7 +270,7 @@ GIT_EXTERN(int) git_tag_list(
|
||||
* the tag names will be stored
|
||||
* @param pattern Standard fnmatch pattern
|
||||
* @param repo Repository where to find the tags
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_list_match(
|
||||
git_strarray *tag_names,
|
||||
@ -286,7 +286,7 @@ GIT_EXTERN(int) git_tag_list_match(
|
||||
*
|
||||
* @param tag_target Pointer to the peeled git_object
|
||||
* @param tag The tag to be processed
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_peel(
|
||||
git_object **tag_target,
|
||||
|
@ -27,7 +27,7 @@ GIT_BEGIN_DECL
|
||||
* @param tree pointer to the looked up tree
|
||||
* @param repo the repo to use when locating the tree.
|
||||
* @param id identity of the tree to locate.
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git_oid *id)
|
||||
{
|
||||
@ -44,7 +44,7 @@ GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git
|
||||
* @param repo the repo to use when locating the tree.
|
||||
* @param id identity of the tree to locate.
|
||||
* @param len the length of the short identifier
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_INLINE(int) git_tree_lookup_prefix(git_tree **tree, git_repository *repo, const git_oid *id, unsigned int len)
|
||||
{
|
||||
@ -141,9 +141,9 @@ GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry);
|
||||
* @param object pointer to the converted object
|
||||
* @param repo repository where to lookup the pointed object
|
||||
* @param entry a tree entry
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_entry_2object(git_object **object_out, git_repository *repo, const git_tree_entry *entry);
|
||||
GIT_EXTERN(int) git_tree_entry_to_object(git_object **object_out, git_repository *repo, const git_tree_entry *entry);
|
||||
|
||||
/**
|
||||
* Write a tree to the ODB from the index file
|
||||
@ -159,7 +159,7 @@ GIT_EXTERN(int) git_tree_entry_2object(git_object **object_out, git_repository *
|
||||
*
|
||||
* @param oid Pointer where to store the written tree
|
||||
* @param index Index to write
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index);
|
||||
|
||||
@ -178,7 +178,7 @@ GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index);
|
||||
*
|
||||
* @param builder_p Pointer where to store the tree builder
|
||||
* @param source Source tree to initialize the builder (optional)
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source);
|
||||
|
||||
@ -229,7 +229,7 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con
|
||||
* @param filename Filename of the entry
|
||||
* @param id SHA1 oid of the entry
|
||||
* @param attributes Folder attributes of the entry
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes);
|
||||
|
||||
@ -264,7 +264,7 @@ GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(cons
|
||||
* @param oid Pointer where to store the written OID
|
||||
* @param repo Repository where to store the object
|
||||
* @param bld Tree builder to write
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld);
|
||||
|
||||
@ -278,8 +278,7 @@ GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_tr
|
||||
* @param subtree Pointer where to store the subtree
|
||||
* @param root A previously loaded tree which will be the root of the relative path
|
||||
* @param subtree_path Path to the contained subtree
|
||||
* @return GIT_SUCCESS on success; GIT_ENOTFOUND if the path does not lead to a
|
||||
* subtree, GIT_EINVALIDPATH or an error code
|
||||
* @return 0 on success; GIT_ENOTFOUND if the path does not lead to a subtree
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_get_subtree(git_tree **subtree, git_tree *root, const char *subtree_path);
|
||||
|
||||
@ -303,50 +302,16 @@ enum git_treewalk_mode {
|
||||
* data itself.
|
||||
*
|
||||
* If the callback returns a negative value, the passed entry
|
||||
* will be skiped on the traversal.
|
||||
* will be skipped on the traversal.
|
||||
*
|
||||
* @param tree The tree to walk
|
||||
* @param callback Function to call on each tree entry
|
||||
* @param mode Traversal mode (pre or post-order)
|
||||
* @param payload Opaque pointer to be passed on each callback
|
||||
* @return GIT_SUCCESS or an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payload);
|
||||
|
||||
typedef enum {
|
||||
GIT_STATUS_ADDED = 1,
|
||||
GIT_STATUS_DELETED = 2,
|
||||
GIT_STATUS_MODIFIED = 3,
|
||||
} git_status_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int old_attr;
|
||||
unsigned int new_attr;
|
||||
git_oid old_oid;
|
||||
git_oid new_oid;
|
||||
git_status_t status;
|
||||
const char *path;
|
||||
} git_tree_diff_data;
|
||||
|
||||
typedef int (*git_tree_diff_cb)(const git_tree_diff_data *ptr, void *data);
|
||||
|
||||
/**
|
||||
* Diff two trees
|
||||
*
|
||||
* Compare two trees. For each difference in the trees, the callback
|
||||
* will be called with a git_tree_diff_data filled with the relevant
|
||||
* information.
|
||||
*
|
||||
* @param old the "old" tree
|
||||
* @param newer the "newer" tree
|
||||
* @param cb callback
|
||||
* @param data data to give to the callback
|
||||
* @return GIT_SUCCESS or an error code
|
||||
*/
|
||||
int git_tree_diff(git_tree *old, git_tree *newer, git_tree_diff_cb cb, void *data);
|
||||
|
||||
int git_tree_diff_index_recursive(git_tree *tree, git_index *index, git_tree_diff_cb cb, void *data);
|
||||
|
||||
/** @} */
|
||||
|
||||
GIT_END_DECL
|
||||
|
@ -158,13 +158,13 @@ typedef enum {
|
||||
GIT_REF_PACKED = 4,
|
||||
GIT_REF_HAS_PEEL = 8,
|
||||
GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
|
||||
} git_rtype;
|
||||
} git_ref_t;
|
||||
|
||||
/** Basic type of any Git branch. */
|
||||
typedef enum {
|
||||
GIT_BRANCH_LOCAL = 1,
|
||||
GIT_BRANCH_REMOTE = 2,
|
||||
} git_branch_type;
|
||||
} git_branch_t;
|
||||
|
||||
typedef struct git_refspec git_refspec;
|
||||
typedef struct git_remote git_remote;
|
||||
|
@ -7,9 +7,9 @@
|
||||
#ifndef INCLUDE_git_version_h__
|
||||
#define INCLUDE_git_version_h__
|
||||
|
||||
#define LIBGIT2_VERSION "0.16.0"
|
||||
#define LIBGIT2_VERSION "0.17.0"
|
||||
#define LIBGIT2_VER_MAJOR 0
|
||||
#define LIBGIT2_VER_MINOR 16
|
||||
#define LIBGIT2_VER_MINOR 17
|
||||
#define LIBGIT2_VER_REVISION 0
|
||||
|
||||
#endif
|
||||
|
131
src/attr.c
131
src/attr.c
@ -13,11 +13,11 @@ static int collect_attr_files(
|
||||
|
||||
|
||||
int git_attr_get(
|
||||
const char **value,
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *pathname,
|
||||
const char *name,
|
||||
const char **value)
|
||||
const char *name)
|
||||
{
|
||||
int error;
|
||||
git_attr_path path;
|
||||
@ -64,12 +64,12 @@ typedef struct {
|
||||
} attr_get_many_info;
|
||||
|
||||
int git_attr_get_many(
|
||||
const char **values,
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *pathname,
|
||||
size_t num_attr,
|
||||
const char **names,
|
||||
const char **values)
|
||||
const char **names)
|
||||
{
|
||||
int error;
|
||||
git_attr_path path;
|
||||
@ -235,31 +235,91 @@ bool git_attr_cache__is_cached(
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int load_attr_file(const char *filename, const char **data)
|
||||
static int load_attr_file(
|
||||
const char **data,
|
||||
git_attr_file_stat_sig *sig,
|
||||
const char *filename)
|
||||
{
|
||||
int error;
|
||||
git_buf content = GIT_BUF_INIT;
|
||||
struct stat st;
|
||||
|
||||
error = git_futils_readbuffer(&content, filename);
|
||||
*data = error ? NULL : git_buf_detach(&content);
|
||||
if (p_stat(filename, &st) < 0)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if (sig != NULL &&
|
||||
(git_time_t)st.st_mtime == sig->seconds &&
|
||||
(git_off_t)st.st_size == sig->size &&
|
||||
(unsigned int)st.st_ino == sig->ino)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
error = git_futils_readbuffer_updated(&content, filename, NULL, NULL);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (sig != NULL) {
|
||||
sig->seconds = (git_time_t)st.st_mtime;
|
||||
sig->size = (git_off_t)st.st_size;
|
||||
sig->ino = (unsigned int)st.st_ino;
|
||||
}
|
||||
|
||||
*data = git_buf_detach(&content);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_attr_blob_from_index(
|
||||
git_repository *repo, const char *filename, git_blob **blob)
|
||||
const char **content,
|
||||
git_blob **blob,
|
||||
git_repository *repo,
|
||||
const git_oid *old_oid,
|
||||
const char *relfile)
|
||||
{
|
||||
int error;
|
||||
git_index *index;
|
||||
git_index_entry *entry;
|
||||
|
||||
if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
|
||||
(error = git_index_find(index, filename)) < 0)
|
||||
(error = git_index_find(index, relfile)) < 0)
|
||||
return error;
|
||||
|
||||
entry = git_index_get(index, error);
|
||||
|
||||
return git_blob_lookup(blob, repo, &entry->oid);
|
||||
if (old_oid && git_oid_cmp(old_oid, &entry->oid) == 0)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if ((error = git_blob_lookup(blob, repo, &entry->oid)) < 0)
|
||||
return error;
|
||||
|
||||
*content = git_blob_rawcontent(*blob);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_attr_from_cache(
|
||||
git_attr_file **file,
|
||||
git_attr_cache *cache,
|
||||
git_attr_file_source source,
|
||||
const char *relative_path)
|
||||
{
|
||||
git_buf cache_key = GIT_BUF_INIT;
|
||||
khiter_t cache_pos;
|
||||
|
||||
*file = NULL;
|
||||
|
||||
if (!cache || !cache->files)
|
||||
return 0;
|
||||
|
||||
if (git_buf_printf(&cache_key, "%d#%s", (int)source, relative_path) < 0)
|
||||
return -1;
|
||||
|
||||
cache_pos = git_strmap_lookup_index(cache->files, cache_key.ptr);
|
||||
|
||||
git_buf_free(&cache_key);
|
||||
|
||||
if (git_strmap_valid_index(cache->files, cache_pos))
|
||||
*file = git_strmap_value_at(cache->files, cache_pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_attr_cache__internal_file(
|
||||
@ -301,6 +361,7 @@ int git_attr_cache__push_file(
|
||||
git_attr_cache *cache = git_repository_attr_cache(repo);
|
||||
git_attr_file *file = NULL;
|
||||
git_blob *blob = NULL;
|
||||
git_attr_file_stat_sig st;
|
||||
|
||||
assert(filename && stack);
|
||||
|
||||
@ -316,29 +377,22 @@ int git_attr_cache__push_file(
|
||||
relfile += strlen(workdir);
|
||||
|
||||
/* check cache */
|
||||
if (cache && cache->files) {
|
||||
git_buf cache_key = GIT_BUF_INIT;
|
||||
khiter_t cache_pos;
|
||||
|
||||
if (git_buf_printf(&cache_key, "%d#%s", (int)source, relfile) < 0)
|
||||
if (load_attr_from_cache(&file, cache, source, relfile) < 0)
|
||||
return -1;
|
||||
|
||||
cache_pos = git_strmap_lookup_index(cache->files, cache_key.ptr);
|
||||
|
||||
git_buf_free(&cache_key);
|
||||
|
||||
if (git_strmap_valid_index(cache->files, cache_pos)) {
|
||||
file = git_strmap_value_at(cache->files, cache_pos);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
/* if not in cache, load data, parse, and cache */
|
||||
|
||||
if (source == GIT_ATTR_FILE_FROM_FILE)
|
||||
error = load_attr_file(filename, &content);
|
||||
if (source == GIT_ATTR_FILE_FROM_FILE) {
|
||||
if (file)
|
||||
memcpy(&st, &file->cache_data.st, sizeof(st));
|
||||
else
|
||||
error = load_attr_blob_from_index(repo, relfile, &blob);
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
error = load_attr_file(&content, &st, filename);
|
||||
} else {
|
||||
error = load_attr_blob_from_index(&content, &blob,
|
||||
repo, file ? &file->cache_data.oid : NULL, relfile);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
/* not finding a file is not an error for this function */
|
||||
@ -349,11 +403,14 @@ int git_attr_cache__push_file(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (blob)
|
||||
content = git_blob_rawcontent(blob);
|
||||
|
||||
if ((error = git_attr_file__new(&file, source, relfile, &cache->pool)) < 0)
|
||||
/* if we got here, we have to parse and/or reparse the file */
|
||||
if (file)
|
||||
git_attr_file__clear_rules(file);
|
||||
else {
|
||||
error = git_attr_file__new(&file, source, relfile, &cache->pool);
|
||||
if (error < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (parse && (error = parse(repo, content, file)) < 0)
|
||||
goto finish;
|
||||
@ -362,6 +419,12 @@ int git_attr_cache__push_file(
|
||||
if (error > 0)
|
||||
error = 0;
|
||||
|
||||
/* remember "cache buster" file signature */
|
||||
if (blob)
|
||||
git_oid_cpy(&file->cache_data.oid, git_object_id((git_object *)blob));
|
||||
else
|
||||
memcpy(&file->cache_data.st, &st, sizeof(st));
|
||||
|
||||
finish:
|
||||
/* push file onto vector if we found one*/
|
||||
if (!error && file != NULL)
|
||||
@ -518,11 +581,11 @@ int git_attr_cache__init(git_repository *repo)
|
||||
if (git_repository_config__weakptr(&cfg, repo) < 0)
|
||||
return -1;
|
||||
|
||||
ret = git_config_get_string(cfg, GIT_ATTR_CONFIG, &cache->cfg_attr_file);
|
||||
ret = git_config_get_string(&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
|
||||
ret = git_config_get_string(cfg, GIT_IGNORE_CONFIG, &cache->cfg_excl_file);
|
||||
ret = git_config_get_string(&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
|
||||
|
@ -139,18 +139,23 @@ int git_attr_file__new_and_load(
|
||||
return error;
|
||||
}
|
||||
|
||||
void git_attr_file__free(git_attr_file *file)
|
||||
void git_attr_file__clear_rules(git_attr_file *file)
|
||||
{
|
||||
unsigned int i;
|
||||
git_attr_rule *rule;
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
git_vector_foreach(&file->rules, i, rule)
|
||||
git_attr_rule__free(rule);
|
||||
|
||||
git_vector_free(&file->rules);
|
||||
}
|
||||
|
||||
void git_attr_file__free(git_attr_file *file)
|
||||
{
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
git_attr_file__clear_rules(file);
|
||||
|
||||
if (file->pool_is_allocated) {
|
||||
git_pool_clear(file->pool);
|
||||
@ -338,10 +343,13 @@ int git_attr_fnmatch__parse(
|
||||
const char **base)
|
||||
{
|
||||
const char *pattern, *scan;
|
||||
int slash_count;
|
||||
int slash_count, allow_space;
|
||||
|
||||
assert(spec && base && *base);
|
||||
|
||||
spec->flags = (spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE);
|
||||
allow_space = (spec->flags != 0);
|
||||
|
||||
pattern = *base;
|
||||
|
||||
while (git__isspace(*pattern)) pattern++;
|
||||
@ -350,8 +358,6 @@ int git_attr_fnmatch__parse(
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
spec->flags = 0;
|
||||
|
||||
if (*pattern == '[') {
|
||||
if (strncmp(pattern, "[attr]", 6) == 0) {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_MACRO;
|
||||
@ -368,8 +374,10 @@ int git_attr_fnmatch__parse(
|
||||
slash_count = 0;
|
||||
for (scan = pattern; *scan != '\0'; ++scan) {
|
||||
/* scan until (non-escaped) white space */
|
||||
if (git__isspace(*scan) && *(scan - 1) != '\\')
|
||||
if (git__isspace(*scan) && *(scan - 1) != '\\') {
|
||||
if (!allow_space || (*scan != ' ' && *scan != '\t'))
|
||||
break;
|
||||
}
|
||||
|
||||
if (*scan == '/') {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH;
|
||||
@ -378,7 +386,7 @@ int git_attr_fnmatch__parse(
|
||||
pattern++;
|
||||
}
|
||||
/* remember if we see an unescaped wildcard in pattern */
|
||||
else if ((*scan == '*' || *scan == '.' || *scan == '[') &&
|
||||
else if (git__iswildcard(*scan) &&
|
||||
(scan == pattern || (*(scan - 1) != '\\')))
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_HASWILD;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define GIT_ATTR_FNMATCH_MACRO (1U << 3)
|
||||
#define GIT_ATTR_FNMATCH_IGNORE (1U << 4)
|
||||
#define GIT_ATTR_FNMATCH_HASWILD (1U << 5)
|
||||
#define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6)
|
||||
|
||||
typedef struct {
|
||||
char *pattern;
|
||||
@ -47,11 +48,21 @@ typedef struct {
|
||||
const char *value;
|
||||
} git_attr_assignment;
|
||||
|
||||
typedef struct {
|
||||
git_time_t seconds;
|
||||
git_off_t size;
|
||||
unsigned int ino;
|
||||
} git_attr_file_stat_sig;
|
||||
|
||||
typedef struct {
|
||||
char *key; /* cache "source#path" this was loaded from */
|
||||
git_vector rules; /* vector of <rule*> or <fnmatch*> */
|
||||
git_pool *pool;
|
||||
bool pool_is_allocated;
|
||||
union {
|
||||
git_oid oid;
|
||||
git_attr_file_stat_sig st;
|
||||
} cache_data;
|
||||
} git_attr_file;
|
||||
|
||||
typedef struct {
|
||||
@ -78,6 +89,8 @@ extern int git_attr_file__new_and_load(
|
||||
|
||||
extern void git_attr_file__free(git_attr_file *file);
|
||||
|
||||
extern void git_attr_file__clear_rules(git_attr_file *file);
|
||||
|
||||
extern int git_attr_file__parse_buffer(
|
||||
git_repository *repo, const char *buf, git_attr_file *file);
|
||||
|
||||
|
56
src/blob.c
56
src/blob.c
@ -148,30 +148,20 @@ static int write_symlink(
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
|
||||
static int blob_create_internal(git_oid *oid, git_repository *repo, const char *path)
|
||||
{
|
||||
int error;
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
git_off_t size;
|
||||
struct stat st;
|
||||
const char *workdir;
|
||||
git_odb *odb = NULL;
|
||||
git_off_t size;
|
||||
|
||||
workdir = git_repository_workdir(repo);
|
||||
assert(workdir); /* error to call this on bare repo */
|
||||
|
||||
if ((error = git_buf_joinpath(&full_path, workdir, path)) < 0 ||
|
||||
(error = git_path_lstat(full_path.ptr, &st)) < 0 ||
|
||||
(error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
{
|
||||
git_buf_free(&full_path);
|
||||
if ((error = git_path_lstat(path, &st)) < 0 || (error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
size = st.st_size;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
error = write_symlink(oid, odb, full_path.ptr, (size_t)size);
|
||||
error = write_symlink(oid, odb, path, (size_t)size);
|
||||
} else {
|
||||
git_vector write_filters = GIT_VECTOR_INIT;
|
||||
int filter_count;
|
||||
@ -186,10 +176,10 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
||||
} else if (filter_count == 0) {
|
||||
/* No filters need to be applied to the document: we can stream
|
||||
* directly from disk */
|
||||
error = write_file_stream(oid, odb, full_path.ptr, size);
|
||||
error = write_file_stream(oid, odb, path, size);
|
||||
} else {
|
||||
/* We need to apply one or more filters */
|
||||
error = write_file_filtered(oid, odb, full_path.ptr, &write_filters);
|
||||
error = write_file_filtered(oid, odb, path, &write_filters);
|
||||
}
|
||||
|
||||
git_filters_free(&write_filters);
|
||||
@ -209,7 +199,41 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
|
||||
*/
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
|
||||
{
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
const char *workdir;
|
||||
int error;
|
||||
|
||||
workdir = git_repository_workdir(repo);
|
||||
assert(workdir); /* error to call this on bare repo */
|
||||
|
||||
if (git_buf_joinpath(&full_path, workdir, path) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path));
|
||||
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path)
|
||||
{
|
||||
int error;
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_path_prettify(&full_path, path, NULL)) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path));
|
||||
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ cleanup:
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_type branch_type)
|
||||
int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_t branch_type)
|
||||
{
|
||||
git_reference *branch = NULL;
|
||||
git_reference *head = NULL;
|
||||
@ -114,7 +114,7 @@ int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_
|
||||
assert((branch_type == GIT_BRANCH_LOCAL) || (branch_type == GIT_BRANCH_REMOTE));
|
||||
|
||||
if ((error = retrieve_branch_reference(&branch, repo, branch_name, branch_type == GIT_BRANCH_REMOTE)) < 0)
|
||||
goto on_error;
|
||||
return error;
|
||||
|
||||
if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) {
|
||||
giterr_set(GITERR_REFERENCE, "Cannot locate HEAD.");
|
||||
@ -170,7 +170,7 @@ int git_branch_list(git_strarray *branch_names, git_repository *repo, unsigned i
|
||||
filter.branchlist = &branchlist;
|
||||
filter.branch_type = list_flags;
|
||||
|
||||
error = git_reference_foreach(repo, GIT_REF_OID|GIT_REF_PACKED, &branch_list_cb, (void *)&filter);
|
||||
error = git_reference_foreach(repo, GIT_REF_LISTALL, &branch_list_cb, (void *)&filter);
|
||||
if (error < 0) {
|
||||
git_vector_free(&branchlist);
|
||||
return -1;
|
||||
|
70
src/buffer.c
70
src/buffer.c
@ -12,9 +12,9 @@
|
||||
/* Used as default value for git_buf->ptr so that people can always
|
||||
* assume ptr is non-NULL and zero terminated even for new git_bufs.
|
||||
*/
|
||||
char git_buf_initbuf[1];
|
||||
char git_buf__initbuf[1];
|
||||
|
||||
static char git_buf__oom;
|
||||
char git_buf__oom[1];
|
||||
|
||||
#define ENSURE_SIZE(b, d) \
|
||||
if ((d) > buf->asize && git_buf_grow(b, (d)) < 0)\
|
||||
@ -25,7 +25,7 @@ void git_buf_init(git_buf *buf, size_t initial_size)
|
||||
{
|
||||
buf->asize = 0;
|
||||
buf->size = 0;
|
||||
buf->ptr = git_buf_initbuf;
|
||||
buf->ptr = git_buf__initbuf;
|
||||
|
||||
if (initial_size)
|
||||
git_buf_grow(buf, initial_size);
|
||||
@ -35,7 +35,7 @@ int git_buf_grow(git_buf *buf, size_t target_size)
|
||||
{
|
||||
int error = git_buf_try_grow(buf, target_size);
|
||||
if (error != 0)
|
||||
buf->ptr = &git_buf__oom;
|
||||
buf->ptr = git_buf__oom;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ int git_buf_try_grow(git_buf *buf, size_t target_size)
|
||||
char *new_ptr;
|
||||
size_t new_size;
|
||||
|
||||
if (buf->ptr == &git_buf__oom)
|
||||
if (buf->ptr == git_buf__oom)
|
||||
return -1;
|
||||
|
||||
if (target_size <= buf->asize)
|
||||
@ -85,7 +85,7 @@ void git_buf_free(git_buf *buf)
|
||||
{
|
||||
if (!buf) return;
|
||||
|
||||
if (buf->ptr != git_buf_initbuf && buf->ptr != &git_buf__oom)
|
||||
if (buf->ptr != git_buf__initbuf && buf->ptr != git_buf__oom)
|
||||
git__free(buf->ptr);
|
||||
|
||||
git_buf_init(buf, 0);
|
||||
@ -98,11 +98,6 @@ void git_buf_clear(git_buf *buf)
|
||||
buf->ptr[0] = '\0';
|
||||
}
|
||||
|
||||
bool git_buf_oom(const git_buf *buf)
|
||||
{
|
||||
return (buf->ptr == &git_buf__oom);
|
||||
}
|
||||
|
||||
int git_buf_set(git_buf *buf, const char *data, size_t len)
|
||||
{
|
||||
if (len == 0 || data == NULL) {
|
||||
@ -164,7 +159,7 @@ int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
|
||||
|
||||
if (len < 0) {
|
||||
git__free(buf->ptr);
|
||||
buf->ptr = &git_buf__oom;
|
||||
buf->ptr = git_buf__oom;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -244,7 +239,7 @@ char *git_buf_detach(git_buf *buf)
|
||||
{
|
||||
char *data = buf->ptr;
|
||||
|
||||
if (buf->asize == 0 || buf->ptr == &git_buf__oom)
|
||||
if (buf->asize == 0 || buf->ptr == git_buf__oom)
|
||||
return NULL;
|
||||
|
||||
git_buf_init(buf, 0);
|
||||
@ -415,3 +410,52 @@ int git_buf_cmp(const git_buf *a, const git_buf *b)
|
||||
return (result != 0) ? result :
|
||||
(a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
|
||||
}
|
||||
|
||||
int git_buf_common_prefix(git_buf *buf, const git_strarray *strings)
|
||||
{
|
||||
size_t i;
|
||||
const char *str, *pfx;
|
||||
|
||||
git_buf_clear(buf);
|
||||
|
||||
if (!strings || !strings->count)
|
||||
return 0;
|
||||
|
||||
/* initialize common prefix to first string */
|
||||
if (git_buf_sets(buf, strings->strings[0]) < 0)
|
||||
return -1;
|
||||
|
||||
/* go through the rest of the strings, truncating to shared prefix */
|
||||
for (i = 1; i < strings->count; ++i) {
|
||||
|
||||
for (str = strings->strings[i], pfx = buf->ptr;
|
||||
*str && *str == *pfx; str++, pfx++)
|
||||
/* scanning */;
|
||||
|
||||
git_buf_truncate(buf, pfx - buf->ptr);
|
||||
|
||||
if (!buf->size)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool git_buf_is_binary(const git_buf *buf)
|
||||
{
|
||||
size_t i;
|
||||
int printable = 0, nonprintable = 0;
|
||||
|
||||
for (i = 0; i < buf->size; i++) {
|
||||
unsigned char c = buf->ptr[i];
|
||||
if (c > 0x1F && c < 0x7F)
|
||||
printable++;
|
||||
else if (c == '\0')
|
||||
return true;
|
||||
else if (!git__isspace(c))
|
||||
nonprintable++;
|
||||
}
|
||||
|
||||
return ((printable >> 7) < nonprintable);
|
||||
}
|
||||
|
||||
|
16
src/buffer.h
16
src/buffer.h
@ -15,9 +15,10 @@ typedef struct {
|
||||
size_t asize, size;
|
||||
} git_buf;
|
||||
|
||||
extern char git_buf_initbuf[];
|
||||
extern char git_buf__initbuf[];
|
||||
extern char git_buf__oom[];
|
||||
|
||||
#define GIT_BUF_INIT { git_buf_initbuf, 0, 0 }
|
||||
#define GIT_BUF_INIT { git_buf__initbuf, 0, 0 }
|
||||
|
||||
/**
|
||||
* Initialize a git_buf structure.
|
||||
@ -61,7 +62,10 @@ void git_buf_attach(git_buf *buf, char *ptr, size_t asize);
|
||||
*
|
||||
* @return false if no error, true if allocation error
|
||||
*/
|
||||
bool git_buf_oom(const git_buf *buf);
|
||||
GIT_INLINE(bool) git_buf_oom(const git_buf *buf)
|
||||
{
|
||||
return (buf->ptr == git_buf__oom);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions below that return int value error codes will return 0 on
|
||||
@ -122,4 +126,10 @@ void git_buf_rtrim(git_buf *buf);
|
||||
|
||||
int git_buf_cmp(const git_buf *a, const git_buf *b);
|
||||
|
||||
/* Fill buf with the common prefix of a array of strings */
|
||||
int git_buf_common_prefix(git_buf *buf, const git_strarray *strings);
|
||||
|
||||
/* Check if buffer looks like it contains binary data */
|
||||
bool git_buf_is_binary(const git_buf *buf);
|
||||
|
||||
#endif
|
||||
|
@ -18,15 +18,6 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COMMIT_BASIC_PARSE 0x0
|
||||
#define COMMIT_FULL_PARSE 0x1
|
||||
|
||||
#define COMMIT_PRINT(commit) {\
|
||||
char oid[41]; oid[40] = 0;\
|
||||
git_oid_fmt(oid, &commit->object.id);\
|
||||
printf("Oid: %s | In degree: %d | Time: %u\n", oid, commit->in_degree, commit->commit_time);\
|
||||
}
|
||||
|
||||
static void clear_parents(git_commit *commit)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -4,8 +4,8 @@
|
||||
* 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_fnmatch__w32_h__
|
||||
#define INCLUDE_fnmatch__w32_h__
|
||||
#ifndef INCLUDE_fnmatch__compat_h__
|
||||
#define INCLUDE_fnmatch__compat_h__
|
||||
|
||||
#include "common.h"
|
||||
|
72
src/config.c
72
src/config.c
@ -199,30 +199,6 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
|
||||
return file->set(file, name, value);
|
||||
}
|
||||
|
||||
int git_config_parse_bool(int *out, const char *value)
|
||||
{
|
||||
/* A missing value means true */
|
||||
if (value == NULL) {
|
||||
*out = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(value, "true") ||
|
||||
!strcasecmp(value, "yes") ||
|
||||
!strcasecmp(value, "on")) {
|
||||
*out = 1;
|
||||
return 0;
|
||||
}
|
||||
if (!strcasecmp(value, "false") ||
|
||||
!strcasecmp(value, "no") ||
|
||||
!strcasecmp(value, "off")) {
|
||||
*out = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_int64(int64_t *out, const char *value)
|
||||
{
|
||||
const char *num_end;
|
||||
@ -297,7 +273,7 @@ int git_config_lookup_map_value(
|
||||
case GIT_CVAR_TRUE: {
|
||||
int bool_val;
|
||||
|
||||
if (git_config_parse_bool(&bool_val, value) == 0 &&
|
||||
if (git__parse_bool(&bool_val, value) == 0 &&
|
||||
bool_val == (int)m->cvar_type) {
|
||||
*out = m->map_value;
|
||||
return 0;
|
||||
@ -322,12 +298,17 @@ int git_config_lookup_map_value(
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
int git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n, int *out)
|
||||
int git_config_get_mapped(
|
||||
int *out,
|
||||
git_config *cfg,
|
||||
const char *name,
|
||||
git_cvar_map *maps,
|
||||
size_t map_n)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(cfg, name, &value);
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -339,12 +320,12 @@ int git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_config_get_int64(git_config *cfg, const char *name, int64_t *out)
|
||||
int git_config_get_int64(int64_t *out, git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(cfg, name, &value);
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -356,12 +337,12 @@ int git_config_get_int64(git_config *cfg, const char *name, int64_t *out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_get_int32(git_config *cfg, const char *name, int32_t *out)
|
||||
int git_config_get_int32(int32_t *out, git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(cfg, name, &value);
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -373,16 +354,16 @@ int git_config_get_int32(git_config *cfg, const char *name, int32_t *out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_get_bool(git_config *cfg, const char *name, int *out)
|
||||
int git_config_get_bool(int *out, git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(cfg, name, &value);
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (git_config_parse_bool(out, value) == 0)
|
||||
if (git__parse_bool(out, value) == 0)
|
||||
return 0;
|
||||
|
||||
if (parse_int32(out, value) == 0) {
|
||||
@ -394,7 +375,7 @@ int git_config_get_bool(git_config *cfg, const char *name, int *out)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_config_get_string(git_config *cfg, const char *name, const char **out)
|
||||
int git_config_get_string(const char **out, git_config *cfg, const char *name)
|
||||
{
|
||||
file_internal *internal;
|
||||
unsigned int i;
|
||||
@ -462,7 +443,7 @@ int git_config_find_global_r(git_buf *path)
|
||||
return git_futils_find_global_file(path, GIT_CONFIG_FILENAME);
|
||||
}
|
||||
|
||||
int git_config_find_global(char *global_config_path)
|
||||
int git_config_find_global(char *global_config_path, size_t length)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
int ret = git_config_find_global_r(&path);
|
||||
@ -472,14 +453,14 @@ int git_config_find_global(char *global_config_path)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (path.size > GIT_PATH_MAX) {
|
||||
if (path.size >= length) {
|
||||
git_buf_free(&path);
|
||||
giterr_set(GITERR_NOMEMORY,
|
||||
"Path is to long to fit on the given buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_buf_copy_cstr(global_config_path, GIT_PATH_MAX, &path);
|
||||
git_buf_copy_cstr(global_config_path, length, &path);
|
||||
git_buf_free(&path);
|
||||
return 0;
|
||||
}
|
||||
@ -489,7 +470,7 @@ int git_config_find_system_r(git_buf *path)
|
||||
return git_futils_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM);
|
||||
}
|
||||
|
||||
int git_config_find_system(char *system_config_path)
|
||||
int git_config_find_system(char *system_config_path, size_t length)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
int ret = git_config_find_system_r(&path);
|
||||
@ -499,14 +480,14 @@ int git_config_find_system(char *system_config_path)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (path.size > GIT_PATH_MAX) {
|
||||
if (path.size >= length) {
|
||||
git_buf_free(&path);
|
||||
giterr_set(GITERR_NOMEMORY,
|
||||
"Path is to long to fit on the given buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_buf_copy_cstr(system_config_path, GIT_PATH_MAX, &path);
|
||||
git_buf_copy_cstr(system_config_path, length, &path);
|
||||
git_buf_free(&path);
|
||||
return 0;
|
||||
}
|
||||
@ -514,11 +495,14 @@ int git_config_find_system(char *system_config_path)
|
||||
int git_config_open_global(git_config **out)
|
||||
{
|
||||
int error;
|
||||
char global_path[GIT_PATH_MAX];
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_config_find_global(global_path)) < 0)
|
||||
if ((error = git_config_find_global_r(&path)) < 0)
|
||||
return error;
|
||||
|
||||
return git_config_open_ondisk(out, global_path);
|
||||
error = git_config_open_ondisk(out, git_buf_cstr(&path));
|
||||
git_buf_free(&path);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -66,22 +66,22 @@ int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar)
|
||||
int error;
|
||||
|
||||
error = git_repository_config__weakptr(&config, repo);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
error = git_config_get_mapped(
|
||||
config, data->cvar_name, data->maps, data->map_count, out);
|
||||
error = git_config_get_mapped(out,
|
||||
config, data->cvar_name, data->maps, data->map_count);
|
||||
|
||||
if (error == GIT_ENOTFOUND)
|
||||
*out = data->default_value;
|
||||
|
||||
else if (error < GIT_SUCCESS)
|
||||
else if (error < 0)
|
||||
return error;
|
||||
|
||||
repo->cvar_cache[(int)cvar] = *out;
|
||||
}
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_repository__cvar_cache_clear(git_repository *repo)
|
||||
|
@ -443,8 +443,10 @@ static int config_delete(git_config_file *cfg, const char *name)
|
||||
pos = git_strmap_lookup_index(b->values, key);
|
||||
git__free(key);
|
||||
|
||||
if (!git_strmap_valid_index(b->values, pos))
|
||||
if (!git_strmap_valid_index(b->values, pos)) {
|
||||
giterr_set(GITERR_CONFIG, "Could not find key '%s' to delete", name);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
var = git_strmap_value_at(b->values, pos);
|
||||
|
||||
|
10
src/crlf.c
10
src/crlf.c
@ -82,8 +82,8 @@ static int crlf_load_attributes(struct crlf_attrs *ca, git_repository *repo, con
|
||||
const char *attr_vals[NUM_CONV_ATTRS];
|
||||
int error;
|
||||
|
||||
error = git_attr_get_many(
|
||||
repo, 0, path, NUM_CONV_ATTRS, attr_names, attr_vals);
|
||||
error = git_attr_get_many(attr_vals,
|
||||
repo, 0, path, NUM_CONV_ATTRS, attr_names);
|
||||
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
ca->crlf_action = GIT_CRLF_GUESS;
|
||||
@ -91,7 +91,7 @@ static int crlf_load_attributes(struct crlf_attrs *ca, git_repository *repo, con
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error == GIT_SUCCESS) {
|
||||
if (error == 0) {
|
||||
ca->crlf_action = check_crlf(attr_vals[2]); /* text */
|
||||
if (ca->crlf_action == GIT_CRLF_GUESS)
|
||||
ca->crlf_action = check_crlf(attr_vals[0]); /* clrf */
|
||||
@ -100,7 +100,7 @@ static int crlf_load_attributes(struct crlf_attrs *ca, git_repository *repo, con
|
||||
return 0;
|
||||
}
|
||||
|
||||
return error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int drop_crlf(git_buf *dest, const git_buf *source)
|
||||
@ -207,7 +207,7 @@ int git_filter_add__crlf_to_odb(git_vector *filters, git_repository *repo, const
|
||||
int auto_crlf;
|
||||
|
||||
if ((error = git_repository__cvar(
|
||||
&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < GIT_SUCCESS)
|
||||
&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < 0)
|
||||
return error;
|
||||
|
||||
if (auto_crlf == GIT_AUTO_CRLF_FALSE)
|
||||
|
@ -111,7 +111,7 @@ int git__delta_apply(
|
||||
|
||||
if (delta != delta_end || res_sz)
|
||||
goto fail;
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
git__free(out->data);
|
||||
|
@ -20,7 +20,7 @@
|
||||
* @param delta the delta to execute copy/insert instructions from.
|
||||
* @param delta_len total number of bytes in the delta.
|
||||
* @return
|
||||
* - GIT_SUCCESS on a successful delta unpack.
|
||||
* - 0 on a successful delta unpack.
|
||||
* - GIT_ERROR if the delta is corrupt or doesn't match the base.
|
||||
*/
|
||||
extern int git__delta_apply(
|
||||
|
112
src/diff.c
112
src/diff.c
@ -11,6 +11,25 @@
|
||||
#include "config.h"
|
||||
#include "attr_file.h"
|
||||
|
||||
static char *diff_prefix_from_pathspec(const git_strarray *pathspec)
|
||||
{
|
||||
git_buf prefix = GIT_BUF_INIT;
|
||||
const char *scan;
|
||||
|
||||
if (git_buf_common_prefix(&prefix, pathspec) < 0)
|
||||
return NULL;
|
||||
|
||||
/* diff prefix will only be leading non-wildcards */
|
||||
for (scan = prefix.ptr; *scan && !git__iswildcard(*scan); ++scan);
|
||||
git_buf_truncate(&prefix, scan - prefix.ptr);
|
||||
|
||||
if (prefix.size > 0)
|
||||
return git_buf_detach(&prefix);
|
||||
|
||||
git_buf_free(&prefix);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool diff_pathspec_is_interesting(const git_strarray *pathspec)
|
||||
{
|
||||
const char *str;
|
||||
@ -251,8 +270,10 @@ static int diff_delta__cmp(const void *a, const void *b)
|
||||
static int config_bool(git_config *cfg, const char *name, int defvalue)
|
||||
{
|
||||
int val = defvalue;
|
||||
if (git_config_get_bool(cfg, name, &val) < 0)
|
||||
|
||||
if (git_config_get_bool(&val, cfg, name) < 0)
|
||||
giterr_clear();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -321,6 +342,7 @@ static git_diff_list *git_diff_list_alloc(
|
||||
git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
|
||||
if (!match)
|
||||
goto fail;
|
||||
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
||||
ret = git_attr_fnmatch__parse(match, &diff->pool, NULL, &pattern);
|
||||
if (ret == GIT_ENOTFOUND) {
|
||||
git__free(match);
|
||||
@ -532,29 +554,27 @@ static int diff_from_iterators(
|
||||
* matched in old (and/or descend into directories as needed)
|
||||
*/
|
||||
else if (nitem && (!oitem || strcmp(oitem->path, nitem->path) > 0)) {
|
||||
int is_ignored;
|
||||
git_delta_t delta_type = GIT_DELTA_ADDED;
|
||||
git_delta_t delta_type = GIT_DELTA_UNTRACKED;
|
||||
|
||||
/* contained in ignored parent directory, so this can be skipped. */
|
||||
/* check if contained in ignored parent directory */
|
||||
if (git_buf_len(&ignore_prefix) &&
|
||||
git__prefixcmp(nitem->path, git_buf_cstr(&ignore_prefix)) == 0)
|
||||
{
|
||||
if (git_iterator_advance(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
is_ignored = git_iterator_current_is_ignored(new_iter);
|
||||
delta_type = GIT_DELTA_IGNORED;
|
||||
|
||||
if (S_ISDIR(nitem->mode)) {
|
||||
/* recurse into directory if explicitly requested or
|
||||
* if there are tracked items inside the directory
|
||||
/* recurse into directory only if there are tracked items in
|
||||
* it or if the user requested the contents of untracked
|
||||
* directories and it is not under an ignored directory.
|
||||
*/
|
||||
if ((diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) ||
|
||||
(oitem && git__prefixcmp(oitem->path, nitem->path) == 0))
|
||||
if ((oitem && git__prefixcmp(oitem->path, nitem->path) == 0) ||
|
||||
(delta_type == GIT_DELTA_UNTRACKED &&
|
||||
(diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0))
|
||||
{
|
||||
if (is_ignored)
|
||||
/* if this directory is ignored, remember it as the
|
||||
* "ignore_prefix" for processing contained items
|
||||
*/
|
||||
if (delta_type == GIT_DELTA_UNTRACKED &&
|
||||
git_iterator_current_is_ignored(new_iter))
|
||||
git_buf_sets(&ignore_prefix, nitem->path);
|
||||
|
||||
if (git_iterator_advance_into_directory(new_iter, &nitem) < 0)
|
||||
@ -562,12 +582,34 @@ static int diff_from_iterators(
|
||||
|
||||
continue;
|
||||
}
|
||||
delta_type = GIT_DELTA_UNTRACKED;
|
||||
}
|
||||
else if (is_ignored)
|
||||
|
||||
/* In core git, the next two "else if" clauses are effectively
|
||||
* reversed -- i.e. when an untracked file contained in an
|
||||
* ignored directory is individually ignored, it shows up as an
|
||||
* ignored file in the diff list, even though other untracked
|
||||
* files in the same directory are skipped completely.
|
||||
*
|
||||
* To me, this is odd. If the directory is ignored and the file
|
||||
* is untracked, we should skip it consistently, regardless of
|
||||
* whether it happens to match a pattern in the ignore file.
|
||||
*
|
||||
* To match the core git behavior, just reverse the following
|
||||
* two "else if" cases so that individual file ignores are
|
||||
* checked before container directory exclusions are used to
|
||||
* skip the file.
|
||||
*/
|
||||
else if (delta_type == GIT_DELTA_IGNORED) {
|
||||
if (git_iterator_advance(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
continue; /* ignored parent directory, so skip completely */
|
||||
}
|
||||
|
||||
else if (git_iterator_current_is_ignored(new_iter))
|
||||
delta_type = GIT_DELTA_IGNORED;
|
||||
else if (new_iter->type == GIT_ITERATOR_WORKDIR)
|
||||
delta_type = GIT_DELTA_UNTRACKED;
|
||||
|
||||
else if (new_iter->type != GIT_ITERATOR_WORKDIR)
|
||||
delta_type = GIT_DELTA_ADDED;
|
||||
|
||||
if (diff_delta__from_one(diff, delta_type, nitem) < 0 ||
|
||||
git_iterator_advance(new_iter, &nitem) < 0)
|
||||
@ -613,13 +655,16 @@ int git_diff_tree_to_tree(
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && old_tree && new_tree && diff);
|
||||
|
||||
if (git_iterator_for_tree(repo, old_tree, &a) < 0 ||
|
||||
git_iterator_for_tree(repo, new_tree, &b) < 0)
|
||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
||||
git_iterator_for_tree_range(&b, repo, new_tree, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
@ -630,13 +675,16 @@ int git_diff_index_to_tree(
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && diff);
|
||||
|
||||
if (git_iterator_for_tree(repo, old_tree, &a) < 0 ||
|
||||
git_iterator_for_index(repo, &b) < 0)
|
||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
||||
git_iterator_for_index_range(&b, repo, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
@ -646,13 +694,16 @@ int git_diff_workdir_to_index(
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && diff);
|
||||
|
||||
if (git_iterator_for_index(repo, &a) < 0 ||
|
||||
git_iterator_for_workdir(repo, &b) < 0)
|
||||
if (git_iterator_for_index_range(&a, repo, prefix, prefix) < 0 ||
|
||||
git_iterator_for_workdir_range(&b, repo, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
@ -664,13 +715,16 @@ int git_diff_workdir_to_tree(
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && old_tree && diff);
|
||||
|
||||
if (git_iterator_for_tree(repo, old_tree, &a) < 0 ||
|
||||
git_iterator_for_workdir(repo, &b) < 0)
|
||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
||||
git_iterator_for_workdir_range(&b, repo, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ static int diff_output_cb(void *priv, mmbuffer_t *bufs, int len)
|
||||
static int update_file_is_binary_by_attr(git_repository *repo, git_diff_file *file)
|
||||
{
|
||||
const char *value;
|
||||
if (git_attr_get(repo, 0, file->path, "diff", &value) < 0)
|
||||
if (git_attr_get(&value, repo, 0, file->path, "diff") < 0)
|
||||
return -1;
|
||||
|
||||
if (GIT_ATTR_FALSE(value))
|
||||
@ -174,15 +174,12 @@ static int file_is_binary_by_content(
|
||||
git_map *new_data)
|
||||
{
|
||||
git_buf search;
|
||||
git_text_stats stats;
|
||||
|
||||
if ((delta->old_file.flags & BINARY_DIFF_FLAGS) == 0) {
|
||||
search.ptr = old_data->data;
|
||||
search.size = min(old_data->len, 4000);
|
||||
|
||||
git_text_gather_stats(&stats, &search);
|
||||
|
||||
if (git_text_is_binary(&stats))
|
||||
if (git_buf_is_binary(&search))
|
||||
delta->old_file.flags |= GIT_DIFF_FILE_BINARY;
|
||||
else
|
||||
delta->old_file.flags |= GIT_DIFF_FILE_NOT_BINARY;
|
||||
@ -192,9 +189,7 @@ static int file_is_binary_by_content(
|
||||
search.ptr = new_data->data;
|
||||
search.size = min(new_data->len, 4000);
|
||||
|
||||
git_text_gather_stats(&stats, &search);
|
||||
|
||||
if (git_text_is_binary(&stats))
|
||||
if (git_buf_is_binary(&search))
|
||||
delta->new_file.flags |= GIT_DIFF_FILE_BINARY;
|
||||
else
|
||||
delta->new_file.flags |= GIT_DIFF_FILE_NOT_BINARY;
|
||||
@ -392,7 +387,7 @@ int git_diff_foreach(
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((delta->new_file.flags | GIT_DIFF_FILE_VALID_OID) == 0) {
|
||||
if ((delta->new_file.flags & GIT_DIFF_FILE_VALID_OID) == 0) {
|
||||
error = git_odb_hash(
|
||||
&delta->new_file.oid, new_data.data, new_data.len, GIT_OBJ_BLOB);
|
||||
|
||||
|
@ -165,7 +165,7 @@ int git_fetch_setup_walk(git_revwalk **out, git_repository *repo)
|
||||
unsigned int i;
|
||||
git_reference *ref;
|
||||
|
||||
if (git_reference_listall(&refs, repo, GIT_REF_LISTALL) < 0)
|
||||
if (git_reference_list(&refs, repo, GIT_REF_LISTALL) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_revwalk_new(&walk, repo) < 0)
|
||||
|
158
src/fileops.c
158
src/fileops.c
@ -185,9 +185,6 @@ int git_futils_readbuffer_updated(git_buf *buf, const char *path, time_t *mtime,
|
||||
|
||||
p_close(fd);
|
||||
|
||||
if (mtime != NULL)
|
||||
*mtime = st.st_mtime;
|
||||
|
||||
if (updated != NULL)
|
||||
*updated = 1;
|
||||
|
||||
@ -244,28 +241,36 @@ void git_futils_mmap_free(git_map *out)
|
||||
|
||||
int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)
|
||||
{
|
||||
int root_path_offset;
|
||||
git_buf make_path = GIT_BUF_INIT;
|
||||
size_t start;
|
||||
size_t start = 0;
|
||||
char *pp, *sp;
|
||||
bool failed = false;
|
||||
|
||||
if (base != NULL) {
|
||||
/*
|
||||
* when a base is being provided, it is supposed to already exist.
|
||||
* Therefore, no attempt is being made to recursively create this leading path
|
||||
* segment. It's just skipped. */
|
||||
start = strlen(base);
|
||||
if (git_buf_joinpath(&make_path, base, path) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
start = 0;
|
||||
int root_path_offset;
|
||||
|
||||
if (git_buf_puts(&make_path, path) < 0)
|
||||
return -1;
|
||||
|
||||
root_path_offset = git_path_root(make_path.ptr);
|
||||
if (root_path_offset > 0) {
|
||||
/*
|
||||
* On Windows, will skip the drive name (eg. C: or D:)
|
||||
* or the leading part of a network path (eg. //computer_name ) */
|
||||
start = root_path_offset;
|
||||
}
|
||||
}
|
||||
|
||||
pp = make_path.ptr + start;
|
||||
|
||||
root_path_offset = git_path_root(make_path.ptr);
|
||||
if (root_path_offset > 0)
|
||||
pp += root_path_offset; /* On Windows, will skip the drive name (eg. C: or D:) */
|
||||
|
||||
while (!failed && (sp = strchr(pp, '/')) != NULL) {
|
||||
if (sp != pp && git_path_isdir(make_path.ptr) == false) {
|
||||
*sp = 0;
|
||||
@ -309,7 +314,7 @@ static int _rmdir_recurs_foreach(void *opaque, git_buf *path)
|
||||
return -1;
|
||||
|
||||
if (p_rmdir(path->ptr) < 0) {
|
||||
if (removal_type == GIT_DIRREMOVAL_ONLY_EMPTY_DIRS && errno == ENOTEMPTY)
|
||||
if (removal_type == GIT_DIRREMOVAL_ONLY_EMPTY_DIRS && (errno == ENOTEMPTY || errno == EEXIST))
|
||||
return 0;
|
||||
|
||||
giterr_set(GITERR_OS, "Could not remove directory '%s'", path->ptr);
|
||||
@ -348,72 +353,23 @@ int git_futils_rmdir_r(const char *path, git_directory_removal_type removal_type
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_futils_find_global_file(git_buf *path, const char *filename)
|
||||
{
|
||||
const char *home = getenv("HOME");
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
if (home == NULL)
|
||||
home = getenv("USERPROFILE");
|
||||
#endif
|
||||
|
||||
if (home == NULL) {
|
||||
giterr_set(GITERR_OS, "Global file lookup failed. "
|
||||
"Cannot locate the user's home directory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_buf_joinpath(path, home, filename) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_path_exists(path->ptr) == false) {
|
||||
git_buf_clear(path);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
typedef struct {
|
||||
wchar_t *path;
|
||||
struct win32_path {
|
||||
wchar_t path[MAX_PATH];
|
||||
DWORD len;
|
||||
} win32_path;
|
||||
};
|
||||
|
||||
static const win32_path *win32_system_root(void)
|
||||
static int win32_expand_path(struct win32_path *s_root, const wchar_t *templ)
|
||||
{
|
||||
static win32_path s_root = { 0, 0 };
|
||||
|
||||
if (s_root.path == NULL) {
|
||||
const wchar_t *root_tmpl = L"%PROGRAMFILES%\\Git\\etc\\";
|
||||
|
||||
s_root.len = ExpandEnvironmentStringsW(root_tmpl, NULL, 0);
|
||||
if (s_root.len <= 0) {
|
||||
giterr_set(GITERR_OS, "Failed to expand environment strings");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s_root.path = git__calloc(s_root.len, sizeof(wchar_t));
|
||||
if (s_root.path == NULL)
|
||||
return NULL;
|
||||
|
||||
if (ExpandEnvironmentStringsW(root_tmpl, s_root.path, s_root.len) != s_root.len) {
|
||||
giterr_set(GITERR_OS, "Failed to expand environment strings");
|
||||
git__free(s_root.path);
|
||||
s_root.path = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return &s_root;
|
||||
s_root->len = ExpandEnvironmentStringsW(templ, s_root->path, MAX_PATH);
|
||||
return s_root->len ? 0 : -1;
|
||||
}
|
||||
|
||||
static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
static int win32_find_file(git_buf *path, const struct win32_path *root, const char *filename)
|
||||
{
|
||||
int error = 0;
|
||||
const win32_path *root = win32_system_root();
|
||||
size_t len;
|
||||
wchar_t *file_utf16 = NULL, *scan;
|
||||
wchar_t *file_utf16 = NULL;
|
||||
char *file_utf8 = NULL;
|
||||
|
||||
if (!root || !filename || (len = strlen(filename)) == 0)
|
||||
@ -435,10 +391,6 @@ static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (scan = file_utf16; *scan; scan++)
|
||||
if (*scan == L'/')
|
||||
*scan = L'\\';
|
||||
|
||||
/* check access */
|
||||
if (_waccess(file_utf16, F_OK) < 0) {
|
||||
error = GIT_ENOTFOUND;
|
||||
@ -455,13 +407,30 @@ static int win32_find_system_file(git_buf *path, const char *filename)
|
||||
|
||||
cleanup:
|
||||
git__free(file_utf16);
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
int git_futils_find_system_file(git_buf *path, const char *filename)
|
||||
{
|
||||
#ifdef GIT_WIN32
|
||||
struct win32_path root;
|
||||
|
||||
if (win32_expand_path(&root, L"%PROGRAMFILES%\\Git\\etc\\") < 0 ||
|
||||
root.path[0] == L'%') /* i.e. no expansion happened */
|
||||
{
|
||||
giterr_set(GITERR_OS, "Cannot locate the system's Program Files directory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (win32_find_file(path, &root, filename) < 0) {
|
||||
git_buf_clear(path);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#else
|
||||
if (git_buf_joinpath(path, "/etc", filename) < 0)
|
||||
return -1;
|
||||
|
||||
@ -469,10 +438,45 @@ int git_futils_find_system_file(git_buf *path, const char *filename)
|
||||
return 0;
|
||||
|
||||
git_buf_clear(path);
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
return win32_find_system_file(path, filename);
|
||||
#else
|
||||
return GIT_ENOTFOUND;
|
||||
#endif
|
||||
}
|
||||
|
||||
int git_futils_find_global_file(git_buf *path, const char *filename)
|
||||
{
|
||||
#ifdef GIT_WIN32
|
||||
struct win32_path root;
|
||||
|
||||
if (win32_expand_path(&root, L"%USERPROFILE%\\") < 0 ||
|
||||
root.path[0] == L'%') /* i.e. no expansion happened */
|
||||
{
|
||||
giterr_set(GITERR_OS, "Cannot locate the user's profile directory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (win32_find_file(path, &root, filename) < 0) {
|
||||
git_buf_clear(path);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
const char *home = getenv("HOME");
|
||||
|
||||
if (home == NULL) {
|
||||
giterr_set(GITERR_OS, "Global file lookup failed. "
|
||||
"Cannot locate the user's home directory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_buf_joinpath(path, home, filename) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_path_exists(path->ptr) == false) {
|
||||
git_buf_clear(path);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -49,6 +49,9 @@ extern int git_futils_creat_locked_withpath(const char *path, const mode_t dirmo
|
||||
|
||||
/**
|
||||
* Create a path recursively
|
||||
*
|
||||
* If a base parameter is being passed, it's expected to be valued with a path pointing to an already
|
||||
* exisiting directory.
|
||||
*/
|
||||
extern int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode);
|
||||
|
||||
|
@ -129,7 +129,7 @@ int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters)
|
||||
|
||||
if (git_buf_len(source) == 0) {
|
||||
git_buf_clear(dest);
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pre-grow the destination buffer to more or less the size
|
||||
@ -160,6 +160,6 @@ int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters)
|
||||
if (src != 1)
|
||||
git_buf_swap(dest, source);
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ extern int git_filters_load(git_vector *filters, git_repository *repo, const cha
|
||||
* @param dest Buffer to store the result of the filtering
|
||||
* @param source Buffer containing the document to filter
|
||||
* @param filters A non-empty vector of filters as supplied by `git_filters_load`
|
||||
* @return GIT_SUCCESS on success, an error code otherwise
|
||||
* @return 0 on success, an error code otherwise
|
||||
*/
|
||||
extern int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters);
|
||||
|
||||
|
11
src/index.c
11
src/index.c
@ -502,6 +502,15 @@ int git_index_find(git_index *index, const char *path)
|
||||
return git_vector_bsearch2(&index->entries, index_srch, path);
|
||||
}
|
||||
|
||||
unsigned int git_index__prefix_position(git_index *index, const char *path)
|
||||
{
|
||||
unsigned int pos;
|
||||
|
||||
git_vector_bsearch3(&pos, &index->entries, index_srch, path);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void git_index_uniq(git_index *index)
|
||||
{
|
||||
git_vector_uniq(&index->entries);
|
||||
@ -930,7 +939,7 @@ static int read_tree_cb(const char *root, git_tree_entry *tentry, void *data)
|
||||
git_index_entry *entry = NULL;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
if (entry_is_tree(tentry))
|
||||
if (git_tree_entry__is_tree(tentry))
|
||||
return 0;
|
||||
|
||||
if (git_buf_joinpath(&path, root, tentry->filename) < 0)
|
||||
|
@ -33,4 +33,6 @@ struct git_index {
|
||||
|
||||
extern void git_index__init_entry_from_stat(struct stat *st, git_index_entry *entry);
|
||||
|
||||
extern unsigned int git_index__prefix_position(git_index *index, const char *path);
|
||||
|
||||
#endif
|
||||
|
@ -110,12 +110,12 @@ static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack)
|
||||
}
|
||||
|
||||
if (hdr->hdr_signature != ntohl(PACK_SIGNATURE)) {
|
||||
giterr_set(GITERR_INVALID, "Wrong pack signature");
|
||||
giterr_set(GITERR_INDEXER, "Wrong pack signature");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pack_version_ok(hdr->hdr_version)) {
|
||||
giterr_set(GITERR_INVALID, "Wrong pack version");
|
||||
giterr_set(GITERR_INDEXER, "Wrong pack version");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -205,9 +205,9 @@ static int store_delta(git_indexer_stream *idx)
|
||||
}
|
||||
|
||||
error = packfile_unpack_compressed(&obj, idx->pack, &w, &idx->off, entry_size, type);
|
||||
if (error == GIT_ESHORTBUFFER) {
|
||||
if (error == GIT_EBUFS) {
|
||||
idx->off = entry_start;
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
} else if (error < 0){
|
||||
return -1;
|
||||
}
|
||||
@ -248,7 +248,7 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
|
||||
|
||||
/* FIXME: Parse the object instead of hashing it */
|
||||
if (git_odb__hashobj(&oid, obj) < 0) {
|
||||
giterr_set(GITERR_INVALID, "Failed to hash object");
|
||||
giterr_set(GITERR_INDEXER, "Failed to hash object");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
|
||||
return 0;
|
||||
|
||||
error = git_packfile_unpack(&obj, idx->pack, &idx->off);
|
||||
if (error == GIT_ESHORTBUFFER) {
|
||||
if (error == GIT_EBUFS) {
|
||||
idx->off = entry_start;
|
||||
return 0;
|
||||
}
|
||||
@ -363,7 +363,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
|
||||
if (error < 0) {
|
||||
idx->off = entry_start;
|
||||
error = store_delta(idx);
|
||||
if (error == GIT_ESHORTBUFFER)
|
||||
if (error == GIT_EBUFS)
|
||||
return 0;
|
||||
if (error < 0)
|
||||
return error;
|
||||
@ -441,10 +441,21 @@ int git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer_stats *stat
|
||||
git_oid file_hash;
|
||||
SHA_CTX ctx;
|
||||
|
||||
/* Test for this before resolve_deltas(), as it plays with idx->off */
|
||||
if (idx->off < idx->pack->mwf.size - GIT_OID_RAWSZ) {
|
||||
giterr_set(GITERR_INDEXER, "Indexing error: junk at the end of the pack");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (idx->deltas.length > 0)
|
||||
if (resolve_deltas(idx, stats) < 0)
|
||||
return -1;
|
||||
|
||||
if (stats->processed != stats->total) {
|
||||
giterr_set(GITERR_INDEXER, "Indexing error: early EOF");
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_vector_sort(&idx->objects);
|
||||
|
||||
git_buf_sets(&filename, idx->pack->pack_name);
|
||||
@ -583,7 +594,7 @@ int git_indexer_new(git_indexer **out, const char *packname)
|
||||
assert(out && packname);
|
||||
|
||||
if (git_path_root(packname) < 0) {
|
||||
giterr_set(GITERR_INVALID, "Path is not absolute");
|
||||
giterr_set(GITERR_INDEXER, "Path is not absolute");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -815,7 +826,7 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
|
||||
/* FIXME: Parse the object instead of hashing it */
|
||||
error = git_odb__hashobj(&oid, &obj);
|
||||
if (error < 0) {
|
||||
giterr_set(GITERR_INVALID, "Failed to hash object");
|
||||
giterr_set(GITERR_INDEXER, "Failed to hash object");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -828,7 +839,6 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
|
||||
git_oid_cpy(&pentry->sha1, &oid);
|
||||
pentry->offset = entry_start;
|
||||
git_oid_fmt(fmt, &oid);
|
||||
printf("adding %s to cache\n", fmt);
|
||||
error = git_vector_insert(&idx->pack->cache, pentry);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
309
src/iterator.c
309
src/iterator.c
@ -11,6 +11,23 @@
|
||||
#include "buffer.h"
|
||||
#include "git2/submodule.h"
|
||||
|
||||
#define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC) do { \
|
||||
(P) = git__calloc(1, sizeof(NAME_LC ## _iterator)); \
|
||||
GITERR_CHECK_ALLOC(P); \
|
||||
(P)->base.type = GIT_ITERATOR_ ## NAME_UC; \
|
||||
(P)->base.start = start ? git__strdup(start) : NULL; \
|
||||
(P)->base.end = end ? git__strdup(end) : NULL; \
|
||||
(P)->base.current = NAME_LC ## _iterator__current; \
|
||||
(P)->base.at_end = NAME_LC ## _iterator__at_end; \
|
||||
(P)->base.advance = NAME_LC ## _iterator__advance; \
|
||||
(P)->base.seek = NAME_LC ## _iterator__seek; \
|
||||
(P)->base.reset = NAME_LC ## _iterator__reset; \
|
||||
(P)->base.free = NAME_LC ## _iterator__free; \
|
||||
if ((start && !(P)->base.start) || (end && !(P)->base.end)) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
|
||||
static int empty_iterator__no_item(
|
||||
git_iterator *iter, const git_index_entry **entry)
|
||||
{
|
||||
@ -31,6 +48,13 @@ static int empty_iterator__noop(git_iterator *iter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int empty_iterator__seek(git_iterator *iter, const char *prefix)
|
||||
{
|
||||
GIT_UNUSED(iter);
|
||||
GIT_UNUSED(prefix);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void empty_iterator__free(git_iterator *iter)
|
||||
{
|
||||
GIT_UNUSED(iter);
|
||||
@ -45,6 +69,7 @@ int git_iterator_for_nothing(git_iterator **iter)
|
||||
i->current = empty_iterator__no_item;
|
||||
i->at_end = empty_iterator__at_end;
|
||||
i->advance = empty_iterator__no_item;
|
||||
i->seek = empty_iterator__seek;
|
||||
i->reset = empty_iterator__noop;
|
||||
i->free = empty_iterator__free;
|
||||
|
||||
@ -53,10 +78,12 @@ int git_iterator_for_nothing(git_iterator **iter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct tree_iterator_frame tree_iterator_frame;
|
||||
struct tree_iterator_frame {
|
||||
tree_iterator_frame *next;
|
||||
git_tree *tree;
|
||||
char *start;
|
||||
unsigned int index;
|
||||
};
|
||||
|
||||
@ -66,6 +93,7 @@ typedef struct {
|
||||
tree_iterator_frame *stack;
|
||||
git_index_entry entry;
|
||||
git_buf path;
|
||||
bool path_has_filename;
|
||||
} tree_iterator;
|
||||
|
||||
static const git_tree_entry *tree_iterator__tree_entry(tree_iterator *ti)
|
||||
@ -74,12 +102,45 @@ static const git_tree_entry *tree_iterator__tree_entry(tree_iterator *ti)
|
||||
git_tree_entry_byindex(ti->stack->tree, ti->stack->index);
|
||||
}
|
||||
|
||||
static char *tree_iterator__current_filename(
|
||||
tree_iterator *ti, const git_tree_entry *te)
|
||||
{
|
||||
if (!ti->path_has_filename) {
|
||||
if (git_buf_joinpath(&ti->path, ti->path.ptr, te->filename) < 0)
|
||||
return NULL;
|
||||
ti->path_has_filename = true;
|
||||
}
|
||||
|
||||
return ti->path.ptr;
|
||||
}
|
||||
|
||||
static void tree_iterator__pop_frame(tree_iterator *ti)
|
||||
{
|
||||
tree_iterator_frame *tf = ti->stack;
|
||||
ti->stack = tf->next;
|
||||
if (ti->stack != NULL) /* don't free the initial tree */
|
||||
git_tree_free(tf->tree);
|
||||
git__free(tf);
|
||||
}
|
||||
|
||||
static int tree_iterator__to_end(tree_iterator *ti)
|
||||
{
|
||||
while (ti->stack && ti->stack->next)
|
||||
tree_iterator__pop_frame(ti);
|
||||
|
||||
if (ti->stack)
|
||||
ti->stack->index = git_tree_entrycount(ti->stack->tree);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tree_iterator__current(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
{
|
||||
tree_iterator *ti = (tree_iterator *)self;
|
||||
const git_tree_entry *te = tree_iterator__tree_entry(ti);
|
||||
|
||||
if (entry)
|
||||
*entry = NULL;
|
||||
|
||||
if (te == NULL)
|
||||
@ -87,11 +148,15 @@ static int tree_iterator__current(
|
||||
|
||||
ti->entry.mode = te->attr;
|
||||
git_oid_cpy(&ti->entry.oid, &te->oid);
|
||||
if (git_buf_joinpath(&ti->path, ti->path.ptr, te->filename) < 0)
|
||||
|
||||
ti->entry.path = tree_iterator__current_filename(ti, te);
|
||||
if (ti->entry.path == NULL)
|
||||
return -1;
|
||||
|
||||
ti->entry.path = ti->path.ptr;
|
||||
if (ti->base.end && git__prefixcmp(ti->entry.path, ti->base.end) > 0)
|
||||
return tree_iterator__to_end(ti);
|
||||
|
||||
if (entry)
|
||||
*entry = &ti->entry;
|
||||
|
||||
return 0;
|
||||
@ -102,11 +167,20 @@ static int tree_iterator__at_end(git_iterator *self)
|
||||
return (tree_iterator__tree_entry((tree_iterator *)self) == NULL);
|
||||
}
|
||||
|
||||
static tree_iterator_frame *tree_iterator__alloc_frame(git_tree *tree)
|
||||
static tree_iterator_frame *tree_iterator__alloc_frame(
|
||||
git_tree *tree, char *start)
|
||||
{
|
||||
tree_iterator_frame *tf = git__calloc(1, sizeof(tree_iterator_frame));
|
||||
if (tf != NULL)
|
||||
if (!tf)
|
||||
return NULL;
|
||||
|
||||
tf->tree = tree;
|
||||
|
||||
if (start && *start) {
|
||||
tf->start = start;
|
||||
tf->index = git_tree__prefix_position(tree, start);
|
||||
}
|
||||
|
||||
return tf;
|
||||
}
|
||||
|
||||
@ -116,35 +190,43 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
|
||||
git_tree *subtree;
|
||||
const git_tree_entry *te = tree_iterator__tree_entry(ti);
|
||||
tree_iterator_frame *tf;
|
||||
char *relpath;
|
||||
|
||||
while (te != NULL && git_tree_entry__is_tree(te)) {
|
||||
if (git_buf_joinpath(&ti->path, ti->path.ptr, te->filename) < 0)
|
||||
return -1;
|
||||
|
||||
/* check that we have not passed the range end */
|
||||
if (ti->base.end != NULL &&
|
||||
git__prefixcmp(ti->path.ptr, ti->base.end) > 0)
|
||||
return tree_iterator__to_end(ti);
|
||||
|
||||
while (te != NULL && entry_is_tree(te)) {
|
||||
if ((error = git_tree_lookup(&subtree, ti->repo, &te->oid)) < 0)
|
||||
return error;
|
||||
|
||||
if ((tf = tree_iterator__alloc_frame(subtree)) == NULL)
|
||||
relpath = NULL;
|
||||
|
||||
/* apply range start to new frame if relevant */
|
||||
if (ti->stack->start &&
|
||||
git__prefixcmp(ti->stack->start, te->filename) == 0)
|
||||
{
|
||||
size_t namelen = strlen(te->filename);
|
||||
if (ti->stack->start[namelen] == '/')
|
||||
relpath = ti->stack->start + namelen + 1;
|
||||
}
|
||||
|
||||
if ((tf = tree_iterator__alloc_frame(subtree, relpath)) == NULL)
|
||||
return -1;
|
||||
|
||||
tf->next = ti->stack;
|
||||
ti->stack = tf;
|
||||
|
||||
if (git_buf_joinpath(&ti->path, ti->path.ptr, te->filename) < 0)
|
||||
return -1;
|
||||
|
||||
te = tree_iterator__tree_entry(ti);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tree_iterator__pop_frame(tree_iterator *ti)
|
||||
{
|
||||
tree_iterator_frame *tf = ti->stack;
|
||||
ti->stack = tf->next;
|
||||
if (ti->stack != NULL) /* don't free the initial tree */
|
||||
git_tree_free(tf->tree);
|
||||
git__free(tf);
|
||||
}
|
||||
|
||||
static int tree_iterator__advance(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
{
|
||||
@ -155,26 +237,40 @@ static int tree_iterator__advance(
|
||||
if (entry != NULL)
|
||||
*entry = NULL;
|
||||
|
||||
while (ti->stack != NULL) {
|
||||
/* remove old entry filename */
|
||||
if (ti->path_has_filename) {
|
||||
git_buf_rtruncate_at_char(&ti->path, '/');
|
||||
ti->path_has_filename = false;
|
||||
}
|
||||
|
||||
while (ti->stack != NULL) {
|
||||
te = git_tree_entry_byindex(ti->stack->tree, ++ti->stack->index);
|
||||
if (te != NULL)
|
||||
break;
|
||||
|
||||
tree_iterator__pop_frame(ti);
|
||||
|
||||
git_buf_rtruncate_at_char(&ti->path, '/');
|
||||
}
|
||||
|
||||
if (te && entry_is_tree(te))
|
||||
if (te && git_tree_entry__is_tree(te))
|
||||
error = tree_iterator__expand_tree(ti);
|
||||
|
||||
if (!error && entry != NULL)
|
||||
if (!error)
|
||||
error = tree_iterator__current(self, entry);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int tree_iterator__seek(git_iterator *self, const char *prefix)
|
||||
{
|
||||
GIT_UNUSED(self);
|
||||
GIT_UNUSED(prefix);
|
||||
/* pop stack until matches prefix */
|
||||
/* seek item in current frame matching prefix */
|
||||
/* push stack which matches prefix */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void tree_iterator__free(git_iterator *self)
|
||||
{
|
||||
tree_iterator *ti = (tree_iterator *)self;
|
||||
@ -186,15 +282,25 @@ static void tree_iterator__free(git_iterator *self)
|
||||
static int tree_iterator__reset(git_iterator *self)
|
||||
{
|
||||
tree_iterator *ti = (tree_iterator *)self;
|
||||
|
||||
while (ti->stack && ti->stack->next)
|
||||
tree_iterator__pop_frame(ti);
|
||||
|
||||
if (ti->stack)
|
||||
ti->stack->index = 0;
|
||||
ti->stack->index =
|
||||
git_tree__prefix_position(ti->stack->tree, ti->base.start);
|
||||
|
||||
git_buf_clear(&ti->path);
|
||||
|
||||
return tree_iterator__expand_tree(ti);
|
||||
}
|
||||
|
||||
int git_iterator_for_tree(
|
||||
git_repository *repo, git_tree *tree, git_iterator **iter)
|
||||
int git_iterator_for_tree_range(
|
||||
git_iterator **iter,
|
||||
git_repository *repo,
|
||||
git_tree *tree,
|
||||
const char *start,
|
||||
const char *end)
|
||||
{
|
||||
int error;
|
||||
tree_iterator *ti;
|
||||
@ -202,22 +308,16 @@ int git_iterator_for_tree(
|
||||
if (tree == NULL)
|
||||
return git_iterator_for_nothing(iter);
|
||||
|
||||
ti = git__calloc(1, sizeof(tree_iterator));
|
||||
GITERR_CHECK_ALLOC(ti);
|
||||
ITERATOR_BASE_INIT(ti, tree, TREE);
|
||||
|
||||
ti->base.type = GIT_ITERATOR_TREE;
|
||||
ti->base.current = tree_iterator__current;
|
||||
ti->base.at_end = tree_iterator__at_end;
|
||||
ti->base.advance = tree_iterator__advance;
|
||||
ti->base.reset = tree_iterator__reset;
|
||||
ti->base.free = tree_iterator__free;
|
||||
ti->repo = repo;
|
||||
ti->stack = tree_iterator__alloc_frame(tree);
|
||||
ti->stack = tree_iterator__alloc_frame(tree, ti->base.start);
|
||||
|
||||
if ((error = tree_iterator__expand_tree(ti)) < 0)
|
||||
git_iterator_free((git_iterator *)ti);
|
||||
else
|
||||
*iter = (git_iterator *)ti;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -232,7 +332,19 @@ static int index_iterator__current(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
{
|
||||
index_iterator *ii = (index_iterator *)self;
|
||||
*entry = git_index_get(ii->index, ii->current);
|
||||
git_index_entry *ie = git_index_get(ii->index, ii->current);
|
||||
|
||||
if (ie != NULL &&
|
||||
ii->base.end != NULL &&
|
||||
git__prefixcmp(ie->path, ii->base.end) > 0)
|
||||
{
|
||||
ii->current = git_index_entrycount(ii->index);
|
||||
ie = NULL;
|
||||
}
|
||||
|
||||
if (entry)
|
||||
*entry = ie;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -246,11 +358,19 @@ static int index_iterator__advance(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
{
|
||||
index_iterator *ii = (index_iterator *)self;
|
||||
|
||||
if (ii->current < git_index_entrycount(ii->index))
|
||||
ii->current++;
|
||||
if (entry)
|
||||
*entry = git_index_get(ii->index, ii->current);
|
||||
return 0;
|
||||
|
||||
return index_iterator__current(self, entry);
|
||||
}
|
||||
|
||||
static int index_iterator__seek(git_iterator *self, const char *prefix)
|
||||
{
|
||||
GIT_UNUSED(self);
|
||||
GIT_UNUSED(prefix);
|
||||
/* find last item before prefix */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int index_iterator__reset(git_iterator *self)
|
||||
@ -267,24 +387,24 @@ static void index_iterator__free(git_iterator *self)
|
||||
ii->index = NULL;
|
||||
}
|
||||
|
||||
int git_iterator_for_index(git_repository *repo, git_iterator **iter)
|
||||
int git_iterator_for_index_range(
|
||||
git_iterator **iter,
|
||||
git_repository *repo,
|
||||
const char *start,
|
||||
const char *end)
|
||||
{
|
||||
int error;
|
||||
index_iterator *ii = git__calloc(1, sizeof(index_iterator));
|
||||
GITERR_CHECK_ALLOC(ii);
|
||||
index_iterator *ii;
|
||||
|
||||
ii->base.type = GIT_ITERATOR_INDEX;
|
||||
ii->base.current = index_iterator__current;
|
||||
ii->base.at_end = index_iterator__at_end;
|
||||
ii->base.advance = index_iterator__advance;
|
||||
ii->base.reset = index_iterator__reset;
|
||||
ii->base.free = index_iterator__free;
|
||||
ii->current = 0;
|
||||
ITERATOR_BASE_INIT(ii, index, INDEX);
|
||||
|
||||
if ((error = git_repository_index(&ii->index, repo)) < 0)
|
||||
git__free(ii);
|
||||
else
|
||||
else {
|
||||
ii->current = start ? git_index__prefix_position(ii->index, start) : 0;
|
||||
*iter = (git_iterator *)ii;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -294,6 +414,7 @@ struct workdir_iterator_frame {
|
||||
workdir_iterator_frame *next;
|
||||
git_vector entries;
|
||||
unsigned int index;
|
||||
char *start;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -332,6 +453,12 @@ static void workdir_iterator__free_frame(workdir_iterator_frame *wf)
|
||||
|
||||
static int workdir_iterator__update_entry(workdir_iterator *wi);
|
||||
|
||||
static int workdir_iterator__entry_cmp(const void *prefix, const void *item)
|
||||
{
|
||||
const git_path_with_stat *ps = item;
|
||||
return git__prefixcmp((const char *)prefix, ps->path);
|
||||
}
|
||||
|
||||
static int workdir_iterator__expand_dir(workdir_iterator *wi)
|
||||
{
|
||||
int error;
|
||||
@ -345,6 +472,17 @@ static int workdir_iterator__expand_dir(workdir_iterator *wi)
|
||||
}
|
||||
|
||||
git_vector_sort(&wf->entries);
|
||||
|
||||
if (!wi->stack)
|
||||
wf->start = wi->base.start;
|
||||
else if (wi->stack->start &&
|
||||
git__prefixcmp(wi->stack->start, wi->path.ptr + wi->root_len) == 0)
|
||||
wf->start = wi->stack->start;
|
||||
|
||||
if (wf->start)
|
||||
git_vector_bsearch3(
|
||||
&wf->index, &wf->entries, workdir_iterator__entry_cmp, wf->start);
|
||||
|
||||
wf->next = wi->stack;
|
||||
wi->stack = wf;
|
||||
|
||||
@ -412,6 +550,16 @@ static int workdir_iterator__advance(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int workdir_iterator__seek(git_iterator *self, const char *prefix)
|
||||
{
|
||||
GIT_UNUSED(self);
|
||||
GIT_UNUSED(prefix);
|
||||
/* pop stack until matching prefix */
|
||||
/* find prefix item in current frame */
|
||||
/* push subdirectories as deep as possible while matching */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int workdir_iterator__reset(git_iterator *self)
|
||||
{
|
||||
workdir_iterator *wi = (workdir_iterator *)self;
|
||||
@ -445,10 +593,18 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
|
||||
git_path_with_stat *ps = git_vector_get(&wi->stack->entries, wi->stack->index);
|
||||
|
||||
git_buf_truncate(&wi->path, wi->root_len);
|
||||
memset(&wi->entry, 0, sizeof(wi->entry));
|
||||
|
||||
if (!ps)
|
||||
return 0;
|
||||
|
||||
if (git_buf_put(&wi->path, ps->path, ps->path_len) < 0)
|
||||
return -1;
|
||||
|
||||
memset(&wi->entry, 0, sizeof(wi->entry));
|
||||
if (wi->base.end &&
|
||||
git__prefixcmp(wi->path.ptr + wi->root_len, wi->base.end) > 0)
|
||||
return 0;
|
||||
|
||||
wi->entry.path = ps->path;
|
||||
|
||||
/* skip over .git directory */
|
||||
@ -495,18 +651,25 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_iterator_for_workdir(git_repository *repo, git_iterator **iter)
|
||||
int git_iterator_for_workdir_range(
|
||||
git_iterator **iter,
|
||||
git_repository *repo,
|
||||
const char *start,
|
||||
const char *end)
|
||||
{
|
||||
int error;
|
||||
workdir_iterator *wi = git__calloc(1, sizeof(workdir_iterator));
|
||||
GITERR_CHECK_ALLOC(wi);
|
||||
workdir_iterator *wi;
|
||||
|
||||
assert(iter && repo);
|
||||
|
||||
if (git_repository_is_bare(repo)) {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Cannot scan working directory for bare repo");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ITERATOR_BASE_INIT(wi, workdir, WORKDIR);
|
||||
|
||||
wi->base.type = GIT_ITERATOR_WORKDIR;
|
||||
wi->base.current = workdir_iterator__current;
|
||||
wi->base.at_end = workdir_iterator__at_end;
|
||||
wi->base.advance = workdir_iterator__advance;
|
||||
wi->base.reset = workdir_iterator__reset;
|
||||
wi->base.free = workdir_iterator__free;
|
||||
wi->repo = repo;
|
||||
|
||||
if (git_buf_sets(&wi->path, git_repository_workdir(repo)) < 0 ||
|
||||
@ -519,9 +682,15 @@ int git_iterator_for_workdir(git_repository *repo, git_iterator **iter)
|
||||
|
||||
wi->root_len = wi->path.size;
|
||||
|
||||
if ((error = workdir_iterator__expand_dir(wi)) < 0)
|
||||
if ((error = workdir_iterator__expand_dir(wi)) < 0) {
|
||||
if (error == GIT_ENOTFOUND)
|
||||
error = 0;
|
||||
else {
|
||||
git_iterator_free((git_iterator *)wi);
|
||||
else
|
||||
wi = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*iter = (git_iterator *)wi;
|
||||
|
||||
return error;
|
||||
@ -559,3 +728,21 @@ int git_iterator_advance_into_directory(
|
||||
|
||||
return entry ? git_iterator_current(iter, entry) : 0;
|
||||
}
|
||||
|
||||
int git_iterator_cmp(
|
||||
git_iterator *iter, const char *path_prefix)
|
||||
{
|
||||
const git_index_entry *entry;
|
||||
|
||||
/* a "done" iterator is after every prefix */
|
||||
if (git_iterator_current(iter, &entry) < 0 ||
|
||||
entry == NULL)
|
||||
return 1;
|
||||
|
||||
/* a NULL prefix is after any valid iterator */
|
||||
if (!path_prefix)
|
||||
return -1;
|
||||
|
||||
return git__prefixcmp(entry->path, path_prefix);
|
||||
}
|
||||
|
||||
|
@ -21,23 +21,48 @@ typedef enum {
|
||||
|
||||
struct git_iterator {
|
||||
git_iterator_type_t type;
|
||||
char *start;
|
||||
char *end;
|
||||
int (*current)(git_iterator *, const git_index_entry **);
|
||||
int (*at_end)(git_iterator *);
|
||||
int (*advance)(git_iterator *, const git_index_entry **);
|
||||
int (*seek)(git_iterator *, const char *prefix);
|
||||
int (*reset)(git_iterator *);
|
||||
void (*free)(git_iterator *);
|
||||
};
|
||||
|
||||
int git_iterator_for_nothing(git_iterator **iter);
|
||||
extern int git_iterator_for_nothing(git_iterator **iter);
|
||||
|
||||
int git_iterator_for_tree(
|
||||
git_repository *repo, git_tree *tree, git_iterator **iter);
|
||||
extern int git_iterator_for_tree_range(
|
||||
git_iterator **iter, git_repository *repo, git_tree *tree,
|
||||
const char *start, const char *end);
|
||||
|
||||
int git_iterator_for_index(
|
||||
git_repository *repo, git_iterator **iter);
|
||||
GIT_INLINE(int) git_iterator_for_tree(
|
||||
git_iterator **iter, git_repository *repo, git_tree *tree)
|
||||
{
|
||||
return git_iterator_for_tree_range(iter, repo, tree, NULL, NULL);
|
||||
}
|
||||
|
||||
extern int git_iterator_for_index_range(
|
||||
git_iterator **iter, git_repository *repo,
|
||||
const char *start, const char *end);
|
||||
|
||||
GIT_INLINE(int) git_iterator_for_index(
|
||||
git_iterator **iter, git_repository *repo)
|
||||
{
|
||||
return git_iterator_for_index_range(iter, repo, NULL, NULL);
|
||||
}
|
||||
|
||||
extern int git_iterator_for_workdir_range(
|
||||
git_iterator **iter, git_repository *repo,
|
||||
const char *start, const char *end);
|
||||
|
||||
GIT_INLINE(int) git_iterator_for_workdir(
|
||||
git_iterator **iter, git_repository *repo)
|
||||
{
|
||||
return git_iterator_for_workdir_range(iter, repo, NULL, NULL);
|
||||
}
|
||||
|
||||
int git_iterator_for_workdir(
|
||||
git_repository *repo, git_iterator **iter);
|
||||
|
||||
/* Entry is not guaranteed to be fully populated. For a tree iterator,
|
||||
* we will only populate the mode, oid and path, for example. For a workdir
|
||||
@ -64,6 +89,12 @@ GIT_INLINE(int) git_iterator_advance(
|
||||
return iter->advance(iter, entry);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_iterator_seek(
|
||||
git_iterator *iter, const char *prefix)
|
||||
{
|
||||
return iter->seek(iter, prefix);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_iterator_reset(git_iterator *iter)
|
||||
{
|
||||
return iter->reset(iter);
|
||||
@ -71,7 +102,16 @@ GIT_INLINE(int) git_iterator_reset(git_iterator *iter)
|
||||
|
||||
GIT_INLINE(void) git_iterator_free(git_iterator *iter)
|
||||
{
|
||||
if (iter == NULL)
|
||||
return;
|
||||
|
||||
iter->free(iter);
|
||||
|
||||
git__free(iter->start);
|
||||
git__free(iter->end);
|
||||
|
||||
memset(iter, 0, sizeof(*iter));
|
||||
|
||||
git__free(iter);
|
||||
}
|
||||
|
||||
@ -105,4 +145,7 @@ extern int git_iterator_current_is_ignored(git_iterator *iter);
|
||||
extern int git_iterator_advance_into_directory(
|
||||
git_iterator *iter, const git_index_entry **entry);
|
||||
|
||||
extern int git_iterator_cmp(
|
||||
git_iterator *iter, const char *path_prefix);
|
||||
|
||||
#endif
|
||||
|
@ -89,7 +89,6 @@ void git_mwindow_scan_lru(
|
||||
{
|
||||
git_mwindow *w, *w_l;
|
||||
|
||||
puts("LRU");
|
||||
for (w_l = NULL, w = mwf->windows; w; w = w->next) {
|
||||
if (!w->inuse_cnt) {
|
||||
/*
|
||||
@ -247,7 +246,6 @@ unsigned char *git_mwindow_open(
|
||||
if (left)
|
||||
*left = (unsigned int)(w->window_map.len - offset);
|
||||
|
||||
fflush(stdout);
|
||||
return (unsigned char *) w->window_map.data + offset;
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,9 @@
|
||||
# include <netdb.h>
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# include <Ws2tcpip.h>
|
||||
# include <ws2tcpip.h>
|
||||
# ifdef _MSC_VER
|
||||
# pragma comment(lib, "Ws2_32.lib")
|
||||
# pragma comment(lib, "ws2_32.lib")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
159
src/notes.c
159
src/notes.c
@ -10,6 +10,7 @@
|
||||
#include "git2.h"
|
||||
#include "refs.h"
|
||||
#include "config.h"
|
||||
#include "iterator.h"
|
||||
|
||||
static int find_subtree(git_tree **subtree, const git_oid *root,
|
||||
git_repository *repo, const char *target, int *fanout)
|
||||
@ -273,7 +274,7 @@ static int note_get_default_ref(const char **out, git_repository *repo)
|
||||
if (git_repository_config__weakptr(&cfg, repo) < 0)
|
||||
return -1;
|
||||
|
||||
ret = git_config_get_string(cfg, "core.notesRef", out);
|
||||
ret = git_config_get_string(out, cfg, "core.notesRef");
|
||||
if (ret == GIT_ENOTFOUND) {
|
||||
*out = GIT_NOTES_DEFAULT_REF;
|
||||
return 0;
|
||||
@ -282,41 +283,54 @@ static int note_get_default_ref(const char **out, git_repository *repo)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int normalize_namespace(const char **notes_ref, git_repository *repo)
|
||||
{
|
||||
if (*notes_ref)
|
||||
return 0;
|
||||
|
||||
return note_get_default_ref(notes_ref, repo);
|
||||
}
|
||||
|
||||
static int retrieve_note_tree_oid(git_oid *tree_oid_out, git_repository *repo, const char *notes_ref)
|
||||
{
|
||||
int error = -1;
|
||||
git_commit *commit = NULL;
|
||||
git_oid oid;
|
||||
|
||||
if ((error = git_reference_name_to_oid(&oid, repo, notes_ref)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_commit_lookup(&commit, repo, &oid) < 0)
|
||||
goto cleanup;
|
||||
|
||||
git_oid_cpy(tree_oid_out, git_commit_tree_oid(commit));
|
||||
|
||||
error = 0;
|
||||
|
||||
cleanup:
|
||||
git_commit_free(commit);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_note_read(git_note **out, git_repository *repo,
|
||||
const char *notes_ref, const git_oid *oid)
|
||||
{
|
||||
int error;
|
||||
char *target;
|
||||
git_reference *ref;
|
||||
git_commit *commit;
|
||||
const git_oid *sha;
|
||||
git_oid sha;
|
||||
|
||||
*out = NULL;
|
||||
|
||||
if (!notes_ref && note_get_default_ref(¬es_ref, repo) < 0)
|
||||
if (normalize_namespace(¬es_ref, repo) < 0)
|
||||
return -1;
|
||||
|
||||
error = git_reference_lookup(&ref, repo, notes_ref);
|
||||
if (error < 0)
|
||||
if ((error = retrieve_note_tree_oid(&sha, repo, notes_ref)) < 0)
|
||||
return error;
|
||||
|
||||
assert(git_reference_type(ref) == GIT_REF_OID);
|
||||
|
||||
sha = git_reference_oid(ref);
|
||||
error = git_commit_lookup(&commit, repo, sha);
|
||||
|
||||
git_reference_free(ref);
|
||||
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
sha = git_commit_tree_oid(commit);
|
||||
git_commit_free(commit);
|
||||
|
||||
target = git_oid_allocfmt(oid);
|
||||
GITERR_CHECK_ALLOC(target);
|
||||
|
||||
error = note_lookup(out, repo, sha, target);
|
||||
error = note_lookup(out, repo, &sha, target);
|
||||
|
||||
git__free(target);
|
||||
return error;
|
||||
@ -334,7 +348,7 @@ int git_note_create(
|
||||
git_commit *commit = NULL;
|
||||
git_reference *ref;
|
||||
|
||||
if (!notes_ref && note_get_default_ref(¬es_ref, repo) < 0)
|
||||
if (normalize_namespace(¬es_ref, repo) < 0)
|
||||
return -1;
|
||||
|
||||
error = git_reference_lookup(&ref, repo, notes_ref);
|
||||
@ -379,8 +393,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref,
|
||||
git_commit *commit;
|
||||
git_reference *ref;
|
||||
|
||||
|
||||
if (!notes_ref && note_get_default_ref(¬es_ref, repo) < 0)
|
||||
if (normalize_namespace(¬es_ref, repo) < 0)
|
||||
return -1;
|
||||
|
||||
error = git_reference_lookup(&ref, repo, notes_ref);
|
||||
@ -435,3 +448,101 @@ void git_note_free(git_note *note)
|
||||
git__free(note->message);
|
||||
git__free(note);
|
||||
}
|
||||
|
||||
static int process_entry_path(
|
||||
const char* entry_path,
|
||||
const git_oid *note_oid,
|
||||
int (*note_cb)(git_note_data *note_data, void *payload),
|
||||
void *payload)
|
||||
{
|
||||
int i = 0, j = 0, error = -1, len;
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
git_note_data note_data;
|
||||
|
||||
if (git_buf_puts(&buf, entry_path) < 0)
|
||||
goto cleanup;
|
||||
|
||||
len = git_buf_len(&buf);
|
||||
|
||||
while (i < len) {
|
||||
if (buf.ptr[i] == '/') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (git__fromhex(buf.ptr[i]) < 0) {
|
||||
/* This is not a note entry */
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (i != j)
|
||||
buf.ptr[j] = buf.ptr[i];
|
||||
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
buf.ptr[j] = '\0';
|
||||
buf.size = j;
|
||||
|
||||
if (j != GIT_OID_HEXSZ) {
|
||||
/* This is not a note entry */
|
||||
error = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (git_oid_fromstr(¬e_data.annotated_object_oid, buf.ptr) < 0)
|
||||
return -1;
|
||||
|
||||
git_oid_cpy(¬e_data.blob_oid, note_oid);
|
||||
|
||||
error = note_cb(¬e_data, payload);
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&buf);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_note_foreach(
|
||||
git_repository *repo,
|
||||
const char *notes_ref,
|
||||
int (*note_cb)(git_note_data *note_data, void *payload),
|
||||
void *payload)
|
||||
{
|
||||
int error = -1;
|
||||
git_oid tree_oid;
|
||||
git_iterator *iter = NULL;
|
||||
git_tree *tree = NULL;
|
||||
const git_index_entry *item;
|
||||
|
||||
if (normalize_namespace(¬es_ref, repo) < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = retrieve_note_tree_oid(&tree_oid, repo, notes_ref)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_tree_lookup(&tree, repo, &tree_oid) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_iterator_for_tree(&iter, repo, tree) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_iterator_current(iter, &item) < 0)
|
||||
goto cleanup;
|
||||
|
||||
while (item) {
|
||||
if (process_entry_path(item->path, &item->oid, note_cb, payload) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_iterator_advance(iter, &item) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
cleanup:
|
||||
git_iterator_free(iter);
|
||||
git_tree_free(tree);
|
||||
return error;
|
||||
}
|
||||
|
10
src/object.c
10
src/object.c
@ -74,7 +74,7 @@ static int create_object(git_object **object_out, git_otype type)
|
||||
object->type = type;
|
||||
|
||||
*object_out = object;
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_object_lookup_prefix(
|
||||
@ -87,7 +87,7 @@ int git_object_lookup_prefix(
|
||||
git_object *object = NULL;
|
||||
git_odb *odb = NULL;
|
||||
git_odb_object *odb_obj;
|
||||
int error = GIT_SUCCESS;
|
||||
int error = 0;
|
||||
|
||||
assert(repo && object_out && id);
|
||||
|
||||
@ -95,7 +95,7 @@ int git_object_lookup_prefix(
|
||||
return GIT_EAMBIGUOUS;
|
||||
|
||||
error = git_repository_odb__weakptr(&odb, repo);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (len > GIT_OID_HEXSZ)
|
||||
@ -109,8 +109,8 @@ int git_object_lookup_prefix(
|
||||
if (object != NULL) {
|
||||
if (type != GIT_OBJ_ANY && type != object->type) {
|
||||
git_object_free(object);
|
||||
giterr_set(GITERR_INVALID, "The given type does not match the type in ODB");
|
||||
return -1;
|
||||
giterr_set(GITERR_ODB, "The given type does not match the type in ODB");
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
*object_out = object;
|
||||
|
39
src/odb.c
39
src/odb.c
@ -505,7 +505,7 @@ int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git
|
||||
error = b->read_header(len_p, type_p, b, id);
|
||||
}
|
||||
|
||||
if (!error || error == GIT_EPASSTHROUGH)
|
||||
if (!error || error == GIT_PASSTHROUGH)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -545,7 +545,7 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
|
||||
* will never have called giterr_set().
|
||||
*/
|
||||
|
||||
if (error && error != GIT_EPASSTHROUGH)
|
||||
if (error && error != GIT_PASSTHROUGH)
|
||||
return error;
|
||||
|
||||
*out = git_cache_try_store(&db->cache, new_odb_object(id, &raw));
|
||||
@ -557,9 +557,9 @@ int git_odb_read_prefix(
|
||||
{
|
||||
unsigned int i;
|
||||
int error = GIT_ENOTFOUND;
|
||||
git_oid full_oid;
|
||||
git_oid found_full_oid = {{0}};
|
||||
git_rawobj raw;
|
||||
int found = 0;
|
||||
bool found = false;
|
||||
|
||||
assert(out && db);
|
||||
|
||||
@ -575,25 +575,30 @@ int git_odb_read_prefix(
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < db->backends.length && found < 2; ++i) {
|
||||
for (i = 0; i < db->backends.length; ++i) {
|
||||
backend_internal *internal = git_vector_get(&db->backends, i);
|
||||
git_odb_backend *b = internal->backend;
|
||||
|
||||
if (b->read != NULL) {
|
||||
git_oid full_oid;
|
||||
error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
|
||||
if (!error)
|
||||
found++;
|
||||
else if (error != GIT_ENOTFOUND && error != GIT_EPASSTHROUGH)
|
||||
if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
|
||||
continue;
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
return git_odb__error_notfound("no match for prefix", short_id);
|
||||
if (found > 1)
|
||||
if (found && git_oid_cmp(&full_oid, &found_full_oid))
|
||||
return git_odb__error_ambiguous("multiple matches for prefix");
|
||||
found_full_oid = full_oid;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
*out = git_cache_try_store(&db->cache, new_odb_object(&full_oid, &raw));
|
||||
if (!found)
|
||||
return git_odb__error_notfound("no match for prefix", short_id);
|
||||
|
||||
*out = git_cache_try_store(&db->cache, new_odb_object(&found_full_oid, &raw));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -618,7 +623,7 @@ int git_odb_write(
|
||||
error = b->write(oid, b, data, len, type);
|
||||
}
|
||||
|
||||
if (!error || error == GIT_EPASSTHROUGH)
|
||||
if (!error || error == GIT_PASSTHROUGH)
|
||||
return 0;
|
||||
|
||||
/* if no backends were able to write the object directly, we try a streaming
|
||||
@ -657,7 +662,7 @@ int git_odb_open_wstream(
|
||||
error = init_fake_wstream(stream, b, size, type);
|
||||
}
|
||||
|
||||
if (error == GIT_EPASSTHROUGH)
|
||||
if (error == GIT_PASSTHROUGH)
|
||||
error = 0;
|
||||
|
||||
return error;
|
||||
@ -678,7 +683,7 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
|
||||
error = b->readstream(stream, b, oid);
|
||||
}
|
||||
|
||||
if (error == GIT_EPASSTHROUGH)
|
||||
if (error == GIT_PASSTHROUGH)
|
||||
error = 0;
|
||||
|
||||
return error;
|
||||
|
12
src/pack.c
12
src/pack.c
@ -222,7 +222,7 @@ static int packfile_unpack_header1(
|
||||
shift = 4;
|
||||
while (c & 0x80) {
|
||||
if (len <= used)
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
|
||||
if (bitsizeof(long) <= shift) {
|
||||
*usedp = 0;
|
||||
@ -260,11 +260,11 @@ int git_packfile_unpack_header(
|
||||
// base = pack_window_open(p, w_curs, *curpos, &left);
|
||||
base = git_mwindow_open(mwf, w_curs, *curpos, 20, &left);
|
||||
if (base == NULL)
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
|
||||
ret = packfile_unpack_header1(&used, size_p, type_p, base, left);
|
||||
git_mwindow_close(w_curs);
|
||||
if (ret == GIT_ESHORTBUFFER)
|
||||
if (ret == GIT_EBUFS)
|
||||
return ret;
|
||||
else if (ret < 0)
|
||||
return packfile_error("header length is zero");
|
||||
@ -428,7 +428,7 @@ int packfile_unpack_compressed(
|
||||
if (st == Z_BUF_ERROR && in == NULL) {
|
||||
inflateEnd(&stream);
|
||||
git__free(buffer);
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
}
|
||||
|
||||
*curpos += stream.next_in - in;
|
||||
@ -467,7 +467,7 @@ git_off_t get_delta_base(
|
||||
base_info = pack_window_open(p, w_curs, *curpos, &left);
|
||||
/* Assumption: the only reason this would fail is because the file is too small */
|
||||
if (base_info == NULL)
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
/* pack_window_open() assured us we have [base_info, base_info + 20)
|
||||
* as a range that we can look at without walking off the
|
||||
* end of the mapped window. Its actually the hash size
|
||||
@ -480,7 +480,7 @@ git_off_t get_delta_base(
|
||||
base_offset = c & 127;
|
||||
while (c & 128) {
|
||||
if (left <= used)
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
base_offset += 1;
|
||||
if (!base_offset || MSB(base_offset, 7))
|
||||
return 0; /* overflow */
|
||||
|
33
src/path.c
33
src/path.c
@ -494,7 +494,7 @@ int git_path_direach(
|
||||
{
|
||||
ssize_t wd_len;
|
||||
DIR *dir;
|
||||
struct dirent de_buf, *de;
|
||||
struct dirent *de, *de_buf;
|
||||
|
||||
if (git_path_to_dir(path) < 0)
|
||||
return -1;
|
||||
@ -506,14 +506,23 @@ int git_path_direach(
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p_readdir_r(dir, &de_buf, &de) == 0 && de != NULL) {
|
||||
#ifdef __sun
|
||||
de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
|
||||
#else
|
||||
de_buf = git__malloc(sizeof(struct dirent));
|
||||
#endif
|
||||
|
||||
while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) {
|
||||
int result;
|
||||
|
||||
if (is_dot_or_dotdot(de->d_name))
|
||||
continue;
|
||||
|
||||
if (git_buf_puts(path, de->d_name) < 0)
|
||||
if (git_buf_puts(path, de->d_name) < 0) {
|
||||
closedir(dir);
|
||||
git__free(de_buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = fn(arg, path);
|
||||
|
||||
@ -521,11 +530,13 @@ int git_path_direach(
|
||||
|
||||
if (result < 0) {
|
||||
closedir(dir);
|
||||
git__free(de_buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
git__free(de_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -537,7 +548,7 @@ int git_path_dirload(
|
||||
{
|
||||
int error, need_slash;
|
||||
DIR *dir;
|
||||
struct dirent de_buf, *de;
|
||||
struct dirent *de, *de_buf;
|
||||
size_t path_len;
|
||||
|
||||
assert(path != NULL && contents != NULL);
|
||||
@ -549,11 +560,17 @@ int git_path_dirload(
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __sun
|
||||
de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
|
||||
#else
|
||||
de_buf = git__malloc(sizeof(struct dirent));
|
||||
#endif
|
||||
|
||||
path += prefix_len;
|
||||
path_len -= prefix_len;
|
||||
need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;
|
||||
|
||||
while ((error = p_readdir_r(dir, &de_buf, &de)) == 0 && de != NULL) {
|
||||
while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) {
|
||||
char *entry_path;
|
||||
size_t entry_len;
|
||||
|
||||
@ -573,11 +590,15 @@ int git_path_dirload(
|
||||
memcpy(&entry_path[path_len + need_slash], de->d_name, entry_len);
|
||||
entry_path[path_len + need_slash + entry_len] = '\0';
|
||||
|
||||
if (git_vector_insert(contents, entry_path) < 0)
|
||||
if (git_vector_insert(contents, entry_path) < 0) {
|
||||
closedir(dir);
|
||||
git__free(de_buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
git__free(de_buf);
|
||||
|
||||
if (error != 0)
|
||||
giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path);
|
||||
|
@ -208,7 +208,7 @@ int git_pkt_parse_line(
|
||||
|
||||
/* Not even enough for the length */
|
||||
if (bufflen > 0 && bufflen < PKT_LEN_SIZE)
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
|
||||
len = parse_len(line);
|
||||
if (len < 0) {
|
||||
@ -230,7 +230,7 @@ int git_pkt_parse_line(
|
||||
* enough in the buffer to satisfy this line
|
||||
*/
|
||||
if (bufflen > 0 && bufflen < (size_t)len)
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
|
||||
line += PKT_LEN_SIZE;
|
||||
/*
|
||||
|
@ -34,7 +34,7 @@ int git_protocol_store_refs(git_protocol *p, const char *data, size_t len)
|
||||
return 0;
|
||||
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, git_buf_len(buf));
|
||||
if (error == GIT_ESHORTBUFFER)
|
||||
if (error == GIT_EBUFS)
|
||||
return 0; /* Ask for more */
|
||||
if (error < 0)
|
||||
return p->error = -1;
|
||||
|
@ -194,10 +194,10 @@ corrupt:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static git_rtype loose_guess_rtype(const git_buf *full_path)
|
||||
static git_ref_t loose_guess_rtype(const git_buf *full_path)
|
||||
{
|
||||
git_buf ref_file = GIT_BUF_INIT;
|
||||
git_rtype type;
|
||||
git_ref_t type;
|
||||
|
||||
type = GIT_REF_INVALID;
|
||||
|
||||
@ -1153,7 +1153,7 @@ int git_reference_lookup_resolved(
|
||||
/**
|
||||
* Getters
|
||||
*/
|
||||
git_rtype git_reference_type(git_reference *ref)
|
||||
git_ref_t git_reference_type(git_reference *ref)
|
||||
{
|
||||
assert(ref);
|
||||
|
||||
@ -1518,7 +1518,7 @@ static int cb__reflist_add(const char *ref, void *data)
|
||||
return git_vector_insert((git_vector *)data, git__strdup(ref));
|
||||
}
|
||||
|
||||
int git_reference_listall(
|
||||
int git_reference_list(
|
||||
git_strarray *array,
|
||||
git_repository *repo,
|
||||
unsigned int list_flags)
|
||||
|
@ -53,6 +53,13 @@ const char *git_refspec_dst(const git_refspec *refspec)
|
||||
return refspec == NULL ? NULL : refspec->dst;
|
||||
}
|
||||
|
||||
int git_refspec_force(const git_refspec *refspec)
|
||||
{
|
||||
assert(refspec);
|
||||
|
||||
return refspec->force;
|
||||
}
|
||||
|
||||
int git_refspec_src_matches(const git_refspec *refspec, const char *refname)
|
||||
{
|
||||
if (refspec == NULL || refspec->src == NULL)
|
||||
@ -68,7 +75,7 @@ int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, con
|
||||
baselen = strlen(spec->dst);
|
||||
if (outlen <= baselen) {
|
||||
giterr_set(GITERR_INVALID, "Reference name too long");
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -90,7 +97,7 @@ int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, con
|
||||
|
||||
if (outlen <= baselen + namelen) {
|
||||
giterr_set(GITERR_INVALID, "Reference name too long");
|
||||
return GIT_ESHORTBUFFER;
|
||||
return GIT_EBUFS;
|
||||
}
|
||||
|
||||
memcpy(out, spec->dst, baselen);
|
||||
|
@ -28,7 +28,7 @@ int git_refspec_parse(struct git_refspec *refspec, const char *str);
|
||||
* @param out where to store the target name
|
||||
* @param spec the refspec
|
||||
* @param name the name of the reference to transform
|
||||
* @return GIT_SUCCESS or error if buffer allocation fails
|
||||
* @return 0 or error if buffer allocation fails
|
||||
*/
|
||||
int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *name);
|
||||
|
||||
|
12
src/remote.c
12
src/remote.c
@ -48,7 +48,7 @@ static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const cha
|
||||
int error;
|
||||
const char *val;
|
||||
|
||||
if ((error = git_config_get_string(cfg, var, &val)) < 0)
|
||||
if ((error = git_config_get_string(&val, cfg, var)) < 0)
|
||||
return error;
|
||||
|
||||
return refspec_parse(refspec, val);
|
||||
@ -121,7 +121,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((error = git_config_get_string(config, git_buf_cstr(&buf), &val)) < 0)
|
||||
if ((error = git_config_get_string(&val, config, git_buf_cstr(&buf))) < 0)
|
||||
goto cleanup;
|
||||
|
||||
remote->repo = repo;
|
||||
@ -189,6 +189,8 @@ int git_remote_save(const git_remote *remote)
|
||||
git_buf_clear(&buf);
|
||||
git_buf_clear(&value);
|
||||
git_buf_printf(&buf, "remote.%s.fetch", remote->name);
|
||||
if (remote->fetch.force)
|
||||
git_buf_putc(&value, '+');
|
||||
git_buf_printf(&value, "%s:%s", remote->fetch.src, remote->fetch.dst);
|
||||
if (git_buf_oom(&buf) || git_buf_oom(&value))
|
||||
return -1;
|
||||
@ -201,6 +203,8 @@ int git_remote_save(const git_remote *remote)
|
||||
git_buf_clear(&buf);
|
||||
git_buf_clear(&value);
|
||||
git_buf_printf(&buf, "remote.%s.push", remote->name);
|
||||
if (remote->push.force)
|
||||
git_buf_putc(&value, '+');
|
||||
git_buf_printf(&value, "%s:%s", remote->push.src, remote->push.dst);
|
||||
if (git_buf_oom(&buf) || git_buf_oom(&value))
|
||||
return -1;
|
||||
@ -338,7 +342,7 @@ int git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, co
|
||||
assert(remote);
|
||||
|
||||
if (refs->length == 0)
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
|
||||
/* HEAD is only allowed to be the first in the list */
|
||||
head = refs->contents[0];
|
||||
@ -490,7 +494,7 @@ int git_remote_add(git_remote **out, git_repository *repo, const char *name, con
|
||||
{
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
|
||||
if (git_buf_printf(&buf, "refs/heads/*:refs/remotes/%s/*", name) < 0)
|
||||
if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_remote_new(out, repo, name, url, git_buf_cstr(&buf)) < 0)
|
||||
|
@ -25,8 +25,7 @@
|
||||
|
||||
#define GIT_BRANCH_MASTER "master"
|
||||
|
||||
#define GIT_CONFIG_CORE_REPOSITORYFORMATVERSION "core.repositoryformatversion"
|
||||
#define GIT_REPOSITORYFORMATVERSION 0
|
||||
#define GIT_REPO_VERSION 0
|
||||
|
||||
static void drop_odb(git_repository *repo)
|
||||
{
|
||||
@ -125,11 +124,12 @@ static int load_config_data(git_repository *repo)
|
||||
if (git_repository_config__weakptr(&config, repo) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_config_get_bool(config, "core.bare", &is_bare) < 0)
|
||||
return -1; /* FIXME: We assume that a missing core.bare
|
||||
variable is an error. Is this right? */
|
||||
|
||||
/* Try to figure out if it's bare, default to non-bare if it's not set */
|
||||
if (git_config_get_bool(&is_bare, config, "core.bare") < 0)
|
||||
repo->is_bare = 0;
|
||||
else
|
||||
repo->is_bare = is_bare;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ static int load_workdir(git_repository *repo, git_buf *parent_path)
|
||||
if (git_repository_config__weakptr(&config, repo) < 0)
|
||||
return -1;
|
||||
|
||||
error = git_config_get_string(config, "core.worktree", &worktree);
|
||||
error = git_config_get_string(&worktree, config, "core.worktree");
|
||||
if (!error && worktree != NULL)
|
||||
repo->workdir = git__strdup(worktree);
|
||||
else if (error != GIT_ENOTFOUND)
|
||||
@ -607,13 +607,13 @@ static int check_repositoryformatversion(git_repository *repo)
|
||||
if (git_repository_config__weakptr(&config, repo) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_config_get_int32(config, GIT_CONFIG_CORE_REPOSITORYFORMATVERSION, &version) < 0)
|
||||
if (git_config_get_int32(&version, config, "core.repositoryformatversion") < 0)
|
||||
return -1;
|
||||
|
||||
if (GIT_REPOSITORYFORMATVERSION < version) {
|
||||
if (GIT_REPO_VERSION < version) {
|
||||
giterr_set(GITERR_REPOSITORY,
|
||||
"Unsupported repository version %d. Only versions up to %d are supported.",
|
||||
version, GIT_REPOSITORYFORMATVERSION);
|
||||
version, GIT_REPO_VERSION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -676,7 +676,7 @@ static int repo_init_config(const char *git_dir, int is_bare)
|
||||
}
|
||||
|
||||
SET_REPO_CONFIG(bool, "core.bare", is_bare);
|
||||
SET_REPO_CONFIG(int32, GIT_CONFIG_CORE_REPOSITORYFORMATVERSION, GIT_REPOSITORYFORMATVERSION);
|
||||
SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION);
|
||||
/* TODO: what other defaults? */
|
||||
|
||||
git_buf_free(&cfg_path);
|
||||
@ -684,6 +684,59 @@ static int repo_init_config(const char *git_dir, int is_bare)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GIT_HOOKS_DIR "hooks/"
|
||||
#define GIT_HOOKS_DIR_MODE 0755
|
||||
|
||||
#define GIT_HOOKS_README_FILE GIT_HOOKS_DIR "README.sample"
|
||||
#define GIT_HOOKS_README_MODE 0755
|
||||
#define GIT_HOOKS_README_CONTENT \
|
||||
"#!/bin/sh\n"\
|
||||
"#\n"\
|
||||
"# Place appropriately named executable hook scripts into this directory\n"\
|
||||
"# to intercept various actions that git takes. See `git help hooks` for\n"\
|
||||
"# more information.\n"
|
||||
|
||||
#define GIT_INFO_DIR "info/"
|
||||
#define GIT_INFO_DIR_MODE 0755
|
||||
|
||||
#define GIT_INFO_EXCLUDE_FILE GIT_INFO_DIR "exclude"
|
||||
#define GIT_INFO_EXCLUDE_MODE 0644
|
||||
#define GIT_INFO_EXCLUDE_CONTENT \
|
||||
"# File patterns to ignore; see `git help ignore` for more information.\n"\
|
||||
"# Lines that start with '#' are comments.\n"
|
||||
|
||||
#define GIT_DESC_FILE "description"
|
||||
#define GIT_DESC_MODE 0644
|
||||
#define GIT_DESC_CONTENT "Unnamed repository; edit this file 'description' to name the repository.\n"
|
||||
|
||||
static int repo_write_template(
|
||||
const char *git_dir, const char *file, mode_t mode, const char *content)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
int fd, error = 0;
|
||||
|
||||
if (git_buf_joinpath(&path, git_dir, file) < 0)
|
||||
return -1;
|
||||
|
||||
fd = p_open(git_buf_cstr(&path), O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||
|
||||
if (fd >= 0) {
|
||||
error = p_write(fd, content, strlen(content));
|
||||
|
||||
p_close(fd);
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
error = fd;
|
||||
|
||||
git_buf_free(&path);
|
||||
|
||||
if (error)
|
||||
giterr_set(GITERR_OS,
|
||||
"Failed to initialize repository with template '%s'", file);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int repo_init_structure(const char *git_dir, int is_bare)
|
||||
{
|
||||
int i;
|
||||
@ -692,8 +745,16 @@ static int repo_init_structure(const char *git_dir, int is_bare)
|
||||
{ GIT_OBJECTS_PACK_DIR, GIT_OBJECT_DIR_MODE }, /* '/objects/pack/' */
|
||||
{ GIT_REFS_HEADS_DIR, GIT_REFS_DIR_MODE }, /* '/refs/heads/' */
|
||||
{ GIT_REFS_TAGS_DIR, GIT_REFS_DIR_MODE }, /* '/refs/tags/' */
|
||||
{ GIT_HOOKS_DIR, GIT_HOOKS_DIR_MODE }, /* '/hooks/' */
|
||||
{ GIT_INFO_DIR, GIT_INFO_DIR_MODE }, /* '/info/' */
|
||||
{ NULL, 0 }
|
||||
};
|
||||
struct { const char *file; mode_t mode; const char *content; } tmpl[] = {
|
||||
{ GIT_DESC_FILE, GIT_DESC_MODE, GIT_DESC_CONTENT },
|
||||
{ GIT_HOOKS_README_FILE, GIT_HOOKS_README_MODE, GIT_HOOKS_README_CONTENT },
|
||||
{ GIT_INFO_EXCLUDE_FILE, GIT_INFO_EXCLUDE_MODE, GIT_INFO_EXCLUDE_CONTENT },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
||||
/* Make the base directory */
|
||||
if (git_futils_mkdir_r(git_dir, NULL, is_bare ? GIT_BARE_DIR_MODE : GIT_DIR_MODE) < 0)
|
||||
@ -716,7 +777,13 @@ static int repo_init_structure(const char *git_dir, int is_bare)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: what's left? templates? */
|
||||
/* Make template files as needed */
|
||||
for (i = 0; tmpl[i].file != NULL; ++i) {
|
||||
if (repo_write_template(
|
||||
git_dir, tmpl[i].file, tmpl[i].mode, tmpl[i].content) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ static int merge_bases_many(commit_list **out, git_revwalk *walk, commit_object
|
||||
if ((p->flags & flags) == flags)
|
||||
continue;
|
||||
|
||||
if ((error = commit_parse(walk, p)) < GIT_SUCCESS)
|
||||
if ((error = commit_parse(walk, p)) < 0)
|
||||
return error;
|
||||
|
||||
p->flags |= flags;
|
||||
@ -600,7 +600,7 @@ static int revwalk_next_timesort(commit_object **object_out, git_revwalk *walk)
|
||||
}
|
||||
}
|
||||
|
||||
return GIT_EREVWALKOVER;
|
||||
return GIT_REVWALKOVER;
|
||||
}
|
||||
|
||||
static int revwalk_next_unsorted(commit_object **object_out, git_revwalk *walk)
|
||||
@ -618,7 +618,7 @@ static int revwalk_next_unsorted(commit_object **object_out, git_revwalk *walk)
|
||||
}
|
||||
}
|
||||
|
||||
return GIT_EREVWALKOVER;
|
||||
return GIT_REVWALKOVER;
|
||||
}
|
||||
|
||||
static int revwalk_next_toposort(commit_object **object_out, git_revwalk *walk)
|
||||
@ -629,7 +629,7 @@ static int revwalk_next_toposort(commit_object **object_out, git_revwalk *walk)
|
||||
for (;;) {
|
||||
next = commit_list_pop(&walk->iterator_topo);
|
||||
if (next == NULL)
|
||||
return GIT_EREVWALKOVER;
|
||||
return GIT_REVWALKOVER;
|
||||
|
||||
if (next->in_degree > 0) {
|
||||
next->topo_delay = 1;
|
||||
@ -654,7 +654,7 @@ static int revwalk_next_toposort(commit_object **object_out, git_revwalk *walk)
|
||||
static int revwalk_next_reverse(commit_object **object_out, git_revwalk *walk)
|
||||
{
|
||||
*object_out = commit_list_pop(&walk->iterator_reverse);
|
||||
return *object_out ? 0 : GIT_EREVWALKOVER;
|
||||
return *object_out ? 0 : GIT_REVWALKOVER;
|
||||
}
|
||||
|
||||
|
||||
@ -670,7 +670,7 @@ static int prepare_walk(git_revwalk *walk)
|
||||
* so we know that the walk is already over.
|
||||
*/
|
||||
if (walk->one == NULL)
|
||||
return GIT_EREVWALKOVER;
|
||||
return GIT_REVWALKOVER;
|
||||
|
||||
/* first figure out what the merge bases are */
|
||||
if (merge_bases_many(&bases, walk, walk->one, &walk->twos) < 0)
|
||||
@ -698,7 +698,7 @@ static int prepare_walk(git_revwalk *walk)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (error != GIT_EREVWALKOVER)
|
||||
if (error != GIT_REVWALKOVER)
|
||||
return error;
|
||||
|
||||
walk->get_next = &revwalk_next_toposort;
|
||||
@ -710,7 +710,7 @@ static int prepare_walk(git_revwalk *walk)
|
||||
if (commit_list_insert(next, &walk->iterator_reverse) == NULL)
|
||||
return -1;
|
||||
|
||||
if (error != GIT_EREVWALKOVER)
|
||||
if (error != GIT_REVWALKOVER)
|
||||
return error;
|
||||
|
||||
walk->get_next = &revwalk_next_reverse;
|
||||
@ -809,9 +809,9 @@ int git_revwalk_next(git_oid *oid, git_revwalk *walk)
|
||||
|
||||
error = walk->get_next(&next, walk);
|
||||
|
||||
if (error == GIT_EREVWALKOVER) {
|
||||
if (error == GIT_REVWALKOVER) {
|
||||
git_revwalk_reset(walk);
|
||||
return GIT_EREVWALKOVER;
|
||||
return GIT_REVWALKOVER;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
@ -838,5 +838,8 @@ void git_revwalk_reset(git_revwalk *walk)
|
||||
commit_list_free(&walk->iterator_rand);
|
||||
commit_list_free(&walk->iterator_reverse);
|
||||
walk->walking = 0;
|
||||
|
||||
walk->one = NULL;
|
||||
git_vector_clear(&walk->twos);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ static int parse_timezone_offset(const char *buffer, int *offset_out)
|
||||
|
||||
if (*offset_start == '\n') {
|
||||
*offset_out = 0;
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset_start[0] != '-' && offset_start[0] != '+')
|
||||
@ -164,7 +164,7 @@ static int parse_timezone_offset(const char *buffer, int *offset_out)
|
||||
if (offset_start[1] < '0' || offset_start[1] > '9')
|
||||
return timezone_error("expected initial digit");
|
||||
|
||||
if (git__strtol32(&dec_offset, offset_start + 1, &offset_end, 10) < GIT_SUCCESS)
|
||||
if (git__strtol32(&dec_offset, offset_start + 1, &offset_end, 10) < 0)
|
||||
return timezone_error("not a valid number");
|
||||
|
||||
if (offset_end - offset_start != 5)
|
||||
|
257
src/status.c
257
src/status.c
@ -70,7 +70,7 @@ static unsigned int workdir_delta2status(git_delta_t workdir_status)
|
||||
|
||||
int git_status_foreach_ext(
|
||||
git_repository *repo,
|
||||
git_status_options *opts,
|
||||
const git_status_options *opts,
|
||||
int (*cb)(const char *, unsigned int, void *),
|
||||
void *cbdata)
|
||||
{
|
||||
@ -163,244 +163,71 @@ int git_status_foreach(
|
||||
return git_status_foreach_ext(repo, &opts, callback, payload);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* the old stuff
|
||||
*/
|
||||
|
||||
struct status_entry {
|
||||
git_index_time mtime;
|
||||
|
||||
git_oid head_oid;
|
||||
git_oid index_oid;
|
||||
git_oid wt_oid;
|
||||
|
||||
unsigned int status_flags;
|
||||
|
||||
char path[GIT_FLEX_ARRAY]; /* more */
|
||||
struct status_file_info {
|
||||
unsigned int count;
|
||||
unsigned int status;
|
||||
char *expected;
|
||||
};
|
||||
|
||||
static struct status_entry *status_entry_new(git_vector *entries, const char *path)
|
||||
static int get_one_status(const char *path, unsigned int status, void *data)
|
||||
{
|
||||
struct status_entry *e = git__calloc(sizeof(*e) + strlen(path) + 1, 1);
|
||||
if (e == NULL)
|
||||
return NULL;
|
||||
struct status_file_info *sfi = data;
|
||||
|
||||
if (entries != NULL)
|
||||
git_vector_insert(entries, e);
|
||||
sfi->count++;
|
||||
sfi->status = status;
|
||||
|
||||
strcpy(e->path, path);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
GIT_INLINE(void) status_entry_update_from_tree_entry(struct status_entry *e, const git_tree_entry *tree_entry)
|
||||
{
|
||||
assert(e && tree_entry);
|
||||
|
||||
git_oid_cpy(&e->head_oid, &tree_entry->oid);
|
||||
}
|
||||
|
||||
GIT_INLINE(void) status_entry_update_from_index_entry(struct status_entry *e, const git_index_entry *index_entry)
|
||||
{
|
||||
assert(e && index_entry);
|
||||
|
||||
git_oid_cpy(&e->index_oid, &index_entry->oid);
|
||||
e->mtime = index_entry->mtime;
|
||||
}
|
||||
|
||||
static void status_entry_update_from_index(struct status_entry *e, git_index *index)
|
||||
{
|
||||
int idx;
|
||||
git_index_entry *index_entry;
|
||||
|
||||
assert(e && index);
|
||||
|
||||
idx = git_index_find(index, e->path);
|
||||
if (idx < 0)
|
||||
return;
|
||||
|
||||
index_entry = git_index_get(index, idx);
|
||||
|
||||
status_entry_update_from_index_entry(e, index_entry);
|
||||
}
|
||||
|
||||
static int status_entry_update_from_workdir(struct status_entry *e, const char* full_path)
|
||||
{
|
||||
struct stat filest;
|
||||
|
||||
if (p_stat(full_path, &filest) < 0) {
|
||||
giterr_set(GITERR_OS, "Cannot access file '%s'", full_path);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
if (e->mtime.seconds == (git_time_t)filest.st_mtime)
|
||||
git_oid_cpy(&e->wt_oid, &e->index_oid);
|
||||
else
|
||||
git_odb_hashfile(&e->wt_oid, full_path, GIT_OBJ_BLOB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int status_entry_update_flags(struct status_entry *e)
|
||||
{
|
||||
git_oid zero;
|
||||
int head_zero, index_zero, wt_zero;
|
||||
|
||||
memset(&zero, 0x0, sizeof(git_oid));
|
||||
|
||||
head_zero = git_oid_cmp(&zero, &e->head_oid);
|
||||
index_zero = git_oid_cmp(&zero, &e->index_oid);
|
||||
wt_zero = git_oid_cmp(&zero, &e->wt_oid);
|
||||
|
||||
if (head_zero == 0 && index_zero == 0 && wt_zero == 0)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if (head_zero == 0 && index_zero != 0)
|
||||
e->status_flags |= GIT_STATUS_INDEX_NEW;
|
||||
else if (index_zero == 0 && head_zero != 0)
|
||||
e->status_flags |= GIT_STATUS_INDEX_DELETED;
|
||||
else if (git_oid_cmp(&e->head_oid, &e->index_oid) != 0)
|
||||
e->status_flags |= GIT_STATUS_INDEX_MODIFIED;
|
||||
|
||||
if (index_zero == 0 && wt_zero != 0)
|
||||
e->status_flags |= GIT_STATUS_WT_NEW;
|
||||
else if (wt_zero == 0 && index_zero != 0)
|
||||
e->status_flags |= GIT_STATUS_WT_DELETED;
|
||||
else if (git_oid_cmp(&e->index_oid, &e->wt_oid) != 0)
|
||||
e->status_flags |= GIT_STATUS_WT_MODIFIED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int status_entry_is_ignorable(struct status_entry *e)
|
||||
{
|
||||
/* don't ignore files that exist in head or index already */
|
||||
return (e->status_flags == GIT_STATUS_WT_NEW);
|
||||
}
|
||||
|
||||
static int status_entry_update_ignore(struct status_entry *e, git_ignores *ignores, const char *path)
|
||||
{
|
||||
int ignored;
|
||||
|
||||
if (git_ignore__lookup(ignores, path, &ignored) < 0)
|
||||
if (sfi->count > 1 || strcmp(sfi->expected, path) != 0) {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Ambiguous path '%s' given to git_status_file", sfi->expected);
|
||||
return -1;
|
||||
|
||||
if (ignored)
|
||||
/* toggle off WT_NEW and on IGNORED */
|
||||
e->status_flags =
|
||||
(e->status_flags & ~GIT_STATUS_WT_NEW) | GIT_STATUS_IGNORED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int recurse_tree_entry(git_tree *tree, struct status_entry *e, const char *path)
|
||||
{
|
||||
char *dir_sep;
|
||||
const git_tree_entry *tree_entry;
|
||||
git_tree *subtree;
|
||||
int error;
|
||||
|
||||
dir_sep = strchr(path, '/');
|
||||
if (!dir_sep) {
|
||||
if ((tree_entry = git_tree_entry_byname(tree, path)) != NULL)
|
||||
/* The leaf exists in the tree*/
|
||||
status_entry_update_from_tree_entry(e, tree_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve subtree name */
|
||||
*dir_sep = '\0';
|
||||
|
||||
if ((tree_entry = git_tree_entry_byname(tree, path)) == NULL)
|
||||
return 0; /* The subtree doesn't exist in the tree*/
|
||||
|
||||
*dir_sep = '/';
|
||||
|
||||
/* Retreive subtree */
|
||||
error = git_tree_lookup(&subtree, tree->object.repo, &tree_entry->oid);
|
||||
if (!error) {
|
||||
error = recurse_tree_entry(subtree, e, dir_sep+1);
|
||||
git_tree_free(subtree);
|
||||
}
|
||||
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_status_file(
|
||||
unsigned int *status_flags, git_repository *repo, const char *path)
|
||||
unsigned int *status_flags,
|
||||
git_repository *repo,
|
||||
const char *path)
|
||||
{
|
||||
struct status_entry *e;
|
||||
git_index *index = NULL;
|
||||
git_buf temp_path = GIT_BUF_INIT;
|
||||
int error = 0;
|
||||
git_tree *tree = NULL;
|
||||
const char *workdir;
|
||||
int error;
|
||||
git_status_options opts;
|
||||
struct status_file_info sfi;
|
||||
|
||||
assert(status_flags && repo && path);
|
||||
|
||||
if ((workdir = git_repository_workdir(repo)) == NULL) {
|
||||
giterr_set(GITERR_INVALID, "Cannot get file status from bare repo");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_buf_joinpath(&temp_path, workdir, path) < 0)
|
||||
memset(&sfi, 0, sizeof(sfi));
|
||||
if ((sfi.expected = git__strdup(path)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (git_path_isdir(temp_path.ptr)) {
|
||||
giterr_set(GITERR_INVALID, "Cannot get file status for directory '%s'", temp_path.ptr);
|
||||
git_buf_free(&temp_path);
|
||||
return -1;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
|
||||
opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
|
||||
GIT_STATUS_OPT_INCLUDE_UNTRACKED |
|
||||
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS |
|
||||
GIT_STATUS_OPT_INCLUDE_UNMODIFIED;
|
||||
opts.pathspec.count = 1;
|
||||
opts.pathspec.strings = &sfi.expected;
|
||||
|
||||
error = git_status_foreach_ext(repo, &opts, get_one_status, &sfi);
|
||||
|
||||
if (!error && !sfi.count) {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Attempt to get status of nonexistent file '%s'", path);
|
||||
error = GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
e = status_entry_new(NULL, path);
|
||||
GITERR_CHECK_ALLOC(e);
|
||||
*status_flags = sfi.status;
|
||||
|
||||
/* Find file in Workdir */
|
||||
if (git_path_exists(temp_path.ptr) == true &&
|
||||
(error = status_entry_update_from_workdir(e, temp_path.ptr)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Find file in Index */
|
||||
if ((error = git_repository_index__weakptr(&index, repo)) < 0)
|
||||
goto cleanup;
|
||||
status_entry_update_from_index(e, index);
|
||||
|
||||
/* Try to find file in HEAD */
|
||||
if ((error = git_repository_head_tree(&tree, repo)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (tree != NULL) {
|
||||
if ((error = git_buf_sets(&temp_path, path)) < 0 ||
|
||||
(error = recurse_tree_entry(tree, e, temp_path.ptr)) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Determine status */
|
||||
if ((error = status_entry_update_flags(e)) < 0)
|
||||
giterr_set(GITERR_OS, "Cannot find file '%s' to determine status", path);
|
||||
|
||||
if (!error && status_entry_is_ignorable(e)) {
|
||||
git_ignores ignores;
|
||||
|
||||
if ((error = git_ignore__for_path(repo, path, &ignores)) == 0)
|
||||
error = status_entry_update_ignore(e, &ignores, path);
|
||||
|
||||
git_ignore__free(&ignores);
|
||||
}
|
||||
|
||||
if (!error)
|
||||
*status_flags = e->status_flags;
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&temp_path);
|
||||
git_tree_free(tree);
|
||||
git__free(e);
|
||||
git__free(sfi.expected);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_status_should_ignore(git_repository *repo, const char *path, int *ignored)
|
||||
int git_status_should_ignore(
|
||||
int *ignored,
|
||||
git_repository *repo,
|
||||
const char *path)
|
||||
{
|
||||
int error;
|
||||
git_ignores ignores;
|
||||
|
@ -218,9 +218,12 @@ static int submodule_from_config(
|
||||
sm->update = (git_submodule_update_t)val;
|
||||
}
|
||||
else if (strcmp(property, "fetchRecurseSubmodules") == 0) {
|
||||
if (git_config_parse_bool(&sm->fetch_recurse, value) < 0)
|
||||
if (git__parse_bool(&sm->fetch_recurse, value) < 0) {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Invalid value for submodule 'fetchRecurseSubmodules' property: '%s'", value);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (strcmp(property, "ignore") == 0) {
|
||||
int val;
|
||||
if (git_config_lookup_map_value(
|
||||
|
10
src/tag.c
10
src/tag.c
@ -168,7 +168,7 @@ static int retrieve_tag_reference(
|
||||
return -1;
|
||||
|
||||
error = git_reference_lookup(&tag_ref, repo, ref_name_out->ptr);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error; /* Be it not foundo or corrupted */
|
||||
|
||||
*tag_reference_out = tag_ref;
|
||||
@ -254,7 +254,7 @@ static int git_tag_create__internal(
|
||||
}
|
||||
|
||||
error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag_name);
|
||||
if (error < GIT_SUCCESS && error != GIT_ENOTFOUND)
|
||||
if (error < 0 && error != GIT_ENOTFOUND)
|
||||
return -1;
|
||||
|
||||
/** Ensure the tag name doesn't conflict with an already existing
|
||||
@ -332,7 +332,7 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
|
||||
}
|
||||
|
||||
error = retrieve_tag_reference_oid(oid, &ref_name, repo, tag.tag_name);
|
||||
if (error < GIT_SUCCESS && error != GIT_ENOTFOUND)
|
||||
if (error < 0 && error != GIT_ENOTFOUND)
|
||||
goto on_error;
|
||||
|
||||
/* We don't need these objects after this */
|
||||
@ -414,7 +414,7 @@ static int tag_list_cb(const char *tag_name, void *payload)
|
||||
return 0;
|
||||
|
||||
filter = (tag_filter_data *)payload;
|
||||
if (!*filter->pattern || p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == GIT_SUCCESS)
|
||||
if (!*filter->pattern || p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0)
|
||||
return git_vector_insert(filter->taglist, git__strdup(tag_name));
|
||||
|
||||
return 0;
|
||||
@ -428,7 +428,7 @@ int git_tag_list_match(git_strarray *tag_names, const char *pattern, git_reposit
|
||||
|
||||
assert(tag_names && repo && pattern);
|
||||
|
||||
if (git_vector_init(&taglist, 8, NULL) < GIT_SUCCESS)
|
||||
if (git_vector_init(&taglist, 8, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
filter.taglist = &taglist;
|
||||
|
@ -37,7 +37,7 @@ static git_transport_cb transport_find_fn(const char *url)
|
||||
}
|
||||
|
||||
/* still here? Check to see if the path points to a file on the local file system */
|
||||
if ((git_path_exists(url) == GIT_SUCCESS) && git_path_isdir(url))
|
||||
if ((git_path_exists(url) == 0) && git_path_isdir(url))
|
||||
return &git_transport_local;
|
||||
|
||||
/* It could be a SSH remote path. Check to see if there's a : */
|
||||
@ -72,7 +72,7 @@ int git_transport_new(git_transport **out, const char *url)
|
||||
}
|
||||
|
||||
error = fn(&transport);
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
transport->url = git__strdup(url);
|
||||
@ -80,7 +80,7 @@ int git_transport_new(git_transport **out, const char *url)
|
||||
|
||||
*out = transport;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* from remote.h */
|
||||
|
@ -147,7 +147,7 @@ static int store_refs(transport_git *t)
|
||||
return 0;
|
||||
|
||||
ret = git_protocol_store_refs(&t->proto, buf->data, buf->offset);
|
||||
if (ret == GIT_ESHORTBUFFER) {
|
||||
if (ret == GIT_EBUFS) {
|
||||
gitno_consume_n(buf, buf->len);
|
||||
continue;
|
||||
}
|
||||
@ -279,7 +279,7 @@ static int recv_pkt(gitno_buffer *buf)
|
||||
return -1;
|
||||
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->offset);
|
||||
if (error == GIT_ESHORTBUFFER)
|
||||
if (error == GIT_EBUFS)
|
||||
continue;
|
||||
if (error < 0)
|
||||
return -1;
|
||||
@ -344,7 +344,7 @@ static int git_negotiate_fetch(git_transport *transport, git_repository *repo, c
|
||||
|
||||
}
|
||||
}
|
||||
if (error < 0 && error != GIT_EREVWALKOVER)
|
||||
if (error < 0 && error != GIT_REVWALKOVER)
|
||||
goto on_error;
|
||||
|
||||
/* Tell the other end that we're done negotiating */
|
||||
@ -384,10 +384,10 @@ static int git_download_pack(git_transport *transport, git_repository *repo, git
|
||||
}
|
||||
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->offset);
|
||||
if (error == GIT_ESHORTBUFFER)
|
||||
if (error == GIT_EBUFS)
|
||||
break;
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (pkt->type == GIT_PKT_PACK) {
|
||||
@ -417,6 +417,8 @@ static int git_close(git_transport *transport)
|
||||
return -1;
|
||||
}
|
||||
|
||||
t->parent.connected = 0;
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
@ -354,10 +354,10 @@ static int on_body_parse_response(http_parser *parser, const char *str, size_t l
|
||||
return 0;
|
||||
|
||||
error = git_pkt_parse_line(&pkt, ptr, &line_end, git_buf_len(buf));
|
||||
if (error == GIT_ESHORTBUFFER) {
|
||||
if (error == GIT_EBUFS) {
|
||||
return 0; /* Ask for more */
|
||||
}
|
||||
if (error < GIT_SUCCESS)
|
||||
if (error < 0)
|
||||
return t->error = -1;
|
||||
|
||||
git_buf_consume(buf, line_end);
|
||||
@ -486,7 +486,7 @@ static int http_negotiate_fetch(git_transport *transport, git_repository *repo,
|
||||
git_buf_clear(&request);
|
||||
git_buf_clear(&data);
|
||||
|
||||
if (ret < GIT_SUCCESS || i >= 256)
|
||||
if (ret < 0 || i >= 256)
|
||||
break;
|
||||
|
||||
if ((ret = parse_response(t)) < 0)
|
||||
@ -610,6 +610,8 @@ static int http_close(git_transport *transport)
|
||||
return -1;
|
||||
}
|
||||
|
||||
t->parent.connected = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ static int store_refs(transport_local *t)
|
||||
|
||||
assert(t);
|
||||
|
||||
if (git_reference_listall(&ref_names, t->repo, GIT_REF_LISTALL) < 0 ||
|
||||
if (git_reference_list(&ref_names, t->repo, GIT_REF_LISTALL) < 0 ||
|
||||
git_vector_init(&t->refs, (unsigned int)ref_names.count, NULL) < 0)
|
||||
goto on_error;
|
||||
|
||||
@ -176,10 +176,21 @@ static int local_connect(git_transport *transport, int direction)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int local_negotiate_fetch(git_transport *transport, git_repository *repo, const git_vector *wants)
|
||||
{
|
||||
GIT_UNUSED(transport);
|
||||
GIT_UNUSED(repo);
|
||||
GIT_UNUSED(wants);
|
||||
|
||||
giterr_set(GITERR_NET, "Fetch via local transport isn't implemented. Sorry");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int local_close(git_transport *transport)
|
||||
{
|
||||
transport_local *t = (transport_local *)transport;
|
||||
|
||||
t->parent.connected = 0;
|
||||
git_repository_free(t->repo);
|
||||
t->repo = NULL;
|
||||
|
||||
@ -220,6 +231,7 @@ int git_transport_local(git_transport **out)
|
||||
|
||||
t->parent.connect = local_connect;
|
||||
t->parent.ls = local_ls;
|
||||
t->parent.negotiate_fetch = local_negotiate_fetch;
|
||||
t->parent.close = local_close;
|
||||
t->parent.free = local_free;
|
||||
|
||||
|
314
src/tree.c
314
src/tree.c
@ -31,8 +31,8 @@ static int entry_sort_cmp(const void *a, const void *b)
|
||||
const git_tree_entry *entry_b = (const git_tree_entry *)(b);
|
||||
|
||||
return git_path_cmp(
|
||||
entry_a->filename, entry_a->filename_len, entry_is_tree(entry_a),
|
||||
entry_b->filename, entry_b->filename_len, entry_is_tree(entry_b));
|
||||
entry_a->filename, entry_a->filename_len, git_tree_entry__is_tree(entry_a),
|
||||
entry_b->filename, entry_b->filename_len, git_tree_entry__is_tree(entry_b));
|
||||
}
|
||||
|
||||
|
||||
@ -170,7 +170,10 @@ git_otype git_tree_entry_type(const git_tree_entry *entry)
|
||||
return GIT_OBJ_BLOB;
|
||||
}
|
||||
|
||||
int git_tree_entry_2object(git_object **object_out, git_repository *repo, const git_tree_entry *entry)
|
||||
int git_tree_entry_to_object(
|
||||
git_object **object_out,
|
||||
git_repository *repo,
|
||||
const git_tree_entry *entry)
|
||||
{
|
||||
assert(entry && object_out);
|
||||
return git_object_lookup(object_out, repo, &entry->oid, GIT_OBJ_ANY);
|
||||
@ -195,6 +198,33 @@ const git_tree_entry *git_tree_entry_byindex(git_tree *tree, unsigned int idx)
|
||||
return git_vector_get(&tree->entries, idx);
|
||||
}
|
||||
|
||||
int git_tree__prefix_position(git_tree *tree, const char *path)
|
||||
{
|
||||
git_vector *entries = &tree->entries;
|
||||
struct tree_key_search ksearch;
|
||||
unsigned int at_pos;
|
||||
|
||||
ksearch.filename = path;
|
||||
ksearch.filename_len = strlen(path);
|
||||
|
||||
/* Find tree entry with appropriate prefix */
|
||||
git_vector_bsearch3(&at_pos, entries, &homing_search_cmp, &ksearch);
|
||||
|
||||
for (; at_pos < entries->length; ++at_pos) {
|
||||
const git_tree_entry *entry = entries->contents[at_pos];
|
||||
if (homing_search_cmp(&ksearch, entry) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
for (; at_pos > 0; --at_pos) {
|
||||
const git_tree_entry *entry = entries->contents[at_pos - 1];
|
||||
if (homing_search_cmp(&ksearch, entry) > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return at_pos;
|
||||
}
|
||||
|
||||
unsigned int git_tree_entrycount(git_tree *tree)
|
||||
{
|
||||
assert(tree);
|
||||
@ -617,7 +647,7 @@ static int tree_frompath(
|
||||
{
|
||||
char *slash_pos = NULL;
|
||||
const git_tree_entry* entry;
|
||||
int error = GIT_SUCCESS;
|
||||
int error = 0;
|
||||
git_tree *subtree;
|
||||
|
||||
if (!*(treeentry_path->ptr + offset)) {
|
||||
@ -694,7 +724,7 @@ static int tree_walk_post(
|
||||
git_buf *path,
|
||||
void *payload)
|
||||
{
|
||||
int error = GIT_SUCCESS;
|
||||
int error = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < tree->entries.length; ++i) {
|
||||
@ -703,7 +733,7 @@ static int tree_walk_post(
|
||||
if (callback(path->ptr, entry, payload) < 0)
|
||||
continue;
|
||||
|
||||
if (entry_is_tree(entry)) {
|
||||
if (git_tree_entry__is_tree(entry)) {
|
||||
git_tree *subtree;
|
||||
size_t path_len = git_buf_len(path);
|
||||
|
||||
@ -731,7 +761,7 @@ static int tree_walk_post(
|
||||
|
||||
int git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payload)
|
||||
{
|
||||
int error = GIT_SUCCESS;
|
||||
int error = 0;
|
||||
git_buf root_path = GIT_BUF_INIT;
|
||||
|
||||
switch (mode) {
|
||||
@ -753,273 +783,3 @@ int git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payl
|
||||
return error;
|
||||
}
|
||||
|
||||
static int tree_entry_cmp(const git_tree_entry *a, const git_tree_entry *b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = a->attr - b->attr;
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return git_oid_cmp(&a->oid, &b->oid);
|
||||
}
|
||||
|
||||
static void mark_del(git_tree_diff_data *diff, git_tree_entry *entry)
|
||||
{
|
||||
diff->old_attr = entry->attr;
|
||||
git_oid_cpy(&diff->old_oid, &entry->oid);
|
||||
diff->path = entry->filename;
|
||||
diff->status |= GIT_STATUS_DELETED;
|
||||
}
|
||||
|
||||
static void mark_add(git_tree_diff_data *diff, git_tree_entry *entry)
|
||||
{
|
||||
diff->new_attr = entry->attr;
|
||||
git_oid_cpy(&diff->new_oid, &entry->oid);
|
||||
diff->path = entry->filename;
|
||||
diff->status |= GIT_STATUS_ADDED;
|
||||
}
|
||||
|
||||
static int signal_additions(git_tree *tree, int start, int end, git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
git_tree_diff_data diff;
|
||||
git_tree_entry *entry;
|
||||
int i;
|
||||
|
||||
if (end < 0)
|
||||
end = git_tree_entrycount(tree);
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
memset(&diff, 0x0, sizeof(git_tree_diff_data));
|
||||
entry = git_vector_get(&tree->entries, i);
|
||||
mark_add(&diff, entry);
|
||||
|
||||
if (cb(&diff, data) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int signal_addition(git_tree_entry *entry, git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
git_tree_diff_data diff;
|
||||
|
||||
memset(&diff, 0x0, sizeof(git_tree_diff_data));
|
||||
|
||||
mark_add(&diff, entry);
|
||||
|
||||
return cb(&diff, data);
|
||||
}
|
||||
|
||||
static int signal_deletions(git_tree *tree, int start, int end, git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
git_tree_diff_data diff;
|
||||
git_tree_entry *entry;
|
||||
int i;
|
||||
|
||||
if (end < 0)
|
||||
end = git_tree_entrycount(tree);
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
memset(&diff, 0x0, sizeof(git_tree_diff_data));
|
||||
entry = git_vector_get(&tree->entries, i);
|
||||
mark_del(&diff, entry);
|
||||
|
||||
if (cb(&diff, data) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int signal_deletion(git_tree_entry *entry, git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
git_tree_diff_data diff;
|
||||
|
||||
memset(&diff, 0x0, sizeof(git_tree_diff_data));
|
||||
|
||||
mark_del(&diff, entry);
|
||||
|
||||
return cb(&diff, data);
|
||||
}
|
||||
|
||||
static int signal_modification(git_tree_entry *a, git_tree_entry *b,
|
||||
git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
git_tree_diff_data diff;
|
||||
|
||||
memset(&diff, 0x0, sizeof(git_tree_diff_data));
|
||||
|
||||
mark_del(&diff, a);
|
||||
mark_add(&diff, b);
|
||||
|
||||
return cb(&diff, data);
|
||||
}
|
||||
|
||||
int git_tree_diff(git_tree *a, git_tree *b, git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
unsigned int i_a = 0, i_b = 0; /* Counters for trees a and b */
|
||||
git_tree_entry *entry_a = NULL, *entry_b = NULL;
|
||||
git_tree_diff_data diff;
|
||||
int cmp;
|
||||
|
||||
while (1) {
|
||||
entry_a = a == NULL ? NULL : git_vector_get(&a->entries, i_a);
|
||||
entry_b = b == NULL ? NULL : git_vector_get(&b->entries, i_b);
|
||||
|
||||
if (!entry_a && !entry_b)
|
||||
return 0;
|
||||
|
||||
memset(&diff, 0x0, sizeof(git_tree_diff_data));
|
||||
|
||||
/*
|
||||
* We've run out of tree on one side so the rest of the
|
||||
* entries on the tree with remaining entries are all
|
||||
* deletions or additions.
|
||||
*/
|
||||
if (entry_a && !entry_b)
|
||||
return signal_deletions(a, i_a, -1, cb, data);
|
||||
if (!entry_a && entry_b)
|
||||
return signal_additions(b, i_b, -1, cb, data);
|
||||
|
||||
/*
|
||||
* Both trees are sorted with git's almost-alphabetical
|
||||
* sorting, so a comparison value < 0 means the entry was
|
||||
* deleted in the right tree. > 0 means the entry was added.
|
||||
*/
|
||||
cmp = entry_sort_cmp(entry_a, entry_b);
|
||||
|
||||
if (cmp == 0) {
|
||||
i_a++;
|
||||
i_b++;
|
||||
|
||||
/* If everything's the same, jump to next pair */
|
||||
if (!tree_entry_cmp(entry_a, entry_b))
|
||||
continue;
|
||||
|
||||
/* If they're not both dirs or both files, it's add + del */
|
||||
if (S_ISDIR(entry_a->attr) != S_ISDIR(entry_b->attr)) {
|
||||
if (signal_addition(entry_a, cb, data) < 0)
|
||||
return -1;
|
||||
if (signal_deletion(entry_b, cb, data) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Otherwise consider it a modification */
|
||||
if (signal_modification(entry_a, entry_b, cb, data) < 0)
|
||||
return -1;
|
||||
|
||||
} else if (cmp < 0) {
|
||||
i_a++;
|
||||
if (signal_deletion(entry_a, cb, data) < 0)
|
||||
return -1;
|
||||
} else if (cmp > 0) {
|
||||
i_b++;
|
||||
if (signal_addition(entry_b, cb, data) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct diff_index_cbdata {
|
||||
git_index *index;
|
||||
unsigned int i;
|
||||
git_tree_diff_cb cb;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static int cmp_tentry_ientry(git_tree_entry *tentry, git_index_entry *ientry)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
cmp = tentry->attr - ientry->mode;
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
return git_oid_cmp(&tentry->oid, &ientry->oid);
|
||||
}
|
||||
|
||||
static void make_tentry(git_tree_entry *tentry, git_index_entry *ientry)
|
||||
{
|
||||
char *last_slash;
|
||||
|
||||
memset(tentry, 0x0, sizeof(git_tree_entry));
|
||||
tentry->attr = ientry->mode;
|
||||
|
||||
last_slash = strrchr(ientry->path, '/');
|
||||
if (last_slash)
|
||||
last_slash++;
|
||||
else
|
||||
last_slash = ientry->path;
|
||||
tentry->filename = last_slash;
|
||||
|
||||
git_oid_cpy(&tentry->oid, &ientry->oid);
|
||||
tentry->filename_len = strlen(tentry->filename);
|
||||
}
|
||||
|
||||
static int diff_index_cb(const char *root, git_tree_entry *tentry, void *data)
|
||||
{
|
||||
struct diff_index_cbdata *cbdata = (struct diff_index_cbdata *) data;
|
||||
git_index_entry *ientry = git_index_get(cbdata->index, cbdata->i);
|
||||
git_tree_entry fake_entry;
|
||||
git_buf fn_buf = GIT_BUF_INIT;
|
||||
int cmp;
|
||||
|
||||
if (entry_is_tree(tentry))
|
||||
return 0;
|
||||
|
||||
if (!ientry)
|
||||
return signal_deletion(tentry, cbdata->cb, cbdata->data);
|
||||
|
||||
git_buf_puts(&fn_buf, root);
|
||||
git_buf_puts(&fn_buf, tentry->filename);
|
||||
|
||||
/* Like with 'git diff-index', the index is the right side*/
|
||||
cmp = strcmp(git_buf_cstr(&fn_buf), ientry->path);
|
||||
git_buf_free(&fn_buf);
|
||||
if (cmp == 0) {
|
||||
cbdata->i++;
|
||||
if (!cmp_tentry_ientry(tentry, ientry))
|
||||
return 0;
|
||||
/* modification */
|
||||
make_tentry(&fake_entry, ientry);
|
||||
if (signal_modification(tentry, &fake_entry, cbdata->cb, cbdata->data) < 0)
|
||||
return -1;
|
||||
} else if (cmp < 0) {
|
||||
/* deletion */
|
||||
memcpy(&fake_entry, tentry, sizeof(git_tree_entry));
|
||||
if (signal_deletion(tentry, cbdata->cb, cbdata->data) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
/* addition */
|
||||
cbdata->i++;
|
||||
make_tentry(&fake_entry, ientry);
|
||||
if (signal_addition(&fake_entry, cbdata->cb, cbdata->data) < 0)
|
||||
return -1;
|
||||
/*
|
||||
* The index has an addition. This means that we need to use
|
||||
* the next entry in the index without advancing the tree
|
||||
* walker, so call ourselves with the same tree state.
|
||||
*/
|
||||
if (diff_index_cb(root, tentry, data) < 0)
|
||||
return -1;;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_tree_diff_index_recursive(git_tree *tree, git_index *index, git_tree_diff_cb cb, void *data)
|
||||
{
|
||||
struct diff_index_cbdata cbdata;
|
||||
git_buf dummy_path = GIT_BUF_INIT;
|
||||
|
||||
cbdata.index = index;
|
||||
cbdata.i = 0;
|
||||
cbdata.cb = cb;
|
||||
cbdata.data = data;
|
||||
|
||||
return tree_walk_post(tree, diff_index_cb, &dummy_path, &cbdata);
|
||||
}
|
||||
|
12
src/tree.h
12
src/tree.h
@ -30,7 +30,7 @@ struct git_treebuilder {
|
||||
};
|
||||
|
||||
|
||||
GIT_INLINE(unsigned int) entry_is_tree(const struct git_tree_entry *e)
|
||||
GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e)
|
||||
{
|
||||
return (S_ISDIR(e->attr) && !S_ISGITLINK(e->attr));
|
||||
}
|
||||
@ -38,4 +38,14 @@ GIT_INLINE(unsigned int) entry_is_tree(const struct git_tree_entry *e)
|
||||
void git_tree__free(git_tree *tree);
|
||||
int git_tree__parse(git_tree *tree, git_odb_object *obj);
|
||||
|
||||
/**
|
||||
* Lookup the first position in the tree with a given prefix.
|
||||
*
|
||||
* @param tree a previously loaded tree.
|
||||
* @param prefix the beginning of a path to find in the tree.
|
||||
* @return index of the first item at or after the given prefix.
|
||||
*/
|
||||
int git_tree__prefix_position(git_tree *tree, const char *prefix);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,14 @@
|
||||
#ifndef INCLUDE_posix__w32_h__
|
||||
#define INCLUDE_posix__w32_h__
|
||||
|
||||
#include <fnmatch.h>
|
||||
#ifndef __sun
|
||||
# include <fnmatch.h>
|
||||
# define p_fnmatch(p, s, f) fnmatch(p, s, f)
|
||||
#else
|
||||
# include "compat/fnmatch.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define p_lstat(p,b) lstat(p,b)
|
||||
#define p_readlink(a, b, c) readlink(a, b, c)
|
||||
@ -16,7 +23,6 @@
|
||||
#define p_mkdir(p,m) mkdir(p, m)
|
||||
#define p_fsync(fd) fsync(fd)
|
||||
#define p_realpath(p, po) realpath(p, po)
|
||||
#define p_fnmatch(p, s, f) fnmatch(p, s, f)
|
||||
#define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a)
|
||||
#define p_snprintf(b, c, f, ...) snprintf(b, c, f, __VA_ARGS__)
|
||||
#define p_mkstemp(p) mkstemp(p)
|
||||
|
24
src/util.c
24
src/util.c
@ -411,3 +411,27 @@ int git__strcmp_cb(const void *a, const void *b)
|
||||
|
||||
return strcmp(stra, strb);
|
||||
}
|
||||
|
||||
int git__parse_bool(int *out, const char *value)
|
||||
{
|
||||
/* A missing value means true */
|
||||
if (value == NULL) {
|
||||
*out = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(value, "true") ||
|
||||
!strcasecmp(value, "yes") ||
|
||||
!strcasecmp(value, "on")) {
|
||||
*out = 1;
|
||||
return 0;
|
||||
}
|
||||
if (!strcasecmp(value, "false") ||
|
||||
!strcasecmp(value, "no") ||
|
||||
!strcasecmp(value, "off")) {
|
||||
*out = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
14
src/util.h
14
src/util.h
@ -216,4 +216,18 @@ GIT_INLINE(int) git__time_cmp(const git_time *a, const git_time *b)
|
||||
return (int)(adjusted_a - b->time);
|
||||
}
|
||||
|
||||
GIT_INLINE(bool) git__iswildcard(int c)
|
||||
{
|
||||
return (c == '*' || c == '?' || c == '[');
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a string value as a boolean, just like Core Git
|
||||
* does.
|
||||
*
|
||||
* Valid values for true are: 'true', 'yes', 'on'
|
||||
* Valid values for false are: 'false', 'no', 'off'
|
||||
*/
|
||||
extern int git__parse_bool(int *out, const char *value);
|
||||
|
||||
#endif /* INCLUDE_util_h__ */
|
||||
|
23
src/vector.c
23
src/vector.c
@ -116,8 +116,13 @@ void git_vector_sort(git_vector *v)
|
||||
v->sorted = 1;
|
||||
}
|
||||
|
||||
int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *key)
|
||||
int git_vector_bsearch3(
|
||||
unsigned int *at_pos,
|
||||
git_vector *v,
|
||||
git_vector_cmp key_lookup,
|
||||
const void *key)
|
||||
{
|
||||
int rval;
|
||||
size_t pos;
|
||||
|
||||
assert(v && key && key_lookup);
|
||||
@ -127,13 +132,16 @@ int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *ke
|
||||
|
||||
git_vector_sort(v);
|
||||
|
||||
if (git__bsearch(v->contents, v->length, key, key_lookup, &pos) >= 0)
|
||||
return (int)pos;
|
||||
rval = git__bsearch(v->contents, v->length, key, key_lookup, &pos);
|
||||
|
||||
return GIT_ENOTFOUND;
|
||||
if (at_pos != NULL)
|
||||
*at_pos = (unsigned int)pos;
|
||||
|
||||
return (rval >= 0) ? (int)pos : GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
int git_vector_search2(git_vector *v, git_vector_cmp key_lookup, const void *key)
|
||||
int git_vector_search2(
|
||||
git_vector *v, git_vector_cmp key_lookup, const void *key)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -157,11 +165,6 @@ int git_vector_search(git_vector *v, const void *entry)
|
||||
return git_vector_search2(v, v->_cmp ? v->_cmp : strict_comparison, entry);
|
||||
}
|
||||
|
||||
int git_vector_bsearch(git_vector *v, const void *key)
|
||||
{
|
||||
return git_vector_bsearch2(v, v->_cmp, key);
|
||||
}
|
||||
|
||||
int git_vector_remove(git_vector *v, unsigned int idx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
17
src/vector.h
17
src/vector.h
@ -26,13 +26,24 @@ void git_vector_free(git_vector *v);
|
||||
void git_vector_clear(git_vector *v);
|
||||
void git_vector_swap(git_vector *a, git_vector *b);
|
||||
|
||||
void git_vector_sort(git_vector *v);
|
||||
|
||||
int git_vector_search(git_vector *v, const void *entry);
|
||||
int git_vector_search2(git_vector *v, git_vector_cmp cmp, const void *key);
|
||||
|
||||
int git_vector_bsearch(git_vector *v, const void *entry);
|
||||
int git_vector_bsearch2(git_vector *v, git_vector_cmp cmp, const void *key);
|
||||
int git_vector_bsearch3(
|
||||
unsigned int *at_pos, git_vector *v, git_vector_cmp cmp, const void *key);
|
||||
|
||||
void git_vector_sort(git_vector *v);
|
||||
GIT_INLINE(int) git_vector_bsearch(git_vector *v, const void *key)
|
||||
{
|
||||
return git_vector_bsearch3(NULL, v, v->_cmp, key);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_vector_bsearch2(
|
||||
git_vector *v, git_vector_cmp cmp, const void *key)
|
||||
{
|
||||
return git_vector_bsearch3(NULL, v, cmp, key);
|
||||
}
|
||||
|
||||
GIT_INLINE(void *) git_vector_get(git_vector *v, unsigned int position)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define INCLUDE_posix__w32_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "fnmatch.h"
|
||||
#include "compat/fnmatch.h"
|
||||
#include "utf-conv.h"
|
||||
|
||||
GIT_INLINE(int) p_link(const char *old, const char *new)
|
||||
|
@ -32,19 +32,16 @@ void gitwin_set_utf8(void)
|
||||
wchar_t* gitwin_to_utf16(const char* str)
|
||||
{
|
||||
wchar_t* ret;
|
||||
size_t cb;
|
||||
int cb;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
cb = strlen(str) * sizeof(wchar_t);
|
||||
cb = MultiByteToWideChar(_active_codepage, 0, str, -1, NULL, 0);
|
||||
if (cb == 0)
|
||||
return (wchar_t *)git__calloc(1, sizeof(wchar_t));
|
||||
|
||||
/* Add space for null terminator */
|
||||
cb += sizeof(wchar_t);
|
||||
|
||||
ret = (wchar_t *)git__malloc(cb);
|
||||
ret = (wchar_t *)git__malloc(cb * sizeof(wchar_t));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
@ -59,7 +56,8 @@ wchar_t* gitwin_to_utf16(const char* str)
|
||||
|
||||
int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len)
|
||||
{
|
||||
int result = MultiByteToWideChar(_active_codepage, 0, str, -1, buffer, (int)len);
|
||||
int result = MultiByteToWideChar(
|
||||
_active_codepage, 0, str, -1, buffer, (int)len);
|
||||
if (result == 0)
|
||||
giterr_set(GITERR_OS, "Could not convert string to UTF-16");
|
||||
return result;
|
||||
@ -68,23 +66,22 @@ int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len)
|
||||
char* gitwin_from_utf16(const wchar_t* str)
|
||||
{
|
||||
char* ret;
|
||||
size_t cb;
|
||||
int cb;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
cb = wcslen(str) * sizeof(char);
|
||||
cb = WideCharToMultiByte(_active_codepage, 0, str, -1, NULL, 0, NULL, NULL);
|
||||
if (cb == 0)
|
||||
return (char *)git__calloc(1, sizeof(char));
|
||||
|
||||
/* Add space for null terminator */
|
||||
cb += sizeof(char);
|
||||
|
||||
ret = (char*)git__malloc(cb);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (WideCharToMultiByte(_active_codepage, 0, str, -1, ret, (int)cb, NULL, NULL) == 0) {
|
||||
if (WideCharToMultiByte(
|
||||
_active_codepage, 0, str, -1, ret, (int)cb, NULL, NULL) == 0)
|
||||
{
|
||||
giterr_set(GITERR_OS, "Could not convert string to UTF-8");
|
||||
git__free(ret);
|
||||
ret = NULL;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user