Adrian's git notes

Much earlier notes - back circa 2015

here I use upstream as freebsd's repo, and origin as my github fork

stuff with arc diff (and I need to flesh this out some more)

2025/2026 workflow

Yes, I use the freebsd github mirror as a way to backup/rendezvous between multiple devices and publish what work I'm doing. You can adapt these to use gitlab, codeberg, etc by substituting the hostname. You can also just skip the "origin" and "upstream" bit by using a local freebsd-src git clone from gitrepo.freebsd.org and just use origin for everything.

Top level notes

Create github clone

 $ cd ~
 $ mkdir git
 $ cd git
 $ git clone --no-checkout git@github.com:yourname/freebsd-src

$ cd ~/git/freebsd-src.git
$ git remote add upstream git@gitrepo.freebsd.org/src.git

$ cd ~
$ mkdir work
$ cd ~/git/freebsd-src.git
$ git worktree add ~/work/freebsd-src-main origin/main
$ git worktree add ~/work/freebsd-src-stable-15 origin/stable/15

Configure your git author details before you start committing code.

$ git config --global user.name "Your name here"
$ git config --global user.email "your@email.here"

* Next, you'll want to install the pre-commit hooks / templates. Each repo (docs, src, ports) has

Syncing repositories into your local repository

git fetch will work from any worktree branch. I recommend doing a sync instead of pull into the branch you're working from in case you mess that up.

$ cd ~/work/freebsd-src-main
$ git fetch --all

origin versus upstream

In this setup "origin" is tracking github.com/<username>/freebsd-src, and "upstream" is tracking upstream FreeBSD git. You keep them in sync with upstream by doing the above git fetch. However, once you've fork'ed from the github.com/freebsd/freebsd-src repository, it won't "auto update" its branches. You're responsible for doing that!

There's a few tricks to make this easy.

I'll cover more of this in the following sections.

Working on branches

The big first step is - don't work on the upstream branch names. You always want to create your own branches. For example, I will create a branch off of upstream/main for my own work and then push the branch and its current HEAD pointer to "origin" so I can clone it on other machines.

$ cd ~/work/freebsd-src-main
$ git checkout -b ahc_20260101_laptop_main upstream/main
$ git push origin @

Then you can just hack hack hack, git commit, etc.

When you're ready to push your changes back up:

$ git push origin @

Note that this hasn't yet covered rebase / updates. I'll cover that soon.

Updating your branch to another point along upstream

Every so often I'll want to go and update my work against upstream. Now here's where it gets fun.

You CAN just rebase your branch, but if you do that, you may (a) end up in "rebase hell" with conflicts, missing diffs, etc, and (b) feel like you can't recover things without just nuking and repaving your work directory and branch.

But remember, branches in git are cheap. Super cheap. They're just labels on commit hashes. If you create a separate branch and rebase THAT branch:

If you want to just rebase your current branch:

# Stash any working changes first
$ git stash
# push the current state to origin just in case
$ git push origin @
# make sure you've updated
$ git fetch --all
# interactive rebase against upstream (in this case "main", but choose your branch)
$ git rebase -i upstream/main
# follow the prompts to include, exclude, fold in, etc

I won't go into the details of what life is like with git rebase; I recommend reading up on the git rebase workflow. I will however call out "git rebase --abort". If you get stuck, use the abort and re-think what you're doing.

If you want to create a branch and then rebase THAT:

# Same as before
$ git stash
$ git push origin @
$ git fetch --all
# Create new branch based on current branch
$ git checkout -b new_branch_name_here
# Rebase this branch against main
$ git rebase -i upstream/main
# follow the rebase prompts

Once you're done and happy, you can rename the branch by deleting the old branch and renaming the current branch.

# Delete the old branch
$ git branch -D oldbranch
# Rename the current branch to the old branch
$ git branch -m oldbranch

Now, your local branch and origin branch differ, and since it's a rebase, the commit hashes / tree is different. Even the ancestor branch commit may be different! So, if you're absolutely certain your current local branch is good, you force push it to "origin".

$ git push --force origin @

This pushes the commits up and resets the branch HEAD pointer in "origin".

Creating a FreeBSD review (for src)

Please note this is a very src oriented workflow. doc and ports don't necessarily use the same workflow (even though honestly I wish they would just unify on it, but that's a different story.)

My workflow in 2026 is something like this:

I'm a committer though, so I'm getting to do both sides of the review pipeline - creating/managing a review, and landing it into the tree.

Now, there are a few gotchas using reviews.freebsd.org.

* Remember that when you edit a commit it creates a brand new commit, and the previous commit/hash will exist in your

* the "git arc" tool looks up your reviews.freebsd.org review number (Dxxxxxx) by matching on the /subject line/ of the

* Also this means you absolutely should create unique subject lines for your reviews otherwise the "git arc" matching

Setting up for using reviews.freebsd.org

Ok, here's where this gets a little easier. In the past you had to use phabricator/arcanist tools directly. And, well, they kind of sucked for that with git. However, Mark Johnson has written a wonderful integration which makes life much, much easier. It's called "git-arc".

First - install devel/arcanist. You'll need this to push stuff into reviews.freebsd.org.

Next - read the phabricator page for how to setup an account on reviews.freebsd.org and then get an API key for the device you're using so it can push reviews up - https://wiki.freebsd.org/Phabricator .

Now, read "man git-arc". Next, you'll need to install it. It's in freebsd-src/tools/tools/git/. cd into that directory, then do "make" and "make install". Yes, it's not a package for some reason.

Once this is all done you should be ready for making, changing, approving and pushing reviews.

git-arc documentation

"man git-arc" lists all the fun things you can do with it for single and branch commit/review management. I'm going to document a few here.

Creating a review from a single commit

This is the easiest to start with.

# Stash any pending changes before you create a commit
$ git stash
# Create a review with the current commit in this tree
$ git arc create HEAD
# This will create a review and give you a review URL. Copy that somewhere.
# Add it to your commit message
$ git commit --amend
# In the commit message you will need to add it as part of the commit body, ie

Differential Review: https://reviews.freebsd.org/Dxxxxxx

# Then you can push your modified commit back to your "origin"
$ git push origin HEAD     # note you may need to use --force if you pushed it already and you changed the commit message
# Restore any local changes you had
$ git stash pop

Now, go to the commit URL itself. There's a few things you'll want to set.

Finally, go tell someone about your commit.

Updating your single commit review

If/when you get feedback, you'll want to make some changes to your single commit and push it back into the review.

# You need a clean work dir for this
$ git stash
# Update the commit based on your changes
$ git arc update HEAD
# Restore your work dir
$ git stash pop

When it's time to push an existing commit to upstream

This is a gap on my side, I need to actually use "git arc stage" instead of manually updating the commit message and then forgetting to update the commit message. "git arc stage" will pull down the reviewers, the differential revision URL, etc and update it via a cherry-pick.

In any case, I do this manually so I can build test it.

# go into my 'main' checkout (ie, upstream/main, no local changes)
$ cd ~/git/freebsd-src-main
# update it to the latest 'main' pull
$ git pull --rebase upstream/main
# cherry-pick in my diff to land
$ git cherry-pick <commit hash>
# re-edit it to make any last minute changes to the commit message / reviewers / etc
$ git commit --amend
# actually DO a build time test here against -HEAD!
#
# Then push it upstream
$ git push upstream @

Obviously a bunch can go wrong here, but as a freebsd committer, we get to figure that out.

When it's time to push an REVIEW to upstream

When taking an external diff in to push upstream, we need to pull it down, build test it and then push it up into upstream.

This is where it's super important that as a submitter, you actually submitted code into the reviews system using a git repo rather than just a bare diff. If your diff doesn't cleanly apply (eg it's against an old tree, or you've substituted tabs for spaces locally) then the "git arc fetch -c" step will fail and it won't be a seamless experience for us.

# go into my 'main' checkout (ie, upstream/main, no local changes)
$ cd ~/git/freebsd-src-main
# update it to the latest 'main' pull
$ git pull --rebase upstream/main
# fetch in the diff to land
$ git arc fetch -c Dxxxxxx
# Actually build time test it here!
#
# Then push it upstream
$ git push upstream @

AdrianChadd/GitNotes (last edited 2026-02-05T16:39:14+0000 by AdrianChadd)