[英]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
為我做stash
和pop
舞嗎?
如果這個命令有一個不同的名字,那沒關系。
為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 a7d18a1 、 commit a751e02 、 commit 3400622 (2021 年 6 月 17 日) 。
(由Junio C gitster
合並-- gitster
-- in commit 221ec24 ,2021 年 7 月 8 日)
pull
: 清理自動存儲檢查簽字人: Felipe Contreras
當前“
git pull --rebase
” ( man )在可能進行快進合並的情況下采用快捷方式;run_merge()
使用 --ff-only 調用。但是,“
git merge
” ( man )沒有--autostash
選項,因此,當--rebase
“git
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.