簡體   English   中英

如何在創建的提交上將分支合並到 master

[英]how to merge branch into master on the created commit

我有這個場景,我從 master 創建了一個分支 A,其中 master 負責人在1234提交 id

現在一些開發人員將更多的分支和提交推送到 master 中,現在 master 負責人在789提交 id 上。

是否可以在提交1234時將分支 A 合並到 master 中?

不要試圖把這個比喻推得太遠(因為它會崩潰),但這有點像問你是否可以將你的 package 放在中國的貨船上,因為船在洛杉磯的港口。 你可以,但你得先把船弄回中國。

讓我們看看 Git 是如何工作的,而不是上面的笨拙的類比。 Git 都是關於提交的,而且——正如你在這里正確描述的——這些提交被編號 不過,這個數字並不是簡單的連續計數數字——例如,提交 #52 后面沒有提交 #53——而是它們是大的、丑陋的、看起來隨機的 hash ID。 所以我喜歡用單個大寫字母來表示它們:

...--G--H   <-- master

在這里,名稱master指向提交H Hmaster上的最新提交 提交H本身向后到達較早的提交G ,后者向后到達另一個較早的提交,依此類推。

在您的情況下,您創建了一個新名稱也指向提交H ,然后進行了一些新提交:

          I--J   <-- your-branch
         /
...--G--H   <-- master

不幸的是,從那時起,其他人master添加了更多提交,如下所示:

          I--J   <-- your-branch
         /
...--G--H
         \
          K--L   <-- master

您現在詢問是否使用git merge

合並是關於合並工作

當我們確實使用git merge時,我們這樣做是因為我們想合並工作 也就是說,你從提交H開始——一些特定的文件集,永遠存儲在一個帶有一些丑陋的大 hash ID 的提交中。 您更改了一個或兩個文件並進行了新的提交,它得到了一些我稱之為I的其他大而丑陋的隨機 ID,並且可能更改了另一個或兩個文件(或相同的文件或兩個)並進行了另一個提交J . 所以在HJ之間,你做了一些工作,導致一些文件發生了一些變化。

Git 可以通過將提交H中的快照(從您開始的所有時間凍結的文件集)與您最近提交中的快照進行比較,向您展示您所做的(總結為一組大的一次性更改), I 這將有如下指令:在文件main.py中,刪除第 47 行,並在第 300 行之后添加一些行

Git 還可以通過比較H中的快照中的內容(注意此快照在兩個分支上共享)與提交Kmaster上的最新快照中的內容,向您展示其他人做了什么。 這可能包含更改 README.md 中的第 7 行README.md類的指令,以及諸如main.py中的第 100 行添加一行的指令

git merge可以為您或任何人做的就是結合這些更改 也就是說,如果他們接觸README.md而你沒有接觸,Git 將保留他們的更改。 如果您觸摸了Documentation/info.md而他們沒有,Git 將保留您的更改。 如果您和他們都修改main.py , Git 將嘗試保留對該文件的兩組更改

如果 Git可以自己組合所有這些更改,則 Git 將自己進行一個新的提交。 這個新的提交將包含來自H中快照的所有文件(通用起點)作為其快照,並應用組合更改,以便 Git 保留您的更改並添加他們的更改,或者 - 如果您更喜歡查看它方式 - 保留他們的更改並添加您的。 結果都是一樣的,看起來像這樣:

          I--J
         /    \
...--G--H      M
         \    /
          K--L

我在這里留下的是哪個分支擁有新的提交M 有兩個名稱——master 和your-branch master並且 Git 只會更新這兩個名稱之一,以便它指向新的提交M 另一個名稱將繼續指向提交J或提交L (無論它之前指向哪個)。

我還省略了另一個細節,這有時確實很重要:因為提交M兩個反向鏈接,或者parents ,指向提交JL ,所以這兩個中的一個首先出現。 另一個是第二個,盡管對於 Git,這只是“不是第一”。 稍后, --first-parent標志有時對於挑選“第一個”父級很有用。 無論您如何進行合並, M中的快照都是相同的,但是第一父級的選擇取決於您git switch到哪個分支,以及您給git merge的名稱:

git switch master
git merge your-branch

給我們:

          I--J   <-- your-branch
         /    \₂
...--G--H      M   <-- master
         \    /¹
          K--L

也就是說, master是指向M名稱,而第一個父級現在是L

這通常是大多數人想要做的——除非他們想使用git rebase

是否可以在 [shared] 提交時將 [my branch] 合並到 master 中?

不完全是,因為無論你做什么, master最終都需要指向除H之外的其他提交。

可以“彈出”提交KL ,如下所示:

          I--J   <-- your-branch
         /
...--G--H   <-- master
         \
          K--L   [abandoned]

這樣做的問題是提交KL現在丟失了 它們並沒有消失——它們仍然在存儲庫中——但是 Git 通過以分支名稱開頭來查找提交。 用於查找提交L的名稱master L , Git 可以向后工作到K

Git無法繼續工作。 Git 總是向后工作。 因此,一旦您將master向后移動兩步,指向H , Git 就再也找不到K了。 即使 Git可以找到K ,也無助於找到L 所以這兩個提交現在被“放棄”了。 丟掉了他們的工作 這不是合並的目的:合並有助於在添加您的工作時保留其他人的工作,或者等效地,在添加其他人的同時保留您的工作

變基

無需贅述,變基背后的想法是我們希望將一些提交復制到一些新的和改進的提交中。 在這種特殊情況下,您可能希望接受您認為非常好的IJ提交,並通過進行兩次的提交來“改進”它們——由於目前還沒有明顯的原因,我們將其稱為I' (I- prime) 和J'很像IJ

新的和改進I'與原來的I之間的區別在於兩部分:

  • 新的I'將不向后鏈接到H ,而是鏈接到K
  • 新的I'作為它的快照,不是H中隨您的更改而修改的快照,而是K中隨您的更改而修改的快照。

I'rest將與I完全相同,包括提交日志消息 現在讓我們畫出I'

          I--J   <-- your-branch
         /
...--G--H
         \
          K--L   <-- master
              \
               I'  <-- temporary-branch

(The underlying Git command that produces I' from I is git cherry-pick . We have to have Git do this on a temporary branch , because Git needs to be able to find all the commits, including both the old ones and the new ones正在構建。rebase 命令隱藏了這種復雜性的大部分,但是因為 Git 在某些事情上很糟糕,所以有時你會看到這一切。)

一旦 Git 復制了II' ,我們需要讓 Git 復制JJ'

          I--J   <-- your-branch
         /
...--G--H
         \
          K--L   <-- master
              \
               I'-J'  <-- temporary-branch

一旦將your-branch上的所有提交復制到新的臨時分支,然后我們將 Git 從提交J中“剝離分支名稱” your-branch並將其粘貼到提交J' — 剛剛制作的最后一個副本 Git —並丟棄臨時名稱:

          I--J   [abandoned]
         /
...--G--H
         \
          K--L   <-- master
              \
               I'-J'  <-- your-branch

因為 Git 按分支名稱查找提交,所以如果我們現在查看這個存儲庫,看起來好像我們等到提交L存在,然后才開始工作並生成提交IJ 我們將看到提交I'J' ,而不是IJ ,但除非我們記住實際的 hash ID——而且沒有人這樣做過——否則我們不會注意到我們現在正在查看兩個不同的提交。 (Git 會知道。Git 查看原始的 hash ID。但我們會忘記,因為這是人類所做的。)

是否以及何時重新設置取決於您

因為 rebase用新的提交替換了舊的提交(新的並且據說是改進的),所以它並不總是合適的。 特別是,如果你已經將你的IJ提交給了其他人,並且他們依賴於他們——包括他們的 hash ID——然后說“把它們扔掉,改用這些新的和改進的”會讓他們做額外的工作. 有時這很好。 (例如,如果他們已經同意這樣做,那也沒關系。)有時不是。

但是,如果您從未將這些提交給任何其他人,他們甚至不會知道您這樣做了。 所以對於那個特殊的情況——“私人”提交——只要你知道你在做什么,rebase 是安全的。

變基的好處是,最后,Git 的歷史“看起來更簡單”,人們可以用更少的精神負擔來思考它。 缺點是它不是真正發生的事情:如果你在 rebase 期間破壞了某些東西,它可能很難調試,這是一個謊言。 是一個善意的謊言讓事情變得更好,還是一個丑陋的大謊言導致死亡和毀滅? 我們不知道,您可能還不知道,直到您嘗試一下。

暫無
暫無

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

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