5

Git: 好用到爆命令和配置

 2 years ago
source link: https://ppzz.github.io/posts/beaa/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Git: 好用到爆命令和配置

发表于 2017-10-17 分类于 Git Valine: 0 本文字数: 4.4k 阅读时长 ≈ 4 分钟

让 Git 的更好用的配置和命令。

git 的配置文件通常是 home 目录下的 .gitignore

可以追加以下内容:

[color]
ui = true # 启用git输出的颜色控制功能
[alias]
st = status
co = checkout
ci = commit
br = branch
di = diff
cane = commit --amend --no-edit # 将staged的改动与上次的commit合并(使用上次的提交信息)
unstage = reset HEAD
last = log -1
lg = log --color --graph --pretty=format:'%C(red)%h%C(reset)%C(green)(%cr)%C(reset) %s %C(yellow)%d%C(reset) %C(bold blue)%an%Creset' --abbrev-commit
  • 可实现 git st == git status 这样的效果。
  • 上图中 git lg 可以实现图形化展示 git 提交过程。
git push <remote> <tag>
git push --tag
git tag -a 1.0.1 -m ‘fixed bug’ #添加一个tag

git tag -a 2.0.0 -m ‘msg’ COMMITID #指定commit号的tag

git tag v0.1.2 #轻量级的tag

checkout:从远端切分支出来

git co -b local_name origin/romote_name

delete 远端分支、tag

git push origin --delete <branchName>
git push origin --delete tag <tagname>

rebase:压缩几个 commit 到一个 commit

# 从 commmit1 之后到 head 压缩到一起
git rebase -i commit1
git rebase --continue
git rebase --edit-todo
git rebase --abort

压缩 commit 时:
在执行的 rebase 的编辑处,
应该把不要的 commit 的记录,从 pick 改成 squash
然后,squash 的 commit 就会被压缩到它前一个 commit 上 (形成一个新的 commitID)

修正 Github Contributions 中的统计数据

检查 git log 中的用户名 & 密码是否正确,通常统计数据不正确是因为账户中的邮箱,跟提交代码的邮箱不一致导致。
修复统计数据的过程实际上就是修改历史提交中邮箱的过程

修复已经提交的 commit:

  • 先克隆一个新的仓库

git clone --bare https://github.com/user/repo.git

  • 再在仓库中执行下面的脚本
#!/bin/sh
git filter-branch --env-filter '
OLD_EMAIL="旧的Email地址"
CORRECT_NAME="正确的用户名"
CORRECT_EMAIL="正确的邮件地址"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
  • 重新推送代码

git push --force --tags origin 'refs/heads/*'

git diff 输出详解

这里的内容以软件 diff 为例,内容是以前在笔记中写的。git diff 与之类似,就不再重写了。

假设有 test1.md, test2.md 两个文本文件.

test1.md

1
2
3
4
this is line 5 of test1
6
7
8
9
10
11
12
this is line 13 of test1
14
15
16
17

test2.md

1
2
3
4
this is line 5 of test2
6
7
8
9
10
11
12
this is line 13 of test2
14
15
16
17

两个文件只有第 5 和 13 行是不一样的.
我们在终端中执行以下代码即可将两个文件的比较结果写入新的 diff.md 中:

diff -u test1.md test2.md > diff.md

解释:
-u 是 diff 的参数,表示输出结果时同时输出上下文.
test1.md test2.md 接下来是参与比较的两个文件
> diff.md 表示将结果输出到 diff.md 这个文件中 (默认是输出到控制台)
以上生成的 diff.md 文件内容是:

--- test1.md    2015-09-04 19:23:06.708723075 +0800
+++ test2.md 2015-09-04 19:23:36.500721968 +0800
@@ -2,7 +2,7 @@
2
3
4
-this is line 5 of test1
+this is line 5 of test2
6
7
8
@@ -10,7 +10,7 @@
10
11
12
-this is line 13 of test1
+this is line 13 of test2
14
15
16

下面是对上面每行的解释:

  • 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 文件删除,然后执行以下命令:

patch test2.md < diff.md

然后会根据 test1.mddiff.md 生成 test2.md .

当需要利用 test2.mddiff.md 生成 test1.md 时,可以执行:

patch-R test1.md < diff.md

这样可以反向生成 test1.md

最后,diff 和 patch 还可以用来对目录进行比较,但是他们存在局限性:不能对二进制文件进行比较,Git 中对 对 diff 进行了扩展,支持二进制文件的版本控制和差异比较.

git hooks

client hook

  • 提交相关
    1. pre-commit: 测试代码,style lint,检查 doc,检查文档结果的空白字符是否存在;以非 0 值 exit 出时将放弃提交
    2. prepare-commit-msg: 默认提交信息创建之后,在启动提交信息编辑器运行之前运行;可以看到本次提交的快照信息;可以编辑提交信息模版,合并提交
    3. commit-msg: 接受一个参数:文件路径,存有当前的提交信息,以非 0 值 exit 出时将放弃提交
    4. post-commit: 一般用于通知,可以使用 git log -1 HEAD 获得最后一次提交的信息
  • 电子邮件相关
    1. applypatch-msg: 接收但个参数,包含请求合并信息的临时文件的名字;如果脚本返回非零值,Git 将放弃该补丁;可以用该脚本来确保提交信息符合格式,或直接用脚本修正格式错误。
    2. pre-applypatch: 运行于应用补丁 之后,产生提交之前,所以你可以用它在提交前检查快照。
    3. 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 追踪系统,

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK