@ -20,6 +20,7 @@ from sys import stdin,stdout,stderr
import argparse
import argparse
import hashlib
import hashlib
import subprocess
import subprocess
import sys
import json , codecs
import json , codecs
try :
try :
from urllib . request import Request , urlopen
from urllib . request import Request , urlopen
@ -158,11 +159,11 @@ def main():
if repo is None :
if repo is None :
print ( " ERROR: No repository configured. Use this command to set: " , file = stderr )
print ( " ERROR: No repository configured. Use this command to set: " , file = stderr )
print ( " git config githubmerge.repository <owner>/<repo> " , file = stderr )
print ( " git config githubmerge.repository <owner>/<repo> " , file = stderr )
exit ( 1 )
sys . exit ( 1 )
if signingkey is None :
if signingkey is None :
print ( " ERROR: No GPG signing key set. Set one using: " , file = stderr )
print ( " ERROR: No GPG signing key set. Set one using: " , file = stderr )
print ( " git config --global user.signingkey <key> " , file = stderr )
print ( " git config --global user.signingkey <key> " , file = stderr )
exit ( 1 )
sys . exit ( 1 )
host_repo = host + " : " + repo # shortcut for push/pull target
host_repo = host + " : " + repo # shortcut for push/pull target
@ -173,7 +174,7 @@ def main():
# Receive pull information from github
# Receive pull information from github
info = retrieve_pr_info ( repo , pull )
info = retrieve_pr_info ( repo , pull )
if info is None :
if info is None :
exit ( 1 )
sys . exit ( 1 )
title = info [ ' title ' ] . strip ( )
title = info [ ' title ' ] . strip ( )
body = info [ ' body ' ] . strip ( )
body = info [ ' body ' ] . strip ( )
# precedence order for destination branch argument:
# precedence order for destination branch argument:
@ -194,27 +195,27 @@ def main():
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , branch ] )
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , branch ] )
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " ERROR: Cannot check out branch %s . " % ( branch ) , file = stderr )
print ( " ERROR: Cannot check out branch %s . " % ( branch ) , file = stderr )
exit ( 3 )
sys . exit ( 3 )
try :
try :
subprocess . check_call ( [ GIT , ' fetch ' , ' -q ' , host_repo , ' +refs/pull/ ' + pull + ' /*:refs/heads/pull/ ' + pull + ' /* ' ] )
subprocess . check_call ( [ GIT , ' fetch ' , ' -q ' , host_repo , ' +refs/pull/ ' + pull + ' /*:refs/heads/pull/ ' + pull + ' /* ' ] )
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " ERROR: Cannot find pull request # %s on %s . " % ( pull , host_repo ) , file = stderr )
print ( " ERROR: Cannot find pull request # %s on %s . " % ( pull , host_repo ) , file = stderr )
exit ( 3 )
sys . exit ( 3 )
try :
try :
subprocess . check_call ( [ GIT , ' log ' , ' -q ' , ' -1 ' , ' refs/heads/ ' + head_branch ] , stdout = devnull , stderr = stdout )
subprocess . check_call ( [ GIT , ' log ' , ' -q ' , ' -1 ' , ' refs/heads/ ' + head_branch ] , stdout = devnull , stderr = stdout )
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " ERROR: Cannot find head of pull request # %s on %s . " % ( pull , host_repo ) , file = stderr )
print ( " ERROR: Cannot find head of pull request # %s on %s . " % ( pull , host_repo ) , file = stderr )
exit ( 3 )
sys . exit ( 3 )
try :
try :
subprocess . check_call ( [ GIT , ' log ' , ' -q ' , ' -1 ' , ' refs/heads/ ' + merge_branch ] , stdout = devnull , stderr = stdout )
subprocess . check_call ( [ GIT , ' log ' , ' -q ' , ' -1 ' , ' refs/heads/ ' + merge_branch ] , stdout = devnull , stderr = stdout )
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " ERROR: Cannot find merge of pull request # %s on %s . " % ( pull , host_repo ) , file = stderr )
print ( " ERROR: Cannot find merge of pull request # %s on %s . " % ( pull , host_repo ) , file = stderr )
exit ( 3 )
sys . exit ( 3 )
try :
try :
subprocess . check_call ( [ GIT , ' fetch ' , ' -q ' , host_repo , ' +refs/heads/ ' + branch + ' :refs/heads/ ' + base_branch ] )
subprocess . check_call ( [ GIT , ' fetch ' , ' -q ' , host_repo , ' +refs/heads/ ' + branch + ' :refs/heads/ ' + base_branch ] )
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " ERROR: Cannot find branch %s on %s . " % ( branch , host_repo ) , file = stderr )
print ( " ERROR: Cannot find branch %s on %s . " % ( branch , host_repo ) , file = stderr )
exit ( 3 )
sys . exit ( 3 )
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , base_branch ] )
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , base_branch ] )
subprocess . call ( [ GIT , ' branch ' , ' -q ' , ' -D ' , local_merge_branch ] , stderr = devnull )
subprocess . call ( [ GIT , ' branch ' , ' -q ' , ' -D ' , local_merge_branch ] , stderr = devnull )
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , ' -b ' , local_merge_branch ] )
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , ' -b ' , local_merge_branch ] )
@ -236,30 +237,30 @@ def main():
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " ERROR: Cannot be merged cleanly. " , file = stderr )
print ( " ERROR: Cannot be merged cleanly. " , file = stderr )
subprocess . check_call ( [ GIT , ' merge ' , ' --abort ' ] )
subprocess . check_call ( [ GIT , ' merge ' , ' --abort ' ] )
exit ( 4 )
sys . exit ( 4 )
logmsg = subprocess . check_output ( [ GIT , ' log ' , ' --pretty=format: %s ' , ' -n ' , ' 1 ' ] ) . decode ( ' utf-8 ' )
logmsg = subprocess . check_output ( [ GIT , ' log ' , ' --pretty=format: %s ' , ' -n ' , ' 1 ' ] ) . decode ( ' utf-8 ' )
if logmsg . rstrip ( ) != firstline . rstrip ( ) :
if logmsg . rstrip ( ) != firstline . rstrip ( ) :
print ( " ERROR: Creating merge failed (already merged?). " , file = stderr )
print ( " ERROR: Creating merge failed (already merged?). " , file = stderr )
exit ( 4 )
sys . exit ( 4 )
symlink_files = get_symlink_files ( )
symlink_files = get_symlink_files ( )
for f in symlink_files :
for f in symlink_files :
print ( " ERROR: File %s was a symlink " % f )
print ( " ERROR: File %s was a symlink " % f )
if len ( symlink_files ) > 0 :
if len ( symlink_files ) > 0 :
exit ( 4 )
sys . exit ( 4 )
# Put tree SHA512 into the message
# Put tree SHA512 into the message
try :
try :
first_sha512 = tree_sha512sum ( )
first_sha512 = tree_sha512sum ( )
message + = ' \n \n Tree-SHA512: ' + first_sha512
message + = ' \n \n Tree-SHA512: ' + first_sha512
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
printf ( " ERROR: Unable to compute tree hash " )
print ( " ERROR: Unable to compute tree hash " )
exit ( 4 )
sys . exit ( 4 )
try :
try :
subprocess . check_call ( [ GIT , ' commit ' , ' --amend ' , ' -m ' , message . encode ( ' utf-8 ' ) ] )
subprocess . check_call ( [ GIT , ' commit ' , ' --amend ' , ' -m ' , message . encode ( ' utf-8 ' ) ] )
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
printf ( " ERROR: Cannot update message. " , file = stderr )
print ( " ERROR: Cannot update message. " , file = stderr )
exit ( 4 )
sys . exit ( 4 )
print_merge_details ( pull , title , branch , base_branch , head_branch )
print_merge_details ( pull , title , branch , base_branch , head_branch )
print ( )
print ( )
@ -268,7 +269,7 @@ def main():
if testcmd :
if testcmd :
if subprocess . call ( testcmd , shell = True ) :
if subprocess . call ( testcmd , shell = True ) :
print ( " ERROR: Running %s failed. " % testcmd , file = stderr )
print ( " ERROR: Running %s failed. " % testcmd , file = stderr )
exit ( 5 )
sys . exit ( 5 )
# Show the created merge.
# Show the created merge.
diff = subprocess . check_output ( [ GIT , ' diff ' , merge_branch + ' .. ' + local_merge_branch ] )
diff = subprocess . check_output ( [ GIT , ' diff ' , merge_branch + ' .. ' + local_merge_branch ] )
@ -279,7 +280,7 @@ def main():
if reply . lower ( ) == ' ignore ' :
if reply . lower ( ) == ' ignore ' :
print ( " Difference with github ignored. " , file = stderr )
print ( " Difference with github ignored. " , file = stderr )
else :
else :
exit ( 6 )
sys . exit ( 6 )
else :
else :
# Verify the result manually.
# Verify the result manually.
print ( " Dropping you on a shell so you can try building/testing the merged source. " , file = stderr )
print ( " Dropping you on a shell so you can try building/testing the merged source. " , file = stderr )
@ -292,7 +293,7 @@ def main():
second_sha512 = tree_sha512sum ( )
second_sha512 = tree_sha512sum ( )
if first_sha512 != second_sha512 :
if first_sha512 != second_sha512 :
print ( " ERROR: Tree hash changed unexpectedly " , file = stderr )
print ( " ERROR: Tree hash changed unexpectedly " , file = stderr )
exit ( 8 )
sys . exit ( 8 )
# Sign the merge commit.
# Sign the merge commit.
print_merge_details ( pull , title , branch , base_branch , head_branch )
print_merge_details ( pull , title , branch , base_branch , head_branch )
@ -306,7 +307,7 @@ def main():
print ( " Error while signing, asking again. " , file = stderr )
print ( " Error while signing, asking again. " , file = stderr )
elif reply == ' x ' :
elif reply == ' x ' :
print ( " Not signing off on merge, exiting. " , file = stderr )
print ( " Not signing off on merge, exiting. " , file = stderr )
exit ( 1 )
sys . exit ( 1 )
# Put the result in branch.
# Put the result in branch.
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , branch ] )
subprocess . check_call ( [ GIT , ' checkout ' , ' -q ' , branch ] )
@ -326,7 +327,7 @@ def main():
subprocess . check_call ( [ GIT , ' push ' , host_repo , ' refs/heads/ ' + branch ] )
subprocess . check_call ( [ GIT , ' push ' , host_repo , ' refs/heads/ ' + branch ] )
break
break
elif reply == ' x ' :
elif reply == ' x ' :
exit ( 1 )
sys . exit ( 1 )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :
main ( )
main ( )