diff options
Diffstat (limited to 'include/git2/checkout.h')
-rw-r--r-- | include/git2/checkout.h | 155 |
1 files changed, 126 insertions, 29 deletions
diff --git a/include/git2/checkout.h b/include/git2/checkout.h index 390d2f215..a9314c2cb 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -25,20 +25,117 @@ GIT_BEGIN_DECL * Checkout behavior flags * * These flags control what checkout does with files. Pass in a - * combination of these values OR'ed together. + * combination of these values OR'ed together. If you just pass zero + * (i.e. no flags), then you are effectively doing a "dry run" where no + * files will be modified. + * + * Checkout groups the working directory content into 3 classes of files: + * (1) files that don't need a change, and files that do need a change + * that either (2) we are allowed to modifed or (3) we are not. The flags + * you pass in will decide which files we are allowed to modify. + * + * By default, checkout is not allowed to modify any files. Anything + * needing a change would be considered a conflict. + * + * GIT_CHECKOUT_UPDATE_UNMODIFIED means that checkout is allowed to update + * any file where the working directory content matches the HEAD + * (e.g. either the files match or the file is absent in both places). + * + * GIT_CHECKOUT_UPDATE_MISSING means checkout can create a missing file + * that exists in the index and does not exist in the working directory. + * This is usually desirable for initial checkout, etc. Technically, the + * missing file differs from the HEAD, which is why this is separate. + * + * GIT_CHECKOUT_UPDATE_MODIFIED means checkout is allowed to update files + * where the working directory does not match the HEAD so long as the file + * actually exists in the HEAD. This option implies UPDATE_UNMODIFIED. + * + * GIT_CHECKOUT_UPDATE_UNTRACKED means checkout is allowed to update files + * even if there is a working directory version that does not exist in the + * HEAD (i.e. the file was independently created in the workdir). This + * implies UPDATE_UNMODIFIED | UPDATE_MISSING (but *not* UPDATE_MODIFIED). + * + * + * On top of these three basic strategies, there are some modifiers + * options that can be applied: + * + * If any files need update but are disallowed by the strategy, normally + * checkout calls the conflict callback (if given) and then aborts. + * GIT_CHECKOUT_ALLOW_CONFLICTS means it is okay to update the files that + * are allowed by the strategy even if there are conflicts. The conflict + * callbacks are still made, but non-conflicting files will be updated. + * + * Any unmerged entries in the index are automatically considered conflicts. + * If you want to proceed anyhow and just skip unmerged entries, you can use + * GIT_CHECKOUT_SKIP_UNMERGED which is less dangerous than just allowing all + * conflicts. Alternatively, use GIT_CHECKOUT_USE_OURS to proceed and + * checkout the stage 2 ("ours") version. GIT_CHECKOUT_USE_THEIRS means to + * proceed and use the stage 3 ("theirs") version. + * + * GIT_CHECKOUT_UPDATE_ONLY means that update is not allowed to create new + * files or delete old ones, only update existing content. With this + * flag, files that needs to be created or deleted are not conflicts - + * they are just skipped. This also skips typechanges to existing files + * (because the old would have to be removed). + * + * GIT_CHECKOUT_REMOVE_UNTRACKED means that files in the working directory + * that are untracked (and not ignored) will be removed altogether. These + * untracked files (that do not shadow index entries) are not considered + * conflicts and would normally be ignored. + * + * + * Checkout is "semi-atomic" as in it will go through the work to be done + * before making any changes and if may decide to abort if there are + * conflicts, or you can use the conflict callback to explicitly abort the + * action before any updates are made. Despite this, if a second process + * is modifying the filesystem while checkout is running, it can't + * guarantee that the choices is makes while initially examining the + * filesystem are still going to be correct as it applies them. */ typedef enum { - /** Checkout does not update any files in the working directory. */ - GIT_CHECKOUT_DEFAULT = (1 << 0), + GIT_CHECKOUT_DEFAULT = 0, /** default is a dry run, no actual updates */ + + /** Allow update of entries where working dir matches HEAD. */ + GIT_CHECKOUT_UPDATE_UNMODIFIED = (1u << 0), + + /** Allow update of entries where working dir does not have file. */ + GIT_CHECKOUT_UPDATE_MISSING = (1u << 1), + + /** Allow safe updates that cannot overwrite uncommited data */ + GIT_CHECKOUT_SAFE = + (GIT_CHECKOUT_UPDATE_UNMODIFIED | GIT_CHECKOUT_UPDATE_MISSING), + + /** Allow update of entries in working dir that are modified from HEAD. */ + GIT_CHECKOUT_UPDATE_MODIFIED = (1u << 2), + + /** Update existing untracked files that are now present in the index. */ + GIT_CHECKOUT_UPDATE_UNTRACKED = (1u << 3), - /** When a file exists and is modified, replace it with new version. */ - GIT_CHECKOUT_OVERWRITE_MODIFIED = (1 << 1), + /** Allow all updates to force working directory to look like index */ + GIT_CHECKOUT_FORCE = + (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_MODIFIED | GIT_CHECKOUT_UPDATE_UNTRACKED), - /** When a file does not exist in the working directory, create it. */ - GIT_CHECKOUT_CREATE_MISSING = (1 << 2), + /** Allow checkout to make updates even if conflicts are found */ + GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4), + + /** Remove untracked files not in index (that are not ignored) */ + GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5), + + /** Only update existing files, don't create new ones */ + GIT_CHECKOUT_UPDATE_ONLY = (1u << 6), + + /** Allow checkout to skip unmerged files */ + GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10), + /** For unmerged files, checkout stage 2 from index */ + GIT_CHECKOUT_USE_OURS = (1u << 11), + /** For unmerged files, checkout stage 3 from index */ + GIT_CHECKOUT_USE_THEIRS = (1u << 12), + + /** Recursively checkout submodule with same options */ + GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16), + /** Recursively checkout submodules only if HEAD moved in super repo */ + GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17), - /** If an untracked file in found in the working dir, delete it. */ - GIT_CHECKOUT_REMOVE_UNTRACKED = (1 << 3), } git_checkout_strategy_t; /** @@ -47,38 +144,38 @@ typedef enum { * Use zeros to indicate default settings. */ typedef struct git_checkout_opts { - unsigned int checkout_strategy; /** default: GIT_CHECKOUT_DEFAULT */ + unsigned int checkout_strategy; /** default will be a dry run */ + int disable_filters; /** don't apply filters like CRLF conversion */ int dir_mode; /** default is 0755 */ int file_mode; /** default is 0644 or 0755 as dictated by blob */ int file_open_flags; /** default is O_CREAT | O_TRUNC | O_WRONLY */ - /** Optional callback to notify the consumer of files that - * haven't be checked out because a modified version of them - * exist in the working directory. - * - * When provided, this callback will be invoked when the flag - * GIT_CHECKOUT_OVERWRITE_MODIFIED isn't part of the checkout strategy. + /** Optional callback made on files where the index differs from the + * working directory but the rules do not allow update. Return a + * non-zero value to abort the checkout. All such callbacks will be + * made before any changes are made to the working directory. */ - int (* skipped_notify_cb)( - const char *skipped_file, - const git_oid *blob_oid, - int file_mode, + int (*conflict_cb)( + const char *conflicting_path, + const git_oid *index_oid, + unsigned int index_mode, + unsigned int wd_mode, void *payload); - void *notify_payload; + void *conflict_payload; /* Optional callback to notify the consumer of checkout progress. */ - void (* progress_cb)( - const char *path, - size_t completed_steps, - size_t total_steps, - void *payload); + void (*progress_cb)( + const char *path, + size_t completed_steps, + size_t total_steps, + void *payload); void *progress_payload; - /** When not NULL, array of fnmatch patterns specifying - * which paths should be taken into account + /** When not zeroed out, array of fnmatch patterns specifying which + * paths should be taken into account, otherwise all files. */ - git_strarray paths; + git_strarray paths; } git_checkout_opts; /** |