Git æä»¶èªå¨è¡¥å ¨ | AIçæåç¿»è¯
Question: æä»¬å¯ä»¥ä½¿ç¨ git ls-files æ¥è·åèªå¨æé¤ .gitignore æ¡ç®çæä»¶å表ï¼ç¨ä½ @ æåèªå¨è¡¥å
¨çæ¥æºåï¼
Answer:
æ¯ç â git ls-files æ£æ¯è¿éæ£ç¡®çå·¥å
·ãå®åçå°é .gitignoreï¼ä»
è¿åå·²è·è¸ª/å¯è·è¸ªçæä»¶ãè¿ä¹æ¯ Claude Code å
鍿åçã
为ä»ä¹ git ls-files æ¯ glob æ´å¥½
ä½¿ç¨ git ls-files çæ´æ°ç AtFileCompleter
import subprocess
import os
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import Completer, Completion
def get_git_files():
"""Return all files tracked or untracked-but-not-ignored by git."""
try:
# --cached = tracked files (staged/committed)
# --others = untracked files
# --exclude-standard = respect .gitignore, .git/info/exclude, etc.
result = subprocess.run(
["git", "ls-files", "--cached", "--others", "--exclude-standard"],
capture_output=True,
text=True,
timeout=5,
)
if result.returncode == 0:
return result.stdout.splitlines()
except (FileNotFoundError, subprocess.TimeoutExpired):
pass
return []
# Cache file list â refresh only when needed
_file_cache = None
def get_cached_files(force_refresh=False):
global _file_cache
if _file_cache is None or force_refresh:
_file_cache = get_git_files()
return _file_cache
class AtFileCompleter(Completer):
def get_completions(self, document, complete_event):
text = document.text_before_cursor
at_pos = text.rfind("@")
if at_pos == -1:
return
prefix = text[at_pos + 1:]
if " " in prefix:
return
all_files = get_cached_files()
for path in all_files:
if prefix.lower() in path.lower(): # fuzzy substring match
meta = "dir" if os.path.isdir(path) else "file"
yield Completion(
path,
start_position=-len(prefix),
display=path,
display_meta=meta,
)
def main():
session = PromptSession(
completer=AtFileCompleter(),
complete_while_typing=True,
)
print("Type your message. Use @filename to reference files.\n")
while True:
try:
user_input = session.prompt("> ")
except (EOFError, KeyboardInterrupt):
break
if user_input.strip() == ".exit":
break
print(f"[You said]: {user_input}\n")
if __name__ == "__main__":
main()
æ¯ä¸ª git ls-files æ å¿çä½ç¨
git ls-files --cached --others --exclude-standard
没æ --othersï¼æ¨åå建çå
¨æ°æä»¶å¨ git add ä¹åä¸ä¼åºç°ãé常æ¨éè¦ä¸¤è
ã
å¯éï¼æä»¶åæ´æ¶çç¼å失æ
妿æ¨å¸ææä»¶åè¡¨å¨æä»¶åæ´æ¶å·æ°ï¼ä¾å¦ç¨æ·å¨ä¼è¯ä¸åå»ºæ°æä»¶ï¼ï¼å¯ä»¥å¨æ¯æ¬¡ @ è§¦åæ¶å¼ºå¶å·æ°ï¼
class AtFileCompleter(Completer):
def get_completions(self, document, complete_event):
text = document.text_before_cursor
at_pos = text.rfind("@")
if at_pos == -1:
return
prefix = text[at_pos + 1:]
if " " in prefix:
return
# Force refresh each time @ is triggered (slightly slower but always fresh)
all_files = get_cached_files(force_refresh=True)
for path in all_files:
if prefix.lower() in path.lower():
yield Completion(path, start_position=-len(prefix))
对äºå¤§å¤æ°ä»åºï¼< 10,000 个æä»¶ï¼ï¼git ls-files å¨ 50ms 以å
宿ï¼å æ¤è¿æ²¡é®é¢ã
æ»ç»
ç¨ git ls-files --cached --others --exclude-standard æ¿æ¢æ¨ç glob æ¹æ³ â å®éè¿ä¸æ¬¡ subprocess è°ç¨ä¸ºæ¨æä¾å¹²åçãæç¥ .gitignore çæä»¶å表ãå¨å
åä¸ç¼åç»æï¼å¹¶å¨æ¯æ¬¡ @ è§¦åæ¶å¯éå·æ°ãè¿æ£å¥½å¹é
Claude Code å¦ä½ç¸å¯¹äºä»åºæ ¹ç®å½è§£æå
¶æä»¶æåå表ã
åèèµæï¼
