命令行使用git的正确姿势--tig

在命令行下使用git的正确姿势应该是在vim里面是用git插件,不过并不是所有人都喜欢Vim编辑器,这个时候你可以试下tig。这也是本文要讲的东西,安装方法很简单、

请看Installation instruction,一般来说用你系统的包管理器安装tig即可。

tig的配置文件为.tigrc,如何配置,将是本文的主题,主要是翻译源码中的帮助文档,希望对你有用。

概述

你可以永久的设置选项通过把它放到~/.tigrc中。

  • tigrc中的每一行只能包含一个命令,
  • 你可以用\用来分隔长行。
  • #开始的语句被视为注释。

除了在.tigrc中设置,你也可以在.gitconfig中新建一个标签[tig]来做一样的设置

示例:

1
[tig] show-changes = true
[tig "color"] cursor = yellow red bold 
[tig "bind"] generic = P parent

tigrc语法总结:

set variable = value
bind keymap key action
color area fgcolor bgcolor [attributes]
source path

变量

语法:

set variables = value

示例:

1
set commit-order = topo		# Order commits topologically
set git-colors = no		# Do not read Git's color settings.
set horizontal-scroll = 33%	# Scroll 33% of the view width
set blame-options = -C -C -C	# Blame lines from other files

# Wrap branch names with () and tags with <>
set reference-format = (branch) <tag>

# Configure blame view columns using command spanning multiple lines.
set blame-view = \
	date:default \
	author:abbreviated \
	file-name:auto \
	id:yes,color \
	line-number:yes,interval=5 text

变量只有三种类型,要么是bool,要么是string要么是int,要么是混合的。

  • bool类型的变量,可能的取值是”true”,”yes”或者”1”
  • int类型的取值只能是非负整数;
  • string类型用单引号或者双引号包括起来。
  • 混合的类型的取值会在下面的提到(只是包含有限的取值)

下面的变量可以设置:

  • diff-options (string)::
    取值是用空格隔开的字符串用于diff-view中。

  • blame-options (string)::
    取值是用空格隔开的字符串。可用于告诉git-blame如何检测行的源头。

  • log-options (string)::
    取值是用空格隔开的字符串用于Log-view中,用于告诉git-log如何显示,实际上就是git-log的选项。

  • main-options (string)::
    取值是用空格隔开的字符串用于main-view中。作用同上。

  • reference-format (string)::
    用空格隔开的格式化字符串,用于格式化参考名字。

    Supported reference types are:

    • head : The current HEAD.
    • tag : A signed tag.
    • local-tag : An unsigned tag.
    • remote : A remote.
    • tracked-remote : The remote tracked by current HEAD.
    • replace : A replaced reference.
    • branch : Any other reference.
  • line-graphics (mixed) [ascii|default|utf-8|]::
    决定哪种类型的字符符号用于画行。

  • horizontal-scroll (mixed)::
    水平滚动百分比(相对当前的屏幕),取值可以像”33”,也可以是”33%”

  • git-colors (list)::
    取值由由空格隔开的”key=value”这样的形式组成,其中的key是git的color
    名字,value是tig的color名字,比如”branch.current=main-head”和”grep.filename=grep.file”
    设置”no”禁止。

  • show-notes (mixed) [|]::
    是否选择显示commit的note,所设置的内容将传递给git show --notes=命令。Note默认是使能的。
  • show-changes (bool)::
    是否在main-view显示stage或者unstage的状态。
  • vertical-split (mixed) [auto|]::
    是垂直还是水平分隔view。auto表示将会根据屏幕大小来自动选择方式。true的话表示垂直分隔。

  • split-view-height (mixed)::
    水平分割时的bottom view的高度(百分比)。

  • split-view-width (mixed)::
    垂直分割时的right-most view的宽度(百分比)。

  • status-untracked-dirs (bool)::
    是否显示未跟踪的目录里的内容。默认是on。

  • tab-size (int)::
    每个tab占据space数量,默认是8。

  • diff-context (int)::
    diff view的时候diff上下文显示行数。

  • diff-highlight (mixed)::
    是否使用Git的’diff-highlight’来高亮diffs。默认是false。

  • ignore-space (mixed) [no|all|some|at-eol|]::
    在diff-view中是否忽略空格改变。默认是不被忽略的。设置为all,, “some” or “at-eol” 相当于传递”–ignore-all-space”, “–ignore-space” or
    “–ignore-space-at-eol”给git diff或者git show

  • commit-order (enum) [auto|default|topo|date|author-date|reverse]::
    选择commit顺序。可选有:chronological reverse, topological order,
    date orderreverse order。用于当commit
    graphics在main-view中使能。在log很长的仓库中推荐设置这个选项为default,这样有助于加快加载的速度。

  • ignore-case (bool)::
    搜索的时候是否大小敏感。默认是大小敏感。

  • mailmap (bool)::
    从.mailmap读取名字和email,默认是off。请看git-shortlog(1)

  • wrap-lines (bool)::
    是否warp长行,默认是不进行warp。

  • focus-child (bool)::
    当子视图打开时是否聚焦在子视图上,默认是true。

  • editor-line-number (bool)::
    是否传递行号给编辑器。行号以+<line-number>加到命令行选项中文件名的前面,比如说:vim +10 tig.c

  • mouse (bool)::
    是否支持鼠标。默认off。

  • mouse-scroll (int)::
    鼠标滚动距离,默认是3行。必须设置mouse为true才能让这个选项有效。

  • refresh-mode (mixed) [manual|auto|after-command|periodic|]::
    控制视图根据仓库里面的文件的修改情况何刷新.当设置为”auto”的时候,当检测到文件修改的时候视图会自动刷新。当设置为manual的时候,不会自动刷新。当设置为after-command,只有在外部命令执行完毕之后才会刷新。当设置为periodic,就是周期刷新,周期根据变量refresh-interval

  • refresh-interval (int)::
    周期刷新的间隔。

  • file-args (args)::
    命令行参数传递给git-rev-parse(1)
  • rev-args (args)::
    命令行参数传递给git-rev-parse(1)

视图(view)变量设置

视图设置定义了视图中不同列的顺序和选项。每个视图设置期待一个用空格隔开的列标准。

列标准以列类型开始,后面可选的加一个冒号接着列选项列表。比如说author:email,width=20

列标准的第一个选项总是display相关的选项,当没有给display的值,那么默认给yes
对于那些期待枚举值的display选项将自动解决默认的枚举值,比如说file-name它的
display选项将自动设置为auto

标准允许单列。比如覆盖系统tigrc的配置。为了覆盖单个列,使用列名作为视图名的后缀。比如
说:main-view-date

示例:

1
# Enable both ID and line numbers in the blame view
set blame-view = date:default author:full file-name:auto id:yes,color \
		 line-number:yes,interval=5 text

# Change grep view to be similar to `git grep` format
set grep-view = file-name:yes line-number:yes,interval=1 text

# Show file sizes as units
set tree-view = line-number:no,interval=5 mode author:full \
		file-size:units date:default id:no file-name

# Show line numbers for every 10th line in the pager view
set pager-view = line-number:yes,interval=10 text

# Shorthands to change view settings for a previously defined column
set main-view-date = custom
set main-view-date-format = "%Y-%m-%d %H:%M"
set blame-view-line-number = no
# Use Git's default commit order, even when the commit graph is enabled.
set commit-order = default

下面这些列类型是这些视图所支持的。

1
2
3
4
5
6
7
8
blob-view, diff-view, log-view, pager-view, stage-view:: line-number, text
blame-view:: author, date, file-name, id, line-number, text
grep-view:: file-name, line-number, text
main-view:: author, date, commit-title, id, line-number
refs-view:: author, date, commit-title, id, line-number, ref
stash-view:: author, date, commit-title, id, line-number
status-view:: file-name, line-number, status
tree-view:: author, date, id, file-name, file-size, line-number, mode

列类型以及它们的列选项:

  • author:
    1. display(mixed) [full|abbreviated|email|email-user|]: 如何显示author的名字
      如果设置为abbreviated,那么author将以缩写来显示。
    2. width (int):列的宽度。如果范围是1到10,那么author名将以缩写来显示,当设置为0,那么将根据
      名字长度来显示。
  • commit-title:
    1. graph(mixed) [no|v2|v1]:是否在main-view显示版本图形。v1表示旧的图形渲染,它虽然不太准确但是
      更快。请看line-graph选项。
    2. refs(bool):在main-view是否显示引用(分支,tags和远程)
    3. overflow(bool or int):当commit文本超过给定的宽度是否在commit标题高亮超出的文本。当为bool值的时候那么默认的宽度是50,当为int值则以这个值为宽度。
  • date:
    1. display (mixed) [relative|relative-compact|custom|default|]:如何显示日期。如果设置为relative或者relative-compact,那么将显示一个相对的日期,比如“2分钟之前”。如果设置为”custom”,那么strftime(3)字符串格式将在format选项中指定。
    2. local(bool):如果是true,那么将使用localtime(3)来转换时区。注意相对时间将总是使用本地便宜。
    3. format(string):当display的模式选择为custom的时候,传给strftime(3)的格式化字符串。
    4. width(int):列的宽度,设置为0将自动适应。
  • file-name:
    1. display(mixed) [auto|always|]:什么时候显示文件名。如果设置为auto,那么文件名只有需要才会显示。
    2. width(int):列的宽度。同上。
  • file-size::
    1. display (mixed) [default|units|]:如何显示文件的大小。当设置为units的时候,sizes将以二进制后缀来显示,比如说12524将显示为”12.2K”。
    2. width(int):同上
  • id::
    1. display (bool):是否在main-view中显示commit ID
    2. width(int):commit ID的宽度,如果没有设置,tig将会使用core.abbrev的git设置。当设置为0将自动适应reflog。
  • line-number::
    1. display (bool):是否显示行号。
    2. interval (int):行号之间的间隔
    3. width (int):列的宽度
  • mode::
    1. display (bool):是否显示文件模式。
    2. width (int): 同上。
  • ref::
    1. display (bool):是否显示引用名(分支名,标签等)
    2. ‘width’ (int):同上。
  • status::
    1. ‘display’ (mixed) [no|short|long|]:如何显示状态标号。
    2. ‘width’ (int):同上。
  • text::
    1. ‘commit-title-overflow’ (bool or int):是否高亮那些超出指定字符长度的commit标题。默认长度是50,当为int值时,就是这个值作为最大长度。

所有的列选项都可以被toggle。形式::toggle coloumname-option

Bind按键映射

用于映射快捷键到指定动作。

语法:

bind keymap key action

示例:

1
# Add keybinding to quickly jump to the next diff chunk in the stage view
bind stage <Enter> :/^@@

# Disable the default mapping for running git-gc
bind generic G none

# User-defined external command to amend the last commit
bind status + !git commit --amend

# User-defined internal command that reloads ~/.tigrc
bind generic S :source ~/.tigrc

# UTF8-encoded characters can be used as key values.
bind generic ø @sh -c "printf '%s' %(commit) | pbcopy"

也可以在gitconfig中设置:

1
[tig "bind"]
	# 'unbind' the default quit key binding
	main = Q none
	# Cherry-pick current commit onto current branch
	generic = C !git cherry-pick %(commit)

keymap指定按键映射的范围,首先是在当前的view中搜索,找不到在从generic中搜。

view按键映射将会覆盖generic的,而它们都会覆盖内置的按键映射的。

Keymaps::

有效的范围是: main, diff, log, help, pager, status, stage,
tree, blob, blame, refs, stash, grep and generic. 使用 generic
作为所有视图的按键映射. 使用 search 作为在搜索时的按键操作。

Key values::

按键值不能被引号括起来。可以使用ASCII或者UTF8编码的字符或者下面这些符号名。符号按键名是大小不敏感的,
<>括起来。使用来绑定#按键,用作为<

一些Keycode:

1
*<Enter>*, *<Space>*, *<Backspace>*, *<Tab>*, *<Escape>* or *<Esc>*, *<Left>*,
*<Right>*, *<Up>*, *<Down>*, *<Insert>* or *<Ins>*, *<Delete>* or *<Del>*,
*<Hash>*, *<LessThan>* or *<LT>*, *<Home>*, *<End>*, *<PageUp>* or *<PgUp>*,
*<PageDown>* or *<PgDown>*, *<F1>*, *<F2>*, *<F3>*, *<F4>*, *<F5>*, *<F6>*,
*<F7>*, *<F8>*, *<F9>*, *<F10>*, *<F11>*, *<F12>*.

映射以Ctrl开始的按键,使用<Ctrl-key>.

例子:

1
bind main R		refresh
bind main <Down>	next
bind main <Ctrl-f>	scroll-page-down
bind main <Esc>o	options

由于ncurse的ctrl编码,其中Ctrl-mCtrl-i 不能被绑定,因为他们与EnterTab冲突。还有,
ncurse无法区分Ctrl-fCtrl-F两个按键映射,另外Ctrl-z也是作为后台执行的按键不能使用。

Actions

既可以是用户定义的命令(外部或者内部的)或者使用下面章节提到的action名字。

外部用户自定义命令

外部命令以一个或者多个选项标志开始:

!: 在前台运行外部命令并输出。
@: 在后台运行命令并且禁止输出
?: 在运行命令前弹出确认
<: 运行命令后退出

例子:?<git commit将会弹出确认提示,然后执行命令行退出tig

访问状态变量

用户定义的命令可以访问Tig的内部状态变量。在执行命令之前它们将被具体内容展开再传入命令中。

变量 说明
%(head) 当前view的head ID,默认是HEAD
%(commit) 当前被选中的commit id
%(blob) 当前被选中的blob ID.
%(branch) 当前被选中的分支名
%(remote) 当前被选中的远程名字.
%(tag) 当前被选中的tag名字
%(stash) 当前被选中的stash名字
%(directory) 在tree视图中的路径名,或者”.”如果没定义的话。
%(file) 当前选中文件名
%(lineno) 当前选择的文件名
%(ref) 当前blame的引用,或者HEAD如果没有定义的话。
%(revargs) 传递给命令行的版本号
%(fileargs) 传递给命令行文件参数
%(cmdlineargs) 其它所有的传递给命令行的参数
%(diffargs) 用于diff和stage视图来自diff-options或者TIG_DIFF_OPTS
%(blameargs) 用于blame视图的来自于选项blame-options的选项。
%(logargs) 用于log视图的来自于选项log-options的选项
%(mainargs) 用于main视图的来自于选项main-options的选项
%(prompt) 弹出提示输入参数的值。也可以用 "%(prompt Enter branch name: )"
%(text) 当前行的文字
%(repo:head) 当前checkout的分支名
%(repo:head-id) 当前checkout的分支的id
%(repo:remote) 当前:远程名/分支名
%(repo:cdup) 将要转到的相对于repo根目录的相对路径名,比如../
%(repo:prefix) 当前工作目录的前缀 e.g subdir/.
%(repo:git-dir) repo的.git所在决定路径, e.g. /src/repo/.git.
%(repo:is-inside-work-tree) tig是否运行在work tree中,true或者false
1
# Save save the current commit as a patch file when the user selects a
# commit in the main view and presses 'S'.
bind main S !git format-patch -1 %(commit)

# Create and checkout a new branch; specify custom prompt
bind main B ?git checkout -b "%(prompt Enter new branch name: )"

高级的类似shell的命令

如果你对命令需要用到一些动态的特性,比如说子shell,可以这样

1
bind generic I @sh -c "echo -n %(commit) | xclip -selection c"

或者结合git config的alias和Tig的外部命令:

1
[alias]
	gitk-bg = !"gitk HEAD --not $(git rev-parse --remotes) &"
	publish = !"for i in origin public; do git push $i; done"
[tig "bind"]
	# @-prefix means that the console output will not be shown.
	generic = V !@git gitk-bg
	generic = > !git publish

内部用户自定义命令

:开始的的命令,将被视为Tig的内部命令,可用的内部命令就是那些配置文件选项(就像本文提到的)还有paper view的命令,例子:

1
# Reload ~/.tigrc when 'S' is pressed
bind generic S :source .tigrc

# Change diff view to show all commit changes regardless of file limitations
bind diff F :set diff-options = --full-diff

# Show the output of git-reflog(1) in the pager view
bind generic W :!git reflog

# Search for previous diff (c)hunk and next diff header
bind stage 2 :?^@@
bind stage D :/^diff --(git|cc)

bind main I :toggle id				# Show/hide the ID column
bind diff D :toggle diff-options --minimal	# Use minimal diff algorithm
bind diff [ :toggle diff-context -3		# Decrease context (-U arg)
bind diff ] :toggle diff-context +3		# Increase context
bind generic V :toggle split-view-height -10%	# Decrease split height

内部Action符号

所有符号都是大小不敏感的,并且”view-main”, “View.Main”, and “VIEW_MAIN”
这三种形式的一样的。

视图切换:

符号 说明
view-main 显示main视图
view-diff 显示diff视图
view-log 显示log视图
view-tree 显示tree视图
view-blob 显示blob视图
view-blame 显示blame视图
view-refs 显示refs视图
view-status 显示status视图
view-stage 显示stage视图
view-stash 显示stash视图
view-grep 显示grep视图
view-pager 显示pager视图
view-help 显示help视图

视图操作:

符号 说明
enter 进入并且打开选择的行
back 返回到上一个视图状态
next 移动到下一个视图
previous 移动到前一个视图
parent 移动到父视图
view-next 移动当前聚焦到下一个视图
refresh 重载和刷新视图
maximize 最大化当前视图
view-close 关闭当前视图
quit 关闭所有视图并退出

视图特殊操作:

符号 说明
status-update Stage/unstage 文件s
status-revert Revert 文件
status-merge 使用外部文件来合并
stage-update-line Stage/unstage 单一文件
stage-split-chunk 分隔当前diff chunk

光标导航:

符号 说明
move-up 移动光标 向上一行
move-down 移动光标 向下一行
move-page-down 移动光标 向下翻页
move-page-up 移动光标 向上翻页
move-half-page-down 移动光标 向下半页
move-half-page-up 移动光标 想上半页
move-first-line 移动光标 到第一行
move-last-line 移动光标 到最后一行
move-next-merge 移动光标 下一个合并的commit
move-prev-merge 移动光标 上一个合并的commit

滚动相关:

符号 说明
scroll-line-up 向上滚动一行
scroll-line-down 向下滚动一行
scroll-page-up 向上滚动一页
scroll-page-down 向下滚动一页
scroll-first-col 移动到行首
scroll-left 向左移动两列
scroll-right 向右移动两列

搜索相关:

符号 说明
search 搜索
search-back 向后搜索
find-next 查找下一个匹配的
find-prev 查找上一个匹配的

其它:

符号 说明
edit 在编辑器中打开
prompt 打开提示
options 打开选项菜单
screen-redraw 重画屏幕
stop-loading 停止所有加载的视图
show-version 显示版本信息
none 什么也做

颜色命令

如果你对终端支持颜色的话,这个颜色命令可用于高亮用户界面的。

语法:

color area fgcolor bgcolor [attributes]

1
# Override the default terminal colors to white on black.
color default		white	black
# Diff colors
color diff-header	yellow	default
color diff-index	blue	default
color diff-chunk	magenta	default
color "Reported-by:"	green	default
# View specific color
color tree.date		black	cyan	bold

Area名字

既可以是内置的area名字也可以自定义的被括起来的字符串。例子:
e.g. “stage.diff-chunk” and “diff.diff-chunk”.

颜色名字

可用颜色包括: *white*, *black*, *green*, *magenta*, *blue*,
*cyan*, *yellow*, *red*, *default*. 使用 *default* 表示使用终端的颜色。

属性名字

可用属性包括:*normal*, *blink*, *bold*, *dim*, *reverse*,
*standout*, and *underline*。注意,不是所有属性都被终端所支持。

UI颜色

UI 说明
default Override default terminal colors (see above).
cursor The cursor line.
status The status window showing info messages.
title-focus The title window for the current view.
title-blur The title window of any backgrounded view.
search-result Highlighted search result.
delimiter Delimiter shown for truncated lines.
header The view header lines. Use ‘status.header’ to color the staged, unstaged, and untracked sections in the status view. Use ‘help.header’ to color the keymap sections in the help view.
line-number Line numbers.
id The commit ID.
date The author date.
author The commit author.
mode The file mode holding the permissions and type.
overflow Title text overflow.
directory The directory name.
file The file name.
file-size File size.

main视图

UI 说明
graph-commit The commit dot in the revision graph.
palette-[0-13] 14 different colors, used for distinguishing branches or commits. By default, the palette uses the ASCII colors, where the second half of them have the bold attribute enabled to give a brighter color.Example: palette-0 = red
main-commit The commit comment.
main-head Label of the current branch.
main-remote Label of a remote.
main-tracked Label of the remote tracked by the current branch.
main-tag Label of a signed tag.
main-local-tag Label of a local tag.
main-ref Label of any other reference.
main-replace Label of replaced reference.

status视图

UI 说明
stat-none Empty status label.
stat-staged Status flag of staged files.
stat-unstaged Status flag of unstaged files.
stat-untracked Status flag of untracked files.

help视图

UI 说明
help-group Help group name.
help-action Help action name.

高亮

Diff 增强

关于diff开始,块和行增加删除。

diff-header, diff-chunk, diff-add, diff-add2, diff-del,
diff-del2

通过Git diff机制发出的额外的diff信息,比如说模式改变,重命名的检测等。

diff-oldmode, diff-newmode, diff-copy-from, diff-copy-to,
diff-similarity, diff-index

漂亮的commit头部

pp-refs, pp-reflog, pp-reflogmsg, pp-merge

commit, parent, tree, author, committer

Signed-off-by, Acked-by, Reviewed-by and Tested-by lines are colorized.
Characters in the commit title exceeding a predefined width can be highlighted.

树增强

tree-dir, tree-file

source命令

source命令让读取另外的配置文件成为可能。

语法:

source ‘path’

示例:

1
source ~/.tig/colorscheme.tigrc
source ~/.tig/keybindings.tigrc