Frameworks/Git Workflow
KDE Git Workflow
This document outlines a recommended workflow for software maintained in KDE git repositories. It's not mandatory; it still has to be tested and adapted according to the experience we gain with it. But it reflects the results of a series of discussions of members of various groups within and outside of KDE taking into account experience from other projects and the proven workflows of KDE with SVN.
The intention is to have a workflow, which is a natural evolution of the SVN based workflow, providing a simple procedure for simple projects, but being able to scale to complex projects with more sophisticated requirements. The workflow is supposed to keep a constant flow of development, while still accommodating to the needs of being able to release stable code to users.
Basic principles
Master is always ready to release
The master branch is the central branch of completed features and improvements. It is the origin for development branches as well as release branches. Code in master is supposed to be done, tested, and ready for being branched for a release. In theory a distribution should be able to take a snapshot of master, go through their QA procedures, and then give stable packages to end users.
All non-trivial commits should be first done in feature branches, being tested and reviewed, and only then merged to master, when they are done and stable.
Master is never frozen for new features or string changes. These freezes happen in release branches.
Development happens in feature branches
Development of features and bug fixes, which require a significant amount of code changes, happens in feature branches. These branches are branched off master. Developers are free to handle these branches according to their own needs, but when they are merged into master they need to be done, tested and reviewed.
Feature branches are tested and reviewed before being merged to master
When feature branches are merged into master, they need to be done, tested, and reviewed. The level of review depends on the policies of the module, and the significance of the change. Libraries will have stricter policies than leaf modules, central applications with a larger developer base will have stricter policies than smaller applications maintained by single persons.
Ideally broad testing of feature branches happens before being merged to master, including testing by developers who haven't worked on the changes. To facilitate this testing the use of integration branches is recommended, which collect changes from feature branches and make them available to a wider audience.
Integration branches are used for wider testing of feature branches
To make the development happening in individual feature branches available to a wider audience, the use of integration branches is recommended. Integration branches are maintained by individuals or groups of maintainers. They collect changes from feature branches, which are ready for review by fellow developers and which are done to a state where they are considered to be ready by the developer.
Integration branches are supposed to be usable for people who want to use or look at the latest state of development and are willing to report or fix bugs. Integration branches should not contain changes known to be broken. These branches are made visible and accessible to a developer audience beyond the people working on the actual features.
Integration branches are not merged into master. Rather, the branches that were merged into these integration branches are merged directly into master after going through any integration and testing.
Release branches
Release branches are branched off master for doing releases. The branch is made when the release goes into feature and string freeze. No feature development and no string changes are done in release branches. They are there for final stabilization and QA of a release and generating release tarballs. The release branch is tagged with the version number, when creating a release tarball.
Fixes going into the release branches are done in the release branch and then merged to master, so master keeps getting all fixes made in release branches, which apply to master.
Local branches are always rebased, remote branches never
When developing in a local branch, changes should always be rebased before pushing them to the remote origin. This keeps a simple linear history. Rebasing can be thought of as applying changes as patches to the latest version of the code. In case of conflicts they need to be adapted. So developers always patch against the latest version of the code.
Remote branches are shared by multiple people. Rebasing them causes different people to have different versions of history, which causes conflicts, inconsistent and hard to understand states. So remote branches should never be rebased. Merging them properly also reflects that development actually happened in a side line.
Workflow is driven by social contract
The workflow is driven by social contract. All contributors have the same technical access rights. There are no formal roles. Those who do the work decide according to the shared values and principles of the community.
Make what we work on visible to others
To support the social nature of development, it is also recommended that all personal branches are pushed as soon as possible so that others may participate as well. Even if the developer is unsure if the branch will be merged or achieve their goals, branches should be pushed to the central repository during their development.
Procedures
This is a collection of procedures for typical use cases. Details might be different according to the policies of different sub communities, but they should always adhere to the general principles of the KDE Git Workflow. This is not an exhausting or authoritative list, but an illustration of how to apply the basic principles in practice.
Ideally we would have examples with commented git commands how exactly to go through the procedures.
Single developer adding a new feature to a leaf application
- Clone or pull from master branch of application
- Create and checkout a local feature branch
- Work on the code, commit changes to local feature branch
When done:
- Rebase the branch to latest version of master
- Push the changes of the branch to the review tool
- The maintainer or another developer of the application reviews the patch
If approved:
- The developer merges the branch into master, and deletes the local branch
(Note the lack of an integration branch in this case. In the case of smaller projects, the overhead of an integration branch may not be offset by the benefits.)
If rejected:
- Fix issues in the branch and repeat with rebasing when done.
Group of developers adding a new feature to a leaf application
If remote feature branch doesn't exist yet:
- Clone or pull from master branch of application
- Create a remote branch and push it to remote
- Checkout and work in this branch
If remote feature branch already exists:
- Clone or pull from remote feature branch
- Check and work in this branch
When done:
- Rebase the branch to latest version of master
- Push the changes of the branch to the review tool
- The maintainer or another developer of the application reviews the patch
If approved:
- One of the developers merges the branch into master
If rejected:
- Fix issues in the branch and repeat with rebasing when done.
Group of developers adding features to a core application or library
If remote feature branch does not exist yet:
- Clone or pull from master branch of application
- Create a remote branch and push it to remote
- Checkout and work in this branch
If remote feature branch already exists:
- Clone or pull from remote feature branch
- Check and work in this branch
When done:
- Notify maintainer of integration branch
- Maintainer of integration branch merges feature branch into integration branch
- Wider group of developers tests feature in the integration branch
When testing successful:
- Developer pushes the changes of the feature branch to the review tool
- The maintainer or another developer of the application or library reviews the
patches
If approved:
- One of the developers merges the branch into master
If rejected because of a minor issue:
- Fix issues in the feature branch and repeat with rebasing, reviewing
If rejected because of a minor issue:
- Fix issues in the feature branch and repeat with testing in integration branch