just playing with tangled
1# Using Jujutsu with GitHub and GitLab Projects
2
3This guide assumes a basic understanding of either Git or Mercurial.
4
5## Set up an SSH key
6
7As of December 2022 it's recommended to set up an SSH key to work with Github
8projects. See [GitHub's Tutorial][gh]. This restriction may be lifted in the
9future, see [issue #469][http-auth] for more information and progress on
10authenticated http.
11
12## Basic workflow
13
14The simplest way to start with Jujutsu, is creating a stack of commits, before
15creating any branch.
16
17```shell script
18# Start a new commit off of `main`
19$ jj new main
20# Refactor some files, then add a description and start a new commit
21$ jj commit -m 'refactor(foo): restructure foo()'
22# Add a feature, then add a description and start a new commit
23$ jj commit -m 'feat(bar): add support for bar'
24# Create a branch so we can push it to GitHub
25$ jj branch create bar -r @-
26# Push the branch to GitHub (pushes only `bar`)
27$ jj git push
28```
29
30While it's possible to create a branch and commit on top of it in a Git like
31manner, it's not recommended, as no further commits will be placed on the
32branch.
33
34## Updating the repository.
35
36As of December 2022, Jujutsu has no equivalent to a `git pull` command. Until
37such a command is added, you need to use `jj git fetch` followed by a
38`jj rebase -d $main_branch` to update your changes.
39
40## Working in a Git co-located repository
41
42After doing `jj init --git-repo=.`, git will be in
43a [detached HEAD state][detached], which is unusual, as git mainly works with
44branches. In a co-located repository, `jj` isn't the source of truth. But
45Jujutsu allows an incremental migration, as `jj commit` updates the HEAD of the
46git repository.
47
48```shell script
49$ nvim docs/tutorial.md
50$ # Do some more work.
51$ jj commit -m "Update tutorial"
52$ jj branch create doc-update
53$ # Move the previous revision to doc-update.
54$ jj branch set doc-update -r @-
55$ jj git push
56```
57
58## Working in a Jujutsu repository
59
60In a Jujutsu repository, the workflow is simplified. If there's no need for
61explicitly named branches, you just can generate one for a change. As Jujutsu is
62able to create a branch for a revision.
63
64```shell script
65$ # Do your work
66$ jj commit
67$ # Jujutsu automatically creates a branch
68$ jj git push --change $revision
69```
70
71## Addressing review comments
72
73There are two workflows for addressing review comments, depending on your
74project's preference. Many projects prefer that you address comments by adding
75commits to your branch[^1]. Some projects (such as Jujutsu and LLVM) instead
76prefer that you keep your commits clean by rewriting them and then
77force-pushing[^2].
78
79### Adding new commits
80
81If your project prefers that you address review comments by adding commits on
82top, you can do that by doing something like this:
83
84```shell script
85$ # Create a new commit on top of the `your-feature` branch from above.
86$ jj new your-feature
87$ # Address the comments, by updating the code
88$ jj diff
89$ # Give the fix a description and create a new working-copy on top.
90$ jj commit -m 'address pr comments'
91$ # Update the branch to point to the new commit.
92$ jj branch set your-feature -r @-
93$ # Push it to your remote
94$ jj git push.
95```
96
97### Rewriting commits
98
99If your project prefers that you keep commits clean, you can do that by doing
100something like this:
101
102```shell script
103$ # Create a new commit on top of the second-to-last commit in `your-feature`,
104$ # as reviews requested a fix there.
105$ jj new your-feature-
106$ # Address the comments by updating the code
107$ # Review the changes
108$ jj diff
109$ # Squash the changes into the parent commit
110$ jj squash
111$ # Push the updated branch to the remote. Jujutsu automatically makes it a force push
112$ jj git push --branch your-feature
113```
114
115## Using GitHub CLI
116
117GitHub CLI will have trouble finding the proper git repository path in jj repos
118that aren't [co-located](./git-compatibility.md#co-located-jujutsugit-repos)
119(see [issue #1008]). You can configure the `$GIT_DIR` environment variable to
120point it to the right path:
121
122```shell
123$ GIT_DIR=.jj/repo/store/git gh issue list
124```
125
126You can make that automatic by installing [direnv](https://direnv.net) and
127defining hooks in a .envrc file in the repository root to configure `$GIT_DIR`.
128Just add this line into .envrc:
129
130```shell
131export GIT_DIR=$PWD/.jj/repo/store/git
132```
133
134and run `direnv allow` to approve it for direnv to run. Then GitHub CLI will
135work automatically even in repos that aren't co-located so you can execute
136commands like `gh issue list` normally.
137
138[issue #1008]: https://github.com/martinvonz/jj/issues/1008
139
140## Useful Revsets
141
142Log all revisions across all local branches, which aren't on the main branch nor
143on any remote
144`jj log -r 'branches() & ~(main | remote_branches())'`
145Log all revisions which you authored, across all branches which aren't on any
146remote
147`jj log -r 'author(your@email.com) & branches() & ~remote_branches()'`
148Log all remote branches, which you authored or committed to
149`jj log -r 'remote_branches() & (committer(your@email.com) | author(your@email.com))'`
150Log all descendants of the current working copy, which aren't on a remote
151`jj log -r '::@ & ~remote_branches()'`
152
153## Merge conflicts
154
155For a detailed overview, how Jujutsu handles conflicts, revisit
156the [tutorial][tut].
157
158[^1]: This is a GitHub Style review, as GitHub currently only is able to compare
159branches.
160[^2]: If you're wondering why we prefer clean commits in this project, see
161e.g.[this blog post][stacked]
162
163[detached]: https://git-scm.com/docs/git-checkout#_detached_head
164
165[gh]: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
166
167[http-auth]: https://github.com/martinvonz/jj/issues/469
168
169[tut]: tutorial.md#Conflicts
170
171[stacked]: https://jg.gg/2018/09/29/stacked-diffs-versus-pull-requests/
172
173## Using several remotes
174
175It is common to use several remotes when contributing to a shared repository.
176For example,
177"upstream" can designate the remote where the changes will be merged through a
178pull-request while "origin" is your private fork of the project. In this case,
179you might want to
180`jj git fetch` from "upstream" and to `jj git push` to "origin".
181
182You can configure the default remotes to fetch from and push to in your
183configuration file
184(for example `.jj/repo/config.toml`):
185
186```toml
187[git]
188fetch = "upstream"
189push = "origin"
190```
191
192The default for both `git.fetch` and `git.push` is "origin".