문제

문제

문제

나는 다음을 가지고 있습니다

git reset HEAD^ half_entered_file_n<Tab>

이 시점에서 half_entered_file_name.txt를 탭 완성하고 싶습니다.

나만의 조사

글을 쓰면 탭 완성이 작동하도록 할 수 있습니다

git reset HEAD\^ ...

대신 "^"를 이스케이프 처리합니다.

HEAD도 존재하지 않는 한 마지막 문자로 "^"를 쓰는 것은 자동 완성에 영향을 미치지 않는 것 같습니다.

#autocomplete works
git reset RANDOM^ half_entered_file_n<Tab> #works

Zsh 구성

저는 Oh-my-zsh를 사용하고 있습니다. oh-my-zsh 외에도 관련성이 있을 수 있는 다음을 구성했습니다.

# Let <TAB> auto completion add a slash at the end instead of space (like BASH)
zstyle ':completion:*' special-dirs true 

# Unless this option is set, you can't write git checkout HEAD^^ without escaping ^ as \^ in zsh
setopt NO_NOMATCH 

# Standard git plugins
plugins=(git git-extras)

완전성을 위해,여기 내 구성이 있습니다

iTerm2의 OSX에서 이것을 실행하고 있습니다.

감사해요!

업데이트

몇 가지 반 솔루션을 찾았지만 아직 "답변" 상태로 이어지는 것은 없습니다. 기본적으로 솔루션이 아닙니다.

  1. compdef -d git.zshrc에 설정"원시인"이 제안한대로
    • 해결: 이제 HEAD^가 더 이상 파일 자동 완성을 중단하지 않습니다.
    • 단점: git 명령 자동 완성이 더 이상 작동하지 않습니다.
  2. 사용이 질문에서 "ralphtheninja"가 답변을 수락했습니다.
    • 해결 방법: 파일 완성 목록이 생성되는 방식을 바꿔서 문제를 해결해야 합니다.
    • 단점: 작동하지 않습니다. git-completion.zsh/.bash의 구문이 변경된 것 같습니다.

나는 git-completion.zsh/.bash에서 무슨 일이 일어나고 있는지 정확히 이해할 만큼 쉘 스크립팅을 잘 알지 못합니다. 그것이 문제가 되는 이유라면 말이죠.

답변1

가정하면 안되는 이유

오랫동안 나는 zsh 구성의 git 완료가 에서 /usr/local/share/git-core/contrib/completion/, 특히 git-completion.zsh또는 심지어 에서 온다고 가정했습니다 git-completion.bash. 대부분의 검색에서 이러한 파일에 대한 결과가 나오기 때문에 나는 이것을 가정하고 있었던 것 같습니다. 그러나 나는 이러한 파일을 명시적으로 포함하지 않았으며 오랫동안 oh-my-zsh가 해당 파일을 포함하고 있다고 추측했습니다.

하지만...

우리는 더 이상 캔자스에 있지 않습니다

를 통해 활성화된 zsh 메서드 추적을 사용하고 나서야 setopt xtrace사용 중인 스크립트가 실제로 이라는 것을 (일부 메서드 이름을 검색하여) 깨달았습니다 /usr/local/share/zsh/functions/_git. 나는 이전에 사용했던XCode Instruments.app파일 시스템에서 어떤 스크립트에 액세스하고 있는지 모니터링했지만 당시에는 파악하지 못했습니다(출력이 상당히 수다스럽고 다른 앱의 액세스도 표시됩니다).

무슨 일이야?

흔적이 이것을 보여주었습니다 (부분적인 흔적이 앞서 있습니다!)

git reset HEAD <TAB>
...
+__git_tree_files:17> tree=HEAD
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z HEAD ./
+__git_tree_files:18> tree_files+=( first second third )

그리고

git reset HEAD^ <TAB>
...
+__git_tree_files:17> tree=HEAD^
+__git_tree_files:18> tree_files+=+__git_tree_files:18> _call_program tree-files git ls-tree --name-only -z 'HEAD^' ./
+__git_tree_files:18> tree_files+=( )

그 빈 공간이 tree_files의심스러워 보입니다.

6058번 라인에서 /usr/local/share/zsh/functions/_git우리는 다음을 찾습니다.

tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z $tree $Path 2>/dev/null)"})

우리는 반드시 그 변수를 탈출해야 합니다 $tree. 말하고 완료했습니다 :

tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree $extra_args --name-only -z ${(q)tree} $Path 2>/dev/null)"}) 

발문

이 스크립트에는 몇 가지 버그가 더 있습니다(예: 파일 목록은 HEAD를 기반으로 해야 하는데 에 대한 파일 목록 git reset <tree-ish>은 을 기반으로 합니다 . 이제 문제를 수정할 위치를 알 수 있습니다!<tree-ish>

업데이트

대신 git에서 완성 스크립트를 실행할 수도 있습니다.이 답변을 따르면 그렇게 할 수 있습니다.

관련 정보