Paul Fournel
Paul Fournel

Reputation: 11207

How to calculate SHA from a string with the Github api in python?

I want to update a file with the Github API and commit it into a branch. I have troubles creating the commit. The SHA does not match the expected one.

{
    'documentation_url': 'https://developer.github.com/enterprise/2.7/v3/repos/contents/',
    'message': 'pom.xml does not match de42fdd980f9b8067a2af982de46b8d5547e4597'
}

I do the following:

import hashlib
myfile = "new content of my README"
resulting_file = base64.b64encode(bytes(myfile, "utf-8"))
file_as_str = str(resulting_file.decode('utf-8'))
sha = hashlib.sha1(file_as_str.encode('utf-8')).hexdigest()

url = 'https://someurl.com/someproject/contents/README.md?access_token=' + access_token
data = '{"message": "bla bla", "content": "'+file_as_str+'", "sha": "'+sha+'", "branch": "'+branch+'"}'
response = requests.put(url, data=data)

I would not like to use a lib to do this to better understand what is happening. probably the SHA is not generated properly, but I cannot identify why. Could someone help?

Upvotes: 2

Views: 2829

Answers (2)

mhawke
mhawke

Reputation: 87084

You don't need to calculate the SHA for the new file. Instead you must supply the SHA of the file that is being replaced. You can obtain that by performing a get contents on the file using requests.get():

url = 'https://api.github.com/repos/someowner/someproject/contents/pom.xml'
r = requests.get(url)
sha = r.json()['sha']

Then use the value of sha in the PUT request to update the file:

with open('myfile', 'rb') as f:
    content = str(base64.b64encode(f.read()), encoding='utf8')
    data = {'message': 'bla bla', 'content': content, 'sha': sha, 'branch': branch}
    r = requests.put(url, json=data)

Upvotes: 8

RFV
RFV

Reputation: 839

GitHub calculates hashes as followes:

sha1("blob " + filesize + "\0" + data)

so use this code:

with open(filepath, 'rb') as file_for_hash:
    data = file_for_hash.read()
    filesize = len(data)
sha = hashlib.sha1("blob " + filesize + "\0" + data).hexdigest()

Upvotes: 2

Related Questions