使用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

标签

David Farrell

David是一位职业程序员,他经常推文博客关于代码和编程的艺术。

浏览他们的文章

反馈

这篇文章有什么问题吗?请在GitHub上打开一个问题或拉取请求来帮助我们。