]>
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 | * |
96b82b11 | 34 | * You give checkout one of three 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 | * |
96b82b11 ET |
43 | * - `GIT_CHECKOUT_SAFE` is between these two options, it will only make |
44 | * modifications that will not lose changes. | |
cf208031 | 45 | * |
11e2665e CMN |
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 | * ---------------------|-----------------------|----------------------| | |
96b82b11 ET |
54 | * workdir missing, | notify dirty DELETED | create file | |
55 | * baseline present | | | | |
11e2665e | 56 | * ---------------------|-----------------------|----------------------| |
cf208031 | 57 | * |
77cffa31 RB |
58 | * To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout |
59 | * notification callback (see below) that displays information about dirty | |
60 | * files. The default behavior will cancel checkout on conflicts. | |
cf208031 | 61 | * |
96b82b11 | 62 | * To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE` with a |
77cffa31 RB |
63 | * notification callback that cancels the operation if a dirty-but-existing |
64 | * file is found in the working directory. This core git command isn't | |
65 | * quite "force" but is sensitive about some types of changes. | |
cf208031 | 66 | * |
77cffa31 | 67 | * To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`. |
cf208031 | 68 | * |
cf208031 | 69 | * |
ac3d33df | 70 | * There are some additional flags to modify the behavior of checkout: |
cf208031 | 71 | * |
77cffa31 RB |
72 | * - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates |
73 | * even if there are conflicts (instead of cancelling the checkout). | |
cf208031 | 74 | * |
77cffa31 RB |
75 | * - GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not |
76 | * in target, baseline, or index, and not ignored) from the working dir. | |
cf208031 | 77 | * |
77cffa31 | 78 | * - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also |
7eb222fc | 79 | * untracked) from the working directory as well. |
77cffa31 RB |
80 | * |
81 | * - GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that | |
82 | * already exist. Files will not be created nor deleted. This just skips | |
83 | * applying adds, deletes, and typechanges. | |
cf208031 | 84 | * |
77cffa31 RB |
85 | * - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the |
86 | * updated files' information to the index. | |
ad9a921b | 87 | * |
77cffa31 RB |
88 | * - Normally, checkout will reload the index and git attributes from disk |
89 | * before any operations. GIT_CHECKOUT_NO_REFRESH prevents this reload. | |
ad9a921b | 90 | * |
77cffa31 RB |
91 | * - Unmerged index entries are conflicts. GIT_CHECKOUT_SKIP_UNMERGED skips |
92 | * files with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and | |
7eb222fc | 93 | * GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the |
77cffa31 | 94 | * stage 2 ("ours") or stage 3 ("theirs") version of files in the index. |
81a2012d ET |
95 | * |
96 | * - GIT_CHECKOUT_DONT_OVERWRITE_IGNORED prevents ignored files from being | |
97 | * overwritten. Normally, files that are ignored in the working directory | |
98 | * are not considered "precious" and may be overwritten if the checkout | |
99 | * target contains that file. | |
e74340b0 ET |
100 | * |
101 | * - GIT_CHECKOUT_DONT_REMOVE_EXISTING prevents checkout from removing | |
102 | * files or folders that fold to the same name on case insensitive | |
103 | * filesystems. This can cause files to retain their existing names | |
104 | * and write through existing symbolic links. | |
0d64bef9 RB |
105 | */ |
106 | typedef enum { | |
11e2665e | 107 | GIT_CHECKOUT_NONE = 0, /**< default is a dry run, no actual updates */ |
ad9a921b | 108 | |
22a2d3d5 UG |
109 | /** |
110 | * Allow safe updates that cannot overwrite uncommitted data. | |
111 | * If the uncommitted changes don't conflict with the checked out files, | |
112 | * the checkout will still proceed, leaving the changes intact. | |
113 | * | |
114 | * Mutually exclusive with GIT_CHECKOUT_FORCE. | |
115 | * GIT_CHECKOUT_FORCE takes precedence over GIT_CHECKOUT_SAFE. | |
116 | */ | |
cf208031 | 117 | GIT_CHECKOUT_SAFE = (1u << 0), |
ad9a921b | 118 | |
22a2d3d5 UG |
119 | /** |
120 | * Allow all updates to force working directory to look like index. | |
121 | * | |
122 | * Mutually exclusive with GIT_CHECKOUT_SAFE. | |
123 | * GIT_CHECKOUT_FORCE takes precedence over GIT_CHECKOUT_SAFE. | |
124 | */ | |
96b82b11 ET |
125 | GIT_CHECKOUT_FORCE = (1u << 1), |
126 | ||
cf208031 | 127 | |
96b82b11 ET |
128 | /** Allow checkout to recreate missing files */ |
129 | GIT_CHECKOUT_RECREATE_MISSING = (1u << 2), | |
fe67e404 | 130 | |
cf208031 | 131 | /** Allow checkout to make safe updates even if conflicts are found */ |
ad9a921b RB |
132 | GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4), |
133 | ||
134 | /** Remove untracked files not in index (that are not ignored) */ | |
135 | GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5), | |
136 | ||
cf208031 RB |
137 | /** Remove ignored files not in index */ |
138 | GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6), | |
139 | ||
ad9a921b | 140 | /** Only update existing files, don't create new ones */ |
cf208031 | 141 | GIT_CHECKOUT_UPDATE_ONLY = (1u << 7), |
ad9a921b | 142 | |
8639ea5f ET |
143 | /** |
144 | * Normally checkout updates index entries as it goes; this stops that. | |
145 | * Implies `GIT_CHECKOUT_DONT_WRITE_INDEX`. | |
146 | */ | |
5cf9875a RB |
147 | GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8), |
148 | ||
7e5c8a5b | 149 | /** Don't refresh index/config/etc before doing checkout */ |
5cf9875a | 150 | GIT_CHECKOUT_NO_REFRESH = (1u << 9), |
7e5c8a5b | 151 | |
629b661c ET |
152 | /** Allow checkout to skip unmerged files */ |
153 | GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10), | |
154 | /** For unmerged files, checkout stage 2 from index */ | |
155 | GIT_CHECKOUT_USE_OURS = (1u << 11), | |
156 | /** For unmerged files, checkout stage 3 from index */ | |
157 | GIT_CHECKOUT_USE_THEIRS = (1u << 12), | |
158 | ||
40342bd2 RB |
159 | /** Treat pathspec as simple list of exact match file paths */ |
160 | GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13), | |
161 | ||
e09d18ee ET |
162 | /** Ignore directories in use, they will be left empty */ |
163 | GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18), | |
164 | ||
81a2012d ET |
165 | /** Don't overwrite ignored files that exist in the checkout target */ |
166 | GIT_CHECKOUT_DONT_OVERWRITE_IGNORED = (1u << 19), | |
167 | ||
e651e8e2 ET |
168 | /** Write normal merge files for conflicts */ |
169 | GIT_CHECKOUT_CONFLICT_STYLE_MERGE = (1u << 20), | |
170 | ||
171 | /** Include common ancestor data in diff3 format files for conflicts */ | |
172 | GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 = (1u << 21), | |
173 | ||
e74340b0 ET |
174 | /** Don't overwrite existing files or folders */ |
175 | GIT_CHECKOUT_DONT_REMOVE_EXISTING = (1u << 22), | |
176 | ||
8639ea5f ET |
177 | /** Normally checkout writes the index upon completion; this prevents that. */ |
178 | GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23), | |
179 | ||
c25aa7cd PP |
180 | /** |
181 | * Show what would be done by a checkout. Stop after sending | |
182 | * notifications; don't update the working directory or index. | |
183 | */ | |
184 | GIT_CHECKOUT_DRY_RUN = (1u << 24), | |
e579e0f7 MB |
185 | |
186 | /** Include common ancestor data in zdiff3 format for conflicts */ | |
187 | GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3 = (1u << 25), | |
188 | ||
0f3def71 RB |
189 | /** |
190 | * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED | |
191 | */ | |
192 | ||
0f3def71 | 193 | /** Recursively checkout submodules with same options (NOT IMPLEMENTED) */ |
ad9a921b | 194 | GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16), |
0f3def71 | 195 | /** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */ |
e579e0f7 | 196 | GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17) |
ef9905c9 | 197 | |
0d64bef9 | 198 | } git_checkout_strategy_t; |
ef9905c9 | 199 | |
cf208031 RB |
200 | /** |
201 | * Checkout notification flags | |
202 | * | |
77cffa31 RB |
203 | * Checkout will invoke an options notification callback (`notify_cb`) for |
204 | * certain cases - you pick which ones via `notify_flags`: | |
205 | * | |
77cffa31 | 206 | * Returning a non-zero value from this callback will cancel the checkout. |
cbd04896 RB |
207 | * The non-zero return value will be propagated back and returned by the |
208 | * git_checkout_... call. | |
209 | * | |
210 | * Notification callbacks are made prior to modifying any files on disk, | |
211 | * so canceling on any notification will still happen prior to any files | |
212 | * being modified. | |
cf208031 RB |
213 | */ |
214 | typedef enum { | |
7e5c8a5b | 215 | GIT_CHECKOUT_NOTIFY_NONE = 0, |
c25aa7cd PP |
216 | |
217 | /** | |
218 | * Invokes checkout on conflicting paths. | |
219 | */ | |
7e5c8a5b | 220 | GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0), |
c25aa7cd PP |
221 | |
222 | /** | |
223 | * Notifies about "dirty" files, i.e. those that do not need an update | |
224 | * but no longer match the baseline. Core git displays these files when | |
225 | * checkout runs, but won't stop the checkout. | |
226 | */ | |
7e5c8a5b | 227 | GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1), |
c25aa7cd PP |
228 | |
229 | /** | |
230 | * Sends notification for any file changed. | |
231 | */ | |
7e5c8a5b | 232 | GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2), |
c25aa7cd PP |
233 | |
234 | /** | |
235 | * Notifies about untracked files. | |
236 | */ | |
cf208031 | 237 | GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3), |
c25aa7cd PP |
238 | |
239 | /** | |
240 | * Notifies about ignored files. | |
241 | */ | |
7e5c8a5b | 242 | GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4), |
36fd9e30 RB |
243 | |
244 | GIT_CHECKOUT_NOTIFY_ALL = 0x0FFFFu | |
cf208031 RB |
245 | } git_checkout_notify_t; |
246 | ||
22a2d3d5 | 247 | /** Checkout performance-reporting structure */ |
1d50b364 ET |
248 | typedef struct { |
249 | size_t mkdir_calls; | |
250 | size_t stat_calls; | |
251 | size_t chmod_calls; | |
252 | } git_checkout_perfdata; | |
253 | ||
77cffa31 | 254 | /** Checkout notification callback function */ |
ac3d33df | 255 | typedef int GIT_CALLBACK(git_checkout_notify_cb)( |
77cffa31 RB |
256 | git_checkout_notify_t why, |
257 | const char *path, | |
258 | const git_diff_file *baseline, | |
259 | const git_diff_file *target, | |
260 | const git_diff_file *workdir, | |
261 | void *payload); | |
262 | ||
263 | /** Checkout progress notification function */ | |
ac3d33df | 264 | typedef void GIT_CALLBACK(git_checkout_progress_cb)( |
77cffa31 RB |
265 | const char *path, |
266 | size_t completed_steps, | |
267 | size_t total_steps, | |
268 | void *payload); | |
269 | ||
1d50b364 | 270 | /** Checkout perfdata notification function */ |
ac3d33df | 271 | typedef void GIT_CALLBACK(git_checkout_perfdata_cb)( |
1d50b364 ET |
272 | const git_checkout_perfdata *perfdata, |
273 | void *payload); | |
274 | ||
fe67e404 RB |
275 | /** |
276 | * Checkout options structure | |
277 | * | |
ac3d33df | 278 | * Initialize with `GIT_CHECKOUT_OPTIONS_INIT`. Alternatively, you can |
22a2d3d5 | 279 | * use `git_checkout_options_init`. |
cfbe4be3 | 280 | * |
fe67e404 | 281 | */ |
6affd71f | 282 | typedef struct git_checkout_options { |
22a2d3d5 | 283 | unsigned int version; /**< The version */ |
cf208031 | 284 | |
ac3d33df | 285 | unsigned int checkout_strategy; /**< default will be a safe checkout */ |
ad9a921b | 286 | |
eb5f0346 CMN |
287 | int disable_filters; /**< don't apply filters like CRLF conversion */ |
288 | unsigned int dir_mode; /**< default is 0755 */ | |
289 | unsigned int file_mode; /**< default is 0644 or 0755 as dictated by blob */ | |
290 | int file_open_flags; /**< default is O_CREAT | O_TRUNC | O_WRONLY */ | |
3aa443a9 | 291 | |
eb5f0346 | 292 | unsigned int notify_flags; /**< see `git_checkout_notify_t` above */ |
22a2d3d5 UG |
293 | |
294 | /** | |
295 | * Optional callback to get notifications on specific file states. | |
296 | * @see git_checkout_notify_t | |
297 | */ | |
77cffa31 | 298 | git_checkout_notify_cb notify_cb; |
22a2d3d5 UG |
299 | |
300 | /** Payload passed to notify_cb */ | |
cf208031 | 301 | void *notify_payload; |
9e592583 | 302 | |
eb5f0346 | 303 | /** Optional callback to notify the consumer of checkout progress. */ |
77cffa31 | 304 | git_checkout_progress_cb progress_cb; |
22a2d3d5 UG |
305 | |
306 | /** Payload passed to progress_cb */ | |
2c8bbb27 BS |
307 | void *progress_payload; |
308 | ||
22a2d3d5 UG |
309 | /** |
310 | * A list of wildmatch patterns or paths. | |
311 | * | |
312 | * By default, all paths are processed. If you pass an array of wildmatch | |
313 | * patterns, those will be used to filter which paths should be taken into | |
314 | * account. | |
315 | * | |
316 | * Use GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as a simple list. | |
3aa443a9 | 317 | */ |
ad9a921b | 318 | git_strarray paths; |
cf208031 | 319 | |
22a2d3d5 UG |
320 | /** |
321 | * The expected content of the working directory; defaults to HEAD. | |
322 | * | |
323 | * If the working directory does not match this baseline information, | |
324 | * that will produce a checkout conflict. | |
1f1f5c63 ET |
325 | */ |
326 | git_tree *baseline; | |
327 | ||
22a2d3d5 UG |
328 | /** |
329 | * Like `baseline` above, though expressed as an index. This | |
330 | * option overrides `baseline`. | |
1f1f5c63 | 331 | */ |
22a2d3d5 | 332 | git_index *baseline_index; |
9094ae5a | 333 | |
eb5f0346 | 334 | const char *target_directory; /**< alternative checkout path to workdir */ |
629b661c | 335 | |
eb5f0346 CMN |
336 | const char *ancestor_label; /**< the name of the common ancestor side of conflicts */ |
337 | const char *our_label; /**< the name of the "our" side of conflicts */ | |
338 | const char *their_label; /**< the name of the "their" side of conflicts */ | |
1d50b364 ET |
339 | |
340 | /** Optional callback to notify the consumer of performance data. */ | |
341 | git_checkout_perfdata_cb perfdata_cb; | |
22a2d3d5 UG |
342 | |
343 | /** Payload passed to perfdata_cb */ | |
1d50b364 | 344 | void *perfdata_payload; |
6affd71f | 345 | } git_checkout_options; |
ef9905c9 | 346 | |
6affd71f | 347 | #define GIT_CHECKOUT_OPTIONS_VERSION 1 |
ac3d33df | 348 | #define GIT_CHECKOUT_OPTIONS_INIT {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE} |
cfbe4be3 | 349 | |
b9f81997 | 350 | /** |
ac3d33df JK |
351 | * Initialize git_checkout_options structure |
352 | * | |
353 | * Initializes a `git_checkout_options` with default values. Equivalent to creating | |
354 | * an instance with GIT_CHECKOUT_OPTIONS_INIT. | |
355 | * | |
356 | * @param opts The `git_checkout_options` struct to initialize. | |
357 | * @param version The struct version; pass `GIT_CHECKOUT_OPTIONS_VERSION`. | |
358 | * @return Zero on success; -1 on failure. | |
359 | */ | |
22a2d3d5 | 360 | GIT_EXTERN(int) git_checkout_options_init( |
bc91347b RB |
361 | git_checkout_options *opts, |
362 | unsigned int version); | |
b9f81997 | 363 | |
ef9905c9 | 364 | /** |
cf208031 RB |
365 | * Updates files in the index and the working tree to match the content of |
366 | * the commit pointed at by HEAD. | |
ef9905c9 | 367 | * |
a574d843 ET |
368 | * Note that this is _not_ the correct mechanism used to switch branches; |
369 | * do not change your `HEAD` and then call this method, that would leave | |
370 | * you with checkout conflicts since your working directory would then | |
371 | * appear to be dirty. Instead, checkout the target of the branch and | |
372 | * then update `HEAD` using `git_repository_set_head` to point to the | |
373 | * branch you checked out. | |
374 | * | |
ef9905c9 BS |
375 | * @param repo repository to check out (must be non-bare) |
376 | * @param opts specifies checkout options (may be NULL) | |
cbd04896 RB |
377 | * @return 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non |
378 | * existing branch, non-zero value returned by `notify_cb`, or | |
ac3d33df | 379 | * other error code < 0 (use git_error_last for error details) |
ef9905c9 | 380 | */ |
746642a6 | 381 | GIT_EXTERN(int) git_checkout_head( |
382 | git_repository *repo, | |
6affd71f | 383 | const git_checkout_options *opts); |
ef9905c9 | 384 | |
e93af304 | 385 | /** |
386 | * Updates files in the working tree to match the content of the index. | |
387 | * | |
bbe6dbec RB |
388 | * @param repo repository into which to check out (must be non-bare) |
389 | * @param index index to be checked out (or NULL to use repository index) | |
e93af304 | 390 | * @param opts specifies checkout options (may be NULL) |
cbd04896 | 391 | * @return 0 on success, non-zero return value from `notify_cb`, or error |
ac3d33df | 392 | * code < 0 (use git_error_last for error details) |
e93af304 | 393 | */ |
394 | GIT_EXTERN(int) git_checkout_index( | |
395 | git_repository *repo, | |
bbe6dbec | 396 | git_index *index, |
6affd71f | 397 | const git_checkout_options *opts); |
e93af304 | 398 | |
3aa443a9 | 399 | /** |
400 | * Updates files in the index and working tree to match the content of the | |
401 | * tree pointed at by the treeish. | |
402 | * | |
403 | * @param repo repository to check out (must be non-bare) | |
404 | * @param treeish a commit, tag or tree which content will be used to update | |
35221441 | 405 | * the working directory (or NULL to use HEAD) |
3aa443a9 | 406 | * @param opts specifies checkout options (may be NULL) |
cbd04896 | 407 | * @return 0 on success, non-zero return value from `notify_cb`, or error |
ac3d33df | 408 | * code < 0 (use git_error_last for error details) |
3aa443a9 | 409 | */ |
410 | GIT_EXTERN(int) git_checkout_tree( | |
411 | git_repository *repo, | |
cfbe4be3 | 412 | const git_object *treeish, |
6affd71f | 413 | const git_checkout_options *opts); |
14741d62 BS |
414 | |
415 | /** @} */ | |
416 | GIT_END_DECL | |
417 | #endif |