緣起
在本地環(huán)境( iTerm2 + zsh) 使用終端工具操作 Git 時(shí), 能夠顯示"當(dāng)前文件夾名稱"以及" Git 分支名稱"(如下圖).
這種設(shè)置非常有用, 尤其是需要頻繁切換分支時(shí), 能夠避免操作錯(cuò)誤的分支.
但是使用遠(yuǎn)程服務(wù)器和 Vagrant 虛擬機(jī)時(shí)沒有這個(gè)功能.
解決
上網(wǎng)搜索, 在一個(gè)博客上找到解決方案.
在 Shell 的配置文件中添加下面代碼:
function git-branch-name {
git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3
}
function git-branch-prompt {
local branch=`git-branch-name`
if [ $branch ]; then printf " [%s]" $branch; fi
}
PS1="\u@\h \[\033[0;36m\]\W\[\033[0m\]\[\033[0;32m\]\$(git-branch-prompt)\[\033[0m\] \$ "
注意: 上面的
git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3
可以改成git symbolic-ref --short -q HEAD
, 更簡潔, 而且測試有效. 謝謝風(fēng)之去向_c305的建議;
為了讓大家可以比較前后, 原來的代碼就不修改了;
因?yàn)檫h(yuǎn)程服務(wù)器使用的是 bash, 所以配置文件在 ~/.bashrc
, 添加上面的代碼之后, 輸入 source ~/.bashrc
使配置立即生效.
PS. 可以通過
echo $SHELL
命令可以查看系統(tǒng)當(dāng)前使用的 Shell; 如果使用的是/bin/zsh
,配置文件在~/.zshrc
, 使用source ~/.bashrc
來使 zsh 的配置立即生效)
最終的效果是:
解讀代碼
第 1 部分
function git-branch-name {
git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3
}
git symbolic-ref
是 Git 的命令, 表示"符號引用 (symbolic reference), 指向目前所在的分支. 比如命令 git symbolic-ref HEAD
會輸出當(dāng)前的分支, 輸出樣式像這樣: refs/heads/dev
命令執(zhí)行有兩種輸出, 一種是正常輸出, 一種是錯(cuò)誤輸出. shell 把正常輸出標(biāo)記為 1, 錯(cuò)誤輸出標(biāo)記為 2.
在非 git 工作目錄下氓奈,‘git symbolic-ref HEAD‘會輸出一個(gè)錯(cuò)誤.
而 /dev/null
文件在被用作重定向輸出時(shí), 表示輸出被直接丟棄; 被用作重定向輸入時(shí), 表示文件結(jié)束.
那么 2>/dev/null
的作用就是:
- 在非 git 工作目錄下,‘git symbolic-ref HEAD‘ 會輸出一個(gè)錯(cuò)誤, 錯(cuò)誤會輸出到 /dev/null, 即不顯示
- 在 git 工作目錄下, ‘git symbolic-ref HEAD‘ 會正常輸出, 提示符會顯示當(dāng)前分支
- 也就是說"只有在 git 工作目錄下時(shí), 提示符才會顯示當(dāng)前分支, 否則什么都不顯示"
cut
是 Shell 命令, 表示剪下文本文件的數(shù)據(jù); cut -d"/" -f 3
表示分隔符是 /
, 以此分隔符來識別分割文本, 取出第 3 段數(shù)據(jù);
所以, git symbolic-ref HEAD
識別出的結(jié)果是 refs/heads/dev
, cut
以 /
為分隔符分割文本, 分別是 refs
和 heads
和 dev
, 然后取出第 3 段數(shù)據(jù), 就是 dev
(當(dāng)前的分支名稱)
第 2 部分
function git-branch-prompt {
local branch=`git-branch-name`
if [ $branch ]; then printf " [%s]" $branch; fi
}
local
在文檔中的解釋是:
The local command creates an [incr Tcl] object that is local to the current call frame. When the call frame goes away, the object is auto-matically deleted. This command is useful for creating objects that are local to a procedure.
那么 local
應(yīng)該是用于聲明"局部變量"的. 查閱資料得知, Shell 中函數(shù)定義的變量默認(rèn)是"全局變量", 所以如果要聲明"局部變量", 需要用 local
顯示聲明;
local branch=`git-branch-name`
是指把函數(shù) git-branch-name
獲得的值賦給 branch
變量;
注意, 在 Shell 中, 聲明變量時(shí)不需要加 $
, 而且 =
符號兩邊不能加空格, 在引用變量時(shí), 則需要加上 $
, 這就是為什么后面 if [ $branch ];
需要加 $
符號的原因.
if [ $branch ]; then printf " [%s]" $branch; fi
表示: 如果存在 $branch
變量, 則將該變量做為字符串打印出來; (PS: shell 的控制結(jié)構(gòu)中, ifelse
判斷語句的開頭是 if
, 結(jié)尾是 fi
,
第 3 部分
PS1
是 Shell 中的一個(gè)特殊變量, 用來表示"提示符", 該變量的可選參數(shù)包括:
-
\d
: 顯示日期, 格式為"星期 月 日" -
\h
: 顯示簡寫主機(jī)名秘车。如默認(rèn)主機(jī)名 "localhost" -
\t
: 顯示 24 小時(shí)制時(shí)間, 格式為 "HH:MM:SS" -
\T
: 顯示 12 小時(shí)制時(shí)間, 格式為 "HH:MM:SS" -
\A
: 顯示 24 小時(shí)制時(shí)間, 格式為 "HH:MM" -
\u
: 顯示當(dāng)前用戶名 -
\w
: 顯示當(dāng)前所在目錄的完整名稱 -
\W
: 顯示當(dāng)前所在目錄的最后一個(gè)目錄 -
\#
: 執(zhí)行的第幾個(gè)命令 -
\$
: 提示符, 如果是 root 用戶會顯示提示符為 "#", 如果是普通用戶會顯示提示符為$
Shell 輸出樣式設(shè)置:
-
\33[0m
關(guān)閉所有屬性 -
\33[1m
設(shè)置高亮度 -
\33[4m
下劃線 -
\33[5m
閃爍 -
\33[7m
反顯 -
\33[8m
消隱 -
\33[30m -- \33[37m
設(shè)置前景色 -
\33[40m -- \33[47m
設(shè)置背景色
所以 PS1="\u@\h \[\033[0;36m\]\W\[\033[0m\]\[\033[0;32m\]\$(git-branch-prompt)\[\033[0m\] \$ "
的解讀如下:
組成部分是:
-
\u@\h
表示顯示"當(dāng)前用戶名"和"主機(jī)名", 用@
符號連接; -
\W
顯示當(dāng)前所在目錄; -
\$(git-branch-prompt)
表示使用前面git-branch-prompt()
函數(shù)的結(jié)果; - 最后一個(gè)
\$
表示是 root 用戶會顯示提示符為 "#", 如果是普通用戶會顯示提示符為$
;
顏色設(shè)置是:
-
\[\033[0;36m\]\W\[\033[0m\]
剔除轉(zhuǎn)義字符應(yīng)該是\033[0;36m \W \033[0m
. 嘗試打印echo -e "\033[0;36m 我是目錄名稱 \033[0m"
, 輸出結(jié)果是
shell_color_set_01.jpg -
\[\033[0;32m\]\$(git-branch-prompt)\[\033[0m\]
剔除轉(zhuǎn)義字符應(yīng)該是\033[0;32m $(git-branch-prompt) \033[0m
, 嘗試打印echo -e "\033[0;32m 我是分支名稱 \033[0m "
, 輸出結(jié)果是
shell_color_set_02.jpg
參考資料
- git-setting-up-a-remote-repository-and-doing-an-initial-push
- Bash變量
- shell筆記-local仍翰、export用法
- shell學(xué)習(xí)筆記
- 本文下面的留言 (風(fēng)之去向_c305 的留言 )
文章歷史
- 2017.04.30 第一次發(fā)布
- 2017.11.06 添加網(wǎng)友 tomhacker 對于
2>/dev/null
的解釋, 謝謝 tomhacker - 2018.01.16 根據(jù)網(wǎng)友風(fēng)之去向_c305 的解釋和建議進(jìn)行修改; 謝謝 風(fēng)之去向_c305.
如果你覺得我的文章對你有用, 請打個(gè)"喜歡", 或者給些改進(jìn)的建議 _