How to convert a SHA1 git repository to SHA256
With the arrival of Git 3.0 expected sometime in 2026, now is the time to start thinking about and preparing for the future. The below details how to migrate a SHA1 Git repository to a SHA256 repository.
Create a new SHA256 repository:
git init new256 -b main --object-format=sha256
Navigate to the new SHA256 repository:
cd new256
Verify it:
git rev-parse --show-object-format
# Output should show: sha256
Navigate to the old SHA1 repository:
cd ../old-sha1
Export the entire SHA1 repository:
git fast-export --all > ../sha1-export.dump
Navigate back to the new SHA256 repository:
cd ../new256
Import the old SHA1 dump into the new SHA256 repository:
git fast-import < ../sha1-export.dump
Checkout the default branch (if not):
# First, see what branches were imported
git branch -a
# Then checkout the main branch
git checkout main
Verify:
git log --oneline -3
git status
git rev-parse --show-object-format
Verify the branches were imported correctly:
# Check all branches
git branch -a
# If only 'main' is seen, check if other branches exist
git show-ref
# List all references (branches, tags)
git for-each-ref
If other branches were not checked out, create them. For each branch in the output, check it out directly (fast-import creates refs/heads/* for normal branches, but does not check them out):
# For example, if 'refs/heads/develop' exists:
git checkout develop
# Or to ensure all branches get local working copies:
git for-each-ref --format='%(refname:short)' refs/heads | while read branch; do
git checkout "$branch" 2>/dev/null || git checkout "$branch"
done
Verify the full history:
git log --oneline --graph --all -10
Final verification of SHA256:
# Confirm SHA256
git rev-parse --show-object-format
# Check a commit hash length (SHA256 is 64 chars)
git rev-parse HEAD
Test basic operations:
git status
git diff HEAD~1
Optional - Set up remote if needed:
git remote add origin <the-remote-url>
Clean up the dump file from its location:
rm ../sha1-export.dump
The new256/ repository should now contain all the history from the old-sha1/, but with SHA256 hashes.
Note: Ensure that your Git server or hosting provider supports SHA256 repositories.
-
For hosted services (e.g. GitHub, GitLab, Codeberg, et al), create a new empty SHA256 repository using their interface and push your converted local repository to it.
-
For self-hosted servers, delete or archive the old SHA1 remote and recreate it in SHA256 format using:
git init --bare new256 -b main --object-format=sha256
Re-add working tree files
If required, copy the working tree files from the old SHA1 directory to the new SHA256 directory, then push from your local SHA256 repository to re-synchronise.
On Branches
The git fast-import command creates all branches as references under refs/heads/* but does not check them out as working branches. Only the default branch (usually ‘main’ or ‘master’) is automatically checked out. Any remote-tracking refs, for example, refs/remotes/origin/* will appear only if they existed in the source export; fast-import itself does not create them.
To see what references exist in the new SHA256 repository:
# Check what references exist
git show-ref
# Or more readable:
git for-each-ref --format='%(refname)'
An example output might be:
refs/heads/main
refs/heads/develop
refs/heads/feature/x
refs/tags/v1.0
This shows that:
mainis already a checked-out working branchdevelopandfeature/xexist as local refs (not remote-tracking refs)- Tags were imported correctly
Check what is present:
git branch -a
If git branch -a shows:
* main
develop
feature/x
Then all branches already exist locally.
If a branch exists only as a reference and has not yet been checked out as a working branch, an example git show-ref might show:
refs/heads/main
refs/remotes/origin/develop
refs/remotes/origin/feature/x
refs/tags/v1.0
In such a case, create local working branches by checking them out:
git checkout develop
git checkout feature/x
The key point: git fast-import imports all refs exactly as they existed in the dump. It does not check out more than the default branch, but all branches under refs/heads/* are created as local refs and can be checked out as needed.
