Git: 好用到爆命令和配置
让 Git 的更好用的配置和命令。
别名配置
git 的配置文件通常是 home 目录下的 .gitignore
可以追加以下内容:
1 | [color] |
- 可实现
git st == git status
这样的效果。 - 上图中
git lg
可以实现图形化展示 git 提交过程。
命令备忘
push
1 | git push <remote> <tag> |
tag
1 | git tag -a 1.0.1 -m ‘fixed bug’ #添加一个tag |
checkout:从远端切分支出来
1 | git co -b local_name origin/romote_name |
delete 远端分支、tag
1 | git push origin --delete <branchName> |
rebase:压缩几个 commit 到一个 commit
1 | # 从 commmit1 之后到 head 压缩到一起 |
压缩 commit 时:
在执行的 rebase 的编辑处,
应该把不要的 commit 的记录,从 pick 改成 squash
然后,squash 的 commit 就会被压缩到它前一个 commit 上 (形成一个新的 commitID)
修正 Github Contributions 中的统计数据
检查 git log
中的用户名 & 密码是否正确,通常统计数据不正确是因为账户中的邮箱,跟提交代码的邮箱不一致导致。
修复统计数据的过程实际上就是修改历史提交中邮箱的过程
修复已经提交的 commit:
- 先克隆一个新的仓库
git clone --bare https://github.com/user/repo.git
- 再在仓库中执行下面的脚本
1 |
|
- 重新推送代码
git push --force --tags origin 'refs/heads/*'
git diff 输出详解
这里的内容以软件 diff 为例,内容是以前在笔记中写的。git diff 与之类似,就不再重写了。
假设有 test1.md, test2.md 两个文本文件.
test1.md
1 | 1 |
test2.md
1 | 1 |
两个文件只有第 5 和 13 行是不一样的.
我们在终端中执行以下代码即可将两个文件的比较结果写入新的 diff.md 中:
1 | diff -u test1.md test2.md > diff.md |
解释:-u
是 diff 的参数,表示输出结果时同时输出上下文.test1.md
test2.md
接下来是参与比较的两个文件> diff.md
表示将结果输出到 diff.md 这个文件中 (默认是输出到控制台)
以上生成的 diff.md 文件内容是:
1 | --- test1.md 2015-09-04 19:23:06.708723075 +0800 |
下面是对上面每行的解释:
- 1-2 行:分别记录了
原始文件
和目标文件
的文件名和时间戳. - 3-11 行:以
@@
开头到下一个@@
开头行之前叫做一个差异小节 (表示一处不同). - 3 行,12 行:差异定位语句,此行以
@@
开头和结束.-2,7
表示本节包含了原始文件的内容是从第2
行开始的接下来7
行.+2,7
则表示目标文件. - 4-6 行,9-11 行:以空格开头表示本行的文本在两个文件中是相同的,在这里是作为上下文输出的.
- 7 行,16 行:以
-
开头表示本行是原始文件的内容. - 8 行,17 行:以
+
开头表示本行是原始文件的内容. - 在一个差异小节中,
-
和+
开头的行表示了文本的差异.
用 patch 来进行 diff 的反向操作
我们用 diff
生成了 diff.md
文件之后,可以用 patch
进行反向还原.
先将 test2.md
文件删除,然后执行以下命令:
1 | patch test2.md < diff.md |
然后会根据 test1.md
和 diff.md
生成 test2.md
.
当需要利用 test2.md
和 diff.md
生成 test1.md
时,可以执行:
1 | patch-R test1.md < diff.md |
这样可以反向生成 test1.md
最后,diff 和 patch 还可以用来对目录进行比较,但是他们存在局限性:不能对二进制文件进行比较,Git 中对 对 diff 进行了扩展,支持二进制文件的版本控制和差异比较.
git hooks
client hook
- 提交相关
- pre-commit: 测试代码,style lint,检查 doc,检查文档结果的空白字符是否存在;以非 0 值 exit 出时将放弃提交
- prepare-commit-msg: 默认提交信息创建之后,在启动提交信息编辑器运行之前运行;可以看到本次提交的快照信息;可以编辑提交信息模版,合并提交
- commit-msg: 接受一个参数:文件路径,存有当前的提交信息,以非 0 值 exit 出时将放弃提交
- post-commit: 一般用于通知,可以使用
git log -1 HEAD
获得最后一次提交的信息
- 电子邮件相关
- applypatch-msg: 接收但个参数,包含请求合并信息的临时文件的名字;如果脚本返回非零值,Git 将放弃该补丁;可以用该脚本来确保提交信息符合格式,或直接用脚本修正格式错误。
- pre-applypatch: 运行于应用补丁 之后,产生提交之前,所以你可以用它在提交前检查快照。
- post-applypatch: 运行于提交产生之后,可以用它把结果通知给一个小组或所拉取的补丁的作者。
- 其他
- pre-rebase: 可以使用这个钩子来禁止对已经推送的提交变基
- post-rewrite: 被那些会替换提交记录的命令调用 (git commit –amend 和 git rebase),有一个参数(触发重写的命令名),同时从标准输入中接受一系列重写的提交记录。 这个钩子的用途很大程度上跟 post-checkout 和 post-merge 差不多。
- post-checkout: 可以用于可以根据你的项目环境用它调整你的工作目录,放入大的二进制文件、自动生成文档或进行其他类似这样的操作
- post-merge: git merge 成功运行后被调用,可以用来验证某些在 Git 控制之外的文件是否存在,这样就能在工作区改变时,把这些文件复制进来
- pre-push: 接受远程分支的名字和位置作为参数,同时从标准输入中读取一系列待更新的引用。可以在推送开始之前,用它验证对引用的更新操作
- pre-auto-gc:
git gc –auto
运行前调用,可以用来设置一些提醒
server hook
这些钩子脚本在推送到服务器之前和之后运行。 推送到服务器前运行的钩子可以在任何时候以非零值退出,拒绝推送并给客户端返回错误消息,还可以依你所想设置足够复杂的推送策略。
- pre-receive: 可以用这个钩子阻止对引用进行非快进(non-fast-forward,git 仓库中已经有一部分代码,所以它不允许你直接把你的代码覆盖上去。)的更新,或者对该推送所修改的所有引用和文件进行访问控制。
- update: pre-receive 脚本十分类似,不同之处在于它会为每一个准备更新的分支各运行一次;推送者同时向多个分支推送内容,pre-receive 只运行一次,相比之下 update 则会为每一个被推送的分支各运行一次。接受三个参数:引用(分支)的名字, 推送前引用指向的 SHA-1 值,用户准备推送的 SHA-1 值。如果 update 脚本以非零值退出,只有相应的那一个引用会被拒绝;其余的依然会被更新。
- post-update
- post-receive: 在整个过程完结以后运行,可以用来更新其他服务或者用户。接受与 pre-receive 相同的标准输入数据。可以用来通知 CI,更新 Issue 追踪系统,