Git 更安全的強制推送,--force-with-lease


 

由於 git rebase 命令的存在,強制將提交推送到遠端倉庫似乎也有些必要。不過都知道 git push --force 是不安全的,這讓 git rebase 命令顯得有些雞肋。

本文將推薦 --force-with-lease 參數,讓我們可以更安全地進行強制推送。


--force-with-lease 參數自 Git 的 1.8.5 版本開始提供,只在解決 git push --force 命令造成的安全問題。

那么 git push --force 命令有什么安全問題?

--force 會使用本地分支的提交覆蓋遠端推送分支的提交。也就是說,如果其他人在相同的分支推送了新的提交,你的這一舉動將“刪除”他的那些提交!就算在強制推送之前先 fetch 並且 mergerebase 了也是不安全的,因為這些操作到推送之間依然存在時間差,別人的提交可能發生在這個時間差之內。

--force-with-lease 將解決這種安全問題

使用了 --force-with-lease 參數之后,上面那種安全問題就沒有那么危險了。

使用此參數推送,如果遠端有其他人推送了新的提交,那么推送將被拒絕,這種拒絕和沒有加 --force 參數時的拒絕是一樣的。

walterlv$ git push --force-with-lease
To https://github.com/walterlv/walterlv.github.io.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/walterlv/walterlv.github.io.git'

請特別注意——如果你 fetch 之后在本地的 origin 相關分支上已經看到了別人的提交,依然進行強制推送,你還是會覆蓋別人的提交。也就是說,--force-with-lease 解決的是本地倉庫不夠新時,依然覆蓋了遠端新倉庫的問題,如果你執意想要覆蓋遠端提交,只需要先 fetch 再推送,它也不會拒絕的

在使用 git push --force-with-lease 命令被拒絕時,你需要 fetch 倉庫,然后確認其他人是否對此分支有新的修改,如果沒有,你才可以繼續強制推送。

walterlv$ git fetch
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 46 (delta 21), reused 40 (delta 15), pack-reused 0
Unpacking objects: 100% (46/46), done.
From https://github.com/walterlv/walterlv.github.io
   e75edf0..217a49d  master     -> origin/master

fetch 完畢之后,請一定檢查此分支是否已經被其他人修改,如果有新的提交,你應該進行一次 merge 或者 rebase

walterlv$ git rebase
First, rewinding head to replay your work on top of it...
Applying: Add post "safe push using force with lease".

此后,再次進行推送或強制推送即可。

walterlv$ git push --force-with-lease
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 363 bytes | 363.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/walterlv/walterlv.github.io.git
   219a6d5..dff94a5  master -> master

額外的問題:為什么推送到遠端的提交還依然要用 rebase?

Git 官方文檔對 rebase 有如下描述:

Git 官方對 rebase 的描述
▲ 如果你想吐槽那段中文翻譯,我只想說——那是 Git 的官方中文文檔

既然已經推送的提交不應該再進行 rebase,那本不應該會遇到本文提到的問題。但是——GitHub 的工作流或者 GitLab 的工作流中,都有一種行為是 rebase 自己的分支到 origin/master 上,以保證 master 分支上的提交是純粹的干凈的。也就是說,本意是禁止對合並到 masterdevelop 分支上的提交進行 rebase;但對於自己的 temp 分支或者 feature 分支,因為提交還沒有合並到主干中,隨時刪除掉或者將歷史進行美化也不會造成太大的問題。

GitLab 那種要求進行 rebase 的設置
▲ 這是 GitLab 上的設置,可以要求提交者必須進行 rebase 才允許合並

參考資料

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM