summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2013-04-22 16:41:56 +0200
committerVicent Marti <tanoku@gmail.com>2013-04-22 16:41:56 +0200
commit0edad3cc0451a42b566d70f64611acc214a03022 (patch)
tree9a7c4c7e7ab0be366df168b7f1750f58b8bd86ae
parent4ef2c79cb6dc81e17b68ccf7c270bcc7e4f85bfb (diff)
parentf063a75882769cb6fc652de425ac16ba4b88b616 (diff)
downloadlibgit2-vmg/dupe-odb-backends.tar.gz
Merge branch 'development' into vmg/dupe-odb-backendsvmg/dupe-odb-backends
Conflicts: src/odb.c
-rw-r--r--.mailmap11
-rw-r--r--README.md11
-rw-r--r--include/git2/commit.h88
-rw-r--r--include/git2/config.h52
-rw-r--r--include/git2/indexer.h22
-rw-r--r--include/git2/odb.h97
-rw-r--r--include/git2/odb_backend.h123
-rw-r--r--include/git2/refdb.h35
-rw-r--r--include/git2/remote.h3
-rw-r--r--include/git2/repository.h62
-rw-r--r--include/git2/sys/commit.h45
-rw-r--r--include/git2/sys/config.h71
-rw-r--r--include/git2/sys/odb_backend.h86
-rw-r--r--include/git2/sys/refdb_backend.h (renamed from include/git2/refdb_backend.h)55
-rw-r--r--include/git2/sys/refs.h38
-rw-r--r--include/git2/sys/repository.h92
-rw-r--r--include/git2/types.h20
-rw-r--r--src/blob.c1
-rw-r--r--src/branch.c2
-rw-r--r--src/commit.c87
-rw-r--r--src/config.c1
-rw-r--r--src/config_file.c1
-rw-r--r--src/index.c2
-rw-r--r--src/iterator.c521
-rw-r--r--src/iterator.h11
-rw-r--r--src/odb.c22
-rw-r--r--src/odb_loose.c2
-rw-r--r--src/odb_pack.c3
-rw-r--r--src/refdb.c44
-rw-r--r--src/refdb.h2
-rw-r--r--src/refdb_fs.c42
-rw-r--r--src/refs.c72
-rw-r--r--src/repository.c7
-rw-r--r--src/revparse.c2
-rw-r--r--src/submodule.c1
-rw-r--r--src/tag.c1
-rw-r--r--src/transports/smart_protocol.c1
-rw-r--r--src/unix/posix.h2
-rw-r--r--src/util.h2
-rw-r--r--tests-clar/config/backend.c1
-rw-r--r--tests-clar/diff/patch.c2
-rw-r--r--tests-clar/object/raw/write.c3
-rw-r--r--tests-clar/odb/packed_one.c3
-rw-r--r--tests-clar/odb/sorting.c18
-rw-r--r--tests-clar/refdb/inmemory.c66
-rw-r--r--tests-clar/refdb/testdb.c59
-rw-r--r--tests-clar/refdb/testdb.h6
-rw-r--r--tests-clar/refs/delete.c1
-rw-r--r--tests-clar/refs/pack.c1
-rw-r--r--tests-clar/refs/rename.c1
-rw-r--r--tests-clar/repo/iterator.c172
-rw-r--r--tests-clar/repo/setters.c2
-rw-r--r--tests-clar/stash/drop.c4
-rw-r--r--tests-clar/status/worktree_init.c6
54 files changed, 1252 insertions, 833 deletions
diff --git a/.mailmap b/.mailmap
index a8b171908..3f5a087ea 100644
--- a/.mailmap
+++ b/.mailmap
@@ -5,3 +5,14 @@ Ben Straub <bs@github.com> Ben Straub <ben@straubnet.net>
Ben Straub <bs@github.com> Ben Straub <bstraub@github.com>
Carlos Martín Nieto <cmn@dwim.me> <carlos@cmartin.tk>
Carlos Martín Nieto <cmn@dwim.me> <cmn@elego.de>
+nulltoken <emeric.fermas@gmail.com> <emeric.fermas@gmail.com>
+Scott J. Goldman <scottjg@github.com> <scottjgo@gmail.com>
+Martin Woodward <martin.woodward@microsoft.com> <martinwo@microsoft.com>
+Peter Drahoš <drahosp@gmail.com> <drahosp@gmail.com>
+Adam Roben <adam@github.com> <adam@roben.org>
+Adam Roben <adam@github.com> <adam@github.com>
+Xavier L. <xavier.l@afrosoft.tk> <xavier.l@afrosoft.ca>
+Xavier L. <xavier.l@afrosoft.tk> <xavier.l@afrosoft.tk>
+Sascha Cunz <sascha@babbelbox.org> <Sascha@BabbelBox.org>
+Authmillenon <authmillenon@googlemail.com> <martin@ucsmail.de>
+Authmillenon <authmillenon@googlemail.com> <authmillenon@googlemail.com>
diff --git a/README.md b/README.md
index fdddc5ca1..a2a18765a 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ release its source code.
* Archives: <http://librelist.com/browser/libgit2/>
* Website: <http://libgit2.github.com>
* API documentation: <http://libgit2.github.com/libgit2>
+* IRC: #libgit2 on irc.freenode.net.
What It Can Do
==================================
@@ -155,15 +156,7 @@ we can add it to the list.
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. 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:
-
-libgit2@librelist.com
+Check the [contribution guidelines](CONTRIBUTING.md).
License
diff --git a/include/git2/commit.h b/include/git2/commit.h
index 764053eaa..0f7601252 100644
--- a/include/git2/commit.h
+++ b/include/git2/commit.h
@@ -201,14 +201,12 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
unsigned int n);
/**
- * Create a new commit in the repository using `git_object`
- * instances as parameters.
+ * Create new commit in the repository from a list of `git_object` pointers
*
- * The message will not be cleaned up. This can be achieved
- * through `git_message_prettify()`.
+ * The message will not be cleaned up automatically. You can do that with
+ * the `git_message_prettify()` function.
*
- * @param id Pointer where to store the OID of the
- * newly created commit
+ * @param id Pointer in which to store the OID of the newly created commit
*
* @param repo Repository where to store the commit
*
@@ -219,73 +217,69 @@ GIT_EXTERN(int) git_commit_nth_gen_ancestor(
* make it point to this commit. If the reference doesn't
* exist yet, it will be created.
*
- * @param author Signature representing the author and the authory
- * time of this commit
+ * @param author Signature with author and author time of commit
*
- * @param committer Signature representing the committer and the
- * commit time of this commit
+ * @param committer Signature with committer and * commit time of commit
*
* @param message_encoding The encoding for the message in the
- * commit, represented with a standard encoding name.
- * E.g. "UTF-8". If NULL, no encoding header is written and
- * UTF-8 is assumed.
+ * commit, represented with a standard encoding name.
+ * E.g. "UTF-8". If NULL, no encoding header is written and
+ * UTF-8 is assumed.
*
* @param message Full message for this commit
*
* @param tree An instance of a `git_tree` object that will
- * be used as the tree for the commit. This tree object must
- * also be owned by the given `repo`.
+ * be used as the tree for the commit. This tree object must
+ * also be owned by the given `repo`.
*
* @param parent_count Number of parents for this commit
*
* @param parents[] Array of `parent_count` pointers to `git_commit`
- * objects that will be used as the parents for this commit. This
- * array may be NULL if `parent_count` is 0 (root commit). All the
- * given commits must be owned by the `repo`.
+ * objects that will be used as the parents for this commit. This
+ * array may be NULL if `parent_count` is 0 (root commit). All the
+ * given commits must be owned by the `repo`.
*
* @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
*/
GIT_EXTERN(int) git_commit_create(
- git_oid *id,
- git_repository *repo,
- const char *update_ref,
- const git_signature *author,
- const git_signature *committer,
- const char *message_encoding,
- const char *message,
- const git_tree *tree,
- int parent_count,
- const git_commit *parents[]);
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ int parent_count,
+ const git_commit *parents[]);
/**
- * Create a new commit in the repository using a variable
- * argument list.
+ * Create new commit in the repository using a variable argument list.
*
- * The message will be cleaned up from excess whitespace
- * it will be made sure that the last line ends with a '\n'.
+ * The message will be cleaned up from excess whitespace and it will be made
+ * sure that the last line ends with a '\n'.
*
- * The parents for the commit are specified as a variable
- * list of pointers to `const git_commit *`. Note that this
- * is a convenience method which may not be safe to export
- * for certain languages or compilers
+ * The parents for the commit are specified as a variable list of pointers
+ * to `const git_commit *`. Note that this is a convenience method which may
+ * not be safe to export for certain languages or compilers
*
- * All other parameters remain the same
+ * All other parameters remain the same at `git_commit_create()`.
*
* @see git_commit_create
*/
GIT_EXTERN(int) git_commit_create_v(
- git_oid *id,
- git_repository *repo,
- const char *update_ref,
- const git_signature *author,
- const git_signature *committer,
- const char *message_encoding,
- const char *message,
- const git_tree *tree,
- int parent_count,
- ...);
+ git_oid *id,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ int parent_count,
+ ...);
/** @} */
GIT_END_DECL
diff --git a/include/git2/config.h b/include/git2/config.h
index 19d4cb78d..5a2f956fd 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -43,29 +43,6 @@ typedef struct {
typedef int (*git_config_foreach_cb)(const git_config_entry *, void *);
-
-/**
- * Generic backend that implements the interface to
- * access a configuration file
- */
-struct git_config_backend {
- unsigned int version;
- struct git_config *cfg;
-
- /* Open means open the file/database and parse if necessary */
- int (*open)(struct git_config_backend *, unsigned int level);
- int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry);
- int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload);
- int (*set)(struct git_config_backend *, const char *key, const char *value);
- int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
- int (*del)(struct git_config_backend *, const char *key);
- int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload);
- int (*refresh)(struct git_config_backend *);
- void (*free)(struct git_config_backend *);
-};
-#define GIT_CONFIG_BACKEND_VERSION 1
-#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION}
-
typedef enum {
GIT_CVAR_FALSE = 0,
GIT_CVAR_TRUE = 1,
@@ -154,30 +131,6 @@ GIT_EXTERN(int) git_config_open_default(git_config **out);
GIT_EXTERN(int) git_config_new(git_config **out);
/**
- * Add a generic config file instance to an existing config
- *
- * Note that the configuration object will free the file
- * automatically.
- *
- * Further queries on this config object will access each
- * of the config file instances in order (instances with
- * a higher priority level will be accessed first).
- *
- * @param cfg the configuration to add the file to
- * @param file the configuration file (backend) to add
- * @param level the priority level of the backend
- * @param force if a config file already exists for the given
- * priority level, replace it
- * @return 0 on success, GIT_EEXISTS when adding more than one file
- * for a given priority level (and force_replace set to 0), or error code
- */
-GIT_EXTERN(int) git_config_add_backend(
- git_config *cfg,
- git_config_backend *file,
- unsigned int level,
- int force);
-
-/**
* Add an on-disk config file instance to an existing config
*
* The on-disk file pointed at by `path` will be opened and
@@ -192,10 +145,9 @@ GIT_EXTERN(int) git_config_add_backend(
* a higher priority level will be accessed first).
*
* @param cfg the configuration to add the file to
- * @param path path to the configuration file (backend) to add
+ * @param path path to the configuration file to add
* @param level the priority level of the backend
- * @param force if a config file already exists for the given
- * priority level, replace it
+ * @param force replace config file at the given priority level
* @return 0 on success, GIT_EEXISTS when adding more than one file
* for a given priority level (and force_replace set to 0),
* GIT_ENOTFOUND when the file doesn't exist or error code
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
index dfe6ae5aa..262dcd154 100644
--- a/include/git2/indexer.h
+++ b/include/git2/indexer.h
@@ -8,31 +8,11 @@
#define _INCLUDE_git_indexer_h__
#include "common.h"
+#include "types.h"
#include "oid.h"
GIT_BEGIN_DECL
-/**
- * This is passed as the first argument to the callback to allow the
- * user to see the progress.
- */
-typedef struct git_transfer_progress {
- unsigned int total_objects;
- unsigned int indexed_objects;
- unsigned int received_objects;
- size_t received_bytes;
-} git_transfer_progress;
-
-
-/**
- * Type for progress callbacks during indexing. Return a value less than zero
- * to cancel the transfer.
- *
- * @param stats Structure containing information about the state of the transfer
- * @param payload Payload provided by caller
- */
-typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload);
-
typedef struct git_indexer_stream git_indexer_stream;
/**
diff --git a/include/git2/odb.h b/include/git2/odb.h
index 8fd1a95be..b64436c4d 100644
--- a/include/git2/odb.h
+++ b/include/git2/odb.h
@@ -10,8 +10,6 @@
#include "common.h"
#include "types.h"
#include "oid.h"
-#include "odb_backend.h"
-#include "indexer.h"
/**
* @file git2/odb.h
@@ -23,6 +21,11 @@
GIT_BEGIN_DECL
/**
+ * Function type for callbacks from git_odb_foreach.
+ */
+typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload);
+
+/**
* Create a new object database with no backends.
*
* Before the ODB can be used for read/writing, a custom database
@@ -53,42 +56,6 @@ GIT_EXTERN(int) git_odb_new(git_odb **out);
GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
/**
- * Add a custom backend to an existing Object DB
- *
- * The backends are checked in relative ordering, based on the
- * value of the `priority` parameter.
- *
- * Read <odb_backends.h> for more information.
- *
- * @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 success; error code otherwise
- */
-GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
-
-/**
- * Add a custom backend to an existing Object DB; this
- * backend will work as an alternate.
- *
- * Alternate backends are always checked for objects *after*
- * all the main backends have been exhausted.
- *
- * The backends are checked in relative ordering, based on the
- * value of the `priority` parameter.
- *
- * Writing is disabled on alternate backends.
- *
- * Read <odb_backends.h> for more information.
- *
- * @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 success; error code otherwise
- */
-GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
-
-/**
* Add an on-disk alternate to an existing Object DB.
*
* Note that the added path must point to an `objects`, not
@@ -406,6 +373,60 @@ GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object);
*/
GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object);
+/**
+ * Add a custom backend to an existing Object DB
+ *
+ * The backends are checked in relative ordering, based on the
+ * value of the `priority` parameter.
+ *
+ * Read <odb_backends.h> for more information.
+ *
+ * @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 success; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority);
+
+/**
+ * Add a custom backend to an existing Object DB; this
+ * backend will work as an alternate.
+ *
+ * Alternate backends are always checked for objects *after*
+ * all the main backends have been exhausted.
+ *
+ * The backends are checked in relative ordering, based on the
+ * value of the `priority` parameter.
+ *
+ * Writing is disabled on alternate backends.
+ *
+ * Read <odb_backends.h> for more information.
+ *
+ * @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 success; error code otherwise
+ */
+GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority);
+
+/**
+ * Get the number of ODB backend objects
+ *
+ * @param odb object database
+ * @return number of backends in the ODB
+ */
+GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb);
+
+/**
+ * Lookup an ODB backend object by index
+ *
+ * @param out output pointer to ODB backend at pos
+ * @param odb object database
+ * @param pos index into object database backend list
+ * @return 0 on success; GIT_ENOTFOUND if pos is invalid; other errors < 0
+ */
+GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
index dbc3981f6..d38005d15 100644
--- a/include/git2/odb_backend.h
+++ b/include/git2/odb_backend.h
@@ -7,106 +7,24 @@
#ifndef INCLUDE_git_odb_backend_h__
#define INCLUDE_git_odb_backend_h__
-#include "common.h"
-#include "types.h"
-#include "oid.h"
-#include "indexer.h"
+#include "git2/common.h"
+#include "git2/types.h"
/**
* @file git2/backend.h
* @brief Git custom backend functions
- * @defgroup git_backend Git custom backend API
+ * @defgroup git_odb Git object database routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
-struct git_odb_stream;
-struct git_odb_writepack;
-
-/**
- * Function type for callbacks from git_odb_foreach.
- */
-typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload);
-
/**
- * An instance for a custom backend
+ * Constructors for in-box ODB backends.
*/
-struct git_odb_backend {
- unsigned int version;
- git_odb *odb;
-
- /* read and read_prefix each return to libgit2 a buffer which
- * will be freed later. The buffer should be allocated using
- * the function git_odb_backend_malloc to ensure that it can
- * be safely freed later. */
- int (* read)(
- void **, size_t *, git_otype *,
- struct git_odb_backend *,
- const git_oid *);
-
- /* To find a unique object given a prefix
- * of its oid.
- * The oid given must be so that the
- * remaining (GIT_OID_HEXSZ - len)*4 bits
- * are 0s.
- */
- int (* read_prefix)(
- git_oid *,
- void **, size_t *, git_otype *,
- struct git_odb_backend *,
- const git_oid *,
- size_t);
-
- int (* read_header)(
- size_t *, git_otype *,
- struct git_odb_backend *,
- const git_oid *);
-
- /* The writer may assume that the object
- * has already been hashed and is passed
- * in the first parameter.
- */
- int (* write)(
- git_oid *,
- struct git_odb_backend *,
- const void *,
- size_t,
- git_otype);
-
- int (* writestream)(
- struct git_odb_stream **,
- struct git_odb_backend *,
- size_t,
- git_otype);
-
- int (* readstream)(
- struct git_odb_stream **,
- struct git_odb_backend *,
- const git_oid *);
-
- int (* exists)(
- struct git_odb_backend *,
- const git_oid *);
-
- int (* refresh)(struct git_odb_backend *);
-
- int (* foreach)(
- struct git_odb_backend *,
- git_odb_foreach_cb cb,
- void *payload);
-
- int (* writepack)(
- struct git_odb_writepack **,
- struct git_odb_backend *,
- git_transfer_progress_callback progress_cb,
- void *progress_payload);
-
- void (* free)(struct git_odb_backend *);
-};
-
-#define GIT_ODB_BACKEND_VERSION 1
-#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir);
+GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync);
+GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file);
/** Streaming mode */
enum {
@@ -117,33 +35,24 @@ enum {
/** A stream to read/write from a backend */
struct git_odb_stream {
- struct git_odb_backend *backend;
+ git_odb_backend *backend;
unsigned int mode;
- int (*read)(struct git_odb_stream *stream, char *buffer, size_t len);
- int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len);
- int (*finalize_write)(git_oid *oid_p, struct git_odb_stream *stream);
- void (*free)(struct git_odb_stream *stream);
+ int (*read)(git_odb_stream *stream, char *buffer, size_t len);
+ int (*write)(git_odb_stream *stream, const char *buffer, size_t len);
+ int (*finalize_write)(git_oid *oid_p, git_odb_stream *stream);
+ void (*free)(git_odb_stream *stream);
};
/** A stream to write a pack file to the ODB */
struct git_odb_writepack {
- struct git_odb_backend *backend;
+ git_odb_backend *backend;
- int (*add)(struct git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
- int (*commit)(struct git_odb_writepack *writepack, git_transfer_progress *stats);
- void (*free)(struct git_odb_writepack *writepack);
+ int (*add)(git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats);
+ int (*commit)(git_odb_writepack *writepack, git_transfer_progress *stats);
+ void (*free)(git_odb_writepack *writepack);
};
-GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
-
-/**
- * Constructors for in-box ODB backends.
- */
-GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir);
-GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync);
-GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file);
-
GIT_END_DECL
#endif
diff --git a/include/git2/refdb.h b/include/git2/refdb.h
index 76b8fda0d..a315876ae 100644
--- a/include/git2/refdb.h
+++ b/include/git2/refdb.h
@@ -22,27 +22,6 @@
GIT_BEGIN_DECL
/**
- * Create a new reference. Either an oid or a symbolic target must be
- * specified.
- *
- * @param refdb the reference database to associate with this reference
- * @param name the reference name
- * @param oid the object id for a direct reference
- * @param symbolic the target for a symbolic reference
- * @return the created git_reference or NULL on error
- */
-GIT_EXTERN(git_reference *) git_reference__alloc(
- git_refdb *refdb,
- const char *name,
- const git_oid *oid,
- const git_oid *peel);
-
-GIT_EXTERN(git_reference *) git_reference__alloc_symbolic(
- git_refdb *refdb,
- const char *name,
- const char *target);
-
-/**
* Create a new reference database with no backends.
*
* Before the Ref DB can be used for read/writing, a custom database
@@ -83,20 +62,6 @@ GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb);
*/
GIT_EXTERN(void) git_refdb_free(git_refdb *refdb);
-/**
- * Sets the custom backend to an existing reference DB
- *
- * Read <refdb_backends.h> for more information.
- *
- * @param refdb database to add the backend to
- * @param backend pointer to a git_refdb_backend instance
- * @param priority Value for ordering the backends queue
- * @return 0 on success; error code otherwise
- */
-GIT_EXTERN(int) git_refdb_set_backend(
- git_refdb *refdb,
- git_refdb_backend *backend);
-
/** @} */
GIT_END_DECL
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 6f36a3999..9494a8b01 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -184,7 +184,8 @@ GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote);
* starts up a specific binary which can only do the one or the other.
*
* @param remote the remote to connect to
- * @param direction whether you want to receive or send data
+ * @param direction GIT_DIRECTION_FETCH if you want to fetch or
+ * GIT_DIRECTION_PUSH if you want to push
* @return 0 or an error code
*/
GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction);
diff --git a/include/git2/repository.h b/include/git2/repository.h
index ed837b359..08024cd89 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -401,21 +401,6 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo);
/**
- * Set the configuration file for this repository
- *
- * This configuration file will be used for all configuration
- * queries involving this repository.
- *
- * The repository will keep a reference to the config file;
- * the user must still free the config after setting it
- * to the repository, or it will leak.
- *
- * @param repo A repository object
- * @param config A Config object
- */
-GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config);
-
-/**
* Get the Object Database for this repository.
*
* If a custom ODB has not been set, the default
@@ -432,21 +417,6 @@ GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *con
GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo);
/**
- * Set the Object Database for this repository
- *
- * The ODB will be used for all object-related operations
- * involving this repository.
- *
- * The repository will keep a reference to the ODB; the user
- * must still free the ODB object after setting it to the
- * repository, or it will leak.
- *
- * @param repo A repository object
- * @param odb An ODB object
- */
-GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
-
-/**
* Get the Reference Database Backend for this repository.
*
* If a custom refsdb has not been set, the default database for
@@ -463,23 +433,6 @@ GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
GIT_EXTERN(int) git_repository_refdb(git_refdb **out, git_repository *repo);
/**
- * Set the Reference Database Backend for this repository
- *
- * The refdb will be used for all reference related operations
- * involving this repository.
- *
- * The repository will keep a reference to the refdb; the user
- * must still free the refdb object after setting it to the
- * repository, or it will leak.
- *
- * @param repo A repository object
- * @param refdb An refdb object
- */
-GIT_EXTERN(void) git_repository_set_refdb(
- git_repository *repo,
- git_refdb *refdb);
-
-/**
* Get the Index file for this repository.
*
* If a custom index has not been set, the default
@@ -496,21 +449,6 @@ GIT_EXTERN(void) git_repository_set_refdb(
GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
/**
- * Set the index file for this repository
- *
- * This index will be used for all index-related operations
- * involving this repository.
- *
- * The repository will keep a reference to the index file;
- * the user must still free the index after setting it
- * to the repository, or it will leak.
- *
- * @param repo A repository object
- * @param index An index object
- */
-GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
-
-/**
* Retrieve git's prepared message
*
* Operations such as git revert/cherry-pick/merge with the -n option
diff --git a/include/git2/sys/commit.h b/include/git2/sys/commit.h
new file mode 100644
index 000000000..096e028c5
--- /dev/null
+++ b/include/git2/sys/commit.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_commit_h__
+#define INCLUDE_sys_git_commit_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * @file git2/sys/commit.h
+ * @brief Low-level Git commit creation
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create new commit in the repository from a list of `git_oid` values
+ *
+ * See documentation for `git_commit_create()` for information about the
+ * parameters, as the meaning is identical excepting that `tree` and
+ * `parents` now take `git_oid`. This is a dangerous API in that the
+ * `parents` list of `git_oid`s in not checked for validity.
+ */
+GIT_EXTERN(int) git_commit_create_from_oids(
+ git_oid *oid,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_oid *tree,
+ int parent_count,
+ const git_oid *parents[]);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h
new file mode 100644
index 000000000..1c9deba7c
--- /dev/null
+++ b/include/git2/sys/config.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_config_backend_h__
+#define INCLUDE_sys_git_config_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/config.h"
+
+/**
+ * @file git2/sys/config.h
+ * @brief Git config backend routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Generic backend that implements the interface to
+ * access a configuration file
+ */
+struct git_config_backend {
+ unsigned int version;
+ struct git_config *cfg;
+
+ /* Open means open the file/database and parse if necessary */
+ int (*open)(struct git_config_backend *, unsigned int level);
+ int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry);
+ int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload);
+ int (*set)(struct git_config_backend *, const char *key, const char *value);
+ int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
+ int (*del)(struct git_config_backend *, const char *key);
+ int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload);
+ int (*refresh)(struct git_config_backend *);
+ void (*free)(struct git_config_backend *);
+};
+#define GIT_CONFIG_BACKEND_VERSION 1
+#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION}
+
+/**
+ * Add a generic config file instance to an existing config
+ *
+ * Note that the configuration object will free the file
+ * automatically.
+ *
+ * Further queries on this config object will access each
+ * of the config file instances in order (instances with
+ * a higher priority level will be accessed first).
+ *
+ * @param cfg the configuration to add the file to
+ * @param file the configuration file (backend) to add
+ * @param level the priority level of the backend
+ * @param force if a config file already exists for the given
+ * priority level, replace it
+ * @return 0 on success, GIT_EEXISTS when adding more than one file
+ * for a given priority level (and force_replace set to 0), or error code
+ */
+GIT_EXTERN(int) git_config_add_backend(
+ git_config *cfg,
+ git_config_backend *file,
+ unsigned int level,
+ int force);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h
new file mode 100644
index 000000000..3cd2734c0
--- /dev/null
+++ b/include/git2/sys/odb_backend.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_odb_backend_h__
+#define INCLUDE_sys_git_odb_backend_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+#include "git2/odb.h"
+
+/**
+ * @file git2/sys/backend.h
+ * @brief Git custom backend implementors functions
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * An instance for a custom backend
+ */
+struct git_odb_backend {
+ unsigned int version;
+ git_odb *odb;
+
+ /* read and read_prefix each return to libgit2 a buffer which
+ * will be freed later. The buffer should be allocated using
+ * the function git_odb_backend_malloc to ensure that it can
+ * be safely freed later. */
+ int (* read)(
+ void **, size_t *, git_otype *, git_odb_backend *, const git_oid *);
+
+ /* To find a unique object given a prefix
+ * of its oid.
+ * The oid given must be so that the
+ * remaining (GIT_OID_HEXSZ - len)*4 bits
+ * are 0s.
+ */
+ int (* read_prefix)(
+ git_oid *, void **, size_t *, git_otype *,
+ git_odb_backend *, const git_oid *, size_t);
+
+ int (* read_header)(
+ size_t *, git_otype *, git_odb_backend *, const git_oid *);
+
+ /* The writer may assume that the object
+ * has already been hashed and is passed
+ * in the first parameter.
+ */
+ int (* write)(
+ git_oid *, git_odb_backend *, const void *, size_t, git_otype);
+
+ int (* writestream)(
+ git_odb_stream **, git_odb_backend *, size_t, git_otype);
+
+ int (* readstream)(
+ git_odb_stream **, git_odb_backend *, const git_oid *);
+
+ int (* exists)(
+ git_odb_backend *, const git_oid *);
+
+ int (* refresh)(git_odb_backend *);
+
+ int (* foreach)(
+ git_odb_backend *, git_odb_foreach_cb cb, void *payload);
+
+ int (* writepack)(
+ git_odb_writepack **, git_odb_backend *,
+ git_transfer_progress_callback progress_cb, void *progress_payload);
+
+ void (* free)(git_odb_backend *);
+};
+
+#define GIT_ODB_BACKEND_VERSION 1
+#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
+
+GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
+
+GIT_END_DECL
+
+#endif
diff --git a/include/git2/refdb_backend.h b/include/git2/sys/refdb_backend.h
index bf33817d6..d5f599fec 100644
--- a/include/git2/refdb_backend.h
+++ b/include/git2/sys/refdb_backend.h
@@ -4,12 +4,12 @@
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
-#ifndef INCLUDE_git_refdb_backend_h__
-#define INCLUDE_git_refdb_backend_h__
+#ifndef INCLUDE_sys_git_refdb_backend_h__
+#define INCLUDE_sys_git_refdb_backend_h__
-#include "common.h"
-#include "types.h"
-#include "oid.h"
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
/**
* @file git2/refdb_backend.h
@@ -30,7 +30,7 @@ struct git_refdb_backend {
*/
int (*exists)(
int *exists,
- struct git_refdb_backend *backend,
+ git_refdb_backend *backend,
const char *ref_name);
/**
@@ -39,7 +39,7 @@ struct git_refdb_backend {
*/
int (*lookup)(
git_reference **out,
- struct git_refdb_backend *backend,
+ git_refdb_backend *backend,
const char *ref_name);
/**
@@ -47,7 +47,7 @@ struct git_refdb_backend {
* provide this function.
*/
int (*foreach)(
- struct git_refdb_backend *backend,
+ git_refdb_backend *backend,
unsigned int list_flags,
git_reference_foreach_cb callback,
void *payload);
@@ -59,7 +59,7 @@ struct git_refdb_backend {
* against the glob.
*/
int (*foreach_glob)(
- struct git_refdb_backend *backend,
+ git_refdb_backend *backend,
const char *glob,
unsigned int list_flags,
git_reference_foreach_cb callback,
@@ -69,13 +69,13 @@ struct git_refdb_backend {
* Writes the given reference to the refdb. A refdb implementation
* must provide this function.
*/
- int (*write)(struct git_refdb_backend *backend, const git_reference *ref);
+ int (*write)(git_refdb_backend *backend, const git_reference *ref);
/**
* Deletes the given reference from the refdb. A refdb implementation
* must provide this function.
*/
- int (*delete)(struct git_refdb_backend *backend, const git_reference *ref);
+ int (*delete)(git_refdb_backend *backend, const git_reference *ref);
/**
* Suggests that the given refdb compress or optimize its references.
@@ -84,25 +84,46 @@ struct git_refdb_backend {
* implementation may provide this function; if it is not provided,
* nothing will be done.
*/
- int (*compress)(struct git_refdb_backend *backend);
+ int (*compress)(git_refdb_backend *backend);
/**
* Frees any resources held by the refdb. A refdb implementation may
* provide this function; if it is not provided, nothing will be done.
*/
- void (*free)(struct git_refdb_backend *backend);
+ void (*free)(git_refdb_backend *backend);
};
#define GIT_ODB_BACKEND_VERSION 1
#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
/**
- * Constructors for default refdb backends.
+ * Constructors for default filesystem-based refdb backend
+ *
+ * Under normal usage, this is called for you when the repository is
+ * opened / created, but you can use this to explicitly construct a
+ * filesystem refdb backend for a repository.
+ *
+ * @param backend_out Output pointer to the git_refdb_backend object
+ * @param repo Git repository to access
+ * @return 0 on success, <0 error code on failure
*/
GIT_EXTERN(int) git_refdb_backend_fs(
- struct git_refdb_backend **backend_out,
- git_repository *repo,
- git_refdb *refdb);
+ git_refdb_backend **backend_out,
+ git_repository *repo);
+
+/**
+ * Sets the custom backend to an existing reference DB
+ *
+ * The `git_refdb` will take ownership of the `git_refdb_backend` so you
+ * should NOT free it after calling this function.
+ *
+ * @param refdb database to add the backend to
+ * @param backend pointer to a git_refdb_backend instance
+ * @return 0 on success; error code otherwise
+ */
+GIT_EXTERN(int) git_refdb_set_backend(
+ git_refdb *refdb,
+ git_refdb_backend *backend);
GIT_END_DECL
diff --git a/include/git2/sys/refs.h b/include/git2/sys/refs.h
new file mode 100644
index 000000000..85963258c
--- /dev/null
+++ b/include/git2/sys/refs.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_refdb_h__
+#define INCLUDE_sys_git_refdb_h__
+
+#include "git2/common.h"
+#include "git2/types.h"
+#include "git2/oid.h"
+
+/**
+ * Create a new direct reference from an OID.
+ *
+ * @param name the reference name
+ * @param oid the object id for a direct reference
+ * @param symbolic the target for a symbolic reference
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc(
+ const char *name,
+ const git_oid *oid,
+ const git_oid *peel);
+
+/**
+ * Create a new symbolic reference.
+ *
+ * @param name the reference name
+ * @param symbolic the target for a symbolic reference
+ * @return the created git_reference or NULL on error
+ */
+GIT_EXTERN(git_reference *) git_reference__alloc_symbolic(
+ const char *name,
+ const char *target);
+
+#endif
diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h
new file mode 100644
index 000000000..34bc17516
--- /dev/null
+++ b/include/git2/sys/repository.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_sys_git_repository_h__
+#define INCLUDE_sys_git_repository_h__
+
+/**
+ * @file git2/sys/repository.h
+ * @brief Git repository custom implementation routines
+ * @defgroup git_backend Git custom backend APIs
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+/**
+ * Create a new repository with neither backends nor config object
+ *
+ * Note that this is only useful if you wish to associate the repository
+ * with a non-filesystem-backed object database and config store.
+ *
+ * @param out The blank repository
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_new(git_repository **out);
+
+/**
+ * Set the configuration file for this repository
+ *
+ * This configuration file will be used for all configuration
+ * queries involving this repository.
+ *
+ * The repository will keep a reference to the config file;
+ * the user must still free the config after setting it
+ * to the repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param config A Config object
+ */
+GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config);
+
+/**
+ * Set the Object Database for this repository
+ *
+ * The ODB will be used for all object-related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the ODB; the user
+ * must still free the ODB object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param odb An ODB object
+ */
+GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb);
+
+/**
+ * Set the Reference Database Backend for this repository
+ *
+ * The refdb will be used for all reference related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the refdb; the user
+ * must still free the refdb object after setting it to the
+ * repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param refdb An refdb object
+ */
+GIT_EXTERN(void) git_repository_set_refdb(git_repository *repo, git_refdb *refdb);
+
+/**
+ * Set the index file for this repository
+ *
+ * This index will be used for all index-related operations
+ * involving this repository.
+ *
+ * The repository will keep a reference to the index file;
+ * the user must still free the index after setting it
+ * to the repository, or it will leak.
+ *
+ * @param repo A repository object
+ * @param index An index object
+ */
+GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
+
+/** @} */
+GIT_END_DECL
+#endif
diff --git a/include/git2/types.h b/include/git2/types.h
index bc15050ce..aca9ed927 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -196,6 +196,26 @@ typedef struct git_push git_push;
typedef struct git_remote_head git_remote_head;
typedef struct git_remote_callbacks git_remote_callbacks;
+/**
+ * This is passed as the first argument to the callback to allow the
+ * user to see the progress.
+ */
+typedef struct git_transfer_progress {
+ unsigned int total_objects;
+ unsigned int indexed_objects;
+ unsigned int received_objects;
+ size_t received_bytes;
+} git_transfer_progress;
+
+/**
+ * Type for progress callbacks during indexing. Return a value less than zero
+ * to cancel the transfer.
+ *
+ * @param stats Structure containing information about the state of the transfer
+ * @param payload Payload provided by caller
+ */
+typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload);
+
/** @} */
GIT_END_DECL
diff --git a/src/blob.c b/src/blob.c
index c0514fc13..11e1f4d77 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -8,6 +8,7 @@
#include "git2/common.h"
#include "git2/object.h"
#include "git2/repository.h"
+#include "git2/odb_backend.h"
#include "common.h"
#include "blob.h"
diff --git a/src/branch.c b/src/branch.c
index e7088790e..956286b74 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -377,7 +377,7 @@ int git_branch_remote_name(char *buffer, size_t buffer_len, git_repository *repo
if (buffer)
git_buf_copy_cstr(buffer, buffer_len, &buf);
- ret = git_buf_len(&buf) + 1;
+ ret = (int)git_buf_len(&buf) + 1;
git_buf_free(&buf);
return ret;
diff --git a/src/commit.c b/src/commit.c
index c7b83ed43..dd416920d 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -9,6 +9,7 @@
#include "git2/object.h"
#include "git2/repository.h"
#include "git2/signature.h"
+#include "git2/sys/commit.h"
#include "common.h"
#include "odb.h"
@@ -44,16 +45,16 @@ void git_commit__free(git_commit *commit)
}
int git_commit_create_v(
- git_oid *oid,
- git_repository *repo,
- const char *update_ref,
- const git_signature *author,
- const git_signature *committer,
- const char *message_encoding,
- const char *message,
- const git_tree *tree,
- int parent_count,
- ...)
+ git_oid *oid,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ int parent_count,
+ ...)
{
va_list ap;
int i, res;
@@ -76,30 +77,29 @@ int git_commit_create_v(
return res;
}
-int git_commit_create(
- git_oid *oid,
- git_repository *repo,
- const char *update_ref,
- const git_signature *author,
- const git_signature *committer,
- const char *message_encoding,
- const char *message,
- const git_tree *tree,
- int parent_count,
- const git_commit *parents[])
+int git_commit_create_from_oids(
+ git_oid *oid,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_oid *tree,
+ int parent_count,
+ const git_oid *parents[])
{
git_buf commit = GIT_BUF_INIT;
int i;
git_odb *odb;
+ assert(oid && repo && tree && parent_count >= 0);
assert(git_object_owner((const git_object *)tree) == repo);
- git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree));
+ git_oid__writebuf(&commit, "tree ", tree);
- for (i = 0; i < parent_count; ++i) {
- assert(git_object_owner((const git_object *)parents[i]) == repo);
- git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i]));
- }
+ for (i = 0; i < parent_count; ++i)
+ git_oid__writebuf(&commit, "parent ", parents[i]);
git_signature__writebuf(&commit, "author ", author);
git_signature__writebuf(&commit, "committer ", committer);
@@ -131,6 +131,41 @@ on_error:
return -1;
}
+int git_commit_create(
+ git_oid *oid,
+ git_repository *repo,
+ const char *update_ref,
+ const git_signature *author,
+ const git_signature *committer,
+ const char *message_encoding,
+ const char *message,
+ const git_tree *tree,
+ int parent_count,
+ const git_commit *parents[])
+{
+ int retval, i;
+ const git_oid **parent_oids;
+
+ assert(parent_count >= 0);
+
+ parent_oids = git__malloc(parent_count * sizeof(git_oid *));
+ GITERR_CHECK_ALLOC(parent_oids);
+
+ for (i = 0; i < parent_count; ++i) {
+ assert(git_object_owner((const git_object *)parents[i]) == repo);
+ parent_oids[i] = git_object_id((const git_object *)parents[i]);
+ }
+
+ retval = git_commit_create_from_oids(
+ oid, repo, update_ref, author, committer,
+ message_encoding, message,
+ git_object_id((const git_object *)tree), parent_count, parent_oids);
+
+ git__free((void *)parent_oids);
+
+ return retval;
+}
+
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
{
const char *buffer = data;
diff --git a/src/config.c b/src/config.c
index 5379b0ec5..1283522ca 100644
--- a/src/config.c
+++ b/src/config.c
@@ -9,6 +9,7 @@
#include "fileops.h"
#include "config.h"
#include "git2/config.h"
+#include "git2/sys/config.h"
#include "vector.h"
#include "buf_text.h"
#include "config_file.h"
diff --git a/src/config_file.c b/src/config_file.c
index 8b51ab21b..a4ff8bb94 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -12,6 +12,7 @@
#include "buffer.h"
#include "buf_text.h"
#include "git2/config.h"
+#include "git2/sys/config.h"
#include "git2/types.h"
#include "strmap.h"
diff --git a/src/index.c b/src/index.c
index 6290ec4e8..2afd28158 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1345,7 +1345,7 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer
static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
{
unsigned int i;
- struct index_header header;
+ struct index_header header = { 0 };
git_oid checksum_calculated, checksum_expected;
#define seek_forward(_increase) { \
diff --git a/src/iterator.c b/src/iterator.c
index 5b5ed9525..ff08c1ce0 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -26,8 +26,6 @@
(GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_DONT_IGNORE_CASE)
#define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC,REPO) do { \
- (P) = git__calloc(1, sizeof(NAME_LC ## _iterator)); \
- GITERR_CHECK_ALLOC(P); \
(P)->base.type = GIT_ITERATOR_TYPE_ ## NAME_UC; \
(P)->base.cb = &(P)->cb; \
ITERATOR_SET_CB(P,NAME_LC); \
@@ -148,7 +146,8 @@ int git_iterator_for_nothing(
const char *start,
const char *end)
{
- empty_iterator *i;
+ empty_iterator *i = git__calloc(1, sizeof(empty_iterator));
+ GITERR_CHECK_ALLOC(i);
#define empty_iterator__current empty_iterator__noop
#define empty_iterator__advance empty_iterator__noop
@@ -581,6 +580,9 @@ int git_iterator_for_tree(
if ((error = git_object_dup((git_object **)&tree, (git_object *)tree)) < 0)
return error;
+ ti = git__calloc(1, sizeof(tree_iterator));
+ GITERR_CHECK_ALLOC(ti);
+
ITERATOR_BASE_INIT(ti, tree, TREE, git_tree_owner(tree));
if ((error = iterator__update_ignore_case((git_iterator *)ti, flags)) < 0)
@@ -810,7 +812,8 @@ int git_iterator_for_index(
const char *start,
const char *end)
{
- index_iterator *ii;
+ index_iterator *ii = git__calloc(1, sizeof(index_iterator));
+ GITERR_CHECK_ALLOC(ii);
ITERATOR_BASE_INIT(ii, index, INDEX, git_index_owner(index));
@@ -833,237 +836,221 @@ int git_iterator_for_index(
}
-#define WORKDIR_MAX_DEPTH 100
-
-typedef struct workdir_iterator_frame workdir_iterator_frame;
-struct workdir_iterator_frame {
- workdir_iterator_frame *next;
+typedef struct fs_iterator_frame fs_iterator_frame;
+struct fs_iterator_frame {
+ fs_iterator_frame *next;
git_vector entries;
size_t index;
};
-typedef struct {
+typedef struct fs_iterator fs_iterator;
+struct fs_iterator {
git_iterator base;
git_iterator_callbacks cb;
- workdir_iterator_frame *stack;
- git_ignores ignores;
+ fs_iterator_frame *stack;
git_index_entry entry;
git_buf path;
size_t root_len;
- int is_ignored;
int depth;
-} workdir_iterator;
-GIT_INLINE(bool) path_is_dotgit(const git_path_with_stat *ps)
-{
- if (!ps)
- return false;
- else {
- const char *path = ps->path;
- size_t len = ps->path_len;
-
- if (len < 4)
- return false;
- if (path[len - 1] == '/')
- len--;
- if (tolower(path[len - 1]) != 't' ||
- tolower(path[len - 2]) != 'i' ||
- tolower(path[len - 3]) != 'g' ||
- tolower(path[len - 4]) != '.')
- return false;
- return (len == 4 || path[len - 5] == '/');
- }
-}
+ int (*enter_dir_cb)(fs_iterator *self);
+ int (*leave_dir_cb)(fs_iterator *self);
+ int (*update_entry_cb)(fs_iterator *self);
+};
-static workdir_iterator_frame *workdir_iterator__alloc_frame(
- workdir_iterator *wi)
+#define FS_MAX_DEPTH 100
+
+static fs_iterator_frame *fs_iterator__alloc_frame(fs_iterator *fi)
{
- workdir_iterator_frame *wf = git__calloc(1, sizeof(workdir_iterator_frame));
+ fs_iterator_frame *ff = git__calloc(1, sizeof(fs_iterator_frame));
git_vector_cmp entry_compare = CASESELECT(
- iterator__ignore_case(wi),
+ iterator__ignore_case(fi),
git_path_with_stat_cmp_icase, git_path_with_stat_cmp);
- if (wf == NULL)
- return NULL;
-
- if (git_vector_init(&wf->entries, 0, entry_compare) != 0) {
- git__free(wf);
- return NULL;
+ if (ff && git_vector_init(&ff->entries, 0, entry_compare) < 0) {
+ git__free(ff);
+ ff = NULL;
}
- return wf;
+ return ff;
}
-static void workdir_iterator__free_frame(workdir_iterator_frame *wf)
+static void fs_iterator__free_frame(fs_iterator_frame *ff)
{
- unsigned int i;
+ size_t i;
git_path_with_stat *path;
- git_vector_foreach(&wf->entries, i, path)
+ git_vector_foreach(&ff->entries, i, path)
git__free(path);
- git_vector_free(&wf->entries);
- git__free(wf);
+ git_vector_free(&ff->entries);
+ git__free(ff);
+}
+
+static void fs_iterator__pop_frame(
+ fs_iterator *fi, fs_iterator_frame *ff, bool pop_last)
+{
+ if (fi && fi->stack == ff) {
+ if (!ff->next && !pop_last) {
+ memset(&fi->entry, 0, sizeof(fi->entry));
+ return;
+ }
+
+ if (fi->leave_dir_cb)
+ (void)fi->leave_dir_cb(fi);
+
+ fi->stack = ff->next;
+ fi->depth--;
+ }
+
+ fs_iterator__free_frame(ff);
}
-static int workdir_iterator__update_entry(workdir_iterator *wi);
+static int fs_iterator__update_entry(fs_iterator *fi);
-static int workdir_iterator__entry_cmp(const void *i, const void *item)
+static int fs_iterator__entry_cmp(const void *i, const void *item)
{
- const workdir_iterator *wi = (const workdir_iterator *)i;
+ const fs_iterator *fi = (const fs_iterator *)i;
const git_path_with_stat *ps = item;
- return wi->base.prefixcomp(wi->base.start, ps->path);
+ return fi->base.prefixcomp(fi->base.start, ps->path);
}
-static void workdir_iterator__seek_frame_start(
- workdir_iterator *wi, workdir_iterator_frame *wf)
+static void fs_iterator__seek_frame_start(
+ fs_iterator *fi, fs_iterator_frame *ff)
{
- if (!wf)
+ if (!ff)
return;
- if (wi->base.start)
+ if (fi->base.start)
git_vector_bsearch2(
- &wf->index, &wf->entries, workdir_iterator__entry_cmp, wi);
+ &ff->index, &ff->entries, fs_iterator__entry_cmp, fi);
else
- wf->index = 0;
-
- if (path_is_dotgit(git_vector_get(&wf->entries, wf->index)))
- wf->index++;
+ ff->index = 0;
}
-static int workdir_iterator__expand_dir(workdir_iterator *wi)
+static int fs_iterator__expand_dir(fs_iterator *fi)
{
int error;
- workdir_iterator_frame *wf;
+ fs_iterator_frame *ff;
+
+ if (fi->depth > FS_MAX_DEPTH) {
+ giterr_set(GITERR_REPOSITORY,
+ "Directory nesting is too deep (%d)", fi->depth);
+ return -1;
+ }
- wf = workdir_iterator__alloc_frame(wi);
- GITERR_CHECK_ALLOC(wf);
+ ff = fs_iterator__alloc_frame(fi);
+ GITERR_CHECK_ALLOC(ff);
error = git_path_dirload_with_stat(
- wi->path.ptr, wi->root_len, iterator__ignore_case(wi),
- wi->base.start, wi->base.end, &wf->entries);
+ fi->path.ptr, fi->root_len, iterator__ignore_case(fi),
+ fi->base.start, fi->base.end, &ff->entries);
- if (error < 0 || wf->entries.length == 0) {
- workdir_iterator__free_frame(wf);
+ if (error < 0 || ff->entries.length == 0) {
+ fs_iterator__free_frame(ff);
return GIT_ENOTFOUND;
}
- if (++(wi->depth) > WORKDIR_MAX_DEPTH) {
- giterr_set(GITERR_REPOSITORY,
- "Working directory is too deep (%d)", wi->depth);
- workdir_iterator__free_frame(wf);
- return -1;
- }
-
- workdir_iterator__seek_frame_start(wi, wf);
+ fs_iterator__seek_frame_start(fi, ff);
- /* only push new ignores if this is not top level directory */
- if (wi->stack != NULL) {
- ssize_t slash_pos = git_buf_rfind_next(&wi->path, '/');
- (void)git_ignore__push_dir(&wi->ignores, &wi->path.ptr[slash_pos + 1]);
- }
+ ff->next = fi->stack;
+ fi->stack = ff;
+ fi->depth++;
- wf->next = wi->stack;
- wi->stack = wf;
+ if (fi->enter_dir_cb && (error = fi->enter_dir_cb(fi)) < 0)
+ return error;
- return workdir_iterator__update_entry(wi);
+ return fs_iterator__update_entry(fi);
}
-static int workdir_iterator__current(
+static int fs_iterator__current(
const git_index_entry **entry, git_iterator *self)
{
- workdir_iterator *wi = (workdir_iterator *)self;
+ fs_iterator *fi = (fs_iterator *)self;
if (entry)
- *entry = (wi->entry.path == NULL) ? NULL : &wi->entry;
+ *entry = (fi->entry.path == NULL) ? NULL : &fi->entry;
return 0;
}
-static int workdir_iterator__at_end(git_iterator *self)
+static int fs_iterator__at_end(git_iterator *self)
{
- return (((workdir_iterator *)self)->entry.path == NULL);
+ return (((fs_iterator *)self)->entry.path == NULL);
}
-static int workdir_iterator__advance_into(
+static int fs_iterator__advance_into(
const git_index_entry **entry, git_iterator *iter)
{
int error = 0;
- workdir_iterator *wi = (workdir_iterator *)iter;
+ fs_iterator *fi = (fs_iterator *)iter;
iterator__clear_entry(entry);
- /* workdir iterator will allow you to explicitly advance into a
- * commit/submodule (as well as a tree) to avoid some cases where an
- * entry is mislabeled as a submodule in the working directory
+ /* Allow you to explicitly advance into a commit/submodule (as well as a
+ * tree) to avoid cases where an entry is mislabeled as a submodule in
+ * the working directory. The fs iterator will never have COMMMIT
+ * entries on it's own, but a wrapper might add them.
*/
- if (wi->entry.path != NULL &&
- (wi->entry.mode == GIT_FILEMODE_TREE ||
- wi->entry.mode == GIT_FILEMODE_COMMIT))
+ if (fi->entry.path != NULL &&
+ (fi->entry.mode == GIT_FILEMODE_TREE ||
+ fi->entry.mode == GIT_FILEMODE_COMMIT))
/* returns GIT_ENOTFOUND if the directory is empty */
- error = workdir_iterator__expand_dir(wi);
+ error = fs_iterator__expand_dir(fi);
if (!error && entry)
- error = workdir_iterator__current(entry, iter);
+ error = fs_iterator__current(entry, iter);
return error;
}
-static int workdir_iterator__advance(
+static int fs_iterator__advance_over(
const git_index_entry **entry, git_iterator *self)
{
int error = 0;
- workdir_iterator *wi = (workdir_iterator *)self;
- workdir_iterator_frame *wf;
+ fs_iterator *fi = (fs_iterator *)self;
+ fs_iterator_frame *ff;
git_path_with_stat *next;
- /* given include_trees & autoexpand, we might have to go into a tree */
- if (iterator__do_autoexpand(wi) &&
- wi->entry.path != NULL &&
- wi->entry.mode == GIT_FILEMODE_TREE)
- {
- error = workdir_iterator__advance_into(entry, self);
-
- /* continue silently past empty directories if autoexpanding */
- if (error != GIT_ENOTFOUND)
- return error;
- giterr_clear();
- error = 0;
- }
-
if (entry != NULL)
*entry = NULL;
- while (wi->entry.path != NULL) {
- wf = wi->stack;
- next = git_vector_get(&wf->entries, ++wf->index);
+ while (fi->entry.path != NULL) {
+ ff = fi->stack;
+ next = git_vector_get(&ff->entries, ++ff->index);
- if (next != NULL) {
- /* match git's behavior of ignoring anything named ".git" */
- if (path_is_dotgit(next))
- continue;
- /* else found a good entry */
+ if (next != NULL)
break;
- }
-
- /* pop stack if anything is left to pop */
- if (!wf->next) {
- memset(&wi->entry, 0, sizeof(wi->entry));
- return 0;
- }
- wi->stack = wf->next;
- wi->depth--;
- workdir_iterator__free_frame(wf);
- git_ignore__pop_dir(&wi->ignores);
+ fs_iterator__pop_frame(fi, ff, false);
}
- error = workdir_iterator__update_entry(wi);
+ error = fs_iterator__update_entry(fi);
if (!error && entry != NULL)
- error = workdir_iterator__current(entry, self);
+ error = fs_iterator__current(entry, self);
return error;
}
-static int workdir_iterator__seek(git_iterator *self, const char *prefix)
+static int fs_iterator__advance(
+ const git_index_entry **entry, git_iterator *self)
+{
+ fs_iterator *fi = (fs_iterator *)self;
+
+ /* given include_trees & autoexpand, we might have to go into a tree */
+ if (iterator__do_autoexpand(fi) &&
+ fi->entry.path != NULL &&
+ fi->entry.mode == GIT_FILEMODE_TREE)
+ {
+ int error = fs_iterator__advance_into(entry, self);
+ if (error != GIT_ENOTFOUND)
+ return error;
+ /* continue silently past empty directories if autoexpanding */
+ giterr_clear();
+ }
+
+ return fs_iterator__advance_over(entry, self);
+}
+
+static int fs_iterator__seek(git_iterator *self, const char *prefix)
{
GIT_UNUSED(self);
GIT_UNUSED(prefix);
@@ -1073,107 +1060,192 @@ static int workdir_iterator__seek(git_iterator *self, const char *prefix)
return 0;
}
-static int workdir_iterator__reset(
+static int fs_iterator__reset(
git_iterator *self, const char *start, const char *end)
{
- workdir_iterator *wi = (workdir_iterator *)self;
+ fs_iterator *fi = (fs_iterator *)self;
- while (wi->stack != NULL && wi->stack->next != NULL) {
- workdir_iterator_frame *wf = wi->stack;
- wi->stack = wf->next;
- workdir_iterator__free_frame(wf);
- git_ignore__pop_dir(&wi->ignores);
- }
- wi->depth = 0;
+ while (fi->stack != NULL && fi->stack->next != NULL)
+ fs_iterator__pop_frame(fi, fi->stack, false);
+ fi->depth = 0;
if (iterator__reset_range(self, start, end) < 0)
return -1;
- workdir_iterator__seek_frame_start(wi, wi->stack);
+ fs_iterator__seek_frame_start(fi, fi->stack);
- return workdir_iterator__update_entry(wi);
+ return fs_iterator__update_entry(fi);
}
-static void workdir_iterator__free(git_iterator *self)
+static void fs_iterator__free(git_iterator *self)
{
- workdir_iterator *wi = (workdir_iterator *)self;
+ fs_iterator *fi = (fs_iterator *)self;
- while (wi->stack != NULL) {
- workdir_iterator_frame *wf = wi->stack;
- wi->stack = wf->next;
- workdir_iterator__free_frame(wf);
- }
+ while (fi->stack != NULL)
+ fs_iterator__pop_frame(fi, fi->stack, true);
- git_ignore__free(&wi->ignores);
- git_buf_free(&wi->path);
+ git_buf_free(&fi->path);
}
-static int workdir_iterator__update_entry(workdir_iterator *wi)
+static int fs_iterator__update_entry(fs_iterator *fi)
{
- int error = 0;
git_path_with_stat *ps =
- git_vector_get(&wi->stack->entries, wi->stack->index);
+ git_vector_get(&fi->stack->entries, fi->stack->index);
- git_buf_truncate(&wi->path, wi->root_len);
- memset(&wi->entry, 0, sizeof(wi->entry));
+ git_buf_truncate(&fi->path, fi->root_len);
+ memset(&fi->entry, 0, sizeof(fi->entry));
if (!ps)
return 0;
+ if (git_buf_put(&fi->path, ps->path, ps->path_len) < 0)
+ return -1;
+ if (iterator__past_end(fi, fi->path.ptr + fi->root_len))
+ return 0;
- /* skip over .git entries */
- if (path_is_dotgit(ps))
- return workdir_iterator__advance(NULL, (git_iterator *)wi);
+ fi->entry.path = ps->path;
+ git_index_entry__init_from_stat(&fi->entry, &ps->st);
+
+ /* need different mode here to keep directories during iteration */
+ fi->entry.mode = git_futils_canonical_mode(ps->st.st_mode);
+
+ /* allow wrapper to check/update the entry (can force skip) */
+ if (fi->update_entry_cb &&
+ fi->update_entry_cb(fi) == GIT_ENOTFOUND)
+ return fs_iterator__advance_over(NULL, (git_iterator *)fi);
+
+ /* if this is a tree and trees aren't included, then skip */
+ if (fi->entry.mode == GIT_FILEMODE_TREE && !iterator__include_trees(fi))
+ return git_iterator_advance(NULL, (git_iterator *)fi);
+
+ return 0;
+}
+
+static int fs_iterator__initialize(
+ git_iterator **out, fs_iterator *fi, const char *root)
+{
+ int error;
- if (git_buf_put(&wi->path, ps->path, ps->path_len) < 0)
+ if (git_buf_sets(&fi->path, root) < 0 || git_path_to_dir(&fi->path) < 0) {
+ git__free(fi);
return -1;
+ }
+ fi->root_len = fi->path.size;
- if (iterator__past_end(wi, wi->path.ptr + wi->root_len))
- return 0;
+ if ((error = fs_iterator__expand_dir(fi)) == GIT_ENOTFOUND) {
+ giterr_clear();
+ error = 0;
+ }
+ if (error) {
+ git_iterator_free((git_iterator *)fi);
+ fi = NULL;
+ }
- wi->entry.path = ps->path;
+ *out = (git_iterator *)fi;
+ return error;
+}
- wi->is_ignored = -1;
+int git_iterator_for_filesystem(
+ git_iterator **out,
+ const char *root,
+ git_iterator_flag_t flags,
+ const char *start,
+ const char *end)
+{
+ fs_iterator *fi = git__calloc(1, sizeof(fs_iterator));
+ GITERR_CHECK_ALLOC(fi);
- git_index_entry__init_from_stat(&wi->entry, &ps->st);
+ ITERATOR_BASE_INIT(fi, fs, FS, NULL);
- /* need different mode here to keep directories during iteration */
- wi->entry.mode = git_futils_canonical_mode(ps->st.st_mode);
+ if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0)
+ fi->base.flags |= GIT_ITERATOR_IGNORE_CASE;
- /* if this is a file type we don't handle, treat as ignored */
- if (wi->entry.mode == 0) {
- wi->is_ignored = 1;
- return 0;
+ return fs_iterator__initialize(out, fi, root);
+}
+
+
+typedef struct {
+ fs_iterator fi;
+ git_ignores ignores;
+ int is_ignored;
+} workdir_iterator;
+
+GIT_INLINE(bool) workdir_path_is_dotgit(const git_buf *path)
+{
+ size_t len;
+
+ if (!path || (len = path->size) < 4)
+ return false;
+
+ if (path->ptr[len - 1] == '/')
+ len--;
+
+ if (tolower(path->ptr[len - 1]) != 't' ||
+ tolower(path->ptr[len - 2]) != 'i' ||
+ tolower(path->ptr[len - 3]) != 'g' ||
+ tolower(path->ptr[len - 4]) != '.')
+ return false;
+
+ return (len == 4 || path->ptr[len - 5] == '/');
+}
+
+static int workdir_iterator__enter_dir(fs_iterator *fi)
+{
+ /* only push new ignores if this is not top level directory */
+ if (fi->stack->next != NULL) {
+ workdir_iterator *wi = (workdir_iterator *)fi;
+ ssize_t slash_pos = git_buf_rfind_next(&fi->path, '/');
+
+ (void)git_ignore__push_dir(&wi->ignores, &fi->path.ptr[slash_pos + 1]);
}
- /* if this isn't a tree, then we're done */
- if (wi->entry.mode != GIT_FILEMODE_TREE)
- return 0;
+ return 0;
+}
- /* detect submodules */
- error = git_submodule_lookup(NULL, wi->base.repo, wi->entry.path);
- if (error == GIT_ENOTFOUND)
- giterr_clear();
+static int workdir_iterator__leave_dir(fs_iterator *fi)
+{
+ workdir_iterator *wi = (workdir_iterator *)fi;
+ git_ignore__pop_dir(&wi->ignores);
+ return 0;
+}
- if (error == GIT_EEXISTS) /* if contains .git, treat as untracked submod */
- error = 0;
+static int workdir_iterator__update_entry(fs_iterator *fi)
+{
+ int error = 0;
+ workdir_iterator *wi = (workdir_iterator *)fi;
+
+ /* skip over .git entries */
+ if (workdir_path_is_dotgit(&fi->path))
+ return GIT_ENOTFOUND;
+
+ /* reset is_ignored since we haven't checked yet */
+ wi->is_ignored = -1;
- /* if submodule, mark as GITLINK and remove trailing slash */
- if (!error) {
- size_t len = strlen(wi->entry.path);
- assert(wi->entry.path[len - 1] == '/');
- wi->entry.path[len - 1] = '\0';
- wi->entry.mode = S_IFGITLINK;
+ /* check if apparent tree entries are actually submodules */
+ if (fi->entry.mode != GIT_FILEMODE_TREE)
return 0;
+
+ error = git_submodule_lookup(NULL, fi->base.repo, fi->entry.path);
+ if (error < 0)
+ giterr_clear();
+
+ /* mark submodule (or any dir with .git) as GITLINK and remove slash */
+ if (!error || error == GIT_EEXISTS) {
+ fi->entry.mode = S_IFGITLINK;
+ fi->entry.path[strlen(fi->entry.path) - 1] = '\0';
}
- if (iterator__include_trees(wi))
- return 0;
+ return 0;
+}
- return workdir_iterator__advance(NULL, (git_iterator *)wi);
+static void workdir_iterator__free(git_iterator *self)
+{
+ workdir_iterator *wi = (workdir_iterator *)self;
+ fs_iterator__free(self);
+ git_ignore__free(&wi->ignores);
}
int git_iterator_for_workdir(
- git_iterator **iter,
+ git_iterator **out,
git_repository *repo,
git_iterator_flag_t flags,
const char *start,
@@ -1182,38 +1254,28 @@ int git_iterator_for_workdir(
int error;
workdir_iterator *wi;
- assert(iter && repo);
+ if (git_repository__ensure_not_bare(repo, "scan working directory") < 0)
+ return GIT_EBAREREPO;
- if ((error = git_repository__ensure_not_bare(
- repo, "scan working directory")) < 0)
- return error;
+ /* initialize as an fs iterator then do overrides */
+ wi = git__calloc(1, sizeof(workdir_iterator));
+ GITERR_CHECK_ALLOC(wi);
+ ITERATOR_BASE_INIT((&wi->fi), fs, FS, repo);
- ITERATOR_BASE_INIT(wi, workdir, WORKDIR, repo);
-
- if ((error = iterator__update_ignore_case((git_iterator *)wi, flags)) < 0)
- goto fail;
+ wi->fi.base.type = GIT_ITERATOR_TYPE_WORKDIR;
+ wi->fi.cb.free = workdir_iterator__free;
+ wi->fi.enter_dir_cb = workdir_iterator__enter_dir;
+ wi->fi.leave_dir_cb = workdir_iterator__leave_dir;
+ wi->fi.update_entry_cb = workdir_iterator__update_entry;
- if (git_buf_sets(&wi->path, git_repository_workdir(repo)) < 0 ||
- git_path_to_dir(&wi->path) < 0 ||
- git_ignore__for_path(repo, "", &wi->ignores) < 0)
+ if ((error = iterator__update_ignore_case((git_iterator *)wi, flags)) < 0 ||
+ (error = git_ignore__for_path(repo, "", &wi->ignores)) < 0)
{
- git__free(wi);
- return -1;
- }
- wi->root_len = wi->path.size;
-
- if ((error = workdir_iterator__expand_dir(wi)) < 0) {
- if (error != GIT_ENOTFOUND)
- goto fail;
- giterr_clear();
+ git_iterator_free((git_iterator *)wi);
+ return error;
}
- *iter = (git_iterator *)wi;
- return 0;
-
-fail:
- git_iterator_free((git_iterator *)wi);
- return error;
+ return fs_iterator__initialize(out, &wi->fi, git_repository_workdir(repo));
}
@@ -1315,7 +1377,8 @@ bool git_iterator_current_is_ignored(git_iterator *iter)
if (wi->is_ignored != -1)
return (bool)(wi->is_ignored != 0);
- if (git_ignore__lookup(&wi->ignores, wi->entry.path, &wi->is_ignored) < 0)
+ if (git_ignore__lookup(
+ &wi->ignores, wi->fi.entry.path, &wi->is_ignored) < 0)
wi->is_ignored = true;
return (bool)wi->is_ignored;
@@ -1340,10 +1403,10 @@ int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter)
{
workdir_iterator *wi = (workdir_iterator *)iter;
- if (iter->type != GIT_ITERATOR_TYPE_WORKDIR || !wi->entry.path)
+ if (iter->type != GIT_ITERATOR_TYPE_WORKDIR || !wi->fi.entry.path)
*path = NULL;
else
- *path = &wi->path;
+ *path = &wi->fi.path;
return 0;
}
diff --git a/src/iterator.h b/src/iterator.h
index 4a4e6a9d8..7998f7c6b 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -19,6 +19,7 @@ typedef enum {
GIT_ITERATOR_TYPE_TREE = 1,
GIT_ITERATOR_TYPE_INDEX = 2,
GIT_ITERATOR_TYPE_WORKDIR = 3,
+ GIT_ITERATOR_TYPE_FS = 4,
} git_iterator_type_t;
typedef enum {
@@ -88,6 +89,16 @@ extern int git_iterator_for_workdir(
const char *start,
const char *end);
+/* for filesystem iterators, you have to explicitly pass in the ignore_case
+ * behavior that you desire
+ */
+extern int git_iterator_for_filesystem(
+ git_iterator **out,
+ const char *root,
+ git_iterator_flag_t flags,
+ const char *start,
+ const char *end);
+
extern void git_iterator_free(git_iterator *iter);
/* Return a git_index_entry structure for the current value the iterator
diff --git a/src/odb.c b/src/odb.c
index 8249c5adc..d6ea8c29a 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -8,6 +8,7 @@
#include "common.h"
#include <zlib.h>
#include "git2/object.h"
+#include "git2/sys/odb_backend.h"
#include "fileops.h"
#include "hash.h"
#include "odb.h"
@@ -407,6 +408,27 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
return add_backend_internal(odb, backend, priority, true, 0);
}
+size_t git_odb_num_backends(git_odb *odb)
+{
+ assert(odb);
+ return odb->backends.length;
+}
+
+int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
+{
+ backend_internal *internal;
+
+ assert(odb && odb);
+ internal = git_vector_get(&odb->backends, pos);
+
+ if (internal && internal->backend) {
+ *out = internal->backend;
+ return 0;
+ }
+
+ return GIT_ENOTFOUND;
+}
+
static int add_default_backends(
git_odb *db, const char *objects_dir,
bool as_alternates, int alternate_depth)
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 68083f7fd..e78172cf6 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -8,7 +8,7 @@
#include "common.h"
#include <zlib.h>
#include "git2/object.h"
-#include "git2/oid.h"
+#include "git2/sys/odb_backend.h"
#include "fileops.h"
#include "hash.h"
#include "odb.h"
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 7240a4ac7..773e14974 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -8,7 +8,8 @@
#include "common.h"
#include <zlib.h>
#include "git2/repository.h"
-#include "git2/oid.h"
+#include "git2/indexer.h"
+#include "git2/sys/odb_backend.h"
#include "fileops.h"
#include "hash.h"
#include "odb.h"
diff --git a/src/refdb.c b/src/refdb.c
index d9b73c6e7..33a1934d1 100644
--- a/src/refdb.c
+++ b/src/refdb.c
@@ -7,15 +7,16 @@
#include "common.h"
#include "posix.h"
+
#include "git2/object.h"
#include "git2/refs.h"
#include "git2/refdb.h"
+#include "git2/sys/refdb_backend.h"
+
#include "hash.h"
#include "refdb.h"
#include "refs.h"
-#include "git2/refdb_backend.h"
-
int git_refdb_new(git_refdb **out, git_repository *repo)
{
git_refdb *db;
@@ -45,7 +46,7 @@ int git_refdb_open(git_refdb **out, git_repository *repo)
return -1;
/* Add the default (filesystem) backend */
- if (git_refdb_backend_fs(&dir, repo, db) < 0) {
+ if (git_refdb_backend_fs(&dir, repo) < 0) {
git_refdb_free(db);
return -1;
}
@@ -57,15 +58,19 @@ int git_refdb_open(git_refdb **out, git_repository *repo)
return 0;
}
-int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend)
+static void refdb_free_backend(git_refdb *db)
{
if (db->backend) {
- if(db->backend->free)
+ if (db->backend->free)
db->backend->free(db->backend);
else
git__free(db->backend);
}
+}
+int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend)
+{
+ refdb_free_backend(db);
db->backend = backend;
return 0;
@@ -74,23 +79,16 @@ int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend)
int git_refdb_compress(git_refdb *db)
{
assert(db);
-
- if (db->backend->compress) {
+
+ if (db->backend->compress)
return db->backend->compress(db->backend);
- }
-
+
return 0;
}
static void refdb_free(git_refdb *db)
{
- if (db->backend) {
- if(db->backend->free)
- db->backend->free(db->backend);
- else
- git__free(db->backend);
- }
-
+ refdb_free_backend(db);
git__free(db);
}
@@ -111,9 +109,19 @@ int git_refdb_exists(int *exists, git_refdb *refdb, const char *ref_name)
int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
{
- assert(db && db->backend && ref_name);
+ git_reference *ref;
+ int error;
+
+ assert(db && db->backend && out && ref_name);
- return db->backend->lookup(out, db->backend, ref_name);
+ if (!(error = db->backend->lookup(&ref, db->backend, ref_name))) {
+ ref->db = db;
+ *out = ref;
+ } else {
+ *out = NULL;
+ }
+
+ return error;
}
int git_refdb_foreach(
diff --git a/src/refdb.h b/src/refdb.h
index 0969711b9..047113ac8 100644
--- a/src/refdb.h
+++ b/src/refdb.h
@@ -41,6 +41,6 @@ int git_refdb_foreach_glob(
int git_refdb_write(git_refdb *refdb, const git_reference *ref);
-int git_refdb_delete(struct git_refdb *refdb, const git_reference *ref);
+int git_refdb_delete(git_refdb *refdb, const git_reference *ref);
#endif
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 784749fd3..443871005 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -18,7 +18,8 @@
#include <git2/tag.h>
#include <git2/object.h>
#include <git2/refdb.h>
-#include <git2/refdb_backend.h>
+#include <git2/sys/refdb_backend.h>
+#include <git2/sys/refs.h>
GIT__USE_STRMAP;
@@ -42,7 +43,6 @@ typedef struct refdb_fs_backend {
git_repository *repo;
const char *path;
- git_refdb *refdb;
git_refcache refcache;
} refdb_fs_backend;
@@ -62,7 +62,7 @@ static int reference_read(
/* Determine the full path of the file */
if (git_buf_joinpath(&path, repo_path, ref_name) < 0)
return -1;
-
+
result = git_futils_readbuffer_updated(file_content, path.ptr, mtime, NULL, updated);
git_buf_free(&path);
@@ -175,7 +175,7 @@ static int packed_load(refdb_fs_backend *backend)
ref_cache->packfile = git_strmap_alloc();
GITERR_CHECK_ALLOC(ref_cache->packfile);
}
-
+
result = reference_read(&packfile, &ref_cache->packfile_time,
backend->path, GIT_PACKEDREFS_FILE, &updated);
@@ -193,7 +193,7 @@ static int packed_load(refdb_fs_backend *backend)
if (result < 0)
return -1;
-
+
if (!updated)
return 0;
@@ -430,12 +430,12 @@ static int loose_lookup(
goto done;
}
- *out = git_reference__alloc_symbolic(backend->refdb, ref_name, target);
+ *out = git_reference__alloc_symbolic(ref_name, target);
} else {
if ((error = loose_parse_oid(&oid, &ref_file)) < 0)
goto done;
-
- *out = git_reference__alloc(backend->refdb, ref_name, &oid, NULL);
+
+ *out = git_reference__alloc(ref_name, &oid, NULL);
}
if (*out == NULL)
@@ -456,19 +456,19 @@ static int packed_map_entry(
if (packed_load(backend) < 0)
return -1;
-
+
/* Look up on the packfile */
packfile_refs = backend->refcache.packfile;
*pos = git_strmap_lookup_index(packfile_refs, ref_name);
-
+
if (!git_strmap_valid_index(packfile_refs, *pos)) {
giterr_set(GITERR_REFERENCE, "Reference '%s' not found", ref_name);
return GIT_ENOTFOUND;
}
*entry = git_strmap_value_at(packfile_refs, *pos);
-
+
return 0;
}
@@ -480,14 +480,14 @@ static int packed_lookup(
struct packref *entry;
khiter_t pos;
int error = 0;
-
+
if ((error = packed_map_entry(&entry, &pos, backend, ref_name)) < 0)
return error;
- if ((*out = git_reference__alloc(backend->refdb, ref_name,
+ if ((*out = git_reference__alloc(ref_name,
&entry->oid, &entry->peel)) == NULL)
return -1;
-
+
return 0;
}
@@ -583,7 +583,7 @@ static int refdb_fs_backend__foreach(
git_buf refs_path = GIT_BUF_INIT;
const char *ref_name;
void *ref = NULL;
-
+
GIT_UNUSED(ref);
assert(_backend);
@@ -591,7 +591,7 @@ static int refdb_fs_backend__foreach(
if (packed_load(backend) < 0)
return -1;
-
+
/* list all the packed references first */
if (list_type & GIT_REF_OID) {
git_strmap_foreach(backend->refcache.packfile, ref_name, ref, {
@@ -925,7 +925,7 @@ static int refdb_fs_backend__delete(
repo = backend->repo;
/* If a loose reference exists, remove it from the filesystem */
-
+
if (git_buf_joinpath(&loose_path, repo->path_repository, ref->name) < 0)
return -1;
@@ -933,7 +933,7 @@ static int refdb_fs_backend__delete(
error = p_unlink(loose_path.ptr);
loose_deleted = 1;
}
-
+
git_buf_free(&loose_path);
if (error != 0)
@@ -947,7 +947,7 @@ static int refdb_fs_backend__delete(
error = packed_write(backend);
}
-
+
if (pack_error == GIT_ENOTFOUND)
error = loose_deleted ? 0 : GIT_ENOTFOUND;
else
@@ -999,8 +999,7 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend)
int git_refdb_backend_fs(
git_refdb_backend **backend_out,
- git_repository *repository,
- git_refdb *refdb)
+ git_repository *repository)
{
refdb_fs_backend *backend;
@@ -1009,7 +1008,6 @@ int git_refdb_backend_fs(
backend->repo = repository;
backend->path = repository->path_repository;
- backend->refdb = refdb;
backend->parent.exists = &refdb_fs_backend__exists;
backend->parent.lookup = &refdb_fs_backend__lookup;
diff --git a/src/refs.c b/src/refs.c
index 29d1c4fa9..9c6684a5a 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -19,7 +19,7 @@
#include <git2/branch.h>
#include <git2/refs.h>
#include <git2/refdb.h>
-#include <git2/refdb_backend.h>
+#include <git2/sys/refs.h>
GIT__USE_STRMAP;
@@ -31,7 +31,7 @@ enum {
GIT_PACKREF_WAS_LOOSE = 2
};
-static git_reference *alloc_ref(git_refdb *refdb, const char *name)
+static git_reference *alloc_ref(const char *name)
{
git_reference *ref;
size_t namelen = strlen(name);
@@ -39,22 +39,19 @@ static git_reference *alloc_ref(git_refdb *refdb, const char *name)
if ((ref = git__calloc(1, sizeof(git_reference) + namelen + 1)) == NULL)
return NULL;
- ref->db = refdb;
memcpy(ref->name, name, namelen + 1);
return ref;
}
git_reference *git_reference__alloc_symbolic(
- git_refdb *refdb,
- const char *name,
- const char *target)
+ const char *name, const char *target)
{
git_reference *ref;
- assert(refdb && name && target);
+ assert(name && target);
- ref = alloc_ref(refdb, name);
+ ref = alloc_ref(name);
if (!ref)
return NULL;
@@ -69,16 +66,15 @@ git_reference *git_reference__alloc_symbolic(
}
git_reference *git_reference__alloc(
- git_refdb *refdb,
const char *name,
const git_oid *oid,
const git_oid *peel)
{
git_reference *ref;
- assert(refdb && name && oid);
+ assert(name && oid);
- ref = alloc_ref(refdb, name);
+ ref = alloc_ref(name);
if (!ref)
return NULL;
@@ -258,10 +254,10 @@ int git_reference_lookup_resolved(
max_nesting = MAX_NESTING_LEVEL;
else if (max_nesting < 0)
max_nesting = DEFAULT_NESTING_LEVEL;
-
+
strncpy(scan_name, name, GIT_REFNAME_MAX);
scan_type = GIT_REF_SYMBOLIC;
-
+
if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
return -1;
@@ -279,7 +275,7 @@ int git_reference_lookup_resolved(
if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0)
return error;
-
+
scan_type = ref->type;
}
@@ -357,7 +353,7 @@ static int reference__create(
git_refdb *refdb;
git_reference *ref = NULL;
int error = 0;
-
+
if (ref_out)
*ref_out = NULL;
@@ -368,18 +364,19 @@ static int reference__create(
if (oid != NULL) {
assert(symbolic == NULL);
- ref = git_reference__alloc(refdb, name, oid, NULL);
+ ref = git_reference__alloc(name, oid, NULL);
} else {
- ref = git_reference__alloc_symbolic(refdb, name, symbolic);
+ ref = git_reference__alloc_symbolic(name, symbolic);
}
-
+
GITERR_CHECK_ALLOC(ref);
+ ref->db = refdb;
if ((error = git_refdb_write(refdb, ref)) < 0) {
git_reference_free(ref);
return error;
}
-
+
if (ref_out == NULL)
git_reference_free(ref);
else
@@ -399,17 +396,17 @@ int git_reference_create(
int error = 0;
assert(repo && name && oid);
-
+
/* Sanity check the reference being created - target must exist. */
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
return error;
-
+
if (!git_odb_exists(odb, oid)) {
giterr_set(GITERR_REFERENCE,
"Target OID for the reference doesn't exist on the repository");
return -1;
}
-
+
return reference__create(ref_out, repo, name, oid, NULL, force);
}
@@ -424,7 +421,7 @@ int git_reference_symbolic_create(
int error = 0;
assert(repo && name && target);
-
+
if ((error = git_reference__normalize_name_lax(
normalized, sizeof(normalized), target)) < 0)
return error;
@@ -438,7 +435,7 @@ int git_reference_set_target(
const git_oid *id)
{
assert(out && ref && id);
-
+
if (ref->type != GIT_REF_OID) {
giterr_set(GITERR_REFERENCE, "Cannot set OID on symbolic reference");
return -1;
@@ -453,13 +450,13 @@ int git_reference_symbolic_set_target(
const char *target)
{
assert(out && ref && target);
-
+
if (ref->type != GIT_REF_SYMBOLIC) {
giterr_set(GITERR_REFERENCE,
"Cannot set symbolic target on a direct reference");
return -1;
}
-
+
return git_reference_symbolic_create(out, ref->db->repo, ref->name, target, 1);
}
@@ -475,7 +472,7 @@ int git_reference_rename(
git_reference *result = NULL;
int error = 0;
int reference_has_log;
-
+
*out = NULL;
normalization_flags = ref->type == GIT_REF_SYMBOLIC ?
@@ -490,10 +487,9 @@ int git_reference_rename(
* Create the new reference.
*/
if (ref->type == GIT_REF_OID) {
- result = git_reference__alloc(ref->db, new_name,
- &ref->target.oid, &ref->peel);
+ result = git_reference__alloc(new_name, &ref->target.oid, &ref->peel);
} else if (ref->type == GIT_REF_SYMBOLIC) {
- result = git_reference__alloc_symbolic(ref->db, new_name, ref->target.symbolic);
+ result = git_reference__alloc_symbolic(new_name, ref->target.symbolic);
} else {
assert(0);
}
@@ -501,6 +497,8 @@ int git_reference_rename(
if (result == NULL)
return -1;
+ result->db = ref->db;
+
/* Check if we have to update HEAD. */
if ((error = git_branch_is_head(ref)) < 0)
goto on_error;
@@ -510,11 +508,11 @@ int git_reference_rename(
/* Now delete the old ref and save the new one. */
if ((error = git_refdb_delete(ref->db, ref)) < 0)
goto on_error;
-
+
/* Save the new reference. */
if ((error = git_refdb_write(ref->db, result)) < 0)
goto rollback;
-
+
/* Update HEAD it was poiting to the reference being renamed. */
if (should_head_be_updated && (error = git_repository_set_head(ref->db->repo, new_name)) < 0) {
giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference");
@@ -548,7 +546,7 @@ int git_reference_resolve(git_reference **ref_out, const git_reference *ref)
switch (git_reference_type(ref)) {
case GIT_REF_OID:
return git_reference_lookup(ref_out, ref->db->repo, ref->name);
-
+
case GIT_REF_SYMBOLIC:
return git_reference_lookup_resolved(ref_out, ref->db->repo, ref->target.symbolic, -1);
@@ -847,7 +845,7 @@ static int reference__update_terminal(
if (nesting > MAX_NESTING_LEVEL)
return GIT_ENOTFOUND;
-
+
error = git_reference_lookup(&ref, repo, ref_name);
/* If we haven't found the reference at all, create a new reference. */
@@ -855,10 +853,10 @@ static int reference__update_terminal(
giterr_clear();
return git_reference_create(NULL, repo, ref_name, oid, 0);
}
-
+
if (error < 0)
return error;
-
+
/* If the ref is a symbolic reference, follow its target. */
if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
error = reference__update_terminal(repo, git_reference_symbolic_target(ref), oid,
@@ -868,7 +866,7 @@ static int reference__update_terminal(
git_reference_free(ref);
error = git_reference_create(NULL, repo, ref_name, oid, 1);
}
-
+
return error;
}
diff --git a/src/repository.c b/src/repository.c
index 64ab2f4db..a16f69da4 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -9,6 +9,7 @@
#include "git2/object.h"
#include "git2/refdb.h"
+#include "git2/sys/repository.h"
#include "common.h"
#include "repository.h"
@@ -129,6 +130,12 @@ static git_repository *repository_alloc(void)
return repo;
}
+int git_repository_new(git_repository **out)
+{
+ *out = repository_alloc();
+ return 0;
+}
+
static int load_config_data(git_repository *repo)
{
int is_bare;
diff --git a/src/revparse.c b/src/revparse.c
index 74635ed04..8a22a04f3 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -16,7 +16,7 @@
static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname)
{
- int error, i;
+ int error = 0, i;
bool fallbackmode = true;
git_reference *ref;
git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;
diff --git a/src/submodule.c b/src/submodule.c
index 2fdaf2f77..0a22e3b13 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "git2/config.h"
+#include "git2/sys/config.h"
#include "git2/types.h"
#include "git2/repository.h"
#include "git2/index.h"
diff --git a/src/tag.c b/src/tag.c
index 735ba7e1d..c82decbe3 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -13,6 +13,7 @@
#include "git2/object.h"
#include "git2/repository.h"
#include "git2/signature.h"
+#include "git2/odb_backend.h"
void git_tag__free(git_tag *tag)
{
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 8acedeb49..90851980c 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -5,6 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "git2.h"
+#include "git2/odb_backend.h"
#include "smart.h"
#include "refs.h"
diff --git a/src/unix/posix.h b/src/unix/posix.h
index f4886c5d1..9c9f837b9 100644
--- a/src/unix/posix.h
+++ b/src/unix/posix.h
@@ -21,6 +21,8 @@
/* The OpenBSD realpath function behaves differently */
#if !defined(__OpenBSD__)
# define p_realpath(p, po) realpath(p, po)
+#else
+char *p_realpath(const char *, char *);
#endif
#define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a)
diff --git a/src/util.h b/src/util.h
index c0f271997..af3ef0b46 100644
--- a/src/util.h
+++ b/src/util.h
@@ -7,6 +7,8 @@
#ifndef INCLUDE_util_h__
#define INCLUDE_util_h__
+#include "common.h"
+
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define bitsizeof(x) (CHAR_BIT * sizeof(x))
#define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits))))
diff --git a/tests-clar/config/backend.c b/tests-clar/config/backend.c
index 28502a8ba..3fd6eb114 100644
--- a/tests-clar/config/backend.c
+++ b/tests-clar/config/backend.c
@@ -1,4 +1,5 @@
#include "clar_libgit2.h"
+#include "git2/sys/config.h"
void test_config_backend__checks_version(void)
{
diff --git a/tests-clar/diff/patch.c b/tests-clar/diff/patch.c
index 4d17da468..d41f3f12d 100644
--- a/tests-clar/diff/patch.c
+++ b/tests-clar/diff/patch.c
@@ -1,4 +1,6 @@
#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
#include "diff_helpers.h"
#include "repository.h"
#include "buf_text.h"
diff --git a/tests-clar/object/raw/write.c b/tests-clar/object/raw/write.c
index 1b28d0df7..60aa31f6a 100644
--- a/tests-clar/object/raw/write.c
+++ b/tests-clar/object/raw/write.c
@@ -1,5 +1,6 @@
-
#include "clar_libgit2.h"
+#include "git2/odb_backend.h"
+
#include "fileops.h"
#include "odb.h"
diff --git a/tests-clar/odb/packed_one.c b/tests-clar/odb/packed_one.c
index e9d246c23..4f9bde9ed 100644
--- a/tests-clar/odb/packed_one.c
+++ b/tests-clar/odb/packed_one.c
@@ -1,5 +1,6 @@
#include "clar_libgit2.h"
-#include "odb.h"
+#include "git2/odb_backend.h"
+
#include "pack_data_one.h"
#include "pack.h"
diff --git a/tests-clar/odb/sorting.c b/tests-clar/odb/sorting.c
index b4f9e44bc..147a160c8 100644
--- a/tests-clar/odb/sorting.c
+++ b/tests-clar/odb/sorting.c
@@ -1,13 +1,12 @@
#include "clar_libgit2.h"
-#include "git2/odb_backend.h"
-#include "odb.h"
+#include "git2/sys/odb_backend.h"
typedef struct {
git_odb_backend base;
- int position;
+ size_t position;
} fake_backend;
-static git_odb_backend *new_backend(int position)
+static git_odb_backend *new_backend(size_t position)
{
fake_backend *b;
@@ -22,14 +21,13 @@ static git_odb_backend *new_backend(int position)
static void check_backend_sorting(git_odb *odb)
{
- unsigned int i;
-
- for (i = 0; i < odb->backends.length; ++i) {
- fake_backend *internal =
- *((fake_backend **)git_vector_get(&odb->backends, i));
+ size_t i, max_i = git_odb_num_backends(odb);
+ fake_backend *internal;
+ for (i = 0; i < max_i; ++i) {
+ cl_git_pass(git_odb_get_backend((git_odb_backend **)&internal, odb, i));
cl_assert(internal != NULL);
- cl_assert(internal->position == (int)i);
+ cl_assert_equal_sz(i, internal->position);
}
}
diff --git a/tests-clar/refdb/inmemory.c b/tests-clar/refdb/inmemory.c
index 2cccd8eb2..243b5bb37 100644
--- a/tests-clar/refdb/inmemory.c
+++ b/tests-clar/refdb/inmemory.c
@@ -1,13 +1,15 @@
#include "clar_libgit2.h"
-#include "refdb.h"
-#include "repository.h"
+
+#include "buffer.h"
+#include "posix.h"
+#include "path.h"
+#include "refs.h"
+
#include "testdb.h"
#define TEST_REPO_PATH "testrepo"
static git_repository *repo;
-static git_refdb *refdb;
-static git_refdb_backend *refdb_backend;
int unlink_ref(void *payload, git_buf *file)
{
@@ -27,7 +29,7 @@ int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *fi
const char *repo_path;
git_buf repo_refs_dir = GIT_BUF_INIT;
int error = 0;
-
+
repo_path = git_repository_path(repo);
git_buf_joinpath(&repo_refs_dir, repo_path, "HEAD");
@@ -39,7 +41,7 @@ int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *fi
git_buf_joinpath(&repo_refs_dir, git_buf_cstr(&repo_refs_dir), "heads");
if (git_path_direach(&repo_refs_dir, cb, NULL) != 0)
return -1;
-
+
git_buf_joinpath(&repo_refs_dir, repo_path, "packed-refs");
if (git_path_exists(git_buf_cstr(&repo_refs_dir)) &&
cb(NULL, &repo_refs_dir) < 0)
@@ -53,17 +55,19 @@ int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *fi
void test_refdb_inmemory__initialize(void)
{
git_buf repo_refs_dir = GIT_BUF_INIT;
+ git_refdb *refdb;
+ git_refdb_backend *refdb_backend;
repo = cl_git_sandbox_init(TEST_REPO_PATH);
cl_git_pass(git_repository_refdb(&refdb, repo));
cl_git_pass(refdb_backend_test(&refdb_backend, repo));
cl_git_pass(git_refdb_set_backend(refdb, refdb_backend));
-
-
+
ref_file_foreach(repo, unlink_ref);
git_buf_free(&repo_refs_dir);
+ git_refdb_free(refdb);
}
void test_refdb_inmemory__cleanup(void)
@@ -75,10 +79,10 @@ void test_refdb_inmemory__doesnt_write_ref_file(void)
{
git_reference *ref;
git_oid oid;
-
+
cl_git_pass(git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
cl_git_pass(git_reference_create(&ref, repo, GIT_REFS_HEADS_DIR "test1", &oid, 0));
-
+
ref_file_foreach(repo, empty);
git_reference_free(ref);
@@ -88,10 +92,10 @@ void test_refdb_inmemory__read(void)
{
git_reference *write1, *write2, *write3, *read1, *read2, *read3;
git_oid oid1, oid2, oid3;
-
+
cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0));
-
+
cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d"));
cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0));
@@ -138,7 +142,7 @@ int foreach_test(const char *ref_name, void *payload)
cl_assert(git_oid_cmp(&expected, git_reference_target(ref)) == 0);
++(*i);
-
+
git_reference_free(ref);
return 0;
@@ -149,19 +153,19 @@ void test_refdb_inmemory__foreach(void)
git_reference *write1, *write2, *write3;
git_oid oid1, oid2, oid3;
size_t i = 0;
-
+
cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0));
-
+
cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d"));
cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0));
-
+
cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af"));
cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0));
-
+
cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, foreach_test, &i));
- cl_assert_equal_i(i, 3);
-
+ cl_assert_equal_i(3, (int)i);
+
git_reference_free(write1);
git_reference_free(write2);
git_reference_free(write3);
@@ -174,14 +178,14 @@ int delete_test(const char *ref_name, void *payload)
size_t *i = payload;
cl_git_pass(git_reference_lookup(&ref, repo, ref_name));
-
- cl_git_pass(git_oid_fromstr(&expected, "e90810b8df3e80c413d903f631643c716887138d"));
+
+ cl_git_pass(git_oid_fromstr(&expected, "e90810b8df3e80c413d903f631643c716887138d"));
cl_assert(git_oid_cmp(&expected, git_reference_target(ref)) == 0);
-
+
++(*i);
-
+
git_reference_free(ref);
-
+
return 0;
}
@@ -190,24 +194,24 @@ void test_refdb_inmemory__delete(void)
git_reference *write1, *write2, *write3;
git_oid oid1, oid2, oid3;
size_t i = 0;
-
+
cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0));
-
+
cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d"));
cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0));
-
+
cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af"));
cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0));
-
+
git_reference_delete(write1);
git_reference_free(write1);
-
+
git_reference_delete(write3);
git_reference_free(write3);
-
+
cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, delete_test, &i));
- cl_assert_equal_i(i, 1);
+ cl_assert_equal_i(1, (int)i);
git_reference_free(write2);
}
diff --git a/tests-clar/refdb/testdb.c b/tests-clar/refdb/testdb.c
index e60f6790e..627254e44 100644
--- a/tests-clar/refdb/testdb.c
+++ b/tests-clar/refdb/testdb.c
@@ -1,23 +1,18 @@
-#include "common.h"
#include "vector.h"
#include "util.h"
-#include <git2/refdb.h>
-#include <git2/refdb_backend.h>
-#include <git2/errors.h>
-#include <git2/repository.h>
+#include "testdb.h"
typedef struct refdb_test_backend {
git_refdb_backend parent;
-
+
git_repository *repo;
- git_refdb *refdb;
git_vector refs;
} refdb_test_backend;
typedef struct refdb_test_entry {
char *name;
git_ref_t type;
-
+
union {
git_oid oid;
char *symbolic;
@@ -38,19 +33,19 @@ static int refdb_test_backend__exists(
refdb_test_backend *backend;
refdb_test_entry *entry;
size_t i;
-
+
assert(_backend);
backend = (refdb_test_backend *)_backend;
-
+
*exists = 0;
-
+
git_vector_foreach(&backend->refs, i, entry) {
if (strcmp(entry->name, ref_name) == 0) {
*exists = 1;
break;
}
}
-
+
return 0;
}
@@ -60,18 +55,18 @@ static int refdb_test_backend__write(
{
refdb_test_backend *backend;
refdb_test_entry *entry;
-
+
assert(_backend);
backend = (refdb_test_backend *)_backend;
entry = git__calloc(1, sizeof(refdb_test_entry));
GITERR_CHECK_ALLOC(entry);
-
+
entry->name = git__strdup(git_reference_name(ref));
GITERR_CHECK_ALLOC(entry->name);
-
+
entry->type = git_reference_type(ref);
-
+
if (entry->type == GIT_REF_OID)
git_oid_cpy(&entry->target.oid, git_reference_target(ref));
else {
@@ -80,7 +75,7 @@ static int refdb_test_backend__write(
}
git_vector_insert(&backend->refs, entry);
-
+
return 0;
}
@@ -95,21 +90,21 @@ static int refdb_test_backend__lookup(
assert(_backend);
backend = (refdb_test_backend *)_backend;
-
+
git_vector_foreach(&backend->refs, i, entry) {
if (strcmp(entry->name, ref_name) == 0) {
if (entry->type == GIT_REF_OID) {
- *out = git_reference__alloc(backend->refdb, ref_name,
+ *out = git_reference__alloc(ref_name,
&entry->target.oid, NULL);
} else if (entry->type == GIT_REF_SYMBOLIC) {
- *out = git_reference__alloc_symbolic(backend->refdb, ref_name,
+ *out = git_reference__alloc_symbolic(ref_name,
entry->target.symbolic);
}
if (*out == NULL)
return -1;
-
+
return 0;
}
}
@@ -126,21 +121,21 @@ static int refdb_test_backend__foreach(
refdb_test_backend *backend;
refdb_test_entry *entry;
size_t i;
-
+
assert(_backend);
backend = (refdb_test_backend *)_backend;
git_vector_foreach(&backend->refs, i, entry) {
if (entry->type == GIT_REF_OID && (list_flags & GIT_REF_OID) == 0)
continue;
-
+
if (entry->type == GIT_REF_SYMBOLIC && (list_flags & GIT_REF_SYMBOLIC) == 0)
continue;
-
+
if (callback(entry->name, payload) != 0)
return GIT_EUSER;
}
-
+
return 0;
}
@@ -148,7 +143,7 @@ static void refdb_test_entry_free(refdb_test_entry *entry)
{
if (entry->type == GIT_REF_SYMBOLIC)
git__free(entry->target.symbolic);
-
+
git__free(entry->name);
git__free(entry);
}
@@ -179,14 +174,14 @@ static void refdb_test_backend__free(git_refdb_backend *_backend)
refdb_test_backend *backend;
refdb_test_entry *entry;
size_t i;
-
+
assert(_backend);
backend = (refdb_test_backend *)_backend;
git_vector_foreach(&backend->refs, i, entry)
refdb_test_entry_free(entry);
- git_vector_free(&backend->refs);
+ git_vector_free(&backend->refs);
git__free(backend);
}
@@ -195,19 +190,13 @@ int refdb_backend_test(
git_repository *repo)
{
refdb_test_backend *backend;
- git_refdb *refdb;
- int error = 0;
-
- if ((error = git_repository_refdb(&refdb, repo)) < 0)
- return error;
backend = git__calloc(1, sizeof(refdb_test_backend));
GITERR_CHECK_ALLOC(backend);
-
+
git_vector_init(&backend->refs, 0, ref_name_cmp);
backend->repo = repo;
- backend->refdb = refdb;
backend->parent.exists = &refdb_test_backend__exists;
backend->parent.lookup = &refdb_test_backend__lookup;
diff --git a/tests-clar/refdb/testdb.h b/tests-clar/refdb/testdb.h
index e38abd967..a0d1bbc48 100644
--- a/tests-clar/refdb/testdb.h
+++ b/tests-clar/refdb/testdb.h
@@ -1,3 +1,9 @@
+#include <git2/errors.h>
+#include <git2/repository.h>
+#include <git2/refdb.h>
+#include <git2/sys/refs.h>
+#include <git2/sys/refdb_backend.h>
+
int refdb_backend_test(
git_refdb_backend **backend_out,
git_repository *repo);
diff --git a/tests-clar/refs/delete.c b/tests-clar/refs/delete.c
index ac517d869..053f41229 100644
--- a/tests-clar/refs/delete.c
+++ b/tests-clar/refs/delete.c
@@ -88,4 +88,5 @@ void test_refs_delete__packed_only(void)
/* This should pass */
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
+ git_refdb_free(refdb);
}
diff --git a/tests-clar/refs/pack.c b/tests-clar/refs/pack.c
index 973abae30..412c4c5fd 100644
--- a/tests-clar/refs/pack.c
+++ b/tests-clar/refs/pack.c
@@ -25,6 +25,7 @@ static void packall(void)
cl_git_pass(git_repository_refdb(&refdb, g_repo));
cl_git_pass(git_refdb_compress(refdb));
+ git_refdb_free(refdb);
}
void test_refs_pack__empty(void)
diff --git a/tests-clar/refs/rename.c b/tests-clar/refs/rename.c
index e39abeb05..5ab84c48e 100644
--- a/tests-clar/refs/rename.c
+++ b/tests-clar/refs/rename.c
@@ -284,6 +284,7 @@ void test_refs_rename__overwrite(void)
git_reference_free(ref_one);
git_reference_free(ref_one_new);
git_reference_free(ref_two);
+ git_refdb_free(refdb);
}
diff --git a/tests-clar/repo/iterator.c b/tests-clar/repo/iterator.c
index 00c46d6b1..ab460735c 100644
--- a/tests-clar/repo/iterator.c
+++ b/tests-clar/repo/iterator.c
@@ -422,7 +422,7 @@ static void build_test_tree(
git_treebuilder *builder;
const char *scan = fmt, *next;
char type, delimiter;
- git_filemode_t mode;
+ git_filemode_t mode = GIT_FILEMODE_BLOB;
git_buf name = GIT_BUF_INIT;
va_list arglist;
@@ -755,47 +755,52 @@ void test_repo_iterator__workdir_icase(void)
git_iterator_free(i);
}
-void test_repo_iterator__workdir_depth(void)
+static void build_workdir_tree(const char *root, int dirs, int subs)
{
int i, j;
- git_iterator *iter;
- char buf[64];
-
- g_repo = cl_git_sandbox_init("icase");
-
- for (i = 0; i < 10; ++i) {
- p_snprintf(buf, sizeof(buf), "icase/dir%02d", i);
- cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
+ char buf[64], sub[64];
+ for (i = 0; i < dirs; ++i) {
if (i % 2 == 0) {
- p_snprintf(buf, sizeof(buf), "icase/dir%02d/file", i);
+ p_snprintf(buf, sizeof(buf), "%s/dir%02d", root, i);
+ cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
+
+ p_snprintf(buf, sizeof(buf), "%s/dir%02d/file", root, i);
cl_git_mkfile(buf, buf);
+ buf[strlen(buf) - 5] = '\0';
+ } else {
+ p_snprintf(buf, sizeof(buf), "%s/DIR%02d", root, i);
+ cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
}
- for (j = 0; j < 10; ++j) {
- p_snprintf(buf, sizeof(buf), "icase/dir%02d/sub%02d", i, j);
- cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
+ for (j = 0; j < subs; ++j) {
+ switch (j % 4) {
+ case 0: p_snprintf(sub, sizeof(sub), "%s/sub%02d", buf, j); break;
+ case 1: p_snprintf(sub, sizeof(sub), "%s/sUB%02d", buf, j); break;
+ case 2: p_snprintf(sub, sizeof(sub), "%s/Sub%02d", buf, j); break;
+ case 3: p_snprintf(sub, sizeof(sub), "%s/SUB%02d", buf, j); break;
+ }
+ cl_git_pass(git_futils_mkdir(sub, NULL, 0775, GIT_MKDIR_PATH));
if (j % 2 == 0) {
- p_snprintf(
- buf, sizeof(buf), "icase/dir%02d/sub%02d/file", i, j);
- cl_git_mkfile(buf, buf);
+ size_t sublen = strlen(sub);
+ memcpy(&sub[sublen], "/file", sizeof("/file"));
+ cl_git_mkfile(sub, sub);
+ sub[sublen] = '\0';
}
}
}
+}
- for (i = 1; i < 3; ++i) {
- for (j = 0; j < 50; ++j) {
- p_snprintf(buf, sizeof(buf), "icase/dir%02d/sub01/moar%02d", i, j);
- cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH));
+void test_repo_iterator__workdir_depth(void)
+{
+ git_iterator *iter;
- if (j % 2 == 0) {
- p_snprintf(buf, sizeof(buf),
- "icase/dir%02d/sub01/moar%02d/file", i, j);
- cl_git_mkfile(buf, buf);
- }
- }
- }
+ g_repo = cl_git_sandbox_init("icase");
+
+ build_workdir_tree("icase", 10, 10);
+ build_workdir_tree("icase/DIR01/sUB01", 50, 0);
+ build_workdir_tree("icase/dir02/sUB01", 50, 0);
/* auto expand with no tree entries */
cl_git_pass(git_iterator_for_workdir(&iter, g_repo, 0, NULL, NULL));
@@ -808,3 +813,114 @@ void test_repo_iterator__workdir_depth(void)
expect_iterator_items(iter, 337, NULL, 337, NULL);
git_iterator_free(iter);
}
+
+void test_repo_iterator__fs(void)
+{
+ git_iterator *i;
+ static const char *expect_base[] = {
+ "DIR01/Sub02/file",
+ "DIR01/sub00/file",
+ "current_file",
+ "dir00/Sub02/file",
+ "dir00/file",
+ "dir00/sub00/file",
+ "modified_file",
+ "new_file",
+ NULL,
+ };
+ static const char *expect_trees[] = {
+ "DIR01/",
+ "DIR01/SUB03/",
+ "DIR01/Sub02/",
+ "DIR01/Sub02/file",
+ "DIR01/sUB01/",
+ "DIR01/sub00/",
+ "DIR01/sub00/file",
+ "current_file",
+ "dir00/",
+ "dir00/SUB03/",
+ "dir00/Sub02/",
+ "dir00/Sub02/file",
+ "dir00/file",
+ "dir00/sUB01/",
+ "dir00/sub00/",
+ "dir00/sub00/file",
+ "modified_file",
+ "new_file",
+ NULL,
+ };
+ static const char *expect_noauto[] = {
+ "DIR01/",
+ "current_file",
+ "dir00/",
+ "modified_file",
+ "new_file",
+ NULL,
+ };
+
+ g_repo = cl_git_sandbox_init("status");
+
+ build_workdir_tree("status/subdir", 2, 4);
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "status/subdir", 0, NULL, NULL));
+ expect_iterator_items(i, 8, expect_base, 8, expect_base);
+ git_iterator_free(i);
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "status/subdir", GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+ expect_iterator_items(i, 18, expect_trees, 18, expect_trees);
+ git_iterator_free(i);
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "status/subdir", GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+ expect_iterator_items(i, 5, expect_noauto, 18, expect_trees);
+ git_iterator_free(i);
+
+ git__tsort((void **)expect_base, 8, (git__tsort_cmp)git__strcasecmp);
+ git__tsort((void **)expect_trees, 18, (git__tsort_cmp)git__strcasecmp);
+ git__tsort((void **)expect_noauto, 5, (git__tsort_cmp)git__strcasecmp);
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "status/subdir", GIT_ITERATOR_IGNORE_CASE, NULL, NULL));
+ expect_iterator_items(i, 8, expect_base, 8, expect_base);
+ git_iterator_free(i);
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "status/subdir", GIT_ITERATOR_IGNORE_CASE |
+ GIT_ITERATOR_INCLUDE_TREES, NULL, NULL));
+ expect_iterator_items(i, 18, expect_trees, 18, expect_trees);
+ git_iterator_free(i);
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "status/subdir", GIT_ITERATOR_IGNORE_CASE |
+ GIT_ITERATOR_DONT_AUTOEXPAND, NULL, NULL));
+ expect_iterator_items(i, 5, expect_noauto, 18, expect_trees);
+ git_iterator_free(i);
+}
+
+void test_repo_iterator__fs2(void)
+{
+ git_iterator *i;
+ static const char *expect_base[] = {
+ "heads/br2",
+ "heads/dir",
+ "heads/master",
+ "heads/packed-test",
+ "heads/subtrees",
+ "heads/test",
+ "tags/e90810b",
+ "tags/foo/bar",
+ "tags/foo/foo/bar",
+ "tags/point_to_blob",
+ "tags/test",
+ NULL,
+ };
+
+ g_repo = cl_git_sandbox_init("testrepo");
+
+ cl_git_pass(git_iterator_for_filesystem(
+ &i, "testrepo/.git/refs", 0, NULL, NULL));
+ expect_iterator_items(i, 11, expect_base, 11, expect_base);
+ git_iterator_free(i);
+}
diff --git a/tests-clar/repo/setters.c b/tests-clar/repo/setters.c
index 7e482dee1..063d76c8d 100644
--- a/tests-clar/repo/setters.c
+++ b/tests-clar/repo/setters.c
@@ -1,4 +1,6 @@
#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
#include "buffer.h"
#include "posix.h"
#include "util.h"
diff --git a/tests-clar/stash/drop.c b/tests-clar/stash/drop.c
index 12f922630..60b3c72e0 100644
--- a/tests-clar/stash/drop.c
+++ b/tests-clar/stash/drop.c
@@ -146,6 +146,8 @@ void retrieve_top_stash_id(git_oid *out)
cl_git_pass(git_reference_name_to_id(out, repo, GIT_REFS_STASH_FILE));
cl_assert_equal_i(true, git_oid_cmp(out, git_object_id(top_stash)) == 0);
+
+ git_object_free(top_stash);
}
void test_stash_drop__dropping_the_top_stash_updates_the_stash_reference(void)
@@ -165,4 +167,6 @@ void test_stash_drop__dropping_the_top_stash_updates_the_stash_reference(void)
retrieve_top_stash_id(&oid);
cl_git_pass(git_oid_cmp(&oid, git_object_id(next_top_stash)));
+
+ git_object_free(next_top_stash);
}
diff --git a/tests-clar/status/worktree_init.c b/tests-clar/status/worktree_init.c
index b67107aec..296c27c86 100644
--- a/tests-clar/status/worktree_init.c
+++ b/tests-clar/status/worktree_init.c
@@ -1,4 +1,6 @@
#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
#include "fileops.h"
#include "ignore.h"
#include "status_helpers.h"
@@ -321,10 +323,10 @@ void test_status_worktree_init__new_staged_file_must_handle_crlf(void)
cl_set_cleanup(&cleanup_new_repo, "getting_started");
cl_git_pass(git_repository_init(&repo, "getting_started", 0));
- // Ensure that repo has core.autocrlf=true
+ /* Ensure that repo has core.autocrlf=true */
cl_repo_set_bool(repo, "core.autocrlf", true);
- cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); // Content with CRLF
+ cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); /* Content with CRLF */
cl_git_pass(git_repository_index(&index, repo));
cl_git_pass(git_index_add_bypath(index, "testfile.txt"));