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