10 个节省时间和改善工作流的 Git 技巧
根据 手册 ,Git 被定义为傻瓜式内容追踪器,它功能丰富,但有些功能却让人望而生畏。因此,我们只是重复使用那几个被记住的命令,而没有充分使用。
技巧 1: 优化配置
Git 在全局、用户和本地级别上都是高度可配置的。
https://git-scm.com/docs/git-config
查找顺序
每个设置都可以被覆盖:
复制代码
$CWD/.git/config ▼ ▼ ▼ $HOME/.gitconfig` ▼ ▼ ▼ $HOME/.config/git/config ▼ ▼ ▼ /etc/gitconfig
修改设置
用你喜欢的编辑器或者 CLI 编辑任何配置文件:
复制代码
# 全局设置 gitconfig--global # 本地设置 gitconfig
如果值包含空格字符,则需要用引号引起来。
显示当前设置
复制代码
# 显示当前设置及其来源 gitconfig--list --show-origin
一些有用的配置
复制代码
# 设定身份 gitconfig--global user.name"" gitconfig--global user.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."" # 使用别名 git
一些有用的别名
复制代码
# 撤销上次提交 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)%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='' # 通过 commit 信息查找 (包含 reflog) gitlog-g --grep=''
通过更改查找
复制代码
# 通过更新的内容查找 gitlog-S ''
通过日期查找
复制代码
# 通过日期范围查找 gitlog--after='DEC 152019' --until='JAN 102020'
技巧 4:添加 hunk
git add
不仅能添加文件的所有变更, --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"" # 交互式储藏 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 stash@{n} # 从 STASH 应用单个文件 (n = stash 列表序号) git checkout stash@{n} --
清理
复制代码
# 删除特定的 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 git diff--cached gitmerge--abort
请注意, git commit -n
根本不是 *dry-run!* 它实际上是 --no-verify
,作用是忽略所有 pre-commit
/ commit-msg
githooks 。
技巧 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""
https://git-scm.com/docs/git-commit#Documentation/git-commit.txt—amend
技巧 9:修改历史
修改代码仓库的历史不仅限于修改上次提交信息,使用 git rebase
可以修改多个提交:
复制代码
# 提交的范围 git rebase -i/--interactive HEAD~ # 该 hash 之后的所有提交 git rebase -i/--interactive
在配置的编辑器中倒序列出所有的 commit,像这样:
复制代码
# 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 --output
可以是一个分支、commit hash 或者一个标签。
额外提醒:单破折号
有一个快捷方式可以表示刚用过的分支:一个单破折号 -
复制代码
git checkout my-branch # 当前分支:my-branch git checkout develop # 当前分支:develop git merge - # 将 my-branch 合并到 develop
单破折号等同于 @{-1}
。
https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt-ltbranchgt
总结
Git 还有很多话题可谈,这里只涉及一些皮毛。在另一篇文章中,我想展示如何用 git bisect
有效查找损坏的 commit,或者如何通过 git reflog
来运用任意 git
操作的完整历史记录。