just playing with tangled
at ig/vimdiffwarn 153 lines 5.5 kB view raw view rendered
1# Git submodules 2 3This is an aspirational document that describes how jj _will_ support Git 4submodules. Readers are assumed to have some familiarity with Git and Git 5submodules. 6 7This document is a work in progress; submodules are a big feature, and relevant 8details will be filled in incrementally. 9 10## Objective 11 12This proposal aims to replicate the workflows users are used to with Git 13submodules, e.g.: 14 15- Cloning submodules 16- Making new submodule commits and updating the superproject 17- Fetching and pushing updates to the submodule's remote 18- Viewing submodule history 19 20When it is convenient, this proposal will also aim to make submodules easier to 21use than Git's implementation. 22 23### Non-goals 24 25- Non-Git 'submodules' (e.g. native jj submodules, other VCSes) 26- Non-Git backends (e.g. Google internal backend) 27- Changing how Git submodules are implemented in Git 28 29## Background 30 31We mainly want to support Git submodules for feature parity, since Git 32submodules are a standard feature in Git and are popular enough that we have 33received user requests for them. Secondarily (and distantly so), Git submodules 34are notoriously difficult to use, so there is an opportunity to improve the UX 35over Git's implementation. 36 37### Intro to Git Submodules 38 39[Git submodules](https://git-scm.com/docs/gitsubmodules) are a feature of Git 40that allow a repository (submodule) to be embedded inside another repository 41(the superproject). Notably, a submodule is a full repository, complete with its 42own index, object store and ref store. It can be interacted with like any other 43repository, regardless of the superproject. 44 45In a superproject commit, submodule information is captured in two places: 46 47- A `gitlink` entry in the commit's tree, where the value of the `gitlink` entry 48 is the submodule commit id. This tells Git what to populate in the working 49 tree. 50 51- A top level `.gitmodules` file. This file is in Git's config syntax and 52 entries take the form `submodule.<submodule-name>.*`. These include many 53 settings about the submodules, but most importantly: 54 55 - `submodule<submodule-name>.path` contains the path from the root of the tree 56 to the `gitlink` being described. 57 58 - `submodule<submodule-name>.url` contains the url to clone the submodule 59 from. 60 61In the working tree, Git notices the presence of a submodule by the `.git` entry 62(signifying the root of a Git repository working tree). This is either the 63submodule's actual Git directory (an "old-form" submodule), or a `.git` file 64pointing to `<superproject-git-directory>/modules/<submodule-name>`. The latter 65is sometimes called the "absorbed form", and is Git's preferred mode of 66operation. 67 68## Roadmap 69 70Git submodules should be implemented in an order that supports an increasing set 71of workflows, with the goal of getting feedback early and often. When support is 72incomplete, jj should not crash, but instead provide fallback behavior and warn 73the user where needed. 74 75The goal is to land good support for pure Jujutsu repositories, while colocated 76repositories will be supported when convenient. 77 78This section should be treated as a set of guidelines, not a strict order of 79work. 80 81### Phase 1: Readonly submodules 82 83This includes work that inspects submodule contents but does not create new 84objects in the submodule. This requires a way to store submodules in a jj 85repository that supports readonly operations. 86 87#### Outcomes 88 89- Submodules can be cloned anew 90- New submodule commits can be fetched 91- Submodule history and branches can be viewed 92- Submodule contents are populated in the working copy 93- Superproject gitlink can be updated to an existing submodule commit 94- Conflicts in the superproject gitlink can be resolved to an existing submodule 95 commit 96 97### Phase 2: Snapshotting new changes 98 99This allows a user to write new contents to a submodule and its remote. 100 101#### Outcomes 102 103- Changes in the working copy can be recorded in a submodule commit 104- Submodule branches can be modified 105- Submodules and their branches can be pushed to their remote 106 107### Phase 3: Merging/rebasing/conflicts 108 109This allows merging and rebasing of superproject commits in a content-aware way 110(in contrast to Git, where only the gitlink commit ids are compared), as well as 111workflows that make resolving conflicts easy and sensible. 112 113This can be done in tandem with Phase 2, but will likely require a significant 114amount of design work on its own. 115 116#### Outcomes 117 118- Merged/rebased submodules result in merged/rebased working copy content 119- Merged/rebased working copy content can be committed, possibly by creating 120 sensible merged/rebased submodule commits 121- Merge/rebase between submodule and non-submodule gives a sensible result 122- Merge/rebase between submodule A and submodule B gives a sensible result 123 124### Phase ?: An ideal world 125 126I.e. outcomes we would like to see if there were no constraints whatsoever. 127 128- Rewriting submodule commits rewrites descendants correctly and updates 129 superproject gitlinks. 130- Submodule conflicts automatically resolve to the 'correct' submodule commits, 131 e.g. a merge between superproject commits creating a merge of the submodule 132 commits. 133- Nested submodules are as easy to work with as non-nested submodules. 134- The operation log captures changes in the submodule. 135 136## Design 137 138### Guiding principles 139 140TODO 141 142### Storing submodules 143 144Possible approaches under discussion. See 145[./git-submodule-storage.md](./git-submodule-storage.md). 146 147### Snapshotting new submodule changes 148 149TODO 150 151### Merging/rebasing with submodules 152 153TODO