threads / patch / 57543

patchtab completion of filenames for 'git restore'

Subject: [PATCH] tab completion of filenames for 'git restore'

## tl;dr

13 messages between Mar 11, 2022 and Mar 17, 2022. Diffs are folded; open one to read it.

replies: 12people: 3as markdown or json

David Cantrell via GitGitGadget· Mar 11, 2022, 21:07 UTC · lore
From: David Cantrell <david@cantrell.org.uk>

If no --args are present after 'git restore' it assumes that you want to tab-complete one of the files with uncommitted changes

Signed-off-by: David Cantrell <david@cantrell.org.uk>
---
    Improved bash tab completion for 'git restore' - adds support for
    auto-completing filenames
    
    This adds tab-completion of filenames to the bash completions for git
    restore.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1227%2FDrHyde%2Ffilename-completion-for-git-restore-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1227/DrHyde/filename-completion-for-git-restore-v1
Pull-Request: https://github.com/git/git/pull/1227
 contrib/completion/git-completion.bash | 7 +++++++
 1 file changed, 7 insertions(+)
Show changes to contrib/completion/git-completion.bash +7 −0
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 49a328aa8a4..7ccad8ff4b1 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2883,14 +2883,21 @@ _git_restore ()
 	case "$cur" in
 	--conflict=*)
 		__gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
+		return
 		;;
 	--source=*)
 		__git_complete_refs --cur="${cur##--source=}"
+		return
 		;;
 	--*)
 		__gitcomp_builtin restore
+		return
 		;;
 	esac
+
+	if __git rev-parse --verify --quiet HEAD >/dev/null; then
+		__git_complete_index_file "--committable"
+	fi
 }
 
 __git_revert_inprogress_options=$__git_sequencer_inprogress_options

base-commit: 1a4874565fa3b6668042216189551b98b4dc0b1b
-- 
gitgitgadget
Junio C Hamano· Mar 13, 2022, 06:45 UTC · re: David Cantrell via GitGitGadget · lore

Re: [PATCH] tab completion of filenames for 'git restore'

"David Cantrell via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 12 quoted lines
> From: David Cantrell <david@cantrell.org.uk>
>
> If no --args are present after 'git restore' it assumes that you want
> to tab-complete one of the files with uncommitted changes
>
> Signed-off-by: David Cantrell <david@cantrell.org.uk>
> ---
>     Improved bash tab completion for 'git restore' - adds support for
>     auto-completing filenames
>     
>     This adds tab-completion of filenames to the bash completions for git
>     restore.
Two questions
 - "restore" is a castrated half "checkout"; shouldn't the latter
   also be getting the same feature?
 - is "complete_index_file --committable" the right thing to use?
   It boils down to running "diff-index HEAD", which means path with
   differences from the HEAD commit is listed.  By default "restore"
   checks out the contents of the given path from the index to the
   working tree, so after "edit F && git add F", "diff-index HEAD"
   may show F in its output (i.e. F is "committable"), but "restore
   F" would be a no-op.  Which feels a bit iffy.
   Modelling it after "git add" completion, where we look for paths
   that are different between the index and the working tree, feels
   more appropriate, but I haven't thought things through.
Show 31 quoted lines
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1227%2FDrHyde%2Ffilename-completion-for-git-restore-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1227/DrHyde/filename-completion-for-git-restore-v1
> Pull-Request: https://github.com/git/git/pull/1227
>
>  contrib/completion/git-completion.bash | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 49a328aa8a4..7ccad8ff4b1 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -2883,14 +2883,21 @@ _git_restore ()
>  	case "$cur" in
>  	--conflict=*)
>  		__gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
> +		return
>  		;;
>  	--source=*)
>  		__git_complete_refs --cur="${cur##--source=}"
> +		return
>  		;;
>  	--*)
>  		__gitcomp_builtin restore
> +		return
>  		;;
>  	esac
> +
> +	if __git rev-parse --verify --quiet HEAD >/dev/null; then
> +		__git_complete_index_file "--committable"
> +	fi
>  }

Do you need to sprinkle return's? Instead you could just add another case arm, like

	case "$cur" in
	--conflict=*)
		... all the existing code ...
	--*)
		__gitcomp_builtin restore
		;;
+	*)
+		... whatever you want to do when
+		... $cur is not a --dashed-option
+		;;
	esac
David Cantrell· Mar 14, 2022, 23:45 UTC · re: Junio C Hamano · lore

Re: [PATCH] tab completion of filenames for 'git restore'

On 13/03/2022 06:45, Junio C Hamano wrote:
Show 10 quoted lines
> "David Cantrell via GitGitGadget" <gitgitgadget@gmail.com> writes:
>>      Improved bash tab completion for 'git restore' - adds support for
>>      auto-completing filenames
>>      
>>      This adds tab-completion of filenames to the bash completions for git
>>      restore.
> Two questions
> 
>   - "restore" is a castrated half "checkout"; shouldn't the latter
>     also be getting the same feature?

`git checkout <tab>` already completes to a list of branches and tags, which is I think more useful in that case.

Show 8 quoted lines
>   - is "complete_index_file --committable" the right thing to use?
> 
>     It boils down to running "diff-index HEAD", which means path with
>     differences from the HEAD commit is listed.  By default "restore"
>     checks out the contents of the given path from the index to the
>     working tree, so after "edit F && git add F", "diff-index HEAD"
>     may show F in its output (i.e. F is "committable"), but "restore
>     F" would be a no-op.  Which feels a bit iffy.
I'd not thought of that. --modified is better.
Show 18 quoted lines
>> @@ -2883,14 +2883,21 @@ _git_restore ()
>>   	case "$cur" in
>>   	--conflict=*)
>>   		__gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
>> +		return
>>   		;;
>>   	--source=*)
>>   		__git_complete_refs --cur="${cur##--source=}"
>> +		return
>>   		;;
>> ...
> Do you need to sprinkle return's?  Instead you could just add
> another case arm, like
> 
> +	*)
> +		... whatever you want to do when
> +		... $cur is not a --dashed-option
> +		;;

Liberal sprinkling of return like that seems to be the norm for the rest of the file so I stuck with it.

-- 
David Cantrell
Junio C Hamano· Mar 15, 2022, 10:23 UTC · re: David Cantrell · lore

Re: [PATCH] tab completion of filenames for 'git restore'

David Cantrell <david@cantrell.org.uk> writes:
Show 20 quoted lines
>>> @@ -2883,14 +2883,21 @@ _git_restore ()
>>>   	case "$cur" in
>>>   	--conflict=*)
>>>   		__gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
>>> +		return
>>>   		;;
>>>   	--source=*)
>>>   		__git_complete_refs --cur="${cur##--source=}"
>>> +		return
>>>   		;;
>>> ...
>> Do you need to sprinkle return's?  Instead you could just add
>> another case arm, like
>> +	*)
>> +		... whatever you want to do when
>> +		... $cur is not a --dashed-option
>> +		;;
>
> Liberal sprinkling of return like that seems to be the norm for the
> rest of the file so I stuck with it.

An existing bad practice is not a good excuse to spread it even more, though.

David Cantrell via GitGitGadget· Mar 15, 2022, 00:52 UTC · re: David Cantrell via GitGitGadget · lore

[PATCH v2 0/2] Improved bash tab completion for 'git restore' - adds support for auto-completing filenames

This adds tab-completion of filenames to the bash completions for git restore.

David Cantrell (2):
  tab completion of filenames for 'git restore'
  if a file has been staged we don't want to list it
 contrib/completion/git-completion.bash | 7 +++++++
 1 file changed, 7 insertions(+)
base-commit: 1a4874565fa3b6668042216189551b98b4dc0b1b
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1227%2FDrHyde%2Ffilename-completion-for-git-restore-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1227/DrHyde/filename-completion-for-git-restore-v2
Pull-Request: https://github.com/git/git/pull/1227
Range-diff vs v1:
 1:  2bb8f1cb1c4 = 1:  2bb8f1cb1c4 tab completion of filenames for 'git restore'
 -:  ----------- > 2:  16aa4d0b2e4 if a file has been staged we don't want to list it
-- 
gitgitgadget
David Cantrell via GitGitGadget· Mar 15, 2022, 00:52 UTC · re: David Cantrell via GitGitGadget · lore

[PATCH v2 2/2] if a file has been staged we don't want to list it

From: David Cantrell <david@cantrell.org.uk>

The previous use of --committable would include files that had been `git add`ed, but for which a simple `git restore filename` doesn't work. --modifed only lists those whose modifications have not been staged.

Signed-off-by: David Cantrell <david@cantrell.org.uk>
---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Show changes to contrib/completion/git-completion.bash +1 −1
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 7ccad8ff4b1..10773a9fecd 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2896,7 +2896,7 @@ _git_restore ()
 	esac
 
 	if __git rev-parse --verify --quiet HEAD >/dev/null; then
-		__git_complete_index_file "--committable"
+		__git_complete_index_file "--modified"
 	fi
 }
 
-- 
gitgitgadget
Bagas Sanjaya· Mar 16, 2022, 11:45 UTC · re: David Cantrell via GitGitGadget · lore

Re: [PATCH v2 2/2] if a file has been staged we don't want to list it

On 15/03/22 07.52, David Cantrell via GitGitGadget wrote:
Show 7 quoted lines
> From: David Cantrell <david@cantrell.org.uk>
> 
> The previous use of --committable would include files that
> had been `git add`ed, but for which a simple `git restore filename`
> doesn't work. --modifed only lists those whose modifications have
> not been staged.
> 

The patch title you wrote descriptive mood instead of imperative one. It should have been "don't list staged files".

-- 
An old man doll... just what I always wanted! - Clara
David Cantrell via GitGitGadget· Mar 15, 2022, 00:52 UTC · re: David Cantrell via GitGitGadget · lore

[PATCH v2 1/2] tab completion of filenames for 'git restore'

From: David Cantrell <david@cantrell.org.uk>

If no --args are present after 'git restore' it assumes that you want to tab-complete one of the files with uncommitted changes

Signed-off-by: David Cantrell <david@cantrell.org.uk>
---
 contrib/completion/git-completion.bash | 7 +++++++
 1 file changed, 7 insertions(+)
Show changes to contrib/completion/git-completion.bash +7 −0
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 49a328aa8a4..7ccad8ff4b1 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2883,14 +2883,21 @@ _git_restore ()
 	case "$cur" in
 	--conflict=*)
 		__gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
+		return
 		;;
 	--source=*)
 		__git_complete_refs --cur="${cur##--source=}"
+		return
 		;;
 	--*)
 		__gitcomp_builtin restore
+		return
 		;;
 	esac
+
+	if __git rev-parse --verify --quiet HEAD >/dev/null; then
+		__git_complete_index_file "--committable"
+	fi
 }
 
 __git_revert_inprogress_options=$__git_sequencer_inprogress_options
-- 
gitgitgadget
Junio C Hamano· Mar 15, 2022, 11:23 UTC · re: David Cantrell via GitGitGadget · lore

Re: [PATCH v2 0/2] Improved bash tab completion for 'git restore' - adds support for auto-completing filenames

"David Cantrell via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 6 quoted lines
> This adds tab-completion of filenames to the bash completions for git
> restore.
>
> David Cantrell (2):
>   tab completion of filenames for 'git restore'
>   if a file has been staged we don't want to list it

Why two patches? The second separate patch makes the topic look as if "oops, the first step designed a wrong behaviour and here is a brown paper bag fix-up".

Junio C Hamano· Mar 15, 2022, 16:27 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 0/2] Improved bash tab completion for 'git restore' - adds support for auto-completing filenames

Junio C Hamano <gitster@pobox.com> writes:
Show 12 quoted lines
> "David Cantrell via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
>> This adds tab-completion of filenames to the bash completions for git
>> restore.
>>
>> David Cantrell (2):
>>   tab completion of filenames for 'git restore'
>>   if a file has been staged we don't want to list it
>
> Why two patches?  The second separate patch makes the topic look as
> if "oops, the first step designed a wrong behaviour and here is a
> brown paper bag fix-up".
Sorry, I forgot the obligatory clarification for new contributors.

This project gives all contributors a chance to pretend to be a "perfect human". When sending an updated patch (or patch series), contributors are encouraged to hide^W correct their earlier mistakes and present a perfect logical progression that they (would have, if they were perfect) followed to arrive at a perfect end result.

So, instead of having step 1 that uses --committable without justifying why it was chosen, and then change mind in step 2 to replace it with --modified, have a single patch that uses --modified, and explain in the proposed log message that --committable and --modified may be possibilities, and why the patch chose to use the latter. The resulting history without a flip-flop in the middle is easier to use by future developers to understand the reasoning behind each change.

Thanks.
David Cantrell via GitGitGadget· Mar 15, 2022, 22:13 UTC · re: David Cantrell via GitGitGadget · lore

[PATCH v3] tab completion of filenames for 'git restore'

From: David Cantrell <david@cantrell.org.uk>

If no --args are present after 'git restore' it assumes that you want to tab-complete one of the files with unstaged uncommitted changes.

If a file has been staged we don't want to list it, as restoring those requires a slightly more complex `git restore --staged`, so we only list those files that are --modified. While --committable also looks like a good candidate, that includes changes that have been staged.

Signed-off-by: David Cantrell <david@cantrell.org.uk>
---
    Improved bash tab completion for 'git restore' - adds support for
    auto-completing filenames
    
    This adds tab-completion of filenames to the bash completions for git
    restore.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1227%2FDrHyde%2Ffilename-completion-for-git-restore-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1227/DrHyde/filename-completion-for-git-restore-v3
Pull-Request: https://github.com/git/git/pull/1227
Range-diff vs v2:
 1:  2bb8f1cb1c4 ! 1:  779744b9fc5 tab completion of filenames for 'git restore'
     @@ Commit message
          tab completion of filenames for 'git restore'
      
          If no --args are present after 'git restore' it assumes that you want
     -    to tab-complete one of the files with uncommitted changes
     +    to tab-complete one of the files with unstaged uncommitted changes.
     +
     +    If a file has been staged we don't want to list it, as restoring those
     +    requires a slightly more complex `git restore --staged`, so we only list
     +    those files that are --modified. While --committable also looks like
     +    a good candidate, that includes changes that have been staged.
      
          Signed-off-by: David Cantrell <david@cantrell.org.uk>
      
       ## contrib/completion/git-completion.bash ##
      @@ contrib/completion/git-completion.bash: _git_restore ()
     - 	case "$cur" in
     - 	--conflict=*)
     - 		__gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
     -+		return
     - 		;;
     - 	--source=*)
     - 		__git_complete_refs --cur="${cur##--source=}"
     -+		return
     - 		;;
       	--*)
       		__gitcomp_builtin restore
     -+		return
       		;;
     ++	*)
     ++		if __git rev-parse --verify --quiet HEAD >/dev/null; then
     ++			__git_complete_index_file "--modified"
     ++		fi
       	esac
     -+
     -+	if __git rev-parse --verify --quiet HEAD >/dev/null; then
     -+		__git_complete_index_file "--committable"
     -+	fi
       }
       
     - __git_revert_inprogress_options=$__git_sequencer_inprogress_options
 2:  16aa4d0b2e4 < -:  ----------- if a file has been staged we don't want to list it
 contrib/completion/git-completion.bash | 4 ++++
 1 file changed, 4 insertions(+)
Show changes to contrib/completion/git-completion.bash +4 −0
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 49a328aa8a4..ba5c395d2d8 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2890,6 +2890,10 @@ _git_restore ()
 	--*)
 		__gitcomp_builtin restore
 		;;
+	*)
+		if __git rev-parse --verify --quiet HEAD >/dev/null; then
+			__git_complete_index_file "--modified"
+		fi
 	esac
 }
 

base-commit: 1a4874565fa3b6668042216189551b98b4dc0b1b
-- 
gitgitgadget
Junio C Hamano· Mar 16, 2022, 00:44 UTC · re: David Cantrell via GitGitGadget · lore

Re: [PATCH v3] tab completion of filenames for 'git restore'

"David Cantrell via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: David Cantrell <david@cantrell.org.uk>
> Subject: Re: [PATCH v3] tab completion of filenames for 'git restore'
Perhaps
    Subject: [PATCH v3] completion: complete modified files for 'git restore'
cf. Documentation/SubmittingPatches::[[summary-section]]
> If no --args are present after 'git restore' it assumes that you want
> to tab-complete one of the files with unstaged uncommitted changes.

Since it is our convention that the first paragraph talks about the current behaviour, i.e. without the proposed changes applied, in the present tense, I'd assume the above is what the current code does.

What do you mean by "--args" in this sentence? Dashed-options? I am getting the same set of files whose name begins with 'a' from these two:

 $ git restore a<TAB>
 $ git restore --staged a<TAB>

so, with or without --dashed-options, we complete one of the files, whether they have any modifications.

Perhaps you meant to say more like:
    When completing a non-option argument to 'git restore', the
    command line completion support offers names of the files
    present in the working tree as candidates.

to describe the status quo; to hint what the shortcoming of the current behaviour is, we may want to add a bit more, perhaps append the following at the end of that first paragraph:

    But many of these files may not have any changes, and running
    "restore" on them would be a no-op.  Listing only the files, to
    which doing "restore" is not a no-op, would reduce the clutter.
    
Then we'd continue with the solution, while explaining why the exact
choice between modified vs committable was made:
    Offer only the files that are different from the index, to match
    the default behaviour of "git restore" that checks out the
    contents last added to the index to the working tree.  We could
    instead show the files that are different between the index and
    HEAD, and that is more suittable if "git restore --staged" is
    being completed, but this should do for now.

or something. The last part is written in such a way to explicitly signal to future developers that we know we did not do a perfect job and we do not mind if they extend the logic to use something other than "--modified" when appropriate. For example, they could build on this solution to make it inspect the command line for "--staged" and "--source" and drive "diff-index" differently to grab the paths that are offered. We just do not do that at least for now, but we have no objection if other people do so in the future.

Thanks.  Will queue as-is for now.
Show 17 quoted lines
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 49a328aa8a4..ba5c395d2d8 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -2890,6 +2890,10 @@ _git_restore ()
>  	--*)
>  		__gitcomp_builtin restore
>  		;;
> +	*)
> +		if __git rev-parse --verify --quiet HEAD >/dev/null; then
> +			__git_complete_index_file "--modified"
> +		fi
>  	esac
>  }
>  
>
> base-commit: 1a4874565fa3b6668042216189551b98b4dc0b1b
David Cantrell· Mar 17, 2022, 22:16 UTC · re: Junio C Hamano · lore

Re: [PATCH v3] tab completion of filenames for 'git restore'

On 16/03/2022 00:44, Junio C Hamano wrote:
> "David Cantrell via GitGitGadget" <gitgitgadget@gmail.com> writes:
>> If no --args are present after 'git restore' it assumes that you want
>> to tab-complete one of the files with unstaged uncommitted changes.
> What do you mean by "--args" in this sentence?  Dashed-options?
Yes.
Show 8 quoted lines
> I am getting the same set of files whose name begins with 'a' from
> these two:
> 
>   $ git restore a<TAB>
>   $ git restore --staged a<TAB>
> 
> so, with or without --dashed-options, we complete one of the files,
> whether they have any modifications.

If --staged is present I think it falls back to the standard behaviour of attempting to complete to any file it can find

Show 32 quoted lines
> Perhaps you meant to say more like:
> 
>      When completing a non-option argument to 'git restore', the
>      command line completion support offers names of the files
>      present in the working tree as candidates.
> 
> to describe the status quo; to hint what the shortcoming of the
> current behaviour is, we may want to add a bit more, perhaps
> append the following at the end of that first paragraph:
> 
>      But many of these files may not have any changes, and running
>      "restore" on them would be a no-op.  Listing only the files, to
>      which doing "restore" is not a no-op, would reduce the clutter.
>      
> Then we'd continue with the solution, while explaining why the exact
> choice between modified vs committable was made:
> 
>      Offer only the files that are different from the index, to match
>      the default behaviour of "git restore" that checks out the
>      contents last added to the index to the working tree.  We could
>      instead show the files that are different between the index and
>      HEAD, and that is more suittable if "git restore --staged" is
>      being completed, but this should do for now.
> 
> or something.  The last part is written in such a way to explicitly
> signal to future developers that we know we did not do a perfect job
> and we do not mind if they extend the logic to use something other
> than "--modified" when appropriate.  For example, they could build
> on this solution to make it inspect the command line for "--staged"
> and "--source" and drive "diff-index" differently to grab the paths
> that are offered.  We just do not do that at least for now, but we
> have no objection if other people do so in the future.
That makes sense.
> Thanks.  Will queue as-is for now.
Thank you.
-- 
David Cantrell

← back to recent threads