@ -1,5 +1,5 @@
#!/usr/bin/env python3
#!/usr/bin/env python3
# Copyright (c) 2016 The Bitcoin Core d evelopers
# Copyright (c) 2016-2017 Bitcoin Core D evelopers
# Distributed under the MIT software license, see the accompanying
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -15,7 +15,7 @@
# In case of a clean merge that is accepted by the user, the local branch with
# In case of a clean merge that is accepted by the user, the local branch with
# name $BRANCH is overwritten with the merged result, and optionally pushed.
# name $BRANCH is overwritten with the merged result, and optionally pushed.
from __future__ import division , print_function , unicode_literals
from __future__ import division , print_function , unicode_literals
import os
import os , sys
from sys import stdin , stdout , stderr
from sys import stdin , stdout , stderr
import argparse
import argparse
import hashlib
import hashlib
@ -127,6 +127,9 @@ def tree_sha512sum(commit='HEAD'):
raise IOError ( ' Non-zero return value executing git cat-file ' )
raise IOError ( ' Non-zero return value executing git cat-file ' )
return overall . hexdigest ( )
return overall . hexdigest ( )
def print_merge_details ( pull , title , branch , base_branch , head_branch ) :
print ( ' %s # %s %s %s %s into %s %s ' % ( ATTR_RESET + ATTR_PR , pull , ATTR_RESET , title , ATTR_RESET + ATTR_PR , branch , ATTR_RESET ) )
subprocess . check_call ( [ GIT , ' log ' , ' --graph ' , ' --topo-order ' , ' --pretty=format: ' + COMMIT_FORMAT , base_branch + ' .. ' + head_branch ] )
def parse_arguments ( ) :
def parse_arguments ( ) :
epilog = '''
epilog = '''
@ -171,7 +174,7 @@ def main():
info = retrieve_pr_info ( repo , pull )
info = retrieve_pr_info ( repo , pull )
if info is None :
if info is None :
exit ( 1 )
exit ( 1 )
title = info [ ' title ' ]
title = info [ ' title ' ] . strip ( )
# precedence order for destination branch argument:
# precedence order for destination branch argument:
# - command line argument
# - command line argument
# - githubmerge.branch setting
# - githubmerge.branch setting
@ -256,8 +259,7 @@ def main():
printf ( " ERROR: Cannot update message. " , file = stderr )
printf ( " ERROR: Cannot update message. " , file = stderr )
exit ( 4 )
exit ( 4 )
print ( ' %s # %s %s %s %s into %s %s ' % ( ATTR_RESET + ATTR_PR , pull , ATTR_RESET , title , ATTR_RESET + ATTR_PR , branch , ATTR_RESET ) )
print_merge_details ( pull , title , branch , base_branch , head_branch )
subprocess . check_call ( [ GIT , ' log ' , ' --graph ' , ' --topo-order ' , ' --pretty=format: ' + COMMIT_FORMAT , base_branch + ' .. ' + head_branch ] )
print ( )
print ( )
# Run test command if configured.
# Run test command if configured.
@ -276,12 +278,6 @@ def main():
print ( " Difference with github ignored. " , file = stderr )
print ( " Difference with github ignored. " , file = stderr )
else :
else :
exit ( 6 )
exit ( 6 )
reply = ask_prompt ( " Press ' d ' to accept the diff. " )
if reply . lower ( ) == ' d ' :
print ( " Diff accepted. " , file = stderr )
else :
print ( " ERROR: Diff rejected. " , file = stderr )
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 )
@ -290,12 +286,6 @@ def main():
if os . path . isfile ( ' /etc/debian_version ' ) : # Show pull number on Debian default prompt
if os . path . isfile ( ' /etc/debian_version ' ) : # Show pull number on Debian default prompt
os . putenv ( ' debian_chroot ' , pull )
os . putenv ( ' debian_chroot ' , pull )
subprocess . call ( [ BASH , ' -i ' ] )
subprocess . call ( [ BASH , ' -i ' ] )
reply = ask_prompt ( " Type ' m ' to accept the merge. " )
if reply . lower ( ) == ' m ' :
print ( " Merge accepted. " , file = stderr )
else :
print ( " ERROR: Merge rejected. " , file = stderr )
exit ( 7 )
second_sha512 = tree_sha512sum ( )
second_sha512 = tree_sha512sum ( )
if first_sha512 != second_sha512 :
if first_sha512 != second_sha512 :
@ -303,14 +293,17 @@ def main():
exit ( 8 )
exit ( 8 )
# Sign the merge commit.
# Sign the merge commit.
reply = ask_prompt ( " Type ' s ' to sign off on the merge. " )
print_merge_details ( pull , title , branch , base_branch , head_branch )
while True :
reply = ask_prompt ( " Type ' s ' to sign off on the above merge, or ' x ' to reject and exit. " ) . lower ( )
if reply == ' s ' :
if reply == ' s ' :
try :
try :
subprocess . check_call ( [ GIT , ' commit ' , ' -q ' , ' --gpg-sign ' , ' --amend ' , ' --no-edit ' ] )
subprocess . check_call ( [ GIT , ' commit ' , ' -q ' , ' --gpg-sign ' , ' --amend ' , ' --no-edit ' ] )
break
except subprocess . CalledProcessError as e :
except subprocess . CalledProcessError as e :
print ( " Error signing, exiting. " , file = stderr )
print ( " Error signing, exiting. " , file = stderr )
exit ( 1 )
exit ( 1 )
els e :
elif r eply == ' x ' :
print ( " Not signing off on merge, exiting. " , file = stderr )
print ( " Not signing off on merge, exiting. " , file = stderr )
exit ( 1 )
exit ( 1 )
@ -326,9 +319,13 @@ def main():
subprocess . call ( [ GIT , ' branch ' , ' -q ' , ' -D ' , local_merge_branch ] , stderr = devnull )
subprocess . call ( [ GIT , ' branch ' , ' -q ' , ' -D ' , local_merge_branch ] , stderr = devnull )
# Push the result.
# Push the result.
reply = ask_prompt ( " Type ' push ' to push the result to %s , branch %s . " % ( host_repo , branch ) )
while True :
if reply . lower ( ) == ' push ' :
reply = ask_prompt ( " Type ' push ' to push the result to %s , branch %s , or ' x ' to exit without pushing. " % ( host_repo , branch ) ) . lower ( )
if reply == ' push ' :
subprocess . check_call ( [ GIT , ' push ' , host_repo , ' refs/heads/ ' + branch ] )
subprocess . check_call ( [ GIT , ' push ' , host_repo , ' refs/heads/ ' + branch ] )
break
elif reply == ' x ' :
exit ( 1 )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :
main ( )
main ( )