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 modified 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 	/** Allow safe updates that cannot overwrite uncommitted data */
110 	GIT_CHECKOUT_SAFE = (1u << 0),
111 
112 	/** Allow all updates to force working directory to look like index */
113 	GIT_CHECKOUT_FORCE = (1u << 1),
114 
115 
116 	/** Allow checkout to recreate missing files */
117 	GIT_CHECKOUT_RECREATE_MISSING = (1u << 2),
118 
119 	/** Allow checkout to make safe updates even if conflicts are found */
120 	GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4),
121 
122 	/** Remove untracked files not in index (that are not ignored) */
123 	GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5),
124 
125 	/** Remove ignored files not in index */
126 	GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6),
127 
128 	/** Only update existing files, don't create new ones */
129 	GIT_CHECKOUT_UPDATE_ONLY = (1u << 7),
130 
131 	/**
132 	 * Normally checkout updates index entries as it goes; this stops that.
133 	 * Implies `GIT_CHECKOUT_DONT_WRITE_INDEX`.
134 	 */
135 	GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8),
136 
137 	/** Don't refresh index/config/etc before doing checkout */
138 	GIT_CHECKOUT_NO_REFRESH = (1u << 9),
139 
140 	/** Allow checkout to skip unmerged files */
141 	GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10),
142 	/** For unmerged files, checkout stage 2 from index */
143 	GIT_CHECKOUT_USE_OURS = (1u << 11),
144 	/** For unmerged files, checkout stage 3 from index */
145 	GIT_CHECKOUT_USE_THEIRS = (1u << 12),
146 
147 	/** Treat pathspec as simple list of exact match file paths */
148 	GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH = (1u << 13),
149 
150 	/** Ignore directories in use, they will be left empty */
151 	GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES = (1u << 18),
152 
153 	/** Don't overwrite ignored files that exist in the checkout target */
154 	GIT_CHECKOUT_DONT_OVERWRITE_IGNORED = (1u << 19),
155 
156 	/** Write normal merge files for conflicts */
157 	GIT_CHECKOUT_CONFLICT_STYLE_MERGE = (1u << 20),
158 
159 	/** Include common ancestor data in diff3 format files for conflicts */
160 	GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 = (1u << 21),
161 
162 	/** Don't overwrite existing files or folders */
163 	GIT_CHECKOUT_DONT_REMOVE_EXISTING = (1u << 22),
164 
165 	/** Normally checkout writes the index upon completion; this prevents that. */
166 	GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23),
167 
168 	/**
169 	 * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
170 	 */
171 
172 	/** Recursively checkout submodules with same options (NOT IMPLEMENTED) */
173 	GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16),
174 	/** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */
175 	GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17),
176 
177 } git_checkout_strategy_t;
178 
179 /**
180  * Checkout notification flags
181  *
182  * Checkout will invoke an options notification callback (`notify_cb`) for
183  * certain cases - you pick which ones via `notify_flags`:
184  *
185  * - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths.
186  *
187  * - GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that
188  *   do not need an update but no longer match the baseline.  Core git
189  *   displays these files when checkout runs, but won't stop the checkout.
190  *
191  * - GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed.
192  *
193  * - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files.
194  *
195  * - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files.
196  *
197  * Returning a non-zero value from this callback will cancel the checkout.
198  * The non-zero return value will be propagated back and returned by the
199  * git_checkout_... call.
200  *
201  * Notification callbacks are made prior to modifying any files on disk,
202  * so canceling on any notification will still happen prior to any files
203  * being modified.
204  */
205 typedef enum {
206 	GIT_CHECKOUT_NOTIFY_NONE      = 0,
207 	GIT_CHECKOUT_NOTIFY_CONFLICT  = (1u << 0),
208 	GIT_CHECKOUT_NOTIFY_DIRTY     = (1u << 1),
209 	GIT_CHECKOUT_NOTIFY_UPDATED   = (1u << 2),
210 	GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3),
211 	GIT_CHECKOUT_NOTIFY_IGNORED   = (1u << 4),
212 
213 	GIT_CHECKOUT_NOTIFY_ALL       = 0x0FFFFu
214 } git_checkout_notify_t;
215 
216 typedef struct {
217 	size_t mkdir_calls;
218 	size_t stat_calls;
219 	size_t chmod_calls;
220 } git_checkout_perfdata;
221 
222 /** Checkout notification callback function */
223 typedef int (*git_checkout_notify_cb)(
224 	git_checkout_notify_t why,
225 	const char *path,
226 	const git_diff_file *baseline,
227 	const git_diff_file *target,
228 	const git_diff_file *workdir,
229 	void *payload);
230 
231 /** Checkout progress notification function */
232 typedef void (*git_checkout_progress_cb)(
233 	const char *path,
234 	size_t completed_steps,
235 	size_t total_steps,
236 	void *payload);
237 
238 /** Checkout perfdata notification function */
239 typedef void (*git_checkout_perfdata_cb)(
240 	const git_checkout_perfdata *perfdata,
241 	void *payload);
242 
243 /**
244  * Checkout options structure
245  *
246  * Zero out for defaults.  Initialize with `GIT_CHECKOUT_OPTIONS_INIT` macro to
247  * correctly set the `version` field.  E.g.
248  *
249  *		git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
250  */
251 typedef struct git_checkout_options {
252 	unsigned int version;
253 
254 	unsigned int checkout_strategy; /**< default will be a safe checkout */
255 
256 	int disable_filters;    /**< don't apply filters like CRLF conversion */
257 	unsigned int dir_mode;  /**< default is 0755 */
258 	unsigned int file_mode; /**< default is 0644 or 0755 as dictated by blob */
259 	int file_open_flags;    /**< default is O_CREAT | O_TRUNC | O_WRONLY */
260 
261 	unsigned int notify_flags; /**< see `git_checkout_notify_t` above */
262 	git_checkout_notify_cb notify_cb;
263 	void *notify_payload;
264 
265 	/** Optional callback to notify the consumer of checkout progress. */
266 	git_checkout_progress_cb progress_cb;
267 	void *progress_payload;
268 
269 	/** When not zeroed out, array of fnmatch patterns specifying which
270 	 *  paths should be taken into account, otherwise all files.  Use
271 	 *  GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH to treat as simple list.
272 	 */
273 	git_strarray paths;
274 
275 	/** The expected content of the working directory; defaults to HEAD.
276 	 *  If the working directory does not match this baseline information,
277 	 *  that will produce a checkout conflict.
278 	 */
279 	git_tree *baseline;
280 
281 	/** Like `baseline` above, though expressed as an index.  This
282 	 *  option overrides `baseline`.
283 	 */
284 	git_index *baseline_index; /**< expected content of workdir, expressed as an index. */
285 
286 	const char *target_directory; /**< alternative checkout path to workdir */
287 
288 	const char *ancestor_label; /**< the name of the common ancestor side of conflicts */
289 	const char *our_label; /**< the name of the "our" side of conflicts */
290 	const char *their_label; /**< the name of the "their" side of conflicts */
291 
292 	/** Optional callback to notify the consumer of performance data. */
293 	git_checkout_perfdata_cb perfdata_cb;
294 	void *perfdata_payload;
295 } git_checkout_options;
296 
297 #define GIT_CHECKOUT_OPTIONS_VERSION 1
298 #define GIT_CHECKOUT_OPTIONS_INIT {GIT_CHECKOUT_OPTIONS_VERSION, GIT_CHECKOUT_SAFE}
299 
300 /**
301 * Initializes a `git_checkout_options` with default values. Equivalent to
302 * creating an instance with GIT_CHECKOUT_OPTIONS_INIT.
303 *
304 * @param opts the `git_checkout_options` struct to initialize.
305 * @param version Version of struct; pass `GIT_CHECKOUT_OPTIONS_VERSION`
306 * @return Zero on success; -1 on failure.
307 */
308 GIT_EXTERN(int) git_checkout_init_options(
309 	git_checkout_options *opts,
310 	unsigned int version);
311 
312 /**
313  * Updates files in the index and the working tree to match the content of
314  * the commit pointed at by HEAD.
315  *
316  * Note that this is _not_ the correct mechanism used to switch branches;
317  * do not change your `HEAD` and then call this method, that would leave
318  * you with checkout conflicts since your working directory would then
319  * appear to be dirty.  Instead, checkout the target of the branch and
320  * then update `HEAD` using `git_repository_set_head` to point to the
321  * branch you checked out.
322  *
323  * @param repo repository to check out (must be non-bare)
324  * @param opts specifies checkout options (may be NULL)
325  * @return 0 on success, GIT_EUNBORNBRANCH if HEAD points to a non
326  *         existing branch, non-zero value returned by `notify_cb`, or
327  *         other error code < 0 (use giterr_last for error details)
328  */
329 GIT_EXTERN(int) git_checkout_head(
330 	git_repository *repo,
331 	const git_checkout_options *opts);
332 
333 /**
334  * Updates files in the working tree to match the content of the index.
335  *
336  * @param repo repository into which to check out (must be non-bare)
337  * @param index index to be checked out (or NULL to use repository index)
338  * @param opts specifies checkout options (may be NULL)
339  * @return 0 on success, non-zero return value from `notify_cb`, or error
340  *         code < 0 (use giterr_last for error details)
341  */
342 GIT_EXTERN(int) git_checkout_index(
343 	git_repository *repo,
344 	git_index *index,
345 	const git_checkout_options *opts);
346 
347 /**
348  * Updates files in the index and working tree to match the content of the
349  * tree pointed at by the treeish.
350  *
351  * @param repo repository to check out (must be non-bare)
352  * @param treeish a commit, tag or tree which content will be used to update
353  * the working directory (or NULL to use HEAD)
354  * @param opts specifies checkout options (may be NULL)
355  * @return 0 on success, non-zero return value from `notify_cb`, or error
356  *         code < 0 (use giterr_last for error details)
357  */
358 GIT_EXTERN(int) git_checkout_tree(
359 	git_repository *repo,
360 	const git_object *treeish,
361 	const git_checkout_options *opts);
362 
363 /** @} */
364 GIT_END_DECL
365 #endif
366