@matheusbsbs / matheus-bagliano / commits / acb658fe7d
Fork 0

completion: improve handling of -c/-C and -b/-B in switch/checkout

A previous commit added several test cases highlighting the subpar completion logic for -c/-C and -b/-B when completing git switch and git checkout. In order to distinguish completing the argument vs the start-point for this option, we now use the wordlist to determine the previous full word on the command line. If it's -c or -C (-b/-B for checkout), then we know that we are completing the argument for the branch name. Given that a user who already knows the branch name they want to complete will simply not use completion, it makes sense to complete the small subset of local branches when completing the argument for -c/-C. In all other cases, if -c/-C are on the command line but are not the most recent option, then we must be completing a start-point, and should allow completing against all references. Update the -c/-C and -b/-B tests to indicate they now pass. Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jacob Keller committed May 28, 2020 at 11:10 UTC acb658fe7d6bc11136be0756270fda675af74761
2 files changed +63 -34
contrib/completion/git-completion.bash
+47 -2
@@ -1505,8 +1505,31 @@ _git_checkout ()
1505 ;;
1506 *)
1507 local dwim_opt="$(__git_checkout_default_dwim_mode)"
1508 + local prevword prevword="${words[cword-1]}"
1509 +
1510 + case "$prevword" in
1511 + -b|-B)
1512 + # Complete local branches (and DWIM branch
1513 + # remote branch names) for an option argument
1514 + # specifying a new branch name. This is for
1515 + # convenience, assuming new branches are
1516 + # possibly based on pre-existing branch names.
1517 + __git_complete_refs $dwim_opt --mode="heads"
1518 + return
1519 + ;;
1520 + *)
1521 + ;;
1522 + esac
1523 +
1524 + # At this point, we've already handled special completion for
1525 + # the arguments to -b/-B. There are 3 main things left we can
1526 + # possibly complete:
1527 + # 1) a start-point for -b/-B or -d/--detach
1528 + # 2) a remote head, for --track
1529 + # 3) an arbitrary reference, possibly including DWIM names
1530 + #
1531
1509 - if [ -n "$(__git_find_on_cmdline "-d --detach")" ]; then
1532 + if [ -n "$(__git_find_on_cmdline "-b -B -d --detach")" ]; then
1533 __git_complete_refs --mode="refs"
1534 elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
1535 __git_complete_refs --mode="remote-heads"
@@ -2361,8 +2384,30 @@ _git_switch ()
2384 ;;
2385 *)
2386 local dwim_opt="$(__git_checkout_default_dwim_mode)"
2387 + local prevword prevword="${words[cword-1]}"
2388 +
2389 + case "$prevword" in
2390 + -c|-C)
2391 + # Complete local branches (and DWIM branch
2392 + # remote branch names) for an option argument
2393 + # specifying a new branch name. This is for
2394 + # convenience, assuming new branches are
2395 + # possibly based on pre-existing branch names.
2396 + __git_complete_refs $dwim_opt --mode="heads"
2397 + return
2398 + ;;
2399 + *)
2400 + ;;
2401 + esac
2402 +
2403 + # At this point, we've already handled special completion for
2404 + # -c/-C. There are 3 main things left to
2405 + # complete:
2406 + # 1) a start-point for -c/-C or -d/--detach
2407 + # 2) a remote head, for --track
2408 + # 3) a branch name, possibly including DWIM remote branches
2409
2365 - if [ -n "$(__git_find_on_cmdline "-d --detach")" ]; then
2410 + if [ -n "$(__git_find_on_cmdline "-c -C -d --detach")" ]; then
2411 __git_complete_refs --mode="refs"
2412 elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
2413 __git_complete_refs --mode="remote-heads"
t/t9902-completion.sh
+16 -32
@@ -1436,8 +1436,7 @@ test_expect_success 'git checkout - with --no-track, complete only local referen
1436 EOF
1437 '
1438
1439 -#TODO: completing the start point of -c/-C should not include DWIM references
1440 -test_expect_failure 'git switch - with -c, complete all references' '
1439 +test_expect_success 'git switch - with -c, complete all references' '
1440 test_completion "git switch -c new-branch " <<-\EOF
1441 HEAD Z
1442 master Z
@@ -1448,8 +1447,7 @@ test_expect_failure 'git switch - with -c, complete all references' '
1447 EOF
1448 '
1449
1451 -#TODO: completing the start point of -c/-C should not include DWIM references
1452 -test_expect_failure 'git switch - with -C, complete all references' '
1450 +test_expect_success 'git switch - with -C, complete all references' '
1451 test_completion "git switch -C new-branch " <<-\EOF
1452 HEAD Z
1453 master Z
@@ -1460,8 +1458,7 @@ test_expect_failure 'git switch - with -C, complete all references' '
1458 EOF
1459 '
1460
1463 -#TODO: completing the start point of -c/-C should include all references, not just local branches
1464 -test_expect_failure 'git switch - with -c and --track, complete all references' '
1461 +test_expect_success 'git switch - with -c and --track, complete all references' '
1462 test_completion "git switch -c new-branch --track " <<-EOF
1463 HEAD Z
1464 master Z
@@ -1472,8 +1469,7 @@ test_expect_failure 'git switch - with -c and --track, complete all references'
1469 EOF
1470 '
1471
1475 -#TODO: completing the start point of -c/-C should include all references, not just local branches
1476 -test_expect_failure 'git switch - with -C and --track, complete all references' '
1472 +test_expect_success 'git switch - with -C and --track, complete all references' '
1473 test_completion "git switch -C new-branch --track " <<-EOF
1474 HEAD Z
1475 master Z
@@ -1484,8 +1480,7 @@ test_expect_failure 'git switch - with -C and --track, complete all references'
1480 EOF
1481 '
1482
1487 -#TODO: completing the start point of -c/-C should include all references, not just local branches
1488 -test_expect_failure 'git switch - with -c and --no-track, complete all references' '
1483 +test_expect_success 'git switch - with -c and --no-track, complete all references' '
1484 test_completion "git switch -c new-branch --no-track " <<-\EOF
1485 HEAD Z
1486 master Z
@@ -1496,8 +1491,7 @@ test_expect_failure 'git switch - with -c and --no-track, complete all reference
1491 EOF
1492 '
1493
1499 -#TODO: completing the start point of -c/-C should include all references, not just local branches
1500 -test_expect_failure 'git switch - with -C and --no-track, complete all references' '
1494 +test_expect_success 'git switch - with -C and --no-track, complete all references' '
1495 test_completion "git switch -C new-branch --no-track " <<-\EOF
1496 HEAD Z
1497 master Z
@@ -1508,8 +1502,7 @@ test_expect_failure 'git switch - with -C and --no-track, complete all reference
1502 EOF
1503 '
1504
1511 -#TODO: completing the start point of -b/-B should not include DWIM references
1512 -test_expect_failure 'git checkout - with -b, complete all references' '
1505 +test_expect_success 'git checkout - with -b, complete all references' '
1506 test_completion "git checkout -b new-branch " <<-\EOF
1507 HEAD Z
1508 master Z
@@ -1520,8 +1513,7 @@ test_expect_failure 'git checkout - with -b, complete all references' '
1513 EOF
1514 '
1515
1523 -#TODO: completing the start point of -b/-B should not include DWIM references
1524 -test_expect_failure 'git checkout - with -B, complete all references' '
1516 +test_expect_success 'git checkout - with -B, complete all references' '
1517 test_completion "git checkout -B new-branch " <<-\EOF
1518 HEAD Z
1519 master Z
@@ -1532,8 +1524,7 @@ test_expect_failure 'git checkout - with -B, complete all references' '
1524 EOF
1525 '
1526
1535 -#TODO: completing the start point of -b/-B should not include DWIM references
1536 -test_expect_failure 'git checkout - with -b and --track, complete all references' '
1527 +test_expect_success 'git checkout - with -b and --track, complete all references' '
1528 test_completion "git checkout -b new-branch --track " <<-EOF
1529 HEAD Z
1530 master Z
@@ -1544,8 +1535,7 @@ test_expect_failure 'git checkout - with -b and --track, complete all references
1535 EOF
1536 '
1537
1547 -#TODO: completing the start point of -b/-B should not include DWIM references
1548 -test_expect_failure 'git checkout - with -B and --track, complete all references' '
1538 +test_expect_success 'git checkout - with -B and --track, complete all references' '
1539 test_completion "git checkout -B new-branch --track " <<-EOF
1540 HEAD Z
1541 master Z
@@ -1624,8 +1614,7 @@ test_expect_success 'git switch - for -C with --no-track, complete local branche
1614 EOF
1615 '
1616
1627 -#TODO: -b/-B argument completion should not include all references
1628 -test_expect_failure 'git checkout - for -b, complete local branches and unique remote branches' '
1617 +test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' '
1618 test_completion "git checkout -b " <<-\EOF
1619 branch-in-other Z
1620 master Z
@@ -1634,8 +1623,7 @@ test_expect_failure 'git checkout - for -b, complete local branches and unique r
1623 EOF
1624 '
1625
1637 -#TODO: -b/-B argument completion should not include all references
1638 -test_expect_failure 'git checkout - for -B, complete local branches and unique remote branches' '
1626 +test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' '
1627 test_completion "git checkout -B " <<-\EOF
1628 branch-in-other Z
1629 master Z
@@ -1644,32 +1632,28 @@ test_expect_failure 'git checkout - for -B, complete local branches and unique r
1632 EOF
1633 '
1634
1647 -#TODO: -b/-B argument completion should not include all references
1648 -test_expect_failure 'git checkout - for -b with --no-guess, complete local branches only' '
1635 +test_expect_success 'git checkout - for -b with --no-guess, complete local branches only' '
1636 test_completion "git checkout --no-guess -b " <<-\EOF
1637 master Z
1638 matching-branch Z
1639 EOF
1640 '
1641
1655 -#TODO: -b/-B argument completion should not include all references
1656 -test_expect_failure 'git checkout - for -B with --no-guess, complete local branches only' '
1642 +test_expect_success 'git checkout - for -B with --no-guess, complete local branches only' '
1643 test_completion "git checkout --no-guess -B " <<-\EOF
1644 master Z
1645 matching-branch Z
1646 EOF
1647 '
1648
1663 -#TODO: -b/-B argument completion should not include all references
1664 -test_expect_failure 'git checkout - for -b with --no-track, complete local branches only' '
1649 +test_expect_success 'git checkout - for -b with --no-track, complete local branches only' '
1650 test_completion "git checkout --no-track -b " <<-\EOF
1651 master Z
1652 matching-branch Z
1653 EOF
1654 '
1655
1671 -#TODO: -b/-B argument completion should not include all references
1672 -test_expect_failure 'git checkout - for -B with --no-track, complete local branches only' '
1656 +test_expect_success 'git checkout - for -B with --no-track, complete local branches only' '
1657 test_completion "git checkout --no-track -B " <<-\EOF
1658 master Z
1659 matching-branch Z