Fast-forward merge support for Merge Trains
Problem to solve
Merge Trains could help solve a fundamental contention problem of fast forward merges because the CI pipeline must be run everytime the merge request is rebased, and the merge request must be rebased every time master
changes - which is frequently! This significantly limits the frequency with which merge requests can be merged.
Further details
When a merge request is created or updated, refs/merge-requests/$iid/merge
will be generated with the merge result. Currently this is always generated using the merge
merge method, regardless of the project settings. A more accurate merge ref should probably be generated #26996 (closed).
But the merge-ref is not the whole story. The merge ref is ephemeral and does not impact the contents of the branch. In order to actually complete the merge, the merge train also needs to rebase the actual feature branch, and then merge.
Fast-forward merge | Merge Train |
---|---|
- User creates a merge request awesome-feature from the tip of master branch. - Someone merged the other merge request into master . Now master branch is advanced. - Now the awesome-feature branch is outdated thus it cannot be merged. - User pulls the latest master branch, rebases awesome-feature on the master manually, and push it to the remote repository. - Once the pipeline passed, awesome-feature can be merged manually. |
- User creates a merge request awesome-feature from the tip of master branch. - User added the merge request on merge train. - Someone merged the other merge request into master . Now master branch is advanced. - Merge Train reconstruct the cascading-refs and re-run pipelines automatically. - Once the pipeline passed, awesome-feature is merged automatically. |
Current problem
Merge Trains with Fast Forward Merge
- User creates a merge request
awesome-feature
from the tip ofmaster
branch. - User added the merge request on merge train.
- Someone merged the other merge request into
master
. Nowmaster
branch is advanced. - Now the
awesome-feature
branch is outdated thus it cannot be merged. - Merge Train tries to reconstruct the cascading-refs but the merge request is not mergeable thus the merge request is dropped from the merge train.
Proposal
Fast-forward with merge train When the fast-forward merge (--ff-only) setting is enabled in the project settings & merge trains are enabled, no merge commits will be created and all merges that are part of the merge train are fast-forwarded, which means that merging is only allowed if the branch can be fast-forwarded.
Rebase with merge train When a fast-forward merge with merge train is not possible, the application will try to rebase - this will rebase the entire merge train. Rebasing on merge train should happen automatically and shouldn't require a manual action from users.
NOTE: "Semi-linear history merge requests" should be also supported
Project settings > General > Merge request section
-
Add a new line of copy to the
Fast-forward merge
option explaining if it activated together with merge trains, merge is only allowed if the branch can be fast-forwarded- Once merge trains are enabled, merging is only allowed if the branch can be fast forwarded
-
Add a link to the documentation page: NEW SECTION ON DOCS, NEEDS TO BE CREATED cc @marcia
-
Update the copy for
merge pipelines
and add link to merge trains documentation- Enables merge train by default. Merge pipelines will try to validate the post-merge result prior to merging
-
Add a link to the documentation page: https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/
Merge request page
Fast-forward with merge train fails:
- A message should be added to the
system notes
in the merge request.
Rebase with merge train fails:
- A message should be added to the
system notes
in the merge request.
Fast-forward / Rebase with merge train succeeds:
- A message should be added to the
system notes
in the merge request. - @dosuken123 to check: An existing rebase/ff-merge feature already provides some system notes for the usage, so we might not need to add extra ones in merge train context.
Workflow 1
- User adds an MR to a merge train.
- Merge Train creates a new pipeline and validates the MR.
- Merge Train rebases the MR onto the latest master.
- If succeed, continue.
- If failed, drops the MR from the train. A message should be added to the
system notes
in the merge request.
- Merge Train merges the MR with Fast Forward option.
- If succeed, the process complete.
- If failed, drops the MR from the train. A message should be added to the
system notes
in the merge request.
Users might want to bypass a merge train exceptionally, and merge immediately instead. This path should also be supported.
Workflow 2
- User adds an MR to a merge train by clicking "Start/Add merge train" button (and the merge train takes care of the rebase + ff-merge)
- Note: Applicable on Add/Start Merge Train /When Pipeline Succeeds states.
- User wants to merge an MR immediately by clicking "Merge" button (e.g. There is an urgent patch needs to be merged asap).
- If the MR is not on top of the latest master, users have to rebase the MR at first by clicking "Rebase" button. (i.e. How ff-merge option works today)
On the MR widget, the dropdown should be updated when rebasing manually is an option for the following criteria:
If the feature branch is NOT on the latest master:
-
Start/Add merge train
button (primary) -
Rebase
dropdown menu option (should substitute the optionmerge immediately
Documentation
Yes, we will need to make updates to the documentation.
Links / references
Please track the status of this issue through the following epic: &4911 (closed)