Add git-mr to checkout GitLab merge requests

This commit is contained in:
Étienne BERSAC 2017-06-13 17:01:14 +02:00
parent 4b29351f2f
commit d4c7581835
No known key found for this signature in database
GPG key ID: 932A5BA4CFF8792B
10 changed files with 292 additions and 0 deletions

View file

@ -37,6 +37,7 @@
- [`git merge-into`](#git-merge-into)
- [`git merge-repo`](#git-merge-repo)
- [`git missing`](#git-missing)
- [`git mr`](#git-mr)
- [`git obliterate`](#git-obliterate)
- [`git pr`](#git-pr)
- [`git psykorebase`](#git-psykorebase)
@ -1201,6 +1202,30 @@ or reset one file to certain commit
$ git reset-file .htaccess dc82b19
```
## git mr
Checks out a merge request from GitLab. Usage: `git mr <ID|URL> [REMOTE]`.
Default remote is `origin`.
``` bash
$ git mr 51
From gitlab.com:owner/repository
* [new ref] refs/merge-requests/51/head -> mr/51
Switched to branch 'mr/51'
```
With full URL, the head is fetched from a temporary remote pointing to the base URL.
``` bash
$ git mr https://gitlab.com/owner/repository/merge_requests/51
From gitlab.com:owner/repository
* [new ref] refs/merge-requests/51/head -> mr/51
Switched to branch 'mr/51'
```
Just like [git pr](#git-pr), `git mr` accepts a `clean` argument to trash all
`mr/` branches. Ensure current branch is not one.
## git pr
Checks out a pull request from GitHub

28
bin/git-mr Executable file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -eu
if [ -z "${1-}" ] ; then
echo "mr number or URL required. See --help for usage." 1>&2
exit 1
fi
if test "$1" = "clean"; then
git for-each-ref refs/heads/mr/* --format='%(refname)' | while read ref; do
git branch -D ${ref#refs/heads/}
done
exit 0
elif [[ $1 =~ ^(https?://[^/]+/(.+))/merge_requests/([0-9]+).*$ ]]; then
remote=${BASH_REMATCH[1]}.git
id=${BASH_REMATCH[3]}
else
id=$1
remote=${2:-origin}
fi
branch=mr/$id
remote_ref=refs/merge-requests/$id/head
git fetch -fu $remote $remote_ref:$branch
git checkout $branch
git config --local --replace branch.$branch.merge $remote_ref
git config --local --replace branch.$branch.remote $remote

View file

@ -404,6 +404,7 @@ zstyle ':completion:*:*:git:*' user-commands \
merge-into:'merge one branch into another' \
merge-repo:'merge two repo histories' \
missing:'show commits missing from another branch' \
mr:'checks out a merge request locally' \
obliterate:'rewrite past commits to remove some files' \
pr:'checks out a pull request locally' \
psykorebase:'rebase a branch with a merge commit' \

View file

@ -132,6 +132,9 @@ Self update\.
\fBgit\-missing(1)\fR Show commits missing from another branch
.
.IP "\(bu" 4
\fB# git\-mr(1)\fR Checks out a merge request locally
.
.IP "\(bu" 4
\fBgit\-pr(1)\fR Checks out a pull request locally
.
.IP "\(bu" 4

View file

@ -128,6 +128,7 @@
<li> <strong><a class="man-ref" href="git-merge-into.html">git-merge-into<span class="s">(1)</span></a></strong> Merge one branch into another</li>
<li> <strong><a class="man-ref" href="git-merge-repo.html">git-merge-repo<span class="s">(1)</span></a></strong> Merge two repo histories</li>
<li> <strong><a class="man-ref" href="git-missing.html">git-missing<span class="s">(1)</span></a></strong> Show commits missing from another branch</li>
<li> <strong><a class="man-ref" href="git-mr.html">git-mr<span class="s">(1)</span></a></strong> Checks out a merge request locally</li>
<li> <strong><a class="man-ref" href="git-pr.html">git-pr<span class="s">(1)</span></a></strong> Checks out a pull request locally</li>
<li> <strong><a class="man-ref" href="git-psykorebase.html">git-psykorebase<span class="s">(1)</span></a></strong> Rebase a branch with a merge commit</li>
<li> <strong><a class="man-ref" href="git-reauthor.html">git-reauthor<span class="s">(1)</span></a></strong> Rewrite history to change author's identity</li>

View file

@ -55,6 +55,7 @@ git-extras(1) -- Awesome GIT utilities
- **git-merge-into(1)** Merge one branch into another
- **git-merge-repo(1)** Merge two repo histories
- **git-missing(1)** Show commits missing from another branch
- **git-mr(1)** Checks out a merge request locally
- **git-pr(1)** Checks out a pull request locally
- **git-psykorebase(1)** Rebase a branch with a merge commit
- **git-reauthor(1)** Rewrite history to change author's identity

56
man/git-mr.1 Normal file
View file

@ -0,0 +1,56 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-MR" "1" "June 2017" "" ""
.
.SH "NAME"
\fBgit\-mr\fR \- Checks out a merge request locally
.
.SH "SYNOPSIS"
\fBgit\-mr\fR <number> [<remote>]
.
.br
\fBgit\-mr\fR <url>
.
.br
\fBgit\-mr clean\fR
.
.SH "DESCRIPTION"
Fetches merge request head by its number or URl and check it out in a branch named with merge request number\.
.
.SH "OPTIONS"
<remote>
.
.P
The name of the remote to fetch from\. Defaults to \fBorigin\fR\.
.
.P
<url>
.
.P
GitLab merge request URL in the format \fBhttps://gitlab\.tld/owner/repository/merge_requests/453\fR\.
.
.SH "EXAMPLES"
This checks out merge request \fB!51\fR from remote \fBorigin\fR to branch \fBmr/51\fR\.
.
.IP "" 4
.
.nf
$ git mr 51
From gitlab\.com:owner/repository
* [new ref] refs/merge\-requests/51/head \-> mr/51
Switched to branch \'mr/51\'
.
.fi
.
.IP "" 0
.
.SH "AUTHOR"
Written by Étienne BERSAC \fIbersace03@gmail\.com\fR from git\-pr(1)\.
.
.SH "REPORTING BUGS"
<\fIhttps://github\.com/tj/git\-extras/issues\fR>
.
.SH "SEE ALSO"
<\fIhttps://github\.com/tj/git\-extras\fR>

130
man/git-mr.html Normal file
View file

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' value='text/html;charset=utf8'>
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
<title>git-mr(1) - Checks out a merge request locally</title>
<style type='text/css' media='all'>
/* style: man */
body#manpage {margin:0}
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
.mp h2 {margin:10px 0 0 0}
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
.mp h3 {margin:0 0 0 4ex}
.mp dt {margin:0;clear:left}
.mp dt.flush {float:left;width:8ex}
.mp dd {margin:0 0 0 9ex}
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
.mp pre {margin-bottom:20px}
.mp pre+h2,.mp pre+h3 {margin-top:22px}
.mp h2+pre,.mp h3+pre {margin-top:5px}
.mp img {display:block;margin:auto}
.mp h1.man-title {display:none}
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
.mp h2 {font-size:16px;line-height:1.25}
.mp h1 {font-size:20px;line-height:2}
.mp {text-align:justify;background:#fff}
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
.mp u {text-decoration:underline}
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
.mp b.man-ref {font-weight:normal;color:#434241}
.mp pre {padding:0 4ex}
.mp pre code {font-weight:normal;color:#434241}
.mp h2+pre,h3+pre {padding-left:0}
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
ol.man-decor {width:100%}
ol.man-decor li.tl {text-align:left}
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
ol.man-decor li.tr {text-align:right;float:right}
</style>
</head>
<!--
The following styles are deprecated and will be removed at some point:
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
.man-navigation should be used instead.
-->
<body id='manpage'>
<div class='mp' id='man'>
<div class='man-navigation' style='display:none'>
<a href="#NAME">NAME</a>
<a href="#SYNOPSIS">SYNOPSIS</a>
<a href="#DESCRIPTION">DESCRIPTION</a>
<a href="#OPTIONS">OPTIONS</a>
<a href="#EXAMPLES">EXAMPLES</a>
<a href="#AUTHOR">AUTHOR</a>
<a href="#REPORTING-BUGS">REPORTING BUGS</a>
<a href="#SEE-ALSO">SEE ALSO</a>
</div>
<ol class='man-decor man-head man head'>
<li class='tl'>git-mr(1)</li>
<li class='tc'></li>
<li class='tr'>git-mr(1)</li>
</ol>
<h2 id="NAME">NAME</h2>
<p class="man-name">
<code>git-mr</code> - <span class="man-whatis">Checks out a merge request locally</span>
</p>
<h2 id="SYNOPSIS">SYNOPSIS</h2>
<p><code>git-mr</code> &lt;number&gt; [&lt;remote&gt;]<br />
<code>git-mr</code> &lt;url&gt;<br />
<code>git-mr clean</code></p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p> Fetches merge request head by its number or URl and check it out in a branch
named with merge request number.</p>
<h2 id="OPTIONS">OPTIONS</h2>
<p> &lt;remote&gt;</p>
<p> The name of the remote to fetch from. Defaults to <code>origin</code>.</p>
<p> &lt;url&gt;</p>
<p> GitLab merge request URL in the format
<code>https://gitlab.tld/owner/repository/merge_requests/453</code>.</p>
<h2 id="EXAMPLES">EXAMPLES</h2>
<p>This checks out merge request <code>!51</code> from remote <code>origin</code> to branch <code>mr/51</code>.</p>
<pre><code>$ git mr 51
From gitlab.com:owner/repository
* [new ref] refs/merge-requests/51/head -&gt; mr/51
Switched to branch 'mr/51'
</code></pre>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Written by Étienne BERSAC <a href="&#x6d;&#x61;&#x69;&#x6c;&#x74;&#x6f;&#x3a;&#x62;&#x65;&#114;&#x73;&#x61;&#x63;&#101;&#x30;&#x33;&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#x63;&#111;&#109;" data-bare-link="true">&#x62;&#x65;&#x72;&#x73;&#x61;&#99;&#101;&#x30;&#x33;&#64;&#103;&#x6d;&#x61;&#x69;&#x6c;&#x2e;&#99;&#111;&#x6d;</a> from <a class="man-ref" href="git-pr.html">git-pr<span class="s">(1)</span></a>.</p>
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
<p>&lt;<a href="https://github.com/tj/git-extras/issues" data-bare-link="true">https://github.com/tj/git-extras/issues</a>&gt;</p>
<h2 id="SEE-ALSO">SEE ALSO</h2>
<p>&lt;<a href="https://github.com/tj/git-extras" data-bare-link="true">https://github.com/tj/git-extras</a>&gt;</p>
<ol class='man-decor man-foot man foot'>
<li class='tl'></li>
<li class='tc'>June 2017</li>
<li class='tr'>git-mr(1)</li>
</ol>
</div>
</body>
</html>

45
man/git-mr.md Normal file
View file

@ -0,0 +1,45 @@
# git-mr(1) -- Checks out a merge request locally
## SYNOPSIS
`git-mr` &lt;number&gt; [&lt;remote&gt;]<br>
`git-mr` &lt;url&gt;<br>
`git-mr clean`
## DESCRIPTION
Fetches merge request head by its number or URl and check it out in a branch
named with merge request number.
## OPTIONS
&lt;remote&gt;
The name of the remote to fetch from. Defaults to `origin`.
&lt;url&gt;
GitLab merge request URL in the format
`https://gitlab.tld/owner/repository/merge_requests/453`.
## EXAMPLES
This checks out merge request `!51` from remote `origin` to branch `mr/51`.
$ git mr 51
From gitlab.com:owner/repository
* [new ref] refs/merge-requests/51/head -> mr/51
Switched to branch 'mr/51'
## AUTHOR
Written by Étienne BERSAC <bersace03@gmail.com> from git-pr(1).
## REPORTING BUGS
&lt;<https://github.com/tj/git-extras/issues>&gt;
## SEE ALSO
&lt;<https://github.com/tj/git-extras>&gt;

View file

@ -34,6 +34,8 @@ git-locked(1) git-locked
git-merge-into(1) git-merge-into
git-merge-repo(1) git-merge-repo
git-missing(1) git-missing
git-mr(1) git-mr
git-obliterate(1) git-obliterate
git-pr(1) git-pr
git-psykorebase(1) git-psykorebase
git-reauthor(1) git-reauthor