-
-
Notifications
You must be signed in to change notification settings - Fork 89
Command: git next, git prev
Available since v0.1.0.
For convenience, git-branchless
offers a pair of commands to navigate to the next or previous commit in a stack. They're shorthand for running git checkout
with the commit ID.
These commits can be very useful for hands-on editing of the commit graph. For example, if you want to update the previous commit, you can run git prev
, amend it, and run git restack
to fix up its descendant commits.
git next
will take you to the next child commit:
$ git next
branchless: running command: git checkout 869c6d3756249eb800e3990affffe6f927ab2605
Previous HEAD position was 91c0908 temp: move foo
branchless: processing 1 update: ref HEAD
HEAD is now at 869c6d3 temp: update foo
branchless: processing checkout
⋮
◇ 86bdeac0 45d (master) Revert "Update foo"
┃
◯ 91c09087 20d temp: move foo
┃
● 869c6d37 20d temp: update foo
And git prev
will take you to the next parent commit:
$ git prev
branchless: running command: git checkout HEAD^
Previous HEAD position was 869c6d3 temp: update foo
branchless: processing 1 update: ref HEAD
HEAD is now at 91c0908 temp: move foo
branchless: processing checkout
⋮
◇ 86bdeac0 45d (master) Revert "Update foo"
┃
● 91c09087 20d temp: move foo
┃
◯ 869c6d37 20d temp: update foo
git next
and git prev
optionally take an argument indicating the number of commits to move:
$ git prev 2
branchless: running command: git checkout HEAD~2
Previous HEAD position was 869c6d3 temp: update foo
branchless: processing 1 update: ref HEAD
HEAD is now at 86bdeac Revert "Update foo"
branchless: processing checkout
⋮
◆ 86bdeac0 45d (master) Revert "Update foo"
┃
◯ 91c09087 20d temp: move foo
┃
◯ 869c6d37 20d temp: update foo
If the target commit is ambiguous (because there are multiple children or parents), then it will ask you to specify --oldest
, --newest
, or --interactive
:
$ git next 2
Found multiple possible next commits to go to after traversing 1 children:
• 869c6d37 temp: update foo (oldest)
• 849bf336 temp: another commit (newest)
(Pass --oldest (-o), --newest (-n), or --interactive (-i) to select between ambiguous next commits)
$ git next 2 -n
branchless: running command: git checkout 849bf3368a5c9c53ff0f1235cc71d8b42b0700a9
Previous HEAD position was 86bdeac Revert "Update foo"
branchless: processing 1 update: ref HEAD
HEAD is now at 849bf33 temp: another commit
branchless: processing checkout
⋮
◇ 86bdeac0 45d (master) Revert "Update foo"
┃
◯ 91c09087 20d temp: move foo
┣━┓
┃ ◯ 869c6d37 20d temp: update foo
┃
● 849bf336 29s temp: another commit
Sometimes it's convenient to go to either the first or last commit in a stack. You can pass -a
/--all
to do this:
$ git sl
⋮
◇ fcba6182 3m (master) Create foo
┃
● 9a80143b 3m Create foo
┃
◯ fa2971d7 3m (baz) Create baz
┃
◯ 2f8daf33 2m Create qux
┃
◯ 7a9883a8 2m (grault) Create grault
┃
◯ d1e3b720 2m Create xyzzy
$ git next -a
branchless: running command: git checkout d1e3b7200ecd2640db754dc52a7ae43e6d94f4ea
Previous HEAD position was 9a80143 Create foo
branchless: processing 1 update: ref HEAD
HEAD is now at d1e3b72 Create xyzzy
branchless: processing checkout
⋮
◇ fcba6182 4m (master) Create foo
┃
◯ 9a80143b 3m Create foo
┃
◯ fa2971d7 3m (baz) Create baz
┃
◯ 2f8daf33 2m Create qux
┃
◯ 7a9883a8 2m (grault) Create grault
┃
● d1e3b720 2m Create xyzzy
Notice that git prev --all
will take you to the first commit in the stack, which will not be the main branch:
$ git prev -a
branchless: running command: git checkout 9a80143be0cb0a4f1d3207371f21e036e0014f60
Previous HEAD position was d1e3b72 Create xyzzy
branchless: processing 1 update: ref HEAD
HEAD is now at 9a80143 Create foo
branchless: processing checkout
⋮
◇ fcba6182 5m (master) Create foo
┃
● 9a80143b 4m Create foo
┃
◯ fa2971d7 4m (baz) Create baz
┃
◯ 2f8daf33 3m Create qux
┃
◯ 7a9883a8 3m (grault) Create grault
┃
◯ d1e3b720 3m Create xyzzy
If there are branches in your stack, you can move to the next or previous branch instead, by using the -b
/--branch
option:
$ git sl
⋮
◆ fcba6182 1m (master) Create foo
┃
◯ 9a80143b 1m Create foo
┃
◯ fa2971d7 1m (baz) Create baz
┃
◯ 2f8daf33 30s Create qux
┃
◯ 7a9883a8 18s (grault) Create grault
┃
◯ d1e3b720 5s Create xyzzy
$ git next -b
branchless: running command: git checkout baz
Switched to branch 'baz'
branchless: processing checkout
⋮
◇ fcba6182 2m (master) Create foo
┃
◯ 9a80143b 1m Create foo
┃
● fa2971d7 1m (baz) Create baz
┃
◯ 2f8daf33 45s Create qux
┃
◯ 7a9883a8 33s (grault) Create grault
┃
◯ d1e3b720 20s Create xyzzy
You can combine --branch
with a number indicating the number of branches to move by:
$ git sl
⋮
◇ fcba6182 6m (master) Create foo
┃
● 9a80143b 5m Create foo
┃
◯ fa2971d7 5m (baz) Create baz
┃
◯ 2f8daf33 5m Create qux
┃
◯ 7a9883a8 4m (grault) Create grault
┃
◯ d1e3b720 4m Create xyzzy
$ git next -b 2
branchless: running command: git checkout grault
Previous HEAD position was 9a80143 Create foo
Switched to branch 'grault'
branchless: processing checkout
⋮
◇ fcba6182 6m (master) Create foo
┃
◯ 9a80143b 5m Create foo
┃
◯ fa2971d7 5m (baz) Create baz
┃
◯ 2f8daf33 5m Create qux
┃
● 7a9883a8 4m (grault) Create grault
┃
◯ d1e3b720 4m Create xyzzy
Or you can combine --branch
with --all
, to move to the first or last commit with a branch in the stack:
$ git sl
⋮
◇ fcba6182 15m (master) Create foo
┃
◯ 9a80143b 15m Create foo
┃
◯ fa2971d7 15m (baz) Create baz
┃
◯ 2f8daf33 14m Create qux
┃
◯ 7a9883a8 14m (grault) Create grault
┃
● d1e3b720 14m Create xyzzy
$ git prev -ab
branchless: running command: git checkout baz
Previous HEAD position was d1e3b72 Create xyzzy
Switched to branch 'baz'
branchless: processing checkout
⋮
◇ fcba6182 15m (master) Create foo
┃
◯ 9a80143b 15m Create foo
┃
● fa2971d7 15m (baz) Create baz
┃
◯ 2f8daf33 14m Create qux
┃
◯ 7a9883a8 14m (grault) Create grault
┃
◯ d1e3b720 14m Create xyzzy
One common use-case for git prev
is to update a previous commit. You can use git commit --amend
as normal:
$ git commit --amend -m 'new message'
branchless: processing 1 update: ref HEAD
branchless: processed commit: 85a1e3c2 new message
branchless: processing 1 rewritten commit
branchless: This operation abandoned 2 commits!
branchless: Consider running one of the following:
branchless: - git restack: re-apply the abandoned commits/branches
branchless: (this is most likely what you want to do)
branchless: - git smartlog: assess the situation
branchless: - git hide [<commit>...]: hide the commits from the smartlog
branchless: - git undo: undo the operation
branchless: - git config branchless.restack.warnAbandoned false: suppress this message
[detached HEAD 85a1e3c] new message
Author: Waleed Khan <[email protected]>
Date: Sat Sep 4 01:35:39 2021 -0500
1 file changed, 0 insertions(+), 0 deletions(-)
rename foo => bar (100%)
When you amend a commit, it abandons any descendant commits:
$ git sl
⋮
◇ 86bdeac0 45d (master) Revert "Update foo"
┣━┓
┃ ✕ 91c09087 20d (rewritten as 85a1e3c2) temp: move foo
┃ ┣━┓
┃ ┃ ◯ 869c6d37 20d temp: update foo
┃ ┃
┃ ◯ 849bf336 6m temp: another commit
┃
● 85a1e3c2 5m new message
To fix this up, run git restack
afterwards:
$ git restack
Attempting rebase in-memory...
[1/2] Committed as: 67687b48 temp: update foo
[2/2] Committed as: 814b2b05 temp: another commit
branchless: processing 2 rewritten commits
In-memory rebase succeeded.
Finished restacking commits.
No abandoned branches to restack.
branchless: running command: git checkout 8d4738cdd4eab974040b93d8ff9bdb1798ad50b4
branchless: processing 1 update: ref HEAD
HEAD is now at 8d4738c new message
args are: 8d4738cdd4eab974040b93d8ff9bdb1798ad50b4 8d4738cdd4eab974040b93d8ff9bdb1798ad50b4 1
branchless: processing checkout
⋮
◇ 86bdeac0 45d (master) Revert "Update foo"
┃
● 8d4738cd 8s new message
┣━┓
┃ ◯ 814b2b05 0s temp: another commit
┃
◯ 67687b48 0s temp: update foo
- Search the Wiki 🔎
- User guide
- Welcome
- Installation
- Tutorial
- Command overview
- General:
- Navigation:
- Committing:
- Rebasing:
- Verification:
- Collaboration:
- Workflows
- Advanced topics
- Reference
- Developer guide
- Onboarding offer
- Development
- Reference