ok/jj
1
0
Fork 0
forked from mirrors/jj
jj/v0.15.0/git-comparison/index.html
Ilya Grigoriev f67d6a192c docs SEO (direct website push): Use "latest" URL as canonical URL for older versions
The replacement was done by `sed`.

This should only change versions of the docs prior to 864869ab (in
particular, not the `latest` version nor the `prerelease` version), and
make it as though the old version of the docs were compiled with that
commit. It tries to solve the same problem:
https://www.google.com/search?q=jj+revsets still points to jj v0.13
docs.

Google seems really slow to update its index, and I'm beginning to worry
that it might think we have a spammy site with many almost identical
pages. I hope it will pick up this change once it tries to update its
crawl of pages it's already indexing.

Loosely related reading: https://news.ycombinator.com/item?id=40970987
2024-07-25 14:29:08 -07:00

1735 lines
No EOL
44 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://martinvonz.github.io/jj/latest/git-comparison/">
<link rel="prev" href="../templates/">
<link rel="next" href="../git-compatibility/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.5.4">
<title>Git comparison - Jujutsu docs</title>
<link rel="stylesheet" href="../assets/stylesheets/main.50c56a3b.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#comparison-with-git" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="Jujutsu docs" class="md-header__button md-logo" aria-label="Jujutsu docs" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Jujutsu docs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Git comparison
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m14.3 16-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9h-1.9M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69m-9.15 3.96h2.3L12 9l-1.15 3.65Z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12c0-2.42-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg>
</label>
</form>
<script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="Jujutsu docs" class="md-nav__button md-logo" aria-label="Jujutsu docs" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>
</a>
Jujutsu docs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Getting started
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Getting started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../install-and-setup/" class="md-nav__link">
<span class="md-ellipsis">
Installation and Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tutorial/" class="md-nav__link">
<span class="md-ellipsis">
Tutorial and Birds-Eye View
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../github/" class="md-nav__link">
<span class="md-ellipsis">
Working with GitHub
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../windows/" class="md-nav__link">
<span class="md-ellipsis">
Working on Windows
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../FAQ/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli-reference/" class="md-nav__link">
<span class="md-ellipsis">
CLI Reference
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../testimonials/" class="md-nav__link">
<span class="md-ellipsis">
Testimonials
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Concepts
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Concepts
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../working-copy/" class="md-nav__link">
<span class="md-ellipsis">
Working Copy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../branches/" class="md-nav__link">
<span class="md-ellipsis">
Branches
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../conflicts/" class="md-nav__link">
<span class="md-ellipsis">
Conflicts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../operation-log/" class="md-nav__link">
<span class="md-ellipsis">
Operation Log
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../glossary/" class="md-nav__link">
<span class="md-ellipsis">
Glossary
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
<span class="md-ellipsis">
Configuration
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../config/" class="md-nav__link">
<span class="md-ellipsis">
Settings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../revsets/" class="md-nav__link">
<span class="md-ellipsis">
Revset language
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../templates/" class="md-nav__link">
<span class="md-ellipsis">
Templating language
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" checked>
<label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0">
<span class="md-ellipsis">
Comparisons
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
Comparisons
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Git comparison
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Git comparison
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#introduction" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-index" class="md-nav__link">
<span class="md-ellipsis">
The index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#command-equivalence-table" class="md-nav__link">
<span class="md-ellipsis">
Command equivalence table
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../git-compatibility/" class="md-nav__link">
<span class="md-ellipsis">
Git compatibility
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sapling-comparison/" class="md-nav__link">
<span class="md-ellipsis">
Sapling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../related-work/" class="md-nav__link">
<span class="md-ellipsis">
Other related work
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_9" >
<label class="md-nav__link" for="__nav_9" id="__nav_9_label" tabindex="0">
<span class="md-ellipsis">
Technical details
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_9">
<span class="md-nav__icon md-icon"></span>
Technical details
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../technical/architecture/" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../technical/concurrency/" class="md-nav__link">
<span class="md-ellipsis">
Concurrency
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../technical/conflicts/" class="md-nav__link">
<span class="md-ellipsis">
Conflicts
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_10" >
<label class="md-nav__link" for="__nav_10" id="__nav_10_label" tabindex="0">
<span class="md-ellipsis">
Contributing
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10">
<span class="md-nav__icon md-icon"></span>
Contributing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../contributing/" class="md-nav__link">
<span class="md-ellipsis">
Guidelines and "How to...?"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../code-of-conduct/" class="md-nav__link">
<span class="md-ellipsis">
Code of conduct
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_11" >
<label class="md-nav__link" for="__nav_11" id="__nav_11_label" tabindex="0">
<span class="md-ellipsis">
Design docs
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_11">
<span class="md-nav__icon md-icon"></span>
Design docs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../design/git-submodules/" class="md-nav__link">
<span class="md-ellipsis">
git-submodules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../design/git-submodule-storage/" class="md-nav__link">
<span class="md-ellipsis">
git-submodule-storage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../design/run/" class="md-nav__link">
<span class="md-ellipsis">
JJ run
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../design/sparse-v2/" class="md-nav__link">
<span class="md-ellipsis">
Sparse Patterns v2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../design/tracking-branches/" class="md-nav__link">
<span class="md-ellipsis">
Tracking branches
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#introduction" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-index" class="md-nav__link">
<span class="md-ellipsis">
The index
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#command-equivalence-table" class="md-nav__link">
<span class="md-ellipsis">
Command equivalence table
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="comparison-with-git">Comparison with Git<a class="headerlink" href="#comparison-with-git" title="Permanent link">&para;</a></h1>
<h2 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">&para;</a></h2>
<p>This document attempts to describe how Jujutsu is different from Git. See
<a href="../git-compatibility/">the Git-compatibility doc</a> for information about how
the <code>jj</code> command interoperates with Git repos.</p>
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
<p>Here is a list of conceptual differences between Jujutsu and Git, along with
links to more details where applicable and available. There's a
<a href="#command-equivalence-table">table further down</a> explaining how to achieve
various use cases.</p>
<ul>
<li><strong>The working copy is automatically committed.</strong> That results in a simpler and
more consistent CLI because the working copy is now treated like any other
commit. <a href="../working-copy/">Details</a>.</li>
<li><strong>There's no index (staging area).</strong> Because the working copy is automatically
committed, an index-like concept doesn't make sense. The index is very similar
to an intermediate commit between <code>HEAD</code> and the working copy, so workflows
that depend on it can be modeled using proper commits instead. Jujutsu has
excellent support for moving changes between commits. <a href="#the-index">Details</a>.</li>
<li><strong>No need for branch names (but they are supported).</strong> Git lets you check out
a commit without attaching a branch. It calls this state "detached HEAD". This
is the normal state in Jujutsu (there's actually no way -- yet, at least -- to
have an active branch). However, Jujutsu keeps track of all visible heads
(leaves) of the commit graph, so the commits won't get lost or
garbage-collected.</li>
<li><strong>No current branch.</strong> Git lets you check out a branch, making it the 'current
branch', and new commits will automatically update the branch. This is
necessary in Git because Git might otherwise lose track of the new commits.
Jujutsu does not have a 'current branch'; instead, you update branches
manually. For example, if you check out a commit with a branch, new commits
are created on top of the branch, then you issue a later command to update the
branch.</li>
<li><strong>Conflicts can be committed.</strong> No commands fail because of merge conflicts.
The conflicts are instead recorded in commits and you can resolve them later.
<a href="../conflicts/">Details</a>.</li>
<li><strong>Descendant commits are automatically rebased.</strong> Whenever you rewrite a
commit (e.g. by running <code>jj rebase</code>), all its descendants commits will
automatically be rebased on top. Branches pointing to it will also get
updated, and so will the working copy if it points to any of the rebased
commits.</li>
<li><strong>Branches are identified by their names (across remotes).</strong> For example, if
you pull from a remote that has a <code>main</code> branch, you'll get a branch by that
name in your local repo as well. If you then move it and push back to the
remote, the <code>main</code> branch on the remote will be updated.
<a href="../branches/">Details</a>.</li>
<li><strong>The operation log replaces reflogs.</strong> The operation log is similar to
reflogs, but is much more powerful. It keeps track of atomic updates to all
refs at once (Jujutsu thus improves on Git's per-ref history much in the same
way that Subversion improved on RCS's per-file history). The operation log
powers e.g. the undo functionality. <a href="../operation-log/">Details</a></li>
<li><strong>There's a single, virtual root commit.</strong> Like Mercurial, Jujutsu has a
virtual commit (with a hash consisting of only zeros) called the "root commit"
(called the "null revision" in Mercurial). This commit is a common ancestor of
all commits. That removes the awkward state Git calls the "unborn branch"
state (which is the state a newly initialized Git repo is in), and related
command-line flags (e.g. <code>git rebase --root</code>, <code>git checkout --orphan</code>).</li>
</ul>
<h2 id="the-index">The index<a class="headerlink" href="#the-index" title="Permanent link">&para;</a></h2>
<p>Git's <a href="https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified">"index"</a> has
multiple roles. One role is as a cache of file system information. Jujutsu has
something similar. Unfortunately, Git exposes the index to the user, which makes
the CLI unnecessarily complicated (learning what the different flavors of
<code>git reset</code> do, especially when combined with commits and/or paths, usually
takes a while). Jujutsu, like Mercurial, doesn't make that mistake.</p>
<p>As a Git power-user, you may think that you need the power of the index to
commit only part of the working copy. However, Jujutsu provides commands for
more directly achieving most use cases you're used to using Git's index for. For
example, to create a commit from part of the changes in the working copy, you
might be used to using <code>git add -p; git commit</code>. With Jujutsu, you'd instead
use <code>jj split</code> to split the working-copy commit into two commits. To add more
changes into the parent commit, which you might normally use
<code>git add -p; git commit --amend</code> for, you can instead use <code>jj squash -i</code> to
choose which changes to move into the parent commit, or <code>jj squash &lt;file&gt;</code> to
move a specific file.</p>
<h2 id="command-equivalence-table">Command equivalence table<a class="headerlink" href="#command-equivalence-table" title="Permanent link">&para;</a></h2>
<p>Note that all <code>jj</code> commands can be run on any commit (not just the working-copy
commit), but that's left out of the table to keep it simple. For example,
<code>jj squash/amend -r &lt;revision&gt;</code> will move the diff from that revision into its
parent.</p>
<table>
<thead>
<tr>
<th>Use case</th>
<th>Jujutsu command</th>
<th>Git command</th>
</tr>
</thead>
<tbody>
<tr>
<td>Create a new repo</td>
<td><code>jj git init [--colocate]</code></td>
<td><code>git init</code></td>
</tr>
<tr>
<td>Clone an existing repo</td>
<td><code>jj git clone &lt;source&gt; &lt;destination&gt;</code> (there is no support
for cloning non-Git repos yet)</td>
<td><code>git clone &lt;source&gt; &lt;destination&gt;</code></td>
</tr>
<tr>
<td>Update the local repo with all branches from a remote</td>
<td><code>jj git fetch [--remote &lt;remote&gt;]</code> (there is no
support for fetching into non-Git repos yet)</td>
<td><code>git fetch [&lt;remote&gt;]</code></td>
</tr>
<tr>
<td>Update a remote repo with all branches from the local repo</td>
<td><code>jj git push --all [--remote &lt;remote&gt;]</code> (there is no
support for pushing from non-Git repos yet)</td>
<td><code>git push --all [&lt;remote&gt;]</code></td>
</tr>
<tr>
<td>Update a remote repo with a single branch from the local repo</td>
<td><code>jj git push --branch &lt;branch name&gt;
[--remote &lt;remote&gt;]</code> (there is no support for
pushing from non-Git repos yet)</td>
<td><code>git push &lt;remote&gt; &lt;branch name&gt;</code></td>
</tr>
<tr>
<td>Show summary of current work and repo status</td>
<td><code>jj st</code></td>
<td><code>git status</code></td>
</tr>
<tr>
<td>Show diff of the current change</td>
<td><code>jj diff</code></td>
<td><code>git diff HEAD</code></td>
</tr>
<tr>
<td>Show diff of another change</td>
<td><code>jj diff -r &lt;revision&gt;</code></td>
<td><code>git diff &lt;revision&gt;^ &lt;revision&gt;</code></td>
</tr>
<tr>
<td>Show diff from another change to the current change</td>
<td><code>jj diff --from &lt;revision&gt;</code></td>
<td><code>git diff &lt;revision&gt;</code></td>
</tr>
<tr>
<td>Show diff from change A to change B</td>
<td><code>jj diff --from A --to B</code></td>
<td><code>git diff A B</code></td>
</tr>
<tr>
<tr>
<td>Show description and diff of a change</td>
<td><code>jj show &lt;revision&gt;</code></td>
<td><code>git show &lt;revision&gt;</code></td>
</tr>
<tr>
<td>Add a file to the current change</td>
<td><code>touch filename</code></td>
<td><code>touch filename; git add filename</code></td>
</tr>
<tr>
<td>Remove a file from the current change</td>
<td><code>rm filename</code></td>
<td><code>git rm filename</code></td>
</tr>
<tr>
<td>Modify a file in the current change</td>
<td><code>echo stuff >> filename</code></td>
<td><code>echo stuff >> filename</code></td>
</tr>
<tr>
<td>Finish work on the current change and start a new change</td>
<td><code>jj commit</code></td>
<td><code>git commit -a</code></td>
</tr>
<tr>
<td>See log of ancestors of the current commit</td>
<td><code>jj log -r ::@</code></td>
<td><code>git log --oneline --graph --decorate</code></td>
</tr>
<tr>
<td>See log of all reachable commits</td>
<td><code>jj log -r 'all()'</code> or <code>jj log -r ::</code></td>
<td><code>git log --oneline --graph --decorate --branches</code></td>
</tr>
<tr>
<td>Show log of commits not on the main branch</td>
<td><code>jj log</code></td>
<td>(TODO)</td>
</tr>
<tr>
<td>Search among files versioned in the repository</td>
<td><code>grep foo $(jj files)</code>, or <code>rg --no-require-git foo</code></td>
<td><code>git grep foo</code></td>
</tr>
<tr>
<td>Abandon the current change and start a new change</td>
<td><code>jj abandon</code></td>
<td><code>git reset --hard</code> (cannot be undone)</td>
</tr>
<tr>
<td>Make the current change empty</td>
<td><code>jj restore</code></td>
<td><code>git reset --hard</code> (same as abandoning a change since Git
has no concept of a "change")</td>
</tr>
<tr>
<td>Abandon the parent of the working copy, but keep its diff in the working copy</td>
<td><code>jj move --from @-</code></td>
<td><code>git reset --soft HEAD~</code></td>
</tr>
<tr>
<td>Discard working copy changes in some files</td>
<td><code>jj restore &lt;paths&gt;...</code></td>
<td><code>git restore &lt;paths&gt;...</code> or <code>git checkout HEAD -- &lt;paths&gt;...</code></td>
</tr>
<tr>
<td>Edit description (commit message) of the current change</td>
<td><code>jj describe</code></td>
<td>Not supported</td>
</tr>
<tr>
<td>Edit description (commit message) of the previous change</td>
<td><code>jj describe @-</code></td>
<td><code>git commit --amend</code> (first make sure that nothing is
staged)</td>
</tr>
<tr>
<td>Temporarily put away the current change</td>
<td><code>jj new @-</code> (the old working-copy commit remains as a sibling commit)<br />
(the old working-copy commit X can be restored with <code>jj edit X</code>)</td>
<td><code>git stash</code></td>
</tr>
<tr>
<td>Start working on a new change based on the &lt;main&gt; branch</td>
<td><code>jj new main</code></td>
<td><code>git switch -c topic main</code> or
<code>git checkout -b topic main</code> (may need to stash or commit
first)</td>
</tr>
<tr>
<td>Move branch A onto branch B</td>
<td><code>jj rebase -b A -d B</code></td>
<td><code>git rebase B A</code>
(may need to rebase other descendant branches separately)</td>
</tr>
<tr>
<td>Move change A and its descendants onto change B</td>
<td><code>jj rebase -s A -d B</code></td>
<td><code>git rebase --onto B A^ &lt;some descendant branch&gt;</code>
(may need to rebase other descendant branches separately)</td>
</tr>
<tr>
<td>Reorder changes from A-B-C-D to A-C-B-D</td>
<td><code>jj rebase -r C -d A; rebase -s B -d C</code> (pass change IDs,
not commit IDs, to not have to look up commit ID of rewritten C)</td>
<td><code>git rebase -i A</code></td>
</tr>
<tr>
<td>Move the diff in the current change into the parent change</td>
<td><code>jj squash/amend</code></td>
<td><code>git commit --amend -a</code></td>
</tr>
<tr>
<td>Interactively move part of the diff in the current change into the
parent change</td>
<td><code>jj squash/amend -i</code></td>
<td><code>git add -p; git commit --amend</code></td>
</tr>
<tr>
<td>Move the diff in the working copy into an ancestor</td>
<td><code>jj move --to X</code></td>
<td><code>git commit --fixup=X; git rebase -i --autosquash X^</code></td>
</tr>
<tr>
<td>Interactively move part of the diff in an arbitrary change to another
arbitrary change</td>
<td><code>jj move -i --from X --to Y</code></td>
<td>Not supported</td>
</tr>
<tr>
<td>Interactively split the changes in the working copy in two</td>
<td><code>jj split</code></td>
<td><code>git commit -p</code></td>
</tr>
<tr>
<td>Interactively split an arbitrary change in two</td>
<td><code>jj split -r &lt;revision&gt;</code></td>
<td>Not supported (can be emulated with the "edit" action in
<code>git rebase -i</code>)</td>
</tr>
<tr>
<td>Interactively edit the diff in a given change</td>
<td><code>jj diffedit -r &lt;revision&gt;</code></td>
<td>Not supported (can be emulated with the "edit" action in
<code>git rebase -i</code>)</td>
</tr>
<tr>
<td>Resolve conflicts and continue interrupted operation</td>
<td><code>echo resolved > filename; jj squash/amend</code> (operations
don't get interrupted, so no need to continue)</td>
<td><code>echo resolved > filename; git add filename; git
rebase/merge/cherry-pick --continue</code></td>
</tr>
<tr>
<td>Create a copy of a commit on top of another commit</td>
<td><code>jj duplicate &lt;source&gt;; jj rebase -r &lt;duplicate commit&gt; -d &lt;destination&gt;</code>
(there's no single command for it yet)</td>
<td><code>git co &lt;destination&gt;; git cherry-pick &lt;source&gt;</code></td>
</tr>
<tr>
<td>Find the root of the working copy (or check if in a repo)</td>
<td><code>jj workspace root</code></td>
<td><code>git rev-parse --show-toplevel</code></td>
</tr>
<tr>
<td>List branches</td>
<td><code>jj branch list</code></td>
<td><code>git branch</code></td>
</tr>
<tr>
<td>Create a branch</td>
<td><code>jj branch create &lt;name&gt; -r &lt;revision&gt;</code></td>
<td><code>git branch &lt;name&gt; &lt;revision&gt;</code></td>
</tr>
<tr>
<td>Move a branch forward</td>
<td><code>jj branch set &lt;name&gt; -r &lt;revision&gt;</code></td>
<td><code>git branch -f &lt;name&gt; &lt;revision&gt;</code></td>
</tr>
<tr>
<td>Move a branch backward or sideways</td>
<td><code>jj branch set &lt;name&gt; -r &lt;revision&gt; --allow-backwards</code></td>
<td><code>git branch -f &lt;name&gt; &lt;revision&gt;</code></td>
</tr>
<tr>
<td>Delete a branch</td>
<td><code>jj branch delete &lt;name&gt; </code></td>
<td><code>git branch --delete &lt;name&gt;</code></td>
</tr>
<tr>
<td>See log of operations performed on the repo</td>
<td><code>jj op log</code></td>
<td>Not supported</td>
</tr>
<tr>
<td>Undo an earlier operation</td>
<td><code>jj [op] undo &lt;operation ID&gt;</code>
(<code>jj undo</code> is an alias for <code>jj op undo</code>)
</td>
<td>Not supported</td>
</tr>
<tr>
<td>Create a commit that cancels out a previous commit</td>
<td><code>jj backout -r &lt;revision&gt;</code>
</td>
<td><code>git revert &lt;revision&gt;</code></td>
</tr>
</tbody>
</table>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.c011b7c0.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../assets/javascripts/bundle.7389ff0e.min.js"></script>
</body>
</html>