2011-05-17 11 views
9

क्या एक बैश-समापन स्क्रिप्ट है जो फ़ाइल नाम पूर्ण करने का समर्थन करती है? मैं ज्यादातर mercurial का उपयोग करता हूं और वहां मैं टाइप कर सकता हूं:फ़ाइल नाम समर्थन के साथ गिट बैश-समापन?

hg diff test/test_<tab> 

और यह सभी संशोधित परीक्षण फ़ाइलों को दिखाएगा/पूरा करेगा। यह अधिकांश उपमहाद्वीपों के लिए काम करता है, यानी hg add <tab><tab> केवल अनचाहे फ़ाइलों को सूचीबद्ध करेगा। यह वास्तव में आसान है।

गिट contrib seams से बैश स्क्रिप्ट इस का समर्थन नहीं करने के लिए। क्या कोई विकल्प है, या आप कमांड लाइन पर गिट के साथ कैसे काम करते हैं?

संपादित करें 2015

git-completion.bash पूर्ण फ़ाइल नाम पूर्णता का समर्थन के बाद से ~1.8.2

+0

मैं सामान्य रूप से पहले 'Git status' का उपयोग करें, और उसके बाद क्या' Git diff' के लिए टाइप करने के लिए पता है। (लेकिन सबसे अधिक बार मैं 'मतभेदों को देखने के लिए gitk' उपयोग कर रहा हूँ।) –

उत्तर

13

तो चलिए देखते हैं कि कैसे मर्क्युरियल बैश पूरा होने स्क्रिप्ट करता हैं।

यह important part है:

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

यह here कहा जाता हो जाता है:

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

इस प्रकार, यह बस hg status -nmar के एक फोन है, और पूरा करने के लिए फ़ाइलों की एक सूची के रूप में उत्पादन का उपयोग कर।

मुझे लगता है कि यह बहुत कठिन git completion script में कुछ इसी तरह पैच करने के लिए नहीं हो सकता है - हम यहाँ __git_diff संशोधित करने के लिए एक सादे फ़ाइल नाम + शाखा पूरा होने से काम नहीं करने के लिए होगा, लेकिन इसके बजाय git status बुला।


आदेशों

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

(git diff --cached के लिए) और

git status --porcelain | grep '^[^ ?]' | cut -b 4- 
( git diff के लिए)

उत्पादन सही बात लग रहे (अगर कोई renames हैं)।

हालांकि वे दोनों हेड के अलावा किसी अन्य चीज में भिन्न होने पर उपयोगी नहीं हैं।

एक अधिक सामान्य तरीका

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

उपयोग करने के लिए जहां commit1 और commit2 (और शायद --cached) पहले से ही दिए गए diff कमांड लाइन से आते हैं होगा।


मैं विचार बैश में ऊपर उल्लिखित लागू किया, और git-completion.bash में समझौता। यदि आप अपना git-completion.bash नहीं बदलना चाहते हैं, तो इन दो फ़ंक्शंस को कुछ बैश फ़ाइल में जोड़ें और मूल git-completion.bash के बाद इसे स्रोत करें। अब यह की तरह

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

मैं submitted this Git मेलिंग सूची के लिए एक पैच के रूप में आदेशों के साथ काम करते हैं, देखते हैं कि यह से क्या परिणाम देना चाहिए।(मैं के रूप में मैं प्रतिक्रिया वहाँ पाने के इस जवाब से अपडेट करेंगे।)

# 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 
} 

अद्यतन: लग रहा है इस पैच की तरह इस रूप में करना चाहता था नहीं है, फ़ाइलों को पूरा करने के लिए मौजूदा तरीके के रूप में के लिए अधिक उपयोगी है लोग जो जाँच करना चाहते हैं कि क्या वहाँ कुछ उपनिर्देशिका में परिवर्तन (जैसे पूरा जब diff उत्पादन खाली हो सकता है) कर रहे हैं। अगर कुछ कॉन्फ़िगरेशन चर से जुड़ा हुआ है (डिफ़ॉल्ट रूप से वर्तमान व्यवहार होने के साथ) यह स्वीकार किया जा सकता है। इसके अलावा, खिसकने मानक करने के लिए अनुकूलित किया जाना चाहिए (Junio C Hamano से जवाब देखें)।

मैं एक और उस पर जाना लग सकता है, लेकिन निकट भविष्य के लिए यह गारंटी नहीं दे सकते। अगर कोई और करना चाहता है, तो मेरा कोड लेने के लिए स्वतंत्र महसूस करें, इसे बदलें और इसे दोबारा सबमिट करें।

3

यह मेरे लिए git diff <tab> समस्या का हल, डाल .bashrc में निम्नलिखित:

alias gid='git diff' 
__gdiff() { 
    local cur prev opts 
    COMPREPLY=() 
    cur="${COMP_WORDS[COMP_CWORD]}" 
    prev="${COMP_WORDS[COMP_CWORD-1]}" 
    opts=$(git status --porcelain | grep '^.[^ ?]' | cut -b 4-) 

    case "${prev}" in 
     gid) 
      COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
      ;; 
    esac 
} 
complete -F __gdiff gid 

और फिर gid <tab> बजाय git diff <tab> है। इसे सरल बनाया जा सकता है, लेकिन एक त्वरित फिक्स के रूप में अच्छी तरह से काम करता प्रतीत होता है।

0

नहीं वास्तव में अपने वांछित जवाब लेकिन मैं तुम्हें पता है कि जल्द ही मछली (अनुकूल इंटरैक्टिव खोल) आप बॉक्स से बाहर Git फ़ाइल नाम पूरा होने समर्थन दे देंगे बताना चाहता था। यह वर्तमान में 2.3.0 रिलीज के साथ जल्द ही मास्टर में है।

https://github.com/fish-shell/fish-shell/issues/901
https://github.com/fish-shell/fish-shell/pull/2364
https://github.com/fish-shell/fish-shell/commit/c5c59d4acb00674bc37198468b5978f69484c628

आप इस तरह एक स्थिति है, तो:

$ git status 
modified: ../README.md 
$ git add <tab> 
:/README.md 

enter image description here

आप, साथ ही टाइप कर सकते हैं README और टैब मारा और इसके लिए जोड़ दिया जाएगा आप अगर यह एकमात्र मैच है। Friggin अच्छा है!

+0

पोस्ट में अपने 2015 अपडेट देखें: – olt

+0

आह, शांत, धन्यवाद" Git-completion.bash पूर्ण फ़ाइल नाम पूरा होने ~ 1.8.2 के बाद से समर्थन करता है। " –

संबंधित मुद्दे