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 v4 0/3] completion of 'git [-C <dir>] diff'
Date: Thu,  6 Aug 2026 18:38:27 -0700	[thread overview]
Message-ID: <20260807013830.698340-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 tests are the only changes relative to v2.  In the step where
tracked paths are completed, v2 did not demonstrate that untracked
ones are *not* completed at the same time.  Now we do by having
untracked 'file3' next to 'file1' and 'file2' that are tracked.  In
the last step, we demonstrate untracked paths that do not share
prefix with refs or tracked paths are completed, with or without the
"-C <dir>" option.

 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                  | 49 ++++++++++++++++++
 2 files changed, 90 insertions(+), 28 deletions(-)

Range-diff against v3:
1:  d3c51c042c = 1:  3b99b45fee completion: no-op refactoring of diff completion
2:  c3658d6ca2 ! 2:  bcc24b6bda 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 in the specified repo' '
     +	test_when_finished "rm -rf repo-for-diff" &&
     +	git init repo-for-diff &&
    ++
    ++	# otherfile is tracked, oops is untracked
     +	echo content >repo-for-diff/otherfile &&
     +	git -C repo-for-diff add otherfile &&
    -+	echo untracked >repo-for-diff/oops &&
     +	git -C repo-for-diff commit -m otherfile &&
    -+	test_completion "git -C repo-for-diff diff o" <<-\EOF
    ++	echo untracked >repo-for-diff/oops &&
    ++	test_completion "git -C repo-for-diff diff o" <<-\EOF &&
     +	otherfile
     +	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
     +	otherfile
     +	EOF
3:  ba5dc6f164 ! 3:  34720a30ab 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' '
    ++	# there is no ref or tracked path that begin 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_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_expect_success 'git -C <path> diff completes in the specified repo' '
      	test_when_finished "rm -rf repo-for-diff" &&
      	git init repo-for-diff &&
    + 
    +-	# otherfile is tracked, oops is untracked
    ++	# otherfile is tracked, oops and ufile are untracked
      	echo content >repo-for-diff/otherfile &&
    -+	echo untracked >repo-for-diff/untracked &&
      	git -C repo-for-diff add otherfile &&
      	git -C repo-for-diff commit -m otherfile &&
    + 	echo untracked >repo-for-diff/oops &&
    ++	echo untracked >repo-for-diff/ufile &&
    + 	test_completion "git -C repo-for-diff diff o" <<-\EOF &&
    + 	otherfile
    + 	EOF
     -	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
      	EOF
     +	test_completion "git -C repo-for-diff diff u" <<-\EOF &&
    -+	untracked
    ++	ufile
     +	EOF
     +	test_completion "git -C repo-for-diff diff -- u" <<-\EOF
    -+	untracked
    ++	ufile
     +	EOF
      '
      
-- 
2.55.0-655-gb2c071042d


  parent reply	other threads:[~2026-08-07  1:38 UTC|newest]

Thread overview: 30+ 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 ` Junio C Hamano [this message]
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

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=20260807013830.698340-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