title: Bash completion: Honor repository-specific Git alias in alias completion
body: <p>Say bash is configured with the following alias:</p>
  
  <p><code>alias up="git --git-dir /path/to/backup/.git"
  </code></p>
  
  <p>And that particular repository - and only that repository - has the following git alias:</p>
  
  <pre><code>[alias]
  backup = commit --allow-empty-message
  </code></pre>
  
  <p>How can <code>up</code> auto-complete <code>backup</code>?</p>
  
  <hr>
  
  <p>This auto-completes <code>backup</code> but not <code>up</code>:</p>
  
  <pre><code>cd /a/different/dir
  git --git-dir=/path/to/backup/.git ba
  </code></pre>
  
  <p>This auto-completes <code>up</code> with standard git commands but not <code>backup</code>:</p>
  
  <p><code>complete -o bashdefault -o default -o nospace -F __git_wrap__git_main up
  </code></p>
  
  <hr>
  
  <p><em>Edit</em>: Etan is right, the completion function needs to see the expanded alias, so I've created the following:</p>
  
  <pre><code>CompletableAlias() {
      if (($#&lt;2)); then
          return 1
      fi
      source_c="$1"
      target_c="$2"
      target_a=( "${@:2}" )
      target_s="${target_a[*]}"
      alias "${source_c}=${target_s}"
      completion_modifier="__${source_c}_completion"
      completion_original="$( complete -p "$target_c" 2&gt;/dev/null |
                              sed 's/.*-F\W\+\(\w\+\).*/\1/'
                            )"
      if [[ -n "$completion_original" ]]; then
          read -r -d '' completion_function &lt;&lt;-EOF
          function $completion_modifier() {
              COMP_LINE="\${COMP_LINE/#${source_c}/${target_s}}"
              ((COMP_POINT+=${#target_s}-${#source_c}))
              ((COMP_CWORD+=${#target_a[@]}-1))
              COMP_WORDS=( ${target_a[@]} \${COMP_WORDS[@]:1} )
              $completion_original
          }
  EOF
          eval "$completion_function"
          completion_command="$( complete -p "$target_c" |
                                 sed "s/${completion_original}/${completion_modifier}/;
                                      s/\w\+\$/${source_c}/"
                               )"
          $completion_command
      fi
  }
  
  
  source "/usr/share/bash-completion/completions/git"
  
  CompletableAlias "up" "git" "--git-dir" "/path/to/backup/.git"
  </code></pre>
  
  <p>But there inexplicable problems:</p>
  
  <ul>
  <li><code>up bac&lt;Tab&gt;</code> doesn't work</li>
  <li><code>up &lt;Tab&gt;</code> uses default completion and doesn't list git subcommands</li>
  <li>and many more ...</li>
  </ul>
  
  <hr>
  
  <p><em>Edit 2</em>: Updated the script to fix the aforementioned problems using the suggestions at <a href="http://ubuntuforums.org/showthread.php?t=733397&amp;p=12514588#post12514588" rel="nofollow">Re: Bash completion of aliased commands</a>. Apparently this is a pretty common task. However now I'm running into this error message:</p>
  
  <pre><code>$ cd /a/different/dir
  $ up backup&lt;Tab&gt; fatal: Not a git repository (or any of the parent directories): .git
  </code></pre>