-
-
Save oconnor663/8ef94b337a1614e40969f7a3ff2bffba to your computer and use it in GitHub Desktop.
#! /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 |
I'm not sure I understand the question. Could you say more?
@oconnor663 i'm looking for a way to change/delete the root commit of a repo without rebasing (which would change the hash of the following commits). i'm still experimenting with this script to fix the root commit of the repo i work on (the author info has some typos) ; in case i can't achieve fixing it, i was willing to delete the root commit.
The reason why i want to avoid rebasing is to avoid loosing the git(hub) history (closed/merged PR, snippets linked to hashes, etc...) of this repo but at the same time i'm just trying to fix old mistakes made 250+ commits ago...
(edit: i edited the original question for clarity, in case someone drops by later)
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.)
@oconnor663 thanks for clarification :)
@oconnor663 could this also be used to remove the root commit ?