Я хочу получить только разницу файла, измененного из репозитория git. Прямо сейчас я использую gitpython для фактического получения объектов фиксации и файлов изменений git, но я хочу провести анализ зависимостей только для измененных частей файла. Есть ли способ получить git diff от git python? Или мне придется сравнивать каждый из файлов, читая строку за строкой?
gitpython и git diff
Ответы (6)
Вы можете использовать GitPython с командой git «diff», просто нужно использовать объект «дерево» каждой фиксации или ветки, для которой вы хотите увидеть различия, например:
repo = Repo('/git/repository')
t = repo.head.commit.tree
repo.git.diff(t)
Это напечатает «все» различия для всех файлов, включенных в эту фиксацию, поэтому, если вы хотите каждый из них, вы должны перебирать их.
С фактической веткой это:
repo.git.diff('HEAD~1')
Надеюсь, что это поможет, с уважением.
diff
между tree
и head~1
. У них есть сходство, но у последнего больше различий. Кажется, что последний включает разницу с последним коммитом.
- person Timo; 17.07.2021
Если вы хотите получить доступ к содержимому diff, попробуйте следующее:
repo = git.Repo(repo_root.as_posix())
commit_dev = repo.commit("dev")
commit_origin_dev = repo.commit("origin/dev")
diff_index = commit_origin_dev.diff(commit_dev)
for diff_item in diff_index.iter_change_type('M'):
print("A blob:\n{}".format(diff_item.a_blob.data_stream.read().decode('utf-8')))
print("B blob:\n{}".format(diff_item.b_blob.data_stream.read().decode('utf-8')))
Это распечатает содержимое каждого файла.
Как вы заметили, Git не хранит различия. Имея два больших двоичных объекта (до и после изменения), вы можете использовать модуль Python difflib
. для сравнения данных.
repo.head.commit.diff(None)
- person Addison Klinke; 25.02.2021
Вместо этого я предлагаю вам использовать PyDriller (внутренне использует GitPython) . Гораздо проще в использовании:
for commit in RepositoryMining("path_to_repo").traverse_commits():
for modified_file in commit.modifications: # here you have the list of modified files
print(modified_file.diff)
# etc...
Вы также можете проанализировать один коммит, выполнив:
for commit in RepositoryMining("path_to_repo", single="123213")
Если вы хотите выполнить git diff для файла между двумя фиксациями, это можно сделать следующим образом:
import git
repo = git.Repo()
path_to_a_file = "diff_this_file_across_commits.txt"
commits_touching_path = list(repo.iter_commits(paths=path))
print repo.git.diff(commits_touching_path[0], commits_touching_path[1], path_to_a_file)
Это покажет вам различия между двумя последними коммитами, которые были сделаны для указанного вами файла.
Надеюсь, это помогло.
Я не уверен, что вы получили то, что искали!
Вот как вы это делаете
import git
repo = git.Repo("path/of/repo/")
# the below gives us all commits
repo.commits()
# take the first and last commit
a_commit = repo.commits()[0]
b_commit = repo.commits()[1]
# now get the diff
repo.diff(a_commit,b_commit)
Ваше здоровье.
AttributeError: 'Repo' object has no attribute 'diff'
и AttributeError: 'Repo' object has no attribute 'commits'
- person firelynx; 16.08.2018