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

completion: add tests showing subpar DWIM logic for switch/checkout

When provided with a single argument that is the name of a remote branch that does not yet exist locally, both git switch and git checkout can interpret this as a request to create a local branch that tracks that remote branch. We call this behavior "Do What I Mean", or DWIM for short. To aid in using this DWIM, it makes sense for completion to list these unique remote branch names when completing possible arguments for git switch and git checkout. Indeed, both _git_checkout and _git_switch implement support for completing such DWIM branch names. In other words, in addition to the usual completions provided for git switch, this "DWIM" logic means completion will include the names of branches on remotes that are unique and thus there can be no ambiguity of which remote to track when creating the local branch. However, the DWIM logic is not always active. Many options, such as --no-guess, --no-track, and --track disable this DWIM logic, as they cause git switch and git checkout to behave in different modes. Additionally, some completion users do not wish to have tab completion include these remote names by default, and thus introduced GIT_COMPLETION_CHECKOUT_NO_GUESS as an optional way to configure the completion support to disable this feature of completion support. For this reason, _git_checkout and _git_switch have many rules about when to enable or disable completing of these remote refs. The two commands follow similar but not identical rules. Set aside the question of command modes that do not accept this DWIM logic (--track, -c, --orphan, --detach) for now. Thinking just about the main mode of git checkout and git switch, the following guidelines will help explain the basic rules we ought to support when deciding whether to list the remote branches for DWIM in completion. 1. if --guess is enabled, we should list DWIM remote branch names, even if something else would disable it 2. if --no-guess, --no-track or GIT_COMPLETION_CHECKOUT_NO_GUESS=1, then we should disable listing DWIM remote branch names. 3. Since the '--guess' option is a boolean option, a later --guess should override --no-guess, and a later --no-guess should override --guess. Putting all of these together, add some tests that highlight the expected behavior of this DWIM logic. 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 ab58e90f8b27f420659345ee462f6a69e26e379b
1 file changed +105
t/t9902-completion.sh
+105
@@ -1263,6 +1263,111 @@ test_expect_success 'git checkout - completes refs and unique remote branches fo
1263 EOF
1264 '
1265
1266 +test_expect_success 'git switch - with --no-guess, complete only local branches' '
1267 + test_completion "git switch --no-guess " <<-\EOF
1268 + master Z
1269 + matching-branch Z
1270 + EOF
1271 +'
1272 +
1273 +test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete only local branches' '
1274 + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch " <<-\EOF
1275 + master Z
1276 + matching-branch Z
1277 + EOF
1278 +'
1279 +
1280 +#TODO: --guess/--no-guess ordering is not taken into account
1281 +#TODO: git switch completion includes unexpected references
1282 +test_expect_failure 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '
1283 + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF
1284 + branch-in-other Z
1285 + master Z
1286 + master-in-other Z
1287 + matching-branch Z
1288 + EOF
1289 +'
1290 +
1291 +#TODO: --guess/--no-guess ordering is not taken into account
1292 +#TODO: git switch completion includes unexpected references
1293 +test_expect_failure 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '
1294 + test_completion "git switch --no-guess --guess " <<-\EOF
1295 + branch-in-other Z
1296 + master Z
1297 + master-in-other Z
1298 + matching-branch Z
1299 + EOF
1300 +'
1301 +
1302 +#TODO: --guess/--no-guess ordering is not taken into account
1303 +test_expect_failure 'git switch - a later --no-guess overrides previous --guess, complete only local branches' '
1304 + test_completion "git switch --guess --no-guess " <<-\EOF
1305 + master Z
1306 + matching-branch Z
1307 + EOF
1308 +'
1309 +
1310 +test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only completes refs' '
1311 + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout " <<-\EOF
1312 + HEAD Z
1313 + master Z
1314 + matching-branch Z
1315 + matching-tag Z
1316 + other/branch-in-other Z
1317 + other/master-in-other Z
1318 + EOF
1319 +'
1320 +
1321 +#TODO: git checkout does not override variable when --guess is provided
1322 +test_expect_failure 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' '
1323 + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF
1324 + HEAD Z
1325 + branch-in-other Z
1326 + master Z
1327 + master-in-other Z
1328 + matching-branch Z
1329 + matching-tag Z
1330 + other/branch-in-other Z
1331 + other/master-in-other Z
1332 + EOF
1333 +'
1334 +
1335 +test_expect_success 'git checkout - with --no-guess, only completes refs' '
1336 + test_completion "git checkout --no-guess " <<-\EOF
1337 + HEAD Z
1338 + master Z
1339 + matching-branch Z
1340 + matching-tag Z
1341 + other/branch-in-other Z
1342 + other/master-in-other Z
1343 + EOF
1344 +'
1345 +
1346 +#TODO: --guess/--no-guess ordering is not taken into account
1347 +test_expect_failure 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' '
1348 + test_completion "git checkout --no-guess --guess " <<-\EOF
1349 + HEAD Z
1350 + branch-in-other Z
1351 + master Z
1352 + master-in-other Z
1353 + matching-branch Z
1354 + matching-tag Z
1355 + other/branch-in-other Z
1356 + other/master-in-other Z
1357 + EOF
1358 +'
1359 +
1360 +test_expect_success 'git checkout - a later --no-guess overrides previous --guess, complete only refs' '
1361 + test_completion "git checkout --guess --no-guess " <<-\EOF
1362 + HEAD Z
1363 + master Z
1364 + matching-branch Z
1365 + matching-tag Z
1366 + other/branch-in-other Z
1367 + other/master-in-other Z
1368 + EOF
1369 +'
1370 +
1371 test_expect_success 'teardown after ref completion' '
1372 git branch -d matching-branch &&
1373 git tag -d matching-tag &&