-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Git is hard. Git workflows are complex. Write code, not git commands, deploy it in a flash. Learn later.
mr
is a cli tool designed to automate routine git branch flow, such as deploying a feature branch across a complex multi-branch workflow.
MR
stands for Merge Request (GitLab) or Pull Request (GitHub). Here MR stands for branch (ex.: a branch with name TASK-42
).
mr
was written to be as git hosting agnostic as possible. If you're ok with some setting up use glab cli or gh cli instead.
-
node -v
>=18.12
-
git --version
>=2.23
-
git --version >= 2.11.0
fallback added sincemr-git-cli 0.1.0
-
npm install -g mr-git-cli@latest
try it without install:
npx mr-git-cli TASK-42
# create branch (press Enter to accept)
$ mr TASK-42
# default repo branch will be detected
Create new branch 'TASK-4444' from 'origin/main' [Y/n]?
> git fetch
> git switch --guess --merge --create TASK-4444 origin/main
Switched to a new branch 'TASK-4444'
# add 'from' to specify any parent branch
$ mr r43 from origin/release
# switch branch
$ mr release
> git switch --merge --guess release
$ mr TASK-42
> git switch --merge --guess TASK-42
if you are using gitlab you can create gitlab merge request from command line using push options
$ mr
> npm test
> git push --set-upstream origin TASK-42:TASK-42 -o merge_request.create
-o merge_request.title='TASK-42 this is first commit message of branch' -o merge_request.target=main
remote: View merge request for TASK-42:
remote: https://gitlab.local/jonny64/mr-git-cli/-/merge_requests/1
remote:
To ssh://gitlab.local/jonny64/mr-git-cli.git
* [new branch] TASK-42 -> TASK-42
Gitlab presence is detected by 'git remote' url and push options are added to git push
to create merge request:
- first commit message of
git log --reverse --pretty=format:%s master..TASK-42
is added as MR title - leading digits of such title are converted to format TASK-42 to create external issue tracker link in merge request title
- merge request target is set as
git config branch.TASK-42.mr-target
(was set whenmr
created branch) -
git config branch.TASK-42.description
is set to prevent duplicates:- next time you use 'mr', it checks
git config branch.TASK-42.description
and if it is non empty, it does nothing to prevent duplicate merge request.
- next time you use 'mr', it checks
If branch is already pushed, gitlab push option does nothing. You can recreate merge request at same branch: git push origin :TASK-42
.
You can run merge (see below) at once: it will push as first step
Typical workflow:
- a developer commits broken tests
- CI send you an email about broken pipeline
- you should fix it. NOW.
mr
applies the shift-left principle:
- a developer commits broken tests
- a developer can't push:
mr
run tests BEFORE branch push - a developer has time to fix it
mr
will run this command BEFORE any branch push (topic or integration):
$ git config mr.test 'npm test' # for code repo
$ git config mr.test 'yamllint .' # for ci repo
you can clear any config value via git config --unset
you can use pre
and post
scripts to group all your checks in one command, ex.:
-
pretest
for static analysis scan -
test
to run tests -
posttest
for security scans
now npm test
will run all checks in this exact order
$ mr TASK-42 to release
> git push --set-upstream origin TASK-42:TASK-42
> git switch release
> git merge origin/TASK-42
> npm test
> git push --set-upstream
# merge current git branch to release
$ mr to release
Typical workflow:
- merge to one integration branch (ex:
test
) - merge to another integration branch (ex:
premain
) - merge to
main
- everything that goes to
main
should already be merged to preceding branches in this exact order. To configure those dependencies:
$ git config --global branch.main.mr-merge-after test,premain
will confirm merge to test first, then premain, then main (target branch) at last (order matters).
use either --global
or --local
setting per repository clone, see git config
reference
mr
- checks if branch was already merged via
git log --oneline origin/master..origin/srcBranch
- produce merge commands for all dependent branches
$ mr hotfix to master
> git push --set-upstream origin hotfix:hotfix
Everything up-to-date
Ok, here is the plan:
git switch test
git merge origin/hotfix
npm test
git push --set-upstream
git switch master
git merge origin/hotfix
npm test
git push --set-upstream
git checkout hotfix
Proceed [Y/n]?
> git switch test
> git merge origin/hotfix
> npm test
> git push --set-upstream
> git switch master
> git merge origin/hotfix
> npm test
> git push --set-upstream
$ echo "alias task=mr" >> ~/.bash_aliases
$ echo "alias deploy=mr" >> ~/.bash_aliases
$ source ~/.bash_aliases
$ task TASK-42 from production
Create new branch 'TASK-42' from origin/production ? y
> git switch --create --guess TASK-42
# yuck yuck
# git commit
$ deploy
remote: View merge request for TASK-42:
remote: https://gitlab.local/jonny64/mr-git-cli/-/merge_requests/1
$ deploy TASK-42 to production
> git push --set-upstream origin TASK-42:TASK-42
> git switch production
> git merge origin/TASK-42
> npm test
> git push --set-upstream