Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4fc098a
Unfinished first draft
aassuied-ps Nov 19, 2025
3b5b11a
Add branching-strategies to _quarto.yml
aassuied-ps Nov 19, 2025
08db07c
remove article folder
aassuied-ps Nov 19, 2025
00bc774
add devel branch description
aassuied-ps Nov 21, 2025
0bcd298
add common main for all milestones
aassuied-ps Nov 21, 2025
ac7d01e
Update branching-strategies.qmd
aassuied-ps Feb 2, 2026
5c63071
update branching-strategies.qmd
aassuied-ps Feb 12, 2026
0d2ccf1
Update branching-strategies.qmd
aassuied-ps Feb 13, 2026
af0f9ac
Update branching-strategies.qmd
aassuied-ps Feb 16, 2026
13ba34f
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
88f46f4
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
91acadd
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
9776112
Update branching-strategies.qmd
aassuied-ps Feb 24, 2026
1cd49ef
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
db770f9
Update branching-strategies.qmd
aassuied-ps Feb 24, 2026
1fa1867
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
6357c63
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
dac283e
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
1c8fb96
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
7d11efd
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
fcc60c5
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
34761b8
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
6db1ab3
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
81235dc
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
fd5c4d5
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
412ba70
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
791781b
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 24, 2026
8c6b713
Update branching-strategies.qmd
aassuied-ps Feb 25, 2026
8c83a80
Update white-paper/branching-strategies.qmd
aassuied-ps Feb 25, 2026
62579d5
Update branching-strategies.qmd
aassuied-ps Feb 25, 2026
d288875
Update branching-strategies.qmd
aassuied-ps Feb 25, 2026
e8ddc26
Update branching-strategies.qmd
aassuied-ps Feb 26, 2026
2bbf99b
Update white-paper/branching-strategies.qmd
aassuied-ps Mar 5, 2026
539b407
Update white-paper/branching-strategies.qmd
aassuied-ps Mar 5, 2026
cdf4fff
Update white-paper/branching-strategies.qmd
aassuied-ps Mar 5, 2026
76f0564
Update white-paper/branching-strategies.qmd
aassuied-ps Mar 5, 2026
dc51732
Update branching-strategies.qmd
aassuied-ps Mar 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion white-paper/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ book:
- index.qmd
- state.qmd
- Challenges.qmd
- part: "Recommendations"
chapters:
- recommendations.qmd
- branching-strategies.qmd
- audittrail.qmd
- qcintegration.qmd
- recommendations.qmd
- summary.qmd
- references.qmd
appendices:
Expand Down
346 changes: 346 additions & 0 deletions white-paper/branching-strategies.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,346 @@
## Branching Strategies

Defining a branching strategy can be tricky and requires to identify the needs of each repository. While there is no best branching strategies, this part provides a few examples of what could be considered as potential branching strategies.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

There is no need to define one single branching strategy for all of the repository of a company or institution. The choice should be made by type of activity.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

::: callout-tip
### About branches

[This guide](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches) explains what a branch is and how it's working.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated
:::

## Basic git structure

The basic structure of a git repository relies on a principal branch called **main**, which will be duplicated in **feature branches** that will in the end merged back to the main branch through a pull request.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

```{mermaid}
%%| echo: false
%%| eval: false

%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#87CEEB'}}}%%
gitGraph
commit id: "Start"
commit id: "Branch 1"
branch feature-1
checkout feature-1
commit id: "Commit 1a"
checkout main
merge feature-1 tag: "PR: Merge feature-1"
commit id: "Merge 1"

checkout main
commit id: "Branch 2"
branch feature-2
checkout feature-2
commit id: "Commit 2a"
checkout main
merge feature-2 tag: "PR: Merge feature-2"
commit id: "Merge 2"
```

```{mermaid}
%%| label: fig-basic-git-structure
%%| fig-cap: "Basic Git branching structure"
flowchart TD
Comment thread
aassuied-ps marked this conversation as resolved.
main["Main branch"]
feature-1("Feature 1 branch")
feature-2("Feature 2 branch")
PR1>"Pull request"]
PR2>"Pull request"]
main --> feature-1
feature-1 --> PR1
PR1 --> main
main -.-> feature-2
feature-2 -.-> PR2
PR2 -.-> main

linkStyle 0 stroke:#0066FF,stroke-width:2px
linkStyle 1 stroke:#0066FF,stroke-width:2px
linkStyle 2 stroke:#FF6600,stroke-width:3px

linkStyle 3 stroke:#0066FF,stroke-width:2px
linkStyle 4 stroke:#0066FF,stroke-width:2px
linkStyle 5 stroke:#FF6600,stroke-width:3px
```

This branching strategy can be used in the case of a team working on a specific activity of a single clinical study within a repository.

It could potentially be used for a study or a product with several distinct activities using flags (see [Branch locking and flagging](##%20Branch%20locking%20and%20flagging)).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link does not work, as there does not appear to be a section on Branch locking and flagging

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is flagging?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced flag by tagging release.


## Usage of a devel branch

A devel branch is usually a development branch located between the main and other specific development branches. It is used to integrate multiple features and updated before all of those are merged with the main branch. The main objective is to ensure stability of interdependent updates. It is possible that two different features, which work fine in separate branches, may cause conflicts when merged into the same branch. The devel branch is used to integrate all updated features and make any necessary final adjustments before merging into the main branch. It's working as a safety net before the final merge to main.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I linked this one.

Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

The figure below shows an example of the usage of the devel branch. The two feature branches are working without any problem separately, but removing ADAE.ARELGRP1 causes a conflict issue in the devel branch. This conflict should be resolved before merging into main.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the relevance of ADAE.ARELGRP1. It is not in the mermaid diagram.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my bad, sorry. I replaced the diagram but did not use the reference I talked about in the text. For now I'll remove this part of the text and think about a new diagram to show a real conflict.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that this mermaid diagram does not quite capture the message. To me, it is showing that conflicts are expected in the merge from devel to main. I could be wrong, but I imagine that the intention is to show that the two feature branches lead to a conflict in devel. If that is in fact the case, perhaps the label of "Resolve conflicts" could go with the arrow for the PR from Feature 2 to Devel?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to understand. Let's talk about it during the next meeting.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the first image I made for devel.

I understood the conflicts should appear at the devel step, not before.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added Figure 5.3 (label: fig-devel-branch-structure-2). Is that what you were thinking about?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you :)


```{mermaid}
%%| echo: false
%%| eval: false

%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#87CEEB'}}}%%
gitGraph
commit
branch devel
checkout devel
commit
branch feature-1
checkout feature-1
commit
checkout devel
merge feature-1
branch feature-2
checkout feature-2
commit
checkout devel
merge feature-2
checkout main
merge devel
```

```{mermaid}
%%| label: fig-devel-branch-structure
%%| fig-cap: "Devel branch structure"
flowchart TD
main["Main branch"]
devel(["Devel branch"])
feature-1("Feature 1 branch")
feature-2("Feature 2 branch")
pr1>"Pull request"]
pr2>"Pull request"]
main --> devel
devel --> feature-1
devel -.-> feature-2
feature-1 --> pr1
feature-2 -.-> pr2
pr1 --> devel
pr2 -.-> devel
devel ==> |"Resolve conflicts"| main

linkStyle 0 stroke:#0066FF,stroke-width:2px
linkStyle 1 stroke:#0066FF,stroke-width:2px
linkStyle 2 stroke:#0066FF,stroke-width:2px
linkStyle 3 stroke:#0066FF,stroke-width:2px
linkStyle 4 stroke:#0066FF,stroke-width:2px
linkStyle 5 stroke:#0066FF,stroke-width:2px
linkStyle 6 stroke:#0066FF,stroke-width:2px
linkStyle 7 stroke:#FF6600,stroke-width:3px
```

A devel branch is very useful in the following cases:

- Several of different people are working on the same time on different features
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

- The features can present interdependancies
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please expand on this point? Why is having devel advantageous if the features are interdependent? Is it so that resolving conflicts is cleaner?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few sentences to start with. I'm not sure about a deep development on it because the article could be too long. Still I can go more in the detail.


In the case of a single or a little group of persons working together, or when tasks have no interdependancies, the devel branch could be avoided.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

An example of workflow using a devel branch is detailled at [this link](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow).
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

## One main branch duplicated per milestone

Several clinical studies relies on the same base programs for several milestone, while some milestones require some specific programs. Storing everything in the main branch and duplicate it for the final step of a milestone is an option.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe some extra words on how the copies are locked for a particular reporting event

Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

```{mermaid}
%%| label: fig-dup-milestone-branch-structure
%%| fig-cap: "Main branch duplicated per milestone structure"
flowchart TB
main["Main branch"]
csr(["CSR"])
dmc1(["DMC #1"])
dmc2(["DMC #2"])
main -.-> csr
main -.-> dmc1
main -.-> dmc2
flag_csr[("Flag #1")]
flag_dmc1[("Flag #2")]
flag_dmc2[("Flag #3")]
csr -.-> flag_csr
dmc1 -.-> flag_dmc1
dmc2 -.-> flag_dmc2
```

```{mermaid}
%%| echo: false
%%| eval: false
flowchart TB
subgraph Main["Main Branch"]
main["Main Branch"]
feature-1["Feature #1"]
pr1["Pull request"]
main --> feature-1
feature-1 --> pr1
pr1 --> main
feature-2["Feature #2"]
pr2["Pull request"]
main --> feature-2
feature-2 --> pr2
pr2 --> main
end

subgraph Milestones["Tag releases"]
milestone-1["DMC branch"]
milestone-2["CSR branch"]
tag-1["Tag #1"]
tag-2["Tag #2"]
main --> milestone-1
main --> milestone-2
milestone-1 --> tag-1
milestone-2 --> tag-2
end
```

Several possibilities can be applied. The most common is to use a tag release on the main branch to identify the milestone. It will save the main branch and clearly identify it as a milestone reached. This link provides more details about [tagging releases](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository/managing-releases-in-a-repository) on GitHub. Similar actions can be performed on other source code management platforms.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

Another way is to duplicate the main branch and use a flag to identify the milestone, with the possibility to lock it. A branch can be locked using a [protection rule (see #13)](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule#creating-a-branch-protection-rule).

## One main branch per milestone

A single study often needs to deal with different activities, sometime happening at the same moment. One potential way to use git in theses cases could be to have:
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

- 1 repository for the study

- **1 main branch per activity** (CSR, DMC #n, DSUR, etc)

This branching strategy would allow to work separately on each activity, keeping them intact, but also to work on both at the same moment if needed. The following examples shows a repository dedicated to a single study with the 2 following main branches:
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

- CSR: for daily ongoing activities related to the CSR preparation

- DMC #1: specific milestone happening soon

Two issues are handled at the same moment. Issue #1 is dedicated to an efficacy endpoint that should not be part of the DMC, while Issue #2 is stricly dedicated to the DMC activity and will not be part of the final CSR outputs.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

```{mermaid}
%%| label: fig-milestone-branch-structure
%%| fig-cap: "One branch per milestone structure"
flowchart TD
csr["CSR"]
dmc["DMC"]
branch-1("Branch #1")
branch-2("Branch #2")
pr1>"Pull request"]
pr2>"Pull request"]
csr --> branch-1
dmc --> branch-2
branch-1 --> pr1
pr1 --> |"Merge #1"| csr
branch-2 --> pr2
pr2 --> |"Merge #2"| dmc
```

### Common issue

If something common to more than one of the main branches should be made, it is possible to make as much pull requests as requested. The only tricky part is to define the source branch. In this example, we take the CSR.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

```{mermaid}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would show two pull requests. i.e., CSR -> Common issue branch -> PR 1 -> CSR; but then also have PR 2 going from Common issue branch to DMC. The current diagram implies there is only one PR, which somehow leads to the CSR and the DMC

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. I updated the diagram.

%%| label: fig-common-issue-branch-structure
%%| fig-cap: "Common issue branch structure"
flowchart TB
csr["CSR"]
dmc["DMC"]

branch-c("Common issue branch")
prc>"Pull request"]

csr --> branch-c --> prc

prc --> csr
prc --> dmc
```

```{mermaid}
%%| echo: false
%%| eval: false
flowchart TB
subgraph Top[" "]
direction LR
csr["CSR"]
dmc["DMC"]
end
branch-c("Common issue branch")
prc>"Pull request"]
csr --> branch-c
branch-c --> prc
prc -->|"Merge common issue"| csr
prc -->|"Merge common issue"| dmc
```

## Hot fixes

Hot fixes are urgent corrections that need to be applied to a specific milestone that has already been released or tagged. These fixes are typically critical bugs or issues discovered after a milestone has been finalized and need immediate attention.

It should focus only on the **resolution** of the critical issue, and **prevent** it to happen again. It should be **clearly documented and tested**, even given the urgency of the fix.
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

Hot fixes are essential for maintaining the integrity of released milestones while allowing development to continue on the main branch without disruption.

[This article](https://rem-baba.medium.com/if-youre-always-hotfixing-you-re-never-fixing-the-real-problem-bc7eb2b28eb0) gives more details about hot fixes and how to avoid them.

When working with milestone branches, hot fixes can be applied in different ways depending on the branching strategy used:

### Hot fixes with tagged milestones

When milestones are identified using tags on the main branch, a hot fix should be created from the specific tag, applied, and then merged back to main. This ensures the fix is available for future milestones while also addressing the specific tagged milestone.

```{mermaid}
%%| label: fig-hotfix-tagged-structure
%%| fig-cap: "Hot fix workflow with tagged milestones"
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#87CEEB'}}}%%
gitGraph
commit id: "Initial"
commit id: "Milestone 1"
commit id: "Tag: v1.0"
commit id: "Continue dev"
branch hotfix-1.0.1
checkout hotfix-1.0.1
commit id: "Hot fix"
checkout main
merge hotfix-1.0.1 tag: "PR: Hot fix"
commit id: "Tag: v1.0.1"
```

### Hot fixes with milestone branches

When using separate milestone branches (e.g., CSR, DMC), hot fixes should be created from the specific milestone branch, applied, and then merged back to that milestone branch. If the fix is also relevant for other milestones or the main development branch, it can be cherry-picked or merged to those branches as well.

```{mermaid}
%%| label: fig-hotfix-milestone-structure
%%| fig-cap: "Hot fix workflow with milestone branches"
flowchart TB
milestone["Milestone branch<br/>(e.g., DMC #1)"]
hotfix("Hot fix branch")
pr>"Pull request"]
milestone --> hotfix
hotfix --> pr
pr -->|"Merge hot fix"| milestone

main["Main branch"]
pr -->|"Cherry-pick or merge"| main
```

[This article](https://www.atlassian.com/git/tutorials/cherry-pick) provides more details about cherry-picking when using a devel branch.

## Pros and cons

Many other strategies can be defined, and the choice depends on the needs of each study team. Also, some of the strategies displayed above can be combined (for instance using a deven branch with a milestone main branch strategy).
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

Here is a summary of the different pros and cons of the different strategies presented above:
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated

+-----------------------------------+----------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
| strategy | pros | cons |
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated
+===================================+============================================================================+===============================================================================================================+
| **devel branch** | - Safety net before merging into main | - Not as instantaneous merge into main, takes more time |
Comment thread
aassuied-ps marked this conversation as resolved.
Outdated
| | | |
| | - Useful when multiple branches are active and merged at the same moment | - Not very useful when a few people are working at the same moment on a project |
+-----------------------------------+----------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
| **Main branch duplicated** | - Only one branch to maintain | - Files tagged for a milestone its do not belong to |
| | | |
| | - Useful when most of the files are common to several milestones | or |
| | | |
| | | - Need to identify and remove files when duplicating and tag the main branch |
+-----------------------------------+----------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
| **One main branch per milestone** | - Clear difference between milestones | - Several branches to maintain |
| | | |
| | - No risk to have file located in the wrong milestone branch | - Intermediate branches regarding files common to several milestone must be merged once for each milestone |
| | | |
| | - Useful when milestones have really different files to run | |
+-----------------------------------+----------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I think this looks great! I think it covers all of the various branching strategies that I have used. Thanks for your hard work on this

Binary file added white-paper/pictures/bs-01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added white-paper/pictures/bs-01b.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added white-paper/pictures/bs-01c.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added white-paper/pictures/bs-02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added white-paper/pictures/bs-03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.