A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://stackoverflow.com/questions/20061898/gitpython-and-git-diff below:

python - gitpython and git diff

Asked 11 years, 9 months ago

Viewed 61k times

I am looking to get only the diff of a file changed from a git repo. Right now, I am using gitpython to actually get the commit objects and the files of git changes, but I want to do a dependency analysis on only the parts of the file changed. Is there any way to get the git diff from git python? Or am I going to have to compare each of the files by reading line by line?

Ryan M

20.5k3535 gold badges7474 silver badges8585 bronze badges

asked Nov 19, 2013 at 2:19

user1816561user1816561

34922 gold badges44 silver badges44 bronze badges

If you want to access the contents of the diff, try this:

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'))) 

This will print the contents of each file.

Aaron Brock

4,57622 gold badges2828 silver badges4646 bronze badges

answered Sep 1, 2017 at 21:14

D. A.D. A.

3,53944 gold badges3535 silver badges3434 bronze badges

3

You can use GitPython with the git command "diff", just need to use the "tree" object of each commit or the branch for that you want to see the diffs, for example:

repo = Repo('/git/repository')
t = repo.head.commit.tree
repo.git.diff(t)

This will print "all" the diffs for all files included in this commit, so if you want each one you must iterate over them.

With the actual branch it's:

repo.git.diff('HEAD~1')

Hope this help, regards.

answered Apr 27, 2014 at 6:15

CairoCairo

6161010 silver badges2121 bronze badges

1

If you're looking to recreate something close to what a standard git diff would show, try:

# cloned_repo = git.Repo.clone_from(
#     url=ssh_url,
#     to_path=repo_dir,
#     env={"GIT_SSH_COMMAND": "ssh -i " + SSH_KEY},
# ) 
for diff_item in cloned_repo.index.diff(None, create_patch=True):
    repo_diff += (
        f"--- a/{diff_item.a_blob.name}\n+++ b/{diff_item.b_blob.name}\n"
        f"{diff_item.diff.decode('utf-8')}\n\n"
        )
Adriaan

18.2k77 gold badges4747 silver badges8787 bronze badges

answered Oct 1, 2021 at 21:50

ZaxRZaxR

5,19544 gold badges2929 silver badges4646 bronze badges

0

Git does not store the diffs, as you have noticed. Given two blobs (before and after a change), you can use Python's difflib module to compare the data.

answered Nov 19, 2013 at 4:36

Greg HewgillGreg Hewgill

1.0m192192 gold badges1.2k1.2k silver badges1.3k1.3k bronze badges

4
repo.git.diff("main", "head~5")

result:

@@ -97,6 +97,25 @@ + </configuration> + + </plugin> + <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>findbugs-maven-plugin</artifactId> - <version>3.0.5</version> - <configuration> - <effort>Low</effort> - <threshold>Medium</threshold> 
Rimian

38.6k1717 gold badges126126 silver badges119119 bronze badges

answered May 24, 2022 at 6:40

土豆先生土豆先生

1111 bronze badge

3

If you want to do git diff on a file between two commits this is the way to do it:

import git
   
repo = git.Repo()
path_to_a_file = "diff_this_file_across_commits.txt"
   
commits_touching_path = list(repo.iter_commits(paths=path_to_a_file))
   
print repo.git.diff(commits_touching_path[0], commits_touching_path[1], path_to_a_file)

This will show you the differences between two latest commits that were done to the file you specify.

Rimian

38.6k1717 gold badges126126 silver badges119119 bronze badges

answered Sep 13, 2016 at 5:42

Nikola ĐuzaNikola Đuza

53577 silver badges1111 bronze badges

My task was compared to two files in different places. Here is a working option.

unidiff dependence that needs to be set as an additional module.

pip install unidiff

import difflib
from unidiff import PatchedFile, PatchSet

def create_diff(file1, file2):
    with open(file1, 'r',encoding='utf-8') as f1:
        lines1 = f1.readlines()
    with open(file2, 'r',encoding='utf-8') as f2:
        lines2 = f2.readlines()

    diff = difflib.unified_diff(lines1, lines2, fromfile=file1, tofile=file2)
    diff_string = ''.join(diff)  
    # patch = PatchedFile.from_string(diff_string)
    patch = PatchSet.from_string(diff_string)
    return str(patch)

if __name__ == "__main__":
    file1 = r"path/to/file1.txt"
    file2 = r"path/to/file2.txt"
    print(create_diff(file1, file2))
    

result

--- c:\REPO\path\to\file1.txt
+++ c:\REPO\path\to\file2.tx
@@ -6021,28 +6021,6 @@
         k3.setucs(k3.k_delete, cursnm)
         if exp_p.result_hh:
             k3.visible(exp_p.parent)
-
-    #-------------------------------------------------------------------------------
-    # cursnm = get_random_name(pref="u")

Here is how you do it

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)
Adriaan

18.2k77 gold badges4747 silver badges8787 bronze badges

answered Mar 7, 2014 at 9:12

Ciasto piekarzCiasto piekarz

8,3372020 gold badges125125 silver badges226226 bronze badges

1

PyDriller +1

pip install pydriller

But with the new API:

Breaking API: ```
from pydriller import Repository

for commit in Repository('https://github.com/ishepard/pydriller').traverse_commits():
    print(commit.hash)
    print(commit.msg)
    print(commit.author.name)

    for file in commit.modified_files:
        print(file.filename, ' has changed')

answered Jun 15, 2022 at 23:15

K. SymbolK. Symbol

3,72622 gold badges2323 silver badges2222 bronze badges

1

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4