簡體   English   中英

默認推送 --force-with-lease

[英]push --force-with-lease by default

我剛剛了解了git push --force-with-lease 這真是太棒了。 但是,當然,我不經常使用武力,所以我擔心下次需要這個漂亮的功能時我可能會忘記它。

有沒有辦法配置 git 所以git push -f會自動使用--force-with-lease除非我故意用--no-force-with-lease覆蓋它?

(我無法想象沒有租約就想使用武力!)

目前沒有辦法將 git 配置為始終使用force-with-lease而不是force 因此,下一個最佳可用選項通常是創建一個用於此目的的別名。

編輯這在 2022 年 5 月仍然是正確的。但是git 2.30添加了一個額外的選項force-if-includes這使得force-with-lease更加安全; 如果您想了解其中的原因,請查看這個深入的答案

創建別名

要創建別名,可以使用git config --global alias.<alias-name> <command> ,在我們的例子中,我會建議類似的東西。

git config --global alias.pushfwl "push --force-with-lease"

這將在你的全局.gitconfig文件中創建一個條目(你通常可以在你的主目錄中找到它)。 在此之后,您可以使用git pushfwl強制使用租賃

弄臟你的手

或者,您可以決定自己實現此功能! 如果您不確定從哪里開始,您可能需要查看git 存儲庫中的文檔目錄 在這里您可以找到有關如何提交補丁編碼指南和信息。

您可以在官方社區頁面上找到所有這些鏈接以及更多信息。

我的解決方案是創建一個包裝腳本,並使用別名,以便我始終使用它來代替真正的git

每當我嘗試git push -f時,我都會看到以下內容:

⚡ git push -f
use this instead so you don't cause race conditions in the 
repo: git push --force-with-lease

該腳本的一些優點是:

  • 它訓練我習慣性地使用--force-with-lease ,所以當我弄錯時我不會被嘮叨
  • 如果出於某種原因,我們確實需要強制推送, git push --force將起作用。

如何實現它:

  1. 創建一個自定義腳本,它將通過任何參數傳遞給 git,除了-f
  2. 為該腳本命名,因此我們使用它而不是git

這些說明假設 Linux 或 Mac 運行 bash。 我沒有在 zsh 或 Windows 上嘗試過這個,但我認為它也可以在那里工作。

~/.bash_profile

alias git=~/.git_wrapper.sh

~./git_wrapper.sh

#!/bin/bash
for arg in "$@"; do
    if [ "$arg" = "push" ]; then
        ispush=1
    elif [ "$ispush" = 1 -a "$arg" = '-f' ]; then
        echo "use this instead so you don't cause race conflicts in the repo: git push --force-with-lease"
        exit 1
    fi
done

git "$@"

通過這些更改,重新啟動您的終端,當您嘗試強制推送時, git現在應該會變得很高興。

我擔心下次需要這個漂亮的功能時我可能會忘記它。

Git 2.13 (Q2 2017) 解釋了為什么沒有“保護”來防止這個推送選項被遺忘,因為即使你沒有git push級別忘記它,它仍然可能被忽略。

請參閱Ævar Arnfjörð Bjarmason ( avar )提交 f17d642 (2017 年 4 月 19 日)。
(由Junio C Hamano -- gitster --提交 46bdfa3中合並,2017 年 4 月 26 日)

push : 使用多個遙控器記錄和測試--force-with-lease

記錄和測試有兩個遙控器指向同一個 URL 的情況,后台獲取和后續git push --force-with-lease不應破壞我們尚未獲取的未更新引用。

像 Microsoft 的 VSC 等一些編輯器具有在后台自動獲取的功能,這繞過了--force-with-lease--force-with-lease=<refname>提供的保護,如在此處添加的文檔中所述.

所以git push的文檔現在包括:

關於安全性的一般注意事項:提供此選項時沒有預期值,即--force-with-lease--force-with-lease=<refname>與在要推送的遠程上隱式運行git fetch的任何內容交互非常糟糕在后台,例如git fetch origin在您的存儲庫中的 cronjob 中。

它提供的保護--force是確保您的工作不是基於的后續更改不會被破壞,但是如果某些后台進程正在后台更新 refs,這將被輕易擊敗。 除了遠程跟蹤信息之外,我們沒有任何其他信息可以作為您希望看到並願意破壞的裁判的啟發式。

如果您的編輯器或其他系統正在后台運行git fetch ,那么緩解這種情況的一種方法是簡單地設置另一個遠程:

git remote add origin-push $(git config remote.origin.url)
git fetch origin-push

現在,當后台進程運行git fetch origin時, origin-push上的引用不會被更新,因此命令如下:

git push --force-with-lease origin-push

除非您手動運行git fetch origin-push否則將失敗。
這個方法當然完全被運行git fetch --all的東西打敗了,在這種情況下,你需要禁用它或者做一些更乏味的事情,比如:

 git fetch # update 'master' from remote git tag base master # mark our base point git rebase -i master # rewrite some commits git push --force-with-lease=master:base master:master

即為您已經看到並願意覆蓋的上游代碼版本創建一個base標記,然后重寫歷史記錄,最后如果遠程版本仍然在base ,則強制將更改推送到master ,無論您的本地remotes/origin/master是什么remotes/origin/master已在后台更新。

對於使用 OMYZSH 的人,您可以簡單地使用ggfl

您可以創建一個替換git的 bash 函數並使用--force-with-lease而不是--force

# replaces `git push --force` with `git push --force-with-lease`
git() {
  if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then
    command git push --force-with-lease
  else
    command git "$@"
  fi
}

或者,在一行中:

git() { if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then command git push --force-with-lease; else command git "$@"; fi; }

只需將其添加到您的~/.bashrc~/.zshrc即可。

我想提醒我不應該使用-f ,但我不想被愚弄相信-f意味着--force-with-lease 所以這是我的看法:

git() {
  if [[ $@ == 'push -f'* || $@ == 'push --force '*  ]]; then
    echo Hey stupid, use --force-with-lease instead
  else
    command git "$@"
  fi
}

添加到您的.bash_profile.bashrc.zshrc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM