A git workflow for Gecko development

Here is my recommended setup for Gecko development with git:

  • Install mercurial (only needed for its libraries). You probably already have it installed. Eventually, this dependency will go away, because the use of mercurial libraries is pretty limited.
  • Use git 2.2.2 or newer, or rebuild an older git with this patch applied: https://github.com/git/git/commit/61e704e38a4c3e181403a766c5cf28814e4102e4. It will make small fetches and pushes much faster.
  • Install git-cinnabar. Just clone it somewhere, and put that directory in your PATH.
  • Create a git repository for Mozilla code:
    $ git init gecko
    $ cd gecko
  • Set fetch.prune for git-cinnabar to be happier:
    $ git config fetch.prune true
  • Set push.default to "upstream", which I think allows a better workflow to use topic branches and push them more easily:
    $ git config push.default upstream
  • Add remotes for the mercurial repositories you pull from:
    $ git remote add central hg::https://hg.mozilla.org/mozilla-central -t branches/default/tip
    $ git remote add inbound hg::https://hg.mozilla.org/integration/mozilla-inbound -t branches/default/tip
    $ git remote set-url --push inbound hg::ssh://hg.mozilla.org/integration/mozilla-inbound
    (...)
    

    -t branches/default/tip is there to reduce the amount of churn from the old branches on these repositories.
    If you want access to all the branch tips, my recommended setting is the following:

    $ git config remote.central.fetch +refs/heads/branches/*/tip:refs/remotes/central/*
    $ git config remote.inbound.fetch +refs/heads/branches/*/tip:refs/remotes/inbound/*
    

    This exposes the branch tips as refs/remotes/$remote/$branch instead of refs/remotes/$remote/branches/$branch/tip.
    You can use a similar setup without the wildcards if you want the remote branch names to be shorter, such as:

    $ git config remote.central.fetch +refs/heads/branches/default/tip:refs/remotes/central/default
    $ git config remote.inbound.fetch +refs/heads/branches/default/tip:refs/remotes/inbound/default
    

    This exposes the tip of the default branch as refs/remotes/$remote/default instead of refs/remotes/$remote/branches/default/tip.

  • Setup a remote for the try server:
    $ git remote add try hg::https://hg.mozilla.org/try
    $ git config remote.try.skipDefaultUpdate true
    $ git remote set-url --push try hg::ssh://hg.mozilla.org/try
    $ git config remote.try.push +HEAD:refs/heads/branches/default/tip
    
  • Update all the remotes:
    $ git remote update

    This essentially does git fetch on all remotes, except try.

With this setup, you can e.g. create new topic branches based on the remote branches:

$ git checkout -b bugxxxxxxx inbound/branches/default/tip

or

$ git checkout -b bugxxxxxxx inbound/default

depending on your remote.inbound.fetch settings (see above).

When you're ready to test your code on try, create a commit with the try syntax, then just do:

$ git push try

This will push whatever your checked-out branch is, to the try server (thanks to the refspec in remote.try.push).

When you're ready to push to an integration branch, remove any try commit. Assuming you were using the topic branch from above, and did set push.default to "upstream", push with:

$ git checkout topic-branch
$ git pull --rebase
$ git push

But, this is only one possibility. You're essentially free to pick your own preferred workflow. Just keep in mind that we generally prefer linear history on integration branches, so prefer rebase to merge (and, git-cinnabar doesn't support pushing merges yet). I'd recommend setting the pull.ff configuration to "only", by the way.

Please note that rebasing something you pushed to e.g. try may leave dangling mercurial metadata in your git clone. git hgdebug fsck will tell you about them, but won't do anything about them, at least currently. Eventually, there will be a git-gc-like command.

Please report any issue you encounter in the comments, or, if they are git-cinnabar related, on github.

6 Responses to “A git workflow for Gecko development”

  1. kats Says:

    Sweet! This is pretty neat. Unfortunately since the SHAs are different from git.m.o it makes it hard to share patches between my B2G tree and repos like the one here (usually I’ll push a topic branch to my github fork and then pull it down on a different machine for testing on a different platform). Still I’ll keep this repo around and see if I can use it for relatively standalone stuff.

  2. kats Says:

    Oh also I used https URLs instead of http URLs in your instructions and that worked fine.

  3. bholley Says:

    This is revolutionary. Thanks a million glandium.

  4. glandium Says:

    @kats: Updated to use https URLs.

  5. past Says:

    I have set push.default to “upstream”, but still “git pull –rebase” doesn’t work for me in a branch. I have to use “git pull –rebase inbound” for a branch that I have checked out from inbound using “git co -b bug/XXX-fix-foo”.

    Should I be using “git co -b bug/XXX-fix-foo inbound/branches/default/tip” instead?

  6. glandium Says:

    > Should I be using “git co -b bug/XXX-fix-foo inbound/branches/default/tip” instead?

    Yes. Or git branch –set-upstream-to=inbound/branches/default/tip once you branched. But that’s standard git practice, not specific to the mercurial remotes.

Leave a Reply