clearly-describe-rm-mv
html 452 lines 16.9 KB
Raw
1 ---
2 layout: zh_reference
3 ---
4
5 <div class="box">
6 <h2>
7 <span class="docs">
8 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Viewing-the-Commit-History">书</a>
9 </span>
10 检查与比较
11 </h2>
12 <div class="block">
13 <p>
14 现在你有了一堆分支,短期的主题、长期的特性或者其它。怎样追踪他们呢?
15 Git 有一组工具,可以帮助你弄明白工作是在哪儿完成的,两个分支间的区别是啥,等等。
16 </p>
17
18 <p class="nutshell">
19 <b>简而言之</b> 执行 <code>git log</code> 找到你的项目历史中的特定提交 ——
20 按作者、日期、内容或者历史记录。执行 <code>git diff</code> 比较历史记录中的两个不同的点 ——
21 通常是为了看看两个分支有啥区别,或者从某个版本到另一个版本,你的软件都有啥变化。
22 </p>
23 </div>
24 </div>
25
26 <div class="box">
27 <h2>
28 <span class="docs">
29 <a target="new" href="http://git-scm.com/docs/git-log">文档</a> &nbsp;
30 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Viewing-the-Commit-History#Limiting-Log-Output">书k</a>
31 </span>
32 <a name="log">git log</a>
33 <span class="desc">过滤你的提交历史记录</span>
34 </h2>
35
36 <div class="block">
37 <p>
38 通过查看分支中另一分支看不到的提交记录,我们已经看到如何用 <code>git log</code> 来比较分支。
39 (如果你不记得了,它看起来是这样的:<code>git log branchA ^branchB</code>)。
40 而且,你也可以用 <code>git log</code> 去寻找特定的提交。
41 在此,我们会看到一些更广为使用的 <code>git log</code> 选项,不过哪有很多。
42 完整的清单可以看看官方文档。
43 </p>
44
45 <h4>
46 git log --author
47 <small>只寻找某个特定作者的提交</small>
48 </h4>
49
50 <p>
51 要过滤你的提交历史,只寻找某个特定作者的提交,你可以使用 <code>--author</code> 选项。
52 例如,比方说我们要找 Git 源码中 Linus 提交的部分。
53 我们可以执行类似 <code>git log --author=Linus</code> 的命令。
54 这个查找是大小写敏感的,并且也会检索电子邮箱地址。
55 我在此例中使用 <code>-[number]</code> 选项,以限制结果为最近 [number] 次的提交。
56 </p>
57
58 <pre>
59 <b>$ git log --author=Linus --oneline -5</b>
60 81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
61 3bb7256 make "index-pack" a built-in
62 377d027 make "git pack-redundant" a built-in
63 b532581 make "git unpack-file" a built-in
64 112dd51 make "mktag" a built-in
65 </pre>
66
67 <h4>
68 git log --since --before
69 <small>根据日期过滤提交记录</small>
70 </h4>
71
72 <p>
73 如果你要指定一个你感兴趣的日期范围以过滤你的提交,可以执行几个选项 ——
74 我用 <code>--since</code> 和 <code>--before</code>,但是你也可以用 <code>--until</code> 和 <code>--after</code>。
75 例如,如果我要看 Git 项目中三周前且在四月十八日之后的所有提交,我可以执行这个(我还用了 <code>--no-merges</code> 选项以隐藏合并提交):
76 </p>
77
78 <pre>
79 <b>$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges</b>
80 5469e2d Git 1.7.1-rc2
81 d43427d Documentation/remote-helpers: Fix typos and improve language
82 272a36b Fixup: Second argument may be any arbitrary string
83 b6c8d2d Documentation/remote-helpers: Add invocation section
84 5ce4f4e Documentation/urls: Rewrite to accomodate transport::address
85 00b84e9 Documentation/remote-helpers: Rewrite description
86 03aa87e Documentation: Describe other situations where -z affects git diff
87 77bc694 rebase-interactive: silence warning when no commits rewritten
88 636db2c t3301: add tests to use --format="%N"
89 </pre>
90
91 <h4>
92 git log --grep
93 <small>根据提交注释过滤提交记录</small>
94 </h4>
95
96 <p>
97 你或许还想根据提交注释中的某个特定短语查找提交记录。可以用 <code>--grep</code> 选项。
98 比如说我知道有个提交是有关使用 P4EDITOR 环境变量,又想回忆起那个改动是啥样子的 —— 我可以用 <code>--grep</code> 选项找到该提交。
99 </p>
100
101 <pre>
102 <b>$ git log --grep=P4EDITOR --no-merges</b>
103 <span class="yellow">commit 82cea9ffb1c4677155e3e2996d76542502611370</span>
104 Author: Shawn Bohrer
105 Date: Wed Mar 12 19:03:24 2008 -0500
106
107 git-p4: Use P4EDITOR environment variable when set
108
109 Perforce allows you to set the P4EDITOR environment variable to your
110 preferred editor for use in perforce. Since we are displaying a
111 perforce changelog to the user we should use it when it is defined.
112
113 Signed-off-by: Shawn Bohrer &lt;shawn.bohrer@gmail.com>
114 Signed-off-by: Simon Hausmann &lt;simon@lst.de>
115 </pre>
116
117 <p>
118 Git 会对所有的 <code>--grep</code> 和 <code>--author</code> 参数作逻辑或。
119 如果你用 <code>--grep</code> 和 <code>--author</code> 时,想看的是某人写作的并且有某个特殊的注释内容的提交记录,
120 你需要加上 <code>--all-match</code> 选项。
121 在这些例子中,我会用上 <code>--format</code> 选项,这样我们就可以看到每个提交的作者是谁了。
122 </p>
123
124 <p>
125 如果我查找注释内容含有 “p4 depo”的提交,我得到了三个提交:
126 </p>
127
128 <pre>
129 <b>$ git log --grep="p4 depo" --format="%h %an %s"</b>
130 ee4fd1a Junio C Hamano Merge branch 'master' of git://repo.or.cz/git/fastimport
131 da4a660 Benjamin Sergeant git-p4 fails when cloning a p4 depo.
132 1cd5738 Simon Hausmann Make incremental imports easier to use by storing the p4 d
133 </pre>
134
135 <p>
136 如果我加上 <code>--author=Hausmann</code> 参数,与进一步过滤上述结果到 Simon 的唯一提交相反,
137 它会告诉我所有 Simon 的提交,或者注释中有“p4 demo”的提交:
138 </p>
139
140 <pre>
141 <b>$ git log --grep="p4 depo" --format="%h %an %s" --author="Hausmann"</b>
142 cdc7e38 Simon Hausmann Make it possible to abort the submission of a change to Pe
143 f5f7e4a Simon Hausmann Clean up the git-p4 documentation
144 30b5940 Simon Hausmann git-p4: Fix import of changesets with file deletions
145 4c750c0 Simon Hausmann git-p4: git-p4 submit cleanups.
146 0e36f2d Simon Hausmann git-p4: Removed git-p4 submit --direct.
147 edae1e2 Simon Hausmann git-p4: Clean up git-p4 submit's log message handling.
148 4b61b5c Simon Hausmann git-p4: Remove --log-substitutions feature.
149 36ee4ee Simon Hausmann git-p4: Ensure the working directory and the index are cle
150 e96e400 Simon Hausmann git-p4: Fix submit user-interface.
151 38f9f5e Simon Hausmann git-p4: Fix direct import from perforce after fetching cha
152 2094714 Simon Hausmann git-p4: When skipping a patch as part of "git-p4 submit" m
153 1ca3d71 Simon Hausmann git-p4: Added support for automatically importing newly ap
154 ...
155 </pre>
156
157 <p>
158 不过,如果加上 <code>--all-match</code>,结果就是我想要的了:
159 </p>
160
161 <pre>
162 <b>$ git log --grep="p4 depo" --format="%h %an %s" --author="Hausmann" --all-match</b>
163 1cd5738 Simon Hausmann Make incremental imports easier to use by storing the p4 d
164 </pre>
165
166 <h4>
167 git log -S
168 <small>依据所引入的差值过滤</small>
169 </h4>
170
171 <p>
172 如果你写的提交注释都极度糟糕怎么办?或者,如果你要找某个函数是何时引入的,某些变量是在哪里开始被使用的?
173 你可以告诉 Git 在每个提交之间的差值中查找特定字符串。
174 例如,如果我们想要找出哪个提交修改出了类似函数名“userformat_find_requirements”,
175 我们可以执行(注意在“-S”与你要找的东东之间没有“=”):
176 </p>
177
178 <pre>
179 <b>$ git log -Suserformat_find_requirements</b>
180 <span class="yellow">commit 5b16360330822527eac1fa84131d185ff784c9fb</span>
181 Author: Johannes Gilger
182 Date: Tue Apr 13 22:31:12 2010 +0200
183
184 pretty: Initialize notes if %N is used
185
186 When using git log --pretty='%N' without an explicit --show-notes, git
187 would segfault. This patches fixes this behaviour by loading the needed
188 notes datastructures if --pretty is used and the format contains %N.
189 When --pretty='%N' is used together with --no-notes, %N won't be
190 expanded.
191
192 This is an extension to a proposed patch by Jeff King.
193
194 Signed-off-by: Johannes Gilger
195 Signed-off-by: Junio C Hamano
196 </pre>
197
198 <h4>
199 git log -p
200 <small>显示每个提交引入的补丁</small>
201 </h4>
202
203 <p>
204 每个提交都是项目的一个快照。由于每个提交都记录它所基于的快照,Git 能够经常对它们求差值,并以补丁形式向你展示。
205 这意味着,对任意提交,你都可以获取该提交给项目引入补丁。
206 你可以用 <code>git show [SHA]</code> 加上某个特定的提交 SHA 获取,或者执行 <code>git log -p</code>,
207 它会告诉 Git 输出每个提交之后的补丁。这是个总结某一分支或者两个提交之间都发生了神马的好途径。
208 </p>
209
210 <pre>
211 <b>$ git log -p --no-merges -2</b>
212 <span class="yellow">commit 594f90bdee4faf063ad07a4a6f503fdead3ef606</span>
213 Author: Scott Chacon &lt;schacon@gmail.com>
214 Date: Fri Jun 4 15:46:55 2010 +0200
215
216 reverted to old class name
217
218 <span class="umber">diff --git a/ruby.rb b/ruby.rb
219 index bb86f00..192151c 100644
220 --- a/ruby.rb
221 +++ b/ruby.rb</span>
222 <span class="lblue">@@ -1,7 +1,7 @@</span>
223 <span class="red">-class HiWorld</span>
224 <span class="green">+class HelloWorld</span>
225 def self.hello
226 puts "Hello World from Ruby"
227 end
228 end
229
230 <span class="red">-HiWorld.hello</span>
231 <span class="green">+HelloWorld.hello</span>
232
233 <span class="yellow">commit 3cbb6aae5c0cbd711c098e113ae436801371c95e</span>
234 Author: Scott Chacon &lt;schacon@gmail.com>
235 Date: Fri Jun 4 12:58:53 2010 +0200
236
237 fixed readme title differently
238
239 <span class="umber">diff --git a/README b/README
240 index d053cc8..9103e27 100644
241 --- a/README
242 +++ b/README</span>
243 <span class="lblue">@@ -1,4 +1,4 @@</span>
244 <span class="red">-Hello World Examples</span>
245 <span class="green">+Many Hello World Examples</span>
246 ======================
247
248 This project has examples of hello world in
249 </pre>
250
251 <p>
252 这是个总结改动,以及合并或发布之前重审一系列提交的好方式。
253 </p>
254
255 <h4>
256 git log --stat
257 <small>显示每个提交引入的改动的差值统计</small>
258 </h4>
259
260 <p>
261 如果 <code>-p</code> 选项对你来说太详细了,你可以用 <code>--stat</code> 总结这些改动。
262 这是不用 <code>-p</code>,而用 <code>--stat</code> 选项时,同一份日志的输出。
263 </p>
264
265 <pre>
266 <b>$ git log --stat --no-merges -2</b>
267 <span class="yellow">commit 594f90bdee4faf063ad07a4a6f503fdead3ef606</span>
268 Author: Scott Chacon &lt;schacon@gmail.com>
269 Date: Fri Jun 4 15:46:55 2010 +0200
270
271 reverted to old class name
272
273 ruby.rb | 4 <span class="green">++</span><span class="red">--</span>
274 1 files changed, 2 insertions(+), 2 deletions(-)
275
276 <span class="yellow">commit 3cbb6aae5c0cbd711c098e113ae436801371c95e</span>
277 Author: Scott Chacon &lt;schacon@gmail.com>
278 Date: Fri Jun 4 12:58:53 2010 +0200
279
280 fixed readme title differently
281
282 README | 2 <span class="green">+</span><span class="red">-</span>
283 1 files changed, 1 insertions(+), 1 deletions(-)
284 </pre>
285
286 <p>
287 同样的基本信息,但更紧凑 —— 它仍然让你看到相对改动,和改动了哪些文件。
288 </p>
289
290 </div>
291 </div>
292
293 <div class="box">
294 <h2>
295 <span class="docs">
296 <a target="new" href="http://git-scm.com/docs/git-diff">文档</a> &nbsp;
297 <a target="new" href="http://git-scm.com/book/en/Distributed-Git-Maintaining-a-Project#Determining-What-Is-Introduced">书</a>
298 </span>
299 <a name="diff">git diff</a>
300 <span class="desc"></span>
301 </h2>
302
303 <div class="block">
304
305 <p>
306 最后,要查看两个提交快照的绝对改动,你可以用 <code>git diff</code> 命令。
307 这在两个主要情况中广为使用 —— 查看两个分支彼此之间的差值,和查看自发布或者某个旧历史点之后都有啥变了。让我们看看这俩情况。
308 </p>
309
310 <p>
311 你仅需执行 <code>git diff [version]</code>(或者你给该发布打的任何标签)就可以查看自最近发布之后的改动。
312 例如,如果我们想要看看自 v0.9 发布之后我们的项目改变了啥,我们可以执行 <code>git diff v0.9</code>
313 </p>
314
315 <pre>
316 <b>$ git diff v0.9</b>
317 <span class="umber">diff --git a/README b/README
318 index d053cc8..d4173d5 100644
319 --- a/README
320 +++ b/README</span>
321 <span class="lblue">@@ -1,4 +1,4 @@</span>
322 <span class="red">-Hello World Examples</span>
323 <span class="green">+Many Hello World Lang Examples</span>
324 ======================
325
326 This project has examples of hello world in
327 <span class="umber">diff --git a/ruby.rb b/ruby.rb
328 index bb86f00..192151c 100644
329 --- a/ruby.rb
330 +++ b/ruby.rb</span>
331 <span class="lblue">@@ -1,7 +1,7 @@</span>
332 <span class="red">-class HiWorld</span>
333 <span class="green">+class HelloWorld</span>
334 def self.hello
335 puts "Hello World from Ruby"
336 end
337 end
338
339 <span class="red">-HiWorld.hello</span>
340 <span class="green">+HelloWorld.hello</span>
341 </pre>
342
343 <p>
344 正如 <code>git log</code>,你可以给它加上 <code>--stat</code> 参数。
345 </p>
346
347 <pre>
348 <b>$ git diff v0.9 --stat</b>
349 README | 2 +-
350 ruby.rb | 4 ++--
351 2 files changed, 3 insertions(+), 3 deletions(-)
352 </pre>
353
354 <p>
355 要比较两个不同的分支,你可以执行类似 <code>git diff branchA branchB</code> 的命令。
356 不过它的问题在于它会完完全全按你说的作 —— 它会直接给你个补丁文件,该补丁能够将甲分支的最新快照变成乙分支的最新快照的样子。
357 这意味着如果两个分支已经产生分歧 —— 奔往两个不同方向了 —— 它会移除甲分支中引入的所有工作,然后累加乙分支中的所有工作。
358 这大概不是你要的吧 —— 你想要不在甲分支中的乙分支的改动。所以你真的需要的是两个分支叉开去时,和最新的乙分支的差别。
359 所以,如果我们的历史记录看起来像这样:
360 </p>
361
362 <pre>
363 <b>$ git log --graph --oneline --decorate --all</b>
364 * 594f90b (HEAD, tag: v1.0, master) reverted to old class name
365 | * 1834130 (erlang) added haskell
366 | * ab5ab4c added erlang
367 |/
368 * 8d585ea Merge branch 'fix_readme'
369 ...
370 </pre>
371
372 <p>
373 并且,我们想要看“erlang”分支与主分支相比的查别。执行 <code>git diff master erlang</code> 会给我们错误的结果。
374 </p>
375
376 <pre>
377 <b>$ git diff --stat master erlang</b>
378 erlang_hw.erl | 5 +++++
379 haskell.hs | 4 ++++
380 ruby.rb | 4 ++--
381 3 files changed, 11 insertions(+), 2 deletions(-)
382 </pre>
383
384 <p>
385 你可以看到,它加上了 erlang 和 haskell 文件,这确实是我们在该分支中做的,
386 但是它同时恢复了我们在主分支中改动的 ruby 文件。我们真心想要的只是“erlang”分支中的改动(添加两个文件)。
387 我们可以通过求两个分支分歧时的共同提交与该分支的差值得到想要的结果:
388 </p>
389
390 <pre>
391 <b>$ git diff --stat 8d585ea erlang</b>
392 erlang_hw.erl | 5 +++++
393 haskell.hs | 4 ++++
394 2 files changed, 9 insertions(+), 0 deletions(-)
395 </pre>
396
397 <p>
398 这才是我们在找的,但是我们可不想要每次都要找出两个分支分歧时的那次提交。
399 幸运的是,Git 为此提供了一个快捷方式。
400 如果你执行 <code>git diff master...erlang</code>(在分支名之间有三个半角的点),
401 Git 就会自动找出两个分支的共同提交(也被成为合并基础),并求差值。
402 </p>
403
404 <pre>
405 <b>$ git diff --stat master erlang</b>
406 erlang_hw.erl | 5 +++++
407 haskell.hs | 4 ++++
408 ruby.rb | 4 ++--
409 3 files changed, 11 insertions(+), 2 deletions(-)
410 <b>$ git diff --stat master...erlang</b>
411 erlang_hw.erl | 5 +++++
412 haskell.hs | 4 ++++
413 2 files changed, 9 insertions(+), 0 deletions(-)
414 </pre>
415
416 <p>
417 几乎每一次你要对比两个分支的时候,你都会想用三个点的语法,因为它通常会给你你想要的。
418 </p>
419
420 <p>
421 顺带提一句,你还可以让 Git 手工计算两次提交的合并基础(第一个共同的祖提交),即 <code>git merge-base</code> 命令:
422 </p>
423
424 <pre>
425 <b>$ git merge-base master erlang</b>
426 8d585ea6faf99facd39b55d6f6a3b3f481ad0d3d
427 </pre>
428
429 <p>
430 所以你执行下面这个也跟 <code>git diff master...erlang</code> 一样:
431 </p>
432
433 <pre>
434 <b>$ git diff --stat $(git merge-base master erlang) erlang</b>
435 erlang_hw.erl | 5 +++++
436 haskell.hs | 4 ++++
437 2 files changed, 9 insertions(+), 0 deletions(-)
438 </pre>
439
440 <p>当然,我会推荐简单点的那个。</p>
441
442
443 <p class="nutshell">
444 <b>简而言之</b> 使用 <code>git diff</code> 查看某一分支自它偏离出来起与过去某一点之间项目的改动。
445 总是使用 <code>git diff branchA...branchB</code> 来查看 branchB 与 branchA 的相对差值,这会让事情简单点。
446 </p>
447
448 </div>
449 </div>
450
451 <p>就是这样了! 请阅读
452 <a href="http://git-scm.com/book/">《Pro Git》</a> 以获得更多信息。</p>