Raw
1 git-replay(1)
2 =============
3
4 NAME
5 ----
6 git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos too
7
8
9 SYNOPSIS
10 --------
11 [verse]
12 (EXPERIMENTAL!) 'git replay' ([--contained] --onto=<newbase> | --advance=<branch> | --revert=<branch>)
13 [--ref=<ref>] [--ref-action=<mode>] [--linearize] <revision-range>
14
15 DESCRIPTION
16 -----------
17
18 Takes a range of commits and replays them onto a new location. Leaves
19 the working tree and the index untouched. By default, updates the
20 relevant references using an atomic transaction (all refs update or
21 none). Use `--ref-action=print` to avoid automatic ref updates and
22 instead get update commands that can be piped to `git update-ref --stdin`
23 (see the <<output,OUTPUT>> section below).
24
25 THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
26
27 OPTIONS
28 -------
29
30 --onto=<newbase>::
31 Starting point at which to create the new commits. May be any
32 valid commit, and not just an existing branch name.
33 +
34 When `--onto` is specified, the branch(es) in the revision range will be
35 updated to point at the new commits, similar to the way `git rebase --update-refs`
36 updates multiple branches in the affected range.
37
38 --advance=<branch>::
39 Starting point at which to create the new commits; must be a
40 branch name.
41 +
42 The history is replayed on top of the <branch> and <branch> is updated to
43 point at the tip of the resulting history. This is different from `--onto`,
44 which uses the target only as a starting point without updating it.
45
46 --revert=<branch>::
47 Starting point at which to create the reverted commits; must be a
48 branch name.
49 +
50 When `--revert` is specified, the commits in the revision range are reverted
51 (their changes are undone) and the reverted commits are created on top of
52 <branch>. The <branch> is then updated to point at the new commits. This is
53 the same as running `git revert <revision-range>` but does not update the
54 working tree.
55 +
56 The commit messages follow `git revert` conventions: they are prefixed with
57 "Revert" and include "This reverts commit <hash>." When reverting a commit
58 whose message starts with "Revert", the new message uses "Reapply" instead.
59 Unlike cherry-pick which preserves the original author, revert commits use
60 the current user as the author, matching the behavior of `git revert`.
61 +
62 This option is mutually exclusive with `--onto` and `--advance`. It is also
63 incompatible with `--contained` (which is a modifier for `--onto` only).
64
65 --contained::
66 Update all branches that point at commits in
67 <revision-range>. Requires `--onto`.
68
69 --ref=<ref>::
70 Override which reference is updated with the result of the replay.
71 The ref must be fully qualified.
72 When used with `--onto`, the `<revision-range>` should have a
73 single tip and only the specified reference is updated instead of
74 inferring refs from the revision range.
75 When used with `--advance` or `--revert`, the specified reference is
76 updated instead of the branch given to those options.
77 This option is incompatible with `--contained`.
78
79 --ref-action[=<mode>]::
80 Control how references are updated. The mode can be:
81 +
82 --
83 ////
84 Expanded description list compared to 'replay.refAction'.
85 ////
86 `update`;; (default) Update refs directly using an atomic transaction.
87 All refs are updated or none are (all-or-nothing behavior).
88 `print`;; Output update-ref commands for pipeline use. This is the
89 traditional behavior where output can be piped to `git update-ref --stdin`.
90 --
91 +
92 The default mode can be configured via the `replay.refAction` configuration variable.
93
94 --linearize::
95 In this mode, each replayed commit is stacked on top of the
96 previously replayed one, so all replayed commits are flattened into
97 a single linear history.
98 +
99 When a merge commit is encountered, the behavior of git-rebase(1)'s
100 option `--no-rebase-merges` is imitated. All commits in the range
101 reachable from the merge commit are replayed into a linear history, and
102 the merge commit itself is dropped. A ref that pointed to a merge commit
103 is updated to the merge's last replayed ancestor.
104 +
105 This flattens the `<revision-range>` as a whole. When multiple revision
106 ranges are given they are stacked on top of each other into one linear
107 history. Each of their refs is updated to point to its position in that
108 history. To linearize ranges separately, replay them in separate `git
109 replay` invocations.
110
111 <revision-range>::
112 Range of commits to replay; see "Specifying Ranges" in
113 linkgit:git-rev-parse[1]. In `--advance=<branch>` or
114 `--revert=<branch>` mode, the range should have a single tip,
115 so that it's clear to which tip the advanced or reverted
116 <branch> should point. Any commits in the range whose changes
117 are already present in the branch the commits are being
118 replayed onto will be dropped.
119
120 :git-replay: 1
121 include::rev-list-options.adoc[]
122
123 [[output]]
124 OUTPUT
125 ------
126
127 By default, or with `--ref-action=update`, this command produces no output on
128 success, as refs are updated directly using an atomic transaction.
129
130 When using `--ref-action=print`, the output is usable as input to
131 `git update-ref --stdin`. It is of the form:
132
133 update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
134 update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
135 update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
136
137 where the number of refs updated depends on the arguments passed and
138 the shape of the history being replayed. When using `--advance` or
139 `--revert`, the number of refs updated is always one, but for `--onto`,
140 it can be one or more (rebasing multiple branches simultaneously is
141 supported).
142
143 There is no stderr output on conflicts; see the <<exit-status,EXIT
144 STATUS>> section below.
145
146 [[exit-status]]
147 EXIT STATUS
148 -----------
149
150 For a successful, non-conflicted replay, the exit status is 0. When
151 the replay has conflicts, the exit status is 1. If the replay is not
152 able to complete (or start) due to some kind of error, the exit status
153 is something other than 0 or 1.
154
155 EXAMPLES
156 --------
157
158 To simply rebase `mybranch` onto `target`:
159
160 ------------
161 $ git replay --onto=target origin/main..mybranch
162 ------------
163
164 The refs are updated atomically and no output is produced on success.
165
166 To see what would be updated without actually updating:
167
168 ------------
169 $ git replay --ref-action=print --onto=target origin/main..mybranch
170 update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
171 ------------
172
173 To cherry-pick the commits from mybranch onto target:
174
175 ------------
176 $ git replay --advance=target origin/main..mybranch
177 ------------
178
179 Note that the first two examples replay the exact same commits and on
180 top of the exact same new base, they only differ in that the first
181 updates mybranch to point at the new commits and the second updates
182 target to point at them.
183
184 What if you have a stack of branches, one depending upon another, and
185 you'd really like to rebase the whole set?
186
187 ------------
188 $ git replay --contained --onto=origin/main origin/main..tipbranch
189 ------------
190
191 All three branches (`branch1`, `branch2`, and `tipbranch`) are updated
192 atomically.
193
194 When calling `git replay`, one does not need to specify a range of
195 commits to replay using the syntax `A..B`; any range expression will
196 do:
197
198 ------------
199 $ git replay --onto=origin/main ^base branch1 branch2 branch3
200 ------------
201
202 This will simultaneously rebase `branch1`, `branch2`, and `branch3`,
203 all commits they have since `base`, playing them on top of
204 `origin/main`. These three branches may have commits on top of `base`
205 that they have in common, but that does not need to be the case.
206
207 To revert commits on a branch:
208
209 ------------
210 $ git replay --revert=main topic~2..topic
211 ------------
212
213 This reverts the last two commits from `topic`, creating revert commits on
214 top of `main`, and updates `main` to point at the result. This is useful when
215 commits from `topic` were previously merged or cherry-picked into `main` and
216 need to be undone.
217
218 NOTE: For reverting an entire merge request as a single commit (rather than
219 commit-by-commit), consider using `git merge-tree --merge-base $TIP HEAD $BASE`
220 which can avoid unnecessary merge conflicts.
221
222 To replay onto a specific commit while updating a different reference:
223
224 ------------
225 $ git replay --onto=112233 --ref=refs/heads/mybranch aabbcc..ddeeff
226 ------------
227
228 This replays the range `aabbcc..ddeeff` onto commit `112233` and updates
229 `refs/heads/mybranch` to point at the result. This can be useful when you want
230 to use bare commit IDs instead of branch names.
231
232 CONFIGURATION
233 -------------
234 :git-replay: 1
235 include::config/replay.adoc[]
236
237 GIT
238 ---
239 Part of the linkgit:git[1] suite