Skip to content

Commit

Permalink
Merge branch 'js/checkout-detach-count'
Browse files Browse the repository at this point in the history
When checking out another commit from an already detached state, we used
to report all commits that are not reachable from any of the refs as
lossage, but some of them might be reachable from the new HEAD, and there
is no need to warn about them.

By Johannes Sixt
* js/checkout-detach-count:
  checkout (detached): truncate list of orphaned commits at the new HEAD
  t2020-checkout-detach: check for the number of orphaned commits
  • Loading branch information
Junio C Hamano committed May 10, 2012
2 parents 499e7b3 + 5d88639 commit dc7a4c3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
13 changes: 7 additions & 6 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,10 +672,10 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
* HEAD. If it is not reachable from any ref, this is the last chance
* for the user to do so without resorting to reflog.
*/
static void orphaned_commit_warning(struct commit *commit)
static void orphaned_commit_warning(struct commit *old, struct commit *new)
{
struct rev_info revs;
struct object *object = &commit->object;
struct object *object = &old->object;
struct object_array refs;

init_revisions(&revs, NULL);
Expand All @@ -685,16 +685,17 @@ static void orphaned_commit_warning(struct commit *commit)
add_pending_object(&revs, object, sha1_to_hex(object->sha1));

for_each_ref(add_pending_uninteresting_ref, &revs);
add_pending_sha1(&revs, "HEAD", new->object.sha1, UNINTERESTING);

refs = revs.pending;
revs.leak_pending = 1;

if (prepare_revision_walk(&revs))
die(_("internal error in revision walk"));
if (!(commit->object.flags & UNINTERESTING))
suggest_reattach(commit, &revs);
if (!(old->object.flags & UNINTERESTING))
suggest_reattach(old, &revs);
else
describe_detached_head(_("Previous HEAD position was"), commit);
describe_detached_head(_("Previous HEAD position was"), old);

clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
free(refs.objects);
Expand Down Expand Up @@ -731,7 +732,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
}

if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
orphaned_commit_warning(old.commit);
orphaned_commit_warning(old.commit, new->commit);

update_refs_for_switch(opts, &old, new);

Expand Down
21 changes: 16 additions & 5 deletions t/t2020-checkout-detach.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ check_not_detached () {
git symbolic-ref -q HEAD >/dev/null
}

ORPHAN_WARNING='you are leaving .* commit.*behind'
PREV_HEAD_DESC='Previous HEAD position was'
check_orphan_warning() {
test_i18ngrep "$ORPHAN_WARNING" "$1" &&
test_i18ngrep "you are leaving $2 behind" "$1" &&
test_i18ngrep ! "$PREV_HEAD_DESC" "$1"
}
check_no_orphan_warning() {
test_i18ngrep ! "$ORPHAN_WARNING" "$1" &&
test_i18ngrep ! "you are leaving .* commit.*behind" "$1" &&
test_i18ngrep "$PREV_HEAD_DESC" "$1"
}

Expand Down Expand Up @@ -110,12 +109,24 @@ test_expect_success 'checkout warns on orphan commits' '
git checkout --detach two &&
echo content >orphan &&
git add orphan &&
git commit -a -m orphan &&
git commit -a -m orphan1 &&
echo new content >orphan &&
git commit -a -m orphan2 &&
orphan2=$(git rev-parse HEAD) &&
git checkout master 2>stderr
'

test_expect_success 'checkout warns on orphan commits: output' '
check_orphan_warning stderr
check_orphan_warning stderr "2 commits"
'

test_expect_success 'checkout warns orphaning 1 of 2 commits' '
git checkout "$orphan2" &&
git checkout HEAD^ 2>stderr
'

test_expect_success 'checkout warns orphaning 1 of 2 commits: output' '
check_orphan_warning stderr "1 commit"
'

test_expect_success 'checkout does not warn leaving ref tip' '
Expand Down

0 comments on commit dc7a4c3

Please sign in to comment.