Chapter 09Lesson 01~185 minutes

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.

Merge methodsMergeabilityGit historyConflictsMerge trainsCI validity

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.
Availability baseline (verified 2026-08-21). Merge commit, merge commit with semi-linear history, fast-forward merge, squash options, ordinary merge-request pipelines, conflict resolution, auto-merge, merge checks such as pipeline/thread requirements, and source-branch cleanup are available on GitLab Free across GitLab.com, Self-Managed, and Dedicated. Merged results pipelines and merge trains are Premium/Ultimate. GitLab 19.2 documents automatic rebase before merge for semi-linear and fast-forward methods as generally available; older Self-Managed versions can differ. The mandatory chapter path therefore uses Free merge methods, local conflict resolution, and ordinary MR/API evidence, while merge trains are optional or simulated.

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

Same proposed change, different target history
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?

What does fast-forward merge add to the target branch?

Why is squash not identical to a merge method?

What API field should automation prefer for the current mergeability reason?

Why preserve the source SHA before branch deletion?

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

Next lesson

Operate two merge outcomes and repair a conflict

Lesson 2 uses a disposable Free project to compare history outcomes, capture mergeability evidence, resolve a real text conflict locally, and model a merge train safely.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.