Commit 56a5000d by Ben Straub

Merge branch 'development' into rev-parse

Conflicts:
	src/util.h
	tests-clar/refs/branches/listall.c
parents e267c9fc 01dbe273
......@@ -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
......@@ -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;
if (p_stat(filename, &st) < 0)
return GIT_ENOTFOUND;
error = git_futils_readbuffer(&content, filename);
*data = error ? NULL : git_buf_detach(&content);
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;
......@@ -48,10 +49,20 @@ typedef struct {
} 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);
......
......@@ -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;
......
......@@ -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);
}
......@@ -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"
......
......@@ -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);
......
......@@ -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(
......
......@@ -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)
......
......@@ -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);
return GIT_ENOTFOUND;
#endif
}
int git_futils_find_global_file(git_buf *path, const char *filename)
{
#ifdef GIT_WIN32
return win32_find_system_file(path, filename);
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);
......
......@@ -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;
......
......@@ -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
......
......@@ -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(&notes_ref, repo) < 0)
if (normalize_namespace(&notes_ref, repo) < 0)
return -1;
error = git_reference_lookup(&ref, repo, notes_ref);
if (error < 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)
if ((error = retrieve_note_tree_oid(&sha, repo, notes_ref)) < 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(&notes_ref, repo) < 0)
if (normalize_namespace(&notes_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(&notes_ref, repo) < 0)
if (normalize_namespace(&notes_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(&note_data.annotated_object_oid, buf.ptr) < 0)
return -1;
git_oid_cpy(&note_data.blob_oid, note_oid);
error = note_cb(&note_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(&notes_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;
}
......@@ -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;
......
......@@ -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 && git_oid_cmp(&full_oid, &found_full_oid))
return git_odb__error_ambiguous("multiple matches for prefix");
found_full_oid = full_oid;
found = true;
}
}
if (found == 0)
if (!found)
return git_odb__error_notfound("no match for prefix", short_id);
if (found > 1)
return git_odb__error_ambiguous("multiple matches for prefix");
*out = git_cache_try_store(&db->cache, new_odb_object(&full_oid, &raw));
*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;
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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)
......
......@@ -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)
{
struct status_entry *e = git__calloc(sizeof(*e) + strlen(path) + 1, 1);
if (e == NULL)
return NULL;
if (entries != NULL)
git_vector_insert(entries, e);
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)
static int get_one_status(const char *path, unsigned int status, void *data)
{
/* don't ignore files that exist in head or index already */
return (e->status_flags == GIT_STATUS_WT_NEW);
}
struct status_file_info *sfi = data;
static int status_entry_update_ignore(struct status_entry *e, git_ignores *ignores, const char *path)
{
int ignored;
sfi->count++;
sfi->status = status;
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)
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);
memset(&sfi, 0, sizeof(sfi));
if ((sfi.expected = git__strdup(path)) == NULL)
return -1;
}
e = status_entry_new(NULL, path);
GITERR_CHECK_ALLOC(e);
/* 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;
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;
if ((error = git_ignore__for_path(repo, path, &ignores)) == 0)
error = status_entry_update_ignore(e, &ignores, path);
error = git_status_foreach_ext(repo, &opts, get_one_status, &sfi);
git_ignore__free(&ignores);
if (!error && !sfi.count) {
giterr_set(GITERR_INVALID,
"Attempt to get status of nonexistent file '%s'", path);
error = GIT_ENOTFOUND;
}
if (!error)
*status_flags = e->status_flags;
*status_flags = sfi.status;
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;
......
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment