зеркало из https://github.com/microsoft/git.git
Merge branch 'jc/maint-checkout-fix'
* jc/maint-checkout-fix: checkout: do not check out unmerged higher stages randomly Conflicts: t/t7201-co.sh
This commit is contained in:
Коммит
11bd3ddb91
|
@ -76,6 +76,15 @@ static int read_tree_some(struct tree *tree, const char **pathspec)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int skip_same_name(struct cache_entry *ce, int pos)
|
||||||
|
{
|
||||||
|
while (++pos < active_nr &&
|
||||||
|
!strcmp(active_cache[pos]->name, ce->name))
|
||||||
|
; /* skip */
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int checkout_paths(struct tree *source_tree, const char **pathspec)
|
static int checkout_paths(struct tree *source_tree, const char **pathspec)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
|
@ -107,6 +116,20 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec)
|
||||||
if (report_path_error(ps_matched, pathspec, 0))
|
if (report_path_error(ps_matched, pathspec, 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Any unmerged paths? */
|
||||||
|
for (pos = 0; pos < active_nr; pos++) {
|
||||||
|
struct cache_entry *ce = active_cache[pos];
|
||||||
|
if (pathspec_match(pathspec, NULL, ce->name, 0)) {
|
||||||
|
if (!ce_stage(ce))
|
||||||
|
continue;
|
||||||
|
errs = 1;
|
||||||
|
error("path '%s' is unmerged", ce->name);
|
||||||
|
pos = skip_same_name(ce, pos) - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errs)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Now we are committed to check them out */
|
/* Now we are committed to check them out */
|
||||||
memset(&state, 0, sizeof(state));
|
memset(&state, 0, sizeof(state));
|
||||||
state.force = 1;
|
state.force = 1;
|
||||||
|
@ -114,7 +137,11 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec)
|
||||||
for (pos = 0; pos < active_nr; pos++) {
|
for (pos = 0; pos < active_nr; pos++) {
|
||||||
struct cache_entry *ce = active_cache[pos];
|
struct cache_entry *ce = active_cache[pos];
|
||||||
if (pathspec_match(pathspec, NULL, ce->name, 0)) {
|
if (pathspec_match(pathspec, NULL, ce->name, 0)) {
|
||||||
errs |= checkout_entry(ce, &state, NULL);
|
if (!ce_stage(ce)) {
|
||||||
|
errs |= checkout_entry(ce, &state, NULL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pos = skip_same_name(ce, pos) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -369,4 +369,26 @@ test_expect_success \
|
||||||
'checkout with --track, but without -b, fails with too short tracked name' '
|
'checkout with --track, but without -b, fails with too short tracked name' '
|
||||||
test_must_fail git checkout --track renamer'
|
test_must_fail git checkout --track renamer'
|
||||||
|
|
||||||
|
test_expect_success 'checkout an unmerged path should fail' '
|
||||||
|
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 &&
|
||||||
|
cat sample >fild &&
|
||||||
|
cat sample >file &&
|
||||||
|
cat sample >filf &&
|
||||||
|
test_must_fail git checkout fild file filf &&
|
||||||
|
test_cmp sample fild &&
|
||||||
|
test_cmp sample filf &&
|
||||||
|
test_cmp sample file
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Загрузка…
Ссылка в новой задаче