Skip to content

Commit be8ba2c

Browse files
committed
Merge #9871: Add a tree sha512 hash to merge commits
fa89670 Add SHA512 tree hash to merge commits (Pieter Wuille) Tree-SHA512: 72321597336d3c4957719c8b907f258814b01499a82d2bc1e8c678b8825461d95f23b42ff6868a25725f4bfc3da24f7b12c058b45cbc7a7dfbf668888b68274e
2 parents 11049f4 + fa89670 commit be8ba2c

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

contrib/devtools/github-merge.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import os
1919
from sys import stdin,stdout,stderr
2020
import argparse
21+
import hashlib
2122
import subprocess
2223
import json,codecs
2324
try:
@@ -69,6 +70,27 @@ def ask_prompt(text):
6970
print("",file=stderr)
7071
return reply
7172

73+
def tree_sha512sum():
74+
files = sorted(subprocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', '--name-only', 'HEAD']).splitlines())
75+
overall = hashlib.sha512()
76+
for f in files:
77+
intern = hashlib.sha512()
78+
fi = open(f, 'rb')
79+
while True:
80+
piece = fi.read(65536)
81+
if piece:
82+
intern.update(piece)
83+
else:
84+
break
85+
fi.close()
86+
dig = intern.hexdigest()
87+
overall.update(dig.encode("utf-8"))
88+
overall.update(" ".encode("utf-8"))
89+
overall.update(f)
90+
overall.update("\n".encode("utf-8"))
91+
return overall.hexdigest()
92+
93+
7294
def parse_arguments():
7395
epilog = '''
7496
In addition, you can set the following git configuration variables:
@@ -157,6 +179,9 @@ def main():
157179
subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch])
158180

159181
try:
182+
# Go up to the repository's root.
183+
toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip()
184+
os.chdir(toplevel)
160185
# Create unsigned merge commit.
161186
if title:
162187
firstline = 'Merge #%s: %s' % (pull,title)
@@ -175,14 +200,29 @@ def main():
175200
print("ERROR: Creating merge failed (already merged?).",file=stderr)
176201
exit(4)
177202

203+
# Put tree SHA512 into the message
204+
try:
205+
first_sha512 = tree_sha512sum()
206+
message += '\n\nTree-SHA512: ' + first_sha512
207+
except subprocess.CalledProcessError as e:
208+
printf("ERROR: Unable to compute tree hash")
209+
exit(4)
210+
try:
211+
subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')])
212+
except subprocess.CalledProcessError as e:
213+
printf("ERROR: Cannot update message.",file=stderr)
214+
exit(4)
215+
second_sha512 = tree_sha512sum()
216+
if first_sha512 != second_sha512:
217+
print("ERROR: Tree hash changed unexpectedly",file=stderr)
218+
exit(4)
219+
178220
print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET))
179221
subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch])
180222
print()
223+
181224
# Run test command if configured.
182225
if testcmd:
183-
# Go up to the repository's root.
184-
toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip()
185-
os.chdir(toplevel)
186226
if subprocess.call(testcmd,shell=True):
187227
print("ERROR: Running %s failed." % testcmd,file=stderr)
188228
exit(5)

0 commit comments

Comments
 (0)