Skip to content

Workflow

Derek Bruening edited this page Mar 12, 2017 · 6 revisions

Dr. Memory Development Workflow

We use a centralized rebase workflow for our "master" branch combined with feature and project branches. Each commit destined for master is first pushed to a feature branch and then fast-forward-merged from there to master. Larger features are similarly built from feature branches being fast-forward-merged into a project branch, with a later rebase from the project branch onto master.

No local changes should be made to the local "master" branch: all changes should occur on a feature branch. For simplicity, pulls and pushes are done directly on the feature branch, so normally the local "master" branch is rarely used.

Code reviews use pull requests.

Getting the Code

Clone the repository, either via ssh if you've set up ssh keys in your Github profile:

git clone [email protected]:DynamoRIO/drmemory.git

Or via https:

git clone https://github.com/DynamoRIO/drmemory.git

Configuring Author Information and Aliases

Before doing anything on a fresh clone, run the development setup script (commands for updating and for code reviews depend on it):

make/git/devsetup.sh

Additionally, make sure that your full name is listed in the Name field at https://github.com/settings/profile and that a legitimate email address that represents you is set as your primary Github address at https://github.com/settings/emails. Those two fields will be used for the author line for pull requests when they are squash-and-merged into master. You must also uncheck Keep my email address private in the email settings page.

Working on a Small Feature or Bug Fix

Small features or bug fixes, i.e., those that will become a single commit in the master branch, use "feature branches".

Ensure origin is up to date:

git fetch origin

Then create a new branch for the feature or bug fix, called a "feature" branch. Replace "NNNN" with the issue number and "myfeature" with a name of your choice following the naming conventions below:

git newbranch iNNNN-myfeature

Now perform your work in the feature branch, committing locally.

Branch Naming Conventions

For a small feature or bug fix, the name should start with the issue number prefixed by i, followed by a dash, followed by a short description. For example, i2172-maps-parsing or i2157-reattach. If there is no filed issue, use the iX- prefix. For example, iX-fix-readme-typo.

Although often a feature branch is short-lived, sometimes experimental work is not able to be finished immediately and there is value in sharing the code so that others can pick up on it. This is the logic behind using descriptive names for feature branches.

For a major project branch (see below), the name should start with project-. For example, project-mac64 or project-powerpc.

Merging upstream changes

The git pullall alias runs a script that does the right type of update depending on whether you're in a feature branch that has not yet been pushed to the Github repository (where we want a rebase) or in a branch that has already been pushed (where we want to rebase from the remote feature branch and merge from the upstream master).

Thus, to update your current feature branch with the latest content in both the upstream master and in the remote feature branch, if it exists, simply execute:

git pullall

After you've shared the branch for review, it is fine to not bother to update to master prior to the final merge, relying on Github's Update Branch button at the time of the merge. If you do need to update from master for some local testing, it's best to use a merge rather than a rebase to avoid losing history in the pull request, and git pullall will make sure that a merge is used. Don't worry about merge commits in feature branches: they'll be removed in the final squash-and-fast-forward-merge step onto master.

If you've pressed the Github button to update the feature branch with changes from master, and you now want to add a commit to your local branch (or have already added one), you want to pull the Github-added commit from the feature branch rather than master as a rebase. As mentioned, git pullall does that for you (along with updating from master).

Submodule rollback

Be careful with submodules when pulling upstream changes. If a submodule was modified upstream and only a git pull is run without a subsequent git submodule update, that upstream change will be reverted upon the next git push. Please use the pullall alias to avoid accidentally clobbering submodule changes.

We do have a pre-commit hook in place that will warn you if you try to roll back the dynamorio submodule while checking in at least one other file:

% git commit -a
Error: the dynamorio submodule is being rolled back.
This is likely a mistake: did you pull but not run git submodule update?
Aborting commit.

Updating DynamoRIO

Run git checkout <hash> to update DynamoRIO to that hash:

cd dynamorio
git checkout 0c81acfc9aaea949e6f6ecfe0b4157c06a014dda

For more details, see UpdatingDR.

Requesting a Code Review and Merging to Master

Code reviews are requested by pushing the feature branch to Github and then creating a pull request onto master. See code review details here. Merges to master occur only via pull request.

Deleting a Feature Branch

Once your changes have been merged into master, you can delete your feature branch with these commands (substituting your branch's name for "feature"):

git checkout master
git pullall
git branch -d feature

Checking Out an Existing Feature Branch

You can check out an existing feature branch iNNNN-name via:

git fetch origin
git checkout iNNNN-name

This is equivalent to:

git fetch origin
git checkout -b iNNNN-name remotes/origin/iNNNN-name

Splitting Up a Feature Branch

If you want to split off the first commit or two from a feature branch and you issue a command like this:

git checkout -b tocheckin 35d4e9c87de22ec9b3a8a110cae2d83821c88ee0

The tocheckin branch will not be a tracking branch. You'll need to issue this command:

git branch --set-upstream-to=origin/master tocheckin

If you've run the development setup script, you can run both commands at once with:

git split tocheckin 35d4e9c87de22ec9b3a8a110cae2d83821c88ee0

Project Branches

For larger features that will end up as multiple commits to master, project branches are used. The workflow for adding small features to the project branch mirror the workflow described above, substituting the project branch for master. Once the project is ready to be merged into master, the project branch is rebased onto the master branch via a pull request.

When updating project branches with the latest changes from master, be sure to merge rather than rebase, to avoid rewriting history in a shared branch. Once the project branch is ready to be merged into master, the merge commits need to be removed before creating the final pull request. This can be done by creating a new branch and cherry-picking the commits to be rebased onto master.

It is also possible to stage large features as multiple incremental commits that are each merged into master. For work shared among multiple developers, or work spanning long periods of time, or highly experimental work, we prefer using project branches, to provide visibility into ongoing projects and to enable other developers to try out new code or contribute to new projects.

Useful Aliases

Some potentially useful aliases that are not in the development setup script include the common tasks of looking at the log of changes versus the remote master:

git config alias.dlog "log --stat origin/master.."

And looking at the full diff versus the remote master:

git config alias.ddiff "diff origin/master.."

No Merge Commits on Master

Our workflow uses fast-forward-merge and rebase when merging into the master branch. We do not want any merge commits on master or on project branches: we want a nice clean line of history. Merge commits on feature branches are fine as they will disappear upon merging into master.