Git的庆典,以完成文件名支持? [英] Git bash-completion with filename support?

查看:203
本文介绍了Git的庆典,以完成文件名支持?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有支持文件名完成一个bash自动完成脚本?我主要使用水银和那里我可以输入:

is there a bash-completion script that supports filename completion? I use mostly mercurial and there I can type:

hg diff test/test_<tab>

,它会显示/完成所有修改过的测试文件。它适用于大多数子命令,即汞添加&LT;标签&gt;&LT;标签&gt; 将只列出未跟踪文件。这实在是方便。

and it will show/complete all modified test files. It works for most subcommands, i.e. hg add <tab><tab> will only list untracked files. It is really handy.

这混帐的contrib接缝的bash脚本不支持这一点。是否有任何替代品,或者你怎么用命令行的git的工作?

The bash script from git contrib seams to not support this. Are there any alternatives, or how do you work with git on the command line?

修改2015

混帐completion.bash 支持完整的文件名,因为完成的〜1.8.2

git-completion.bash supports full filename completion since ~1.8.2

推荐答案

所以,让我们看到了水银的bash脚本完成如何做到这一点。

So, let's see how the Mercurial bash completion script does this.

这是重要组成部分

_hg_status()
{
    local files="$(_hg_cmd status -n$1 .)"
    local IFS=$'\n'
    COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
}

在这里被调用

It gets called here:

_hg_command_specific()
{
    case "$cmd" in 
    [...]
    diff)
        _hg_status "mar"
    ;;
    [...]
    esac
    return 0
}

因此​​,它是一个简单的通话汞柱状态-nmar ,并使用输出作为完成的文件列表。

Thus, it is simply a call of hg status -nmar, and using the output as a list of files for completion.

我想会不会太硬修补类似成的 git的完成脚本 - 我们将不得不修改 __ git_diff 在这里不能做一个普通的文件名+分公司完成,但调用 git的状态代替。

I think it would not be too hard to patch something similar into the git completion script - we would have to modify __git_diff here to not do a plain filename + branch completion, but calling git status instead.

命令

git status --porcelain | grep '^.[^ ?]' | cut -b 4-

(为 git的差异--cached )以及

git status --porcelain | grep '^[^ ?]' | cut -b 4-

(为 git的差异)似乎输出正确的事情(如果没有改名)。

(for git diff) seem to output the right thing (if there are no renames).

版本比较除头之外的任何时候,虽然他们都是没有用的。

They both are not useful when diffing to anything other than HEAD, though.

一个更一般的方式是使用

A more general way would be to use

git diff --relative --name-only [--cached] [commit1] [commit2]]

其中, commit1 commit2 (也许 - 缓存)来自已经给diff命令行。

where commit1 and commit2 (and maybe --cached) come from the already given diff command line.

我实现这个想法上面的介绍在bash和修补成混帐completion.bash 。如果你不想改变你的混帐completion.bash ,这两个功能添加到原来经过一番的bash文件和源它 git- completion.bash 。现在应该像

I implemented the idea outlined above in bash, and patched into git-completion.bash. If you don't want to change your git-completion.bash, add these two functions to some bash file and source it after the original git-completion.bash. It should now work with commands like

git diff -- <tab>
git diff --cached -- <tab>
git diff HEAD^^ -- <tab>
git diff origin/master master -- <tab>

这作为补丁git的邮件列表,让我们看看结果源于此。 (因为我得到的反馈那里我会更新这个答案。)

I submitted this as a patch to the git mailing list, let's see what results from this. (I'll update this answer as I get feedback there.)

# 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_diff ()
{
    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
            --base --ours --theirs --no-index
            $__git_diff_common_options
            "
        return
        ;;
    esac
    __git_complete_revlist_file
    fi
}


更新:貌似这个补丁不以这种形式想,作为当前的方式来完成的文件是其中要检查是否有一些子目录改变人们更加有用(如完成时在差异输出可能是空的)。如果与一些配置变量(默认为当前行为)可能被接受。此外,该缩进应适应于标准(见从 JUNIOÇ滨野答案)。


Update: Looks like this patch is not wanted in this form, as the current way to complete files is more useful for people which want to check whether there are changes in some subdirectory (e.g. completing when the diff output could be empty). It might be accepted if linked to some configuration variable (with the default being the current behavior). Also, the indenting should be adapted to the standard (see the answer from Junio C Hamano).

我可能会采取另一种走就可以了,但不能保证这一点在不久的将来。如果其他人想这样做,随意把我的code,改变它,再次提交。

I might take another go on it, but can't guarantee this for the near future. If someone else want to do, feel free to take my code, change it and submit it again.

这篇关于Git的庆典,以完成文件名支持?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆