Accessing source code via Git
Browsing the repository
The Rockbox source code is available to browse online at http://git.rockbox.org/?p=rockbox.git;a=summary
The log of commits to the master branch (the current development work) is at http://git.rockbox.org/?p=rockbox.git;a=log;h=refs/heads/master
Downloading (cloning, checking out) the source
You need to have git installed to check out the source code. Linux users should be able to install it from their distribution package manager; Windows users will need to use msysgit or Cygwin git (we don't currently have a good idea which of these is preferable). Once you have git installed, you can get a copy of the Rockbox source repository with:
git clone git://git.rockbox.org/rockbox
This will create a directory called
in your current directory, which will contain the most recent version of Rockbox on the master branch (the main development branch). This is a complete clone of the repository and includes the entire development history as well as all the release branches; consult the git documentation for how to check out different points in history if you don't want to work with the latest version.
If you are behind a restrictive firewall, this command might fail. You can try to check out via HTTP instead, which is more likely to work with firewalls but may be slower:
git clone http://gerrit.rockbox.org/p/rockbox
Updating the source
Any time you want to update your copy to the latest code, you can do:
git pull --rebase
This will download the latest changes, and then update your working copy to be based on the latest version. If you've made any local commits, they will be moved to be on top of the latest version. Git experts will notice that we are recommending rebasing rather than merging here; if you know what you are doing you can merge instead, but in most cases rebasing is the right thing to do. If you've made no changes then you don't need to worry about this.
Preparing to make changes
Before making any changes, you need to tell git who you are. Commits in git are identified by a name and email address, not by a username. If you already use git, you may have done this already; however, note that Rockbox policy requires that you use your real name. Set your name and email with:
git config --global user.name "John Doe"
git config --global user.email email@example.com
You will probably find git easier to use if you enable coloured output with
git config --global color.ui auto
but this is optional.
Setting up Gerrit
Rockbox uses a server program called Gerrit to host the project's git repositories. Gerrit provides self-service access control and the ability to upload code to be reviewed. All committers need to use Gerrit in order to make commits. Even if you are not a committer, you should set up an account on Gerrit if you ever intend to contribute any changes to Rockbox - you don't need to have commit access in order to upload a proposed change to be looked at. There are several steps, but you only need to do this once, before you start making changes.
- Create an SSH key, if you don't already have one. On Linux you can just run
ssh-keygen to do this. Set a passphrase on the key so that it can't be used if the file is stolen from your computer. To avoid you having to type the passphrase repeatedly as you work with the remote repository you probably want to add the key to an ssh key agent; check
man ssh-agent or Google for how to set this up on your distro/environment.
- Have some kind of OpenID account. Google accounts, Yahoo accounts, and a bunch of other website accounts provide OpenID. This does not include Twitter/Facebook. You can run your own if you think that's a good idea; Gerrit doesn't care where your OpenID comes from.
- Go to http://gerrit.rockbox.org/ and click on the "Register" link in the top right corner. Put in your OpenID URL, or click the google/yahoo buttons if you are using google/yahoo. You'll get sent to your provider's site to confirm that you want to allow this machine to log you in. You need to include the http:// at the start of your OpenID URL because of a bug in the current released version of Gerrit.
- Gerrit will offer you a first time setup page containing several fields you will need to fill in. Please enter your real name and email address; the same ones you used when configuring git. (if they do not match you will not be allowed to upload changes). You also need to choose a username for SSH access; this doesn't have to be your real name, you can use whatever is convenient for you (e.g. your normal system username). Paste the public portion of your SSH key into the key field. You can upload multiple keys if you use different keys on different computers.
- To test that your SSH account has been set up correctly, run
ssh -p 29418 firstname.lastname@example.org - (notice: yourusername is case sensitive) if everything is OK then you should get a message from gerrit telling you that you have connected successfully, but interactive shells are disabled. If you're using an SSH keyagent then this should succeed without requiring you to type your passphrase.
- In your git repository, enter
git remote set-url --push origin ssh://email@example.com:29418/rockbox This will set the address to be used to commit. Updating from the server will continue to take place over the more efficient anonymous git protocol.
- Install Gerrit's commit message hook into your clone of the repository:
scp -p -P 29418 firstname.lastname@example.org:hooks/commit-msg .git/hooks/ This hook will add an extra line to the end of each commit you make with a unique "change ID". This is used by Gerrit to keep track of updated versions of patches; don't remove it.
Making changes locally
You can simply edit any file in the working directory to make changes. Once you're happy with your changes and want to make a permanent record of them, you can commit them to your local repository. You don't need to have commit access to the server to do this; the commit is only stored on your local computer to start with.
Git keeps track of the changes to be committed in a hidden file called the "index" (also sometimes referred to as the cache). This means that you have to explicitly tell git which changes to add to the index before you can commit your changes. You can see which files you have changed with
and you can see a diff of all the changes not yet added to the index with
. To add all the changes in a file to the index (this works for both new and existing files; you need to do this even for existing files, unlike many other version control systems):
git add path/to/file.c
Once you have added some changes to the index, you can check on the status of your working directory with
. This will list all the files that have been changed, and show you which ones are added to the index. It also displays some suggested commands to add or remove things from the index. To see a diff of the files that have been added to the index, you can use
git diff --cached
When you've made sure that the index contains the changes you want to commit, create a commit with:
This will start your default text editor in order to enter a commit message. The suggested format for a commit message is to start with a single, short line that describes the overall purpose of the commit (a single sentence), then a blank line, then a full description of your change taking as many lines as you need. The template will show you which files you are committing; if you want to see the full diff of the changes you are committing, you can run
git commit -v
to have this information included in the template, so you can double-check you are doing what you intend.
Alternatively, you can use
git commit -a
to commit all changed files without having to add them to the index first. This will not
include newly created files, only modifications to existing files.
If you want to make further changes after making a commit, you can just follow the same process again to create a new commit, but you may prefer to amend the existing commit (for example, if you are making a correction to the change you previously made). You can't amend things once they have been submitted to Rockbox, but you are free to do so as much as you like on your local machine or submitted to gerrit, and if it's part of the same logical change it's encouraged. To amend the most recent commit use
git commit --amend
- this will combine the previous commit with whatever changes you have added to the index since then, and give you the opportunity to edit the commit message as well. Don't remove or change the Change-Id line in the commit message when you do this; Gerrit uses this to track which commit is which even when they are edited.
Uploading a change for review and testing
Gerrit is a code review system as well as a git server. Anyone can upload a change for review, you don't need to be a developer with commit access. You need to commit your change locally first as shown in the earlier section, and you should make sure your commit message has had a Change-Id: line inserted by the commit-msg hook - if not then check the Gerrit setup instructions for how to install the hook and try again. Each local commit you have made will create a separate code review on Gerrit, with dependencies between them in the order they were made. Generally, you will want to flatten your change to a single commit before uploading it: read GitCommitPolicy
for an explanation of what makes a good commit or series of commits.
To push your change to the code review system:
git push origin HEAD:refs/for/master
The output will include the URL of the newly created code review, which you can also find on your review list at http://gerrit.rockbox.org/r/#mine
- you can visit the review to see the patch and any comments people have added.
If you need to change your patch, use
git commit --amend
on your local copy to edit the existing commit, and then simply push it again; as long as the Change-Id line is still there, it will be uploaded as a newer version of the same change, at the same URL. Review comments apply to specific versions of the patch, so each time you upload a new version you will get a "clean slate", neither accepted nor rejected.
Anyone can review your change, and generally the best way to get it reviewed will be to ask on IRC, or post on rockbox-dev, with a link to the review. However, if you know a specific person is interested in reviewing it or knows a lot about the code you are changing, you can invite them specifically by entering their name or email address in the "Add Reviewer" field and they will be emailed automatically.
If you can't remember
'git push origin HEAD:refs/for/master'
add the following to your .git/config file. Then you can just type
and it will automatically push your current branch to Gerrit for review. Feel free to change
to any alias you would like to use.
gerrit = push origin HEAD:refs/for/master
All changes are publicly visible and anyone with a Gerrit account can review them. The most useful kind of comment is a comment on a specific line of the patch. To do this, double click on the line while in the diff view. These comments are saved as drafts until you are done, and are not visible to anyone other than you until you publish them.
Once you have written your comments on specific lines, click the "Review" button on the patchset. This will take you to a form where you can enter any overall comments that are not specific to any particular line, and will also allow you to assign scores to the patch. You don't need to assign scores in order to leave comments. Once you're done, click the "Publish Comments" button to make your comments visible to everyone, and to send an email with the comments to the author and reviewers.
Comments and scores apply to particular versions of a change (a single patch set) so if the author later uploads a new version all scores are reset. You can see the comments for a previous version by expanding the old patch set on the change's main page.
Each review has a score on two different criteria. The most important criteria is the code review score. Anyone can assign a code review score of +1 or -1, to indicate that they think the change looks OK, or that they think the change should not be accepted. Scores of +1 and -1 are for information only; they don't affect your ability to actually submit a change, but if people have scored your change as -1 then you should at least make sure you have understood why. Committers have permission to assign scores of +2 or -2. For a change to be submitted, you need at least one committer to give it a +2 score, and you may not submit if any
committer has given it a -2 score. The scores do not add up: two +1s do not make a +2, and a +2 does not cancel out a -2.
There is a second review score called "Tested", which you may use to indicate that you tested a change (whether it's your change or someone else's) on a target device, and it either worked or did not work. If it doesn't work, please make sure to add a comment explaining what went wrong. Changes do not have to score +1 Tested before they can be submitted; we assume that changes have been tested by their author at minimum. If you haven't tested it (e.g. it's a change for a device you do not have), please do try and get someone else to test it. A score of -1 Tested (i.e. fails) also does not block the change from being submitted, in order that a tester who has made a mistake can be overruled without requiring them to change their score, but again: if someone has marked your change as failing, please make sure you understand why before you submit.
Committing a change "for real" after code review
Once a change has a +2 Code Review score from a committer, and no -2 Code Review score from any other committer, it is eligible to be committed to the master branch. Any developer with commit access can do this: you doesn't have to be the original author, and you don't have to be the person who gave the change a +2. If you aren't a committer then you should probably ask the person who gave the change +2 to do this for you.
All you need to do is click the "Submit Patch Set" button, and the change will be cherrypicked onto the branch. The original author of the change will be recorded as the author of the commit on the branch; the person who clicked the submit button will be recorded as the committer. The commit message will contain Reviewed-By lines indicating who gave the change a +2.
Because changes are commited via a cherry-pick, you will need to use
git pull --rebase
on your local copy once the change has been committed upstream. This will replace your local commit with the "real" commit to master, containing the final timestamp for when it was committed, the committer, and the reviewers.
Submitting a change directly to the Rockbox master branch
Only developers with commit access can do this. Make sure you have read GitCommitPolicy
before attempting to submit anything to master. You need to commit your change locally first as shown in the earlier section. To push your change to the master branch on the server:
git push origin HEAD:master
This means "push the HEAD (latest version of the currently checked out branch) to the branch named master, on the remote repository named origin". Git sets up the link to the remote repository when you initially clone the repository, and calls it "origin".
If this succeeds, you're done. However, if someone else has submitted a change since you last updated, it will fail, telling you that your change is not a fast-forward (i.e. your commit is not descended from the current latest commit). In most cases (when you have made one or more simple changes), you should rebase your changes to be based on the latest version. To do this, run:
git pull --rebase
This will set your changes aside in a temporary area, update to the latest version on the server, and then reapply each of your local commits in order. If any of them conflict, you will be given the opportunity to fix the conflicts and continue. Once you've done this, you can try and push again.
Rebasing certain kinds of change can be difficult; however, please do not just create a merge without considering the alternatives. The server will not allow you to push a merge commit without special permissions, in the interest of maintaining a clean history. Refer to the page on GitCommitPolicy
for an explanation of why we discourage merging, what you can do instead, and how to get permission to do a merge if there is no sensible alternative.
Applying a patch from someone else
patch -p0 < /path/to/lang.patch
Verify that the patch is correct, then mark the file for commit:
git add apps/lang/modified.file.lang
git commit -s --author="John Doe <email@example.com>"
The --author will change the author of the patch.
The -s will add a "Signed-off-by: Your Self <firstname.lastname@example.org>" line to the commit log.
Check that it went well with:
When you release a binary using a certain revision in git, you should tag it with:
git tag -a rbutil_v6.66 <SHA1 COMMIT ID>
If you built it from the current source you can omit the commit id:
git tag -a bootloader_iphone_4s_v1337
Your editor will open, and you will add a description of the tag.
You will first need to add yourself to the Rockbox Release Committers group.
In gerrit interface, go to Admin, then Groups, then select that group.
Then to push your tag to the repository use:
git push --tags
New remote branches can be created via the Gerrit web interface.
To track the remote branch in new local branch, use:
git checkout -b branch_name origin/branch_name
Frequently Asked Questions
How do I check out the revision previous to current?
git reset --hard HEAD~1 # replace 1 with N for any further revision backwards
NOTE: This discards any uncommitted changes as well. Use "git stash" to save them temporarily.
How do I check out an SVN revision made before the transition to git?
git log -n 1 --grep=@NNNNN
This returns a commit (including message, etc). Pass the hash to git checkout.
How do I undo a change (svn revert file.c)?
git checkout -- file.c
How do branches work?
git branches allow you to have multiple edited versions of the source tree at once.
To see your branches
To create a new branch
git branch branch_name
To switch to a different branch
git checkout branch_name
How do I diff against the rockbox git repo (equivalent of 'svn diff')
git diff origin/master
How do I undo all my changes and revert to rockbox git?
git reset --hard origin/master
How do I bisect using git?
git bisect start
git bisect bad # Mark the current commit as bad
git bisect good <hash/tag> # Marks the last known-good commit
After that git will start bisect and automatically checkout commits for you. Depending on whether they are good or bad you run
git bisect good
git bisect bad
or if the current revision can't be tested (e.g. because it doesn't build)
git bisect skip
and git will automatically proceed with bisection.
To cancel or finish bisection run:
git bisect reset
That'll drop you to where you started. "git bisect --help" has a lot more information.
Experimenting with git and gerrit
If you want to experiment with using git and gerrit, there is a sandbox repository in order to allow you to do this without interfering with real development. You do not need to be a committer to use the sandbox; the permissions are more relaxed and anyone is allowed to submit changes. It doesn't contain any real code, though!
To check out the sandbox repository, use:
git clone git://git.rockbox.org/sandbox
You can try out anything mentioned on this page using the sandbox repository.
Copyright © by the contributing authors.