Merge Methods, Merge Trains, Mergeability Checks, Conflict Resolution, and Integration Strategies: Concepts, Architecture, and Mental Model
Build a precise mental model of GitLab integration: merge methods shape Git history, mergeability checks gate state transitions, conflicts require semantic resolution, and merge trains validate ordered combinations.
Learning objectives
- Explain how GitLab merge settings translate into concrete Git commit-graph outcomes rather than cosmetic UI choices.
- Distinguish merge commit, semi-linear merge commit, fast-forward, and squash as separate dimensions of integration behavior.
- Read mergeability as a set of independent checks whose current state can be inspected through the MR UI and API.
- Explain why merge-request pipelines, merged-results pipelines, and merge trains validate different candidate states.
- Preserve source/target commit identities before resolving conflicts or deleting source branches.
1. Why the integration method is part of the delivery design
Chapter 08 answered whether a change is allowed to integrate. Chapter 09 asks what happens after authorization. Two teams can review the same source commit and still produce very different target histories: one records an explicit merge commit, another requires a linear fast-forward, and a third squashes ten review commits into one target commit. Those outcomes change rollback, bisecting, release provenance, and the SHA that downstream automation sees.
Integration therefore needs two models at once: Git history tells you which commits and parents exist, while GitLab merge-request state tells you which checks, discussions, pipelines, policies, and permissions permit the transition.
2. Merge methods are commit-graph policies
gitGraph commit id: "A" branch feature commit id: "B" commit id: "C" checkout main commit id: "D" branch merge_commit checkout merge_commit merge feature id: "M" checkout main
The diagram is conceptual: source commits B/C
represent reviewed work, while target branch advancement can
preserve them with a merge commit, require a linear path, or
replace them with a new squash commit. Always inspect the actual
graph after merge.
| Method | GitLab project value | History outcome | Key precondition |
|---|---|---|---|
| Merge commit | merge |
Creates a merge commit for the MR integration. | Can merge divergent histories if no content conflict and checks pass. |
| Semi-linear | rebase_merge |
Creates a merge commit but only after the source can fast-forward from the target line. | Source must be up-to-date/rebasable onto target. |
| Fast-forward | ff |
Moves the target ref to source/rebased commits; no merge commit. | A fast-forward path must exist. |
| Squash | Project/MR squash option | Combines source commits into a new squash commit; may be followed by a merge commit depending on method. | Configured as never/always/default on/default off. |
3. Mergeability is a state machine, not one boolean
A green-looking MR can still be unmergeable. GitLab evaluates
multiple conditions asynchronously. Current REST responses expose
detailed_merge_status; examples include
conflict, draft_status,
ci_must_pass, ci_still_running,
discussions_not_resolved, not_approved,
need_rebase, and mergeable.
Use detailed_merge_status instead of building
automation around the older coarse merge_status.
Because checking is asynchronous, an operator may need to poll after
pushing or rebasing rather than assuming the first API response is
final.
PROJECT_ID="123456"
MR_IID="17"
glab api "projects/$PROJECT_ID/merge_requests/$MR_IID" --jq '{iid,state,draft,sha,source_branch,target_branch,has_conflicts,detailed_merge_status,head_pipeline}'
4. Three pipeline questions that are easy to conflate
An ordinary merge-request pipeline runs against source-branch contents and is Free. It does not validate the source combined with the latest target. A merged results pipeline builds a temporary merged commit combining source and target and is Premium/Ultimate. A merge train orders multiple ready MRs and validates each in the context of earlier train entries, also Premium/Ultimate.
| Evidence | What it validates | What it does not prove |
|---|---|---|
| MR pipeline passed | The tested source-branch state passed configured MR jobs. | That the latest target plus source still passes. |
| Merged results pipeline passed | A temporary source+target merged result passed. | That another MR merging first will not invalidate it. |
| Merge train car passed | The MR passed in its ordered train context. | That unrelated external systems or later policy changes are safe. |
5. Conflict resolution changes code and often commit identity
A merge conflict is not a formatting inconvenience. Git is telling you that it cannot infer the intended combined state. The resolution must preserve the semantic intent of both sides or explicitly choose one. GitLab can resolve certain small UTF-8 text conflicts in the UI, but binary files, large files, path changes, or complex conflict sets require local Git.
The safe sequence is: capture source and target SHAs → fetch both refs → inspect the conflict → decide semantics → resolve → test → commit/rebase → push → re-check the MR. Do not click “use ours” or “use theirs” merely because it removes conflict markers.
6. Source-branch deletion is a lifecycle choice
Deleting a source branch after merge reduces clutter but also removes the easiest named pointer to the pre-merge source tip. The commits may remain reachable from the target or MR metadata, but recovery becomes less convenient. Capture the source SHA, merge/squash SHA, target SHA, and MR URL before deletion when those identities matter.
GitLab can default the “Delete source branch” option for new MRs. For fork-based MRs, the default comes from the fork. Deletion is performed by the merging/auto-merge actor and can fail if that actor lacks permission.
7. Inspect before changing merge behavior
Project settings and MR state are both readable through the API. The project response also reveals whether paid merged-results/train capabilities are enabled.
REPO="GROUP/integration-sandbox"
PROJECT_ID="123456"
glab auth status
glab api "projects/$PROJECT_ID" --jq '{path_with_namespace,default_branch,merge_method,squash_option,only_allow_merge_if_pipeline_succeeds,only_allow_merge_if_all_discussions_are_resolved,remove_source_branch_after_merge,merge_pipelines_enabled,merge_trains_enabled}'
git fetch --all --prune
git log --graph --decorate --oneline --all -n 30
8. DevOps connection: integration policy defines evidence quality
Release automation often keys on a target SHA. Incident response may need to identify which reviewed source produced that SHA. A merge method that teams do not understand creates ambiguity exactly when traceability matters most. The policy should therefore state the intended graph, the pipeline evidence required for that graph, and which identities are recorded before cleanup.
Knowledge check
Why can a passed merge-request pipeline become stale evidence?
It validates the tested source state, while the target can advance afterward. It does not prove the latest source+target result.
What does fast-forward merge add to the target branch?
No merge commit. The target ref advances along the source/rebased commit line when a fast-forward is possible.
Why is squash not identical to a merge method?
Squash controls how source commits are condensed; the project merge method still determines whether the target receives a merge commit or fast-forwards.
What API field should automation prefer for the current mergeability reason?
detailed_merge_status, because it exposes specific gating states such as conflict, need_rebase, or ci_still_running.
Why preserve the source SHA before branch deletion?
The branch is a convenient recovery/evidence pointer. After deletion, commits may still be reachable, but proving the exact reviewed source becomes less convenient.
Summary
GitLab integration is a composition of Git graph policy, mergeability checks, CI evidence, conflict resolution, and branch lifecycle. Merge methods are Free; merged-results pipelines and merge trains are paid. Reliable operators preserve SHAs and prove the post-merge graph rather than assuming the UI label predicts every resulting commit.
Official references
- GitLab Docs — Merge methods
- GitLab Docs — Squash and merge
- GitLab Docs — Merge conflicts
- GitLab Docs — Merge trains
- GitLab Docs — Merged results pipelines
- GitLab Docs — Merge request pipelines
- GitLab Docs — Auto-merge
- GitLab Docs — Merge requests API
- GitLab Docs — Projects API
- GitLab Docs — Project settings
- GitLab Docs — Merge requests
- GitLab Docs — Default branch
- GitLab Docs — Merge trains API
- GitLab Docs — REST API pagination
- GitLab Docs — glab API
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.