Deprecation

This document is DEPRECATED.

Please consider any information here as out of date. DO NOT use this document.

Instead, refer to http://infinispan.org/documentation.

Please update your bookmarks accordingly.

Skip to end of metadata
Go to start of metadata
As a convention, upstream is used as the name of the http://github.com/infinispan/infinispan repository. This repository is the canonical repository for Infinispan.

Pre-requisites

This document assumes some working knowledge of git. We recommend Scott Chacon's excellent Pro Git as a valuable piece of background reading. The book is released under the Creative Commons license and can be downloaded in electronic form for free At very least, we recommend that Chapter 2, Chapter 3 and Chapter 5 of Pro Git are read before proceeding.

Repositories

Infinispan uses http://github.com/infinispan/infinispan as its canonical repository, and this repository contains the stable code on master (currently Infinispan 5.x) as well as the maintenance branches for 4.2.x, 4.1.x and 4.0.x.

Typically, only Project Admins would be able to push to this repo while all else may clone or fork this repo.

Roles

The project assumes one of 3 roles an individual may assume when interacting with the Infinispan codebase. The three roles here are:

  • Project Admin (typically, no more than 3 or 4 people)
  • Frequent Contributor
  • Occasional Contributor
None of the roles assume that you are a Red Hat employee.  All it assumes is how much responsibility over the project has been granted to you.  Typically, someone may be in more than one role at any given time, and puts on a different "hats" based on the task at hand.

Occasional Contributor

This role defines a user who browses through the source code of the project and occasionally submits patches. Patches may be submitted in one of two ways:

  • Attach a patch file to the JIRA issue
  • Creating a pull request on GitHub

The approach a contributor chooses to use depends entirely his/her personal preference, but usually is tied to how the contributor accesses Infinispan's source code. If the contributor directly clones the upstream repository, they should submit patch files. If the contributor instead uses their personal GitHub account to fork the upstream repository, then they are should issue a pull request.

A GitHub pull request is the preferred method to submit a patch!

Attach a patch file to the JIRA issue

In this workflow, the contributor directly clones the upstream repository, makes changes to his local clone, adequately tests and commits his work with proper comments (more on commit comments later), and generates a patch. The patch should then be attached to the JIRA issue.

More information on generating patches suitable for attaching to a JIRA can be found in Chapter 5, Section 2 of Pro Git, under the section titled Public Large Project .

Rather than emailing the patches to a developer mail list as suggested by Pro Git, please attach your patch to the JIRA issue.

Creating a pull request on GitHub

In this workflow, the contributor forks the Infinispan upstream repository on GitHub, clones their fork, and makes changes to this private fork. When changes have been tested and are ready to be contributed back to the project, a pull request is issued via GitHub so that one of the Project Administrators can pull in the change.

Topic Branches
It is desirable to work off a topic branch, even when using your own, forked repository. A topic branch is created for every feature or bug fix you do. Typically you would create one topic branch per issue. 

Before you push your work onto your fork of the repository, it is often a good idea to review your commits. Consolidating them (squashing) or breaking them up as necessary and cleaning up commit messages should all be done while still working off your local clone. Also, prior to issuing a pull request, you should make sure you rebase your branch against the upstream branch you expect it to be merged into.  Also, only submit pull requests for your branch - not for your master!

The section on Public Small Project in Chapter 5, Section 2 of Pro Git has more information on this style of workflow.

A worked example
  1. Make sure your master is synced up with upstream. See this section for how to do this
  2. Create new branch for your topic and switch to it. For the example issue, ISPN-1234:
  3. Do your work. Test. Repeat
  4. Commit your work on your topic branch
  5. Push your topic branch to GitHub. For example:
  6. Issue a pull request using the GitHub pull request system
  7. Once your pull request has been applied upstream, delete the topic branch both locally and on your fork. For example:
  8. Sync with upstream again so that your changes now appear in your master branch

If your topic branch has been open for a while and you are afraid changes upstream may clash with your changes, it may make sense to rebase your topic branch before you issue a pull request. To do this:

  1. Sync your master branch with upstream
  2. Switch to your topic branch. For example:
  3. Rebase your topic branch against master:
  4. Test, test, test!
  5. Push your rebased topic branch to your repo on GitHub (you may need to force this with the -f option).
  6. Continue your work on your topic branch.
If you are sharing your forked Infinispan repo with others, then do not rebase!  Use a merge instead.

Multi-step coordination between developers using forked repositories

Sometimes a feature/task is rather complex to implement and requires competence from multiple areas of the projects. In such occasions it is not uncommon for developers to coordinate feature implementation using personal forks of Infinispan repo prior to finally issuing request to integrate into Infinispan main repository on GitHub.

For example, developer A using his personal Infinispan fork creates a topic branch T and completes as much work as he/she can before requesting for assistance from developer B. Developer A pushes topic T to his personal Infinispan fork where developer B picks it up and brings it down to his local repo. Developer B then in turn completes necessary work, commits his/her changes on branch T, and finally pushes back T to his own personal fork. After issuing request for pull to developer A, developer B waits for notification that developer A integrated his changes. This exchange can be repeated as much as it is necessary and can involve multiple developers.

A worked example

This example assumes that developer A and B have added each others Infinispan forked repositories with the git add remote command. For example, developer B would add developer A's personal Infinispan fork repository with the command

  1. Developer A starts implementing feature ISPN-244 and works on a local topic branch ispn244
    Developer A pushes ispn244 to personal Infinispan fork. For example:
  2. Developer B fetches branch ispn244 to local repository. For example:
  3. Developer B works on local branch my_ispn244
  4. Developer B commits changes, pushes my_ispn244 to own fork.
  5. Developer B sends pull request to developer A to integrate changes from my_ispn244 to ispn244

Frequent Contributor

A frequent contributor will only ever submit patches via a pull requests. The pull request will be submitted via GitHub.

Frequent contributors should always fork the upstream project on GitHub and work off a clone of this fork. This is very similar to Creating a pull request on GitHub workflow used by a Occasional Contributor.

All Infinispan core developers are considered frequent contributors and work off personal forks of the upstream repository.  This allows for complex features to be developed in parallel without tripping up over one another.  This process is certainly not restricted to just Infinispan core developers; any contributor may also participate in this manner.

Project Admin

Project Admins have a very limited role. Only Project Admins are allowed to push to upstream, and Project Admins never write any code directly on the upstream repository. All Project Admins do is pull in and merge changes from contributors (even if the "contributor" happens to be themselves) into upstream, perform code reviews and either commit or reject such changes.

All Contributors who are also Project Admins are encouraged to not merge their own changes, to ensure that all changes are reviewed.

This approach ensures Infinispan maintains quality on the main code source tree, and allows for important code reviews to take place again ensuring quality. Further, it ensures clean and easily traceable code history.

Merging in patches

Patches submitted via JIRA are audited and promoted to the upstream repository as detailed above. A Project Admin would typically create a working branch to which the patch is applied and tested. The patch can be further modified, cleaned up, and commit messages made clearer if necessary. The branch should then be merged to the master or one of the maintenance branches before being pushed.

More information on applying patches can be found in Chapter 5, Section 3 of Pro Git, under Applying Patches From Email.

Handling pull requests

Project Admins are also responsible for responding to pull requests. The process is similar to applying a patch directly, except that when pulling in changes from a forked repository, more than a single commit may be pulled in. Again, this should be done on a newly created working branch, code reviewed, tested and cleaned up as necessary.

If commits need to be altered - e.g., rebasing to squash or split commits, or to alter commit messages - it is often better to contact the Contributor and ask the Contributor to do so and re-issue the pull request, since doing so on the upstream repo could cause update issues for contributors later on. If commits were altered or three-way merge was performed during a merge instead of fast-forward, it's also a good idea to check the log to make sure that the resulting repository history looks OK:

It is therefore strongly recommended that you use the handle_pull_request script that ensures a clean merge. If you still wish to do this manually, please consider reading through the script first to get an idea of what needs to happen.

More information on pulling changes from remote, forked repos can be found in Chapter 5, Section 3 of Pro Git, under Checking Out Remote Branches .

Cutting releases

Releases can only me cut by Project Admins, and must be done off a recently updated (git fetch and git pull origin) clone of the upstream repo. Infinispan's release.py script takes care of the rest.

Committing your work

Release branches

Infinispan has 4 main release branches.  These are master (ongoing work on the 5.0.x series), 4.2.x (ongoing work on the 4.2.x series), 4.1.x and 4.0.x (respective maintenance branches). Work should never be committed directly to any of these release branches; topic branches should always be used for work, and these topic branches should be merged in.

Topic branches

Some of the biggest features of git are speed and efficiency of branching, and accuracy of merging. As a result, best practices involve making frequent use of branches. Creating several topic branches a day, even, should not be considered excessive, and working on several topic branches simultaneously again should be commonplace.

Chapter 3, Section 4 of Pro Git has a detailed discussion of topic branches. For Infinispan, it makes sense to create a topic branch and name it after the JIRA it corresponds to. (if it doesn't correspond to a JIRA, a simple but descriptive name should be used).

Topic Branches Affecting More Than One Release Branch

Most topic branches will only affect a single release branch, e.g. Infinispan 5.0 features only affect the master release branch, so a topic branch should be created based off master. However, occasionally, fixes may apply to both release branches 4.2.x as well as master. In this case, the following workflow should apply:

  • Create topic branch off 4.2.x. For example:
  • Create topic branch off master. For example:
  • Do your work on <topic>_master, test and commit your fixes
  • Switch to {{<topic>_4.2.x}. For example:
  • Cherry-pick your commit on <topic>_master onto <topic>_4.2.x. For example:
  • Test <topic>_4.2.x for correctness, modify as necessary
  • Issue pull requests for both topic branches

Comments

It is extremely important that comments for each commit are clear and follow certain conventions. This allows for proper parsing of logs by git tools. Read this article on how to format comments for git and adhere to them. Further to the recommendations in the article, the short summary of the commit message should be in the following format:

This should be followed by a detailed explanation of the commit.  Why it was done, how much of it. was completed, etc. You may wish to express this as a list, for example:

Commits

Sometimes work on your topic branch may include several commits. For example, committing a test. Then committing another test. Then perhaps committing a fix. And perhaps fixing the fix in the next commit . Before issuing a pull request for this topic branch, consider cleaning up these commits. Interactive rebasing helps you squash several commits into a single commit, which is often more coherent to deal with for others merging in your work. Chapter 6, Section 4 of Pro Git has details on how to squash commits and generally, clean up a series of commits before sharing this work with others.

Also, it is important to make sure you don't accidentally commit files for which no real changes have happened, but rather, whitespace has been modified. This often happens with some IDEs. git diff --check should be run before you issue such a pull request, which will check for such "noise" commits and warn you accordingly. Such files should be reverted and not be committed to the branch.

Further, adhering to Infinispan's code style guidelines will help minimise "noise" commits. Project Admins should feel free to ask contributors to reformat their code if necessary.

Keeping your repo in sync with upstream

If you have cloned upstream

If you have a clone of the upstream, you may want to update it from time to time. Running:

will often do the trick. You could then pull the specific branches you would need to update:

Updating topic branches

You should rebase your topic branches at this point so that they are up-to-date and when pulled by upstream, upstream can fast-forward the release branches:

and/or

If you have forked upstream

If you have a fork of upstream, you should probably define upstream as one of your remotes:

You should now be able to fetch and pull changes from upstream into your local repo, though you should make sure you have no uncommitted changes. (You do use topic branches, right?)

A script can do this for you - have a look at sync_with_upstream.

Updating topic branches

Again, you should rebase your topic branches at this point so that they are up-to-date and when pulled by upstream, upstream can fast-forward the release branches:

and/or

The sync_with_upstream script can do this for you if your topic branch naming conventions match the script.

Tips on enhancing git

Auto-completions

Save this script as /.git-completion.bash and in /.bash_profile, add the following on one line:

After logging out and back in again, typing git <TAB> will give you a list of git commands, as would git c<TAB>, etc. This even works for options, e.g. git commit --<TAB>. The completions are even aware of your refs, so even git checkout my_br<TAB> will complete to git checkout my_branch!

Note that you get git autocompletion for free if you use zsh instead of bash.

Terminal colours

Add the following to your ~/.gitconfig

Aliases

Some git commands are pretty long to type, especially with various switches. Aliases help you to map shortcuts to more complex commands.; Again, For example, add the followin to ~/.gitconfig:

Visual History

Git ships with gitk, a GUI that visually represents a log. If you use Mac OS X, GitX is a good alternative. Try typing gitk or gitx in a git project directory.

Visual diff and merge tools

There are several options available, including KDiff3, meld and Perforce's P4Merge which are all either open source or available for free. See this link on setting these up (section under External Merge and Diff Tools)

Choosing an Editor

You can customise the editor used by git editing ~/.gitconfig. The following fires up MacVIM instead of the default vi editor:

Alternatively, you could fire up TextMate or another editors of your choice.

Shell prompt

You can change your Bash shell prompt to print the current repository's branch name. Add the following to your ~/.bashrc:

The resulting shell prompt will look like:

If you're a ZSH user, you can get even more interesting branch information thanks to this blog post, such as:

  • whether your branch is dirty (⚡)
  • whether it's ahead of the remote(↑)
  • whether it diverges with the remote (↕)
  • whether it's behind (↓)

For example, the following prompt indicates that the current branch is 't_ispn775_master' and that the branch is dirty:

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.