Patrick Georgi wrote:
I'm glad to be able to announce that we moved the repository infrastructure to git and gerrit, with jenkins as supporting facility.
This is exciting!
the coreboot development workflow changes considerably:
- New SCM
You will need git, so install it from your usual software distribution channels.
For Windows users I would recommend installing the command line tools in the msysGit package. During installation there is a somewhat important question about how Git should handle line endings on Windows.
Git can perform automatic translation between line ending formats, so that code in the repository will never use anything but LF line endings, while developers working on Windows will still have every single file in their working tree use CRLF line endings. This translation is enabled by the core.autocrlf setting, which is what the installer will asks for the default value of.
There are many git configuration options. Options can be set either per user (AKA global) or per repository. Options in a repo override the global ones. Options are stored in plain text in ~/.gitconfig or <repodir>/.git/config
You can edit the text files or use the git config command:
git config --global user.name "Peter Stuge" git config --global user.email peter@stuge.se
The above two lines configure git so that all commits I make will have my name and email. It's important that you do the same configuration before you create commits, or they will look really bad and ultimately end up being rejected.
If you run git config inside a repo dir you can leave out --global to change settings locally for that repo only.
If you prefer to use a GUI for Git on Windows then I recommend Git Extensions, which also includes a Visual Studio plugin, so that you can interact with Git a little more easily directly from the IDE if you prefer to use Visual Studio.
But allow me to emphasize that it is highly valuable to learn how to work with Git on the command line. It may feel a little raw, but it is incredibly efficient, and it very much exposes the concepts of Git in a clear way, which I must say I have not really seen in any GUI so far.
For patch submission a gerrit account is necessary. You can register it on http://review.coreboot.org.
Currently registration requires OpenID and might be limited to Google and Yahoo accounts, but I think this will change tomorrow. (I have neither, so I can't register. :) We will certainly work something out.
- New patch submission process
Develop "as usual" in git, and commit freely. When you're ready to submit patches, push them with git push origin HEAD:refs/for/master
HEAD deserves a little discussion.
HEAD is a "meta name" which always refers to the last commit on whatever branch is currently checked out.
Subversion has revisions, Git has commits. Git commits are identified by a SHA-1 checksum calculated from the exact contents of the entire repository. Commit ids can be abbreviated as long as they are unique.
In SVN, revisions are always linear.
In Git, commits can form a directed acyclic graph. ( http://en.wikipedia.org/wiki/Directed_acyclic_graph )
The graph theory is not important, just keep in mind that with Git also the "parent commit" can be significant. So far, all coreboot work has been quite linear, and I think it will continue to be mostly linear, even if Git can handle more complicated situations.
With Git, the branch concept is very important. The actual commits themselves are really low-level building blocks of a Git repository, but it is only common to deal with commit ids while doing e.g. interactive rebase or cherry-picking, which are slightly advanced tasks compared to development using SVN. (But they are really lovely features of Git! More later.)
A Git branch is nothing but a nickname pointing to one particular commit in the repository commit graph. The branch thus also implies a particular commit history; namely all commits that came before the one that is the so-called branch HEAD.
Git is distributed, so *everything* is local by default in Git repos. This goes for commits, branches, tags and everything else. But everything can also be transferred to other repos easily. git push is one way, email is another popular way to at least transfer commits between repositories. Git can send email directly, but thanks to Gerrit it will not likely be used for coreboot. By using git push to transfer stuff over to Gerrit, emails will get sent out without further action from the developer.
So, HEAD in the git push command above refers to the last commit on the checked out branch.
The checked out branch was branched off the master branch at some point in time, and maybe there are new commits in master since then.
Unless there is an actual conflict that's no problem. If there is a conflict, you will eventually have to resolve it. Git may be able to help, but can not always succeed without help, just like svn.
Instead of HEAD you could thus also type the current branch name.
All commits you have done since the branch was created will be submitted to Gerrit, for proposed inclusion in the main coreboot repository master branch.
How and when to create branches is very much a personal thing. I find that I am a little too lazy to create branches as often as would actually be practical, so I sometimes have to do a bit of surgery to move commits around to fix that. :) It is much easier to deal with too many branches, than it is to deal with too few branches.
Note that there is absolutely no requirement to create branches, but it can be really really helpful, so it is a good habit to aquire quickly if you are only just starting to use Git now.
Branches in Git are first class citizens, they are basically nothing more than a name so they are very fast to deal with.
When you clone the coreboot repository, you will get a local Git repository, where you can work completely freely. There are no limitations to what you can do in the local Git repository, so please feel free to work with it any way you like. You can also have multiple repository clones, just like with svn, personally I find this useful sometimes.
After cloning, your local repo only has one branch, called master.
I try to immediately create a branch named according to the particular task or feature to work on next. This is so that the master branch always has only commits that come from the main coreboot repository. ("upstream") Again, I fail at this sometimes and end up doing work on the master branch. I guess this is mostly a matter of choice, how you want to work.
If you want to create a branch, you can do it two ways. The first is:
git branch newcoolfeature
This will create a branch called "newcoolfeature" which points to HEAD. You will stay "on" the current branch. If you make a commit on the current branch (as opposed to on the just-created branch) then "newcoolfeature" does not change and still points to the same commit as before; ie. the second last commit on the current branch.
The other way is:
git checkout -b newcoolfeature [<start_point>]
This does not only create a branch called "newcoolfeature" but it also does a checkout of that branch, so that you will be "on" the branch. If you create a commit after this, then newcoolfeature HEAD will change, and the previous branch will stay unchanged. Sort-of the opposite of what happened above - because even though a new branch was created, "git branch" does not change what the current branch is.
Branches or not, you really only require very few commands after having made a source code change:
git add changedfile.c git commit
Git is more featureful than SVN, so creating a commit is split into two steps. git add will let Git know what you want to include in the commit. You can run git add many times before running git commit. You can even undo. No commit will be created until you run git commit. git add adds the changes you have made in the named files into the "index" AKA "staging area" of the repository. This is a halfway house before the changes are actually committed. It is possible to add only some parts of a changed file, using "interactive add" which is entered by the git add -i command.
Please see git add --help for more information on interactive add.
There exists a shortcut, in case you really truly want to create one commit with every change that you have made in the source tree:
git commit -a
But I recommend to exercise caution with this command. Always using git add is another good habit, because it makes you think a little more about the changes that are about to be committed, which helps create nicely formatted commits, which helps working with commits going forward, which saves time.
Before you create a commit, please review the changes you have made, just like with svn.
The command I like to use for review is git diff. In it's simplest form, git diff will show all changes in your work tree which have not yet been added to the index.
Use git diff --cached to instead show *only* the changes that *are* added to the index; this is what will make up the commit if you would run git commit.
git diff --cached is the perfect way to review changes before creating a commit. git status is also helpful to get an overview of the files that are involved. git status, git diff (with and without --cached and/or other options) and git branch (without parameters) are always safe, read-only, operations that can be run at any point in time, regardless of the repository state, and will provide helpful information about the repo state.
If you push a number of commits at once, they're properly linked as "dependencies", so people (and tools like gerrit and jenkins) are aware about prerequisites.
Pushing a number of commits at once happens when the HEAD that you push has more than one commit that is not available in the branch that your push is targeted at. (Normally the master branch of the main coreboot repo.) So if you have created two commits before you push, then they will be assumed to depend on each other. If the commits are not really related then please keep in mind to push one at a time. Using one branch per related logical change is a good tool to accomplish this.
Praise?
Indeed! Thank you so much for the work getting this infrastructure up and running. I am personally excited to see coreboot start using Git and I think it will actually help developers a lot once everyone has gotten up to speed. For example Marshall and I worked on the last patchset for the E350M1 board exclusively using Git, and it would have taken us a lot more time and would have been a lot more tedious work to accomplish what we did without Git.
I think the same is true for much future development, in particular since we tend to see (and very much prefer!) more patchsets, as opposed to individual patches, and this fits Git very well.
Git is new for several coreboot developers, while some of us have been using it for a while already. If you should run into trouble please get in touch, the very best is to check on IRC, because if there is a problem there will likely be a couple of commands back and forth before the problem has been resolved, and email can be somewhat slow and impractical.
Kind regards
//Peter