Git Branches and Merges
This document provides a comprehensive overview of the branching and merging concepts in Git.
Branching Model
We use a two-branch workflow in the NFDI4Immuno projects/repositories:
main: Production-ready code, releases onlydevelopment: Active development, all features merge from and to here first
When we're ready for a release, we merge development into main before continuing further development form the development-branch.
We are using an Issues-First approach so that every piece of work starts with an issue. This ensures:
- All work is documented and tracked
- Changes are discussed before implementation
- Understanding the "why" behind the changes is straight forward
- Project management and progress tracking are clear
What is a Branch?
A branch represents an independent line of development within a repository. It can be viewed as a snapshot of the project at a specific point in time, allowing work to proceed on new features, bug fixes, or experiments without affecting the main codebase.
Once the work on a branch is complete and verified, it can be merged back into the primary development branch, integrating the new changes.
Example: The main branch contains the stable version of the project. The branch development has been created from main a long time ago. A developer creates a branch named feature-branch-1 to fix a problem. Another developer later creates feature-branch-2 to fix some typos. Both branches have the same starting point in the development branch.
gitGraph
commit id: "Project initialization"
branch development
commit id: "Some previous commit"
branch feature-branch-1
branch feature-branch-2
checkout feature-branch-1
commit id: "Commit 1"
commit id: "Commit 2"
checkout feature-branch-2
commit id: "Fix typo 1"
commit id: "Fix typo 2"
commit id: "Fix typo 3"
In the example above there are four branches: main, development, feature-branch-1, and feature-branch-2. feature-branch-1, and feature-branch-2 grew off development. feature-branch-1 contains two changes (Commit 1 and 2) and feature-branch-2 contains three changes (Fix typo 1-3). The commit 1 and 2 do not exist in feature-branch-2.
What is a Merge Request (MR)?
A Merge Request (MR) is a formal proposal to integrate changes from one branch into another, typically from a feature branch into the development branch.
The MR process serves as a checkpoint where collaborators can:
- Review the proposed changes
- Discuss implementation details
- Verify compliance with coding standards and test coverage
- Approve or request revisions before integration
Example: After completing the feature-branch-1 branch, the developer opens a Merge Request to merge it into the development branch. This enables review and approve the work before it becomes part of the shared codebase.
gitGraph
commit id: "Project initialization"
branch development
commit id: "Some previous commit"
branch feature-branch-1
branch feature-branch-2
checkout feature-branch-1
commit id: "Commit 1"
commit id: "Commit 2"
checkout feature-branch-2
commit id: "Fix typo 1"
commit id: "Fix typo 2"
commit id: "Fix typo 3"
checkout development
merge feature-branch-1
The development branch now contains the two changes from feature-branch-1 (Commit 1 and 2). Before merging feature-branch-2 a developer creates a new branch feature-branch-3. This branch contains Commit 1 and 2 from the development branch. Afterwards feature-branch-2 is merged to development which contains Fix typo 1-3 in addition to Commit 1 and 2.
gitGraph
commit id: "Project initialization"
branch development
commit id: "Some previous commit"
branch feature-branch-1
branch feature-branch-2
checkout feature-branch-1
commit id: "Commit 1"
commit id: "Commit 2"
checkout feature-branch-2
commit id: "Fix typo 1"
commit id: "Fix typo 2"
commit id: "Fix typo 3"
checkout development
merge feature-branch-1
branch feature-branch-3
checkout feature-branch-3
commit id: "Commit on feature 3"
checkout development
merge feature-branch-2
Merging the typo fixes was the last things needed for a release, so development is merged into main. The main branch now contains everything from the development branch, but not the change from feature-branch-3. This branch is later merged into development.
gitGraph
commit id: "Project initialization"
branch development
commit id: "Some previous commit"
branch feature-branch-1
branch feature-branch-2
checkout feature-branch-1
commit id: "Commit 1"
commit id: "Commit 2"
checkout feature-branch-2
commit id: "Fix typo 1"
commit id: "Fix typo 2"
commit id: "Fix typo 3"
checkout development
merge feature-branch-1
branch feature-branch-3
checkout feature-branch-3
commit id: "Commit on feature 3"
checkout development
merge feature-branch-2
checkout main
merge development
checkout development
merge feature-branch-3