Remote Operations
jj works with git remotes but handles them differently.
Fetching Changes
git
git fetch origingit log origin/mainjj
jj git fetchjj log| git | jj |
|---|---|
| git fetch origin | jj git fetch |
| git log origin/main | jj log |
Pulling and Rebasing
jj doesn't have jj git pull. Instead, you fetch then rebase:
git
git pull origin maingit fetch origingit rebase origin/mainjj
jj git fetchjj rebase -d main@origin| git | jj |
|---|---|
| git pull origin main | jj git fetch |
| git fetch origin | jj rebase -d main@origin |
| git rebase origin/main |
NOTE:
The @origin suffix denotes the remote-tracking branch. main@origin is the remote's version of main.
Pushing Changes
git
git push origin mainjj
jj git push| git | jj |
|---|---|
| git push origin main | jj git push |
Setting Up Remotes
git
git remote add origin https://github.com/user/repo.gitgit remote -vjj
jj git remote add origin https://github.com/user/repo.gitjj git remote list| git | jj |
|---|---|
| git remote add origin https://github.com/user/repo.git | jj git remote add origin https://github.com/user/repo.git |
| git remote -v | jj git remote list |
Cloning Repositories
git
git clone https://github.com/user/repo.gitcd repojj
jj git clone https://github.com/user/repo.gitcd repo| git | jj |
|---|---|
| git clone https://github.com/user/repo.git | jj git clone https://github.com/user/repo.git |
| cd repo | cd repo |
Both create a git repository. To use jj:
cd repo
jj git init --colocate
Typical Remote Workflow
# 1. Fetch latest changes
jj git fetch
# 2. Rebase your work on top of remote
jj rebase -d main@origin
# 3. Make your changes
jj describe -m "New feature"
jj new
# 4. Push to remote
jj git push
Colocated Workflow
Since jj and git share the same .git directory:
# Use jj for daily work
jj status
jj log
jj describe -m "Work"
jj new
# Use git for remotes if needed
git push
git fetch
But it's better to use jj's git commands:
jj git fetch
jj git push
Handling Divergence
If your local and remote have diverged:
git
git pull --rebasejj
jj git fetchjj rebase -d main@origin| git | jj |
|---|---|
| git pull --rebase | jj git fetch |
Multiple Remotes
git
git remote add upstream https://github.com/original/repo.gitgit fetch upstreamjj
jj git remote add upstream https://github.com/original/repo.gitjj git fetch --remote upstream| git | jj |
|---|---|
| git remote add upstream https://github.com/original/repo.git | jj git remote add upstream https://github.com/original/repo.git |
| git fetch upstream | jj git fetch --remote upstream |
Git Compatibility
Since jj uses git's storage:
- Use git GUI tools (GitHub Desktop, SourceTree, etc.)
- CI/CD systems work unchanged
- Host services (GitHub, GitLab) just see git
You get jj's UX with git's compatibility.
Try It Yourself
If you have a GitHub repository:
# Clone with jj
jj git clone git@github.com:user/repo.git
cd repo
# Initialize jj
jj git init --colocate
# Make a change
echo "test" > test.txt
jj describe -m "Add test"
jj new
# Push
jj git push
# Pull from another machine
jj git fetch
jj rebase -d main@origin
Key Takeaways
jj git fetchdownloads remote changesjj git pushuploads local changesjj rebase -d branch@originpulls changes- Use
@originsuffix for remote-tracking branches - jj and git can work on the same repo
Next Steps
Now let's learn about jj's powerful revset syntax for querying commits.