sapling/website/docs/overview/rebase.md
Shish dff773ccfd make examples consistent (#269)
Summary:
Stack created with [Sapling]
* __->__ https://github.com/facebook/sapling/issues/269
* https://github.com/facebook/sapling/issues/267
* https://github.com/facebook/sapling/issues/266
* https://github.com/facebook/sapling/issues/264

[docs] make examples consistent

 both human understanding and syntax highlighting work better when the examples are consistent :)

Pull Request resolved: https://github.com/facebook/sapling/pull/269

Test Plan: manually looked through every page

Reviewed By: bolinfest

Differential Revision: D41544321

Pulled By: shish

fbshipit-source-id: aca88968b1c6cfc5340a004dd115e9eabbd4313c
2022-12-05 17:00:49 -08:00

5.5 KiB

sidebar_position
70

Rebase

While the word "rebase" is a bit confusing, it fundamentally just means moving commits from one part of the repository to another. In Sapling, this is done with the sl rebase command.

Rebasing requires two pieces of information:

  1. Which commits will be moved, via one of the flags -r (revisions), -s (source), or -b (base).
  2. The destination commit to move the commits to, via the -d (destination) flag.

Examples

To illustrate the different types of rebases, assume we start with the following commit graph. Note that we are currently on Commit C, as indicated by the @ symbol.

$ sl
o  d78f66e01  106 seconds ago  remote/main
╷
╷ o  306ce5ffb  67 seconds ago  mary
╷ │  Commit F
╷ │
╷ o  2ff5f28a1  67 seconds ago  mary
╷ │  Commit E
╷ │
╷ │ o  e5513dac4  67 seconds ago  mary
╷ │ │  Commit D
╷ │ │
╷ │ @  6f782187a  67 seconds ago  mary
╷ ├─╯  Commit C
╷ │
╷ o  3beadc099  67 seconds ago  mary
╷ │  Commit B
╷ │
╷ o  b48ce5c8e  67 seconds ago  mary
╭─╯  Commit A
│
o  17af69994  Today at 08:33  remote/stable
╷
~

-b / --base

The most common use for rebase is to move your in-progress commits onto a newer version of main. The -b flag is ideal for this situation, as it will take the entire subtree of your commits and move them onto the destination.

Below we use -b . to rebase the current commit, ., and its entire related subtree onto main. In this case, the subtree is Commit A and all of its descendants.

Note that sl rebase -b . -d XXX is the same as sl rebase -d XXX, as -b . is the default behavior.

# Move entire current subtree onto main.
$ sl rebase -b . -d main
  o  91ecebda8  12 seconds ago  mary
  │  Commit F
  │
  o  b26b55434  12 seconds ago  mary
  │  Commit E
  │
  │ o  a9ef0ee2d  12 seconds ago  mary
  │ │  Commit D
  │ │
  │ @  37d2d0296  12 seconds ago  mary
  ├─╯  Commit C
  │
  o  37d536158  12 seconds ago  mary
  │  Commit B
  │
  o  81910236f  12 seconds ago  mary
╭─╯  Commit A
│
o  d78f66e01  15 minutes ago  remote/main
╷
o  17af69994  Today at 08:33  remote/stable
╷
~

-s / --source

If you don't want to rebase the entire subtree with -b, you can use -s to rebase a given commit and all of its descendants.

Below we use -s . to rebase the current commit, ., and its descendant Commit D onto main. All other commits are left behind.

# Move current commit and its descendants onto main.
$ sl rebase -s . -d main
  o  aa40b4d44  44 seconds ago  mary
  │  Commit D
  │
  @  95cf1e999  44 seconds ago  mary
╭─╯  Commit C
│
o  d78f66e01  11 minutes ago  remote/main
╷
╷ o  306ce5ffb  11 minutes ago  mary
╷ │  Commit F
╷ │
╷ o  2ff5f28a1  11 minutes ago  mary
╷ │  Commit E
╷ │
╷ o  3beadc099  11 minutes ago  mary
╷ │  Commit B
╷ │
╷ o  b48ce5c8e  11 minutes ago  mary
╭─╯  Commit A
│
o  17af69994  Today at 08:33  remote/stable
╷
~

-r / --revisions

If we only want to move a specific commit or commits, we use -r to move exactly the commits we specified.

Below we move the commit we're on by specifying . as the argument to -r. We move it onto main by specifying main as the argument to -d.

# Move just the current commit to be based on main
$ sl rebase -r . -d main
rebasing 6f782187aa42 "Commit C"
6f782187aa42 -> 8abef7d37f3a "Commit C"
$ sl
  @  8abef7d37  6 seconds ago  mary
╭─╯  Commit C
│
o  d78f66e01  4 minutes ago  remote/main
╷
╷ o  306ce5ffb  3 minutes ago  mary
╷ │  Commit F
╷ │
╷ o  2ff5f28a1  3 minutes ago  mary
╷ │  Commit E
╷ │
╷ │ o  e5513dac4  3 minutes ago  mary
╷ │ │  Commit D
╷ │ │
╷ │ x  6f782187a [Rebased to 8abef7d37f3a]  3 minutes ago  mary
╷ ├─╯  Commit C
╷ │
╷ o  3beadc099  3 minutes ago  mary
╷ │  Commit B
╷ │
╷ o  b48ce5c8e  3 minutes ago  mary
╭─╯  Commit A
│
o  17af69994  Today at 08:33  remote/stable
╷
~

Note how 6f782187a is identified with an x in the commit graph to denote that it has been rewritten to the newer version 8abef7d37f3a. However, it is still visible because commit D did not get rebased.

Other

The rebase command can move multiple stacks and subtrees in a single invocation. The tree structure will be retained across the rebase. For example, one can use the draft() revset to rebase all of your local commits onto a newer base commit.

$ sl
o  b5d600552  27 seconds ago  remote/main
╷
╷ o  9d5ba71bc  2 minutes ago  mary
╷ │  Commit C
╷ │
╷ │ o  37d536158  12 minutes ago  mary
╷ ├─╯  Commit B
╷ │
╷ o  81910236f  12 minutes ago  mary
╭─╯  Commit A
│
o  d78f66e01  27 minutes ago
╷
╷ @  ecf227650  69 seconds ago  mary
╷ │  Commit Two
╷ │
╷ o  5da2b3e5a  91 seconds ago  mary
╭─╯  Commit One
│
o  17af69994  Today at 08:33  remote/stable
╷
~

# Rebase all my commits onto new main.
$ sl rebase -r 'draft()' -d main

$ sl
  o  3c5549fb7  10 seconds ago  mary
  │  Commit C
  │
  │ o  ed3106510  10 seconds ago  mary
  ├─╯  Commit B
  │
  o  23a6f6012  10 seconds ago  mary
╭─╯  Commit A
│
│ @  9f73762dd  10 seconds ago  mary
│ │  Commit Two
│ │
│ o  9d550d707  10 seconds ago  mary
├─╯  Commit One
│
o  b5d600552  3 minutes ago  remote/main
╷
o  17af69994  Today at 08:33  remote/stable
╷
~