Created
April 28, 2026 21:29
-
-
Save leewc/985ebf3faaf52622262c961b55dbe144 to your computer and use it in GitHub Desktop.
Convert git repo from SHA256 to SHA1 object formats (and vice versa)
This file contains hidden or 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
| #!/usr/bin/env bash | |
| # Toggle a git repo between SHA-1 and SHA-256 object formats. | |
| # Usage: git-convert-hash.sh [repo-path] | |
| set -euo pipefail | |
| REPO="${1:-.}" | |
| cd "$REPO" | |
| if [[ ! -d .git ]]; then | |
| echo "Error: $PWD is not a git repository" | |
| exit 1 | |
| fi | |
| CURRENT=$(git rev-parse --show-object-format) | |
| if [[ "$CURRENT" == "sha256" ]]; then TARGET="sha1"; else TARGET="sha256"; fi | |
| BRANCH=$(git branch --show-current) | |
| REMOTE_URL=$(git remote get-url origin 2>/dev/null || true) | |
| EXPORT_FILE=$(mktemp /tmp/git-export-XXXXXX.fi) | |
| BACKUP_DIR="${REPO}/.git.backup-$(date +%Y%m%d%H%M%S)" | |
| echo "Converting $PWD from $CURRENT -> $TARGET" | |
| echo "Branch: $BRANCH" | |
| echo "Remote: ${REMOTE_URL:-none}" | |
| echo "Backup: $BACKUP_DIR" | |
| echo "" | |
| # Backup | |
| cp -r "$REPO/.git" "$BACKUP_DIR" | |
| echo "✓ Backed up .git to $BACKUP_DIR" | |
| # Export | |
| git fast-export --all --signed-tags=strip > "$EXPORT_FILE" | |
| echo "✓ Exported history to $EXPORT_FILE" | |
| # Reinit | |
| rm -rf .git | |
| git init --object-format="$TARGET" -b "$BRANCH" | |
| echo "✓ Reinitialized as $TARGET" | |
| # Import | |
| git fast-import < "$EXPORT_FILE" | |
| echo "✓ Imported history" | |
| # Restore working tree | |
| git checkout -f "$BRANCH" | |
| echo "✓ Checked out $BRANCH" | |
| # Restore remote | |
| if [[ -n "$REMOTE_URL" ]]; then | |
| git remote add origin "$REMOTE_URL" | |
| echo "✓ Restored remote origin -> $REMOTE_URL" | |
| fi | |
| # Cleanup | |
| rm -f "$EXPORT_FILE" | |
| echo "" | |
| echo "Done! Verify with:" | |
| echo " git log --oneline" | |
| echo " git status" | |
| echo "" | |
| echo "=== SYNCING WITH REMOTE ===" | |
| echo "" | |
| echo "Since all commit hashes changed, you have two options:" | |
| echo "" | |
| echo "Option 1: Force push from this local copy (if you have push access):" | |
| echo " git push --force --all" | |
| echo " git push --force --tags" | |
| echo "" | |
| echo "Option 2: If the remote was ALSO converted separately (e.g. GitLab" | |
| echo " converted the repo), the remote has new hashes too. In that case," | |
| echo " follow these steps:" | |
| echo "" | |
| echo " # 1. Fetch the new remote history (don't pull!)" | |
| echo " git fetch origin" | |
| echo "" | |
| echo " # 2. Set upstream tracking" | |
| echo " git branch --set-upstream-to=origin/$BRANCH $BRANCH" | |
| echo "" | |
| echo " # 3. Rebase your local commits onto the new remote history" | |
| echo " git rebase --onto origin/$BRANCH --root" | |
| echo "" | |
| echo " # 4. Resolve any conflicts (prefer your version for files you own)" | |
| echo " # git checkout --theirs <file> # take your version" | |
| echo " # git add <file>" | |
| echo " # git rebase --continue" | |
| echo "" | |
| echo " # 5. Push" | |
| echo " git push" | |
| echo "" | |
| echo " ⚠️ Do NOT use 'git pull' or 'git pull -Xours/-Xtheirs'!" | |
| echo " The histories have no common ancestor, so a merge/pull will" | |
| echo " silently discard your commit history. If you already did this," | |
| echo " your commits are still in the reflog:" | |
| echo "" | |
| echo " git reflog # find your old HEAD" | |
| echo " git cherry-pick <oldest>..<newest> # replay them on top" | |
| echo "" | |
| if [[ -z "$REMOTE_URL" ]]; then | |
| echo "No remote was configured. To add one:" | |
| echo " git remote add origin <url>" | |
| echo " git push -u origin $BRANCH" | |
| echo "" | |
| fi | |
| echo "Backup at: $BACKUP_DIR (remove when satisfied)" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why
I was smart enough to enable SHA256 only in Gitlab, and then realized Nix does not work with this NixOS/nix#9980 -- so instead of patching Nix package manager or specifically
libgit2, go back to the SHA1 setup lol.Usage
Then
cdinto your git repo and run:Or if you are in parent directory
A backup
.gitwill be generated so it is safe to revert. (just delete the new.gitfolder and move the backup back to.git)