1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
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"
12 #include "diff.h"
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 
23 /**
24  * Checkout behavior flags
25  *
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.
29  *
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.
33  *
34  * You give checkout one of three strategies for update:
35  *
36  * - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts,
37  *   etc., but doesn't make any actual changes.
38  *
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).
42  *
43  * - `GIT_CHECKOUT_SAFE` is between these two options, it will only make
44  *   modifications that will not lose changes.
45  *
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,   | notify dirty DELETED  |     create file      |
55  *      baseline present   |                       |                      |
56  *    ---------------------|-----------------------|----------------------|
57  *
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.
61  *
62  * To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE` with a
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.
66  *
67  * To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`.
68  *
69  *
70  * There are some additional flags to modify the behavior of checkout:
71  *
72  * - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates
73  *   even if there are conflicts (instead of cancelling the checkout).
74  *
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.
77  *
78  * - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also
79  *   untracked) from the working directory as well.
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.
84  *
85  * - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the
86  *   updated files' information to the index.
87  *
88  * - Normally, checkout will reload the index and git attributes from disk
89  *   before any operations.  GIT_CHECKOUT_NO_REFRESH prevents this reload.
90  *
91  * - Unmerged index entries are conflicts.  GIT_CHECKOUT_SKIP_UNMERGED skips
92  *   files with unmerged index entries instead.  GIT_CHECKOUT_USE_OURS and
93  *   GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the
94  *   stage 2 ("ours") or stage 3 ("theirs") version of files in the index.
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.
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.
105  */
106 typedef enum {
107 	GIT_CHECKOUT_NONE = 0, /**< default is a dry run, no actual updates */
108 
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 	 */
117 	GIT_CHECKOUT_SAFE = (1u << 0),
118 
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 	 */
125 	GIT_CHECKOUT_FORCE = (1u << 1),
126 
127 
128 	/** Allow checkout to recreate missing files */
129 	GIT_CHECKOUT_RECREATE_MISSING = (1u << 2),
130 
131 	/** Allow checkout to make safe updates even if conflicts are found */
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 
137 	/** Remove ignored files not in index */
138 	GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6),
139 
140 	/** Only update existing files, don't create new ones */
141 	GIT_CHECKOUT_UPDATE_ONLY = (1u << 7),
142 
143 	/**
144 	 * Normally checkout updates index entries as it goes; this stops that.
145 	 * Implies `GIT_CHECKOUT_DONT_WRITE_INDEX`.
146 	 */
147 	GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8),
148 
149 	/** Don't refresh index/config/etc before doing checkout */
150 	GIT_CHECKOUT_NO_REFRESH = (1u << 9),
151 
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 
159 	/** Treat pathspec as simple list of exact match file paths */
160 	GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
161 
162 	/** Ignore directories in use, they will be left empty */
163 	GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18),
164 
165 	/** Don't overwrite ignored files that exist in the checkout target */
166 	GIT_CHECKOUT_DONT_OVERWRITE_IGNORED = (1u << 19),
167 
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 
174 	/** Don't overwrite existing files or folders */
175 	GIT_CHECKOUT_DONT_REMOVE_EXISTING = (1u << 22),
176 
177 	/** Normally checkout writes the index upon completion; this prevents that. */
178 	GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
179 
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),
185 
186 	/**
187 	 * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
188 	 */
189 
190 	/** Recursively checkout submodules with same options (NOT IMPLEMENTED) */
191 	GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16),
192 	/** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */
193 	GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17),
194 
195 } git_checkout_strategy_t;
196 
197 /**
198  * Checkout notification flags
199  *
200  * Checkout will invoke an options notification callback (`notify_cb`) for
201  * certain cases - you pick which ones via `notify_flags`:
202  *
203  * Returning a non-zero value from this callback will cancel the checkout.
204  * The non-zero return value will be propagated back and returned by the
205  * git_checkout_... call.
206  *
207  * Notification callbacks are made prior to modifying any files on disk,
208  * so canceling on any notification will still happen prior to any files
209  * being modified.
210  */
211 typedef enum {
212 	GIT_CHECKOUT_NOTIFY_NONE      = 0,
213 
214 	/**
215 	 * Invokes checkout on conflicting paths.
216 	 */
217 	GIT_CHECKOUT_NOTIFY_CONFLICT  = (1u << 0),
218 
219 	/**
220 	 * Notifies about "dirty" files, i.e. those that do not need an update
221 	 * but no longer match the baseline.  Core git displays these files when
222 	 * checkout runs, but won't stop the checkout.
223 	 */
224 	GIT_CHECKOUT_NOTIFY_DIRTY     = (1u << 1),
225 
226 	/**
227 	 * Sends notification for any file changed.
228 	 */
229 	GIT_CHECKOUT_NOTIFY_UPDATED   = (1u << 2),
230 
231 	/**
232 	 * Notifies about untracked files.
233 	 */
234 	GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3),
235 
236 	/**
237 	 * Notifies about ignored files.
238 	 */
239 	GIT_CHECKOUT_NOTIFY_IGNORED   = (1u << 4),
240 
241 	GIT_CHECKOUT_NOTIFY_ALL       = 0x0FFFFu
242 } git_checkout_notify_t;
243 
244 /** Checkout performance-reporting structure */
245 typedef struct {
246 	size_t mkdir_calls;
247 	size_t stat_calls;
248 	size_t chmod_calls;
249 } git_checkout_perfdata;
250 
251 /** Checkout notification callback function */
252 typedef int GIT_CALLBACK(git_checkout_notify_cb)(
253 	git_checkout_notify_t why,
254 	const char *path,
255 	const git_diff_file *baseline,
256 	const git_diff_file *target,
257 	const git_diff_file *workdir,
258 	void *payload);
259 
260 /** Checkout progress notification function */
261 typedef void GIT_CALLBACK(git_checkout_progress_cb)(
262 	const char *path,
263 	size_t completed_steps,
264 	size_t total_steps,
265 	void *payload);
266 
267 /** Checkout perfdata notification function */
268 typedef void GIT_CALLBACK(git_checkout_perfdata_cb)(
269 	const git_checkout_perfdata *perfdata,
270 	void *payload);
271 
272 /**
273  * Checkout options structure
274  *
275  * Initialize with `GIT_CHECKOUT_OPTIONS_INIT`. Alternatively, you can
276  * use `git_checkout_options_init`.
277  *
278  */
279 typedef struct git_checkout_options {
280 	unsigned int version; /**< The version */
281 
282 	unsigned int checkout_strategy; /**< default will be a safe checkout */
283 
284 	int disable_filters;    /**< don't apply filters like CRLF conversion */
285 	unsigned int dir_mode;  /**< default is 0755 */
286 	unsigned int file_mode; /**< default is 0644 or 0755 as dictated by blob */
287 	int file_open_flags;    /**< default is O_CREAT | O_TRUNC | O_WRONLY */
288 
289 	unsigned int notify_flags; /**< see `git_checkout_notify_t` above */
290 
291 	/**
292 	 * Optional callback to get notifications on specific file states.
293 	 * @see git_checkout_notify_t
294 	 */
295 	git_checkout_notify_cb notify_cb;
296 
297 	/** Payload passed to notify_cb */
298 	void *notify_payload;
299 
300 	/** Optional callback to notify the consumer of checkout progress. */
301 	git_checkout_progress_cb progress_cb;
302 
303 	/** Payload passed to progress_cb */
304 	void *progress_payload;
305 
306 	/**
307 	 * A list of wildmatch patterns or paths.
308 	 *
309 	 * By default, all paths are processed. If you pass an array of wildmatch
310 	 * patterns, those will be used to filter which paths should be taken into
311 	 * account.
312 	 *
313 	 * Use GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as a simple list.
314 	 */
315 	git_strarray paths;
316 
317 	/**
318 	 * The expected content of the working directory; defaults to HEAD.
319 	 *
320 	 * If the working directory does not match this baseline information,
321 	 * that will produce a checkout conflict.
322 	 */
323 	git_tree *baseline;
324 
325 	/**
326 	 * Like `baseline` above, though expressed as an index.  This
327 	 * option overrides `baseline`.
328 	 */
329 	git_index *baseline_index;
330 
331 	const char *target_directory; /**< alternative checkout path to workdir */
332 
333 	const char *ancestor_label; /**< the name of the common ancestor side of conflicts */
334 	const char *our_label; /**< the name of the "our" side of conflicts */
335 	const char *their_label; /**< the name of the "their" side of conflicts */
336 
337 	/** Optional callback to notify the consumer of performance data. */
338 	git_checkout_perfdata_cb perfdata_cb;
339 
340 	/** Payload passed to perfdata_cb */
341 	void *perfdata_payload;
342 } git_checkout_options;
343 
344 #define GIT_CHECKOUT_OPTIONS_VERSION 1
345 #define GIT_CHECKOUT_OPTIONS_INIT {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE}
346 
347 /**
348  * Initialize git_checkout_options structure
349  *
350  * Initializes a `git_checkout_options` with default values. Equivalent to creating
351  * an instance with GIT_CHECKOUT_OPTIONS_INIT.
352  *
353  * @param opts The `git_checkout_options` struct to initialize.
354  * @param version The struct version; pass `GIT_CHECKOUT_OPTIONS_VERSION`.
355  * @return Zero on success; -1 on failure.
356  */
357 GIT_EXTERN(int) git_checkout_options_init(
358 	git_checkout_options *opts,
359 	unsigned int version);
360 
361 /**
362  * Updates files in the index and the working tree to match the content of
363  * the commit pointed at by HEAD.
364  *
365  * Note that this is _not_ the correct mechanism used to switch branches;
366  * do not change your `HEAD` and then call this method, that would leave
367  * you with checkout conflicts since your working directory would then
368  * appear to be dirty.  Instead, checkout the target of the branch and
369  * then update `HEAD` using `git_repository_set_head` to point to the
370  * branch you checked out.
371  *
372  * @param repo repository to check out (must be non-bare)
373  * @param opts specifies checkout options (may be NULL)
374  * @return 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non
375  *         existing branch, non-zero value returned by `notify_cb`, or
376  *         other error code < 0 (use git_error_last for error details)
377  */
378 GIT_EXTERN(int) git_checkout_head(
379 	git_repository *repo,
380 	const git_checkout_options *opts);
381 
382 /**
383  * Updates files in the working tree to match the content of the index.
384  *
385  * @param repo repository into which to check out (must be non-bare)
386  * @param index index to be checked out (or NULL to use repository index)
387  * @param opts specifies checkout options (may be NULL)
388  * @return 0 on success, non-zero return value from `notify_cb`, or error
389  *         code < 0 (use git_error_last for error details)
390  */
391 GIT_EXTERN(int) git_checkout_index(
392 	git_repository *repo,
393 	git_index *index,
394 	const git_checkout_options *opts);
395 
396 /**
397  * Updates files in the index and working tree to match the content of the
398  * tree pointed at by the treeish.
399  *
400  * @param repo repository to check out (must be non-bare)
401  * @param treeish a commit, tag or tree which content will be used to update
402  * the working directory (or NULL to use HEAD)
403  * @param opts specifies checkout options (may be NULL)
404  * @return 0 on success, non-zero return value from `notify_cb`, or error
405  *         code < 0 (use git_error_last for error details)
406  */
407 GIT_EXTERN(int) git_checkout_tree(
408 	git_repository *repo,
409 	const git_object *treeish,
410 	const git_checkout_options *opts);
411 
412 /** @} */
413 GIT_END_DECL
414 #endif
415