]>
Commit | Line | Data |
---|---|---|
14741d62 | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
14741d62 BS |
3 | * |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with | |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
6 | */ | |
7 | #ifndef INCLUDE_git_checkout_h__ | |
8 | #define INCLUDE_git_checkout_h__ | |
9 | ||
10 | #include "common.h" | |
11 | #include "types.h" | |
7e5c8a5b | 12 | #include "diff.h" |
14741d62 BS |
13 | |
14 | /** | |
15 | * @file git2/checkout.h | |
16 | * @brief Git checkout routines | |
17 | * @defgroup git_checkout Git checkout routines | |
18 | * @ingroup Git | |
19 | * @{ | |
20 | */ | |
21 | GIT_BEGIN_DECL | |
22 | ||
0d64bef9 RB |
23 | /** |
24 | * Checkout behavior flags | |
25 | * | |
77cffa31 RB |
26 | * In libgit2, checkout is used to update the working directory and index |
27 | * to match a target tree. Unlike git checkout, it does not move the HEAD | |
28 | * commit for you - use `git_repository_set_head` or the like to do that. | |
cf208031 | 29 | * |
77cffa31 RB |
30 | * Checkout looks at (up to) four things: the "target" tree you want to |
31 | * check out, the "baseline" tree of what was checked out previously, the | |
32 | * working directory for actual files, and the index for staged changes. | |
cf208031 | 33 | * |
77cffa31 | 34 | * You give checkout one of four strategies for update: |
cf208031 | 35 | * |
77cffa31 RB |
36 | * - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts, |
37 | * etc., but doesn't make any actual changes. | |
cf208031 | 38 | * |
77cffa31 RB |
39 | * - `GIT_CHECKOUT_FORCE` is at the opposite extreme, taking any action to |
40 | * make the working directory match the target (including potentially | |
41 | * discarding modified files). | |
cf208031 | 42 | * |
77cffa31 RB |
43 | * In between those are `GIT_CHECKOUT_SAFE` and `GIT_CHECKOUT_SAFE_CREATE` |
44 | * both of which only make modifications that will not lose changes. | |
cf208031 | 45 | * |
77cffa31 RB |
46 | * | target == baseline | target != baseline | |
47 | * ---------------------|-----------------------|----------------------| | |
48 | * workdir == baseline | no action | create, update, or | | |
49 | * | | delete file | | |
50 | * ---------------------|-----------------------|----------------------| | |
51 | * workdir exists and | no action | conflict (notify | | |
52 | * is != baseline | notify dirty MODIFIED | and cancel checkout) | | |
53 | * ---------------------|-----------------------|----------------------| | |
54 | * workdir missing, | create if SAFE_CREATE | create file | | |
55 | * baseline present | notify dirty DELETED | | | |
56 | * ---------------------|-----------------------|----------------------| | |
cf208031 | 57 | * |
77cffa31 RB |
58 | * The only difference between SAFE and SAFE_CREATE is that SAFE_CREATE |
59 | * will cause a file to be checked out if it is missing from the working | |
60 | * directory even if it is not modified between the target and baseline. | |
cf208031 | 61 | * |
cf208031 | 62 | * |
77cffa31 RB |
63 | * To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout |
64 | * notification callback (see below) that displays information about dirty | |
65 | * files. The default behavior will cancel checkout on conflicts. | |
cf208031 | 66 | * |
77cffa31 RB |
67 | * To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE_CREATE` with a |
68 | * notification callback that cancels the operation if a dirty-but-existing | |
69 | * file is found in the working directory. This core git command isn't | |
70 | * quite "force" but is sensitive about some types of changes. | |
cf208031 | 71 | * |
77cffa31 | 72 | * To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`. |
cf208031 | 73 | * |
77cffa31 | 74 | * To emulate `git clone` use `GIT_CHECKOUT_SAFE_CREATE` in the options. |
cf208031 | 75 | * |
cf208031 | 76 | * |
77cffa31 | 77 | * There are some additional flags to modified the behavior of checkout: |
cf208031 | 78 | * |
77cffa31 RB |
79 | * - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates |
80 | * even if there are conflicts (instead of cancelling the checkout). | |
cf208031 | 81 | * |
77cffa31 RB |
82 | * - GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not |
83 | * in target, baseline, or index, and not ignored) from the working dir. | |
cf208031 | 84 | * |
77cffa31 | 85 | * - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also |
7eb222fc | 86 | * untracked) from the working directory as well. |
77cffa31 RB |
87 | * |
88 | * - GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that | |
89 | * already exist. Files will not be created nor deleted. This just skips | |
90 | * applying adds, deletes, and typechanges. | |
cf208031 | 91 | * |
77cffa31 RB |
92 | * - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the |
93 | * updated files' information to the index. | |
ad9a921b | 94 | * |
77cffa31 RB |
95 | * - Normally, checkout will reload the index and git attributes from disk |
96 | * before any operations. GIT_CHECKOUT_NO_REFRESH prevents this reload. | |
ad9a921b | 97 | * |
77cffa31 RB |
98 | * - Unmerged index entries are conflicts. GIT_CHECKOUT_SKIP_UNMERGED skips |
99 | * files with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and | |
7eb222fc | 100 | * GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the |
77cffa31 | 101 | * stage 2 ("ours") or stage 3 ("theirs") version of files in the index. |
0d64bef9 RB |
102 | */ |
103 | typedef enum { | |
cf208031 | 104 | GIT_CHECKOUT_NONE = 0, /** default is a dry run, no actual updates */ |
ad9a921b | 105 | |
7eb222fc | 106 | /** Allow safe updates that cannot overwrite uncommitted data */ |
cf208031 | 107 | GIT_CHECKOUT_SAFE = (1u << 0), |
ad9a921b | 108 | |
cf208031 RB |
109 | /** Allow safe updates plus creation of missing files */ |
110 | GIT_CHECKOUT_SAFE_CREATE = (1u << 1), | |
fe67e404 | 111 | |
ad9a921b | 112 | /** Allow all updates to force working directory to look like index */ |
cf208031 RB |
113 | GIT_CHECKOUT_FORCE = (1u << 2), |
114 | ||
fe67e404 | 115 | |
cf208031 | 116 | /** Allow checkout to make safe updates even if conflicts are found */ |
ad9a921b RB |
117 | GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4), |
118 | ||
119 | /** Remove untracked files not in index (that are not ignored) */ | |
120 | GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5), | |
121 | ||
cf208031 RB |
122 | /** Remove ignored files not in index */ |
123 | GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6), | |
124 | ||
ad9a921b | 125 | /** Only update existing files, don't create new ones */ |
cf208031 | 126 | GIT_CHECKOUT_UPDATE_ONLY = (1u << 7), |
ad9a921b | 127 | |
5cf9875a RB |
128 | /** Normally checkout updates index entries as it goes; this stops that */ |
129 | GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8), | |
130 | ||
7e5c8a5b | 131 | /** Don't refresh index/config/etc before doing checkout */ |
5cf9875a | 132 | GIT_CHECKOUT_NO_REFRESH = (1u << 9), |
7e5c8a5b | 133 | |
40342bd2 RB |
134 | /** Treat pathspec as simple list of exact match file paths */ |
135 | GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13), | |
136 | ||
0f3def71 RB |
137 | /** |
138 | * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED | |
139 | */ | |
140 | ||
141 | /** Allow checkout to skip unmerged files (NOT IMPLEMENTED) */ | |
ad9a921b | 142 | GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10), |
0f3def71 | 143 | /** For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) */ |
ad9a921b | 144 | GIT_CHECKOUT_USE_OURS = (1u << 11), |
0f3def71 | 145 | /** For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) */ |
ad9a921b RB |
146 | GIT_CHECKOUT_USE_THEIRS = (1u << 12), |
147 | ||
0f3def71 | 148 | /** Recursively checkout submodules with same options (NOT IMPLEMENTED) */ |
ad9a921b | 149 | GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16), |
0f3def71 | 150 | /** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */ |
ad9a921b | 151 | GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17), |
ef9905c9 | 152 | |
0d64bef9 | 153 | } git_checkout_strategy_t; |
ef9905c9 | 154 | |
cf208031 RB |
155 | /** |
156 | * Checkout notification flags | |
157 | * | |
77cffa31 RB |
158 | * Checkout will invoke an options notification callback (`notify_cb`) for |
159 | * certain cases - you pick which ones via `notify_flags`: | |
160 | * | |
161 | * - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths. | |
162 | * | |
163 | * - GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that | |
164 | * do not need an update but no longer match the baseline. Core git | |
165 | * displays these files when checkout runs, but won't stop the checkout. | |
166 | * | |
167 | * - GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed. | |
168 | * | |
169 | * - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files. | |
170 | * | |
171 | * - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files. | |
172 | * | |
173 | * Returning a non-zero value from this callback will cancel the checkout. | |
174 | * Notification callbacks are made prior to modifying any files on disk. | |
cf208031 RB |
175 | */ |
176 | typedef enum { | |
7e5c8a5b RB |
177 | GIT_CHECKOUT_NOTIFY_NONE = 0, |
178 | GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0), | |
179 | GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1), | |
180 | GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2), | |
cf208031 | 181 | GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3), |
7e5c8a5b | 182 | GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4), |
cf208031 RB |
183 | } git_checkout_notify_t; |
184 | ||
77cffa31 RB |
185 | /** Checkout notification callback function */ |
186 | typedef int (*git_checkout_notify_cb)( | |
187 | git_checkout_notify_t why, | |
188 | const char *path, | |
189 | const git_diff_file *baseline, | |
190 | const git_diff_file *target, | |
191 | const git_diff_file *workdir, | |
192 | void *payload); | |
193 | ||
194 | /** Checkout progress notification function */ | |
195 | typedef void (*git_checkout_progress_cb)( | |
196 | const char *path, | |
197 | size_t completed_steps, | |
198 | size_t total_steps, | |
199 | void *payload); | |
200 | ||
fe67e404 RB |
201 | /** |
202 | * Checkout options structure | |
203 | * | |
77cffa31 RB |
204 | * Zero out for defaults. Initialize with `GIT_CHECKOUT_OPTS_INIT` macro to |
205 | * correctly set the `version` field. E.g. | |
cfbe4be3 VM |
206 | * |
207 | * git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; | |
fe67e404 | 208 | */ |
ef9905c9 | 209 | typedef struct git_checkout_opts { |
cfbe4be3 | 210 | unsigned int version; |
cf208031 | 211 | |
ad9a921b RB |
212 | unsigned int checkout_strategy; /** default will be a dry run */ |
213 | ||
cf208031 RB |
214 | int disable_filters; /** don't apply filters like CRLF conversion */ |
215 | unsigned int dir_mode; /** default is 0755 */ | |
216 | unsigned int file_mode; /** default is 0644 or 0755 as dictated by blob */ | |
217 | int file_open_flags; /** default is O_CREAT | O_TRUNC | O_WRONLY */ | |
3aa443a9 | 218 | |
cf208031 | 219 | unsigned int notify_flags; /** see `git_checkout_notify_t` above */ |
77cffa31 | 220 | git_checkout_notify_cb notify_cb; |
cf208031 | 221 | void *notify_payload; |
9e592583 | 222 | |
2c8bbb27 | 223 | /* Optional callback to notify the consumer of checkout progress. */ |
77cffa31 | 224 | git_checkout_progress_cb progress_cb; |
2c8bbb27 BS |
225 | void *progress_payload; |
226 | ||
ad9a921b | 227 | /** When not zeroed out, array of fnmatch patterns specifying which |
40342bd2 RB |
228 | * paths should be taken into account, otherwise all files. Use |
229 | * GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as simple list. | |
3aa443a9 | 230 | */ |
ad9a921b | 231 | git_strarray paths; |
cf208031 RB |
232 | |
233 | git_tree *baseline; /** expected content of workdir, defaults to HEAD */ | |
ef9905c9 BS |
234 | } git_checkout_opts; |
235 | ||
bde336ea | 236 | #define GIT_CHECKOUT_OPTS_VERSION 1 |
fac43c54 | 237 | #define GIT_CHECKOUT_OPTS_INIT {GIT_CHECKOUT_OPTS_VERSION} |
cfbe4be3 | 238 | |
ef9905c9 | 239 | /** |
cf208031 RB |
240 | * Updates files in the index and the working tree to match the content of |
241 | * the commit pointed at by HEAD. | |
ef9905c9 BS |
242 | * |
243 | * @param repo repository to check out (must be non-bare) | |
244 | * @param opts specifies checkout options (may be NULL) | |
8b05bea8 | 245 | * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing |
246 | * branch, GIT_ERROR otherwise (use giterr_last for information | |
746642a6 | 247 | * about the error) |
ef9905c9 | 248 | */ |
746642a6 | 249 | GIT_EXTERN(int) git_checkout_head( |
250 | git_repository *repo, | |
80642656 | 251 | git_checkout_opts *opts); |
ef9905c9 | 252 | |
e93af304 | 253 | /** |
254 | * Updates files in the working tree to match the content of the index. | |
255 | * | |
bbe6dbec RB |
256 | * @param repo repository into which to check out (must be non-bare) |
257 | * @param index index to be checked out (or NULL to use repository index) | |
e93af304 | 258 | * @param opts specifies checkout options (may be NULL) |
e93af304 | 259 | * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information |
260 | * about the error) | |
261 | */ | |
262 | GIT_EXTERN(int) git_checkout_index( | |
263 | git_repository *repo, | |
bbe6dbec | 264 | git_index *index, |
2c8bbb27 | 265 | git_checkout_opts *opts); |
e93af304 | 266 | |
3aa443a9 | 267 | /** |
268 | * Updates files in the index and working tree to match the content of the | |
269 | * tree pointed at by the treeish. | |
270 | * | |
271 | * @param repo repository to check out (must be non-bare) | |
272 | * @param treeish a commit, tag or tree which content will be used to update | |
273 | * the working directory | |
274 | * @param opts specifies checkout options (may be NULL) | |
3aa443a9 | 275 | * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information |
276 | * about the error) | |
277 | */ | |
278 | GIT_EXTERN(int) git_checkout_tree( | |
279 | git_repository *repo, | |
cfbe4be3 | 280 | const git_object *treeish, |
80642656 | 281 | git_checkout_opts *opts); |
14741d62 BS |
282 | |
283 | /** @} */ | |
284 | GIT_END_DECL | |
285 | #endif |