[COMING SOON] Git
Git access
| For | Use |
|---|---|
| Developers | git clone $USER@git.test.NetBSD.org:/git/$REPO |
| Anonymous SSH | git clone anongit@anongit.test.NetBSD.org:/git/$REPO |
| Anonymous HTTPS | git clone https://anongit.test.NetBSD.org/$REPO |
| Browsing | https://gitweb.test.NetBSD.org |
Developers MUST clone from git.test.NetBSD.org in order to push to it. Developers MUST NOT push anything to git.test.NetBSD.org based on cloning or pulling from anongit.test.NetBSD.org.
Repositories
| main | draft | |
|---|---|---|
| NetBSD source | src | src@draft |
| NetBSD X11 source | xsrc | xsrc@draft |
| Packages | pkgsrc | pkgsrc@draft |
| Testing sandbox | testsrc | testsrc@draft |
Main repositories. The main repositories such as src and pkgsrc, without the “@draft” suffix, have only long-term branches and tags.
History rewriting (rebasing and pushing forced updates with
“git push -f”) is forbidden,
branches are never deleted, and—outside the
vendor/* namespace—new branches may only be
created by releng and admins.
Draft repositories. The “@draft” repositories are for work in progress destined for future merge to a long-term branch, which may be created, rebased, rewritten, or deleted by any developer at any time.
A change by developer jrandomdev@NetBSD.org meant for the next
NetBSD 11.x release to fix the veeblefitzer for PR 12345,
for example, should be pushed to
src@draft
branch
“netbsd-11/jrandomdev-pr12345-fixveeblefitzer”.
When releng merges it into
src
branch “netbsd-11” to complete the
pullup, the
draft branch will be deleted.
Git branches in the “@draft” repositories correspond to draft-phase changesets on topics in the Mercurial “@draft” repositories.
Developer workflow
Software prerequisites.
Install
devel/git-base
from pkgsrc.
Create a file ~/.gitconfig with the
following contents to configure what name Git will put on
commits you make:
[user] name = J. Random Developer email = jrandomdev@NetBSD.org
You can alternatively configure Git on a per-repository
basis instead by editing
$REPO/.git/config
instead; see the
git-config(1)
man page for more details.
To start. Clone the Git repository:
$ git clone jrandomdev@git.test.NetBSD.org:/git/src
The initial clone may take a long time, and if interrupted,
Git is unable to automatically save its progress and pick up
where it left off.
An alternative is to start with a shallow clone, and
then—if you need the history—to iteratively
deepen it with “git fetch”:
$ git clone --depth=1 jrandomdev@git.test.NetBSD.org:/git/src $ cd src $ git fetch --deepen=10000 $ git fetch --deepen=20000 $ git fetch --deepen=30000 ... $ git fetch --deepen=300000 $ git fetch --unshallow
Other alternatives are
partial
clones, for which the repository supports the
filters “blob:none” (blobless) and
“tree:0” (treeless).
See
GitHub's blog post on partial/shallow clones
for more information on when to choose which type of partial
or shallow clone.
You can also have multiple working trees sharing the same
repository data, e.g. to work on checkouts of two different
branches at the same time, using
git-worktree(1).
To make and publish changes.
Once you have edited some files in the working tree, such as
“sys/kern/kern_wotsit.c”:
- Record the changes in the staging area:
$ git add sys/kern/kern_wotsit.c
- Create a local commit with the changes in the
staging area and a commit message:
$ git commit
Make sure to cite any relevant problem report with the magic string “PR $CATEGORY/$NUMBER” in the commit message. - Review your changes and the history and what
you're about to push:
$ git show $ git log --graph $ git push --dry-run
- Publish your changes to the central repository:
$ git push
If someone else has already pushed changes since you last updated, you will see a message like this:
$ git push To jrandomdev@git.test.NetBSD.org:/git/src ! [rejected] default -> default (fetch first) error: failed to push some refs to 'jrandomdev@git.test.NetBSD.org:/git/src' hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. If you want to integrate the remote changes, use hint: 'git pull' before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Do not merge or use plain “git
pull”; instead, rebase.
We require a linear history, so you should fetch, rebase your
changes, and retry:
$ git fetch $ git rebase origin/default $ git push
You can also use “git pull --rebase”
instead of “git fetch” and then
“git rebase origin/default”.
Note:
Developers must set
$USER@NetBSD.org
or
$USER@pkgsrc.org
as the
email address for changesets,
by setting “user.email” in the
per-user ~/.gitconfig or the
per-repository
$REPO/.git/config
file.
If you already made a commit but can't push it because it has
the wrong email address, you can fix it with “git
commit --amend --reset-author”.
If you made multiple commits, you can edit them with
“git rebase --interactive”; see the
git-rebase(1)
man page for details.
Using
“git log --graph default origin/default”
may help to identify the rebase parameters.
Note that the equivalent of “cvs
commit” is three steps in git:
1. “git add” to record changes to be
committed in the staging area (even changes to existing files,
not just adding new files), 2. “git
commit” to locally create a
commit object, and then 3. “git
push” to publish it to the central repository.
To track development. From the src directory, fetch new changes from the central repository:
$ git fetch
If you don't have any local commits, you can update your working tree to the latest change:
$ git merge --ff-only origin/default
“git merge --ff-only”, perhaps
confusingly, does not actually create merge commits; it just
advances the current branch in what Git calls a
“fast-forward merge”.
We use (non-fast-forward) merge commits only for vendor
branches.
If you do have local commits, you need to rebase
them—the history is required to be linear:
$ git rebase origin/default
If “git rebase” fails with merge
conflicts, you must resolve them and record the resolution
with “git add”,
“git commit”, and “git
rebase --continue” before proceeding.
You can also “git rebase --abort”
to go back to the way things were before you started rebase
in case you want to start over.
You can also switch the working tree to different commits with
“git checkout” or “git
switch”, or switch the current branch to
different commits with “git reset”.
Beware: using these may leave commits without any
“ref” pointing at them (e.g., a branch or a
tag), which git may then delete at some point.
Git treats refs as precious, but
commits as potential garbage to be
cleaned up periodically.
If you get lost.
Before you follow the
xkcd git procedure,
review the output of these commands, and share them with
developers or admins you're asking for help, as well as the
contents of ~/.gitconfig and
$REPO/.git/config,
and the output of any command you're having trouble with:
$ git status $ git show $ git log --graph --all
As an alternative, you can also use Mercurial instead.
Draft branches for work in progress and pullups
If you are working on a change that is not “ready for commit”, you can push to a draft branch the “@draft” repository where you are free to edit and amend it before it is applied to the main branch.
First, create a remote to track the “@draft” repository:
$ git remote add draft jrandomdev@git.test.NetBSD.org:/git/src@draft
To create a draft branch. Switch to a new local git branch and make some commits on the branch:
$ git switch --create jrandomdev-pr12345-fixveeblefitzer $ ... edit/commit/review ...
When you're ready to share it, push it to the draft remote under the name of the main branch it's meant to be applied to:
$ git push --set-upstream draft jrandomdev-pr12345-fixveeblefitzer:default/jrandomdev-pr12345-fixveeblefitzer
As others review the draft and request changes, you can
amend it and push your updates with “git push
-f”:
$ ... edit/commit --amend/review ... $ git push -f draft jrandomdev-pr12345-fixveeblefitzer
(If you accidentally use “git push
-f” with the main repository instead of the
draft one, it will reject the forced push unless the
“-f” made no difference anyway.)
To get at an existing draft branch. If you want to review a draft branch that another developer has posted, you can fetch it from draft remote and create your own local branch to track it:
$ git fetch draft default/alyssaphacker-pr54321-turboencabulator $ git switch --create alyssaphacker-pr54321-turboencabulator --track draft/default/alyssaphacker-pr54321-turboencabulator
When a draft branch is done. We require the history to be linear, so first rebase the changes onto the main branch:
$ git fetch $ git switch jrandomdev-pr12345-fixveeblefitzer $ git rebase origin/default
If that succeeded with no merge conflicts (and if any applicable tests still pass), then you can merge it into the main branch:
$ git switch default $ git merge --ff-only jrandomdev-pr12345-fixveeblefitzer $ git push origin default
And you can delete the draft branch:
$ git push draft :default/jrandomdev-pr12345-fixveeblefitzer
In the future, we may make it mandatory for all changes to start as draft branches for automatic verification and testing before being merged to the main branch.
To draft a pullup.
If you have a change you want to pull up so that appears in
the next NetBSD 11.x release, use “git
cherry-pick” to apply it onto a draft branch
destined for the “netbsd-11”:
$ git switch --create jrandomdev-pr31415-typofixes $ git cherry-pick 01234abcd $ git push --set-upstream draft jrandomdev-pr31415-typofixes:netbsd-11/jrandomdev-pr31415-typofixes
Then you can can ask releng to pull up the draft branch
“netbsd-11/jrandomdev-pr31415-typofixes”.
