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".