214 lines
6.6 KiB
Plaintext
214 lines
6.6 KiB
Plaintext
git-history(1)
|
|
==============
|
|
|
|
NAME
|
|
----
|
|
git-history - EXPERIMENTAL: Rewrite history
|
|
|
|
SYNOPSIS
|
|
--------
|
|
[synopsis]
|
|
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
|
|
-----------
|
|
|
|
Rewrite history by rearranging or modifying specific commits in the
|
|
history.
|
|
|
|
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
|
|
|
|
This command is related to linkgit:git-rebase[1] in that both commands can be
|
|
used to rewrite history. There are a couple of major differences though:
|
|
|
|
* Most subcommands of linkgit:git-history[1] can work in a bare repository as
|
|
they do not need to touch either the index or the worktree. The `fixup`
|
|
subcommand is an exception to this, as it reads staged changes from the index.
|
|
* linkgit:git-history[1] does not execute any linkgit:githooks[5] at the
|
|
current point in time. This may change in the future.
|
|
* linkgit:git-history[1] by default updates all branches that are descendants
|
|
of the original commit to point to the rewritten commit.
|
|
|
|
Overall, linkgit:git-history[1] aims to provide a more opinionated way to modify
|
|
your commit history that is simpler to use compared to linkgit:git-rebase[1] in
|
|
general.
|
|
|
|
Use linkgit: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.
|
|
|
|
LIMITATIONS
|
|
-----------
|
|
|
|
This command does not (yet) work with histories that contain merges. You
|
|
should use linkgit: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.
|
|
|
|
COMMANDS
|
|
--------
|
|
|
|
The following commands are available to rewrite history in different ways:
|
|
|
|
`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
|
|
linkgit:gitglossary[7].
|
|
+
|
|
It is invalid to select either all or no hunks, as that would lead to
|
|
one of the commits becoming empty.
|
|
|
|
OPTIONS
|
|
-------
|
|
|
|
`--dry-run`::
|
|
Do not update any references, but instead print any ref updates in a
|
|
format that can be consumed by linkgit:git-update-ref[1]. Necessary new
|
|
objects will be written into the repository, so applying these printed
|
|
ref updates is generally safe.
|
|
|
|
`--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 the
|
|
fixup. This can happen in two situations:
|
|
+
|
|
--
|
|
* The fixup target 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.
|
|
--
|
|
+
|
|
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. With
|
|
`branches`, all local branches that point to commits which are
|
|
descendants of the original commit will be rewritten. With `head`, only
|
|
the current `HEAD` reference will be rewritten. Defaults to `branches`.
|
|
|
|
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.
|
|
|
|
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(+)
|
|
----------
|
|
|
|
GIT
|
|
---
|
|
Part of the linkgit:git[1] suite
|