Git is a distributed revision control system. Explaining git itself is beyond the scope of this document; instead the aim is to briefly explain the git-svn extension and how to use it with Native Client. Git-svn is a git extension that uses a local git repository backed by a central Subversion server. The commits in Subversion appear in the git repository as a remote branch, and you can fork your own branches off of svn HEAD, or any other commit in your repository. The git-svn extension fetches commits from svn and checks them into git, and when you are ready to commit to svn, it takes your git commits and checks them into the remote Subversion server. A tool called git-cl (part of the depot_tools) manages code review, try jobs, and the other tasks you would use gcl for in a Subversion environment.
Native Client uses Subversion as its centralized source control system. Why would we want to pile git on top of that? There are 2 reasons. First, in order to have multiple CLs in flight at once, using Subversion requires you have multiple checkouts of the source and all the deps, each of which is dedicated to a single set of changes. Conversely git's model uses a single directory and switches back and forth between different branches (or commits in a branch), modifying the files in the working directory. You might or might not think this is an advantage; that's largely a matter of taste. However the real benefit is that when you use git, you can commit to your local branches as often as you want, for whatever reason you want; to save your progress partway through a task, to try different approaches, or to facilitate easy switching between different CLs.
The setup described here is analogous to the preferred way to use git with Chromium, described at http://code.google.com/p/chromium/wiki/UsingNewGit
Setup from scratch
If you are on Linux start by making sure you have the git-svn package:
Create a directory to hold Native Client and all its deps (We'll call it $NACL_DIR) and cd into it.
[OPTIONAL] This svn command may help you avoid incomprehensible password prompts:
[HINT: On Linux systems, you can tell SVN not to use the GNOME keychain by setting "password-stores =" in your ~/.subversion/.config file.]
Setup your .gclient file, using git-style DEPS:
You'll notice that all the DEPS checkouts tell you about big long hex numbers (git commit IDs) instead of short decimal numbers (svn revision numbers). This is the key difference from the old regime: all the DEPS checkouts are git checkouts, rather than svn checkouts. (You'll also notice that this first "gclient sync" run takes a while--it's getting the entire history of each DEPS repository, not just the current checkouts. Thereafter, the incremental updates are usually much faster than with svn.)
This gives you a setup very analogous to the all-svn setup you get from using plain gclient. Notably, your main native_client checkout is "managed" by gclient. This means that "gclient sync" will update your git checkout. (See below for how to get around this if you prefer to update native_client yourself).
If you don't need to commit, you are done. You can use a pure git checkout, and keep it up to date by running "gclient sync" from $NACL_DIR
If you do need to commit, you need to setup git-svn.
Now you have a native_client directory controlled by git-svn. The origin/master branch mirrors SVN trunk, and your local master branch tracks the master branch from the origin remote.
You should not make local commits to your master branch, or gclient may complain about not being able to fast-forward the merge (and then eat that complaint, not showing you the text until you hit "enter" on what looks like a hung update).
Your workflow might be like the following:
Update your master branch
The 'gclient sync' command will pull down the changes on origin/master and merge them into your local checked-out master branch.
I like to at least have a commit for every time I run a test (or try job) that takes sufficiently long that I won't sit and wait for it. That way when I come back and look at the results, I'm sure to have a snapshot of my code that was tested, even if I make new edits while the test is running.
Send a try job
Watch out! The command for sending try jobs is 'git try', not 'git cl try'.
Managing your own native_client checkout
You may not want gclient to mess with your main native_client checkout. You can prevent this, making gclient only keep your DEPS up to date (based on the content of the currently checked-out native_client/DEPS file). Then you are responsible for updating native_client itself. To get this behavior do the following in the $NACL_DIR directory (i.e. the directory above native_client)
In the above workflow, everywhere it says 'gclient sync', you can do 'git pull' to update your native_client directory, followed by 'gclient sync' to update the DEPS based on the native_client/DEPS file you just checked out.
Git mirroring and DEPS
One final note about the mirroring: how this works is that the infrastructure folks have a cron job that runs every few minutes (I think it may be every 3 minutes) to update the various git mirrors from the svn repositories. If the DEPS file changes, then it regenerates .DEPS.git and does an automatic svn commit of the new .DEPS.git file. (A git-based gclient checkout looks at .DEPS.git and ignores DEPS.) So when you do a commit, you may have to wait a few minutes before you can see it in a git update.