Skip to content

Instantly share code, notes, and snippets.

@leewc
Created April 28, 2026 21:29
Show Gist options
  • Select an option

  • Save leewc/985ebf3faaf52622262c961b55dbe144 to your computer and use it in GitHub Desktop.

Select an option

Save leewc/985ebf3faaf52622262c961b55dbe144 to your computer and use it in GitHub Desktop.
Convert git repo from SHA256 to SHA1 object formats (and vice versa)
#!/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)"
@leewc
Copy link
Copy Markdown
Author

leewc commented Apr 28, 2026

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

curl -L https://gist.github.com/leewc/985ebf3faaf52622262c961b55dbe144/raw/ > git-convert-hash.sh
chmod u+x git-convert-hash.sh

Then cd into your git repo and run:

./git-convert-hash.sh

Or if you are in parent directory

./git-convert-hash.sh folder-name-with-git

A backup .git will be generated so it is safe to revert. (just delete the new .git folder and move the backup back to .git)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment