簡體   English   中英

“git pull”可以自動隱藏和彈出待處理的更改嗎?

[英]Can “git pull” automatically stash and pop pending changes?

我知道如何解決這個問題:

user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
    foo.bar
Please, commit your changes or stash them before you can merge.
Aborting

但是沒有辦法讓git pull為我做stashpop舞嗎?

如果這個命令有一個不同的名字,那沒關系。

git stash; git pull; git stash pop創建一個 shell 別名git stash; git pull; git stash pop git stash; git pull; git stash pop git stash; git pull; git stash pop是一個解決方案,但我正在尋找更好的解決方案。

對於 Git 2.6+(2015 年 9 月 28 日發布)

只要感興趣的git config設置是:

rebase.autostash

(在 2020 年第二季度的 Git 2.27 中,您現在還擁有merge.autostash ,見下文)

當設置為 true 時,在操作開始前自動創建一個臨時存儲,並在操作結束后應用它。
這意味着您可以在臟工作樹上運行 rebase。

但是,請謹慎使用:成功 rebase 后的最終存儲應用程序可能會導致重大沖突。 默認為假。

結合它:

pull.rebase

如果為 true,則在獲取的分支之上重新設置分支,而不是在運行“git pull”時從默認遠程合並默認分支。

在給定的存儲庫中:

git config pull.rebase true
git config rebase.autoStash true

這足以讓簡單的git pull即使在臟樹中也能工作。
在這種情況下不需要別名。


提交53c76dc (2015年7月4日),由凱文Daudt( Ikke
(由Junio C gitster合並-- gitster -- in commit e69b408 ,2015 年 8 月 17 日)

pull : 啟用rebase.autostash時允許臟樹

rebase 在遇到臟工作樹時學會了隱藏更改,但git pull --rebase沒有。

僅在未啟用rebase.autostash時驗證工作樹是否臟。


注意:如果你想在沒有autostash 的情況下拉取(即使rebase.autoStash true被設置),你從 git 2.9(2016 年 6 月)開始:

 pull --rebase --no-autostash

提交450dd1d提交1662297提交44a59ff提交5c82bcd提交6ddc97c提交eff960b提交efa195d (2016年4月2日),以及提交f66398e提交c48d73b (2016年3月21日)由MEHUL耆那( mehul2029
(由Junio C gitster合並-- gitster -- in commit 7c137bb ,2016 年 4 月 13 日)

Commit f66398e特別包括:

pull --rebase : 添加--[no-]autostash標志

如果設置了rebase.autoStash配置變量,則無法git pull --rebase為“ git pull --rebase ”覆蓋它。

教“ git pull --rebase--[no-]autostash命令行標志,該標志會覆蓋rebase.autoStash的當前值(如果已設置)。 由於“ git rebase ”理解--[no-]autostash選項,因此當調用“ git pull --rebase ”時,只需將選項傳遞給底層“ git rebase ”。


警告:在 Git 2.14(2017 年第 3 季度)之前,當本地歷史快進到上游時,“ git pull --rebase --autostash ”不會自動存儲。

請參閱Tyler Brazier ( tylerbrazier ) 的提交 f15e7cf (2017 年 6 月 1 日)
(由Junio C gitster合並-- gitster -- in commit 35898ea ,2017 年 6 月 5 日)

pull : ff --rebase --autostash在臟--rebase --autostash工作

當臟存儲庫中的git pull --rebase --autostash導致快進時,沒有自動存儲任何內容並且拉取失敗。
這是由於在我們可以快進時避免運行 rebase 的快捷方式,但自動存儲在該代碼路徑上被忽略。


更新: Mariusz Pawelski 在評論中提出了一個有趣的問題:

所以當你做 rebase (或pull --rebase )時,每個人都在寫關於autostash pull --rebase

但是當您使用合並進行正常拉取時,沒有人會考慮自動存儲。
所以沒有自動切換? 或者我錯過了什么? 我更喜歡做git pull --rebase但 OP 詢問“標准” git pull

回答:

討論這個自動存儲功能的原始線程,它最初是為git pull (merge) 和git pull --rebase

但是…… Junio C Hamano(Git 維護者)指出:

如果pull-merge會引起觸發這個主題的“煩惱”,根據定義,本地更改與合並重疊,並且這個內部“stash pop”將觸及合並觸及的路徑,它可能不會導致在“丟棄”中,但留下進一步的沖突有待解決。

我懷疑pull.autostash配置不是一個好的補充,因為它鼓勵糟糕的、令人痛苦的工作流程。
在簡單的情況下它可能不會受到傷害,但是當局部變化很復雜時,它會比沒有它更積極,並且配置剝奪了選擇的動力。

“pull-rebase”的等式有些不同,因為“rebase”堅持你從一個干凈的工作樹開始,所以“下載然后停止”的煩惱感覺更大。 我懷疑放松可能是解決實際問題的更有效方法。

因此,對於經典的 pull-merge,最好是:

鼓勵用戶在運行“ git pull ”之前考慮他在工作樹中擁有的 WIP 的性質
它是一個過於復雜的野獸,可能會干擾其他人正在做的事情,還是一個微不足道的變化,他可以藏起來然后把它彈回來?

如果是前者,他會更好地執行“ checkout -b ”,繼續工作直到本地更改變得更好並“提交”,然后再進入原始分支。

如果是后者,他最好這樣做:

  • " git pull ",
  • 發現沖突后,運行
    • git stash
    • git merge FETCH_HEAD
    • git stash pop

話雖如此,在 Git 2.27(2020 年第二季度)中,“ git pull ”學會了在不存在pull.rebase配置時發出警告,並且--[no-]rebase--ff-only都沒有給出(這將導致合並)。

請參閱Alex Henrie ( alexhenrie ) 的commit d18c950 (10 Mar 2020 )
(由Junio C gitster -- gitster --commit 1c56d6f 中合並,2020 年 3 月 27 日)

pull : 如果用戶沒有說是 rebase 還是合並,則發出警告

簽字人:Alex Henrie

新手 Git 用戶經常忘記說“ pull --rebase ”,結果是從上游進行了不必要的合並。

他們通常想要的是“ pull --rebase ”在更簡單的情況下,或者“ pull --ff-only ”來更新主要集成分支的副本,並分別重新調整他們的工作。
pull.rebase配置變量的存在是為了在更簡單的情況下幫助他們,但沒有機制讓這些用戶意識到它。

當命令行中沒有--[no-]rebase選項並且沒有給出pull.rebase配置變量時,發出警告消息。
這會給那些從來不想“ pull --rebase ”的人帶來不便,他們本來不必做任何特別的事情,但不便的成本每個用戶只支付一次,這應該是一個合理的成本,可以幫助一些新的用戶。


在 Git 2.27(2020 年第二季度)中,“ git merge ”學習了“ --autostash ”選項和新的merge.autostash設置。

提交d9f15d3提交f8a1785提交a03b555提交804fe31提交12b6e13提交0dd562e提交0816f1d提交9bb3dea提交4d4bc15提交b309a97提交f213f06提交86ed00a提交facca7f提交be1bb60提交efcf6cf提交c20de8b提交bfa50c2提交 3442c3d提交 5b2f6d9 (2020 年 4 月 7 日), 提交 65c425a (2020 年 4 月 4 日),以及提交 fd6852c提交 805d9ea (2020 年 3 月 21 日)由Denton Liu ( Denton-L
(由Junio C gitster -- gitster --提交 bf10200 中合並,2020 年 4 月 29 日)

pull : 通過 --autostash 合並

簽字人:Denton Liu

之前,-- --autostash只適用於git pull --rebase

然而,在上一個補丁中,merge 也學習了--autostash ,所以我們沒有理由再有這個限制了。
教 pull 通過--autostash進行合並,就像它為 rebase 所做的那樣。

和:

rebase :使用apply_autostash()

簽字人:Denton Liu

所述apply_autostash()函數builtin/rebase.c類似於足以將apply_autostash()函數sequencer.c它們是可以互換的,除了的ARG他們接受的類型。 使sequencer.c版本為 extern 並在 rebase 中使用它。

rebase 版本是在6defce2b02中引入的(“builtin rebase: support --autostash option”,2018-09-04,Git v2.20.0-rc0 -- merge第 8 批中列出)作為 shell 到 C 轉換的一部分。
它選擇復制該函數,因為當時還有另一個正在進行的項目將交互式 rebase 從 shell 轉換為 C,並且他們不想通過重構sequencer.c版本的apply_autostash()與它們發生沖突。
由於這兩種努力已經完成很久,我們現在可以自由地將它們組合在一起。


Git 2.30(2021 年第一季度)改進了 UI:

請參閱Johannes Schindelin ( dscho ) 的commit e01ae2a (2020 年 11 月 19 日
(由Junio C gitster -- gitster --commit 290c940 中合並,2020 年 11 月 30 日)

pull : 着色關於設置pull.rebase的提示

指出者:Ævar Arnfjörð Bjarmason
簽字人:約翰內斯·辛德林

d18c950a69f (“ pull : warn if the user didn't say is rebase or to merge”, 2020-03-09, Git v2.27.0-rc0 -- merge列在批處理#2 中),引入了一個新的提示通過配置pull.rebase設置,鼓勵用戶有意識地決定他們是希望他們的 pull 合並還是 rebase。

此警告顯然是為了向用戶提供建議,但正如該線程中指出的那樣,它使用warning()而不是advise()

一個后果是,通知的顏色與其他類似消息不同。
所以讓我們改用advise()


在 Git 2.33(2021 年第三季度)中,簡化了 git pull --rebase:

請參閱Felipe Contreras ( felipec ) 的commit a7d18a1commit a751e02commit 3400622 (2021 年 6 月 17 日
(由Junio C gitster合並-- gitster -- in commit 221ec24 ,2021 年 7 月 8 日)

pull : 清理自動存儲檢查

簽字人: Felipe Contreras

當前“ git pull --rebaseman在可能進行快進合並的情況下采用快捷方式; run_merge()使用 --ff-only 調用。

但是,“ git merge( man )沒有--autostash選項,因此,當--rebasegit pull --rebase --autostash`` ( man )采用快進合並快捷方式時,拉失敗。

這在提交 f15e7cf (“ pull : ff --rebase --autostash 在臟--rebase工作”,2017 年 6 月 1 日,Git v2.14.0-rc0 -- 合並第 7 批中列出)中得到修復,只需跳過快速-向前合並快捷方式。

后來“ git merge ”絕活--autostash選項[ a03b555 ( “ merge :教--autostash選項”,2020年4月7日,Git的v2.27.0-RC0 - 合並上市批號#5 )],等等做了“ git pull( man ) [ d9f15d3 (“ pull : pass --autostash to merge”, 2020-04-07, Git v2.27.0-rc0 -- merge第5批中列出)]。

因此,當使用--rebase --autostash調用時,不再需要跳過快進合並快捷方式。

讓我們始終通過基本上恢復f15e7cf來采用快進合並快捷方式。

為了為即將到來的探索者節省幾秒鍾,這里是一個摘要(感謝@VonC):

git pull --rebase --autostash

正如上面的評論所述,設置兩個配置值當前不適用於git pull ,因為 autostash 配置僅適用於實際的變基。 這些 git 命令可以執行您想要的操作:

git fetch
git rebase --autostash FETCH_HEAD

或將其設置為別名:

git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'

然后做:

git pullr

當然,這個別名可以根據需要重命名。

使用 Git 2.6+,您可以使用以下內容:

alias gup='git -c rebase.autoStash=true pull --rebase'

--rebase使 git-pull 使用rebase而不是merge ,因此諸如--ff-only類的設置/選項將不適用。

默認情況下,我使用別名來拉取--ff-only ( git pull --ff-only ),然后可以使用gup (從上面),以防無法進行快進合並或存在隱藏的更改。

正如您已經提到的,這就是這樣做的方法。 您可以在別名中使用它來保存您的輸入並使用快捷方式,或者您可以在一行中使用它(也可以是別名)

git stash && git pull --rebase && git stash pop

它會做和你做的一樣的事情,但在一行(&&)中,如果你設置為別名,它甚至會更短。

在拉/推之前,以下幾行將顯示傳入/傳出的更改

git log ^master origin/master
git log master ^origin/master

暫無
暫無

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

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