Install
openclaw skills install @ahmadhussain0335/mobile-merge-requestGuides the merge request and pull request workflow for mobile teams: branch naming, Conventional Commits, small and stacked MRs, self-review, rebase vs merge, safe conflict resolution for lockfiles, project.pbxproj and version catalogs, MR descriptions with screenshots and rollback, and reviewer etiquette. Use when creating branches, writing commits or MR descriptions, rebasing, resolving conflicts or answering review comments.
openclaw skills install @ahmadhussain0335/mobile-merge-requestGet mobile changes from a branch into main with a clean history, a description a reviewer can act on, and no lost work along the way. Applies to GitLab merge requests and GitHub pull requests alike; "MR" below means either.
Not for: reviewing the code itself for bugs (use mobile-code-review), or pipeline configuration
(use mobile-ci-cd).
git branch --show-current, git fetch origin.git log --oneline origin/main..HEAD.git diff --stat --merge-base origin/main.TODO for the author.# BAD
ahmad-changes
fix
feature/new-stuff
# GOOD
feature/AH/PROJ-123-ble-reconnect-backoff
fix/AH/PROJ-456-crash-on-empty-scan
chore/AH/PROJ-789-bump-agp
<type>/<initials>/<TICKET>-<kebab-short-title>. Types: feature, fix, chore,
refactor, docs, test, release, hotfix.git fetch origin
git switch -c feature/AH/PROJ-123-ble-reconnect-backoff origin/main
# BAD
fixed stuff
WIP
Update MainActivity.kt
# GOOD
fix(ble): retry GATT connect with exponential backoff
feat(onboarding): add QR pairing screen
refactor(settings): move formatting out of SettingsViewController
<type>(<optional scope>): <imperative summary>, summary under about 72 characters, no period.feat, fix, refactor, perf, test, docs, build, ci, chore, style, revert.Refs: PROJ-123, BREAKING CHANGE: <what breaks and how to migrate>.Breaking changes:
# BAD: breaking change hidden in a fix
fix(api): rename deviceId field
# GOOD
feat(api)!: rename deviceId to gatewayId in telemetry payload
BREAKING CHANGE: backend must accept gatewayId; app versions before 3.2 send deviceId.
Refs: PROJ-321
# BAD: one MR
feat: QR pairing + Gradle 9 upgrade + rename package + fix crash in settings
# GOOD: four MRs
chore(build): upgrade Gradle wrapper
refactor: rename package com.acme.old to com.acme.gateway
feat(onboarding): add QR pairing screen
fix(settings): crash on empty device name
# BAD: second MR targets main and shows the first MR's commits too
git switch -c feature/AH/PROJ-124-pairing-ui feature/AH/PROJ-123-pairing-api
# ...opened against main
# GOOD: target the parent branch; after the parent merges, rebase and retarget to main
git switch -c feature/AH/PROJ-124-pairing-ui feature/AH/PROJ-123-pairing-api
# open MR: feature/AH/PROJ-124-pairing-ui -> feature/AH/PROJ-123-pairing-api
git rebase --onto (see
git commands) and retarget the MR to main.# BAD
git push --force # overwrites whatever is on the remote, including others' commits
git rebase origin/main # on main, develop or a branch a colleague also pushes to
# GOOD: own branch only, refuses if the remote moved since your last fetch
git fetch origin
git rebase origin/main
git push --force-with-lease
main, develop, release/*, a branch two people push to) only get merge commits
or new commits, never rewrites.# BAD: noise that lands in main
git commit -m "address review comments"
git commit -m "fix typo"
# GOOD
git commit --fixup=a1b2c3d
# after approval, fold fixups into their targets
git rebase -i --autosquash origin/main
git range-diff origin/main @{u} HEAD # confirm only intended changes before pushing
git push --force-with-lease
git bisect and git revert stay precise.# BAD squash-merge title
Feature/AH/PROJ-123 ble reconnect backoff
# GOOD
fix(ble): retry GATT connect with exponential backoff (PROJ-123)
# BAD: pick a side blindly for every file
git checkout --theirs .
git add . && git rebase --continue
# GOOD: inspect, resolve per file, regenerate what is generated, then build and test
git status
git diff --name-only --diff-filter=U
# resolve each file; regenerate lockfiles and generated code instead of hand-merging
git add <file>
git rebase --continue
./gradlew assembleDebug testDebugUnitTest
--ours is the branch being rebased onto (main) and --theirs is your commit.
The opposite of a merge.project.pbxproj and version catalogs have specific procedures:
conflict resolution.<!-- BAD -->
Fixes the bug.
<!-- GOOD (short form) -->
## Summary
Reconnect to the gateway with exponential backoff after GATT error 133 instead of failing at once.
## Ticket
PROJ-123
## Testing
- Unit: BackoffPolicyTest (new), ConnectionManagerTest (updated)
- Manual: Pixel 8 Android 16, iPhone 15 iOS 26; power-cycled gateway 10 times, reconnected every time
Info.plist keys, entitlements, minSdk,
targetSdk or deployment target changes, database migrations, analytics or telemetry changes.# BAD
This is wrong.
Why would you do it like this?
# GOOD
issue: `onCharacteristicChanged` runs on a binder thread; `_state.value = ...` here races with the
collector. Use `_state.update {}` or hop to the main dispatcher.
nit (non-blocking): `deviceList` -> `devices` to match the repository naming.
question: Is the 10 s timeout from the firmware spec, or a guess? If a guess, add a constant with a comment.
issue: (blocking), suggestion:, question:, nit: (never blocks), praise:, todo:.--force, or rewriting main, develop or a colleague's branch.pubspec.lock, Podfile.lock, Package.resolved or generated code.project.pbxproj conflicts by taking one side wholesale and losing the other side's files.<type>/<initials>/<TICKET>-<short-title> and is based on current main! and a BREAKING CHANGE: footerInfo.plist, entitlements, SDK levels and migrations are called out--force-with-lease, on the author's own branch onlyWhen asked to write an MR or PR description, produce the title and the filled template:
Title: fix(ble): retry GATT connect with exponential backoff (PROJ-123)
## Summary
<one or two sentences: what changes for the user or the codebase, and why>
## Ticket
PROJ-123
## Changes
- <grouped by intent, not by file>
## Screenshots / recordings
| Android | iOS |
|---|---|
| TODO | TODO |
## Testing
- <tests added or updated, devices and OS versions, manual steps>
## Risk and rollback
- Risk: <what could break, who is affected>
- Rollback: <revert MR | disable flag X | server config>
## Checklist
- [x] <items verified from the diff>
- [ ] <items the author must confirm>
When asked to check MR hygiene, produce findings in this shape:
## MR hygiene: <branch name>
Target: main. Commits: 5. Changed: 612 lines in 14 files (180 in lockfiles and generated code).
### Findings
1. [Must fix] Commit "wip" (a1b2c3d) -- not a Conventional Commit.
Fix: `git commit --fixup=<target>` or reword before merge.
2. [Must fix] Description has no iOS screenshots for a shared UI change.
3. [Should fix] Gradle wrapper bump mixed with feature code -- split into its own MR.
4. [Note] `Info.plist` gains `NSBluetoothAlwaysUsageDescription` -- call it out under Risk.
### Suggested commands
```bash
git rebase -i --autosquash origin/main
git push --force-with-lease
```
### Verdict
Not ready -- 2 Must fix.
Severity: Must fix blocks requesting review; Should fix is expected before merge; Note is informational.
mobile-code-review -- reviewing the code inside the MRmobile-ci-cd -- pipelines, required checks, release branches and signingmobile-security -- when the diff touches secrets, permissions, network or storagemobile-kotlin, mobile-swift, mobile-flutter -- build and test commands per platformmobile-release -- release notes and readiness before merging a release branch