↜ Home

Quick introduction to git/jj

Norbert Pozar

Git is a version control tool that can track changes in files in a given directory (called git repository), save a snapshot of the exact content of the directory at a given time, and share these snapshot and the change history with others (on GitHub etc.)

Setting up GitHub access

Git interacts with GitHub by connecting to github.com using the SSH protocol. We need to set up an SSH key so that GitHub can recognize our computer.

Warning. KAINS-WiFi blocks SSH connection so to connect to github.com you need to connect to another wifi.

Follow the instructions at Generating a new SSH key and adding it to the ssh-agent

On mac, this is the summary of commands to run in the terminal:

  1. create a new key (if you don’t already have one)

    $ ssh-keygen -t ed25519 -C "your_email@example.com"
    • Use the default location (press Enter).

    • It is OK to keep the password empty (press Enter)

  2. add the key to ssh-agent

    1. In the terminal run:

      $ eval "$(ssh-agent -s)"
      $ mkdir ~/.ssh
      $ touch ~/.ssh/config 
    2. Add the following to ~/.ssh/config using text editor (VS Code).

      Host github.com
        AddKeysToAgent yes
        UseKeychain yes
        IdentityFile ~/.ssh/id_ed25519
    3. In terminal run:

      $ ssh-add --apple-use-keychain ~/.ssh/id_ed25519
  3. add the new key to GitHub at GitHub/Settings/SSH Keys

    Click “New SSH Key” and paste the content of ~/.ssh/id_ed25519.pub. You can copy it by running:

    $ pbcopy < ~/.ssh/id_ed25519.pub

    Detailed guide: Adding a new SSH key to your GitHub account

Basic git usage

For a detailed guide, see git Book

Basic usage of git is pretty simple but I have recently starting using jj that makes it even simpler.

jj is a command line tool to interact with a git repository in a easier to understand way.

  1. On mac, install jj using Homebrew:

    $ brew install jj
  2. Set up jj

    1. Set up your name and email so that the correct information is used (each snapshot in git contain author who created it; it shows on github too):

      $ jj config set --user user.name "Your Name"
      $ jj config set --user user.email "your@email"
    2. Set jj log to be the default when running jj:

      $ jj config set --user ui.default-command log

What git does

Most simply, git can be used to create snapshots (called commits) of the state of a directory at a given time. These snapshots can then be shared with others by uploading to GitHub etc.

The snapshots (commits) are created, uploaded to GitHub, and manipulated by git or jj terminal commands.

jj commands (as of jj version 0.35)

  • Initialize a new git repository:

    1. In your project directory, create .gitignore file that lists files that should NOT be tracked by git. These should be all generated files (images, computation data, binary files) since git is really useful only for tracking text files, and generated files can be regenerated from the source files. A file that is once added will stay in the git history forever so if it is a large binary file that changes often and does not need to be tracked it only increase the size of the git repository.

      Example. .gitignore file for a Python project with numpy might look like:

      *.png
      *.jpg
      *.npz
      *.npy
      __pycache__
    2. Initialize git:

      In the project directory, run:

      $ jj git init
  • Check the status of the repository (the program directory):

    $ jj status

    or

    $ jj st

    This shows which files have been added etc.:

    Working copy changes:
    A git-jj.md
    Working copy  (@) : ssqq 7422 (no description set)
    Parent commit (@-): ovrq 0105 (no description set)
  • Describe changes:

    $ jj desc -m "My first change"

    Sets the description of the current changes to My first change. This will be displayed later on GitHub or appear in the log (jj log).

    Example.

    $ jj desc -m "Add git/jj guide"
    Working copy  (@) now at: ssqq d834 Add git/jj guide
    Parent commit (@-)      : ovrq 0105 (no description set)

    You can also just run jj desc without -m. This opens an editor (vi by default so careful: exit by pressing :q) where you can type the message.

  • Upload current state to GitHub:

    1. (Only first time uploading the given project to GitHub)

      Create a new project on GitHub: Create a new repository

      After clicking Create repository git shows some git commands. Since we are using jj, we only need the project URL. It looks like git@github.com:pozar-lab/reponame.git

      To tell jj that this is the location of the GitHub repository, run in terminal in the project directory:

      $ jj git remote add origin git@github.com:pozar-lab/reponame.git
      $ jj bookmark track main@origin
    2. Check that you are happy with the changes:

      $ jj st

      (or jj status)

      If there are any changes that should not be there (usually a file added by mistake), add its name or extension to .gitignore and run jj file untrack filename.

    3. Upload the changes

      $ jj b s main
      $ jj git push

      jj b s main is a shorthand for jj bookmark set main, which marks the current changes with a bookmark main. main is a default branch of the change graph in git that is also the default in GitHub.

      jj git push also starts a new snapshot so that any further changes to files in the directory do not modify the previous snapshot (commit) that you just uploaded to GitHub.

  • Getting new changes from GitHub (that someone else uploaded):

    $ jj git fetch

    See the log of the changes:

    $ jj

    or jj log.

    If you have made some changes in your local copy while some changes were pushed to GitHub, you will see that the graph has two branches. To put your changes on top the changes from GitHub (with bookmark main), you can use

    $ jj rebase -s @ -d main

    Check a more detailed tutorial Steve’s Jujutsu Tutorial/Merging anonymous branches, for example.

  • Finish a snapshot and start editing a new snapshot:

    $ jj new