diff options
| author | Edward Thomson <ethomson@github.com> | 2017-02-13 11:10:49 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-02-13 11:10:49 +0000 |
| commit | 4f9f8e0dc9ca8a912fe1b32aeca545d25790d3fe (patch) | |
| tree | 404ecc3bc1014661b72c99076e72f3da54aca0a5 /include/git2 | |
| parent | 43275f512ef888a14c43bde8007251ce595be32a (diff) | |
| parent | 1ba242c9ab0eb323abed1b3bbc770aeb3367d855 (diff) | |
| download | libgit2-4f9f8e0dc9ca8a912fe1b32aeca545d25790d3fe.tar.gz | |
Merge pull request #3436 from pks-t/libgit2-worktree
Worktree implementation
Diffstat (limited to 'include/git2')
| -rw-r--r-- | include/git2/branch.h | 12 | ||||
| -rw-r--r-- | include/git2/errors.h | 1 | ||||
| -rw-r--r-- | include/git2/repository.h | 91 | ||||
| -rw-r--r-- | include/git2/types.h | 3 | ||||
| -rw-r--r-- | include/git2/worktree.h | 161 |
5 files changed, 268 insertions, 0 deletions
diff --git a/include/git2/branch.h b/include/git2/branch.h index 34354f4e5..88fe723a0 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -246,6 +246,18 @@ GIT_EXTERN(int) git_branch_is_head( const git_reference *branch); /** + * Determine if the current branch is checked out in any linked + * repository. + * + * @param branch Reference to the branch. + * + * @return 1 if branch is checked out, 0 if it isn't, + * error code otherwise. + */ +GIT_EXTERN(int) git_branch_is_checked_out( + const git_reference *branch); + +/** * Return the name of remote that the remote tracking branch belongs to. * * @param out Pointer to the user-allocated git_buf which will be filled with the name of the remote. diff --git a/include/git2/errors.h b/include/git2/errors.h index e959ffd8a..1d271366f 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -100,6 +100,7 @@ typedef enum { GITERR_REBASE, GITERR_FILESYSTEM, GITERR_PATCH, + GITERR_WORKTREE } git_error_t; /** diff --git a/include/git2/repository.h b/include/git2/repository.h index 3d70d1b89..a396a5409 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -35,6 +35,17 @@ GIT_BEGIN_DECL * @return 0 or an error code */ GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path); +/** + * Open working tree as a repository + * + * Open the working directory of the working tree as a normal + * repository that can then be worked on. + * + * @param out Output pointer containing opened repository + * @param wt Working tree to open + * @return 0 or an error code + */ +GIT_EXTERN(int) git_repository_open_from_worktree(git_repository **out, git_worktree *wt); /** * Create a "fake" repository to wrap an object database @@ -335,6 +346,17 @@ GIT_EXTERN(int) git_repository_init_ext( GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo); /** + * Retrieve the referenced HEAD for the worktree + * + * @param out pointer to the reference which will be retrieved + * @param repo a repository object + * @param name name of the worktree to retrieve HEAD for + * @return 0 when successful, error-code otherwise + */ +GIT_EXTERN(int) git_repository_head_for_worktree(git_reference **out, git_repository *repo, + const char *name); + +/** * Check if a repository's HEAD is detached * * A repository's HEAD is detached when it points directly to a commit @@ -346,6 +368,20 @@ GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo); */ GIT_EXTERN(int) git_repository_head_detached(git_repository *repo); +/* + * Check if a worktree's HEAD is detached + * + * A worktree's HEAD is detached when it points directly to a + * commit instead of a branch. + * + * @param repo a repository object + * @param name name of the worktree to retrieve HEAD for + * @return 1 if HEAD is detached, 0 if its not; error code if + * there was an error + */ +GIT_EXTERN(int) git_repository_head_detached_for_worktree(git_repository *repo, + const char *name); + /** * Check if the current branch is unborn * @@ -371,6 +407,42 @@ GIT_EXTERN(int) git_repository_head_unborn(git_repository *repo); GIT_EXTERN(int) git_repository_is_empty(git_repository *repo); /** + * List of items which belong to the git repository layout + */ +typedef enum { + GIT_REPOSITORY_ITEM_GITDIR, + GIT_REPOSITORY_ITEM_WORKDIR, + GIT_REPOSITORY_ITEM_COMMONDIR, + GIT_REPOSITORY_ITEM_INDEX, + GIT_REPOSITORY_ITEM_OBJECTS, + GIT_REPOSITORY_ITEM_REFS, + GIT_REPOSITORY_ITEM_PACKED_REFS, + GIT_REPOSITORY_ITEM_REMOTES, + GIT_REPOSITORY_ITEM_CONFIG, + GIT_REPOSITORY_ITEM_INFO, + GIT_REPOSITORY_ITEM_HOOKS, + GIT_REPOSITORY_ITEM_LOGS, + GIT_REPOSITORY_ITEM_MODULES, + GIT_REPOSITORY_ITEM_WORKTREES +} git_repository_item_t; + +/** + * Get the location of a specific repository file or directory + * + * This function will retrieve the path of a specific repository + * item. It will thereby honor things like the repository's + * common directory, gitdir, etc. In case a file path cannot + * exist for a given item (e.g. the working directory of a bare + * repository), an error is returned. + * + * @param out Buffer to store the path at + * @param repo Repository to get path for + * @param item The repository item for which to retrieve the path + * @return 0 on success, otherwise a negative value + */ +GIT_EXTERN(int) git_repository_item_path(git_buf *out, git_repository *repo, git_repository_item_t item); + +/** * Get the path of this repository * * This is the path of the `.git` folder for normal repositories, @@ -393,6 +465,17 @@ GIT_EXTERN(const char *) git_repository_path(git_repository *repo); GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo); /** + * Get the path of the shared common directory for this repository + * + * If the repository is bare is not a worktree, the git directory + * path is returned. + * + * @param repo A repository object + * @return the path to the common dir + */ +GIT_EXTERN(const char *) git_repository_commondir(git_repository *repo); + +/** * Set the path to the working directory for this repository * * The working directory doesn't need to be the same one @@ -421,6 +504,14 @@ GIT_EXTERN(int) git_repository_set_workdir( GIT_EXTERN(int) git_repository_is_bare(git_repository *repo); /** + * Check if a repository is a linked work tree + * + * @param repo Repo to test + * @return 1 if the repository is a linked work tree, 0 otherwise. + */ +GIT_EXTERN(int) git_repository_is_worktree(git_repository *repo); + +/** * Get the configuration file for this repository. * * If a configuration file has not been set, the default diff --git a/include/git2/types.h b/include/git2/types.h index 6f41014b3..dfdaa2920 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -104,6 +104,9 @@ typedef struct git_refdb_backend git_refdb_backend; */ typedef struct git_repository git_repository; +/** Representation of a working tree */ +typedef struct git_worktree git_worktree; + /** Representation of a generic object in a repository */ typedef struct git_object git_object; diff --git a/include/git2/worktree.h b/include/git2/worktree.h new file mode 100644 index 000000000..cad1284fa --- /dev/null +++ b/include/git2/worktree.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_worktree_h__ +#define INCLUDE_git_worktree_h__ + +#include "common.h" +#include "buffer.h" +#include "types.h" +#include "strarray.h" + +/** + * @file git2/worktrees.h + * @brief Git worktree related functions + * @defgroup git_commit Git worktree related functions + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * List names of linked working trees + * + * The returned list should be released with `git_strarray_free` + * when no longer needed. + * + * @param out pointer to the array of working tree names + * @param repo the repo to use when listing working trees + * @return 0 or an error code + */ +GIT_EXTERN(int) git_worktree_list(git_strarray *out, git_repository *repo); + +/** + * Lookup a working tree by its name for a given repository + * + * @param out Output pointer to looked up worktree or `NULL` + * @param repo The repository containing worktrees + * @param name Name of the working tree to look up + * @return 0 or an error code + */ +GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name); + +/** + * Free a previously allocated worktree + * + * @param wt worktree handle to close. If NULL nothing occurs. + */ +GIT_EXTERN(void) git_worktree_free(git_worktree *wt); + +/** + * Check if worktree is valid + * + * A valid worktree requires both the git data structures inside + * the linked parent repository and the linked working copy to be + * present. + * + * @param wt Worktree to check + * @return 0 when worktree is valid, error-code otherwise + */ +GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt); + +/** + * Add a new working tree + * + * Add a new working tree for the repository, that is create the + * required data structures inside the repository and check out + * the current HEAD at `path` + * + * @param out Output pointer containing new working tree + * @param repo Repository to create working tree for + * @param name Name of the working tree + * @param path Path to create working tree at + * @return 0 or an error code + */ +GIT_EXTERN(int) git_worktree_add(git_worktree **out, git_repository *repo, const char *name, const char *path); + +/** + * Lock worktree if not already locked + * + * Lock a worktree, optionally specifying a reason why the linked + * working tree is being locked. + * + * @param wt Worktree to lock + * @param reason Reason why the working tree is being locked + * @return 0 on success, non-zero otherwise + */ +GIT_EXTERN(int) git_worktree_lock(git_worktree *wt, char *reason); + +/** + * Unlock a locked worktree + * + * @param wt Worktree to unlock + * @return 0 on success, 1 if worktree was not locked, error-code + * otherwise + */ +GIT_EXTERN(int) git_worktree_unlock(git_worktree *wt); + +/** + * Check if worktree is locked + * + * A worktree may be locked if the linked working tree is stored + * on a portable device which is not available. + * + * @param reason Buffer to store reason in. If NULL no reason is stored. + * @param wt Worktree to check + * @return 0 when the working tree not locked, a value greater + * than zero if it is locked, less than zero if there was an + * error + */ +GIT_EXTERN(int) git_worktree_is_locked(git_buf *reason, const git_worktree *wt); + +/** + * Flags which can be passed to git_worktree_prune to alter its + * behavior. + */ +typedef enum { + /* Prune working tree even if working tree is valid */ + GIT_WORKTREE_PRUNE_VALID = 1u << 0, + /* Prune working tree even if it is locked */ + GIT_WORKTREE_PRUNE_LOCKED = 1u << 1, + /* Prune checked out working tree */ + GIT_WORKTREE_PRUNE_WORKING_TREE = 1u << 2, +} git_worktree_prune_t; + +/** + * Is the worktree prunable with the given set of flags? + * + * A worktree is not prunable in the following scenarios: + * + * - the worktree is linking to a valid on-disk worktree. The + * GIT_WORKTREE_PRUNE_VALID flag will cause this check to be + * ignored. + * - the worktree is not valid but locked. The + * GIT_WORKRTEE_PRUNE_LOCKED flag will cause this check to be + * ignored. + * + * If the worktree is not valid and not locked or if the above + * flags have been passed in, this function will return a + * positive value. + */ +GIT_EXTERN(int) git_worktree_is_prunable(git_worktree *wt, unsigned flags); + +/** + * Prune working tree + * + * Prune the working tree, that is remove the git data + * structures on disk. The repository will only be pruned of + * `git_worktree_is_prunable` succeeds. + * + * @param wt Worktree to prune + * @param flags git_worktree_prune_t flags + * @return 0 or an error code + */ +GIT_EXTERN(int) git_worktree_prune(git_worktree *wt, unsigned flags); + +/** @} */ +GIT_END_DECL +#endif |
