Categories
程式開發

10個節省時間和改善工作流的Git技巧


10個節省時間和改善工作流的Git技巧 1

根據手冊,Git被定義為傻瓜式內容追踪器,它功能豐富,但有些功能卻讓人望而生畏。因此,我們只是重複使用那幾個被記住的命令,而沒有充分使用。

技巧1: 優化配置

Git在全局、用戶和本地級別上都是高度可配置的。

https://git-scm.com/docs/git-config

查找順序

每個設置都可以被覆蓋:

$CWD/.git/config
    ▼ ▼ ▼
$HOME/.gitconfig`
    ▼ ▼ ▼
$HOME/.config/git/config
    ▼ ▼ ▼
/etc/gitconfig

修改設置

用你喜歡的編輯器或者CLI編輯任何配置文件:

# 全局设置
git config --global  
# 本地设置
git config  

如果值包含空格字符,則需要用引號引起來。

顯示當前設置

# 显示当前设置及其来源
git config --list --show-origin

一些有用的配置

# 设定身份
git config --global user.name ""
git config --global user.email 
# 首选编辑器
git config --global core.editor vim
# 证书缓存
# WINDOWS
git config --global credential.helper manager
# LINUX (超时时间——以秒为单位)
git config --global credential.helper "cache --timeout=3600"
# MACOS
git config --global credential.helper osxkeychain

https://git-scm.com/docs/gitcredentials

技巧2:別名(alias)

創建一個別名來保存常用的git命令:

# 创建别名
git config --global alias. ""
# 使用别名
git  

一些有用的別名

# 撤销上次提交
git config --global alias.undo "reset --soft HEAD^"
# 将暂存区更新修订到上次提交(不改变提交信息)
git config --global alias.amend "commit --amend --no-edit"
# 压缩的状态输出
git config --global alias.st "status -sb"
# 用GRAPH为日志着色
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)%Creset'"
# 删除所有已合并的分支
git config --global alias.rmb "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d"
# 贡献排行
git config --global alias.rank "shortlog -n -s --no-merges"

技巧3:查找Commits和更改

通過Commits信息查找

# 通过commit信息查找(所有分支)
git log --all --grep=''
# 通过commit信息查找(包含reflog)
git log -g --grep=''

通過更改查找

# 通过更新的内容查找
git log -S ''

通過日期查找

# 通过日期范围查找
git log --after='DEC 15 2019' --until='JAN 10 2020'

技巧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 stash list

瀏覽

# 浏览STASH内容
git stash show
# 浏览STASH差异
git stash show -p

應用

# 应用上一个STASH (删除stash)
git stash pop
# 应用上一个STASH (保留stash)
git stash apply
# 应用特定的STASH (n = stash列表序号)
git stash pop/apply [email protected]{n}
# 从STASH创建新的分支 (n = stash列表序号)
git stash branch  [email protected]{n}
# 从STASH应用单个文件 (n = stash列表序号)
git checkout [email protected]{n} -- 

清理

# 删除特定的STASH (n = stash列表序号)
git stash drop [email protected]{n}
# 删除所有的STASH
git stash clear

技巧6:空運行(Dry Run)

許多git操作可能具有破壞性,例如,git clean -f將刪除所有未跟踪的文件,而且無法恢復。

要避免出現這種災難性的結果,許多命令都支持dry-run,可以在實際產生結果前對其進行檢查。不過遺憾的是,使用的選項不完全一致:

git clean -n/--dry-run
git add -n/--dry-run
git rm -n/--dry-run
# GIT MERGE模拟DRY-RUN
git merge --no-commit --no-ff 
git diff --cached
git merge --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中使用它。

git commit --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,像這樣:

#   
pick 5df8fbc 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:存檔跟踪文件

可以使用不同格式(ziptar)來壓縮特定引用的跟踪文件:

git archive --format  --output  

可以是一個分支、commit hash或者一個標籤。
https://git-scm.com/docs/git-archive

額外提醒:單破折號

有一個快捷方式可以表示剛用過的分支:一個單破折號-

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操作的完整歷史記錄。

閱讀英文:

10 Git Tips To Save Time And Improve Your Workflow