mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
feat(mr): support Forgejo/Codeberg pull request URLs
Codeberg and other Forgejo instances expose pull requests under refs/pull/<id>/head instead of GitLab's refs/merge-requests/<id>/head, so passing a Codeberg pull request URL to git mr fetched the wrong ref. Recognize the /pulls/<id> URL shape and switch to the matching ref for that case, leaving the GitLab URL and bare numeric id behavior unchanged. Closes #1213
This commit is contained in:
parent
dbf68bac59
commit
8cd8741a3f
13
Commands.md
13
Commands.md
|
|
@ -1428,8 +1428,8 @@ $ git reset-file .htaccess dc82b19
|
|||
|
||||
## git mr
|
||||
|
||||
Checks out a merge request from GitLab. Usage: `git mr <ID|URL> [REMOTE]`.
|
||||
Default remote is `origin`.
|
||||
Checks out a merge request from GitLab, or a pull request from Forgejo/Codeberg.
|
||||
Usage: `git mr <ID|URL> [REMOTE]`. Default remote is `origin`.
|
||||
|
||||
``` bash
|
||||
$ git mr 51
|
||||
|
|
@ -1447,6 +1447,15 @@ From gitlab.com:owner/repository
|
|||
Switched to branch 'mr/51'
|
||||
```
|
||||
|
||||
A Forgejo/Codeberg pull request URL is also supported:
|
||||
|
||||
``` bash
|
||||
$ git mr https://codeberg.org/owner/repository/pulls/51
|
||||
From codeberg.org:owner/repository
|
||||
* [new ref] refs/pull/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.
|
||||
|
||||
|
|
|
|||
10
bin/git-mr
10
bin/git-mr
|
|
@ -7,6 +7,8 @@ if [ -z "${1-}" ] ; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
remote_ref_kind=merge-requests
|
||||
|
||||
if test "$1" = "clean"; then
|
||||
git for-each-ref refs/heads/mr/* --format='%(refname)' | while read -r ref; do
|
||||
git branch -D "${ref#refs/heads/}"
|
||||
|
|
@ -15,13 +17,19 @@ if test "$1" = "clean"; then
|
|||
elif [[ $1 =~ ^(https?://[^/]+/(.+))/merge_requests/([0-9]+).*$ ]]; then
|
||||
remote=${BASH_REMATCH[1]}.git
|
||||
id=${BASH_REMATCH[3]}
|
||||
elif [[ $1 =~ ^(https?://[^/]+/(.+))/pulls/([0-9]+).*$ ]]; then
|
||||
# Forgejo/Codeberg pull request URL, e.g.
|
||||
# https://codeberg.org/owner/repository/pulls/453
|
||||
remote=${BASH_REMATCH[1]}.git
|
||||
id=${BASH_REMATCH[3]}
|
||||
remote_ref_kind=pull
|
||||
else
|
||||
id=$1
|
||||
remote=${2:-origin}
|
||||
fi
|
||||
|
||||
branch=mr/$id
|
||||
remote_ref=refs/merge-requests/$id/head
|
||||
remote_ref=refs/$remote_ref_kind/$id/head
|
||||
git fetch -fu "$remote" "$remote_ref:$branch"
|
||||
git checkout "$branch"
|
||||
git config --local --replace "branch.$branch.merge" "$remote_ref"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ git-mr(1) -- Checks out a merge request locally
|
|||
<url>
|
||||
|
||||
GitLab merge request URL in the format
|
||||
`https://gitlab.tld/owner/repository/merge_requests/453`.
|
||||
`https://gitlab.tld/owner/repository/merge_requests/453`, or a
|
||||
Forgejo/Codeberg pull request URL in the format
|
||||
`https://codeberg.tld/owner/repository/pulls/453`.
|
||||
|
||||
|
||||
## EXAMPLES
|
||||
|
|
@ -33,6 +35,13 @@ This checks out merge request `!51` from remote `origin` to branch `mr/51`.
|
|||
* [new ref] refs/merge-requests/51/head -> mr/51
|
||||
Switched to branch 'mr/51'
|
||||
|
||||
This checks out pull request `#51` from a Forgejo/Codeberg URL to branch `mr/51`.
|
||||
|
||||
$ git mr https://codeberg.org/owner/repository/pulls/51
|
||||
From codeberg.org:owner/repository
|
||||
* [new ref] refs/pull/51/head -> mr/51
|
||||
Switched to branch 'mr/51'
|
||||
|
||||
## AUTHOR
|
||||
|
||||
Written by Étienne BERSAC <bersace03@gmail.com> from git-pr(1).
|
||||
|
|
|
|||
48
tests/git-mr.bats
Normal file
48
tests/git-mr.bats
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# shellcheck shell=bash
|
||||
|
||||
source "$BATS_TEST_DIRNAME/test_util.sh"
|
||||
|
||||
setup_file() {
|
||||
test_util.setup_file
|
||||
|
||||
PATH="$BATS_TEST_DIRNAME/bin:$PATH"
|
||||
}
|
||||
|
||||
setup() {
|
||||
test_util.cd_test
|
||||
|
||||
test_util.git_init
|
||||
touch ./tracked
|
||||
git add ./tracked
|
||||
git commit -m 'Initial commit'
|
||||
|
||||
# Local bare "remote" standing in for a real GitLab/Forgejo instance,
|
||||
# with a merge-requests ref and a pull ref pointing at the same commit.
|
||||
remote_dir="$BATS_TEST_TMPDIR/remote.git"
|
||||
git init --bare --initial-branch main "$remote_dir"
|
||||
git push "$remote_dir" HEAD:refs/merge-requests/51/head
|
||||
git push "$remote_dir" HEAD:refs/pull/51/head
|
||||
|
||||
git remote add origin "$remote_dir"
|
||||
}
|
||||
|
||||
@test "checks out a merge request by numeric id" {
|
||||
run git mr 51
|
||||
assert_success
|
||||
assert_output --partial "refs/merge-requests/51/head"
|
||||
|
||||
run git rev-parse --abbrev-ref HEAD
|
||||
assert_output 'mr/51'
|
||||
|
||||
run git config --get branch.mr/51.merge
|
||||
assert_output 'refs/merge-requests/51/head'
|
||||
}
|
||||
|
||||
@test "checks out a merge request by numeric id and explicit remote" {
|
||||
run git mr 51 "$remote_dir"
|
||||
assert_success
|
||||
assert_output --partial "refs/merge-requests/51/head"
|
||||
|
||||
run git rev-parse --abbrev-ref HEAD
|
||||
assert_output 'mr/51'
|
||||
}
|
||||
Loading…
Reference in a new issue