Introduction
Installation
building from source
Currently, the only way to install the tool is by building it yourself.
You must have GNU Make and Go installed on your system.
Running make install will also install the corresponding manpages.
cloning
git clone https://codeberg.org/dozrye/git-rewrite-authors-and-resign.git
cd git-rewrite-authors-and-resign
Clone the repository to retrieve the full source code and build scripts
compiling
make build
$(COMPILETARGET): precheck
@echo "compiling"
go build -o $(COMPILETARGET) $(SRC)
$(COMPILETARGETRESIGN): precheck
@echo "compiling"
go build -o $(COMPILETARGETRESIGN) $(SRCRESIGN)
.Phony: user-install build all
build: $(COMPILETARGET) $(COMPILETARGETRESIGN)
Compile the project using Make.
This step builds the binaries for both git-rewrite-authors and git-re-sign.
On the right side you see the shell command and the relevant part in the Makefile.
installing
make install
.Phony: system-install system-man-install installdirs
PREFIX ?= /usr/local
system-install: $(COMPILETARGET) $(COMPILETARGETRESIGN) $(COMPILETARGETRESIGN) system-man-install installdirs
install -m 555 $(COMPILETARGET) $(PREFIX)/bin/$(COMPILEDNAME)
install -m 555 $(COMPILETARGETRESIGN) $(PREFIX)/bin/$(COMPILENAMERESIGN)
.Phony: normal-install install install-strip
normal-install: system-install
install: system-install
Install the built binaries and manpages into your system (default prefix: /usr/local).
This requires root privileges unless you change the installation prefix.
warnings
This tool rewrites every commit in the repository. You must force-push rewritten branches. This will break Fork-Relations and everyone who is currently working on a copy of this repo has to force pull this repo. This will break current pull requests. This will break relationships between branches.
You probably have to redo this for every branch, you want to change your name in. You probably want to bring your repo into a linear history for this tool to work best, and with the least amount of side-effects.
ONLY DO THIS ON GIT REPOSITORIES YOU OWN AND ARE NOT MISSION CRITICAL.
Signed tags may be stripped or rewritten.
Git change-name
git change-name rewrites commit metadata across an entire Git repository.
It replaces outdated or incorrect author names, email addresses, and Signed-off-by lines while preserving commit timestamps and commit messages.
Because the tool rewrites every commit object, it produces an entirely new commit history.
Description
git change-name works by streaming your entire history through git fast-export, modifying the author/committer metadata and Signed-off-by lines, and then reconstructing the history with git fast-import. This method ensures that all changes are applied consistently and that the commit structure is retained.
Optionally, the tool can also re-sign each commit after rewriting, creating a new branch containing both rewritten and re-signed commits.
Since commit hashes are immutable, this process changes every commit in the repository and requires a force push.
Synopsis
git change-name
[-oldName <name>]
[-oldEmail <email>]
[-newName <name>]
[-newEmail <email>]
[-signCommits]
[-signOnBranch <branch>]
| option | description |
|---|---|
-oldName <name> | Specifies an author or committer name in existing commits that should be replaced |
-oldEmail <email> | Specifies an email address to match and replace in author or committer fields |
-newName <name> | Provides the new name that should replace any matched old names |
-newEmail <email> | Provides the new email address to apply to rewritten metadata |
-signCommits | If enabled, the tool uses Git’s signing configuration to re-sign all rewritten commits. Disabled by default |
-signOnBranch <branch> | Defines the branch where re-signed commits should be written The default branch name is resigned |
Warning
Rewriting commit history is a destructive operation. Since every commit hash changes:
- You must force push rewritten branches.
- Forks and clones will no longer be compatible without a forced pull or re-clone.
- Open pull requests referencing the old history will break.
- Relationships between branches may be disrupted.
- In most cases, you must repeat the process for every branch where the metadata should be corrected.
- For best results, use a linearized repository (e.g., after rebasing) to reduce complexity and side effects.
Only use this tool on repositories you fully control and that are not mission-critical. Signed tags may also be removed or altered during rewriting.
Examples
Rewrite author metadata
git change-name \
-oldName "Old Dev" \
-oldEmail old@example.com \
-newName "New Dev" \
-newEmail new@example.com
This updates all commits that were created using the old name or email, preserving the existing timestamps and messages.
Rewrite and re-sign commits
git change-name \
-oldName Old \
-oldEmail old@example.com \
-newName New \
-newEmail new@example.com \
-signCommits \
-signOnBranch re-signed-history
This performs the metadata rewrite and then rebuilds the entire history with fresh commit signatures on a dedicated branch.
Git re-sign
git re-sign reconstructs every commit in a Git repository and re-signs them using your configured Git signing method (GPG, SSH, etc.).
It’s most useful after rewriting author/committer identities or when converting a repository to fully signed commits.
All rewritten commits are placed onto a new branch, or a optionally specified branch, leaving the original history untouched.
Features
- Rebuilds every commit using
git commit-tree -S - Preserves tree contents, parents, author/committer metadata, and messages
- Re-signs each commit with your Git signing configuration
- Writes the rewritten history to a new branch (default:
resigned) - Leaves original branches unchanged
- Ideal for repositories that have:
- Metadata corrections (author/committer changes)
- Unsigned historical commits that need signing
- Migration between signing methods (GPG → SSH, etc.)
Usage
man git-re-sign
For convenience sake you can also access the man pages of this command
General Usage
git re-sign [ -signCommits ] [ -signOnBranch <branch> ]
| option | description |
|---|---|
-signCommits | Enable commit signing. Enabled by default |
-signOnBranch <branch> | Name of the branch that will receive the rewritten, signed history. Default: resigned |
Examples
Re-sign all commits using the configured signing key
git re-sign
Result:
- Original history on main stays the same
- New rewritten history stored at
resigned
Re-sign commits into your own custom branch name
git re-sign -signOnBranch fully-signed
Result:
- Original history on main stays the same
- New rewritten history stored at
fully-signed
Re-sign commits into your main branch
git re-sign -signOnBranch main
Warning: This will have serious side effects.
After rewriting author names or emails
git filter-repo --mailmap .mailmap
If you changed author/committer information
git re-sign -signOnBranch corrected-signed
…then rebuild and re-sign commits
Migrate a repository from unsigned → signed commits
git config commit.gpgsign true
git re-sign -signOnBranch signed-history
Migrate from GPG to SSH signing
git config gpg.format ssh
git config user.signingkey ~/.ssh/id_ed25519.pub
git re-sign -signOnBranch ssh-signed
In some cases you might want to switch from GPG signing to ssh signing.
This tool can help keeping the git history consistent
Replace a remote branch with the re-signed history (force push!)
git re-sign
git checkout resigned
git push origin HEAD:main --force
Dangerous action: do not do this on shared branches unless coordinated.
Important
git log signed-history --show-signature
Inspect rewritten commits before pushing
Background
Rewriting Git history allows you to modify commits that already exist in a repository. You might do this to correct author or committer information, adjust Signed-off-by lines, remove sensitive data, or re-sign all commits. Because commits are immutable, any rewrite creates entirely new commit hashes. This means that rewriting is a destructive process and often requires a force push. This guide explains how rewriting works and how to perform it safely.
Inside Git
Git stores its data using four main object types: blobs, trees, commits, and tags. Blobs represent file contents, while trees store directory structures. Commits reference a tree, parent commits, metadata, and a message. Tags provide optional annotated labels. Since commit objects include hashes of their contents and parents, any change produces a new commit with a new hash.
Why tho?
There are many reasons to rewrite Git history. Common motivations include fixing incorrect names or email addresses, correcting DCO lines, re-signing commits (e.g., switching from GPG to SSH), and removing sensitive text. Rewrites are also useful when importing unrelated history or standardizing metadata in shared or corporate repositories.

