Шпаргалка Далвича: как воспроизвести "git ls-files"?
Уважаемые участники сообщества,
Я работаю над системой анализа кода и хотел бы заменить вызовы приложения CLI Git модулем Dulwich. В качестве первого шага мне нужно заменить команду "git ls-files" на эквивалент Dulwich. Я сделал это следующим образом:
import os
import stat
import subprocess
from tempfile import TemporaryDirectory
from dulwich import porcelain
from dulwich.repo import Repo
from dulwich.objects import Commit, Tree
def _flatten_git_tree(r, object_sha, prefix=b'', sep=b'/'):
result=[]
git_object=r.get_object(object_sha)
if git_object.type_name==b'tree':
for item in git_object.iteritems():
if stat.S_ISREG(item.mode):
result.append(sep.join([prefix, item.path]))
if stat.S_ISDIR(item.mode):
result.extend(_flatten_git_tree(r, item.sha, prefix+sep+item.path, sep))
if git_object.type_name==b'commit':
result.extend(_flatten_git_tree(r, git_object.tree, prefix, sep))
return result
def _run_git_cmd(git_arguments):
return subprocess.Popen(git_arguments, stdout=subprocess.PIPE).communicate()[0]
with TemporaryDirectory() as temp_dir:
git_clone_url=r"https://github.com/dulwich/dulwich.git"
repo=porcelain.clone(git_clone_url, temp_dir, checkout=True)
dulwich_ls_files=_flatten_git_tree(repo, repo.head())
git_ls_files=_run_git_cmd(['git', '-C', os.path.join(temp_dir, 'dulwich'), 'ls-files'])
git_ls_files=git_ls_files.decode('utf-8').splitlines()
assert len(dulwich_ls_files)==len(git_ls_files)
Быстрое утверждение показывает, что выходы отличаются. В чем может быть причина?
Отвечая на мой вопрос с помощью @jelmer. Причина проблемы была в строке, которую я прокомментировал. Теперь выходы совпадают.
import os
import subprocess
from tempfile import TemporaryDirectory
from dulwich import porcelain
from dulwich.repo import Repo
def _run_git_cmd(git_arguments):
return subprocess.Popen(git_arguments, stdout=subprocess.PIPE).communicate()[0]
with TemporaryDirectory() as temp_dir:
git_clone_url=r"https://github.com/dulwich/dulwich.git"
repo=porcelain.clone(git_clone_url, temp_dir)
dulwich_ls_files=[path.decode('utf-8') for path in sorted(repo.open_index())]
#git_ls_files=_run_git_cmd(['git', '-C', os.path.join(temp_dir, 'dulwich'), 'ls-files'])
git_ls_files=_run_git_cmd(['git', '-C', temp_dir, 'ls-files'])
git_ls_files=git_ls_files.decode('utf-8').splitlines()
print(len(dulwich_ls_files), len(git_ls_files))
1 ответ
Что-то вроде этого:
from dulwich.repo import Repo
r = Repo('.')
index = r.open_index()
for path in sorted(index):
print(path)