储藏与清理

储藏会处理工作目录的脏的状态 - 即修改的跟踪文件与暂存改动 - 然后将未完成的修改保存到一个栈上,可以在任何时候重新应用这些改动。

储藏工作

示例

$ 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》笔记之九(储藏与清理、签署工作、搜索)相关推荐

  1. Git笔记(27) 储藏与清理

    Git笔记(27) 储藏与清理 1. 混乱的状态 2. 储藏工作 3. 创造性的储藏 4. 从储藏创建一个分支 5. 清理工作目录 1. 混乱的状态 有时,当在项目的一部分上已经工作一段时间后,所有东 ...

  2. Git仓库储藏和清理

    贮藏(stash)会处理工作目录的脏的状态--即跟踪文件的修改与暂存的改动--然后将未完成的修改保存到一个栈上, 而你可以在任何时候重新应用这些改动(甚至在不同的分支上).或在清理(clean)文件. ...

  3. Git笔记(32) 高级合并

    Git笔记(32) 高级合并 1. 合并冲突 1.1. 中断一次合并 1.2. 忽略空白 1.3. 手动文件再合并 1.4. 检出冲突 1.5. 合并日志 1.6. 组合式差异格式 2. 撤消合并 2 ...

  4. Git笔记(31) 重置揭密

    Git笔记(31) 重置揭密 1. 三棵树 1.1. HEAD 1.2. 索引 1.3. 工作目录 2. 工作流程 3. 重置 3.1. 移动 HEAD(--soft) 3.2. 更新索引(--mix ...

  5. Git笔记(29) 搜索

    Git笔记(29) 搜索 1. 浏览代码和提交 2. Git Grep 3. Git 日志搜索 4. 行日志搜索 1. 浏览代码和提交 无论仓库里的代码量有多少 经常需要查找一个函数是在哪里调用或者定 ...

  6. Git笔记(28) 签署工作

    Git笔记(28) 签署工作 1. 签署工作 2. GPG 介绍 3. 签署标签 4. 验证标签 5. 签署提交 6. 使用环境 1. 签署工作 Git 虽然是密码级安全的,但它不是万无一失的 如果从 ...

  7. Git笔记(16) 变基

    Git笔记(16) 变基 1. 整合分支 2. 基本操作 3. 指定目标分支 4. 变基的风险 5. 用变基解决变基 6. 手动解决变基 7. 整合原则 1. 整合分支 在 Git笔记(12) 分支使 ...

  8. Git笔记(ydl)

    Git笔记(ydl) 第一章 理论基础 一 .Git安装 windows安装:进入网站https://git-scm.com/下载安装,然后在cmd命令行配置 直接去腾讯软件中心下载也可以! > ...

  9. Intel VT学习笔记(九)—— EPT应用示例

    Intel VT学习笔记(九)-- EPT应用示例 内存保护 EPT violation 代码实现 参考资料 内存保护 描述:尝试使用EPT将一块特定的物理内存保护起来. 先来选择一块物理地址,那么这 ...

  10. Windows进程与线程学习笔记(九)—— 线程优先级/进程挂靠/跨进程读写

    Windows进程与线程学习笔记(九)-- 线程优先级/进程挂靠/跨进程读写 要点回顾 线程优先级 调度链表 分析 KiFindReadyThread 分析 KiSwapThread 总结 进程挂靠 ...

最新文章

  1. 远程服务器如何传文件大小,linux服务器远程传文件大小
  2. spark on k8s报错:pods “spark-pi-4f2cd9772397764d-driver“ is forbidden: User “system:anonymous“
  3. url(r'^index/$',views.index)的含义解释
  4. 性能测试十四:Xshell链接linux虚拟机
  5. 描述符演练-02-逻辑疏理-类的装饰器
  6. 在MacBook上Jupyter安装
  7. 深度学习backbone是什么意思_一场突如其来的讨论:到底什么是深度学习?SVM其实也是深度学习吗?...
  8. 【BZOJ3884】上帝与集合的正确用法
  9. X server:linux 图形界面原理
  10. L1-028. 判断素数-PAT团体程序设计天梯赛GPLT
  11. 时间和日期的JS库Day.js入门教程
  12. 前端Unicode字符图标汇总
  13. SVN客户端和中文包的安装
  14. mac下webstorm 汉化解决方案
  15. 联想从国有企业演变成民营集团揭秘(深度)
  16. java模拟刷百度排名无效_刷百度排名软件教程-软件设置问题
  17. 直线绘制算法-中点画线法
  18. VT是什么?怎么打开教程
  19. linux 创建gpt分区,parted创建GPT分区
  20. css第八课:文本属性(字体,颜色属性)

热门文章

  1. 《菜根谭》 明·洪应明
  2. 使用Fiddler快速保存微信视频号上的视频
  3. Android锁机病毒分析
  4. 罗振宇2021跨年演讲5:为什么你要建成自己的“黄鹤楼”?
  5. 搜狐全体员工遭遇工资补助诈骗,CEO张朝阳回应:没那么严重
  6. Activiti会签
  7. python爬虫12306查票
  8. 寡人的难题 (数据结构作业)
  9. 直接耦合共射放大电路带载与不带载的电路参数分析
  10. createjs之easeljs【游戏看你有多色(一)】