使用Perl或不使用Perl在终端提示符中显示Git分支

作为程序员成长的一种方式是关注你经常做的事情,并用更有效的替代方案来替换这项操作。我羞愧地意识到,我每天都在多次输入git branch
来检查我正在将代码提交到哪个分支。一个更有效的方法是在终端提示符中显示当前分支名称。理想情况下,我想看到类似这样的内容
~/some/path [master]
分支命令
在使用Git版本控制时,代码更改会提交到分支。活动分支是工作的上下文。例如,我可能正在开发一个新功能,因此我创建了一个名为“new-feature-x”的新分支并开始编写代码。我在此分支中对代码所做的任何更改都不会影响代码的master分支。这使得了解活动分支非常重要——我不想将代码提交到错误的分支。
branch
命令显示所有本地分支的列表,并在活动分支旁边放置一个星号。所以在我的虚构例子中,它可能看起来像这样
$ git branch
master
* new-feature-x
Git会在活动分支名称前添加一个星号来突出显示。有时我会用这个来提醒自己哪些分支在本地上可用,但大多数时候我是在检查我目前正在哪个分支上工作。有关branch
的更多信息,请参阅Git的分支文档。
使用Perl解析git分支
这是我想要使用的单行代码
$ git branch 2> /dev/null | perl -ne 'print " [$_]" if s/^\*\s+// && chomp'
它运行git branch
,将错误消息重定向到虚无之地。这意味着如果当前工作目录不是一个git仓库,后续的错误消息将被忽略。我们将git分支列表通过Perl管道传输,Perl使用-n
选项遍历每一行输入,并运行引用的代码。
代码在默认变量$_
上操作,它是git branch
循环输出的行。活动分支名称始终以星号开头,因此s/^\*\s+//
试图替换分支名称的前导星号和空格。替换返回它替换的字符数,所以对于除了活动分支之外的所有行,这将为零,评估为假。如果是真的,则代码将删除分支名称后面的换行符并打印它。
我可以将其添加到我的.bashrc
文件中
function current_git_branch {
git branch 2> /dev/null | perl -ne 'print " [$_]" if s/^\*\s+// && chomp'
}
PS1="\w\$(current_git_branch) "
PS1
变量定义了终端提示符的内容和样式。在这里,我将其定义为以下内容:\w
是当前工作目录的路径,例如~/Projects/work/
或任何其他路径。这是调用current_git_branch
的后续操作。一旦在我的.bashrc
中保存了这些编辑,我需要保存文件并重新加载它
$ . ~/.bashrc
现在我的终端提示符看起来像这样
~/Projects/work [new-feature-x]
如果我从不同的分支签出,它将改变
~/Projects/work [new-feature-x] git checkout master
~/Projects/work [master]
其他方法
一个简单的替代方案是使用Perl 6
$ git branch 2> /dev/null | perl6 -ne 'print " [$_]" if s/^\*\s+// && .chomp'
代码几乎与之前相同,只是将chomp
改为方法调用。也可以使用正则表达式捕获
$ git branch 2> /dev/null | perl -ne 'print " [$1]" if /^\*\s+(\S+)/'
我还看到过使用sed
而不是Perl来解析输出的示例。
Bash专用
可能一个更有效的方法是让Git只输出活动分支名,这样我们就不需要另一个程序来解析输出了,我们只需使用bash。感谢Randal Schwartz向我展示这一点
$ git rev-parse --abbrev-ref HEAD
new-feature-x
这只会输出活动分支。所以现在我的.bashrc
中的代码变为
function current_git_branch {
local branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null);
if [[ -n $branch ]];then
echo " [$branch]";
fi
}
PS1="\w\$(current_git_branch) "
这段代码将git命令的输出赋值给变量branch
。然后只要分支名不是空字符串(当当前工作目录不是git仓库时会发生这种情况),就会输出分支名。但是等等,分支名末尾的那个换行符去哪了?Bash嵌套echo
命令有一些有趣的行为。看看这个
$ echo -n $(echo -e "\n\n\n\n")
如果你在终端运行这个命令,你应该没有输出,尽管它包含了4个换行符,加上echo
子命令追加的另一个换行符。外层的echo
忽略了子命令返回的所有换行符,而-n
选项抑制了它自己的换行符追加(感谢Ben Grimm的解释)。
我选择使用bash变体,但无论你使用哪种方法,在终端显示分支名都是一个节省时间的妙招。
这篇文章最初发布在PerlTricks.com。
标签
反馈
这篇文章有什么问题吗?请在GitHub上打开一个问题或拉取请求来帮助我们。