65.9K
CodeProject 正在变化。 阅读更多。
Home

无需魔法、便携的方式,从命令行打开拉取请求

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2018 年 10 月 10 日

CPOL

3分钟阅读

viewsIcon

6704

一种无需魔法、便携的方式,从命令行打开拉取请求

A portable and magic-free way to open Pull Requests from the Command Line

这个小巧的 Bash 代码片段可以让您在大多数类 Unix 系统(OSX、Ubuntu 等)上从命令行打开 GitHub 或 GitLab 的 pull request,而无需使用任何魔法库、ZSH 技巧或其他依赖项。

A portable and magic-free way to open Pull Requests from the Command Line

这是它在 OSX 中的运行效果

A portable and magic-free way to open Pull Requests from the Command Line

以及 Ubuntu

A portable and magic-free way to open Pull Requests from the Command Line

该脚本可作为 gpr.sh gist 获取。您也可以在我的 dotfiles 中的 git.sh 文件中找到它。

脚本

以下是脚本的完整内容

# Colour constants for nicer output.
GREEN='\033[0;32m'
RESET='\033[0m'

# Push the current branch to origin, set upstream, open the PR page if possible.
gpr() {
    # Get the current branch name, or use 'HEAD' if we cannot get it.
    branch=$(git symbolic-ref -q HEAD)
    branch=${branch##refs/heads/}
    branch=${branch:-HEAD}

    # Pushing take a little while, so let the user know we're working.
    echo "Opening pull request for ${GREEN}${branch}${RESET}..."

    # Push to origin, grabbing the output but then echoing it back.
    push_output=`git push origin -u ${branch} 2>&1`
    echo ""
    echo ${push_output}

    # If there's anything which starts with http, it's a good guess it'll be a
    # link to GitHub/GitLab/Whatever. So open it.
    link=$(echo ${push_output} | grep -o 'http.*' | sed -e 's/[[:space:]]*$//')
    if [ ${link} ]; then
        echo ""
        echo "Opening: ${GREEN}${link}${RESET}..."
        python -mwebbrowser ${link}
    fi
}

工作原理

让我们来逐步了解一下。

# Colour constants for nicer output.
GREEN='\033[0;32m'
RESET='\033[0m'

为了更容易地对控制台输出进行着色,我们创建了带有设置“green”颜色所需的转义代码的字符串,并重置文本颜色。

gpr() {
    # Get the current branch name, or use 'HEAD' if we cannot get it.
    branch=$(git symbolic-ref -q HEAD)
    branch=${branch##refs/heads/}
    branch=${branch:-HEAD}

现在我们定义 gpr (Git Pull Request) 函数。 我们需要推送当前分支,因此我们需要获取当前分支名称。 在 Stack Overflow: 如何在 Git 中获取当前分支名称 上有很多关于此工作原理的讨论。 本质上,我们只是获取当前分支头的符号名称,它会是这样的

refs/heads/my-new-branch

然后我们使用 Bash 子字符串删除 来删除 ref/heads/ 部分。 如果我们没有分支(例如,我们处于分离状态),我们只需使用 HEAD 作为分支名称。

接下来,我们有这个

    # Pushing take a little while, so let the user know we're working.
    echo "Opening pull request for ${GREEN}${branch}${RESET}..."

    # Push to origin, grabbing the output but then echoing it back.
    push_output=`git push origin -u ${branch} 2>&1`
    echo ""
    echo ${push_output}

我们之前定义了一些 string,其中包括用于着色终端输出的转义代码。 现在我们只是向用户显示我们要推送的分支,推送它,然后将所有输出存储在 push_output 变量中。

2>&1 是一种常见的用法。 这只是确保我们将所有 stderr 输出(始终是文件描述符 2)放入 stdout(始终是文件描述符 1)中。 这意味着无论程序将输出写入 stdout 还是 stderr,我们都会捕获它。 在博客文章“理解 Shell 脚本的习惯用法:2>&1”中有一个很好的描述
'.

Git push 的输出将取决于所使用的 Git 服务器。 对于 GitHub,它会是这样的

remote:
remote: Create a pull request for 'feat/doc-cleanup' on GitHub by visiting:
remote:      https://github.com/dwmkerr/dotfiles/pull/new/feat/doc-cleanup
remote:
To github.com:dwmkerr/dotfiles
 * [new branch]      feat/doc-cleanup -> feat/doc-cleanup
Branch feat/doc-cleanup set up to track remote branch feat/doc-cleanup from origin.

现在我们只想看看是否有任何以 http 开头的文本,如果有,则打开它。 这是我们如何做到的

    # If there's anything which starts with http, it's a good guess it'll be a
    # link to GitHub/GitLab/Whatever. So open it.
    link=$(echo ${push_output} | grep -o 'http.*' | sed -e 's/[[:space:]]*$//')
    if [ ${link} ]; then
        echo ""
        echo "Opening: ${GREEN}${link}${RESET}..."
        python -mwebbrowser ${link}
    fi

这使用 grephttp 开始提取所有内容,并使用 sed 删除任何尾随空格。 如果我们找到了链接,我们使用 python 打开它(这是一个相当安全的跨平台解决方案)。

就这样! 当您准备好要推送并从中创建 pull request 的分支时,只需运行

gpr

该分支将被推送到 origin,并且如果存在 Pull Request 网页,它将被打开。

现有技术

我的同事 Tobias 最近分享了一个我们研究出的打开 GitLab merge request 的好技巧 - 现在也适用于 GitHub

我想能够在 Ubuntu 和其他 Linux 发行版中使用相同的技巧,但意识到它依赖于 oh-my-zsh 并且假定 OSX 使用 Chrome 作为浏览器,因此将其调整为上述。 谢谢 Tobi!

© . All rights reserved.