根据 手册 ,Git 被定义为傻瓜式内容追踪器, 它功能丰富, 但有些功能却让人望而生畏. 因此, 我们只是重复使用那几个被记住的命令, 而没有充分使用.
技巧 1: 优化配置
Git 在全局, 用户和本地级别上都是高度可配置的.
https://git-scm.com/docs/git-config
查找顺序
每个设置都可以被覆盖:
$CWD/.Git/config
▼ ▼ ▼
$HOME/.gitconfig`
▼ ▼ ▼
$HOME/.config/Git/config
▼ ▼ ▼
/etc/gitconfig
修改设置
用你喜欢的编辑器或者 CLI 编辑任何配置文件:
- # 全局设置
- gitconfig--global <keypath> <value>
- # 本地设置
- gitconfig<keypath> <value>
如果值包含空格字符, 则需要用引号引起来.
显示当前设置
- # 显示当前设置及其来源
- gitconfig--list --show-origin
一些有用的配置
- # 设定身份
- gitconfig--global user.name"<your name>"
- gitconfig--global user.email <your email>
- # 首选编辑器
- gitconfig--global core.editor VIM
- # 证书缓存
- # Windows
- gitconfig--global credential.helper manager
- # Linux (超时时间 -- 以秒为单位)
- gitconfig--global credential.helper"cache --timeout=3600"
- # MACOS
- gitconfig--global credential.helper osxkeychain
- https://git-scm.com/docs/gitcredentials
技巧 2: 别名(alias)
创建一个别名来保存常用的 Git 命令:
- # 创建别名
- gitconfig--global alias.<alias-name>"<git command>"
- # 使用别名
- Git <alias-name> <more optional arguments>
一些有用的别名
- # 撤销上次提交
- gitconfig--global alias.undo"reset --soft HEAD^"
- # 将暂存区更新修订到上次提交 (不改变提交信息)
- gitconfig--global alias.amend"commit --amend --no-edit"
- # 压缩的状态输出
- gitconfig--global alias.st"status -sb"
- # 用 GRAPH 为日志着色
- gitconfig--global alias.lg"log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'"
- # 删除所有已合并的分支
- gitconfig--global alias.rmb"!git branch --merged | grep -v'*'| xargs -n 1 git branch -d"
- # 贡献排行
- gitconfig--global alias.rank"shortlog -n -s --no-merges"
技巧 3: 查找 Commits 和更改
通过 Commits 信息查找
- # 通过 commit 信息查找 (所有分支)
- gitlog--all --grep='<search term>'
- # 通过 commit 信息查找 (包含 reflog)
- gitlog-g --grep='<search term>'
通过更改查找
- # 通过更新的内容查找
- gitlog-S '<search term>'
通过日期查找
- # 通过日期范围查找
- gitlog--after='DEC 152019' --until='JAN 102020'
技巧 4: 添加 hunk
Git add <filepath> 不仅能添加文件的所有变更, --path / -p 参数还可以交互式暂存区块.
# 补丁命令
y = 暂存区块
n = 不暂存这个区块
q = 退出
a = 暂存当前文件的此区块以及所有剩余区块
d = 不暂存当前文件的此区块以及所有剩余区块
/ = 查找区块 (正则表达式)
s = 划分成更小的区块
e = 手动编辑区块
? = 打印帮助说明
g = 选择要前往的区块
j = 将区块设为未定, 查看下一个未定区块
J = 将区块设为未定, 查看下一个区块
k = 将区块设为未定, 查看上一个未定区块
J = 将区块设为未定, 查看下一个区块
https://git-scm.com/docs/git-add#Documentation/git-add.txt-i
技巧 5: 储藏 (stash) 更改而不提交
stash 将当前的更改临时搁置起来. 在它的帮助下, 可以返回当前状态的索引, 并能在稍后应用已储藏的更改.
默认情况下, 仅储藏当前跟踪文件中的更改, 新文件将被忽略.
我们可以独立地创建和应用多个 stash.
https://git-scm.com/docs/git-stash
创建
- # 创建新的 STASH
- Git stash
- # 创建新的 STASH (包含未追踪的更改)
- Git stash -u/--include-untracked
- # 创建新的 STASH 并命名
- Git stash save"<stash name>"
- # 交互式储藏
- Git stash -p
罗列
- # 列出所有的 STASH (为其他命令提供 "n")
- Git stashlist
浏览
- # 浏览 STASH 内容
- Git stashshow
- # 浏览 STASH 差异
- Git stashshow-p
应用
- # 应用上一个 STASH (删除 stash)
- Git stash pop
- # 应用上一个 STASH (保留 stash)
- Git stash apply
- # 应用特定的 STASH (n = stash 列表序号)
- Git stash pop/apply stash@{
- n
- }
- # 从 STASH 创建新的分支 (n = stash 列表序号)
- Git stash branch <newbranch name> stash@{
- n
- }
- # 从 STASH 应用单个文件 (n = stash 列表序号)
- Git checkout stash@{
- n
- } -- <filepath>
清理
- # 删除特定的 STASH (n = stash 列表序号)
- gitstash drop stash@{
- n
- }
- # 删除所有的 STASH
- gitstash clear
技巧 6: 空运行(Dry Run)
许多 Git 操作可能具有破坏性, 例如, Git clean -f 将删除所有未跟踪的文件, 而且无法恢复.
要避免出现这种灾难性的结果, 许多命令都支持 dry-run , 可以在实际产生结果前对其进行检查. 不过遗憾的是, 使用的选项不完全一致:
- Git clean -n/--dry-run
- gitadd-n/--dry-run
- Git rm -n/--dry-run
- # Git MERGE 模拟 DRY-RUN
- gitmerge--no-commit --no-ff <branch>
- Git diff--cached
- gitmerge--abort
请注意, Git commit -n 根本不是 *dry-run!* 它实际上是 --no-verify , 作用是忽略所有 pre-commit / commit-msg http://schacon.github.io/git/githooks.html .
技巧 7: 安全强制推送
在处理旧的 commit, 创建新的 head 等情况时时很容易弄乱分支. Git push --force 可以覆盖远程变更, 但不应该这样做!
Git push --force 是一种具有破坏性且危险的操作, 因为它无条件生效, 并且会破坏其他提交者已经推送的所有 commit. 这对于其他人的代码仓库来说不一定是致命的, 但是改变历史记录并影响其他人并不是一个好主意.
更好的选择是使用 Git push --force-with-lease .
Git 不会无条件地覆盖上游的远程仓库, 而是检查是否有本地不可用的远程更改. 如果有, 它会失败并显示一条 "stale info" 消息, 并告诉我们需要先运行 Git fetch .
https://git-scm.com/docs/git-push#Documentation/git-push.txt-force-with-leaseltrefnamegt
技巧 8: 修改 commit 信息
Commit 是不可变的, 且不能更改. 不过可以用一条新的 commit 信息修订现有的 commit, 这会覆盖原始 commit, 因此请勿在已推送的 commit 中使用它.
- gitcommit--amend-m"<new commit message>"
- https://git-scm.com/docs/git-commit#Documentation/git-commit.txt-amend
技巧 9: 修改历史
修改代码仓库的历史不仅限于修改上次提交信息, 使用 Git rebase 可以修改多个提交:
- # 提交的范围
- Git rebase -i/--interactive HEAD~<number of commits>
- # 该 hash 之后的所有提交
- Git rebase -i/--interactive <commit hash>
在配置的编辑器中倒序列出所有的 commit, 像这样:
- #<command><commit hash><commit message>
- pick5df8fbc revamped logic
- pick ca5154e README typos fixed
- pick a104aff added awesome new feature
通过更改编辑器中的实际内容, 可以为 Git 提供一个方案, 来说明如何进行 rebase:
- # p, pick = 使用提交而不更改
- # r, reword = 修改提交信息
- # e, edit = 编辑提交
- # s, squash = 汇合提交
- # f, fixup = 类似 "squash", 但是会丢弃提交信息
- # x, exec = 运行命令 (其余行)
- # d, drop = 移除提交
保存编辑器后, Git 将运行该方案以重写历史记录.
e, edit 会暂停 rebase, 就可以编辑代码仓库的当前状态. 完成编辑后, 运行 Git rebase --continue .
如果过程中出现问题(例如合并冲突), 我们需要重新开始, 可以使用 Git rebase --abort .
https://git-scm.com/docs/git-rebase
技巧 10: 存档跟踪文件
可以使用不同格式 ( zip 或 tar ) 来压缩特定引用的跟踪文件:
- Git archive --format<format> --output<filename> <ref>
- <ref> 可以是一个分支, commit hash 或者一个标签.
- https://git-scm.com/docs/git-archive
额外提醒: 单破折号
有一个快捷方式可以表示刚用过的分支: 一个单破折号 -
- Git checkout my-branch
- # 当前分支: my-branch
- <dosome Git operations, e.g. adding/commiting>
- Git checkout develop
- # 当前分支: develop
- Git merge -
- # 将 my-branch 合并到 develop
单破折号等同于 @{-1} .
总结
Git 还有很多话题可谈, 这里只涉及一些皮毛. 在另一篇文章中, 我想展示如何用 Git bisect 有效查找损坏的 commit, 或者如何通过 Git reflog 来运用任意 Git 操作的完整历史记录.
阅读英文:
10 Git Tips To Save Time And Improve Your Workflow
来源: http://www.tuicool.com/articles/v63Mjeb