GIT-HISTORY(1)
π git-history(1) β rewrite history, but make it cute
okay so bestie, welcome to git-history, the manual page I'm literally obsessed with. it's EXPERIMENTAL (say it with me), so the behavior may change. read the whole thing before you go rewriting your whole repo, mkay? π
β¨ NAME β¨
git-history β EXPERIMENTAL: Rewrite history
π¦ SYNOPSIS π¦
git history drop <commit> [--dry-run] [--update-refs=(branches|head)] [--empty=(drop|keep|abort)]
git history fixup <commit> [--dry-run] [--update-refs=(branches|head)] [--reedit-message] [--empty=(drop|keep|abort)]
git history reword <commit> [--dry-run] [--update-refs=(branches|head)]
git history split <commit> [--dry-run] [--update-refs=(branches|head)] [--] [<pathspec>...]
πΈ DESCRIPTION πΈ
So the whole vibe here: you rewrite history by rearranging or modifying specific commits in the history. That's it. That's the job. π«Ά
π¨ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. π¨ like fr fr, don't say I didn't warn you.
This command is related to git-rebase(1) in that both commands can be used to rewrite history. There are a couple of major differences though:
- Most subcommands of
git-history(1)can work in a bare repository as they do not need to touch either the index or the worktree. Thefixupsubcommand is an exception to this, as it reads staged changes from the index. git-history(1)does not execute anygithooks(5)at the current point in time. This may change in the future. πgit-history(1)by default updates all branches that are descendants of the original commit to point to the rewritten commit.
Overall, git-history(1) aims to provide a more opinionated way to modify your commit history that is simpler to use compared to git-rebase(1) in general. it's giving "just tell me what you want and I'll handle it" energy, and honestly? iconic.
Use git-rebase(1) if you want to reapply a range of commits onto a different base, or interactive rebases if you want to edit a range of commits at once. different tool, different vibe, both slay in their own lane. π
π LIMITATIONS π
okay bestie, the fine print, and I need you to actually read this part:
This command does not (yet) work with histories that contain merges. You should use git-rebase(1) with the --rebase-merges flag instead.
Furthermore, the command does not support operations that can result in merge conflicts. This limitation is by design as history rewrites are not intended to be stateful operations. The limitation can be lifted once (if) Git learns about first-class conflicts.
When using fixup with --empty=drop, dropping the root commit is not yet supported. Likewise, drop cannot remove the root commit or a merge commit.
π COMMANDS π
The following commands are available to rewrite history in different ways:
ποΈ drop <commit>
Remove the specified commit from the history. All descendants of the commit are replayed directly onto its parent.
The root commit cannot be dropped as that may lead to edge cases where refs end up with no commits anymore. Merge commits cannot be dropped either; see LIMITATIONS.
If HEAD points at a commit that is to be rewritten, the index and working tree are updated to match the new HEAD. The command aborts before any references are updated in case local modifications would be overwritten.
If replaying any descendant would result in a conflict, the command aborts with an error.
π§ fixup <commit>
Apply the currently staged changes to the specified commit. This is similar in nature to git commit --fixup=<commit> followed by git rebase --autosquash <commit>~. Changes are applied to the target commit by performing a three-way merge between the HEAD commit, the target commit and the tree generated from staged changes.
The commit message and authorship of the target commit are preserved by default, unless you specify --reedit-message.
If applying the staged changes would result in a conflict, the command aborts with an error. All branches that are descendants of the original commit are updated to point to the rewritten history.
βοΈ reword <commit>
Rewrite the commit message of the specified commit. All the other details of this commit remain unchanged. This command will spawn an editor with the current message of that commit.
βοΈ split <commit> [--] [<pathspec>...]
Interactively split up <commit> into two commits by choosing hunks introduced by it that will be moved into the new split-out commit. These hunks will then be written into a new commit that becomes the parent of the previous commit. The original commit stays intact, except that its parent will be the newly split-out commit.
The commit messages of the split-up commits will be asked for by launching the configured editor. Authorship of the commit will be the same as for the original commit.
If passed, <pathspec> can be used to limit which changes shall be split out of the original commit. Files not matching any of the pathspecs will remain part of the original commit. For more details, see the pathspec entry in gitglossary(7).
β οΈ It is invalid to select either all or no hunks, as that would lead to one of the commits becoming empty. pick something, bestie. π
β OPTIONS β
--dry-runβ Do not update any references, but instead print any ref updates in a format that can be consumed bygit-update-ref(1). Necessary new objects will be written into the repository, so applying these printed ref updates is generally safe. lowkey the safest way to test the waters first. π--reedit-messageβ Open an editor to modify the target commit's message.--empty=(drop|keep|abort)β Control what happens when a commit becomes empty as a result of thefixup. This can happen in two situations:- The
fixuptarget itself becomes empty because the staged changes exactly cancel out all changes introduced by that commit. - A descendant commit becomes empty during replay because it introduced the same change that was just fixed up into an ancestor.
- The
With drop (the default), empty commits are removed from the rewritten history. Descendants of a dropped target commit are replayed directly onto the target's parent. Note that dropping the root commit is not supported; see LIMITATIONS.
With keep, empty commits are retained in the rewritten history as-is.
With abort, the command stops with an error if any commit would become empty.
--update-refs=(branches|head)β Control which references will be updated by the command, if any. Withbranches, all local branches that point to commits which are descendants of the original commit will be rewritten. Withhead, only the currentHEADreference will be rewritten. Defaults tobranches.
π EXAMPLES π
π§ Fixup a commit
$ git log --oneline --stat
abc1234 (HEAD -> main) third
third.txt | 1 +
def5678 second
second.txt | 1 +
ghi9012 first
first.txt | 1 +
$ echo "change" >>unrelated.txt
$ git add unrelated.txt
$ git history fixup ghi9012
$ git log --oneline --stat
jkl3456 (HEAD -> main) third
third.txt | 1 +
mno7890 second
second.txt | 1 +
pqr1234 first
first.txt | 1 +
unrelated.txt | 1 +
The staged addition of unrelated.txt has been incorporated into the first commit. All descendant commits have been replayed on top of the rewritten history. ate and left no crumbs. π
ποΈ Drop a commit
$ git log --oneline
abc1234 (HEAD -> main) third
def5678 second
ghi9012 first
$ git history drop 'main^{/second}'
$ git log --oneline
jkl3456 (HEAD -> main) third
ghi9012 first
The second commit has been removed from the history, and third has been replayed directly on top of first. All branches that pointed at the dropped commit have been moved to its parent. poof, gone, bye. π¦
βοΈ Split a commit
$ git log --stat --oneline
3f81232 (HEAD -> main) original
bar | 1 +
foo | 1 +
2 files changed, 2 insertions(+)
$ git history split HEAD
diff --git a/bar b/bar
new file mode 100644
index 0000000..5716ca5
--- /dev/null
+++ b/bar
@@ -0,0 +1 @@
+bar
(1/1) Stage addition [y,n,q,a,d,p,?]? y
diff --git a/foo b/foo
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo
(1/1) Stage addition [y,n,q,a,d,p,?]? n
$ git log --stat --oneline
7cebe64 (HEAD -> main) original
foo | 1 +
1 file changed, 1 insertion(+)
d1582f3 split-out commit
bar | 1 +
1 file changed, 1 insertion(+)
look at that, one commit became two. main character energy tbh. β¨
π GIT π
Part of the git(1) suite.
and that's the whole page, bestie!! you just read the entire git-history manual, and honestly? proud of you. π this was Git 2.56.0, dated 2026-09-27 β go forth and rewrite your history responsibly, mwah ππ«ΆπΈ
π¦ where this page comes from
- arch rolling: git 2.56.0-1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms