2014-11-23 317 views
0

當我嘗試進入交互式底線模式時,如here所解釋的,我所得到的全部是無效這很奇怪,但我不明白爲什麼。git rebase -i foo/dev給予noop

我在我的機器上一個臨時分支內,當我嘗試查看的區別,我得到這個:

 
[email protected] /D/Dropbox/AppsPublic/gulp-aspnet-k (temp-a) 
$ git log --pretty=oneline temp-a..ajryan/dev 
f0ef4ee40fde4de5360515fd556de9c3ed40431c update readme with new optionsfcba1ae3306ae041a1d82647e4cf65a0c96fe2f7 do not loop for build, restore8bedd238660908f06d698815ef12fce786d716ed fix command concat 
e2e3a0d00e3950911c00c0e6e51a671f5f2ac2d3 bump version 
d65923ff91eb9d6b9782bc2bf5ab606d19733203 add quiet option 
91a1faff0a3aa1ca552df2151190a3ecd87cfc6f allow caller to loop all comma962c55854457314324d81457c42913532875cc85 trailing whitespace, tabs > sp 

然而,當我運行下面的命令,我得到空操作:

 
[email protected] /D/Dropbox/AppsPublic/gulp-aspnet-k (temp-a) 
$ git rebase -i ajryan/dev 

任何想法爲什麼和我做錯了什麼?

+0

如果'temp-a'是'ajryan/dev'的祖先,那麼我認爲這是預期的。 – 2014-11-23 23:56:02

回答

2

您的git log命令顯示ajryan/dev上的提交,但不顯示temp-a上的提交。您的rebase命令被告知重新綁定temp-a而不是ajryan/dev上的提交,但推測不存在這樣的提交。形象地:

... - o - o - o     <-- HEAD=temp-a 
       \ 
        o - o - o - * <-- ajryan/dev 

因此,不存在提交拿起和重訂到提交我已經標有星號*。所以rebase -i生成一個單一的無操作命令。

如果執行任何操作,底墊操作應通過移動temp-a指向最後提交*後添加上,這將使temp-a點提交*結論。 (如果沒有發生,這是rebase中的一個小錯誤。)但是,如果您刪除了無操作,則重設操作將被中止,並且temp-a將不會移動。


需要注意的是,如果你沒有temp-a你能變基他們,或重訂其他分支不同的項目。這裏有兩個以上的插圖,從幾乎相同的基礎,但有一個承諾是對temp-a不是在ajryan/dev

... - o - o - o - @    <-- HEAD=temp-a 
       \ 
        o - o - o - * <-- ajryan/dev 

在這種情況下,你可以把@提交的其他提交的頂:

... - o - o - o 
       \      (illustration 1) 
        o - o - o - * - @ 

或底部,其他提交如下:

... - o - o - o 
       \      (illustration 2) 
        @ - o - o - o - * 

在這裏,我已經離開了標籤(temp-aajryan/dev)。這是有目的的:在git中,分支標籤很容易移動(並且實際上預計只要它處於「前進」方式就會移動)。所有的實際分支都存儲在提交本身中。 git rebase實際上做的是複製舊承諾到新的,以便您可以更改他們的父母年齡和/或內容。

在插圖#1中,我們重新提交了承諾@:現在它已提交*作爲其父項。所有其他提交都沒有更改,因此只有提交@必須被複制。

然而,在插圖#2中,我們重新提交了原始僅在ajryan/dev上的整個提交鏈。提交@本身不變,但我們必須複製原始o - o - o - *提交中的全部四個:我們複製第一個o以將其父項設置爲@。這個新提交有一個新的不同的SHA-1 ID,所以我們複製第二個o以使用新的提交ID作爲它的父代。第二個副本強制執行第三個副本,然後強制執行*提交的最後一個副本。關於這一點,請參閱下一節。


在Git中,加入提交的兩個不同的鏈,你通常會使用git merge

  A - B 
     /  \ 
... - o   M <-- HEAD=branch 
     \  /
      C - D 

這裏合併提交M連接兩個鏈A - BC - Do叉掉。如果所有AD都存在,並且您創建新提交M,則AD之間沒有任何反應:它們仍然與以前相同。

但是,對於簡單的開發,通常更好的做法是「重新分配」工作:使CD位於A - B的「頂部」。但要做到這一點,你必須拷貝提交,因爲提交git是永久的和不變的。您將C複製到一個新的,略有不同的C',並將D複製到一個新的,略有不同的D'。這是不同的約C'最主要的是,它的母公司是B,不o,這是不同的約D'的是,其母公司是C',不C主要的事情:

  A - B - C' - D' <-- HEAD=branch 
     /
... - o 
     \ 
      C - D   [abandoned] 

一旦底墊複製完成後,你簡單地拋棄舊CD提交,並開始假裝C'D'是原始提交:

  A - B - C - D <-- HEAD=branch 
     /
... - o 

現在我們沒有長呃需要在圖中的小糾結,因爲我們已經忘記了所有關於原CD,歷史看起來就像這樣:

... - o - A - B - C - D <-- HEAD=branch 

的骯髒的祕密(不那麼祕密,不是髒),是由於原始CD仍然在那裏,他們只是看不見(對你)。如果其他人具有原始的兩個CD提交,則會使其真正變髒。 Git commit IDs是其內容的加密校驗和,包括父母SHA-1 ID,因此原始CD仍然存在,並且CD以及其他任何人不同。

當你從其他人處提交提交時,這一點很重要:如果你將他們的提交重新分配到你的工作上,那麼將更改的ID。你製作新的複製品,你可能會忘記他們有原件,但他們不知道你的新副本,他們沒有忘記他們的原始ID。

如果您稍後向他們提交了他們提交的重新發布的副本,他們需要做更多的工作來提取他們的提交副本,並可能移動他們所做的任何其他工作。

總之,除非您事先與他們(無論他們是誰)做出安排,否則像插圖#2所示的變形通常不是一個好主意。


那麼「快進」呢?那麼讓我們再看一下插圖#1。假設o - o - o - @鏈來自其他人(「拉取請求」),並且您通過將工作重新分配到他們的賬戶上來添加提交*。讓我們重新繪製圖形過,再添加一個扭結,並把ajryan/dev標籤背面:

... - o - o - o  [your original '@' commit, before rebasing, was here] 
       \ 
        o - o - o - *  <-- ajryan/dev 
           \ 
            @ <-- HEAD=(something, maybe "dev") 

現在讓我們進一步假設他們,無論他們是誰,對他們dev分支o - o - o - *序列,並沒有做任何額外的工作,以便他們的東西在標記爲*的提交結束。如果您向他們提供此提交序列,他們可以將它提取出來,並將提交@添加到他們的dev分支,只需將其dev標籤向下滑動即可將其指向@標籤。現在讓我們也刪除我們的ajryan/dev標籤,並理清這些圖紙中的扭結,並使用標籤dev。這裏的結果:

... - o - o - o - o - o - o - * - @ <-- HEAD=dev 

這是他們都會有,而且會有什麼,一旦你無論是在同步是。這是一個非常簡單的歷史記錄,即使它與實際開發過程略有偏差(您在未看到鏈接以*結尾的情況下提交@)。但是這是一種「重新設計」,使得開發工作更容易,而且一般人們想要做的事情。

向右滑動標籤(包括像這樣的圖紙中的向下和向右或向上和向右)是「快進」操作。如果您運行git merge--ff-only,它將只會執行「合併」,如果它真的是這種非合併快進。


底線:我想你想衍合@提交到ajryan/dev的工作,但你沒有@承諾變基。這就是爲什麼rebase給你一個noop。在這種情況下,簡單的非合併快速轉發git merge就足以讓您的標籤與其標籤匹配。


這也是值得我們思考的是:當你做git log X..Y你問混帳像我一樣在這裏繪製圖形:

... - o - o - o  <-- X 
     \ 
      o - o - o <-- Y 

X..Y概念實際上是說:開始用這個圖,拿出熒光筆並突出顯示X指向的提交,以及所有提交從那裏離開和/或上下的提交。(這留下了Y指向的三個o未標記)。然後,找到Y所指向的所有未提交的提交,並記錄這些提交。

如果顛倒了XY,如git log Y..X,你問混帳「跑熒光筆」在提交由Y標記,其中僅只有兩個o S於X離開,然後登錄所有提交指向的通過X尚未突出顯示。所以在這裏你得到X上的兩個o,並且沒有共享的。

+0

應該是什麼命令? 'git rebase -i --onto temp-b ajryan/dev'?它不起作用:s – tugberk 2014-11-24 00:04:39

+0

你會喜歡什麼結果? ''temp-a'上沒有提交'ajryan/dev'上沒有的提交。你可以做一個'git merge --ff-only ajryan/dev'來告訴git你希望分支'temp-a'跟上'ajryan/dev',如果(並且只有)它可以做到這一點做一個真正的合併(我相信這是真的,但我沒有你的回購)。 – torek 2014-11-24 02:44:45

+0

我想要做的是將遠程拉取請求分支內的更改帶入交互式重定製會話到我的'temp-a'分支中。 – tugberk 2014-11-24 08:36:20