Git Repositories on oss.oracle.com
Some source repositories on oss.oracle.com are moving from Subversion to Git. Git is the distributed source control management (SCM) system originally written by Linus Torvalds and used for the Linux Kernel.
Benefits
Modern distributed SCMs like Git and Mercurial provide a host of advantages over centralized systems like Subversion. Each user gets a full local copy of the repository. The user can view history, make changes, commit changes, and basically do every conceivable task, all on their own machine. They only need network access when they wish to communicate their changes to others. This includes temporary branches that are never seen outside of the user's machine, as well as the ability to store work as commited changes, yet never make it public if the approach is abandoned.
Once the initial learning curve is overcome - and it's not large - it often is hard to go back to a centralized system.
Learning Git
If you are not familiar with Git, there is excellent documentation. Start with the tutorial, then read Everyday Git. That will give you a good set of basics.
Garzik On Git is a tutorial for using Git with the Linux Kernel
Zack Rusin has written a fantastic cheat sheet
Where are the Repositories?
On oss.oracle.com, the git repositories are viewable via the web at http://oss.oracle.com/git/. Feel free to poke around. They can be cloned via HTTP and via the Git native protocol. Take the repository name and add it to http://oss.oracle.com/git/ or git://oss.oracle.com/git. For example, the ocfs2-tools.git repository can be cloned with either:
$ git clone git://oss.oracle.com/git/ocfs2-tools.git localdir
or:
$ git clone http://oss.oracle.com/git/ocfs2-tools.git localdir
In general, use the Git native protocol when you can.
If you are new to Git and don't know what "cloning" is, the Git documentation listed above is a great place to start!
Repository Types
There are two types of repositories on oss.oracle.com: repositories with one maintainer, and repositories with multiple maintainers.
Single Maintainer Repositories
These repositories follow the general development style of the Linux Kernel. All changes are sent to the maintainer, and the maintainer is responsible for integrating them and putting them up on oss.oracle.com. The repositories under a user's path (eg, http://oss.oracle.com/git/user/project.git) are generally of this style.
We won't discuss this type of repository any further. Most oss.oracle.com projects have multiple maintainers.
Multiple Maintainer Repositories
Regular oss.oracle.com projects have multiple maintainers. That is, there are multiple people with permission to upload changes. Note that I said upload changes, not commit changes. Git is distributed, and anyone can commit changes to their local repositories. Only the maintainers can upload changes from their repositories to the master repository on oss.oracle.com.
Working on an oss.oracle.com Project
If you are just someone who wants to contribute, feel free to hack as any Git user would. Clone the repository to your local machine, create a branch, hack and commit away, and when you want to submit the change, use git format-patch to send emails to the development mailing list. The usual stuff.
A Few Recommendations
Tell Git Your Name and Email Address
Before you commit to a Git repository, make sure you have told Git who you are. This is important, as any changes will have your name and email as the author and committer information. You want this to be your real name and correct email address.
$ git config --global user.name "Bob User" $ git config --global user.email "bobg@my.site.com"
This will store your name and email address in your personal git configuration (~/.gitconfig). All git operations use this global (hence --global) configuration file.
Sign-off Your Commits
Always use the -s option to git commit. This will attach a Signed-off-by: line to your commit message, using your name and email address. All changes to oss.oracle.com projects require a sign-off from the author and anyone along the path to the central repository.
Work on a Branch
We recommend that you never make changes to the master branch. If you always make changes on a separate branch, you always know that the master branch is representative of the last time you pulled from oss.oracle.com.
$ git clone git://oss.oracle.com/git/project.git localdir $ cd localdir $ git branch workingbranch master $ git checkout workingbranch $ git branch master * workingbranch $ vi foo.c $ git commit -s -a
Now you can easily see your changes from master or create a set of patches.
$ git diff master workingbranch $ git format-patch master workingbranch
If changes have been made to the central repository, you can easily grab them. Make sure your working tree is clean (that is, git status is empty of changes), and then:
$ git branch master * workingbranch $ git checkout master $ git pull ... updates master ... $ git checkout workingbranch
You are back on your working branch, but master is now representative of the oss.oracle.com central repository.
For Maintainers
Maintainers of a project are responsible for uploading (pushing) changes to the central repository. Details on this process are on the /ForMaintainers page.
Some Tips
Here are a few tips on Git usage that may be helpful for contributors and maintainers alike.
Using git send-email
You've written a patch, and you want to send it to the -devel mailing list for review. Perhaps it's a series of commits. Git provides a relatively convenient way to do this. I say "relatively," because it doesn't quite work right with the defaults!
First, you need to actually get the send-email command. These days, it usually is part of the git-email package, not the git-core package. Make sure you have the correct package.
For the sake of this example, I'm going to assume that you have a change or set of changes on the branch pending, and that you are working against the project <project>.
The general process is to use git format-patch to generate a patch for each commit you wrote, and then git send-email to send them as a single email thread. Pay attention to the options I use, at least until you read the documentation and understand why I use them. You need to be inside the repository for these commands to work.
To send a single patch (one commit):
$ git branch master * pending $ git format-patch -C master..pending $ git send-email --suppress-from --to <project>-devel@oss.oracle.com 0001-<patchname>.patch
We use the -C option to git format-patch because we are sending Git patches - Renames are nice! We do not use the -k option, because this is an email, and we want [PATCH] in the Subject: header. git format-patch will create a patch with the name 0001-<patchname>.patch, where <patchname> is the first line of the commit message.
We use --supress-from to prevent mailing yourself. By default, git send-email will add the patch author and any Signed-off-by: email addresses to the Cc: list. We suppress the author in this example. You can suppress the sign-off address with --no-signed-off-by-cc
Once again, this is for a single patch. A patch series needs a couple more options.
To send a patch series (multiple commits):
$ git branch master * pending $ git format-patch -C -n master..pending $ git send-email --compose --no-chain-reply-to --suppress-from --to <project>-devel@oss.oracle.com 00*.patch
We still use the -C option to git format-patch, but we also add the -n option. This creates the [PATCH n/m] style Subject: header. git format-patch will create one patch per commit, named sequentially from 0001-<patchname>.patch Each patch will have <patchname> created from the first line of its commit message.
First, we have added the --compose option. git send-email will ask you to compose an introductory email. This introduction will be sent first and will start an email thread containing the patch series. When you are asked for a subject, you probably want to start it with [PATCH 0/m], as git send-email does not do that for you. Once you have written this introduction email, git send-email will send out the patches.
Of special note is the --no-chain-reply-to option to git send-email. By default, git send-email will make each patch a reply to the one before. This will thread like so:
- [PATCH 0/m] Introductory email
- [PATCH 1/m] First patch
- [PATCH 2/m] Second patch
- ...
- [PATCH m/m] Last patch
- ...
- [PATCH 2/m] Second patch
- [PATCH 1/m] First patch
Most people hate this, myself included. It scrolls off the right side of the email folder in a thread view. With the --no-chain-reply-to option, all patches are sent as replies to the introduction. This threads like so:
- [PATCH 0/m] Introductory email
- [PATCH 1/m] First patch
- [PATCH 2/m] Second patch
- ...
- [PATCH m/m] Last patch
This is much nicer to see in a threaded email folder. You can also set the sendemail.chainreplyto option false in your .gitconfig. See the documentation for more on the configuration options for git send-email.
Note: Be sure to remove old patches before you provide "00*.patch" to git send-email. You don't want to send old patches with the new series!