Skip to content
This repository has been archived by the owner on Aug 26, 2020. It is now read-only.

Commit

Permalink
eclipse-rdf4j/rdf4j#2011 added merge strategy steps and motivation
Browse files Browse the repository at this point in the history
- added links between workflow and merge strategy page
- updated workflow in several places to conform to current understanding
  • Loading branch information
abrokenjester committed Apr 1, 2020
1 parent 8625d42 commit 4929d46
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 39 deletions.
1 change: 1 addition & 0 deletions site/content/documentation/developer/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ hide_page_title: "false"
---

- <a href="workflow">Workflow</a>
- <a href="merge-strategy">RDF4J merge strategy</a>
- <a href="squashing">Squashing commits</a>
- <a href="releases">Release management</a>
91 changes: 91 additions & 0 deletions site/content/documentation/developer/merge-strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: "RDF4J merge strategy"
layout: "doc"
---

RDF4J values a clean, linear commit history on our main branches. To achieve this, we default to using [Squash and merge](https://help.github.com/en/github/administering-a-repository/about-merge-methods-on-github#squashing-your-merge-commits) as our merge strategy for all new features, improvements, or bug fixes.

See also: [developer workflow](/documentation/developer/workflow/)

# Self-contained changes, pull requests, and commits

We define a *self-contained change* as a change that addresses a single issue,
addresses it completely, and does not also address other issues.

We expect every pull request to be a self-contained change. Note that that does
not mean that a pull request can only contain a single commit: it can have
several commits that together form a self-contained change.

If a pull request is properly self-contained, merging it using squash and merge
will result in a single, self-contained commit on the main branch that
completely addresses a single issue.

## Commit messages

We prefer every commit message to be descriptive: it should start with the
github issue number to which it relates, then have a short one line description
that details the specific change.

Examples of good commit messages:

- "GH-1234 else condition no longer hits NPE in MyFancyClass"
- "GH-666 added test for corner case where user inputs negative number"

Examples of poor commit messages:

- "typo"
- "GH-666 typo"
- "GH-1234 fixed the problem"

You may ask why we bother with this when we're going to squash everything into
a single commit anyway. We still prefer meaningful commits because:

- it makes reviewing the pull request easier;
- in a squash and merge, each individual commit message is added as a bullet
list point in the description, so it is helpful if it is meaningful even
after squashing.

That said, if occassionally a less "perfect" commit message slips through, that's
fine. We're all human.

And oh yeah: don't forget to [sign off your commits](/documentation/developer/workflow/#patch-requests)!

# Motivation

We use squash and merge because we value a clean, linear history over a more
detailed, accurate history for our main branches. There are several reasons we
value this:

1. it makes the history tree easier to read, with no "branch spaghetti"
2. it makes it more obvious what feature a particular change relates to when
using blame or bisect tools. Because changes are self-contained, every
commit on the main branch relates to a single feature or fix, and the
context of any particular line changed as part of that is immediately
obvious.

A common objection is that using squash and merge, you lose the (potentially
valuable) information the individual commits gave you. This is not quite true:
Github preserves the original commit history on the (closed) pull request page.
Since the squash and merge commit message refers back to this pull request
with a number, it can be easily found back even years later.

For an excellent in-depth discussion of the advantages of using squash and
merge, we recommend reading this blog article: [Two Years of squash
merge](https://blog.dnsimple.com/2019/01/two-years-of-squash-merge/).

# Exceptions

There is one standard exception to the rule: pull requests that involve
bringing our main branches (`master` and `develop`) in sync with each other use
a merge commit. The main reason for this is that here, it is more important to
track progression through time accurately, and we do want to preserve
individual commits.

In very rare cases, by exception, we allow a feature pull request to be merged
using a merge commit. This will only be done if the following conditions are
all met:

1. the author explicitly comments on the pull request that this is necessary (and why), and;
2. the author can show that the PR has been rebased (not merged!) so that the result of the merge will be near-linear, and;
3. the project lead has given explicit approval of the intent to use a merge commit.

2 changes: 1 addition & 1 deletion site/content/documentation/developer/squashing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ layout: "doc"
hide_page_title: "false"
---

When submitting a pull request to RDF4J, we ask that you squash your commits before we merge.
When submitting a pull request to RDF4J, we sometimes ask that you squash your commits before we merge.

On the command line, the process is as follows:

Expand Down
70 changes: 32 additions & 38 deletions site/content/documentation/developer/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ RDF4J strives to apply [Semantic Versioning](http://www.semver.org/) principles

1. We use a `MAJOR.MINOR.PATCH` versioning template.
2. A *PATCH* release (2.2.1, 2.2.2, etc.) is a release that contains only bug fixes that are backwards compatible.
3. A *MINOR* release (2.0, 2.1, 2.2, etc.) is a release that can contain improvements and new features but makes no backward-incompatible changes to existing functionality.
4. A *MAJOR* release (1.0, 2.0, 3.0, etc) is a release that can contain changes to the public API that are not backward compatible.
3. A *MINOR* release (2.0.0, 2.1.0, 2.2.0, etc.) is a release that can contain improvements and new features but makes no backward-incompatible changes to existing functionality.
4. A *MAJOR* release (1.0.0, 2.0.0, 3.0.0, etc) is a release that can contain changes to the public API that are not backward compatible.

It is currently not fully specified what the boundaries of the RDF4J public API are. Until this is resolved (see [issue #619](https://github.com/eclipse/rdf4j/issues/619)), we allow changes to public or protected methods/classes/interfaces in *minor* releases under the following conditions:

Expand All @@ -27,80 +27,74 @@ These conditions are to ensure that existing user code will continue to work whe

For patch releases we never allow changes in the public API, unless the change is specifically to fix a bug that aligns the actual behavior of the code with the publicly documented behavior.

Only release branches (more on those later) include the full major.minor.patch
version numbers included with releases. The major and minor version of the _master_ and
_develop_ branches do not include a patch number and always have a SNAPSHOT tag.
The _master_ and _develop_ versions always matches the pattern *MAJOR*.*MINOR*-SNAPSHOT.

The _master_ version always has the same major and minor number as the latest
release while the _develop_ version uses the next expected major/minor
release number, such as 2.1-SNAPSHOT and 2.2-SNAPSHOT respectively
(after a 2.1.x release, but before any 2.2.x releases are made public).
The main branches (`master` and `develop`) use a SNAPSHOT version number to indicate that they are snapshots on the road to the next version. The `master` version always has the same major and minor number as the latest release, with the patch version incremented by one: for example if the latest release was 3.1.0, the master version will be 3.1.1-SNAPSHOT. The `develop` version uses the next expected major/minor release number, for example 3.2.0-SNAPSHOT.

# Workflow

Every issue, no matter how small, gets its own [issue
ticket](https://github.com/eclipse/rdf4j/issues), and its own branch while
under development. The milestone label of the issue is set to the *planned*
release version for the issue, but that could change by the time a PR is
merged. Issue branch names are always prefixed with `GH-<issuenumber>`,
merged. Issue branch names are always prefixed with `GH-<issuenumber>-`,
followed by one or two dash-separated keywords for the issue.

For example: `GH-1664-transformation-servlet` is the branch for a fix for issue
`GH-1664`, which has to do with the transformation servlet.

RDF4J uses a git branching model where collaborative feature development takes
place on branches from the _develop_ branch. This is where all development for
the next (minor or major) release happens.
place on branches from the `develop` branch. This is where all development for
the next (minor or major) release happens. The `master` branch is reserved for
small bug fixes (to be released in patch/service releases) only.

Once a issue is complete and tested, a *Pull Request* (PR) should be created
for peer review. The Pull Request description should start with a link to the
issue that is addressed by the PR. If the issue is part of a larger feature,
the PR should be branched from (and target) the corresponding branch. If the
issue is a new feature in and of itself, the PR should be branched from (and
target) the _develop_ branch. If the issue is a bug fix, the PR should be
branched from (and target) the _master_ branch.
for peer review. Like the feature branch to which it corresponds, a Pull
Request should be a self-contained change, that is it fixes a single issue.
Don't be tempted to fix several unrelated issues in a single PR please.

The Pull Request description should start with a link to the
issue that is addressed by the PR. If the issue is a new feature or improvment,
the PR should target the `develop` branch. If the issue is a bug fix, the PR
should be branched from (and target) the `master` branch.

Tip: when starting work on an issue, and you are unsure if it will be a new
feature or "just" a bug fix, start by branching from the `master` branch. It
will always be possible to merge your issue branch into `develop` later if
necessary. However, if you start from `develop`, merging into `master` will not
be possible, and you're therefore committed to the next minor/major release.

RDF4J uses 'squash and merge' as its pull request merge strategy, to preserve a
clean history. Read more about our strategy and the motivation for in this
article: [RDF4J merge strategy](/documentation/developer/merge-strategy/).

## Patch Requests

If the change is a bug fix, contains no new features, and does not change any public or protected APIs:

1. Create an issue in our [issue tracker](https://github.com/eclipse/rdf4j/issues) if it doesn't exist yet.
1. Create an issue branch by branching off from the _master_ branch, using `GH-<issuenumber>-short-description` as the branch name convention.
1. Create an issue branch by branching off from the `master` branch, using `GH-<issuenumber>-short-description` as the branch name convention.
2. Make the necessary changes and verify the codebase.
3. [Squash your commits](../squashing).
3. Create a Pull Request that targets the _master_ branch.
3. Optionally [squash your commits](../squashing) to clean up your branch.
3. Create a Pull Request that targets the `master` branch.
4. Peers and project committers now have a chance to review the PR and make suggestions.
5. Any modifications can be made to the _issue_ branch as recommended.
6. Once any necessary changes have been made, project committers can mark the PR as approved.
7. Project committers should then determine what patch release this fix will be included in by updating the milestone label of both the PR and the issue.
8. Only when a Pull Request is approved *and* scheduled for the next patch release it should be merged into the _master_ branch then
9. After a PR has been merged into the _master_ branch, the _master_ branch should
then be merged into the _develop_ branch by the project committer that merged the PR,
any conflicts (such as due to new features) should be resolved.
This can be done from the command line from a clean checkout as follows:

git checkout develop
git pull origin master
git push origin develop
8. Once a Pull Request is approved and scheduled, it can be merged into the `master` branch, using 'squash and merge'.
9. After a PR has been merged into the `master` branch, the `master` branch should
then be merged into the `develop` branch by the project committer that merged the PR,
any conflicts (such as due to new features) should be resolved. This merge should happen using a merge-commit.

## Feature Requests

Pull Requests that add a self contained new feature to the public API follow
the same steps as a Patch Request but should start from and target the _develop_ branch.
Pull Requests that add a self-contained new feature to the public API follow
the same steps as a Patch Request but should target the `develop` branch.
Only PRs that have been scheduled for the next minor release
should be merged into the _develop_ branch.
should be merged into the `develop` branch.

Project committers that are contributing to a branch should periodically
pull changes from the _develop_ branch (either by merging or rebasing) to minimize conflicts later on.
Once a features is complete another PR should be created using the feature branch and target the _develop_ branch.
Then follow similar steps to a patch request to schedule and merge into _develop_.
pull changes from the `develop` branch (by either rebasing or merging) to minimize conflicts later on.
Once a feature is complete a PR should be created using the feature branch and target the `develop` branch.
Then follow similar steps to a patch request to schedule and merge into `develop`, using 'squash and merge'.

Minor and major releases require a formal [release
review](https://www.eclipse.org/projects/handbook/#release-review), and because
Expand Down

0 comments on commit 4929d46

Please sign in to comment.