[PATCH/WIP] completion: complete git diff with only changed files.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The bash completion script for git diff completes either for
references or for file names. If there was a -- given, it uses
the default bash filename completion.

The completion for hg diff completes only changed file names
here - this is quite useful if we want to see changes in only
some file (or directory). (This was mentioned on stackoverflow,
which gave me the idea: http://stackoverflow.com/q/6034472/600500 )

I ported this idea to git. Now
   git diff -- <tab>
will complete any changed files. It also works for the other ways
of calling git diff, except the .. and ... notations (as I'm
not sure how to do this).

Signed-off-by: PaÅlo Ebermann <Paul-Ebermann@xxxxxx>
---

Hello,
this is my first contribution to git at all, and I only joined the
mailing list some hours ago (right before starting to code this), so I hope
I'm not making any mistakes here. (I read the SubmittingPatches document,
though.)


I only made this work after the --, while the usual file completion already
seems to work if there is no --. I'm not really sure what is wanted here.

I'm checking the non-option arguments on being commits (or tags), and pass
only the matching ones to the nested `git diff` call.
It might be easier to ommit this check and pass everything that does not
start with a `-`. Then it would also easily work for the .. and ... syntax,
I think.
Opinions?

The same completion function or a variation might also be useful for other
commands like git add (completing changed or new files) or git rm
(completing already removed files). Input is welcome here.

This patch is based on the current master branch, I hope this is the right
one.


 contrib/completion/git-completion.bash |   72 +++++++++++++++++++++++++++++++-
 1 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index bb8d7d0..c529bdf 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -663,6 +663,69 @@ __git_compute_merge_strategies ()
 	: ${__git_merge_strategies:=$(__git_list_merge_strategies)}
 }
 
+
+# Completion for the file argument for git diff.
+# It completes only files actually changed. This might be useful
+# as completion for other commands as well.
+#
+# The idea comes from the bash completion for Mercurial (hg),
+# which does something similar (but more simple, only difference of
+# working directory to HEAD and/or index, if I understand right).
+# It (the idea) was brought to us by the question
+#      http://stackoverflow.com/q/6034472/600500
+#  from "olt".
+__git_complete_changed_files()
+{
+  #
+  # We use "git diff --name-only --relative" to generate the list,
+  # but this needs the same --cached and <commit> arguments as the
+  # command line being constructed.
+  #
+
+
+    # first grab arguments like --cached and any commit arguments.
+
+    local -a args=()
+    local finish=false
+
+    for (( i=1 ; i < cword ; i++)) do
+    local current_arg=${words[$i]}
+    #  echo checking $current_arg >&2
+       case $current_arg in
+           --cached)
+               args+=( $current_arg )
+               ;;
+           --)
+               # finish parsing arguments, the rest are file names
+               break
+               ;;
+           -*)
+               # other options are ignored
+               ;;
+           *)
+               if git cat-file -e $current_arg 2> /dev/null
+               then
+                   case $( git cat-file -t $current_arg ) in
+                       commit|tag)
+                       # commits and tags are added to the command line.
+                           args+=( $current_arg )
+                           # echo adding $current_arg >&2
+                           ;;
+                       *)
+                   esac
+               fi
+               ;;
+       esac
+    done
+
+    # now we can call `git diff`
+
+    COMPREPLY=( $( compgen \
+        -W "$( git diff --name-only --relative "${args[@]}" -- )" -- $cur ) )
+}
+
+
+
 __git_complete_revlist_file ()
 {
 	local pfx ls ref cur_="$cur"
@@ -1314,10 +1377,14 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
 			--dirstat-by-file= --cumulative
 "
 
+
 _git_diff ()
 {
-	__git_has_doubledash && return
-
+    if __git_has_doubledash
+    then
+        # complete for the file part: only changed files
+        __git_complete_changed_files
+    else
 	case "$cur" in
 	--*)
 		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
@@ -1328,6 +1395,7 @@ _git_diff ()
 		;;
 	esac
 	__git_complete_revlist_file
+    fi
 }
 
 __git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]