Raw
1 git-history(1)
2 ==============
3
4 NAME
5 ----
6 git-history - EXPERIMENTAL: Rewrite history
7
8 SYNOPSIS
9 --------
10 [synopsis]
11 git history drop <commit> [--dry-run] [--update-refs=(branches|head)] [--empty=(drop|keep|abort)]
12 git history fixup <commit> [--dry-run] [--update-refs=(branches|head)] [--reedit-message] [--empty=(drop|keep|abort)]
13 git history reword <commit> [--dry-run] [--update-refs=(branches|head)]
14 git history split <commit> [--dry-run] [--update-refs=(branches|head)] [--] [<pathspec>...]
15
16 DESCRIPTION
17 -----------
18
19 Rewrite history by rearranging or modifying specific commits in the
20 history.
21
22 THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
23
24 This command is related to linkgit:git-rebase[1] in that both commands can be
25 used to rewrite history. There are a couple of major differences though:
26
27 * Most subcommands of linkgit:git-history[1] can work in a bare repository as
28 they do not need to touch either the index or the worktree. The `fixup`
29 subcommand is an exception to this, as it reads staged changes from the index.
30 * linkgit:git-history[1] does not execute any linkgit:githooks[5] at the
31 current point in time. This may change in the future.
32 * linkgit:git-history[1] by default updates all branches that are descendants
33 of the original commit to point to the rewritten commit.
34
35 Overall, linkgit:git-history[1] aims to provide a more opinionated way to modify
36 your commit history that is simpler to use compared to linkgit:git-rebase[1] in
37 general.
38
39 Use linkgit:git-rebase[1] if you want to reapply a range of commits onto a
40 different base, or interactive rebases if you want to edit a range of commits
41 at once.
42
43 LIMITATIONS
44 -----------
45
46 This command does not (yet) work with histories that contain merges. You
47 should use linkgit:git-rebase[1] with the `--rebase-merges` flag instead.
48
49 Furthermore, the command does not support operations that can result in merge
50 conflicts. This limitation is by design as history rewrites are not intended to
51 be stateful operations. The limitation can be lifted once (if) Git learns about
52 first-class conflicts.
53
54 When using `fixup` with `--empty=drop`, dropping the root commit is not yet
55 supported. Likewise, `drop` cannot remove the root commit or a merge commit.
56
57 COMMANDS
58 --------
59
60 The following commands are available to rewrite history in different ways:
61
62 `drop <commit>`::
63 Remove the specified commit from the history. All descendants of the
64 commit are replayed directly onto its parent.
65 +
66 The root commit cannot be dropped as that may lead to edge cases where refs
67 end up with no commits anymore. Merge commits cannot be dropped either; see
68 LIMITATIONS.
69 +
70 If `HEAD` points at a commit that is to be rewritten, the index and working
71 tree are updated to match the new `HEAD`. The command aborts before any
72 references are updated in case local modifications would be overwritten.
73 +
74 If replaying any descendant would result in a conflict, the command aborts
75 with an error.
76
77 `fixup <commit>`::
78 Apply the currently staged changes to the specified commit. This is
79 similar in nature to `git commit --fixup=<commit>` followed by `git
80 rebase --autosquash <commit>~`. Changes are applied to the target
81 commit by performing a three-way merge between the HEAD commit, the
82 target commit and the tree generated from staged changes.
83 +
84 The commit message and authorship of the target commit are preserved by
85 default, unless you specify `--reedit-message`.
86 +
87 If applying the staged changes would result in a conflict, the command
88 aborts with an error. All branches that are descendants of the original
89 commit are updated to point to the rewritten history.
90
91 `reword <commit>`::
92 Rewrite the commit message of the specified commit. All the other
93 details of this commit remain unchanged. This command will spawn an
94 editor with the current message of that commit.
95
96 `split <commit> [--] [<pathspec>...]`::
97 Interactively split up <commit> into two commits by choosing
98 hunks introduced by it that will be moved into the new split-out
99 commit. These hunks will then be written into a new commit that
100 becomes the parent of the previous commit. The original commit
101 stays intact, except that its parent will be the newly split-out
102 commit.
103 +
104 The commit messages of the split-up commits will be asked for by launching
105 the configured editor. Authorship of the commit will be the same as for the
106 original commit.
107 +
108 If passed, _<pathspec>_ can be used to limit which changes shall be split out
109 of the original commit. Files not matching any of the pathspecs will remain
110 part of the original commit. For more details, see the 'pathspec' entry in
111 linkgit:gitglossary[7].
112 +
113 It is invalid to select either all or no hunks, as that would lead to
114 one of the commits becoming empty.
115
116 OPTIONS
117 -------
118
119 `--dry-run`::
120 Do not update any references, but instead print any ref updates in a
121 format that can be consumed by linkgit:git-update-ref[1]. Necessary new
122 objects will be written into the repository, so applying these printed
123 ref updates is generally safe.
124
125 `--reedit-message`::
126 Open an editor to modify the target commit's message.
127
128 `--empty=(drop|keep|abort)`::
129 Control what happens when a commit becomes empty as a result of the
130 fixup. This can happen in two situations:
131 +
132 --
133 * The fixup target itself becomes empty because the staged changes exactly
134 cancel out all changes introduced by that commit.
135
136 * A descendant commit becomes empty during replay because it introduced the
137 same change that was just fixed up into an ancestor.
138 --
139 +
140 With `drop` (the default), empty commits are removed from the rewritten
141 history. Descendants of a dropped target commit are replayed directly onto
142 the target's parent. Note that dropping the root commit is not supported;
143 see LIMITATIONS.
144 +
145 With `keep`, empty commits are retained in the rewritten history as-is.
146 +
147 With `abort`, the command stops with an error if any commit would become
148 empty.
149
150 `--update-refs=(branches|head)`::
151 Control which references will be updated by the command, if any. With
152 `branches`, all local branches that point to commits which are
153 descendants of the original commit will be rewritten. With `head`, only
154 the current `HEAD` reference will be rewritten. Defaults to `branches`.
155
156 EXAMPLES
157 --------
158
159 Fixup a commit
160 ~~~~~~~~~~~~~~
161
162 ----------
163 $ git log --oneline --stat
164 abc1234 (HEAD -> main) third
165 third.txt | 1 +
166 def5678 second
167 second.txt | 1 +
168 ghi9012 first
169 first.txt | 1 +
170
171 $ echo "change" >>unrelated.txt
172 $ git add unrelated.txt
173 $ git history fixup ghi9012
174
175 $ git log --oneline --stat
176 jkl3456 (HEAD -> main) third
177 third.txt | 1 +
178 mno7890 second
179 second.txt | 1 +
180 pqr1234 first
181 first.txt | 1 +
182 unrelated.txt | 1 +
183 ----------
184
185 The staged addition of `unrelated.txt` has been incorporated into the `first`
186 commit. All descendant commits have been replayed on top of the rewritten
187 history.
188
189 Drop a commit
190 ~~~~~~~~~~~~~
191
192 ----------
193 $ git log --oneline
194 abc1234 (HEAD -> main) third
195 def5678 second
196 ghi9012 first
197
198 $ git history drop 'main^{/second}'
199
200 $ git log --oneline
201 jkl3456 (HEAD -> main) third
202 ghi9012 first
203 ----------
204
205 The `second` commit has been removed from the history, and `third` has been
206 replayed directly on top of `first`. All branches that pointed at the dropped
207 commit have been moved to its parent.
208
209 Split a commit
210 ~~~~~~~~~~~~~~
211
212 ----------
213 $ git log --stat --oneline
214 3f81232 (HEAD -> main) original
215 bar | 1 +
216 foo | 1 +
217 2 files changed, 2 insertions(+)
218
219 $ git history split HEAD
220 diff --git a/bar b/bar
221 new file mode 100644
222 index 0000000..5716ca5
223 --- /dev/null
224 +++ b/bar
225 @@ -0,0 +1 @@
226 +bar
227 (1/1) Stage addition [y,n,q,a,d,p,?]? y
228
229 diff --git a/foo b/foo
230 new file mode 100644
231 index 0000000..257cc56
232 --- /dev/null
233 +++ b/foo
234 @@ -0,0 +1 @@
235 +foo
236 (1/1) Stage addition [y,n,q,a,d,p,?]? n
237
238 $ git log --stat --oneline
239 7cebe64 (HEAD -> main) original
240 foo | 1 +
241 1 file changed, 1 insertion(+)
242 d1582f3 split-out commit
243 bar | 1 +
244 1 file changed, 1 insertion(+)
245 ----------
246
247 GIT
248 ---
249 Part of the linkgit:git[1] suite