completion: silence pseudoref existence check

In 44dbb3bf29 (completion: support pseudoref existence checks for reftables, 2023-12-19), we have extended the Bash completion script to support future ref backends better by using git-rev-parse(1) to check for pseudo-ref existence. This conversion has introduced a bug, because even though we pass `--quiet` to git-rev-parse(1) it would still output the resolved object ID of the ref in question if it exists. Fix this by redirecting its stdout to `/dev/null` and add a test that catches this behaviour. Note that the test passes even without the fix for the "files" backend because we parse pseudo refs via the filesystem directly in that case. But the test will fail with the "reftable" backend. Helped-by: Jeff King <peff@peff.net> Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 15, 2024 at 11:36 UTC 9a9c31135e6029dbda773f7271cea4648644eb8e
2 files changed +32 -1
contrib/completion/git-completion.bash
+1 -1
@@ -148,7 +148,7 @@ __git_pseudoref_exists ()
148 # platforms.
149 if __git_eread "$__git_repo_path/HEAD" head; then
150 if [ "$head" == "ref: refs/heads/.invalid" ]; then
151 - __git rev-parse --verify --quiet "$ref"
151 + __git rev-parse --verify --quiet "$ref" >/dev/null
152 return $?
153 fi
154 fi
t/t9902-completion.sh
+31
@@ -1933,6 +1933,14 @@ test_expect_success 'git checkout - --orphan with branch already provided comple
1933 EOF
1934 '
1935
1936 +test_expect_success 'git restore completes modified files' '
1937 + test_commit A a.file &&
1938 + echo B >a.file &&
1939 + test_completion "git restore a." <<-\EOF
1940 + a.file
1941 + EOF
1942 +'
1943 +
1944 test_expect_success 'teardown after ref completion' '
1945 git branch -d matching-branch &&
1946 git tag -d matching-tag &&
@@ -2728,4 +2736,27 @@ test_expect_success '__git_complete' '
2736 test_must_fail __git_complete ga missing
2737 '
2738
2739 +test_expect_success '__git_pseudoref_exists' '
2740 + test_when_finished "rm -rf repo" &&
2741 + git init repo &&
2742 + (
2743 + cd repo &&
2744 + sane_unset __git_repo_path &&
2745 +
2746 + # HEAD points to an existing branch, so it should exist.
2747 + test_commit A &&
2748 + __git_pseudoref_exists HEAD >output 2>&1 &&
2749 + test_must_be_empty output &&
2750 +
2751 + # CHERRY_PICK_HEAD does not exist, so the existence check should fail.
2752 + ! __git_pseudoref_exists CHERRY_PICK_HEAD >output 2>&1 &&
2753 + test_must_be_empty output &&
2754 +
2755 + # CHERRY_PICK_HEAD points to a commit, so it should exist.
2756 + git update-ref CHERRY_PICK_HEAD A &&
2757 + __git_pseudoref_exists CHERRY_PICK_HEAD >output 2>&1 &&
2758 + test_must_be_empty output
2759 + )
2760 +'
2761 +
2762 test_done