Created
October 4, 2017 17:02
-
-
Save oconnor663/8ef94b337a1614e40969f7a3ff2bffba to your computer and use it in GitHub Desktop.
edit a git commit without changing the hash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
d="$(mktemp -d)" | |
# Make a git repo with one file in it. | |
mkdir "$d/good" | |
cd "$d/good" | |
git init | |
echo good > file.txt | |
git add -A | |
git commit -m "first commit" | |
# Copy the whole thing. | |
cp -r "$d/good" "$d/bad" | |
# Go in the copy and edit the object that holds file.txt. Its path is always | |
# the same because, unlike the commit object, it doesn't contain any | |
# timestamps. | |
# NOTE: The blob object contains its own length, so if we wanted to substitute | |
# something other than another 4 bytes in there, we'd need to edit the length | |
# too. | |
file_hash_path=".git/objects/12/799ccbe7ce445b11b7bd4833bcc2c2ce1b48b7" | |
chmod +w "$d/bad/$file_hash_path" | |
cat "$d/good/$file_hash_path" \ | |
| python2 -c "import zlib, sys; sys.stdout.write(zlib.decompress(sys.stdin.read()))" \ | |
| sed 's/good/💩/' \ | |
| python2 -c "import zlib, sys; sys.stdout.write(zlib.compress(sys.stdin.read()))" \ | |
> "$d/bad/$file_hash_path" | |
echo "Here's a commit from the good repo:" | |
echo | |
git -C "$d/good" show -p | |
echo | |
echo "And here's "the same commit" from the bad repo:" | |
echo | |
git -C "$d/bad" show -p |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't think you'll be able to get away with that. Git is willing to interact with bad commit objects locally, but usually once you try to transfer them over the network protocol (i.e. push them to GitHub), they get rejected. (If they didn't, that would be a fairly massive oversight by the GitHub security team.)