本文主要是介绍《精通git》笔记之九(储藏与清理、签署工作、搜索),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
储藏与清理
储藏会处理工作目录的脏的状态 - 即修改的跟踪文件与暂存改动 - 然后将未完成的修改保存到一个栈上,可以在任何时候重新应用这些改动。
储藏工作
示例
$ git status
Changes to be committed:(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git checkout -- <file>..." to discard changes in working
directory)
modified: lib/simplegit.rb
现在想要切换分支,但是还不想要提交之前的工作;所以储藏修改。将新的储藏推送到栈上,运行 git stash或 git stash save:
$ git stash
Saved working directory and index state \"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
工作目录是干净的了:
$ git status
# On branch master
nothing to commit, working directory clean
在这时,能够轻易地切换分支并在其他地方工作;之前的修改被存储在栈上。要查看储藏的东西,可以使用 git stash list:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
在本例中,有两个之前做的储藏,所以可以看到三个不同的储藏工作。可以通过原来 stash 命令的帮助提示中的命令将刚刚储藏的工作重新应用:git stash apply。
如果想要应用其中一个更旧的储藏,可以通过名字指定它,像这样:git stash apply stash@{2}。如果
不指定一个储藏,Git 认为指定的是最近的储藏:
$ git stash apply
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb
#
应用选项只会尝试应用暂存的工作 - 在堆栈上还有它。可以运行 git stash drop 加上将要移除的储藏的名字
来移除它:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
也可以运行 git stash pop 来应用储藏然后立即从栈上扔掉它。
创造性的储藏
有几个储藏的变种可能也很有用。第一个非常流行的选项是 stash save 命令的 --keep-index 选项。它告诉
Git 不要储藏任何你通过 git add 命令已暂存的东西。
当做了几个改动并只想提交其中的一部分,过一会儿再回来处理剩余改动时,这个功能会很有用。
$ git status -s
M index.htmlM lib/simplegit.rb
$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the
index file
HEAD is now at 1b65b17 added the index file
$ git status -s
M index.html
另一个经常使用储藏来做的事情是像储藏跟踪文件一样储藏未跟踪文件。默认情况下,git stash 只会储藏已经在索引中的文件。如果指定 --include-untracked 或 -u 标记,Git 也会储藏任何创建的未跟踪文件。
$ git status -s
M index.htmlM lib/simplegit.rb
?? new-file.txt
$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the
index file
HEAD is now at 1b65b17 added the index file
$ git status -s
$
如果指定了 --patch 标记,Git 不会储藏所有修改过的任何东西,但是会交互式地提示哪些改动想要储藏、哪些改动需要保存在工作目录中。
$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGitreturn `#{git_cmd} 2>&1`.chompendend
+
+ def show(treeish = 'master')
+ command("git show #{treeish}")
+ endendtest
Stash this hunk [y,n,q,a,d,/,e,?]? y
Saved working directory and index state WIP on master: 1b65b17 added the
index file
从储藏创建一个分支
如果储藏了一些工作,将它留在那儿了一会儿,然后继续在储藏的分支上工作,在重新应用工作时可能会有问题。如果应用尝试修改刚刚修改的文件,将会出现一个合并冲突并不得不解决它。如果想要一个轻松的方式来再次测试储藏的改动,可以运行 git stash branch 创建一个新分支,检出储藏工作时所在的提交,重新在那应用工作,然后在应用成功后扔掉储藏:
$ git stash branch testchanges
Switched to a new branch "testchanges"
# On branch testchanges
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: lib/simplegit.rb
#
Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
这是在新分支轻松恢复储藏工作并继续工作的一个很不错的途径。
清理工作目录
对于工作目录中一些工作或文件,有时需要想做的也许不是储藏而是移除。可以使用git clean 命令。
需要谨慎地使用这个命令,因为它被设计为从工作目录中移除未被追踪的文件。不一定能找回来那些文件的内容。一个更安全的选项是运行 git stash --all 来移除每一样东西并存放在栈中。
可以使用git clean
命令去除冗余文件或者清理工作目录。使用git clean -f -d
命令来移除工作目录中所有
未追踪的文件以及空的子目录。-f 意味着 强制 或 “确定移除”。
如果只是想要看看它会做什么,可以使用 -n 选项来运行命令,这意味着 “做一次演习然后告诉你 将要 移除什么”。
$ git clean -d -n
Would remove test.o
Would remove tmp/
默认情况下,git clean 命令只会移除没有忽略的未跟踪文件。任何与 .gitiignore 或其他忽略文件中的模
式匹配的文件都不会被移除。如果移除所有的 .o 文件,可以给 clean 命令增加一个 -x 选项。
$ git status -sM lib/simplegit.rb
?? build.TMP
?? tmp/
$ git clean -n -d
Would remove build.TMP
Would remove tmp/
$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/
如果不知道 git clean 命令将会做什么,在将 -n 改为 -f 来真正做之前总是先用 -n 来运行它做双重检查。另一个小心处理过程的方式是使用 -i 或 “interactive” 标记来运行它。
这将会以交互模式运行 clean 命令。
签署工作
这一部分功能看起来很复杂,不太常用,略过。
搜索
Git 提供了一个 grep 命令,可以很方便地从提交历史或者工作目录中查找一个字符串或者正则表达式。
默认情况下 Git 会查找你工作目录的文件。可以传入 -n 参数来输出 Git 所找到的匹配行行号。
$ git grep -n gmtime_r
compat/gmtime.c:3:#undef gmtime_r
compat/gmtime.c:8: return git_gmtime_r(timep, &result);
compat/gmtime.c:11:struct tm *git_gmtime_r(const time_t *timep, struct tm
*result)
可以使用 --count 选项来使 Git 输出概述的信息,仅仅包括哪些文件包含匹配以及每个文件包含了多少个匹配。
$ git grep --count gmtime_r
compat/gmtime.c:4
compat/mingw.c:1
compat/mingw.h:1
如果想看匹配的行是属于哪一个方法或者函数,你可以传入 -p 选项:
$ git grep -p gmtime_r *.c
date.c=static int match_multi_number(unsigned long num, char c, const char
*date, char *end, struct tm *tm)
date.c: if (gmtime_r(&now, &now_tm))
date.c=static int match_digit(const char *date, struct tm *tm, int
*offset, int *tm_gmt)
date.c: if (gmtime_r(&time, tm)) {
在这里我们可以看到在 date.c 文件中有 match_multi_number 和 match_digit 两个函数调用了gmtime_r。
相比于一些常用的搜索命令比如 grep 和 ack,git grep 命令有一些的优点。第一就是速度非常快,第二是你不仅仅可以可以搜索工作目录,还可以搜索任意的 Git 树。例如可以在一个旧版本的 Git 源代码中查找,而不是当前检出的版本。
Git 日志搜索
若是想知道是什么 时候 存在或者引入的。git log 命令有许多强大的工具可以通过提交信息甚至是 diff 的内容来找到某个特定的提交。
例如,如果我们想找到 ZLIB_BUF_MAX 常量是什么时候引入的,我们可以使用 -S 选项来显示新增和删除该字符串的提交。
$ git log -S ZLIB_BUF_MAX --oneline
e01503b zlib: allow feeding more than 4GB in one go
ef49a7a zlib: zlib can only process 4GB at a time
如果我们查看这些提交的 diff,我们可以看到在 ef49a7a 这个提交引入了常量,并且在 e01503b 这个提交中被修改了。
如果希望得到更精确的结果,可以使用 -G 选项来使用正则表达式搜索。
行日志搜索
行日志搜索是另一个相当高级并且有用的日志搜索功能。这是一个最近新增的不太知名的功能,但却是十分有用。在 git log 后加上 -L 选项即可调用,它可以展示代码中一行或者一个函数的历史。
例如,假设我们想查看 zlib.c 文件中git_deflate_bound
函数的每一次变更,我们可以执行 git log -L :git_deflate_bound:zlib.c。Git 会尝试找出这个函数的范围,然后查找历史记录,并且显示从函数创建之后一系列变更对应的补丁。
$ git log -L :git_deflate_bound:zlib.c
commit ef49a7a0126d64359c974b4b3b71d7ad42ee3bca
Author: Junio C Hamano <gitster@pobox.com>
Date: Fri Jun 10 11:52:15 2011 -0700zlib: zlib can only process 4GB at a time
diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -85,5 +130,5 @@
-unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+unsigned long git_deflate_bound(git_zstream *strm, unsigned long size){
- return deflateBound(strm, size);
+ return deflateBound(&strm->z, size);}
commit 225a6f1068f71723a910e8565db4e252b3ca21fa
Author: Junio C Hamano <gitster@pobox.com>
Date: Fri Jun 10 11:18:17 2011 -0700zlib: wrap deflateBound() too
diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -81,0 +85,5 @@
+unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+{
+ return deflateBound(strm, size);
+}
+
如果 Git 无法计算出如何匹配你代码中的函数或者方法,可以提供一个正则表达式。例如,这个命令和上面的是等同的:git log -L ‘/unsigned long git_deflate_bound/’,/^}/:zlib.c。也可以提供单行或者一个范围的行号来获得相同的输出。
这篇关于《精通git》笔记之九(储藏与清理、签署工作、搜索)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!