completion: list refs from remote when remote's name matches a directory

If the remote given to __git_refs() happens to match both the name of a configured remote and the name of a directory in the current working directory, then that directory is assumed to be a git repository, and listing refs from that directory will be attempted. This is wrong, because in such a situation git commands (e.g. 'git fetch|pull|push <remote>' whom these refs will eventually be passed to) give precedence to the configured remote. Therefore, __git_refs() should list refs from the configured remote as well. Add the helper function __git_is_configured_remote() that checks whether its argument matches the name of a configured remote. Use this helper to decide how to handle the remote passed to __git_refs(). Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

SZEDER Gábor committed Feb 3, 2017 at 03:48 UTC 69a775963b76824511fe4bdaf949f2e44df4b7a5
2 files changed +28 -3
contrib/completion/git-completion.bash
+18 -2
@@ -347,12 +347,16 @@ __git_refs ()
347 local format refs pfx
348
349 if [ -n "$remote" ]; then
350 - if [ -d "$remote/.git" ]; then
350 + if __git_is_configured_remote "$remote"; then
351 + # configured remote takes precedence over a
352 + # local directory with the same name
353 + list_refs_from=remote
354 + elif [ -d "$remote/.git" ]; then
355 dir="$remote/.git"
356 elif [ -d "$remote" ]; then
357 dir="$remote"
358 else
355 - list_refs_from=remote
359 + list_refs_from=url
360 fi
361 fi
362
@@ -435,6 +439,18 @@ __git_remotes ()
439 git --git-dir="$d" remote
440 }
441
442 +# Returns true if $1 matches the name of a configured remote, false otherwise.
443 +__git_is_configured_remote ()
444 +{
445 + local remote
446 + for remote in $(__git_remotes); do
447 + if [ "$remote" = "$1" ]; then
448 + return 0
449 + fi
450 + done
451 + return 1
452 +}
453 +
454 __git_list_merge_strategies ()
455 {
456 git merge -s help 2>&1 |
t/t9902-completion.sh
+10 -1
@@ -373,6 +373,15 @@ test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from
373 test_cmp expect actual
374 '
375
376 +test_expect_success '__git_is_configured_remote' '
377 + test_when_finished "git remote remove remote_1" &&
378 + git remote add remote_1 git://remote_1 &&
379 + test_when_finished "git remote remove remote_2" &&
380 + git remote add remote_2 git://remote_2 &&
381 + verbose __git_is_configured_remote remote_2 &&
382 + test_must_fail __git_is_configured_remote non-existent
383 +'
384 +
385 test_expect_success 'setup for ref completion' '
386 git commit --allow-empty -m initial &&
387 git branch matching-branch &&
@@ -516,7 +525,7 @@ test_expect_success '__git_refs - configured remote - full refs - repo given on
525 test_cmp expected "$actual"
526 '
527
519 -test_expect_failure '__git_refs - configured remote - remote name matches a directory' '
528 +test_expect_success '__git_refs - configured remote - remote name matches a directory' '
529 cat >expected <<-EOF &&
530 HEAD
531 branch-in-other