[英]Git: How to apply changes of one file from branch A to another file in branch B of the same repo?
在存儲庫 X 中,我有一個分支 A,我想在其中應用來自分支 B 的更改。我想將來自分支 B 的文件 d(以master
作為基礎)的所有更改的總和應用到不同的分支 A 上的文件 c(也有master
作為基礎):
Branch A (based on master)
app/file_c (should receive the changes from app/file_d on branch B)
app/file_d
Branch B (based on master)
app/file_c
app/file_d (has the changes I'm interested in)
我嘗試將分支 B 上的文件 d 移動到文件 c 的位置,然后在分支 A 上將更改挑選為分支 B 的提交,但這將覆蓋整個文件並使 git 歷史的可讀性降低。
哪些 git 命令可以幫助我實現此更新?
記住這些項目:
提交保存快照。 它們不是更改,它們是每個文件的完整副本。 (Git 會自動進行重復數據刪除,因此許多提交重用許多文件這一事實意味着它們確實重用了該文件,即使每個都有一個完整的快照。他們都有該文件的一個快照,在所有文件中共享具有該文件的一個版本的快照。)
分支名稱僅標識一個特定的提交。 每個提交都指向一個較早的提交或父提交。 1根據定義,分支選擇的提交是該分支中的最后一次提交。 (這反過來意味着一些提交同時在許多甚至每個分支上。)
因此,要獲得更改,您必須選擇兩個提交並比較它們。 否則,您所擁有的只是一張快照。 (嘗試鏈接並比較第一對圖片。時鍾上的時間有變化嗎?)
提交本身是完全只讀的。 您永遠無法更改任何現有提交中的任何內容。 Git 所做的是將現有提交提取到工作區。 您可以在此工作區中進行任何您喜歡的更改,然后使用git add
和git commit
進行新的提交。 新的提交添加到存儲庫; 現有的提交保持不變。
1合並提交引用了多個先前的提交,並且每個存儲庫中至少有一個提交(第一個提交)實際上不能引用先前的提交,所以它沒有。 但大多數提交大多有一個父提交,即前一次提交。 這就是歷史,在 Git 存儲庫中:這個向后指向的提交鏈,從提交到父級,再到祖父級等等。 這些提交中的每一個都有所有文件的完整快照。
我有一個分支 A,我想在其中應用分支 B 的更改。
讓我們畫出這個,早期的提交向左,后來的提交向右。 我們將使用單個大寫字母來代表真正的 Git 提交 hash ID,但保留A
和B
作為分支名稱:
I--J <-- A
/
...--G--H <-- master
\
K--L <-- B
當然,我不知道你的分支是什么樣的,但是在這里,我們有三個分支:
A
在提交J
處結束;B
在提交L
處結束; 和master
在提交H
處結束。 提交J
的父級是提交I
,其父級是提交G
。 提交L
的父級是提交K
,而K
的父級是提交H
,其父級也是提交G
。 這意味着提交G
在所有三個分支上; 提交H
在master
和B
上; 並且提交IJ
和KL
分別僅在A
和B
上。
我想將來自分支 B 的文件 d (以 master 作為基礎)的所有更改的總和應用到分支 A 上的另一個文件 c (也有 master 作為基礎)...
好吧,也許我應該把它畫成:
I--J <-- A
/
...--G--H <-- master
\
K--L <-- B
您現在的目標是查找對某個文件d
的更改,如提交中所見——可能是H
,由名稱master
標識——對提交中所見的該文件版本的更改L
,由分支名稱B
標識。
git diff
命令會做這樣的事情:
git diff master B
將向您顯示提交H
中的所有文件(使用名稱master
找到)到提交L
中的所有文件(使用名稱B
找到)中的變化,就像在找不同的游戲中一樣。 您可以通過詢問git diff
以限制其 output 來讓 Git 修剪回只顯示文件d
中的任何不同之處,而忽略所有其他文件:
git diff master B -- d
您可能希望將git diff
output 重定向到臨時文件:
git diff master B -- d > /tmp/the_diff
請注意,此文件在其說明中包含文件名d
以及要進行的更改。 您將需要替換此文件名,可能使用保存的git diff
output 上的任何文本編輯器,我們稍后會看到。
到分支 A 上的不同文件 c
請記住,分支名稱僅標識某些特定的提交。 要將該提交從Git 中取出,進入您的工作區,請使用:
git checkout A
或(自 2.23 起在 Git 中):
git switch A
(這些特定的調用執行完全相同的操作;新的git switch
命令比舊的git checkout
命令更加用戶友好,因為許多git checkout
操作已被移至單獨的命令,而無需靜默地覆蓋您的結帳操作使git switch
使用更安全)。
您的工作樹現在具有文件c
的可修改副本。 您現在需要修改它,使用 Git 生成的指令來修改提交H
中的d
副本,使其看起來像提交L
中的副本。 為此,您將首先更改說明以引用文件c
而不是文件d
。 然后你可以運行:
git apply /tmp/the_diff
這將嘗試修改(現在修改為“更改文件c
”,而不是“更改文件d
”)差異到c
的副本是在您的工作樹。
如果一切順利,Git 將應用所有更改。 如果其中一些不能正確應用,您有多種選擇,例如--reject
或--3way
。
注意,默認情況下, git apply
不會暫存要提交的更改; 它留給你。 使用git apply --index
將改變這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.