1.4 查看 DAG
图
DAG
图:全名为 Directed Acyclic Graph
,即有向无环图。
示例仓库的 DAG
图如下:
注意:图中的箭头是对版本依赖的描述,即从每个版本指向其上一个版本,因此与版本的实际创建过程是相反的。
本节介绍 git log
命令的几个相关特性:
# ensure that the master branch is pointing to 34acc37:
$ git checkout master && git reset --hard 34acc37
# Show the last 3 commits
$ git log -3
# Turn on colors in the Git output
$ git config --global color.ui auto
# Some more pretty print
$ git log --decorate --graph --oneline --all
# Some DIY format using --pretty
$ git log --all --graph --pretty=format:'%Cred%h%Creset -
%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset'
# Make a new alias
$ git config --global alias.graph "log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset'"
注意:自定义格式中的通用格式为:%C<color-name>text-be-colored%Creset
1.5 提取已修复事项
在软件项目的发布声明中列出已修复的 bug 清单是很常见的操作。一个不错的做法是每次将 bug 修复情况写入提交版本的注释里。而更好的做法,是将这类操作标准化,例如用 "Fixes-bug"
开头,然后是 bug 的标识符,再一并放到提交注释的末尾。这样做的好处在于,可以自动生成下一次发布所修复的 bug 清单。
以 JGit
项目为例,其 bug 标识符为字符串 Bug:
+ bug ID
。
练习目标:将 git log
的输出限制在“仅列出自上次发布(贴标签)以来的提交、且这些提交中包含一个修复的 bug”。
# Init repo
$ git clone https://git.eclipse.org/r/jgit/jgit demo
$ cd demo
$ git checkout master
$ git reset --hard b14a939
# Find the last tag (release)
$ git describe
v3.1.0.201310021548-r-96-gb14a939
关于
v3.1.0.201310021548-r-96-gb14a939
:
- 最近一次的标签名:
v3.1.0.201310021548-r
- 自上一标签以来的
commit
数:96
- 当前
commit
的简化SHA-1
:b14a939
# Our target format should be like this:
# Commit-id: Commit subject
# Fixes-bug: xxx
# ======================================
# Get the commits between HEAD and last release
$ git log --grep "Bug: " v3.1.0.201310021548-r..HEAD
# Rearrange the output with --pretty
# that is:
# 1. %h: abbreviated commit ID
# 2. |: a separator
# 3. %s: the commit subject (the first line of the commit message)
# 4. %n: a new line
# 5. %b: the body
$ git log --grep "Bug: " v3.1.0.201310021548-r..HEAD --pretty="%h|%s%n%b"
# use grep to filter the lines that contain "|" or "Bug: "
$ git log --grep "Bug: " v3.1.0.201310021548-r..HEAD --pretty="%h|%s%n%b" | grep -E "\||Bug: "
# replace "|" and "Bug " with sed
$ git log --grep "Bug: " v3.1.0.201310021548-r..HEAD --pretty="%h|%s%n%b" | grep -E "\||Bug: " | sed -e 's/|/: /' -e 's/Bug:/Fixes-bug:/'
相关语法:
sed
: short for stream editor
,-e
is short for --expression
sed -e script
等效于 sed --expression=script
sed -e 's/regexp/replacement'
: Attempt to match regexp
against the pattern space. If successful, replace that portion matched with replacement
. The replacement may contain the special character &
to refer to that portion of the pattern space which matched, and the special escapes \1
through \9
to refer to the corresponding matching sub-expressions in the regexp.
grep -E PATTERNS
: PATTERNS are extended regular expressions
如果只提取 Bug 的 ID:
$ git log v3.1.0.201310021548-r..HEAD | grep "Bug: "
如果只提取包含 Bug 的 commit
ID,以及注释的主题(subjects,即首行注释):
$ git log --grep "Bug: " --oneline v3.1.0.201310021548-r..HEAD
1.6 获取变更文件列表
获取指定版本范围内的文件变更列表:
$ git checkout master && git reset --hard b14a939
$ git diff --name-only v3.1.0.201310021548-r..HEAD
与 1.5 节中的 git log 命令一样,git diff
也对指定版本范围内的所有内容生效。参数 --name-only
会仅输出指定版本范围内、所有包含变更的文件路径列表。
若要细分出变更的具体类型,例如被删除的文件,则可以加过滤参数 --diff-filter=D
:
$ git checkout master && git reset --hard b14a939
$ git diff --name-only --diff-filter=D v3.1.0.201310021548-r..HEAD
常见的变更类型:
--diff-filter=A
: added--diff-filter=C
: copied--diff-filter=D
: deleted--diff-filter=M
: modified--diff-filter=R
: renamed
更多参数设置,详见:git help diff