just playing with tangled
at gvimdiff 222 lines 11 kB view raw view rendered
1# Git compatibility 2 3Jujutsu has two backends for storing commits. One of them uses a regular Git 4repo, which means that you can collaborate with Git users without them even 5knowing that you're not using the `git` CLI. 6 7See `jj help git` for help about the `jj git` family of commands, and e.g. 8`jj help git push` for help about a specific command (use `jj git push -h` for 9briefer help). 10 11 12## Supported features 13 14The following list describes which Git features Jujutsu is compatible with. For 15a comparison with Git, including how workflows are different, see the 16[Git-comparison doc](git-comparison.md). 17 18* **Configuration: Partial.** The only configuration from Git (e.g. in 19 `~/.gitconfig`) that's respected is the following. Feel free to file a bug if 20 you miss any particular configuration options. 21 * The configuration of remotes (`[remote "<name>"]`). Only the names and URLs 22 are respected (refspecs are not respected, and 23 [only the last pushurl](https://github.com/jj-vcs/jj/issues/4889) is 24 respected). 25 * `core.excludesFile` 26* **Authentication: Yes.** With the default authentication scheme, which uses 27 `git` under the hood. With `git.subprocess = false`, only `ssh-agent`, a 28 password-less key (only `~/.ssh/id_rsa`, `~/.ssh/id_ed25519` or 29 `~/.ssh/id_ed25519_sk`), or a `credential.helper` are supported. 30* **Branches: Yes.** You can read more about 31 [how branches work in Jujutsu](bookmarks.md) 32 and [how they interoperate with Git](#branches). 33* **Tags: Partial.** You can check out tagged commits by name (pointed to be 34 either annotated or lightweight tags), but you cannot create new tags. 35* **.gitignore: Yes.** Patterns in `.gitignore` files are supported. So are 36 ignores in `.git/info/exclude` or configured via Git's `core.excludesfile` 37 config. Since working-copy files are snapshotted by every `jj` command, you 38 might need to run `jj file untrack` to exclude newly ignored files from the 39 working-copy commit. It's recommended to set up the ignore patterns earlier. 40 The `.gitignore` support uses a native implementation, so please report a bug 41 if you notice any difference compared to `git`. 42* **.gitattributes: No.** There's [#53](https://github.com/jj-vcs/jj/issues/53) 43 about adding support for at least the `eol` attribute. 44* **Hooks: No.** There's [#405](https://github.com/jj-vcs/jj/issues/405) 45 specifically for providing the checks from https://pre-commit.com. 46* **Merge commits: Yes.** Octopus merges (i.e. with more than 2 parents) are 47 also supported. 48* **Detached HEAD: Yes.** Jujutsu supports anonymous branches, so this is a 49 natural state. 50* **Orphan branch: Yes.** Jujutsu has a virtual root commit that appears as 51 parent of all commits Git would call "root commits". 52* **Staging area: Kind of.** The staging area will be ignored. For example, 53 `jj diff` will show a diff from the Git HEAD to the working copy. There are 54 [ways of fulfilling your use cases without a staging 55 area](https://github.com/jj-vcs/jj/blob/main/docs/git-comparison.md#the-index). 56* **Garbage collection: Yes.** It should be safe to run `git gc` in the Git 57 repo, but it's not tested, so it's probably a good idea to make a backup of 58 the whole workspace first. There's [no garbage collection and repacking of 59 Jujutsu's own data structures yet](https://github.com/jj-vcs/jj/issues/12), 60 however. 61* **Bare repositories: Yes.** You can use `jj git init --git-repo=<path>` to 62 create a repo backed by a bare Git repo. 63* **Submodules: No.** They will not show up in the working copy, but they will 64 not be lost either. 65* **Partial clones: No.** We use the [libgit2](https://libgit2.org/) library, 66 which [doesn't have support for partial clones](https://github.com/libgit2/libgit2/issues/5564). 67* **Shallow clones: Kind of.** Shallow commits all have the virtual root commit as 68 their parent. However, deepening or fully unshallowing a repository is currently not yet 69 supported and will cause issues. 70* **git-worktree: No.** However, there's native support for multiple working 71 copies backed by a single repo. See the `jj workspace` family of commands. 72* **Sparse checkouts: No.** However, there's native support for sparse 73 checkouts. See the `jj sparse` command. 74* **Signed commits: Partial.** 75 So far only [by configuration](https://github.com/jj-vcs/jj/blob/main/docs/config.md#commit-signing), 76 later perhaps [a command](https://github.com/jj-vcs/jj/pull/3142). 77* **Git LFS: No.** ([#80](https://github.com/jj-vcs/jj/issues/80)) 78 79 80## Creating an empty repo 81 82To create an empty repo using the Git backend, use `jj init --git <name>`. Since 83the command creates a Jujutsu repo, it will have a `.jj/` directory. The 84underlying Git repo will be inside of that directory (currently in 85`.jj/repo/store/git/`). 86 87 88## Creating a repo backed by an existing Git repo 89 90To create a Jujutsu repo backed by a Git repo you already have on disk, use 91`jj git init --git-repo=<path to Git repo> <name>`. The repo will work similar 92to a [Git worktree](https://git-scm.com/docs/git-worktree), meaning that the 93working copies files and the record of the working-copy commit will be separate, 94but the commits will be accessible in both repos. Use `jj git import` to update 95the Jujutsu repo with changes made in the Git repo. Use `jj git export` to 96update the Git repo with changes made in the Jujutsu repo. 97 98## Creating a repo by cloning a Git repo 99 100To create a Jujutsu repo from a remote Git URL, use `jj git clone <URL> 101[<destination>]`. For example, `jj git clone 102https://github.com/octocat/Hello-World` will clone GitHub's "Hello-World" repo 103into a directory by the same name. 104 105By default, the remote repository will be named `origin`. You can use 106a name of your choice by adding `--remote <remote name>` to the `jj 107git clone` command. 108 109## Co-located Jujutsu/Git repos 110 111A "co-located" Jujutsu repo is a hybrid Jujutsu/Git repo. These can be created 112if you initialize the Jujutsu repo in an existing Git repo by running `jj git 113init --colocate` or with `jj git clone --colocate`. The Git repo and the Jujutsu 114repo then share the same working copy. Jujutsu will import and export from and 115to the Git repo on every `jj` command automatically. 116 117This mode is very convenient when tools (e.g. build tools) expect a Git repo to 118be present. 119 120It is allowed to mix `jj` and `git` commands in such a repo in any order. 121However, it may be easier to keep track of what is going on if you mostly use 122read-only `git` commands and use `jj` to make changes to the repo. One reason 123for this (see below for more) is that `jj` commands will usually put the git 124repo in a "detached HEAD" state, since in `jj` there is not concept of a 125"currently tracked branch". Before doing mutating Git commands, you may need to 126tell Git what the current branch should be with a `git switch` command. 127 128You can undo the results of mutating `git` commands using `jj undo` and `jj op 129restore`. Inside `jj op log`, changes by `git` will be represented as an "import 130git refs" operation. 131 132There are a few downsides to this mode of operation. Generally, using co-located 133repos may require you to deal with more involved Jujutsu and Git concepts. 134 135* Interleaving `jj` and `git` commands increases the chance of confusing branch 136 conflicts or [conflicted (AKA divergent) change 137 ids](glossary.md#divergent-change). These never lose data, but can be 138 annoying. 139 140 Such interleaving can happen unknowingly. For example, some IDEs can cause 141 it because they automatically run `git fetch` in the background from time to 142 time. 143 144* In co-located repos with a very large number of branches or other refs, `jj` 145 commands can get noticeably slower because of the automatic `jj git import` 146 executed on each command. This can be mitigated by occasionally running `jj util 147 gc` to speed up the import (that command includes packing the Git refs). 148 149* Git tools will have trouble with revisions that contain conflicted files. While 150 `jj` renders these files with conflict markers in the working copy, they are 151 stored in a non-human-readable fashion inside the repo. Git tools will often 152 see this non-human-readable representation. 153 154* When a `jj` branch is conflicted, the position of the branch in the Git repo 155 will disagree with one or more of the conflicted positions. The state of that 156 branch in git will be labeled as though it belongs to a remote named "git", 157 e.g. `branch@git`. 158 159* Jujutsu will ignore Git's staging area. It will not understand merge conflicts 160 as Git represents them, unfinished `git rebase` states, as well as other less 161 common states a Git repository can be in. 162 163* Colocated repositories are less resilient to 164 [concurrency](technical/concurrency.md#syncing-with-rsync-nfs-dropbox-etc) 165 issues if you share the repo using an NFS filesystem or Dropbox. In general, 166 such use of Jujutsu is not currently thoroughly tested. 167 168* There may still be bugs when interleaving mutating `jj` and `git` commands, 169 usually having to do with a branch pointer ending up in the wrong place. We 170 are working on the known ones, and are not aware of any major ones. Please 171 report any new ones you find, or if any of the known bugs are less minor than 172 they appear. 173 174### Converting a repo into a co-located repo 175 176A Jujutsu repo backed by a Git repo has a full Git repo inside, so it is 177technically possible (though not officially supported) to convert it into a 178co-located repo like so: 179 180```bash 181# Ignore the .jj directory in Git 182echo '/*' > .jj/.gitignore 183# Move the Git repo 184mv .jj/repo/store/git .git 185# Tell jj where to find it 186echo -n '../../../.git' > .jj/repo/store/git_target 187# Make the Git repository non-bare and set HEAD 188git config --unset core.bare 189# Convince jj to update .git/HEAD to point to the working-copy commit's parent 190jj new && jj undo 191``` 192 193We may officially support this in the future. If you try this, we would 194appreciate feedback and bug reports. 195 196## Branches 197 198TODO: Describe how branches are mapped 199 200 201## Format mapping details 202 203Paths are assumed to be UTF-8. I have no current plans to support paths with 204other encodings. 205 206Commits created by `jj` have a ref starting with `refs/jj/` to prevent GC. 207 208Commit metadata that cannot be represented in Git commits (such as the Change 209ID and information about conflicts) is stored outside of the Git repo (currently 210in `.jj/store/extra/`). 211 212Commits with conflicts cannot be represented in Git. They appear in the Git 213commit as as root directories called`.jjconflict-base-*/` and 214`.jjconflict-side-*/`. Note that the purpose of this representation is only to 215prevent GC of the relevant trees; the authoritative information is in the 216Git-external storage mentioned in the paragraph above. As long as you use `jj` 217commands to work with them, you won't notice those paths. If, on the other hand, 218you use e.g. `git switch` to check one of them out, you will see those 219directories in your working copy. If you then run e.g. `jj status`, the 220resulting snapshot will contain those directories, making it look like they 221replaced all the other paths in your repo. You will probably want to run 222`jj abandon` to get back to the state with the unresolved conflicts.