mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-19 19:08:08 +00:00
Update tutorial for 0.23 and clarify diffedit
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Some checks are pending
binaries / Build binary artifacts (push) Waiting to run
nix / flake check (push) Waiting to run
build / build (, macos-13) (push) Waiting to run
build / build (, macos-14) (push) Waiting to run
build / build (, ubuntu-latest) (push) Waiting to run
build / build (, windows-latest) (push) Waiting to run
build / build (--all-features, ubuntu-latest) (push) Waiting to run
build / Build jj-lib without Git support (push) Waiting to run
build / Check protos (push) Waiting to run
build / Check formatting (push) Waiting to run
build / Check that MkDocs can build the docs (push) Waiting to run
build / Check that MkDocs can build the docs with latest Python and uv (push) Waiting to run
build / cargo-deny (advisories) (push) Waiting to run
build / cargo-deny (bans licenses sources) (push) Waiting to run
build / Clippy check (push) Waiting to run
Codespell / Codespell (push) Waiting to run
website / prerelease-docs-build-deploy (ubuntu-latest) (push) Waiting to run
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
This commit is contained in:
parent
86a2a2b1e9
commit
ffe5519fd0
1 changed files with 151 additions and 78 deletions
229
docs/tutorial.md
229
docs/tutorial.md
|
@ -1,8 +1,8 @@
|
|||
# Tutorial
|
||||
|
||||
> **Hint:** This tutorial has become somewhat out of date. Many people find
|
||||
> the alternative (not quite finished) [tutorial by Steve
|
||||
> Klabnik](https://steveklabnik.github.io/jujutsu-tutorial/) helpful.
|
||||
> **Hint:** This tutorial has become somewhat out of date. Many people find
|
||||
> the alternative (not quite finished) [tutorial by Steve
|
||||
> Klabnik](https://steveklabnik.github.io/jujutsu-tutorial/) helpful.
|
||||
|
||||
This text assumes that the reader is familiar with Git.
|
||||
|
||||
|
@ -11,7 +11,10 @@ This text assumes that the reader is familiar with Git.
|
|||
If you haven't already, make sure you
|
||||
[install and configure Jujutsu](install-and-setup.md).
|
||||
|
||||
## Cloning a Git repo
|
||||
## Cloning a Git repository
|
||||
|
||||
> **Hint:** Most identifiers used in this tutorial will be different when you
|
||||
> try this at home!
|
||||
|
||||
Let's start by cloning GitHub's Hello-World repo using `jj`:
|
||||
|
||||
|
@ -20,6 +23,10 @@ Let's start by cloning GitHub's Hello-World repo using `jj`:
|
|||
# repos yet)
|
||||
$ jj git clone https://github.com/octocat/Hello-World
|
||||
Fetching into new repo in "/tmp/tmp.O1DWMiaKd4/Hello-World"
|
||||
bookmark: master@origin [new] untracked
|
||||
bookmark: octocat-patch-1@origin [new] untracked
|
||||
bookmark: test@origin [new] untracked
|
||||
Setting the revset alias "trunk()" to "master@origin"
|
||||
Working copy now at: kntqzsqt d7439b06 (empty) (no description set)
|
||||
Parent commit : orrkosyo 7fd1a60b master | (empty) Merge pull request #6 from Spaceghost/patch-1
|
||||
Added 1 files, modified 0 files, removed 0 files
|
||||
|
@ -35,20 +42,50 @@ Working copy : kntqzsqt d7439b06 (empty) (no description set)
|
|||
Parent commit: orrkosyo 7fd1a60b master | (empty) Merge pull request #6 from Spaceghost/patch-1
|
||||
```
|
||||
|
||||
We can see from the output above that our working copy is a real commit with a
|
||||
commit ID (`d7439b06` in the example). When you make a change in the working
|
||||
copy, the working-copy commit gets automatically amended by the next `jj`
|
||||
command.
|
||||
Let's look at that output as it introduces new concepts. You can see two
|
||||
commits: Parent and working copy. Both are identified using two separate
|
||||
identifiers: the "change ID" and the "commit ID".
|
||||
|
||||
The parent commit, for example, has the change ID `orrkosyo` and the commit ID
|
||||
`7fd1a60b`.
|
||||
|
||||
> **Git users:** The commit ID/hash is what you're used to from Git and should
|
||||
> match what you see when you look at the repository using `git log` in a Git
|
||||
> checkout of the repository.
|
||||
> The change ID however, is a new concept, unique to Jujutsu.
|
||||
|
||||
We can also see from the output above that our working copy is an actual commit
|
||||
with a commit ID (`d7439b06` in the example). When you make a change in the
|
||||
working copy, the working-copy commit gets automatically amended by the next
|
||||
`jj` command.
|
||||
|
||||
> **Git users:** This is a huge difference from Git where the working copy is a
|
||||
> separate concept and not yet a commit.
|
||||
|
||||
## Changes
|
||||
|
||||
A change is a commit that can evolve while keeping a stable identifier (similar
|
||||
to Gerrit's Change-Id). In other words: You can make changes to files in a
|
||||
change, resulting in a new commit hash, but the change ID will remain the same.
|
||||
|
||||
You can see that our clone operation automatically created a new change:
|
||||
|
||||
```
|
||||
Working copy : kntqzsqt d7439b06 (empty) (no description set)
|
||||
```
|
||||
|
||||
This new change has the ID `kntqzsqt` and it is currently empty (contains no
|
||||
changes compared to the parent) and has no description.
|
||||
|
||||
## Creating our first change
|
||||
|
||||
Now let's say we want to edit the `README` file in the repo to say "Goodbye"
|
||||
instead of "Hello". Let's start by describing the change (adding a
|
||||
commit message) so we don't forget what we're working on:
|
||||
Let's say we want to edit the `README` file in the repo to say "Goodbye"
|
||||
instead of "Hello". Start by describing the change (adding a commit message) so
|
||||
we don't forget what we're working on:
|
||||
|
||||
```shell
|
||||
# This will bring up $EDITOR (or `pico` or `Notepad` by default). Enter
|
||||
# something like "Say goodbye" in the editor and then save the file and close
|
||||
# This brings up $EDITOR (or `pico` or `Notepad` by default).
|
||||
# Enter something like "Say goodbye" in the editor and then save the file and close
|
||||
# the editor.
|
||||
$ jj describe
|
||||
Working copy now at: kntqzsqt e427edcf (empty) Say goodbye
|
||||
|
@ -72,6 +109,9 @@ Note that you didn't have to tell Jujutsu to add the change like you would with
|
|||
remove existing files. To untrack a path, add it to your `.gitignore` and run
|
||||
`jj file untrack <path>`.
|
||||
|
||||
Also note that the commit hash for our current change (`kntqzsqt`) changed from
|
||||
`e427edcf` to `5d39e19d`!
|
||||
|
||||
To see the diff, run `jj diff`:
|
||||
|
||||
```shell
|
||||
|
@ -109,12 +149,12 @@ Working copy : mpqrykyp aef4df99 (empty) (no description set)
|
|||
Parent commit: kntqzsqt 5d39e19d Say goodbye
|
||||
```
|
||||
|
||||
If we later realize that we want to make further changes, we can make them
|
||||
in the working copy and then run `jj squash`. That command squashes the changes
|
||||
from a given commit into its parent commit. Like most commands, it acts on the
|
||||
working-copy commit by default. When run on the working-copy commit, it behaves
|
||||
very similar to `git commit --amend`, and `jj amend` is in fact an alias for
|
||||
`jj squash`.
|
||||
If we later realize that we want to make further changes, we can make them in
|
||||
the working copy and then run `jj squash`. That command squashes (moves) the
|
||||
changes from a given commit into its parent commit. Like most commands, it acts
|
||||
on the working-copy commit by default. When run on the working-copy commit, it
|
||||
behaves very similar to `git commit --amend`, and `jj amend` is in fact an alias
|
||||
for `jj squash`.
|
||||
|
||||
Alternatively, we can use `jj edit <commit>` to resume editing a commit in the
|
||||
working copy. Any further changes in the working copy will then amend the
|
||||
|
@ -124,8 +164,8 @@ done, it makes sense to use `jj new` so you can easily review your adjustments
|
|||
with `jj diff` before running `jj squash`.
|
||||
|
||||
To view how a change has evolved over time, we can use `jj evolog` to see each
|
||||
recorded change for the current commit. This records changes to the working copy,
|
||||
message, squashes, rebases, etc.
|
||||
recorded change for the current commit. This records changes to the working
|
||||
copy, message, squashes, rebases, etc.
|
||||
|
||||
## The log command and "revsets"
|
||||
|
||||
|
@ -148,21 +188,20 @@ $ jj log
|
|||
```
|
||||
|
||||
The `@` indicates the working-copy commit. The first ID on a line
|
||||
(e.g. "mpqrykyp" above) is the "change ID", which is an ID that follows the
|
||||
commit as it's rewritten (similar to Gerrit's Change-Id). The second ID is the
|
||||
commit ID, which changes when you rewrite the commit. You can give either ID
|
||||
to commands that take revisions as arguments. We will generally prefer change
|
||||
IDs because they stay the same when the commit is rewritten.
|
||||
(e.g. "mpqrykyp" above) is the change ID. The second ID is the commit ID. You
|
||||
can give either ID to commands that take revisions as arguments. We will
|
||||
generally prefer change IDs because they stay the same when the commit is
|
||||
rewritten.
|
||||
|
||||
By default, `jj log` lists your local commits, with some remote commits added
|
||||
for context. The `~` indicates that the commit has parents that are not
|
||||
included in the graph. We can use the `--revisions`/`-r` flag to select a
|
||||
different set of revisions to list. The flag accepts a ["revset"](revsets.md),
|
||||
which is an expression in a simple language for specifying revisions. For
|
||||
example, `@` refers to the working-copy commit, `root()` refers to the root
|
||||
commit, `bookmarks()` refers to all commits pointed to by bookmarks (similar to
|
||||
Git's branches). We can combine expressions with `|` for union, `&` for
|
||||
intersection and `~` for difference. For example:
|
||||
for context. The `~` indicates that the commit has parents that are not included
|
||||
in the graph. We can use the `--revisions`/`-r` flag to select a different set
|
||||
of revisions to list. The flag accepts a ["revset"](revsets.md), which is an
|
||||
expression in a simple language for specifying revisions. For example, `@`
|
||||
refers to the working-copy commit, `root()` refers to the root commit,
|
||||
`bookmarks()` refers to all commits pointed to by bookmarks (similar to Git's
|
||||
branches). We can combine expressions with `|` for union, `&` for intersection
|
||||
and `~` for difference. For example:
|
||||
|
||||
```shell
|
||||
$ jj log -r '@ | root() | bookmarks()'
|
||||
|
@ -173,8 +212,8 @@ $ jj log -r '@ | root() | bookmarks()'
|
|||
◉ zzzzzzzz root() 00000000
|
||||
```
|
||||
|
||||
The `00000000` commit (change ID `zzzzzzzz`) is a virtual commit that's
|
||||
called the "root commit". It's the root commit of every repo. The `root()`
|
||||
The `00000000` commit (change ID `zzzzzzzz`) is a virtual commit that's called
|
||||
the "root commit". It's the root commit of every repo. The `root()`
|
||||
function in the revset matches it.
|
||||
|
||||
There are also operators for getting the parents (`foo-`), children (`foo+`),
|
||||
|
@ -235,6 +274,11 @@ on A.
|
|||
```shell
|
||||
$ jj rebase -s puqltutt -d nuvyytnq # Replace the IDs by what you have for B2 and A
|
||||
Rebased 2 commits
|
||||
Working copy now at: qzvqqupx 1978b534 (conflict) C
|
||||
Parent commit : puqltutt f7fb5943 (conflict) B2
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
There are unresolved conflicts at these paths:
|
||||
file1 2-sided conflict
|
||||
New conflicts appeared in these commits:
|
||||
qzvqqupx 1978b534 (conflict) C
|
||||
puqltutt f7fb5943 (conflict) B2
|
||||
|
@ -243,9 +287,7 @@ To resolve the conflicts, start by updating to the first one:
|
|||
Then use `jj resolve`, or edit the conflict markers in the file directly.
|
||||
Once the conflicts are resolved, you may want to inspect the result with `jj diff`.
|
||||
Then run `jj squash` to move the resolution into the conflicted commit.
|
||||
Working copy now at: qzvqqupx 1978b534 (conflict) C
|
||||
Parent commit : puqltutt f7fb5943 (conflict) B2
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
|
||||
$ jj log
|
||||
@ qzvqqupx martinvonz@google.com 2023-02-12 15:08:33.000 -08:00 1978b534 conflict
|
||||
│ C
|
||||
|
@ -269,10 +311,10 @@ $ jj log
|
|||
There are several things worth noting here. First, the `jj rebase` command said
|
||||
"Rebased 2 commits". That's because we asked it to rebase commit B2 with the
|
||||
`-s` option, which also rebases descendants (commit C in this case). Second,
|
||||
because B2 modified the same file (and word) as B1, rebasing
|
||||
it resulted in conflicts, as the output indicates. Third, the conflicts
|
||||
did not prevent the rebase from completing successfully, nor did it prevent C
|
||||
from getting rebased on top.
|
||||
because B2 modified the same file (and word) as B1, rebasing it resulted in
|
||||
conflicts, as the output indicates. Third, the conflicts did not prevent the
|
||||
rebase from completing successfully, nor did it prevent C from getting rebased
|
||||
on top.
|
||||
|
||||
Now let's resolve the conflict in B2. We'll do that by creating a new commit on
|
||||
top of B2. Once we've resolved the conflict, we'll squash the conflict
|
||||
|
@ -283,28 +325,44 @@ $ jj new puqltutt # Replace the ID by what you have for B2
|
|||
Working copy now at: zxoosnnp c7068d1c (conflict) (empty) (no description set)
|
||||
Parent commit : puqltutt f7fb5943 (conflict) B2
|
||||
Added 0 files, modified 0 files, removed 1 files
|
||||
There are unresolved conflicts at these paths:
|
||||
file1 2-sided conflict
|
||||
|
||||
$ jj st
|
||||
The working copy is clean
|
||||
There are unresolved conflicts at these paths:
|
||||
file1 2-sided conflict
|
||||
Working copy : zxoosnnp c7068d1c (conflict) (empty) (no description set)
|
||||
Parent commit: puqltutt f7fb5943 (conflict) B2
|
||||
To resolve the conflicts, start by updating to it:
|
||||
jj new puqltutt
|
||||
Then use `jj resolve`, or edit the conflict markers in the file directly.
|
||||
Once the conflicts are resolved, you may want to inspect the result with `jj diff`.
|
||||
Then run `jj squash` to move the resolution into the conflicted commit.
|
||||
|
||||
$ cat file1
|
||||
<<<<<<<
|
||||
%%%%%%%
|
||||
-b1
|
||||
+a
|
||||
+++++++
|
||||
b2
|
||||
>>>>>>>
|
||||
<<<<<<< Conflict 1 of 1
|
||||
%%%%%%% Changes from base to side #1
|
||||
-b1+a+++++++ Contents of side #2
|
||||
b2>>>>>>> Conflict 1 of 1 ends
|
||||
|
||||
$ echo resolved > file1
|
||||
|
||||
$ jj st
|
||||
Working copy changes:
|
||||
M file1
|
||||
Working copy : zxoosnnp c2a31a06 (no description set)
|
||||
Parent commit: puqltutt f7fb5943 (conflict) B2
|
||||
Conflict in parent commit has been resolved in working copy
|
||||
|
||||
$ jj squash
|
||||
Rebased 1 descendant commits
|
||||
Working copy now at: ntxxqymr e3c279cc (empty) (no description set)
|
||||
Parent commit : puqltutt 2c7a658e B2
|
||||
Existing conflicts were resolved or abandoned from these commits:
|
||||
qzvqqupx hidden 1978b534 (conflict) C
|
||||
puqltutt hidden f7fb5943 (conflict) B2
|
||||
Working copy now at: ntxxqymr e3c279cc (empty) (no description set)
|
||||
Parent commit : puqltutt 2c7a658e B2
|
||||
|
||||
$ jj log
|
||||
@ ntxxqymr martinvonz@google.com 2023-02-12 19:34:09.000 -08:00 e3c279cc
|
||||
│ (empty) (no description set)
|
||||
|
@ -372,6 +430,7 @@ Once the conflicts are resolved, you may want to inspect the result with `jj dif
|
|||
Then run `jj squash` to move the resolution into the conflicted commit.
|
||||
Working copy now at: zxoosnnp 63874fe6 (no description set)
|
||||
Parent commit : puqltutt f7fb5943 (conflict) B2
|
||||
|
||||
$ jj log
|
||||
@ zxoosnnp martinvonz@google.com 2023-02-12 19:34:09.000 -08:00 63874fe6
|
||||
│ (no description set)
|
||||
|
@ -399,8 +458,9 @@ squashing the conflict resolution into commit B2 earlier. Notice that it also
|
|||
updated the working copy.
|
||||
|
||||
You can also view the repo the way it looked after some earlier operation. For
|
||||
example, if you want to see `jj log` output right after the `jj rebase` operation,
|
||||
try `jj log --at-op=367400773f87` but use the hash from your own `jj op log`.
|
||||
example, if you want to see `jj log` output right after the `jj rebase`
|
||||
operation, try `jj log --at-op=367400773f87` but use the hash from your own
|
||||
`jj op log`.
|
||||
|
||||
## Moving content changes between commits
|
||||
|
||||
|
@ -416,12 +476,15 @@ $ jj new master -m abc; printf 'a\nb\nc\n' > file
|
|||
Working copy now at: ztqrpvnw f94e49cf (empty) abc
|
||||
Parent commit : orrkosyo 7fd1a60b master | (empty) Merge pull request #6 from Spaceghost/patch-1
|
||||
Added 0 files, modified 0 files, removed 1 files
|
||||
|
||||
$ jj new -m ABC; printf 'A\nB\nc\n' > file
|
||||
Working copy now at: kwtuwqnm 6f30cd1f (empty) ABC
|
||||
Parent commit : ztqrpvnw 51002261 ab
|
||||
|
||||
$ jj new -m ABCD; printf 'A\nB\nC\nD\n' > file
|
||||
Working copy now at: mrxqplyk a6749154 (empty) ABCD
|
||||
Parent commit : kwtuwqnm 30aecc08 ABC
|
||||
|
||||
$ jj log -r master::@
|
||||
@ mrxqplyk martinvonz@google.com 2023-02-12 19:38:21.000 -08:00 b98c607b
|
||||
│ ABCD
|
||||
|
@ -437,14 +500,15 @@ $ jj log -r master::@
|
|||
We "forgot" to capitalize "c" in the second commit when we capitalized the other
|
||||
letters. We then fixed that in the third commit when we also added "D". It would
|
||||
be cleaner to move the capitalization of "c" into the second commit. We can do
|
||||
that by running `jj squash` with the `--interactive`/`-i` option on the
|
||||
third commit. Remember that `jj squash` moves all the changes from one commit
|
||||
into its parent. `jj squash -i` moves only part of the changes into its parent.
|
||||
Now try that:
|
||||
that by running `jj squash` with the `--interactive`/`-i` option on the third
|
||||
commit. Remember that `jj squash` moves all the changes from one commit into its
|
||||
parent. `jj squash -i` moves only part of the changes into its parent. Now try
|
||||
that:
|
||||
|
||||
```shell
|
||||
$ jj squash -i
|
||||
Using default editor ':builtin'; you can change this by setting ui.diff-editor
|
||||
Hint: Using default editor ':builtin'; run `jj config set --user ui.diff-editor :builtin` to disable this message.
|
||||
Rebased 1 descendant commits
|
||||
Working copy now at: mrxqplyk 52a6c7fd ABCD
|
||||
Parent commit : kwtuwqnm 643061ac ABC
|
||||
```
|
||||
|
@ -463,15 +527,22 @@ squash -i --tool meld-3`. You can configure the default with the
|
|||
[`ui.diff-editor` option](config.md#editing-diffs); those docs also explain how
|
||||
to specify a path to an executable if it is not in the PATH.
|
||||
|
||||
If we look at the diff of the second commit, we now see
|
||||
that all three lines got capitalized:
|
||||
If we look at the diff of the second commit, we now see that all three lines got
|
||||
capitalized:
|
||||
|
||||
```shell
|
||||
$ jj diff -r @-
|
||||
Modified regular file file:
|
||||
1 1: aA
|
||||
2 2: bB
|
||||
3 3: cC
|
||||
$ jj diff -r @- --git
|
||||
diff --git a/file b/file
|
||||
index de980441c3..b1e67221af 100644
|
||||
--- a/file
|
||||
+++ b/file
|
||||
@@ -1,3 +1,3 @@
|
||||
-a
|
||||
-b
|
||||
-c
|
||||
+A
|
||||
+B
|
||||
+C
|
||||
```
|
||||
|
||||
The child change ("ABCD" in our case) will have the same content *state* after
|
||||
|
@ -480,14 +551,19 @@ the parent change, even if they touch the same word, and it won't cause any
|
|||
conflicts.
|
||||
|
||||
Let's try one final command for changing the contents of an exiting commit. That
|
||||
command is `jj diffedit`, which lets you edit the contents of a commit without
|
||||
command is `jj diffedit`, which lets you edit the changes in a commit without
|
||||
checking it out.
|
||||
|
||||
```shell
|
||||
$ jj diffedit -r @-
|
||||
Using default editor ':builtin'; you can change this by setting ui.diff-editor
|
||||
Hint: Using default editor ':builtin'; run `jj config set --user ui.diff-editor :builtin` to disable this message.
|
||||
Created kwtuwqnm 70985eaa (empty) ABC
|
||||
Rebased 1 descendant commits
|
||||
Working copy now at: mrxqplyk 1c72cd50 (conflict) ABCD
|
||||
Parent commit : kwtuwqnm 70985eaa (empty) ABC
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
There are unresolved conflicts at these paths:
|
||||
file 2-sided conflict
|
||||
New conflicts appeared in these commits:
|
||||
mrxqplyk 1c72cd50 (conflict) ABCD
|
||||
To resolve the conflicts, start by updating to it:
|
||||
|
@ -495,18 +571,15 @@ To resolve the conflicts, start by updating to it:
|
|||
Then use `jj resolve`, or edit the conflict markers in the file directly.
|
||||
Once the conflicts are resolved, you may want to inspect the result with `jj diff`.
|
||||
Then run `jj squash` to move the resolution into the conflicted commit.
|
||||
Working copy now at: mrxqplyk 1c72cd50 (conflict) ABCD
|
||||
Parent commit : kwtuwqnm 70985eaa (empty) ABC
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
```
|
||||
|
||||
In the diff editor, edit the right side by e.g. adding something to the first
|
||||
line. Press 'c' to save the changes and close it. You can now inspect the rewritten
|
||||
commit with `jj diff -r @-` again and you should see your addition to the first
|
||||
line. Unlike `jj squash -i`, which left the content state of the commit
|
||||
In the diff editor, use the arrow keys and spacebar to select all lines but the
|
||||
last. Press 'c' to save the changes and close it. You can now inspect the
|
||||
rewritten commit with `jj diff -r @-` again, and you should see your deletion of
|
||||
the last line. Unlike `jj squash -i`, which left the content state of the commit
|
||||
unchanged, `jj diffedit` (typically) results in a different state, which means
|
||||
that descendant commits may have conflicts.
|
||||
|
||||
Another command for rewriting contents of existing commits is `jj split`. Now that
|
||||
you've seen how `jj squash -i` and `jj diffedit` work, you can hopefully figure out
|
||||
how it works (with the help of the instructions in the diff).
|
||||
Another command for rewriting contents of existing commits is `jj split`. Now
|
||||
that you've seen how `jj squash -i` and `jj diffedit` work, you can hopefully
|
||||
figure out how it works (with the help of the instructions in the diff).
|
||||
|
|
Loading…
Reference in a new issue