Git development
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: "Philippe Blain" <levraiphilippeblain@gmail.com>,
	"Britton Leo Kerin" <britton.kerin@gmail.com>,
	"Elijah Newren" <newren@gmail.com>,
	"Rubén Justo" <rjusto@gmail.com>,
	"Patrick Steinhardt" <ps@pks.im>,
	"D. Ben Knoble" <ben.knoble@gmail.com>,
	"SZEDER Gábor" <szeder.dev@gmail.com>
Subject: [PATCH v6 0/3] completion of 'git [-C <dir>] diff'
Date: Wed, 12 Aug 2026 09:25:48 -0700	[thread overview]
Message-ID: <20260812162551.2229680-1-gitster@pobox.com> (raw)
In-Reply-To: <xmqqcxw010me.fsf@gitster.g>

The primary motivation for this topic is that the command-line
completion of 'git diff' does not handle paths (unlike 'git status'
and 'git add') and instead relies on the default behavior of Bash
command-line completion, which completes files in $PWD; this does
not work at all with the '-C <directory>' option.

This series teaches the completion machinery to complete revisions
(unless '--' exists), then tracked paths, and then untracked paths,
before letting the Bash default kick in.  This way, we correctly
complete 'git diff' command line even when '-C <directory>' is in
effect.

The changes since v5 are all concentrated in the tests.  They test
the same thing, but organized in a more logical and regular way.

This round hopefully will be the last one (famous last words).

 1/3: completion: no-op refactoring of diff completion
 2/3: completion: complete tracked paths for 'git diff'
 3/3: completion: 'git diff' completes untracked paths as a last
        resort

 contrib/completion/git-completion.bash | 69 +++++++++++++++-----------
 t/t9902-completion.sh                  | 58 ++++++++++++++++++++++
 2 files changed, 99 insertions(+), 28 deletions(-)

Range-diff against v5:
1:  74bfe67e24 = 1:  a5b2bdcd21 completion: no-op refactoring of diff completion
2:  f6892a66e9 ! 2:  cb84c1407c completion: complete tracked paths for 'git diff'
    @@ contrib/completion/git-completion.bash: _git_diff ()
      __git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
     
      ## t/t9902-completion.sh ##
    +@@ t/t9902-completion.sh: test_expect_success 'setup for integration tests' '
    + 	echo content >file1 &&
    + 	echo more >file2 &&
    + 	git add file1 file2 &&
    ++	echo untracked >file3 &&
    + 	git commit -m one &&
    + 	git branch mybranch &&
    + 	git tag mytag
     @@ t/t9902-completion.sh: test_expect_success 'git -C <path> checkout uses the right repo' '
      	EOF
      '
      
     +test_expect_success 'git diff completes tracked paths when no refs match' '
     +	# file1 and file2 are tracked but file3 is not
    -+	test_completion "git diff f" <<-\EOF
    ++	# there is no ref that begins with f
    ++	test_completion "git diff f" <<-\EOF &&
     +	file1
     +	file2
     +	EOF
    -+'
    -+
    -+test_expect_success 'git diff -- completes tracked paths' '
    -+	# file1 and file2 are tracked but file3 is not
     +	test_completion "git diff -- f" <<-\EOF
     +	file1
     +	file2
     +	EOF
     +'
     +
    -+test_expect_success 'git -C <path> diff completes tracked paths in specified repo' '
    ++test_expect_success 'git -C <path> diff completes paths in specified repo' '
     +	test_when_finished "rm -rf repo-for-diff" &&
     +	git init repo-for-diff &&
     +	echo content >repo-for-diff/otherfile &&
    ++	echo content >repo-for-diff/lostfile &&
     +	git -C repo-for-diff add otherfile &&
    -+	echo untracked >repo-for-diff/oops &&
    ++	git -C repo-for-diff add lostfile &&
     +	git -C repo-for-diff commit -m otherfile &&
    -+	test_completion "git -C repo-for-diff diff o" <<-\EOF
    ++	echo untracked >repo-for-diff/oops &&
    ++	rm -f repo-for-diff/lostfile &&
    ++
    ++	test_completion "git -C repo-for-diff diff o" <<-\EOF &&
     +	otherfile
     +	EOF
    -+'
    ++	test_completion "git -C repo-for-diff diff l" <<-\EOF &&
    ++	lostfile
    ++	EOF
     +
    -+test_expect_success 'git -C <path> diff -- completes pathspecs in specified repo' '
    -+	test_when_finished "rm -rf repo-for-diff" &&
    -+	git init repo-for-diff &&
    -+	echo content >repo-for-diff/otherfile &&
    -+	git -C repo-for-diff add otherfile &&
    -+	git -C repo-for-diff commit -m otherfile &&
    -+	test_completion "git -C repo-for-diff diff -- o" <<-\EOF
    ++	test_completion "git -C repo-for-diff diff -- o" <<-\EOF &&
     +	otherfile
     +	EOF
    ++	test_completion "git -C repo-for-diff diff -- l" <<-\EOF
    ++	lostfile
    ++	EOF
     +'
     +
      test_expect_success 'show completes all refs' '
3:  dcc5f881f2 ! 3:  d73c18e876 completion: 'git diff' completes untracked paths as a last resort
    @@ contrib/completion/git-completion.bash: _git_diff ()
     
      ## t/t9902-completion.sh ##
     @@ t/t9902-completion.sh: test_expect_success 'setup for integration tests' '
    - 	echo content >file1 &&
      	echo more >file2 &&
      	git add file1 file2 &&
    + 	echo untracked >file3 &&
     +	echo untracked >ufile &&
      	git commit -m one &&
      	git branch mybranch &&
      	git tag mytag
    -@@ t/t9902-completion.sh: test_expect_success 'git diff -- completes tracked paths' '
    +@@ t/t9902-completion.sh: test_expect_success 'git diff completes tracked paths when no refs match' '
      	EOF
      '
      
     +test_expect_success 'git diff [--] completes untracked paths, too' '
    ++	# ufile is not tracked and there is no ref that begins with u
     +	test_completion "git diff u" <<-\EOF &&
     +	ufile
     +	EOF
    @@ t/t9902-completion.sh: test_expect_success 'git diff -- completes tracked paths'
     +	EOF
     +'
     +
    - test_expect_success 'git -C <path> diff completes tracked paths in specified repo' '
    + test_expect_success 'git -C <path> diff completes paths in specified repo' '
      	test_when_finished "rm -rf repo-for-diff" &&
      	git init repo-for-diff &&
    -@@ t/t9902-completion.sh: test_expect_success 'git -C <path> diff -- completes pathspecs in specified repo
    - 	test_when_finished "rm -rf repo-for-diff" &&
    - 	git init repo-for-diff &&
    - 	echo content >repo-for-diff/otherfile &&
    -+	echo untracked >repo-for-diff/untracked &&
    - 	git -C repo-for-diff add otherfile &&
    +@@ t/t9902-completion.sh: test_expect_success 'git -C <path> diff completes paths in specified repo' '
    + 	git -C repo-for-diff add lostfile &&
      	git -C repo-for-diff commit -m otherfile &&
    --	test_completion "git -C repo-for-diff diff -- o" <<-\EOF
    -+	test_completion "git -C repo-for-diff diff o" <<-\EOF &&
    -+	otherfile
    -+	EOF
    -+	test_completion "git -C repo-for-diff diff -- o" <<-\EOF &&
    - 	otherfile
    + 	echo untracked >repo-for-diff/oops &&
    ++	echo untracked >repo-for-diff/ufile &&
    + 	rm -f repo-for-diff/lostfile &&
    + 
    + 	test_completion "git -C repo-for-diff diff o" <<-\EOF &&
    +@@ t/t9902-completion.sh: test_expect_success 'git -C <path> diff completes paths in specified repo' '
    + 	test_completion "git -C repo-for-diff diff l" <<-\EOF &&
    + 	lostfile
      	EOF
     +	test_completion "git -C repo-for-diff diff u" <<-\EOF &&
    -+	untracked
    ++	ufile
     +	EOF
    + 
    + 	test_completion "git -C repo-for-diff diff -- o" <<-\EOF &&
    + 	otherfile
    + 	EOF
    +-	test_completion "git -C repo-for-diff diff -- l" <<-\EOF
    ++	test_completion "git -C repo-for-diff diff -- l" <<-\EOF &&
    + 	lostfile
    + 	EOF
     +	test_completion "git -C repo-for-diff diff -- u" <<-\EOF
    -+	untracked
    ++	ufile
     +	EOF
      '
      
-- 
2.55.0-721-gd75157efe4


  parent reply	other threads:[~2026-08-12 16:25 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-03  0:58 [PATCH] completion: complete tracked paths for 'git diff' Junio C Hamano
2026-08-03  1:07 ` Junio C Hamano
2026-08-03  5:44 ` SZEDER Gábor
2026-08-03 13:41   ` Junio C Hamano
2026-08-03 15:45     ` Junio C Hamano
2026-08-04 16:22 ` [PATCH v2] " Junio C Hamano
2026-08-05 19:42 ` [PATCH v3 0/3] completion of 'git [-C <dir>] diff' Junio C Hamano
2026-08-05 19:42   ` [PATCH v3 1/3] completion: no-op refactoring of diff completion Junio C Hamano
2026-08-05 19:42   ` [PATCH v3 2/3] completion: complete tracked paths for 'git diff' Junio C Hamano
2026-08-05 19:42   ` [PATCH v3 3/3] completion: 'git diff' completes untracked paths as a last resort Junio C Hamano
2026-08-06 11:30     ` D. Ben Knoble
2026-08-06 15:06       ` Junio C Hamano
2026-08-06 11:30   ` [PATCH v3 0/3] completion of 'git [-C <dir>] diff' D. Ben Knoble
2026-08-07  1:38 ` [PATCH v4 " Junio C Hamano
2026-08-07  1:38   ` [PATCH v4 1/3] completion: no-op refactoring of diff completion Junio C Hamano
2026-08-07  6:15     ` Elijah Newren
2026-08-07 15:09       ` Junio C Hamano
2026-08-07  1:38   ` [PATCH v4 2/3] completion: complete tracked paths for 'git diff' Junio C Hamano
2026-08-07  6:18     ` Elijah Newren
2026-08-07 11:02       ` D. Ben Knoble
2026-08-07 15:13       ` Junio C Hamano
2026-08-07 15:22         ` Elijah Newren
2026-08-07  1:38   ` [PATCH v4 3/3] completion: 'git diff' completes untracked paths as a last resort Junio C Hamano
2026-08-07  6:31   ` [PATCH v4 0/3] completion of 'git [-C <dir>] diff' Elijah Newren
2026-08-07 11:05     ` D. Ben Knoble
2026-08-07 16:19 ` [PATCH v5 " Junio C Hamano
2026-08-07 16:19   ` [PATCH v5 1/3] completion: no-op refactoring of diff completion Junio C Hamano
2026-08-07 16:19   ` [PATCH v5 2/3] completion: complete tracked paths for 'git diff' Junio C Hamano
2026-08-07 16:19   ` [PATCH v5 3/3] completion: 'git diff' completes untracked paths as a last resort Junio C Hamano
2026-08-07 16:53   ` [PATCH v5 0/3] completion of 'git [-C <dir>] diff' Elijah Newren
2026-08-12 16:25 ` Junio C Hamano [this message]
2026-08-12 16:25   ` [PATCH v6 1/3] completion: no-op refactoring of diff completion Junio C Hamano
2026-08-12 16:25   ` [PATCH v6 2/3] completion: complete tracked paths for 'git diff' Junio C Hamano
2026-08-12 16:25   ` [PATCH v6 3/3] completion: 'git diff' completes untracked paths as a last resort Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260812162551.2229680-1-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=ben.knoble@gmail.com \
    --cc=britton.kerin@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=levraiphilippeblain@gmail.com \
    --cc=newren@gmail.com \
    --cc=ps@pks.im \
    --cc=rjusto@gmail.com \
    --cc=szeder.dev@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox