1
+#include "cache.h"
2
+#include "builtin.h"
3
+#include "parse-options.h"
4
+#include "refs.h"
5
+#include "commit.h"
6
+#include "tree.h"
7
+#include "tree-walk.h"
8
+#include "unpack-trees.h"
9
+#include "dir.h"
10
+#include "run-command.h"
11
+#include "merge-recursive.h"
12
+#include "branch.h"
13
+#include "diff.h"
14
+#include "revision.h"
15
+
16
+static const char * const checkout_usage[] = {
17
+ "git checkout [options] <branch>",
18
+ "git checkout [options] [<branch>] -- <file>...",
19
+ NULL,
20
+};
21
+
22
+static int post_checkout_hook(struct commit *old, struct commit *new,
23
+ int changed)
24
+{
25
+ struct child_process proc;
26
+ const char *name = git_path("hooks/post-checkout");
27
+ const char *argv[5];
28
+
29
+ if (access(name, X_OK) < 0)
30
+ return 0;
31
+
32
+ memset(&proc, 0, sizeof(proc));
33
+ argv[0] = name;
34
+ argv[1] = xstrdup(sha1_to_hex(old->object.sha1));
35
+ argv[2] = xstrdup(sha1_to_hex(new->object.sha1));
36
+ argv[3] = changed ? "1" : "0";
37
+ argv[4] = NULL;
38
+ proc.argv = argv;
39
+ proc.no_stdin = 1;
40
+ proc.stdout_to_stderr = 1;
41
+ return run_command(&proc);
42
+}
43
+
44
+static int update_some(const unsigned char *sha1, const char *base, int baselen,
45
+ const char *pathname, unsigned mode, int stage)
46
+{
47
+ int len;
48
+ struct cache_entry *ce;
49
+
50
+ if (S_ISGITLINK(mode))
51
+ return 0;
52
+
53
+ if (S_ISDIR(mode))
54
+ return READ_TREE_RECURSIVE;
55
+
56
+ len = baselen + strlen(pathname);
57
+ ce = xcalloc(1, cache_entry_size(len));
58
+ hashcpy(ce->sha1, sha1);
59
+ memcpy(ce->name, base, baselen);
60
+ memcpy(ce->name + baselen, pathname, len - baselen);
61
+ ce->ce_flags = create_ce_flags(len, 0);
62
+ ce->ce_mode = create_ce_mode(mode);
63
+ add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
64
+ return 0;
65
+}
66
+
67
+static int read_tree_some(struct tree *tree, const char **pathspec)
68
+{
69
+ int newfd;
70
+ struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
71
+ newfd = hold_locked_index(lock_file, 1);
72
+ read_cache();
73
+
74
+ read_tree_recursive(tree, "", 0, 0, pathspec, update_some);
75
+
76
+ if (write_cache(newfd, active_cache, active_nr) ||
77
+ commit_locked_index(lock_file))
78
+ die("unable to write new index file");
79
+
80
+ /* update the index with the given tree's info
81
+ * for all args, expanding wildcards, and exit
82
+ * with any non-zero return code.
83
+ */
84
+ return 0;
85
+}
86
+
87
+static int checkout_paths(const char **pathspec)
88
+{
89
+ int pos;
90
+ struct checkout state;
91
+ static char *ps_matched;
92
+ unsigned char rev[20];
93
+ int flag;
94
+ struct commit *head;
95
+
96
+ for (pos = 0; pathspec[pos]; pos++)
97
+ ;
98
+ ps_matched = xcalloc(1, pos);
99
+
100
+ for (pos = 0; pos < active_nr; pos++) {
101
+ struct cache_entry *ce = active_cache[pos];
102
+ pathspec_match(pathspec, ps_matched, ce->name, 0);
103
+ }
104
+
105
+ if (report_path_error(ps_matched, pathspec, 0))
106
+ return 1;
107
+
108
+ memset(&state, 0, sizeof(state));
109
+ state.force = 1;
110
+ state.refresh_cache = 1;
111
+ for (pos = 0; pos < active_nr; pos++) {
112
+ struct cache_entry *ce = active_cache[pos];
113
+ if (pathspec_match(pathspec, NULL, ce->name, 0)) {
114
+ checkout_entry(ce, &state, NULL);
115
+ }
116
+ }
117
+
118
+ resolve_ref("HEAD", rev, 0, &flag);
119
+ head = lookup_commit_reference_gently(rev, 1);
120
+
121
+ return post_checkout_hook(head, head, 0);
122
+}
123
+
124
+static void show_local_changes(struct object *head)
125
+{
126
+ struct rev_info rev;
127
+ /* I think we want full paths, even if we're in a subdirectory. */
128
+ init_revisions(&rev, NULL);
129
+ rev.abbrev = 0;
130
+ rev.diffopt.output_format |= DIFF_FORMAT_NAME_STATUS;
131
+ add_pending_object(&rev, head, NULL);
132
+ run_diff_index(&rev, 0);
133
+}
134
+
135
+static void describe_detached_head(char *msg, struct commit *commit)
136
+{
137
+ struct strbuf sb;
138
+ strbuf_init(&sb, 0);
139
+ parse_commit(commit);
140
+ pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, "", "", 0, 0);
141
+ fprintf(stderr, "%s %s... %s\n", msg,
142
+ find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
143
+ strbuf_release(&sb);
144
+}
145
+
146
+static int reset_to_new(struct tree *tree, int quiet)
147
+{
148
+ struct unpack_trees_options opts;
149
+ struct tree_desc tree_desc;
150
+ memset(&opts, 0, sizeof(opts));
151
+ opts.head_idx = -1;
152
+ opts.update = 1;
153
+ opts.reset = 1;
154
+ opts.merge = 1;
155
+ opts.fn = oneway_merge;
156
+ opts.verbose_update = !quiet;
157
+ parse_tree(tree);
158
+ init_tree_desc(&tree_desc, tree->buffer, tree->size);
159
+ if (unpack_trees(1, &tree_desc, &opts))
160
+ return 128;
161
+ return 0;
162
+}
163
+
164
+static void reset_clean_to_new(struct tree *tree, int quiet)
165
+{
166
+ struct unpack_trees_options opts;
167
+ struct tree_desc tree_desc;
168
+ memset(&opts, 0, sizeof(opts));
169
+ opts.head_idx = -1;
170
+ opts.skip_unmerged = 1;
171
+ opts.reset = 1;
172
+ opts.merge = 1;
173
+ opts.fn = oneway_merge;
174
+ opts.verbose_update = !quiet;
175
+ parse_tree(tree);
176
+ init_tree_desc(&tree_desc, tree->buffer, tree->size);
177
+ if (unpack_trees(1, &tree_desc, &opts))
178
+ exit(128);
179
+}
180
+
181
+struct checkout_opts {
182
+ int quiet;
183
+ int merge;
184
+ int force;
185
+
186
+ char *new_branch;
187
+ int new_branch_log;
188
+ int track;
189
+};
190
+
191
+struct branch_info {
192
+ const char *name; /* The short name used */
193
+ const char *path; /* The full name of a real branch */
194
+ struct commit *commit; /* The named commit */
195
+};
196
+
197
+static void setup_branch_path(struct branch_info *branch)
198
+{
199
+ struct strbuf buf;
200
+ strbuf_init(&buf, 0);
201
+ strbuf_addstr(&buf, "refs/heads/");
202
+ strbuf_addstr(&buf, branch->name);
203
+ branch->path = strbuf_detach(&buf, NULL);
204
+}
205
+
206
+static int merge_working_tree(struct checkout_opts *opts,
207
+ struct branch_info *old, struct branch_info *new,
208
+ const char *prefix)
209
+{
210
+ int ret;
211
+ struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
212
+ int newfd = hold_locked_index(lock_file, 1);
213
+ read_cache();
214
+
215
+ if (opts->force) {
216
+ ret = reset_to_new(new->commit->tree, opts->quiet);
217
+ if (ret)
218
+ return ret;
219
+ } else {
220
+ struct tree_desc trees[2];
221
+ struct tree *tree;
222
+ struct unpack_trees_options topts;
223
+ memset(&topts, 0, sizeof(topts));
224
+ topts.head_idx = -1;
225
+
226
+ refresh_cache(REFRESH_QUIET);
227
+
228
+ if (unmerged_cache()) {
229
+ ret = opts->merge ? -1 :
230
+ error("you need to resolve your current index first");
231
+ } else {
232
+ topts.update = 1;
233
+ topts.merge = 1;
234
+ topts.gently = opts->merge;
235
+ topts.fn = twoway_merge;
236
+ topts.dir = xcalloc(1, sizeof(*topts.dir));
237
+ topts.dir->show_ignored = 1;
238
+ topts.dir->exclude_per_dir = ".gitignore";
239
+ topts.prefix = prefix;
240
+ tree = parse_tree_indirect(old->commit->object.sha1);
241
+ init_tree_desc(&trees[0], tree->buffer, tree->size);
242
+ tree = parse_tree_indirect(new->commit->object.sha1);
243
+ init_tree_desc(&trees[1], tree->buffer, tree->size);
244
+ ret = unpack_trees(2, trees, &topts);
245
+ }
246
+ if (ret) {
247
+ /*
248
+ * Unpack couldn't do a trivial merge; either
249
+ * give up or do a real merge, depending on
250
+ * whether the merge flag was used.
251
+ */
252
+ struct tree *result;
253
+ struct tree *work;
254
+ if (!opts->merge)
255
+ return 1;
256
+ parse_commit(old->commit);
257
+
258
+ /* Do more real merge */
259
+
260
+ /*
261
+ * We update the index fully, then write the
262
+ * tree from the index, then merge the new
263
+ * branch with the current tree, with the old
264
+ * branch as the base. Then we reset the index
265
+ * (but not the working tree) to the new
266
+ * branch, leaving the working tree as the
267
+ * merged version, but skipping unmerged
268
+ * entries in the index.
269
+ */
270
+
271
+ add_files_to_cache(0, NULL, NULL);
272
+ work = write_tree_from_memory();
273
+
274
+ ret = reset_to_new(new->commit->tree, opts->quiet);
275
+ if (ret)
276
+ return ret;
277
+ merge_trees(new->commit->tree, work, old->commit->tree,
278
+ new->name, "local", &result);
279
+ reset_clean_to_new(new->commit->tree, opts->quiet);
280
+ }
281
+ }
282
+
283
+ if (write_cache(newfd, active_cache, active_nr) ||
284
+ commit_locked_index(lock_file))
285
+ die("unable to write new index file");
286
+
287
+ if (!opts->force)
288
+ show_local_changes(&new->commit->object);
289
+
290
+ return 0;
291
+}
292
+
293
+static void update_refs_for_switch(struct checkout_opts *opts,
294
+ struct branch_info *old,
295
+ struct branch_info *new)
296
+{
297
+ struct strbuf msg;
298
+ const char *old_desc;
299
+ if (opts->new_branch) {
300
+ create_branch(old->name, opts->new_branch, new->name, 0,
301
+ opts->new_branch_log, opts->track);
302
+ new->name = opts->new_branch;
303
+ setup_branch_path(new);
304
+ }
305
+
306
+ strbuf_init(&msg, 0);
307
+ old_desc = old->name;
308
+ if (!old_desc)
309
+ old_desc = sha1_to_hex(old->commit->object.sha1);
310
+ strbuf_addf(&msg, "checkout: moving from %s to %s",
311
+ old_desc, new->name);
312
+
313
+ if (new->path) {
314
+ create_symref("HEAD", new->path, msg.buf);
315
+ if (!opts->quiet) {
316
+ if (old->path && !strcmp(new->path, old->path))
317
+ fprintf(stderr, "Already on \"%s\"\n",
318
+ new->name);
319
+ else
320
+ fprintf(stderr, "Switched to%s branch \"%s\"\n",
321
+ opts->new_branch ? " a new" : "",
322
+ new->name);
323
+ }
324
+ } else if (strcmp(new->name, "HEAD")) {
325
+ update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
326
+ REF_NODEREF, DIE_ON_ERR);
327
+ if (!opts->quiet) {
328
+ if (old->path)
329
+ fprintf(stderr, "Note: moving to \"%s\" which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n git checkout -b <new_branch_name>\n", new->name);
330
+ describe_detached_head("HEAD is now at", new->commit);
331
+ }
332
+ }
333
+ remove_branch_state();
334
+ strbuf_release(&msg);
335
+}
336
+
337
+static int switch_branches(struct checkout_opts *opts,
338
+ struct branch_info *new, const char *prefix)
339
+{
340
+ int ret = 0;
341
+ struct branch_info old;
342
+ unsigned char rev[20];
343
+ int flag;
344
+ memset(&old, 0, sizeof(old));
345
+ old.path = resolve_ref("HEAD", rev, 0, &flag);
346
+ old.commit = lookup_commit_reference_gently(rev, 1);
347
+ if (!(flag & REF_ISSYMREF))
348
+ old.path = NULL;
349
+
350
+ if (old.path && !prefixcmp(old.path, "refs/heads/"))
351
+ old.name = old.path + strlen("refs/heads/");
352
+
353
+ if (!new->name) {
354
+ new->name = "HEAD";
355
+ new->commit = old.commit;
356
+ if (!new->commit)
357
+ die("You are on a branch yet to be born");
358
+ parse_commit(new->commit);
359
+ }
360
+
361
+ /*
362
+ * If the new thing isn't a branch and isn't HEAD and we're
363
+ * not starting a new branch, and we want messages, and we
364
+ * weren't on a branch, and we're moving to a new commit,
365
+ * describe the old commit.
366
+ */
367
+ if (!new->path && strcmp(new->name, "HEAD") && !opts->new_branch &&
368
+ !opts->quiet && !old.path && new->commit != old.commit)
369
+ describe_detached_head("Previous HEAD position was", old.commit);
370
+
371
+ if (!old.commit) {
372
+ if (!opts->quiet) {
373
+ fprintf(stderr, "warning: You appear to be on a branch yet to be born.\n");
374
+ fprintf(stderr, "warning: Forcing checkout of %s.\n", new->name);
375
+ }
376
+ opts->force = 1;
377
+ }
378
+
379
+ ret = merge_working_tree(opts, &old, new, prefix);
380
+ if (ret)
381
+ return ret;
382
+
383
+ update_refs_for_switch(opts, &old, new);
384
+
385
+ return post_checkout_hook(old.commit, new->commit, 1);
386
+}
387
+
388
+static int branch_track = 0;
389
+
390
+static int git_checkout_config(const char *var, const char *value)
391
+{
392
+ if (!strcmp(var, "branch.autosetupmerge"))
393
+ branch_track = git_config_bool(var, value);
394
+
395
+ return git_default_config(var, value);
396
+}
397
+
398
+int cmd_checkout(int argc, const char **argv, const char *prefix)
399
+{
400
+ struct checkout_opts opts;
401
+ unsigned char rev[20];
402
+ const char *arg;
403
+ struct branch_info new;
404
+ struct tree *source_tree = NULL;
405
+ struct option options[] = {
406
+ OPT__QUIET(&opts.quiet),
407
+ OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
408
+ OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
409
+ OPT_BOOLEAN( 0 , "track", &opts.track, "track"),
410
+ OPT_BOOLEAN('f', NULL, &opts.force, "force"),
411
+ OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
412
+ };
413
+
414
+ memset(&opts, 0, sizeof(opts));
415
+ memset(&new, 0, sizeof(new));
416
+
417
+ git_config(git_checkout_config);
418
+
419
+ opts.track = branch_track;
420
+
421
+ argc = parse_options(argc, argv, options, checkout_usage, 0);
422
+ if (argc) {
423
+ arg = argv[0];
424
+ if (get_sha1(arg, rev))
425
+ ;
426
+ else if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
427
+ new.name = arg;
428
+ setup_branch_path(&new);
429
+ if (resolve_ref(new.path, rev, 1, NULL))
430
+ new.commit = lookup_commit_reference(rev);
431
+ else
432
+ new.path = NULL;
433
+ parse_commit(new.commit);
434
+ source_tree = new.commit->tree;
435
+ argv++;
436
+ argc--;
437
+ } else if ((source_tree = parse_tree_indirect(rev))) {
438
+ argv++;
439
+ argc--;
440
+ }
441
+ }
442
+
443
+ if (argc && !strcmp(argv[0], "--")) {
444
+ argv++;
445
+ argc--;
446
+ }
447
+
448
+ if (!opts.new_branch && (opts.track != branch_track))
449
+ die("git checkout: --track and --no-track require -b");
450
+
451
+ if (opts.force && opts.merge)
452
+ die("git checkout: -f and -m are incompatible");
453
+
454
+ if (argc) {
455
+ const char **pathspec = get_pathspec(prefix, argv);
456
+ /* Checkout paths */
457
+ if (opts.new_branch || opts.force || opts.merge) {
458
+ if (argc == 1) {
459
+ die("git checkout: updating paths is incompatible with switching branches/forcing\nDid you intend to checkout '%s' which can not be resolved as commit?", argv[0]);
460
+ } else {
461
+ die("git checkout: updating paths is incompatible with switching branches/forcing");
462
+ }
463
+ }
464
+
465
+ if (source_tree)
466
+ read_tree_some(source_tree, pathspec);
467
+ else
468
+ read_cache();
469
+ return checkout_paths(pathspec);
470
+ }
471
+
472
+ if (new.name && !new.commit) {
473
+ die("Cannot switch branch to a non-commit.");
474
+ }
475
+
476
+ return switch_branches(&opts, &new, prefix);
477
+}