Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Display diff between two commits.
#!/usr/bin/env python
import sys, subprocess, os
TOOLS = ['bcompare', 'meld']
HEAD = 'HEAD'
TMP = '/tmp/'
execute = lambda command: subprocess.check_output(command)
which = lambda tool: execute(['which', tool]).strip()
def getTool():
for tool in TOOLS:
try:
out = which(tool)
if tool in out:
return tool
except subprocess.CalledProcessError:
pass
return None
def printUsageAndExit():
print 'Usage: python bdiff.py <project> <commit_one> <commit_two>'
print 'Example: python bdiff.py <project> 0 1'
print 'Example: python bdiff.py <project> fhejk7fe d78ewg9we'
print 'Example: python bdiff.py <project> 0 d78ewg9we'
print 'Example: python bdiff.py <project> HEAD d78ewg9we'
print 'Example: python bdiff.py <project> HEAD-4 87'
sys.exit(0)
def revParse(name, position):
if '-' in position:
position.replace('-', '~')
command = ['git', '-C', name, 'rev-parse', position]
return execute(command).strip()
def getCommitId(name, position):
index = -1;
command = ['git', '-C', name, 'log', '--pretty=format:"%h"', '--abbrev=7']
reverse = ['--reverse']
if position == HEAD:
return revParse(name, position)
elif HEAD in position and ('-' in position or '~' in position):
try:
return revParse(name, position)
except ValueError:
print "Error in parsing commit ids!"
sys.exit(0)
elif HEAD in position:
print "Error in parsing commit ids!"
sys.exit(-1)
elif '-' in position:
commitid = position.split()[0][:7]
index = execute(command).splitlines().index(commitid)
try:
index -= int(position.split()[1])
catch ValueError:
print "Unable to paser the input!"
sys.exit(-1)
elif position.isdigit():
command.extend(reverse)
index = int(position)
else:
return position
if index >= 0:
logs = execute(command).splitlines()
return logs[index].strip()
else: return None
dir_name = lambda commit: (commit if commit else '0')
tmp = lambda name: (TMP + dir_name(name))
def validate(name, commit):
if not commit:
print "Nothing to do, exit!"
return False
try:
if commit:
execute(['git', '-C', name, 'cat-file', '-t', commit])
except subprocess.CalledProcessError:
return False
return True
cleanup = lambda commit: execute(['rm', '-rf', tmp(commit)])
def checkoutCommit(name, commit):
if commit:
execute(['git', 'clone', name, tmp(commit)])
execute(['git', '-C', tmp(commit), 'checkout', commit])
else:
execute(['mkdir', tmp('0')])
def compare(tool, commit1, commit2):
execute([tool, tmp(commit1), tmp(commit2)])
def parseOpt():
if len(sys.argv) is 2:
return os.getcwd(), sys.argv[1]+'-1', sys.argv[1]
elif len(sys.argv) is 3:
return os.getcwd(), sys.argv[1], sys.argv[2]
elif len(sys.argv) is 4:
return sys.argv[1], sys.argv[2], sys.argv[3]
else: printUsageAndExit()
if __name__ == '__main__':
tool = getTool()
if not tool:
print "No GUI diff tools, install bcompare or meld"
sys.exit(0)
name, first, second = parseOpt()
commit1, commit2 = getCommitId(name, first), getCommitId(name, second)
if validate(name, commit1) and validate(name, commit2) is False:
sys.exit(0)
cleanup(commit1), cleanup(commit2)
try:
checkoutCommit(name, commit1), checkoutCommit(name, commit2)
compare(tool, commit1, commit2)
except KeyboardInterrupt:
pass
finally:
cleanup(commit1), cleanup(commit2)
sys.exit(0)
@saiftheboss7

This comment has been minimized.

Copy link

commented Nov 1, 2018

How to use it??

@Somayeh12

This comment has been minimized.

Copy link

commented Jul 17, 2019

These are two commits for gson project:
'0eab91a57fee3c86b5f7b904bb8211ecf843b450'
'9e9ebf095e2b9d4ba4d3955f4fa59128bb2420c0'
Considering the project is cloned in 'D:\projects\gson'
How do you use this code to find the files that have been modified between these tow commits?
Can you please provide an example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.