Size: 8439
Comment: flesh out some sections.
|
Size: 8666
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 145: | Line 145: |
Good for you, and this has been done but abandoned again for various reasons ... | Good for you, and this has been done but abandoned again for various reasons: There's no authoritative, complete and stable mapping of svn users to "Name <email>" pairs. Especially for people without access to freefall. Random contributors are more likely to have a conversion using the current parameters. |
Line 147: | Line 147: |
Indeed, and noone is stopping you from adding this as another remote into your current git repository and fetching all | Indeed, and no one is stopping you from adding this as another remote into your current git repository and fetching all |
Introduction
This page describes a working model for using git to develop FreeBSD code in head. Merges to stable branches still have to be done using svn, same goes for adding new files. This is mostly to keep the meta-data stored in our svn tree happy.
That being said, it still can work wonders to have fast access to the complete history, commit offline and be able to rebase patches on top of head.
Also bear in mind that git will not replace Subversion for use in FreeBSD for quite some time to come. It is good for a single "project", but FreeBSD's tree is full of (third party) projects. If you want a bad example of how far this can go look at the Android or Chromium source tree. We don't want that ...
Contents
The repositories
There are three repositories currently in circulation, with different characteristics
- A git-svn clone of head and a couple of stable branches, but with truncated history.
- git://gitorious.org/freebsd/freebsd.git
A git-svn clone of head, with complete history. It's what you get when doing: git svn clone -Thead svn+ssh://svn.freebsd.org/base/
- git://git.freebsd.your.org/freebsd-head
- rsync://repos.freebsd.your.org/freebsd-head.git/
- git://github.com/freebsd/freebsd-head.git
- git://gitorious.org/freebsd/freebsd-head.git
https://code.google.com/p/freebsd-head (busted, don't use)
- A complete conversion of the SVN repo, using svn2git
- git://git.freebsd.your.org/freebsd
- git://github.com/freebsd/freebsd.git
https://code.google.com/p/freebsd (busted, don't use)
Using git-svn to work on the FreeBSD head branch
Quick Start (for non-committers)
See above for some locations where you can clone the freebsd-head variant from, this is what committers can use to push commits into svn without hassle (but see constraints as outlined in the introduction).
$ git clone git://git.freebsd.your.org/freebsd-head $ cd freebsd-head $ hack, hack, hack $ git commit
If you want to run the git-svn incremental updates yourself (the mirrors only update every couple of hours), read about rsync in the next section.
Fast Start (for committers)
While you can use the simple clone as outlined above, it will do you no good when trying to push some of the git commits into subversion. Instead, you need all the git-svn metadata for that to work:
$ mkdir freebsd-head $ rsync -av rsync://repos.freebsd.your.org/freebsd-head.git/.git freebsd-head $ cd freebsd-head && git reset --hard
Now you have a clone of the repository that is used to do the conversion, it will have origin, github, gitorious, and googlecode remote specifications that you could use to pull (but not for pushing), you still need to fix the config. Edit .git/config and change the "svn-remote" section:
[svn-remote "svn"] rewriteRoot = svn+ssh://svn.freebsd.org/base url = file:///data/src/freebsd.svn # if you have a local svn mirror, using the same UUID as the official repo url = svn+ssh://svn.freebsd.org/base # if you are a committer, add username@ if it differs from your local username url = svn://svn.freebsd.org/base # if you just have read-only access fetch = head:refs/remotes/trunk
Choose one of the url methods above and leave the rewriteRoot option as is. Try running git svn rebase, it should update your local repo in a couple of seconds. If it starts to work real hard and produces no output for a minute or so, you have screwed up the rewriteRoot option and should have a look at the .git/config file again.
git svn rebase will rebase your local "master" branch on top of the "remotes/trunk" (after that has been updated with all the new stuff from svn. You can now branch "master" to work on separate features or just stack 2-3 commits on top of master and push them upstream using:
$ git svn dcommit -n # ALWAYS USE -n FIRST, MAKE SURE IT LOOKS LIKE WHAT YOU EXPECT
Then run it without the -n to actually push into svn. Please note that you currently cannot add new files using this method, as git-svn has no concept of svn properties and our repository requires the $FreeBSD$ tag expansion hack, which is stored in an svn property.
Also, you should make a habit of creating new (local) branches for every distinct bug, feature, fix, etc. that you are working on (you can push these branches into github for review or beta-testing, etc.). Never git merge those branches, always use git rebase.
$ git checkout master && git svn rebase # our master is now equal to svn trunk $ git branch -t feature1 $ hack, hack, git commit, hack, git commit # let's switch to bug2, which I was working on earlier, it's slightly stale though $ git checkout bug2 && git rebase master bug2 # bug2 is now at master + whatever commits were in bug2 $ hack, hack, git commit, etc.
Once either feature1 or bug2 is ready to be pushed into svn, you can squash the commits into one, or rearrange them in 2-3 meaningful commits using `git rebase -i`. Read up on the advanced features of git on the web ...
Things to keep in mind
Never git merge branches, unless you know what you're doing.
Always git rebase your work on top of master, then git svn dcommit can push the top commits to svn.
Always double-check with git svn dcommit -n to see what would happen.
While you can use git add for new files just fine, you won't be able to push those upstream, you can however use the patch, apply it to some subversion checkout and do the commit there. This is a shortcoming of our very own Subversion hacks, but hey, it's better than nothing!
While git-svn now allows you to set svn:mergeinfo when committing, this is so fragile that the FreeBSD projects discourages its use. Please use svn(1) for merging, sorry.
Using git to base your own work on (this is for vendors)
This is for non-FreeBSD committers that might want to have access to more history than the head branch, or that want to base their work on some stable branches. Tracking FreeBSD thus, git might ease the work of, e.g., porting custom patches from stable/8 to stable/9 or cherry-pick single commits from head into stable/8. There are some tricks to show commits that are in one branch, but not the other, purely based on the introduced diff. This is useless for "MFCs" from head to stable where multiple SVN revisions are merged at once. But it might be useful still (TODO(uqs): research the necessary commands).
Getting started
Clone the full repository.
$ git clone git://git.freebsd.your.org/freebsd $ git checkout -b vendor_foo stable/9 # branch stable/9 into vendor_foo $ hack, commit, hack, etc.
To bring recent upstream commits into your local branch, you can git fetch; git merge stable/9, which will get the newest upstream commits and merge stable/9 into vendor_foo. The merge can be aborted any time and you can rewind the vendor_foo branch to any point in time.
Advanced merge capabilities
WIP.
FAQ
- I want authornames!
Good for you, and this has been done but abandoned again for various reasons: There's no authoritative, complete and stable mapping of svn users to "Name <email>" pairs. Especially for people without access to freefall. Random contributors are more likely to have a conversion using the current parameters.
http://git.freebsd.your.org/cgit/freebsd/ is better, because it contains all branches!
- Indeed, and no one is stopping you from adding this as another remote into your current git repository and fetching all those branches. Since you can not/should not use git-svn to merge changes into stable/*, those branches have been left out of the development repository deliberately.
- Why the full history (of head) and not only since day X
- It would make the history incompatible with other people's repository and the space savings are simply not worth the hassle. As of Aug/2011, all revisions in head make up 570MB vs. 164MB for history since r225000.
Further Reading
It is *really* recommended, that you read Git for computer scientists and skim GitTalkDevSummit, although parts of it are outdated.
It really helps to understand the data structure of a git commit, because then you know how merging/rebasing works and can fix snafus easily.