forked from git/git
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'cc/git-replay' into seen
* cc/git-replay: SQUASH??? replay: stop assuming replayed branches do not diverge replay: add --contained to rebase contained branches replay: add --advance or 'cherry-pick' mode replay: disallow revision specific options and pathspecs replay: use standard revision ranges replay: make it a minimal server side command replay: remove HEAD related sanity check replay: remove progress and info output replay: add an important FIXME comment about gpg signing replay: don't simplify history replay: introduce pick_regular_commit() replay: die() instead of failing assert() replay: start using parse_options API replay: introduce new builtin t6429: remove switching aspects of fast-rebase
- Loading branch information
Showing
12 changed files
with
794 additions
and
264 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -135,6 +135,7 @@ | |
/git-remote-ext | ||
/git-repack | ||
/git-replace | ||
/git-replay | ||
/git-request-pull | ||
/git-rerere | ||
/git-reset | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
git-replay(1) | ||
============= | ||
|
||
NAME | ||
---- | ||
git-replay - Replay commits on a different base, without touching working tree | ||
|
||
|
||
SYNOPSIS | ||
-------- | ||
[verse] | ||
'git replay' [--contained] (--onto <newbase> | --advance <branch>) <revision-range>... | ||
|
||
DESCRIPTION | ||
----------- | ||
|
||
Takes a range of commits, and replays them onto a new location. Does | ||
not touch the working tree or index, and does not update any | ||
references. However, the output of this command is meant to be used | ||
as input to `git update-ref --stdin`, which would update the relevant | ||
branches. | ||
|
||
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. | ||
|
||
OPTIONS | ||
------- | ||
|
||
--onto <newbase>:: | ||
Starting point at which to create the new commits. May be any | ||
valid commit, and not just an existing branch name. | ||
+ | ||
When `--onto` is specified, the update-ref command(s) in the output will | ||
update the branch(es) in the revision range to point at the new | ||
commits (in other words, this mimics a rebase operation). | ||
|
||
--advance <branch>:: | ||
Starting point at which to create the new commits; must be a | ||
branch name. | ||
+ | ||
When `--advance` is specified, the update-ref command(s) in the output | ||
will update the branch passed as an argument to `--advance` to point at | ||
the new commits (in other words, this mimics a cherry-pick operation). | ||
|
||
<revision-range>:: | ||
Range of commits to replay; see "Specifying Ranges" in | ||
linkgit:git-rev-parse. | ||
|
||
OUTPUT | ||
------ | ||
|
||
When there are no conflicts, the output of this command is usable as | ||
input to `git update-ref --stdin`. It is basically of the form: | ||
|
||
update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} | ||
update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} | ||
update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} | ||
|
||
where the number of refs updated depend on the arguments passed. When | ||
using `--advance`, the number of refs updated is always one, but for | ||
`--onto`, it can be one or more (rebasing multiple branches | ||
simultaneously is supported). | ||
|
||
EXIT STATUS | ||
----------- | ||
|
||
For a successful, non-conflicted replay, the exit status is 0. When | ||
the replay has conflicts, the exit status is 1. If the replay is not | ||
able to complete (or start) due to some kind of error, the exit status | ||
is something other than 0 or 1. | ||
|
||
EXAMPLES | ||
-------- | ||
|
||
To simply rebase mybranch onto target: | ||
|
||
------------ | ||
$ git replay --onto target origin/main..mybranch | ||
update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH} | ||
------------ | ||
|
||
To cherry-pick the commits from mybranch onto target: | ||
|
||
------------ | ||
$ git replay --advance target origin/main..mybranch | ||
update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH} | ||
------------ | ||
|
||
Note that the first two examples replay the exact same commits and on | ||
top of the exact same new base, they only differ in that the first | ||
provides instructions to make mybranch point at the new commits and | ||
the second provides instructions to make target point at them. | ||
|
||
What if you have a stack of branches, one depending upon another, and | ||
you'd really like to rebase the whole set? | ||
|
||
------------ | ||
$ git replay --contained --onto origin/main origin/main..tipbranch | ||
update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} | ||
update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} | ||
update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH} | ||
------------ | ||
|
||
In contrast, trying to do this with rebase would require 3 separate | ||
rebases, eacho of which involves a different <ONTO> and <UPSTREAM> and | ||
forces you to first check out each branch in turn. | ||
|
||
When calling `git replay`, one does not need to specify a range of | ||
commits to replay using the syntax `A..B`; any range expression will | ||
do: | ||
|
||
------------ | ||
$ git replay --onto origin/main ^base branch1 branch2 branch3 | ||
update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} | ||
update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} | ||
update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} | ||
------------ | ||
|
||
This will simultaneously rebase branch1, branch2, and branch3 -- all | ||
commits they have since base, playing them on top of origin/main. | ||
These three branches may have commits on top of base that they have in | ||
common, but that does not need to be the case. | ||
|
||
GIT | ||
--- | ||
Part of the linkgit:git[1] suite |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.