summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: db94109)
raw | patch | inline | side by side (parent: db94109)
author | Junio C Hamano <gitster@pobox.com> | |
Sat, 30 Aug 2008 14:48:18 +0000 (07:48 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sun, 31 Aug 2008 02:28:45 +0000 (19:28 -0700) |
This lets you to check out 'our' (or 'their') version of an
unmerged path out of the index while resolving conflicts.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
unmerged path out of the index while resolving conflicts.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-checkout.txt | patch | blob | history | |
builtin-checkout.c | patch | blob | history | |
t/t7201-co.sh | patch | blob | history |
index 15fdb08ce078fe58db1c4b2484c638d0522703f2..a9ca2f552017cc592c8ff6b553bf0bbf875646a0 100644 (file)
--------
[verse]
'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
-'git checkout' [-f] [<tree-ish>] [--] <paths>...
+'git checkout' [-f|--ours|--theirs] [<tree-ish>] [--] <paths>...
DESCRIPTION
-----------
The index may contain unmerged entries after a failed merge. By
default, if you try to check out such an entry from the index, the
checkout operation will fail and nothing will be checked out.
-Using -f will ignore these unmerged entries.
+Using -f will ignore these unmerged entries. The contents from a
+specific side of the merge can be checked out of the index by
+using --ours or --theirs.
OPTIONS
-------
When checking out paths from the index, do not fail upon unmerged
entries; instead, unmerged entries are ignored.
+--ours::
+--theirs::
+ When checking out paths from the index, check out stage #2
+ ('ours') or #3 ('theirs') for unmerged paths.
+
-b::
Create a new branch named <new_branch> and start it at
<branch>. The new branch name must pass all checks defined
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 1303f3b5b363d82cdc17f925b1ed82ce0d955175..16bfbb66055951e44c19410b6c889b3aa63891ec 100644 (file)
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
int quiet;
int merge;
int force;
+ int writeout_stage;
int writeout_error;
const char *new_branch;
return pos;
}
+static int check_stage(int stage, struct cache_entry *ce, int pos)
+{
+ while (pos < active_nr &&
+ !strcmp(active_cache[pos]->name, ce->name)) {
+ if (ce_stage(active_cache[pos]) == stage)
+ return 0;
+ pos++;
+ }
+ return error("path '%s' does not have %s version",
+ ce->name,
+ (stage == 2) ? "our" : "their");
+}
+
+static int checkout_stage(int stage, struct cache_entry *ce, int pos,
+ struct checkout *state)
+{
+ while (pos < active_nr &&
+ !strcmp(active_cache[pos]->name, ce->name)) {
+ if (ce_stage(active_cache[pos]) == stage)
+ return checkout_entry(active_cache[pos], state, NULL);
+ pos++;
+ }
+ return error("path '%s' does not have %s version",
+ ce->name,
+ (stage == 2) ? "our" : "their");
+}
static int checkout_paths(struct tree *source_tree, const char **pathspec,
struct checkout_opts *opts)
int flag;
struct commit *head;
int errs = 0;
-
+ int stage = opts->writeout_stage;
int newfd;
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
continue;
if (opts->force) {
warning("path '%s' is unmerged", ce->name);
+ } else if (stage) {
+ errs |= check_stage(stage, ce, pos);
} else {
errs = 1;
error("path '%s' is unmerged", ce->name);
errs |= checkout_entry(ce, &state, NULL);
continue;
}
+ if (stage)
+ errs |= checkout_stage(stage, ce, pos, &state);
pos = skip_same_name(ce, pos) - 1;
}
}
OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
OPT_SET_INT('t', "track", &opts.track, "track",
BRANCH_TRACK_EXPLICIT),
+ OPT_SET_INT('2', "ours", &opts.writeout_stage, "stage",
+ 2),
+ OPT_SET_INT('3', "theirs", &opts.writeout_stage, "stage",
+ 3),
OPT_BOOLEAN('f', NULL, &opts.force, "force"),
OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
OPT_END(),
if (new.name && !new.commit) {
die("Cannot switch branch to a non-commit.");
}
+ if (opts.writeout_stage)
+ die("--ours/--theirs is incompatible with switching branches.");
return switch_branches(&opts, &new);
}
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 88692f98774bb22f0fb2850b6331e63e8bb65966..c7ae14118a538414c71170516d683a888878a656 100755 (executable)
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
test_cmp sample file
'
+test_expect_success 'checkout unmerged stage' '
+ rm -f .git/index &&
+ O=$(echo original | git hash-object -w --stdin) &&
+ A=$(echo ourside | git hash-object -w --stdin) &&
+ B=$(echo theirside | git hash-object -w --stdin) &&
+ (
+ echo "100644 $A 0 fild" &&
+ echo "100644 $O 1 file" &&
+ echo "100644 $A 2 file" &&
+ echo "100644 $B 3 file" &&
+ echo "100644 $A 0 filf"
+ ) | git update-index --index-info &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout --ours . &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp expect file &&
+ git checkout --theirs file &&
+ test ztheirside = "z$(cat file)"
+'
+
test_done