GitPython check if git pull changed local files
Asked Answered
C

2

6

Using GitPython and I want to call a function only if there is a change to local files after a pull. For example if I make a push on a separate computer. Then pull on the first computer it works as expected but does not provide any output. An ideal output is a list of files changed. Or alternatively just something that told me if the pull had an error, nothing pulled because the branch was up to date or a boolean that changes had happened. I believe I could scrape repo.git.status() but it seems crude. Looking around it looks like I could also compare branches for changes but it seems like a lot of extra code and remote calls. Is there a correct way using just the pull call?

while True:
    repo = git.Repo()
    o = repo.remotes.origin
    o.pull()
    changed = NOT_SURE
    if changed:
        do_something()
    print(repo.git.status())
    time.sleep(POLLING_RATE)

Update: This does work for checking if changes were made but does not give the files changes without extra remote calls

while True:
    print(str(time.ctime())+": Checking for updates")
    repo = git.Repo()
    current_hash = repo.head.object.hexsha
    o = repo.remotes.origin
    o.pull()
    pull_hash = repo.head.object.hexsha
    if current_hash != pull_hash:
        print("files have changed")
    else:
        print("no changes")

    time.sleep(config.GIT_POLL_RATE)
Chloramine answered 31/5, 2018 at 22:6 Comment(2)
To determine the difference between the newest commit (after pulling) and an earlier commit you would use git diff. I can't tell you how to do that in GitPython, however.Beadroll
Comparing hashes tells you whether you received new commits by pulling. It is possible, however, that there are no differences in the files between the two commits.Beadroll
C
5

I appreciate that this is two years late, however, I hope it may still be of some use.

I have just written pullcheck, a simple script to pull from a repo, check for changes then restart a target if changes are found. I found that this method was able to identify changes from the pull.

def git_pull_change(path):
    repo = git.Repo(path)
    current = repo.head.commit

    repo.remotes.origin.pull()

    if current == repo.head.commit:
        print("Repo not changed. Sleep mode activated.")
        return False
    else:
        print("Repo changed! Activated.")
        return True
Claudell answered 21/7, 2020 at 15:39 Comment(0)
C
0

You could use git-fetch as well if you want just check what kind of changes were on the remote side.

And if you want to print changes, you probably should explore git-diff, e.g.:


POLLING_RATE = 10
REM_BRANCH = 'master'

def pretty_diff(diff):
    for cht in diff.change_type:
        changes = list(diff.iter_change_type(cht))
        if len(changes) == 0:
            continue
        print("Changes type:", cht)
        for d in changes:
            print(d.b_path)


while True:
    repo = git.Repo('.')
    current_hash = repo.head.object.hexsha
    o = repo.remotes.origin
    o.fetch()
    changed = o.refs[REM_BRANCH].object.hexsha != current_hash
    if changed:
        # do_something()
        diff = repo.head.commit.diff(o.refs[REM_BRANCH].object.hexsha)
        pretty_diff(diff)
    time.sleep(POLLING_RATE)

git-diff supports different change types:

print(diff.change_type)
#('A', 'C', 'D', 'R', 'M', 'T')

You may do different things for the different change types.

Chatelaine answered 6/12, 2020 at 20:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.