16 KiB
GitLab Merge Requests Reference
Overview
Merge Requests (MRs) are the primary mechanism for proposing changes, conducting code reviews, and merging code in GitLab.
Creating Merge Requests
Via UI
- Navigate to project
- Create/push to branch
- Click "Create merge request"
- Fill in details:
- Title and description
- Source and target branches
- Assignees and reviewers
- Labels and milestone
- Click "Create merge request"
Via API
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests" \
--data "source_branch=feature" \
--data "target_branch=main" \
--data "title=Add new feature" \
--data "description=This MR adds..." \
--data "assignee_id=123" \
--data "reviewer_ids[]=456"
Via Git Push Options
# Create MR on push
git push -o merge_request.create \
-o merge_request.target=main \
-o merge_request.title="Add feature" \
origin feature-branch
# Create and assign
git push -o merge_request.create \
-o merge_request.assign="username" \
origin feature-branch
# Create with labels
git push -o merge_request.create \
-o merge_request.label="bug" \
-o merge_request.label="priority::high" \
origin feature-branch
Via CLI
# Using glab
glab mr create --title "Add feature" \
--description "Detailed description" \
--source feature-branch \
--target main \
--assignee @username \
--label bug,feature
Merge Request Details
Basic Information
Title: Add user authentication
Description: |
Implements JWT authentication for API endpoints.
Changes:
- Add JWT middleware
- Add auth routes
- Add user model
- Add tests
Closes #123
Source Branch: feature/auth
Target Branch: main
Author: @john
Assignee: @jane
Reviewers: @alice, @bob
Labels: feature, security
Milestone: v1.0
Closing Issues
Link issues in description:
Closes #123Fixes #456Resolves #789Implements #101
Description Templates
Create .gitlab/merge_request_templates/Default.md:
## What does this MR do?
<!-- Brief description -->
## Related issues
<!-- Link related issues -->
Closes #
## Author's checklist
- [ ] Tests added
- [ ] Documentation updated
- [ ] Changelog entry added
- [ ] Reviewed by peers
## Reviewer's checklist
- [ ] Code follows style guide
- [ ] Tests pass
- [ ] No security issues
- [ ] Performance acceptable
Merge Request Workflow
Draft/WIP Merge Requests
Mark as draft:
# In title
Draft: Add feature
WIP: Add feature
# Via API
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "draft=true"
Remove draft status:
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "draft=false"
Assignees and Reviewers
Assignees: Responsible for the MR Reviewers: Review and approve the MR
# Set assignees
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "assignee_ids[]=123" \
--data "assignee_ids[]=456"
# Set reviewers
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "reviewer_ids[]=789"
Labels and Milestones
# Add labels
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "labels=bug,feature,priority::high"
# Set milestone
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "milestone_id=10"
Code Review
Comments and Discussions
Add comment:
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/notes" \
--data "body=Looks good!"
Add line comment:
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/discussions" \
--data "body=Consider refactoring this" \
--data "position[base_sha]=abc123" \
--data "position[start_sha]=def456" \
--data "position[head_sha]=ghi789" \
--data "position[new_path]=src/file.js" \
--data "position[new_line]=42" \
--data "position[position_type]=text"
Resolvable Discussions
Mark discussions as resolvable:
- Reviewer creates resolvable discussion
- Author resolves after fixing
- Must resolve all before merging (if required)
# Resolve discussion
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/discussions/:discussion_id" \
--data "resolved=true"
Suggestions
Apply code suggestions in reviews:
```suggestion
const result = calculate(x, y);
return result * 2;
Apply suggestion:
- Click "Apply suggestion" button
- Or use API to apply
**Batch apply suggestions**:
1. Select multiple suggestions
2. Click "Apply X suggestions"
3. Commit with single commit
### Code Quality Reports
View code quality changes:
- New issues introduced
- Resolved issues
- Code quality score
Requires CI/CD job with code quality report:
```yaml
code_quality:
image: docker:stable
services:
- docker:stable-dind
script:
- docker run --env SOURCE_CODE="$PWD" --volume "$PWD":/code \
--volume /var/run/docker.sock:/var/run/docker.sock \
registry.gitlab.com/gitlab-org/ci-cd/codequality:latest /code
artifacts:
reports:
codequality: gl-code-quality-report.json
Merge Request Approvals
Configure Approval Rules
Via UI:
- Project Settings > Merge requests > Approval rules
- Add rule
- Set required approvers
- Set approval count
Via API:
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/approval_rules" \
--data "name=Security Review" \
--data "approvals_required=2" \
--data "user_ids[]=123" \
--data "user_ids[]=456"
Approve Merge Request
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/approve"
Unapprove
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/unapprove"
Approval Settings
Require approvals:
- Number of approvals needed
- Eligible approvers
- Approval groups
- Code owner approvals
Prevent self-approval:
- Author cannot approve own MR
Prevent committer approval:
- Users who committed cannot approve
Require new approvals when pushed:
- Reset approvals on new commits
Merge Strategies
Merge Commit
Creates merge commit with two parents:
C---D feature
/ \
A---B-------E main
Fast-Forward Merge
No merge commit when possible:
A---B---C---D main
(was feature)
Squash and Merge
Combines all commits into one:
A---B---C main
(squashed feature commits)
Configure in MR:
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid" \
--data "squash=true"
Semi-Linear Merge
Rebase then merge (no fast-forward):
C'--D' feature
/ \
A---B-------E main
Merging
Merge When Pipeline Succeeds
Automatically merge after pipeline passes:
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/merge" \
--data "merge_when_pipeline_succeeds=true" \
--data "should_remove_source_branch=true"
Manual Merge
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/merge" \
--data "squash=true" \
--data "should_remove_source_branch=true" \
--data "merge_commit_message=Custom merge message"
Merge Trains
Queue merges to prevent breaking main branch:
Enable merge trains:
- Project Settings > Merge requests
- Enable "Merged results pipelines"
- Enable "Merge trains"
Benefits:
- Serialized merging
- Pipeline runs against merged result
- Prevents breaking main branch
- Automatic rebase
Merge Conflicts
View Conflicts
curl --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/conflicts"
Resolve Conflicts via UI
- View MR with conflicts
- Click "Resolve conflicts"
- Choose conflict resolution
- Commit resolution
Resolve Conflicts Locally
# Fetch latest changes
git fetch origin
# Checkout source branch
git checkout feature-branch
# Merge or rebase
git merge origin/main
# or
git rebase origin/main
# Resolve conflicts in files
# Add resolved files
git add .
# Complete merge/rebase
git commit # for merge
git rebase --continue # for rebase
# Push
git push origin feature-branch
Merge Request Diff
View Diff
curl --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid/changes"
Diff Options
- Inline diff: Side-by-side comparison
- Side-by-side diff: Parallel view
- File by file: Navigate file by file
- Ignore whitespace: Skip whitespace changes
Download Patch
curl --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid.patch" \
-o merge_request.patch
Download Diff
curl --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid.diff" \
-o merge_request.diff
Merge Request Pipelines
Pipeline for Merged Results
Test merge result before merging:
.gitlab-ci.yml:
workflow:
rules:
- if: $CI_MERGE_REQUEST_ID
when: always
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
Require Pipeline Success
Configure in project settings:
- Pipelines must succeed
- Required successful jobs
Merge Request Dependencies
Depend on Another MR
Use cross-references in description:
Depends on !123
Blocked by !456
Merge Request Metrics
View Metrics
curl --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests/:mr_iid"
Metrics include:
- Time to merge
- First comment time
- First approve time
- Review time
- Diff stats (additions/deletions)
Merge Request Analytics
Project level:
- Average time to merge
- Throughput
- Open MRs over time
Group level (Premium/Ultimate):
- Cross-project metrics
- Team performance
- Bottleneck identification
Merge Request Automation
Quick Actions
Use in comments:
/approve- Approve MR/merge- Merge MR/close- Close MR/reopen- Reopen MR/assign @user- Assign to user/unassign- Remove assignee/label ~bug- Add label/unlabel ~bug- Remove label/milestone %v1.0- Set milestone/due 2025-12-31- Set due date/estimate 2h- Set time estimate/spend 1h- Add time spent/draft- Mark as draft/ready- Remove draft status
Merge Request Webhooks
Trigger automation on MR events:
# Example CI/CD trigger
review-app:
script:
- deploy-review-app.sh
only:
- merge_requests
environment:
name: review/$CI_MERGE_REQUEST_IID
url: https://$CI_MERGE_REQUEST_IID.review.example.com
on_stop: stop-review-app
Code Owners
CODEOWNERS File
Create .gitlab/CODEOWNERS:
# Backend team owns all .rb files
*.rb @backend-team
# Frontend team owns React components
/src/components/ @frontend-team
# DevOps owns CI/CD config
/.gitlab-ci.yml @devops
/docker/ @devops
# Security team must approve sensitive files
/config/secrets/ @security-team
/lib/auth/ @security-team
# Everyone in group must approve
/docs/ @group/docs-team
Syntax:
path @user- User approvalpath @group- Group approvalpath @group/subgroup- Subgroup approval
Require Code Owner Approval
- Project Settings > Merge requests
- Enable "Require approval from code owners"
- Code owners must approve changes to their files
Merge Request Templates
Create Templates
Create in .gitlab/merge_request_templates/:
Feature.md:
## Feature Description
<!-- What feature does this add? -->
## Implementation Details
<!-- Technical details -->
## Testing
- [ ] Unit tests added
- [ ] Integration tests added
- [ ] Manual testing completed
## Screenshots
<!-- If applicable -->
## Related Issues
Closes #
Bugfix.md:
## Bug Description
<!-- What bug does this fix? -->
## Root Cause
<!-- What caused the bug? -->
## Solution
<!-- How is it fixed? -->
## Testing
- [ ] Bug reproduced
- [ ] Fix verified
- [ ] Regression tests added
Fixes #
Use Template
# Create MR with template
curl --request POST --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.com/api/v4/projects/:id/merge_requests" \
--data "source_branch=feature" \
--data "target_branch=main" \
--data "title=Add feature" \
--data "description=$(cat .gitlab/merge_request_templates/Feature.md)"
Best Practices
1. Merge Request Size
- Keep MRs focused and small
- Aim for < 400 lines of changes
- Split large features into multiple MRs
- Easier to review and test
2. Title and Description
- Clear, descriptive title
- Explain "why" not just "what"
- Link related issues
- Include screenshots/videos
- Checklist for requirements
3. Commits
- Atomic commits
- Descriptive commit messages
- Consider squashing for cleaner history
- Sign commits for verification
4. Review Process
- Request specific reviewers
- Respond to all comments
- Resolve discussions
- Re-request review after changes
- Thank reviewers
5. Testing
- Add/update tests
- Ensure CI passes
- Manual testing in review app
- Performance testing if needed
6. Documentation
- Update relevant docs
- Add API documentation
- Update CHANGELOG
- Include inline comments
7. Communication
- Use discussions for questions
- Mark as draft while working
- Update status regularly
- Notify when ready for review
CLI Examples
Using glab
# View MRs
glab mr list
glab mr list --assignee @me
glab mr list --state merged
# View MR details
glab mr view 123
# Create MR
glab mr create
# Checkout MR
glab mr checkout 123
# Approve MR
glab mr approve 123
# Merge MR
glab mr merge 123
# Close MR
glab mr close 123
# View MR diff
glab mr diff 123
API Examples
Python
import gitlab
gl = gitlab.Gitlab('https://gitlab.com', private_token='token')
project = gl.projects.get('group/project')
# Create MR
mr = project.mergerequests.create({
'source_branch': 'feature',
'target_branch': 'main',
'title': 'Add feature',
'description': 'Description',
'assignee_id': 123
})
# Get MR
mr = project.mergerequests.get(1)
# Add comment
mr.notes.create({'body': 'Looks good!'})
# Approve
mr.approve()
# Merge
mr.merge()
JavaScript
const { Gitlab } = require('@gitbeaker/node');
const api = new Gitlab({ token: 'token' });
// Create MR
const mr = await api.MergeRequests.create('group/project', 'feature', 'main', 'Add feature');
// Get MR
const mr = await api.MergeRequests.show('group/project', 1);
// Add comment
await api.MergeRequestNotes.create('group/project', 1, 'Looks good!');
// Approve
await api.MergeRequests.approve('group/project', 1);
// Merge
await api.MergeRequests.accept('group/project', 1, {
should_remove_source_branch: true,
squash: true
});
Additional Resources
- Merge Requests Documentation: https://docs.gitlab.com/ee/user/project/merge_requests/
- Code Review Guidelines: https://docs.gitlab.com/ee/development/code_review.html
- Approval Rules: https://docs.gitlab.com/ee/user/project/merge_requests/approvals/
- Code Owners: https://docs.gitlab.com/ee/user/project/code_owners.html