Skip to content

Commit bb0bd71

Browse files
author
Edward Thomson
committed
checkout: use empty baseline when no index
When no index file exists and a baseline is not explicitly provided, use an empty baseline instead of trying to load `HEAD`.
1 parent abb6f72 commit bb0bd71

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

src/checkout.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2430,8 +2430,13 @@ static int checkout_data_init(
24302430

24312431
if (!data->opts.baseline && !data->opts.baseline_index) {
24322432
data->opts_free_baseline = true;
2433+
error = 0;
24332434

2434-
error = checkout_lookup_head_tree(&data->opts.baseline, repo);
2435+
/* if we don't have an index, this is an initial checkout and
2436+
* should be against an empty baseline
2437+
*/
2438+
if (data->index->on_disk)
2439+
error = checkout_lookup_head_tree(&data->opts.baseline, repo);
24352440

24362441
if (error == GIT_EUNBORNBRANCH) {
24372442
error = 0;

tests/checkout/tree.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,3 +1416,66 @@ void test_checkout_tree__safe_proceeds_if_no_index(void)
14161416
git_object_free(obj);
14171417
}
14181418

1419+
static int checkout_conflict_count_cb(
1420+
git_checkout_notify_t why,
1421+
const char *path,
1422+
const git_diff_file *b,
1423+
const git_diff_file *t,
1424+
const git_diff_file *w,
1425+
void *payload)
1426+
{
1427+
size_t *n = payload;
1428+
1429+
GIT_UNUSED(why);
1430+
GIT_UNUSED(path);
1431+
GIT_UNUSED(b);
1432+
GIT_UNUSED(t);
1433+
GIT_UNUSED(w);
1434+
1435+
(*n)++;
1436+
1437+
return 0;
1438+
}
1439+
1440+
/* A repo that has a HEAD (even a properly born HEAD that peels to
1441+
* a commit) but no index should be treated as if it's an empty baseline
1442+
*/
1443+
void test_checkout_tree__baseline_is_empty_when_no_index(void)
1444+
{
1445+
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
1446+
git_reference *head;
1447+
git_object *obj;
1448+
git_status_list *status;
1449+
size_t conflicts = 0;
1450+
1451+
assert_on_branch(g_repo, "master");
1452+
cl_git_pass(git_repository_head(&head, g_repo));
1453+
cl_git_pass(git_reference_peel(&obj, head, GIT_OBJ_COMMIT));
1454+
1455+
cl_git_pass(git_reset(g_repo, obj, GIT_RESET_HARD, NULL));
1456+
1457+
cl_must_pass(p_unlink("testrepo/.git/index"));
1458+
1459+
/* for a safe checkout, we should have checkout conflicts with
1460+
* the existing untracked files.
1461+
*/
1462+
opts.checkout_strategy &= ~GIT_CHECKOUT_FORCE;
1463+
opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
1464+
opts.notify_cb = checkout_conflict_count_cb;
1465+
opts.notify_payload = &conflicts;
1466+
1467+
cl_git_fail_with(GIT_ECONFLICT, git_checkout_tree(g_repo, obj, &opts));
1468+
cl_assert_equal_i(4, conflicts);
1469+
1470+
/* but force should succeed and update the index */
1471+
opts.checkout_strategy |= GIT_CHECKOUT_FORCE;
1472+
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
1473+
1474+
cl_git_pass(git_status_list_new(&status, g_repo, NULL));
1475+
cl_assert_equal_i(0, git_status_list_entrycount(status));
1476+
git_status_list_free(status);
1477+
1478+
git_object_free(obj);
1479+
git_reference_free(head);
1480+
}
1481+

0 commit comments

Comments
 (0)