For Developers‎ > ‎How-Tos‎ > ‎

Layout of the chromium git repository


The chromium git repository contains three heads:
  • refs/heads/git-svn, which tracks revisions imported from the subversion repository
  • refs/heads/master, which adds to the subversion history information to enable git submodules.
  • refs/heads/lkgr, which adds to the subversion history information to enable git submodules at svn revisions selected as lkgr (not all of which may be in refs/heads/master).
Here's a brief explanation of how the repository is populated:
  1. svn update is run to get the latest changes from the subversion repository.
  2. is run to generate the .DEPS.git file from the DEPS file.
  3. The .DEPS.git file is committed back to the subversion repository.
  4. git-svn fetch is run to fetch new subversion history (including changes to .DEPS.git from the previous step) onto the refs/heads/git-svn branch of the git repository.
  5. git merge --no-commit is run to merge the existing refs/heads/master and the new refs/heads/git-svn.
  6. Prior to committing the merge, is run to read .DEPS.git and regenerate the .gitmodules file and other submodule-related payload.
  7. refs/heads/master is updated to point to the new merge+edit commit.
  8. If lkgr has changed since the last time:
    1. The lkgr branch is checked out.
    2. git merge --no-commit is run to merge the existing refs/heads/lkgr and `git svn rev-find $LKGR` (which finds a commit in refs/heads/git-svn).
    3. is run to generate the .DEPS.git file from the DEPS file.
    4. is run to read .DEPS.git and regenerate the .gitmodules file and other submodule-related payload.
    5. refs/heads/lkgr is updated to point to the new merge+edit commit.


  Here's what a typical checkout looks like, when using the default ('managed') behavior of gclient.  Note:
  • The master and git-svn branches in the remote repository become refs/remotes/origin/master and refs/remotes/origin/git-svn in the local checkout.
  • refs/remotes/origin/master will always point to a merge commit containing the git submodule data.
  • refs/remotes/origin/git-svn will always point to the familiar linear history containing only changes imported from subversion.
With this topology, git logs and visual tools will behave differently than they did when history was purely linear.  In particular, git log will show merge commits interspersed with the subversion history; and git log --graph will show an unreadable "subway map" of branches.  But all is not lost -- there are a couple of tricks you can use to see the linear history of subversion commits.  This list is by no means comprehensive:
  • git log --first-parent master will show a single merge commit at HEAD, followed by uninterrupted subversion history.
  • git log master^ will omit the merge commit at HEAD, and show only the subversion history.
If you're having trouble with your git checkout, here are some troubleshooting tips.

This is what a checkout will typically look like after running gclient sync.  The red objects show the new git history which was fetched from the remote repository.  It includes a couple of commits imported from subversion, and a new merge commit containing updated git submodule data.  Note that gclient automatically fast-forwards the master branch to origin/master, but it leaves the work branch untouched.

At this point, you will most likely want to update your 'work' branch to incorporate the new commits.  There are typically two ways to do this (these commands assume you currently have the work branch checked out):
  • git rebase master
  • git merge master
Which method you use depends on whether you use vi or emacs -- which is to say, it is a matter of personal preference, hotly debated, and beyond the scope of this documentation to elaborate.


If you ever run git svn fetch or git svn pull, you need to read this!

Previously, it was OK for 
git svn fetch/pull to import new subversion commits onto refs/remotes/origin/master.  However, if you do that now, you will wind up  with the screwed up topology pictured left, where there is a merge commit stranded in the middle of the svn history.  If you then rebase/merge your work branch, well... it gets ugly.

To avoid this situation, you need to set up git-svn to import to the refs/remotes/origin/git-svn branch:

    $ git config svn-remote.svn.fetch trunk/src:refs/remotes/origin/git-svn

With the new configuration, git svn fetch will create a topology like this, where the new commits (in red) are added to the existing subversion-only history.  There is now one more important step...

You need to merge/rebase your master branch with the new subversion commits.  That will result in the topology to the left, where the blue objects denote the result of rebase/merge (the dashed line will exist if you merge, but not if you rebase).

At this point, you can merge/rebase your work branch with the master branch, exactly as you would do after a gclient sync.

Stefan Zager,
Jul 3, 2012, 3:03 PM
Stefan Zager,
Jul 3, 2012, 3:20 PM
Stefan Zager,
Jul 3, 2012, 3:20 PM
Stefan Zager,
Jul 3, 2012, 1:52 PM
Robbie Iannucci,
Feb 13, 2013, 6:24 PM
Stefan Zager,
Jul 3, 2012, 1:46 PM