One way to accomplish this would be to copy the git completion script,
/usr/share/bash-completion/completions/git, to
~/.local/share/bash-completion/completions/ and modify it to complete with
full index paths:
mkdir -p ~/.local/share/bash-completion/completions
cd ~/.local/share/bash-completion/completions
cp /usr/share/bash-completion/completions/git .
# See diff below
patch -lp0 </tmp/index_paths.diff
echo GIT_COMPLETION_FULL_INDEX_PATHS=1 >>~/.bashrc
exec bash
As far as I can tell the changes required are:
- Modify - __git_index_files()so that it outputs full index paths rather than
just the first path component.
 
- In - __git_complete_index_file(), stop using- __gitcomp_file_directto set- COMPREPLYbecause it uses- compopt -o filenames, which only outputs
basenames. This option was also taking care of shell quoting, so do that
manually now.
 
Note that __git_complete_index_file is used for the completion of several
other git commands other than add such as clean, commit, and rm, so the
full path completion will apply to those too. Here's the diff of my attempt at
these changes, which adds the functionality behind the shell variable
GIT_COMPLETION_FULL_INDEX_PATHS:
--- git
+++ git
@@ -39,6 +39,11 @@
 #     When set to "1", do not include "DWIM" suggestions in git-checkout
 #     and git-switch completion (e.g., completing "foo" when "origin/foo"
 #     exists).
+#
+#   GIT_COMPLETION_FULL_INDEX_PATHS
+#
+#     Normally index path completions return only the next path component. When
+#     set to "1", the whole path will be completed.
 
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
@@ -435,6 +440,19 @@
    __gitcomp_nl_append "$@"
 }
 
+# Shell quotes each word and fills the COMPREPLY array.
+# 1: List of newline-separated completion words.
+__gitcomp_quote_direct ()
+{
+   local IFS=$'\n'
+   local quoted="$1"
+   [[ -n $1 ]] && quoted=$(printf '%q\n' $1)
+
+   COMPREPLY=($quoted)
+
+   compopt +o nospace 2>/dev/null || true
+}
+
 # Fills the COMPREPLY array with prefiltered paths without any additional
 # processing.
 # Callers must take care of providing only paths that match the current path
@@ -503,10 +521,12 @@
 __git_index_files ()
 {
    local root="$2" match="$3"
+   local field=1
+   [ "$GIT_COMPLETION_FULL_INDEX_PATHS" = "1" ] && field=0
 
    __git_ls_files_helper "$root" "$1" "$match" |
    awk -F / -v pfx="${2//\\/\\\\}" '{
-       paths[$1] = 1
+       paths[$f] = 1
    }
    END {
        for (p in paths) {
@@ -518,19 +538,13 @@
 
            # The path is quoted.
            p = dequote(p)
-           if (p == "")
-               continue
 
-           # Even when a directory name itself does not contain
-           # any special characters, it will still be quoted if
-           # any of its (stripped) trailing path components do.
-           # Because of this we may have seen the same directory
-           # both quoted and unquoted.
-           if (p in paths)
-               # We have seen the same directory unquoted,
-               # skip it.
-               continue
-           else
+           # When not using full index paths, p in paths is checked
+           # because the dequoted directory name may already be in
+           # paths. This is the case when the directory name itself
+           # does not contain special characters, but a (stripped)
+           # trailing path component does.
+           if (p != "" && (f == 0 || !(p in paths)))
                print pfx p
        }
    }
@@ -573,7 +587,7 @@
            out = out p
 
        return out
-   }'
+   }' "f=$field"
 }
 
 # __git_complete_index_file requires 1 argument:
@@ -595,7 +609,11 @@
        cur_="$dequoted_word"
    esac
 
-   __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
+   if [ "$GIT_COMPLETION_FULL_INDEX_PATHS" = "1" ]; then
+       __gitcomp_quote_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
+   else
+       __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
+   fi
 }
 
 # Lists branches from the local repository.
     
    
zsh+ zsh-autosuggestions, which can be installed simply by runningmkdir -p ~/.zsh && git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions && echo 'source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh >> ~/.zshrc', or probably simply through your distro's package manager)