jj/v0.10.0/git-compatibility/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

1424 lines
No EOL
37 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-compatibility/">
<link rel="prev" href="../git-comparison/">
<link rel="next" href="../sapling-comparison/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.5.2, mkdocs-material-9.2.5">
<title>Git compatibility - Jujutsu docs</title>
<link rel="stylesheet" href="../assets/stylesheets/main.0e669242.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">
<script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
<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="#git-compatibility" 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 compatibility
</span>
</div>
</div>
</div>
<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>
</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 md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_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_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<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_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_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_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<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_6" checked>
<label class="md-nav__link" for="__nav_6" id="__nav_6_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_6_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Comparisons
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../git-comparison/" class="md-nav__link">
<span class="md-ellipsis">
Git comparison
</span>
</a>
</li>
<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 compatibility
</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 compatibility
</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="#supported-features" class="md-nav__link">
Supported features
</a>
</li>
<li class="md-nav__item">
<a href="#creating-an-empty-repo" class="md-nav__link">
Creating an empty repo
</a>
</li>
<li class="md-nav__item">
<a href="#creating-a-repo-backed-by-an-existing-git-repo" class="md-nav__link">
Creating a repo backed by an existing Git repo
</a>
</li>
<li class="md-nav__item">
<a href="#creating-a-repo-by-cloning-a-git-repo" class="md-nav__link">
Creating a repo by cloning a Git repo
</a>
</li>
<li class="md-nav__item">
<a href="#co-located-jujutsugit-repos" class="md-nav__link">
Co-located Jujutsu/Git repos
</a>
<nav class="md-nav" aria-label="Co-located Jujutsu/Git repos">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#converting-a-repo-into-a-co-located-repo" class="md-nav__link">
Converting a repo into a co-located repo
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#branches" class="md-nav__link">
Branches
</a>
</li>
<li class="md-nav__item">
<a href="#format-mapping-details" class="md-nav__link">
Format mapping details
</a>
</li>
</ul>
</nav>
</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_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_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_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<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_8" >
<label class="md-nav__link" for="__nav_8" id="__nav_8_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_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_8">
<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_9" >
<label class="md-nav__link" for="__nav_9" id="__nav_9_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_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_9">
<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/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="#supported-features" class="md-nav__link">
Supported features
</a>
</li>
<li class="md-nav__item">
<a href="#creating-an-empty-repo" class="md-nav__link">
Creating an empty repo
</a>
</li>
<li class="md-nav__item">
<a href="#creating-a-repo-backed-by-an-existing-git-repo" class="md-nav__link">
Creating a repo backed by an existing Git repo
</a>
</li>
<li class="md-nav__item">
<a href="#creating-a-repo-by-cloning-a-git-repo" class="md-nav__link">
Creating a repo by cloning a Git repo
</a>
</li>
<li class="md-nav__item">
<a href="#co-located-jujutsugit-repos" class="md-nav__link">
Co-located Jujutsu/Git repos
</a>
<nav class="md-nav" aria-label="Co-located Jujutsu/Git repos">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#converting-a-repo-into-a-co-located-repo" class="md-nav__link">
Converting a repo into a co-located repo
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#branches" class="md-nav__link">
Branches
</a>
</li>
<li class="md-nav__item">
<a href="#format-mapping-details" class="md-nav__link">
Format mapping details
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="git-compatibility">Git compatibility<a class="headerlink" href="#git-compatibility" title="Permanent link">&para;</a></h1>
<p>Jujutsu has two backends for storing commits. One of them uses a regular Git
repo, which means that you can collaborate with Git users without them even
knowing that you're not using the <code>git</code> CLI.</p>
<p>See <code>jj help git</code> for help about the <code>jj git</code> family of commands, and e.g.
<code>jj help git push</code> for help about a specific command (use <code>jj git push -h</code> for
briefer help).</p>
<h2 id="supported-features">Supported features<a class="headerlink" href="#supported-features" title="Permanent link">&para;</a></h2>
<p>The following list describes which Git features Jujutsu is compatible with. For
a comparison with Git, including how workflows are different, see the
<a href="../git-comparison/">Git-comparison doc</a>.</p>
<ul>
<li><strong>Configuration: Partial.</strong> The only configuration from Git (e.g. in
<code>~/.gitconfig</code>) that's respected is the following. Feel free to file a bug if
you miss any particular configuration options.</li>
<li>The configuration of remotes (<code>[remote "&lt;name&gt;"]</code>).</li>
<li><code>core.excludesFile</code></li>
<li><strong>Authentication: Partial.</strong> Only <code>ssh-agent</code>, a password-less key (
only <code>~/.ssh/id_rsa</code>, <code>~/.ssh/id_ed25519</code> or <code>~/.ssh/id_ed25519_sk</code>), or
a <code>credential.helper</code>.</li>
<li><strong>Branches: Yes.</strong> You can read more about
<a href="../branches/">how branches work in Jujutsu</a>
and <a href="#branches">how they interoperate with Git</a>.</li>
<li><strong>Tags: Partial.</strong> You can check out tagged commits by name (pointed to be
either annotated or lightweight tags), but you cannot create new tags.</li>
<li><strong>.gitignore: Yes.</strong> Ignores in <code>.gitignore</code> files are supported. So are
ignores in <code>.git/info/exclude</code> or configured via Git's <code>core.excludesfile</code>
config. The <code>.gitignore</code> support uses a native implementation, so please
report a bug if you notice any difference compared to <code>git</code>. </li>
<li><strong>.gitattributes: No.</strong> There's <a href="https://github.com/martinvonz/jj/issues/53">#53</a>
about adding support for at least the <code>eol</code> attribute.</li>
<li><strong>Hooks: No.</strong> There's <a href="https://github.com/martinvonz/jj/issues/405">#405</a>
specifically for providing the checks from https://pre-commit.com.</li>
<li><strong>Merge commits: Yes.</strong> Octopus merges (i.e. with more than 2 parents) are
also supported.</li>
<li><strong>Detached HEAD: Yes.</strong> Jujutsu supports anonymous branches, so this is a
natural state.</li>
<li><strong>Orphan branch: Yes.</strong> Jujutsu has a virtual root commit that appears as
parent of all commits Git would call "root commits".</li>
<li><strong>Staging area: Kind of.</strong> The staging area will be ignored. For example,
<code>jj diff</code> will show a diff from the Git HEAD to the working copy. There are
<a href="https://github.com/martinvonz/jj/blob/main/docs/git-comparison.md#the-index">ways of fulfilling your use cases without a staging
area</a>. </li>
<li><strong>Garbage collection: Yes.</strong> It should be safe to run <code>git gc</code> in the Git
repo, but it's not tested, so it's probably a good idea to make a backup of
the whole workspace first. There's <a href="https://github.com/martinvonz/jj/issues/12">no garbage collection and repacking of
Jujutsu's own data structures yet</a>,
however.</li>
<li><strong>Bare repositories: Yes.</strong> You can use <code>jj init --git-repo=&lt;path&gt;</code> to create
a repo backed by a bare Git repo.</li>
<li><strong>Submodules: No.</strong> They will not show up in the working copy, but they will
not be lost either.</li>
<li><strong>Partial clones: No.</strong> We use the <a href="https://libgit2.org/">libgit2</a> library,
which <a href="https://github.com/libgit2/libgit2/issues/5564">doesn't have support for partial clones</a>.</li>
<li><strong>Shallow clones: No.</strong> We use the <a href="https://libgit2.org/">libgit2</a> library,
which <a href="https://github.com/libgit2/libgit2/issues/3058">doesn't have support for shallow clones</a>.</li>
<li><strong>git-worktree: No.</strong> However, there's native support for multiple working
copies backed by a single repo. See the <code>jj workspace</code> family of commands.</li>
<li><strong>Sparse checkouts: No.</strong> However, there's native support for sparse
checkouts. See the <code>jj sparse</code> command.</li>
<li><strong>Signed commits: No.</strong> (<a href="https://github.com/martinvonz/jj/issues/58">#58</a>)</li>
<li><strong>Git LFS: No.</strong> (<a href="https://github.com/martinvonz/jj/issues/80">#80</a>)</li>
</ul>
<h2 id="creating-an-empty-repo">Creating an empty repo<a class="headerlink" href="#creating-an-empty-repo" title="Permanent link">&para;</a></h2>
<p>To create an empty repo using the Git backend, use <code>jj init --git &lt;name&gt;</code>. Since
the command creates a Jujutsu repo, it will have a <code>.jj/</code> directory. The
underlying Git repo will be inside of that directory (currently in
<code>.jj/repo/store/git/</code>).</p>
<h2 id="creating-a-repo-backed-by-an-existing-git-repo">Creating a repo backed by an existing Git repo<a class="headerlink" href="#creating-a-repo-backed-by-an-existing-git-repo" title="Permanent link">&para;</a></h2>
<p>To create a Jujutsu repo backed by a Git repo you already have on disk, use
<code>jj init --git-repo=&lt;path to Git repo&gt; &lt;name&gt;</code>. The repo will work similar to a
<a href="https://git-scm.com/docs/git-worktree">Git worktree</a>, meaning that the working
copies files and the record of the working-copy commit will be separate, but the
commits will be accessible in both repos. Use <code>jj git import</code> to update the
Jujutsu repo with changes made in the Git repo. Use <code>jj git export</code> to update
the Git repo with changes made in the Jujutsu repo.</p>
<h2 id="creating-a-repo-by-cloning-a-git-repo">Creating a repo by cloning a Git repo<a class="headerlink" href="#creating-a-repo-by-cloning-a-git-repo" title="Permanent link">&para;</a></h2>
<p>To create a Jujutsu repo from a remote Git URL, use <code>jj git clone &lt;URL&gt;
[&lt;destination&gt;]</code>. For example, <code>jj git clone
https://github.com/octocat/Hello-World</code> will clone GitHub's "Hello-World" repo
into a directory by the same name.</p>
<h2 id="co-located-jujutsugit-repos">Co-located Jujutsu/Git repos<a class="headerlink" href="#co-located-jujutsugit-repos" title="Permanent link">&para;</a></h2>
<p>A "co-located" Jujutsu repo is a hybrid Jujutsu/Git repo. These can be created
if you initialize the Jujutsu repo in an existing Git repo by running <code>jj init
--git-repo=.</code> or with <code>jj git clone --colocate</code>. The Git repo and the Jujutsu
repo then share the same working copy. Jujutsu will import and export from and
to the Git repo on every <code>jj</code> command automatically.</p>
<p>This mode is very convenient when tools (e.g. build tools) expect a Git repo to
be present.</p>
<p>It is allowed to mix <code>jj</code> and <code>git</code> commands in such a repo in any order.
However, it may be easier to keep track of what is going on if you mostly use
read-only <code>git</code> commands and use <code>jj</code> to make changes to the repo. One reason
for this (see below for more) is that <code>jj</code> commands will usually put the git
repo in a "detached HEAD" state, since in <code>jj</code> there is not concept of a
"currently tracked branch". Before doing mutating Git commands, you may need to
tell Git what the current branch should be with a <code>git switch</code> command.</p>
<p>You can undo the results of mutating <code>git</code> commands using <code>jj undo</code> and <code>jj op
restore</code>. Inside <code>jj op log</code>, changes by <code>git</code> will be represented as an "import
git refs" operation.</p>
<p>There are a few downsides to this mode of operation. Generally, using co-located
repos may require you to deal with more involved Jujutsu and Git concepts.</p>
<ul>
<li>
<p>Interleaving <code>jj</code> and <code>git</code> commands increases the chance of confusing branch
conflicts or <a href="../glossary/#divergent-change">conflicted (AKA divergent) change
ids</a>. These never lose data, but can be
annoying.</p>
<p>Such interleaving can happen unknowingly. For example, some IDEs can cause
it because they automatically run <code>git fetch</code> in the background from time to
time.</p>
</li>
<li>
<p>In co-located repos with a very large number of branches or other refs, <code>jj</code>
commands can get noticeably slower because of the automatic <code>jj git import</code>
executed on each command. This can be mitigated by occasionally running <code>git
pack-refs --all</code> to speed up the import.</p>
</li>
<li>
<p>Git tools will have trouble with revisions that contain conflicted files. While
<code>jj</code> renders these files with conflict markers in the working copy, they are
stored in a non-human-readable fashion inside the repo. Git tools will often
see this non-human-readable representation.</p>
</li>
<li>
<p>When a <code>jj</code> branch is conflicted, the position of the branch in the Git repo
will disagree with one or more of the conflicted positions. The state of that
branch in git will be labeled as though it belongs to a remote named "git",
e.g. <code>branch@git</code>.</p>
</li>
<li>
<p>Jujutsu will ignore Git's staging area. It will not understand merge conflicts
as Git represents them, unfinished <code>git rebase</code> states, as well as other less
common states a Git repository can be in.</p>
</li>
<li>
<p>Colocated repositories are less resilient to
<a href="../technical/concurrency/#syncing-with-rsync-nfs-dropbox-etc">concurrency</a>
issues if you share the repo using an NFS filesystem or Dropbox. In general,
such use of Jujutsu is not currently thoroughly tested.</p>
</li>
<li>
<p>There may still be bugs when interleaving mutating <code>jj</code> and <code>git</code> commands,
usually having to do with a branch pointer ending up in the wrong place. We
are working on the known ones, and are not aware of any major ones. Please
report any new ones you find, or if any of the known bugs are less minor than
they appear.</p>
</li>
</ul>
<h3 id="converting-a-repo-into-a-co-located-repo">Converting a repo into a co-located repo<a class="headerlink" href="#converting-a-repo-into-a-co-located-repo" title="Permanent link">&para;</a></h3>
<p>A Jujutsu repo backed by a Git repo has a full Git repo inside, so it is
technically possible (though not officially supported) to convert it into a
co-located repo like so:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Move the Git repo</span>
mv<span class="w"> </span>.jj/repo/store/git<span class="w"> </span>.git
<span class="c1"># Tell jj where to find it</span>
<span class="nb">echo</span><span class="w"> </span>-n<span class="w"> </span><span class="s1">&#39;../../../.git&#39;</span><span class="w"> </span>&gt;<span class="w"> </span>.jj/repo/store/git_target
<span class="c1"># Ignore the .jj directory in Git</span>
<span class="nb">echo</span><span class="w"> </span>/.jj/<span class="w"> </span>&gt;<span class="w"> </span>.git/info/exclude
<span class="c1"># Make the Git repository non-bare and set HEAD</span>
git<span class="w"> </span>config<span class="w"> </span>--unset<span class="w"> </span>core.bare
jj<span class="w"> </span>st
</code></pre></div>
<p>We may officially support this in the future. If you try this, we would
appreciate feedback and bug reports.</p>
<h2 id="branches">Branches<a class="headerlink" href="#branches" title="Permanent link">&para;</a></h2>
<p>TODO: Describe how branches are mapped</p>
<h2 id="format-mapping-details">Format mapping details<a class="headerlink" href="#format-mapping-details" title="Permanent link">&para;</a></h2>
<p>Paths are assumed to be UTF-8. I have no current plans to support paths with
other encodings.</p>
<p>Commits created by <code>jj</code> have a ref starting with <code>refs/jj/</code> to prevent GC.</p>
<p>Commit metadata that cannot be represented in Git commits (such as the Change
ID) is stored outside of the Git repo (currently in <code>.jj/store/extra/</code>).</p>
<p>Paths with conflicts cannot be represented in Git. They appear as files with
a <code>.jjconflict</code> suffix in the Git repo. They contain a JSON representation with
information about the conflict. They are not meant to be human-readable.</p>
</article>
</div>
</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.dfff1995.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.78eede0e.min.js"></script>
</body>
</html>