ROSE Compiler Framework/Git
The ROSE project has been through multiple stages of source content management, starting from CVS, then subversion, and now Git.
Git becomes the official source code version control software due to its unique features, including
- Distributed source code management. Developers can have a self-contained local repository to do their work anywhere they want, without the need for active connection to a central repository.
- Easy merge. Merging using Git is as simple as it can get.
- Backup. Since easy clone of our central repository can serve as a standalone repository. We no longer worry too much about losing the central repository.
- Integrity. Hashing algorithm used by Git ensures that you will get out what you have put into the repository.
Many other prominent software projects have also been through the similar switch from Subversion to Git, including
- the Linux kernel,
A more comprehensive list of Git users is given by https://git.wiki.kernel.org/index.php/GitProjects
In summary, Git IS the state-of-the-art for source code management.
git 1.7.10 or later for github.com
github requires git 1.7.10 or later to avoid HTTPS cloning errors, as mentioned at https://help.github.com/articles/https-cloning-errors
Ubuntu 10.04's package repository has git 188.8.131.52. So building later version of git is needed. But you still need an older version of git to get the latest version of git.
apt-get install git-core
Now you can clone the latest git
git clone https://github.com/git/git.git
Install all prerequisite packages needed to build git from source files(assuming you already installed GNU tool chain with GCC compiler, make, etc.)
sudo apt-get install gettext zlib1g-dev asciidoc libcurl4-openssl-dev
$ cd git # enter the cloned git directory $ make configure ;# as yourself $ ./configure --prefix=/usr ;# as yourself $ make all doc ;# as yourself # make install install-doc install-html;# as root
Converting from a Subversion user
If you're coming from a centralized system, you may have to unlearn a few of the things you've become accustomed to.
- For example, you generally don't checkout out a branch from a central repo, but rather clone a copy of the entire repository for your own local use.
- Also, rather than using small, sequential integers to identify revisions, Git uses a cryptographic hash (SHA1), although in general you only need to ever write the first few characters of the hash--just enough to uniquely identify a revision.
- Finally, the biggest thing to get used to: ALL(!) work is done on local branches--there's no such thing in the DSCM world as working directly on a central branch, or checking your work directly into a central branch.
Having said that, distributed revision control is a superset of centralized revision control, and some projects, including ROSE, set up a centralized repository as a policy choice for sharing code between developers. When a developer works on ROSE, they generally clone from this central location, and when they've made changes, they generally push those changes back to the same central location.
Name and Email
Before you commit your local changes, you MUST ensure that you have correctly configured your author and email information (on all of your machines). Having a recognizable and consistent name and email will make it easier for us to evaluate the contributions that you've made to our project.
- Name: You MUST use your official name you commonly use for work/business, not nickname or alias which cannot be easily recognized by co-workers, managers, or sponsors.
- Email: You MUST use your email commonly used for work. It can be either your company email or your personal email (gmail) if you DO commonly use that personal email for business purpose.
To check if your author and email are configured correctly:
$ git config user.name <your name> $ git config user.email <your email>
Alternatively, you can just type the following to list all your current git configuration variables and values, including name and email information.
$ git config -l
To set your name and email:
$ git config --global user.name "<Your Name>" $ git config --global user.email "<email@example.com>"
Branch Naming Convention
All developer central repository branches should be named using the following pattern
- NAME is typically a login name or surname.
- PURPOSE is a single-word description of the type of work performed on that branch, such as "bugfixes".
- OPTION is information for ROSE robots with regards to your branch.
- -test Changes to the branch are automatically tested
- -rc Changes are tested and if they pass then they're merged into the "master" branch (like "trunk" in Subversion).
- The "matzke-bugfixes-rc" branch is "owned" by Robb Matzke (i.e., he's the one that generally makes changes to that branch), it probably contains only bug fixes or minor edits, and it's being automatically tested and merged into the master branch for eventual release to the public.
It is important to have concise and accurate commit messages to help code reviewers do their work.
Example commit message, excerpt from link
(Binary Analysis) SMT solver statistics; documentation * Replaced the SMT class-wide number-of-calls statistic with a more flexible and extensible design that also tracks the amount of I/O between ROSE and the SMT solver. The new method tracks statistics on a per-solver basis as well as a class-wide basis, and allows the statistics to be reset at artibrary points by the user. * More documentation for the new memory cell, memory state, and X86 register state classes.
- (Required) Summary: the first line of the commit message is a one line summary (<50 words) of the commit. Start the summary with a topic, enclosed in parentheses, to indicate the project, feature, bugfix, etc. that this commit represents.
- (Optional) Use a bullet-list (using an asterisk, *) for each item to elaborate on the commit
Creating and deleting branches on the remote repository is accomplished with git-push.
This is its general form:
$ git push <remote> <source-ref>:<destination-ref>
- When you clone a repository, the default <remote> is called "origin"
- The <source-ref> is the branch in your local repository (cloned from <remote>) that you want to create or synchronize with the <remote>
- The <destination-ref> is the branch that you want to create on the <remote>
Create remote branch
$ git remote -v origin https://github.com/rose-compiler/rose.git (fetch) origin https://github.com/rose-compiler/rose.git (push) $ git branch * master # Method 1 $ git push origin master:refs/heads/master # Method 2 - The currently checked out branch (see git-branch) is also called the <tt>HEAD</tt> $ git push origin HEAD:refs/heads/master # Method 3 - Git is pretty smart -- if you only specify one name, it will use it as both # the source and destination. $ git push origin master
Delete remote branch
Deleting a remote branch is simply a matter of specifying nothing as the <source-ref>. To delete the branch my-branch, issue this git-push command:
$ git push origin :refs/heads/my-branch
It is recommended to rebase your branch before pushing your work. So your local commits will be moved to the head of the latest master branch, instead of being interleaved with commits from master.
git pull origin master git rebase master
Rebase helps to cut up commits and slice them into any way that you want them served up, and placed exactly where you want them. You can actually rewrite history with this command, be it reordering commits, squashing them into bigger ones, or completely ignoring them if you so desire.
Why is this helpful?
- One of the most common use cases is that you’ve been working on your own features/fixes/etc in separate branches. Instead of creating ugly merge commits for every change that is brought back into the master branch, you could create one big commit and let rebase handle attaching it.
- Another frequent use of rebase is to pull in changes from a project and keep your own modifications in line. Usually by doing merges, you’ll end up with a history in which commits are interleaved between upstream and your own. Doing a rebase prevents this and keeps the order in a more sane state.
Modifying a submodule
ROSE uses submodule to link to EDG files.
the default checked out version of submodule is on a ghost branch
[youraccount@yourmachine:~/rose/src/frontend/CxxFrontend/EDG]git branch * (no branch) master
You have to create a local branch before you can change the submodule, you should create a new branch based on the ghost branch, which may or may not correspond to the remote master. In our settings, we push EDG changes to non-master branches so most likely the ghost branch is tied to a non-master branch.
$ git checkout -b fix-up
Do you changes then
Always commit and push the submodule changes first
$ git commit -a -m "Updated the submodule from within the superproject." // commit locally $ git push origin HEAD:refs/heads/your-account/edg4x-rc // push to your own remote branch
Finally change the super project's link to the changed submodule
$ cd .. # back down to its parent repository's path $ git add EDG # Please note: NEVER use "git add EDG/" !!!! , this will add all files under EDG/ to the super project!! $ git commit -m "Updated submodule EDG." $ git push