Integration Manager Workflows & Pull Requests with Git and Mercurial

Overview

If you are not familiar yet with the basics of Integration Manager Workflow, we suggest you to read the Version Control Workflows page as a pre-requisite.

codeBeamer is the only product on the market that implements the Integration Manager workflow in a DVCS-agnostic way: it enables using the same methodology for both Git and Mercurial teams.

What repositories are the components of this approach?

Based on the illustration:

  • Blessed is a serverside repository, that stores the "official reference" version of the source code. This is typically from which code-base products are built or product instances deployed.
  • Integration manager is the local clone of blessed, used by the team lead, a senior developer or whoever actually integrates changes proposed and sent by the developers.
  • Developer public repositories are serverside forks of blessed. Typically each developer has his own fork.
  • Developer private repositories are clones of the developer public repositories. They physically exists on the developers work stations. Developers work in this repositories, then push their changes back to developer private's and ask the integrator to propagate those to blessed.

Integration Manager Workflow: Demo Video

Here is a HD quality video that is an ideal start for learning the integrator workflow. Get some popcorn, put it to fullscreen (so that the Git commandline operations are readable) and enjoy!

Steps of the Integration Manager Workflow

Forking

You start the workflow by making your public developer fork. To achieve this, just navigate to the blessed repository, click "Fork" in the action bar and enter a meaningful name and some description for your fork.

You can now clone your public developer fork to a local developer private instance like:

git clone <clone-url-of-your-developer-public>
For Mercurial:
hg clone <clone-url-of-your-developer-public>

Start making changes in this clone, commit and push them back to your serverside fork. You will see the changes popping up in the "Changes" tab of your developer public.

Sending Pull Requests

When you reach a point where you want to send your changes back to the blessed repository, navigate to your developer public and click "Send Pull Request". This typically happens when a "story" resulting in multiple changes is completed: a feature is implemented, a bug is fixed and so on.

codeBeamer will now show you the changes you've made since the last merge with the blessed repository. This is the set of changes that you offer for the integrator to bring to blessed repository.

You can give a summary and some description where you explain what is the reason behind the changes, what you actually did, whether it's a risky change to merge, and so on. You can also choose which other users to involve in the integration workflow.

We strongly suggest sending pull requests to multiple integrators, so that they can discuss and review it collaboratively.

Viewing Pull Requests

Pull requests are listed in the "Pull Requests" tab of their target repositories. You can filter them by status and then browse through the lists easily. The count of pending pull requests is also shown in the "repository cards", as this is considered as a very important piece of information.

Accepting and Rejecting Pull Requests

After the pull request is sent, integrators will be notified via email. They can review and discuss the proposed change by commenting on it. A pull request discussion like this is perfect for a quick peer code review.

They can then decide whether to accept (and merge) or reject the changes. If the submitter changes his mind, he has the chance to revoke the pull request, too.

When integrators decide to accept the proposed changes, they can do two things:

  1. If there will be no merge conflict introduced by accepting the change, they can merge it by clicking "Merge" in the web interface.
  2. If there are merge conflicts, codeBeamer allows resolving the conflict by manual merging.

See both situations in details in the following sections.

Closing Pull Requests by Web-based Merging

If the pull request can be merged without conflicts, then you can simply click "Merge" and the contributed changes will be automatically merged into the upstream repository and the status of the pull request will be set to "completed".

(Obviously, this only updates the repositories on your codeBeamer server. To see the fresh state in your local environment, you have to pull everything to your local clone.)

With the changes merged into blessed, the workflow has been completed.

Closing Pull Requests by Manually Resolving Merge Conflicts

Sometimes a pull request can't be automatically merged. In most of the cases, it happens simply when two users modified the same line of the same file concurrently. In this situation, Git obviously can't decide which changes is the "correct" one. Git will detect the conflict, then lets you to manually resolve it.

First, you will have to pull in the changes from the fork:

git pull <name-of-the-remote-that-points-to-the-fork> master
(Please read the next section about configuring remotes if you are not familiar with this.

If you want to fetch from the fork only up to a given changeset just use the following two commands instead of git pull:

git checkout master
git fetch <name-of-the-remote-that-points-to-the-fork> master
git merge <the-last-changeset-id-to-be-merged>

With Mercurial:

hg pull -u <symbolic-name-that-points-to-the-fork>
hg merge
(Please learn more about configuring symbolic names in "hgrc" if you don't know how to do that.)

As a result of the pull, Git will list the files with conflicts. Open the conflicting files in your favourite editor and resolve the changes. After this, you can commit and push everything back to the server:

git commit -a -m "Manually resolving conflicts"
git push
With Mercurial you have to mark all the conflicting files as resolved:
hg resolve -m <file-name>

Then you can commit:

hg commit -m "Manually resolving conflicts"
hg push

The good news is that codeBeamer will automatically detect if there is a pending pull request related to this set of changes. If so, then it will change its status to "completed" without any further user interaction.

With the changes merged into blessed, the workflow has been completed in this case, too.

Synchronizing Your Local Clone with the Upstream Repository

While working on your fork, other team members will contribute changes to the blessed repository, unless you are a solo developer. With your developer private, it's always a good idea to stay as "close" as possible to the blessed repo, otherwise either you or the integrator will face challenging merge conflicts. Long diverging histories have a higher probability to lead to merge conflicts, thus we recommend pulling in the changes from the blessed repository time to time.

How to do this?

Synchronizing with the Upstream using Git

To make your life easier, set up a so-called remote pointing to the upstream repository. You have to do this only once, issuing the following commands in the root directory of the local clone of your fork.
git remote add <name-of-the-remote> <clone-url-of-the-upstream-repository>
For the sake of simplicity, we suggest using the name of the upstream repo as name of the remote.

If you are not sure whether you have already set up the remote, you can easily list the existing remotes:

git remote

When you have the remote in place, you can pull in all changes from the upstream repo executing this any time:

git pull <name-of-the-remote> master

After executing this pull command, your local developer private is in sync with blessed again.

Synchronizing with the Upstream using Mercurial

It's a good idea to setup a symbolic name to point to the upstream repository. This is a one-time operation that can be done by editing the "paths" section in the "hgrc" configuration file.

Just launch your favorite editor like:

vim /path/to/your/local/clone/.hg/hgrc
...and append a line to the "paths" section with the symbolic name like:
[paths]
default = ssh://bond@myserver.com/hg/hgtest-james
hgtest-blessed = ssh://bond@myserver.com/hg/hgtest-blessed

If you want to check if this new name is picked up correctly by Mercurial, or you don't know whether you already created the symbolic name before, you can list the already configured paths any time by:

hg paths

If you registered the symbolic name, it's easier to pull in changes as you can enter the symbolic name instead of the URL of the repository:

hg pull -u hgtest-blessed

After this your clone is synchronized with the blessed repository.

Advanced Integrator Workflows

Integrator Workflows with Multiple Levels: Organization - Team - Developer

In larger teams and deeper hierarchies, it's a powerful approach to set up multiple levels of forks. Say, you are an organization with three teams A, B and C. A has 2 developers, B has 3 and C has 4.

For that setup, you can setup a repository hierarchy like this:

blessed
|
|-- team-a-public
|   |
|   -- joe-public
|   |
|   -- jack-public
|
|-- team-b-public
|   |
|   -- arthur-public
|   |
|   -- charlie-public
|   |
|   -- dave-public
|
|-- team-c-public
    |
    -- mary-public
    |
    -- steve-public
    |
    -- hugh-public
    |
    -- lee-public
With this setup developers send pull request to their own team repository. Team leads decide whether to accept or reject those change. The changes accepted on team level can then be propagated to blessed, where the CTO or the dev lead can review them again. This gives an additional level of control and security.

This approach can be generalized to arbitrary depth.