分享

25个 Git 进阶技巧

 gljin_cn 2015-05-13

日志以及有哪些改动?

13. 查看日志

长时间使用 Git 的话,不会没用过‘git log’来查看最近的提交。不过,有一些技巧来更好地应用。比如,你可以使用下面的命令来查看每次提交的具体改动:

  1. $ git log -p

或者你可以仅仅查看有哪些文件改动:

  1. $ git log --stat

有个很不错的别名你可以试试,会显示简短提交名和一个不错的分支图并在一行里显示提交信息(有点像gitk,但是是在命令行下):

  1. $ git config --global alias.lol "log --pretty=oneline --abbrev-commit --graph --decorate"
  2. $ git lol
  3. * 4d2409a (master) Oops, meant that to be in Korean
  4. * 169b845 Hello world

14. 搜索日志

如果你想找特定提交者可以这样做:

  1. $ git log --author=Andy

更新:感谢Johannes的评论,我已经去掉了之前这里的一些有混淆的地方。

或者你想在提交信息里找一些相关字段:

  1. $ git log --grep="Something in the message"

也有一个更强大的叫做pickaxe的命令用来查找包含了删除或添加的某个特定内容的提交(比如,该内容第一次出现或被删除)。这可以告诉你什么时候增加了一行(但这一行里的某个字符后面被改动过就不行了):

  1. $ git log -S "TODO: Check for admin status"

假如你改动了一个特定的文件,比如lib/foo.rb

  1. $ git log lib/foo.rb

比如说你有一个feature/132分支和feature/145分支,然后你想看看这两个分支上不在master分支里的提交(注意符号是不在的意思):

  1. $ git log feature/132 feature/145 ^master

你也可以使用ActiveSupport格式的日期来缩小到某个日期范围:

  1. $ git log --since=2.months.ago --until=1.day.ago

默认情况下会用OR来组合查询,但你可以轻易地改为AND(如果你有超过一条的查询标准)

  1. $ git log --since=2.months.ago --until=1.day.ago --author=andy -S "something" --all-match

15. 查看/修改版本

有很多方式可以用来引用一个版本,看你记得哪个:

  1. $ git show 12a86bc38 # 根据版本
  2. $ git show v1.0.1 # 根据标签
  3. $ git show feature132 # 根据分支名
  4. $ git show 12a86bc38^ # 一次提交的父节点
  5. $ git show 12a86bc38~2 # 一次提交的祖父节点
  6. $ git show feature132@{yesterday} # 时间相关
  7. $ git show feature132@{2.hours.ago} # 时间相关

注意和之前部分有些不同,末尾的的意思是该提交的父节点 - 开始位置的的意思是不在这个分支。

16. 选择范围

最简单的方式:

  1. $ git log origin/master..new
  2. # [old]..[new] - 所有你还没有推送的提交

你也可以省略[new],将使用当前的HEAD。

时光回溯和后悔药

17. 重置改动

如果你还没有提交的话可以用下面的命令轻松地取消改动:

  1. $ git reset HEAD lib/foo.rb

通常会使用‘unstage’的别名,因为上面的看上去有些不直观。

  1. $ git config --global alias.unstage "reset HEAD"
  2. $ git unstage lib/foo.rb

如果你已经提交了该文件,你可以做两件事 - 如果是最后一次提交你还可以改正:

  1. $ git commit --amend

这会取消最后一次提交,把工作分支回退到提交前标记了所有改动的状态,而且提交信息也都准备好可以修改或直接提交。

如果你已经提交过多次而且希望全部回退,你可以将分支重置到合适的位置。

  1. $ git checkout feature132
  2. $ git reset --hard HEAD~2

如果你实际上希望将分支指向一个完全不同的SHA1(也许你要将一个分支的HEAD替换到另一个分支,或者之后的某次提交)你可以使用下面的较长的方式:

  1. $ git checkout FOO
  2. $ git reset --hard SHA

实际上有一个快速的方式(不需要先把你的工作分支切换到FOO再前进到SHA):

  1. $ git update-ref refs/heads/FOO SHA

18. 提交到了错误的分支

好吧,假如说你已经提交到了master,但却应该创建一个叫experimental的主题分支更合适。要移动这些改动,你可以在当前位置创建分支,回退HEAD再检出新分支:

  1. $ git branch experimental # 创建一个指向当前master的位置的指针
  2. $ git reset --hard master~3 # 移动master分支的指针到3个版本之前
  3. $ git checkout experimental

如果你的改动是在分支的分支的分支上会更复杂。那样你需要做的是将分支基础切换到其他地方:

  1. $ git branch newtopic STARTPOINT
  2. $ git rebase oldtopic --onto newtopic

19. 交互式切换基础

这是一个我之前看过展示却没真正理解过的很赞的功能,现在觉得它就很简单了。假如说你提交了3次但是你希望更改顺序或编辑(或者合并):

  1. $ git rebase -i master~3

然后这会启动你的编辑器并带有一些指令。你所要做的就是修改这些指令来选择/插入/编辑(或者删除)提交和保存/退出。然后在编辑完后你可以用git rebase --continue命令来让每一条指令生效。

如果你有修改,将会切换到你提交时所处的状态,之后你需要使用命令git commit --amend来编辑。

注意:在rebase的时候千万不要提交 - 只能先添加然后使用参数--continue,--skip或--abort。

20. 清理

如果你提交了一些内容到你的分支(也许你从SVN导入了一些旧仓库),然后你希望把某个文件从历史记录中全部删掉:

  1. $ git filter-branch --tree-filter 'rm -f *.class' HEAD

如果你已经推送到origin了,但之后提交了一些垃圾改动,你也可以在推送前在本地系统里这样做:

  1. $ git filter-branch --tree-filter 'rm -f *.class' origin/master..HEAD

其他技巧

21. 你查看过的前一个引用

如果你知道自己之前查看过一个SHA-1,但是随后做了一些重置/回退的操作,你可以使用reflog命令来列出最近查看过的SHA-1记录:

  1. $ git reflog
  2. $ git log -g # 和上面一样,但是使用'log'格式输出

22. 分支命名

一个可爱的小技巧 - 别忘了分支名并不限于a-z和0-9。名字中可以用/和.将非常方便用来建立伪命名空间或版本,例如:

  1. $ # 生成版本132的改动历史
  2. $ git shortlog release/132 ^release/131
  3. $ # 贴上v1.0.1的标签
  4. $ git tag v1.0.1 release/132

23. 找出谁是凶手

通常找出来谁改动了某个文件里的某行代码会很有用。实现这个功能的最简单命令是:

  1. $ git blame FILE

有时候这些改动来自其他文件(如果你合并了两个文件,或者你移动了某个函数)所以你可以使用下面的命令:

  1. $ # 显示内容来自哪个文件
  2. $ git blame -C FILE

有时候通过点击各个改动然后回到很早很早以前来跟踪改动会很不错。有一个很好的内建GUI命令来做这个:

  1. $ git gui blame FILE

24. 数据维护

通常git不需要经常维护,它把自己照顾的很好。不过,你可以通过下面的命令查看数据统计:

  1. $ git count-objects -v

如果占用很多空间的话,你可以选择在你的本地仓库做垃圾回收。这不会影响推送或其他人,却会让一些命令运行更快而且减少空间占用:

  1. $ git gc

经常运行完整性检查也很有意义:

  1. $ git fsck --full

你也可以在末尾加上--auto参数(如果你在服务器上通过crontab经常/每天都运行这个命令的话),然后它只会在必要的时候才执行fsck动作。

在检查的时候,看到“dangling”或“unreachable”是正常的,通常这是由回退HEAD或切换基础的结果。而看到“missing”或“sha1 mismatch”就不对了...找专业人士帮忙吧!

25. 恢复遗失的分支

如果你使用-D参数删除了experimental分支,可以用下面的命令重新建立:

  1. $ git branch experimental SHA1_OF_HASH

如果你最近访问过的话,你通常可以用git reflog来找到SHA1哈希值。

另一种方式是使用git fsck —lost-found。其中一个dangling的提交就是丢失的HEAD(它只是已删除分支的HEAD,而HEAD被引用为当前的HEAD所以它并不处于dangling状态)

搞定!

哇,这是我写过的最长的一篇博客,我希望有人能觉得有用。如果你这么觉得,或者你有任何疑问请在评论里留言让我知道...

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多