ok/jj
1
0
Fork 0
forked from mirrors/jj
jj/v0.12.0/design/git-submodules/index.html

1592 lines
No EOL
36 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/v0.12.0/design/git-submodules/">
<link rel="prev" href="../../code-of-conduct/">
<link rel="next" href="../git-submodule-storage/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.4.7">
<title>git-submodules - Jujutsu docs</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.4b4a2bd9.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-submodules" 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-submodules
</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--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">
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="false">
<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">
<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_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--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_9" checked>
<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="true">
<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 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-submodules
</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-submodules
</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="#objective" class="md-nav__link">
Objective
</a>
<nav class="md-nav" aria-label="Objective">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#non-goals" class="md-nav__link">
Non-goals
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#background" class="md-nav__link">
Background
</a>
<nav class="md-nav" aria-label="Background">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#intro-to-git-submodules" class="md-nav__link">
Intro to Git Submodules
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#roadmap" class="md-nav__link">
Roadmap
</a>
<nav class="md-nav" aria-label="Roadmap">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#phase-1-readonly-submodules" class="md-nav__link">
Phase 1: Readonly submodules
</a>
<nav class="md-nav" aria-label="Phase 1: Readonly submodules">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#outcomes" class="md-nav__link">
Outcomes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#phase-2-snapshotting-new-changes" class="md-nav__link">
Phase 2: Snapshotting new changes
</a>
<nav class="md-nav" aria-label="Phase 2: Snapshotting new changes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#outcomes_1" class="md-nav__link">
Outcomes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#phase-3-mergingrebasingconflicts" class="md-nav__link">
Phase 3: Merging/rebasing/conflicts
</a>
<nav class="md-nav" aria-label="Phase 3: Merging/rebasing/conflicts">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#outcomes_2" class="md-nav__link">
Outcomes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#phase-an-ideal-world" class="md-nav__link">
Phase ?: An ideal world
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#design" class="md-nav__link">
Design
</a>
<nav class="md-nav" aria-label="Design">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#guiding-principles" class="md-nav__link">
Guiding principles
</a>
</li>
<li class="md-nav__item">
<a href="#storing-submodules" class="md-nav__link">
Storing submodules
</a>
</li>
<li class="md-nav__item">
<a href="#snapshotting-new-submodule-changes" class="md-nav__link">
Snapshotting new submodule changes
</a>
</li>
<li class="md-nav__item">
<a href="#mergingrebasing-with-submodules" class="md-nav__link">
Merging/rebasing with submodules
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../git-submodule-storage/" class="md-nav__link">
<span class="md-ellipsis">
git-submodule-storage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../run/" class="md-nav__link">
<span class="md-ellipsis">
JJ run
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../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="#objective" class="md-nav__link">
Objective
</a>
<nav class="md-nav" aria-label="Objective">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#non-goals" class="md-nav__link">
Non-goals
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#background" class="md-nav__link">
Background
</a>
<nav class="md-nav" aria-label="Background">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#intro-to-git-submodules" class="md-nav__link">
Intro to Git Submodules
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#roadmap" class="md-nav__link">
Roadmap
</a>
<nav class="md-nav" aria-label="Roadmap">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#phase-1-readonly-submodules" class="md-nav__link">
Phase 1: Readonly submodules
</a>
<nav class="md-nav" aria-label="Phase 1: Readonly submodules">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#outcomes" class="md-nav__link">
Outcomes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#phase-2-snapshotting-new-changes" class="md-nav__link">
Phase 2: Snapshotting new changes
</a>
<nav class="md-nav" aria-label="Phase 2: Snapshotting new changes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#outcomes_1" class="md-nav__link">
Outcomes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#phase-3-mergingrebasingconflicts" class="md-nav__link">
Phase 3: Merging/rebasing/conflicts
</a>
<nav class="md-nav" aria-label="Phase 3: Merging/rebasing/conflicts">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#outcomes_2" class="md-nav__link">
Outcomes
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#phase-an-ideal-world" class="md-nav__link">
Phase ?: An ideal world
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#design" class="md-nav__link">
Design
</a>
<nav class="md-nav" aria-label="Design">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#guiding-principles" class="md-nav__link">
Guiding principles
</a>
</li>
<li class="md-nav__item">
<a href="#storing-submodules" class="md-nav__link">
Storing submodules
</a>
</li>
<li class="md-nav__item">
<a href="#snapshotting-new-submodule-changes" class="md-nav__link">
Snapshotting new submodule changes
</a>
</li>
<li class="md-nav__item">
<a href="#mergingrebasing-with-submodules" class="md-nav__link">
Merging/rebasing with submodules
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="git-submodules">Git submodules<a class="headerlink" href="#git-submodules" title="Permanent link">&para;</a></h1>
<p>This is an aspirational document that describes how jj <em>will</em> support Git
submodules. Readers are assumed to have some familiarity with Git and Git
submodules.</p>
<p>This document is a work in progress; submodules are a big feature, and relevant
details will be filled in incrementally.</p>
<h2 id="objective">Objective<a class="headerlink" href="#objective" title="Permanent link">&para;</a></h2>
<p>This proposal aims to replicate the workflows users are used to with Git
submodules, e.g.:</p>
<ul>
<li>Cloning submodules</li>
<li>Making new submodule commits and updating the superproject</li>
<li>Fetching and pushing updates to the submodule's remote</li>
<li>Viewing submodule history</li>
</ul>
<p>When it is convenient, this proposal will also aim to make submodules easier to
use than Git's implementation.</p>
<h3 id="non-goals">Non-goals<a class="headerlink" href="#non-goals" title="Permanent link">&para;</a></h3>
<ul>
<li>Non-Git 'submodules' (e.g. native jj submodules, other VCSes)</li>
<li>Non-Git backends (e.g. Google internal backend)</li>
<li>Changing how Git submodules are implemented in Git</li>
</ul>
<h2 id="background">Background<a class="headerlink" href="#background" title="Permanent link">&para;</a></h2>
<p>We mainly want to support Git submodules for feature parity, since Git
submodules are a standard feature in Git and are popular enough that we have
received user requests for them. Secondarily (and distantly so), Git submodules
are notoriously difficult to use, so there is an opportunity to improve the UX
over Git's implementation.</p>
<h3 id="intro-to-git-submodules">Intro to Git Submodules<a class="headerlink" href="#intro-to-git-submodules" title="Permanent link">&para;</a></h3>
<p><a href="https://git-scm.com/docs/gitsubmodules">Git submodules</a> are a feature of Git
that allow a repository (submodule) to be embedded inside another repository
(the superproject). Notably, a submodule is a full repository, complete with its
own index, object store and ref store. It can be interacted with like any other
repository, regardless of the superproject.</p>
<p>In a superproject commit, submodule information is captured in two places:</p>
<ul>
<li>
<p>A <code>gitlink</code> entry in the commit's tree, where the value of the <code>gitlink</code> entry
is the submodule commit id. This tells Git what to populate in the working
tree.</p>
</li>
<li>
<p>A top level <code>.gitmodules</code> file. This file is in Git's config syntax and
entries take the form <code>submodule.&lt;submodule-name&gt;.*</code>. These include many
settings about the submodules, but most importantly:</p>
<ul>
<li>
<p><code>submodule&lt;submodule-name&gt;.path</code> contains the path from the root of the tree
to the <code>gitlink</code> being described.</p>
</li>
<li>
<p><code>submodule&lt;submodule-name&gt;.url</code> contains the url to clone the submodule
from.</p>
</li>
</ul>
</li>
</ul>
<p>In the working tree, Git notices the presence of a submodule by the <code>.git</code> entry
(signifying the root of a Git repository working tree). This is either the
submodule's actual Git directory (an "old-form" submodule), or a <code>.git</code> file
pointing to <code>&lt;superproject-git-directory&gt;/modules/&lt;submodule-name&gt;</code>. The latter
is sometimes called the "absorbed form", and is Git's preferred mode of
operation.</p>
<h2 id="roadmap">Roadmap<a class="headerlink" href="#roadmap" title="Permanent link">&para;</a></h2>
<p>Git submodules should be implemented in an order that supports an increasing set
of workflows, with the goal of getting feedback early and often. When support is
incomplete, jj should not crash, but instead provide fallback behavior and warn
the user where needed.</p>
<p>The goal is to land good support for pure Jujutsu repositories, while colocated
repositories will be supported when convenient.</p>
<p>This section should be treated as a set of guidelines, not a strict order of
work.</p>
<h3 id="phase-1-readonly-submodules">Phase 1: Readonly submodules<a class="headerlink" href="#phase-1-readonly-submodules" title="Permanent link">&para;</a></h3>
<p>This includes work that inspects submodule contents but does not create new
objects in the submodule. This requires a way to store submodules in a jj
repository that supports readonly operations.</p>
<h4 id="outcomes">Outcomes<a class="headerlink" href="#outcomes" title="Permanent link">&para;</a></h4>
<ul>
<li>Submodules can be cloned anew</li>
<li>New submodule commits can be fetched</li>
<li>Submodule history and branches can be viewed</li>
<li>Submodule contents are populated in the working copy</li>
<li>Superproject gitlink can be updated to an existing submodule commit</li>
<li>Conflicts in the superproject gitlink can be resolved to an existing submodule
commit</li>
</ul>
<h3 id="phase-2-snapshotting-new-changes">Phase 2: Snapshotting new changes<a class="headerlink" href="#phase-2-snapshotting-new-changes" title="Permanent link">&para;</a></h3>
<p>This allows a user to write new contents to a submodule and its remote.</p>
<h4 id="outcomes_1">Outcomes<a class="headerlink" href="#outcomes_1" title="Permanent link">&para;</a></h4>
<ul>
<li>Changes in the working copy can be recorded in a submodule commit</li>
<li>Submodule branches can be modified</li>
<li>Submodules and their branches can be pushed to their remote</li>
</ul>
<h3 id="phase-3-mergingrebasingconflicts">Phase 3: Merging/rebasing/conflicts<a class="headerlink" href="#phase-3-mergingrebasingconflicts" title="Permanent link">&para;</a></h3>
<p>This allows merging and rebasing of superproject commits in a content-aware way
(in contrast to Git, where only the gitlink commit ids are compared), as well as
workflows that make resolving conflicts easy and sensible.</p>
<p>This can be done in tandem with Phase 2, but will likely require a significant
amount of design work on its own.</p>
<h4 id="outcomes_2">Outcomes<a class="headerlink" href="#outcomes_2" title="Permanent link">&para;</a></h4>
<ul>
<li>Merged/rebased submodules result in merged/rebased working copy content</li>
<li>Merged/rebased working copy content can be committed, possibly by creating
sensible merged/rebased submodule commits</li>
<li>Merge/rebase between submodule and non-submodule gives a sensible result</li>
<li>Merge/rebase between submodule A and submodule B gives a sensible result</li>
</ul>
<h3 id="phase-an-ideal-world">Phase ?: An ideal world<a class="headerlink" href="#phase-an-ideal-world" title="Permanent link">&para;</a></h3>
<p>I.e. outcomes we would like to see if there were no constraints whatsoever.</p>
<ul>
<li>Rewriting submodule commits rewrites descendants correctly and updates
superproject gitlinks.</li>
<li>Submodule conflicts automatically resolve to the 'correct' submodule commits,
e.g. a merge between superproject commits creating a merge of the submodule
commits.</li>
<li>Nested submodules are as easy to work with as non-nested submodules.</li>
<li>The operation log captures changes in the submodule.</li>
</ul>
<h2 id="design">Design<a class="headerlink" href="#design" title="Permanent link">&para;</a></h2>
<h3 id="guiding-principles">Guiding principles<a class="headerlink" href="#guiding-principles" title="Permanent link">&para;</a></h3>
<p>TODO</p>
<h3 id="storing-submodules">Storing submodules<a class="headerlink" href="#storing-submodules" title="Permanent link">&para;</a></h3>
<p>Possible approaches under discussion. See
<a href="../git-submodule-storage/">./git-submodule-storage.md</a>.</p>
<h3 id="snapshotting-new-submodule-changes">Snapshotting new submodule changes<a class="headerlink" href="#snapshotting-new-submodule-changes" title="Permanent link">&para;</a></h3>
<p>TODO</p>
<h3 id="mergingrebasing-with-submodules">Merging/rebasing with submodules<a class="headerlink" href="#mergingrebasing-with-submodules" title="Permanent link">&para;</a></h3>
<p>TODO</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.f886a092.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.aecac24b.min.js"></script>
</body>
</html>