2010-09-15 60 views
9

git rebase在文件被添加到存儲庫,然後從存儲庫中刪除,然後添加到工作目錄(但不是存儲庫)的某些情況下似乎無法正常工作。git rebase,「會被覆蓋」,「沒有變化 - 你忘了使用'git add'嗎?」

這裏是我的問題更具體的描述:

  • 如果創建,並從一些 幹線切換到一個分支,

  • 和文件X添加和分支致力於 ,

  • 並且隨後X被移除並且 在分支中提交,

  • 和X在工作 目錄下重新創建的,但不能添加或 承諾,

  • 和主幹分支進步,

  • 然後

  • 採用了先進的 衍合進行幹線作爲基地將失敗,因爲 它會拒絕覆蓋X,

  • 和rebas e不能繼續 ,即使工作目錄X是 已移除或移除。

以下腳本複製在命令行上我的問題:

git init 
echo foo > foo.txt 
git add . 
git commit -m 'foo' 
echo foo >> foo.txt 
git add . 
git commit -m 'foo foo' 
git checkout -b topic HEAD^ 
git log 
echo bar > bar.txt 
echo baz > baz.txt 
git add . 
git commit -m 'bar baz' 
git rm bar.txt 
git commit -m '-bar' 
echo bar > bar.txt 
git rebase master 
# the following output is emitted: 
# First, rewinding head to replay your work on top of it... 
# Applying: bar baz 
# Using index info to reconstruct a base tree... 
# Falling back to patching base and 3-way merge... 
# error: Untracked working tree file 'bar.txt' would be overwritten by merge. Aborting 
# Failed to merge in the changes. 
# Patch failed at 0001 bar baz 
# 
# When you have resolved this problem run "git rebase --continue". 
rm bar.txt 
git rebase --continue 
# the following output is emitted: 
# Applying: bar baz 
# No changes - did you forget to use 'git add'? 
# 
# When you have resolved this problem run "git rebase --continue". 
# If you would prefer to skip this patch, instead run "git rebase --skip". 
# To restore the original branch and stop rebasing run "git rebase --abort". 

我知道我可以放棄使用git rebase --abort底墊,去除bar.txt,然後再git rebase master。但是,我怎樣才能在不墮落的情況下繼續進行重組?

回答

4

我找到了一個解決方案:手動應用問題提交的補丁並將其添加到索引。

$ patch -p1 < .git/rebase-apply/patch 
patching file bar.txt 
patching file baz.txt 
$ git add bar.txt baz.txt 
$ git rebase --continue 
Applying: bar baz 
Applying: -bar 
+1

我建議使用'git-apply',因爲'patch'不支持Git二進制diff格式。 – 2015-02-14 01:16:38

2

您需要在嘗試重新綁定之前提交。如果你不這樣做,它有時會起作用,但你不應該那樣做。

如果您因爲某種原因而不舒服,至少可以使用藏匿(大致相同的東西)。

+0

好了,但如果是這樣的話,那麼我得到的錯誤信息是非常無益的,因爲它意味着有可能繼續重訂。 – 2010-09-15 21:22:08

+0

@Russell Silva:你可以繼續。問題是,既然你刪除了'bar.txt','rebase'在這個提交中沒有任何工作要做。 'git rebase --skip'應該可以解決問題,因爲您現在想要跳過(空)提交。這有點令人困惑,我很驚訝'git rebase'甚至可以讓你繼續做一個骯髒的工作樹,但是'git rebase'並不適合膽小的人。 – mipadi 2010-09-15 21:55:49

+0

@mipadi:提交不是空的。在這個例子中,'baz.txt'是通過添加'bar.txt'的相同提交添加的。 'git rebase --skip'導致'baz.txt'丟失。 – 2010-09-15 22:31:27

0

爲了讓GIT在文件移除後繼續進行rebase,我添加了一個空白變化,然後用這個變化「git add」文件。

2

git rebase工作正常。它正在保護你未跟蹤的文件在被訪問提交時想要寫出一個具有相同路徑名的文件時被銷燬。

似乎沒有辦法重試rebase的最新步驟。通常情況下,當一個基金會暫停時,它會在索引中留下衝突。但在這種情況下,它不能在索引中標記此問題,因爲這樣做會將未跟蹤文件轉換爲跟蹤文件。這在git rebase的用戶界面中可能有點粗糙。你可以深入到它用來存儲其內部狀態的目錄(.git/rebase-apply)並手動應用「當前」補丁,但中止並重新啓動可能更容易(但如果你正在重新組裝一個很長的系列,可能不會更快) 。


如果bar.txt加入被認爲是一個錯誤,那麼你可以考慮使用git rebase -i梳理開,因爲你是無論如何改寫歷史滴bar.txt添加和刪除。
您仍然會遇到衝突,但下面的方法也可以與git rebase -i一起應用。在結束該腳本將具有通常需要這兩個部分之間的多個命令被自交互式底墊分成兩個部分(「設置temp/」和「包括底墊結果」。


移動衝突文件一旁暫時和重做的底墊。

mv bar.txt +bar.txt 
git rebase --abort 
git rebase master 

如果你指望有很多這樣的衝突文件,那麼你可以考慮做衍合在一個單獨的克隆,你可以肯定,你不會有任何未跟蹤文件。也許最棘手的部分是檢查你未跟蹤的文件是否與t的結果相沖突他rebase(git checkout rebased-topic完成此;如果未跟蹤的文件與rebase結果衝突,它會中止)。

: "Note: will destroy 
:  * 'rebased-topic' branch 
:  * 'temp' directory" 
(set -x && 
    : '*** Clearing temp/' && 
    rm -rf temp/ && 

    : '*** Making sure we have topic checked out' && 
    git checkout topic 

    : '*** Cloning into temp/' && 
    git clone . temp && 

    : '*** Rebasing topic onto master in temp/ clone' && 
    (cd temp && 
    git rebase origin/master 
) && 

    : '*** Fetching rebase result from topic/ into local rebased-topic branch' && 
    git fetch -f temp topic:rebased-topic && 

    : '*** Checking rebased-topic for conflicts with untracked files' && 
    git checkout rebased-topic && 

    : '*** Resetting topic to tip of rebased-topic' && 
    git branch -f topic rebased-topic && 

    : '*** Returning to topic branch' && 
    git checkout topic && 

    : '*** Deleting rebased-topic branch' && 
    git branch -d rebased-topic && 

    : '*** Deleting temp/' && 
    rm -rf temp/ 
) 
+0

在我的情況下,文件未被跟蹤的唯一原因是由於rebase倒帶。不應該倒退刪除早期提交中未跟蹤的文件?不會有數據丟失。 – Shannon 2013-01-08 22:05:24

+0

@ rehevkor5:我不確定你的情況的細節,但是如果(例如)你有連續的提交A,B,C和D,而最後一個只有文件'frob'(即它最初被添加在D和其他地方),然後Git *將*(暫時)刪除'frob',同時倒回到其他基地(如修改後的B)。這個問題的情況有點複雜,如果你有一些具體的情況,你可能想要提供一個新的問題與細節。 – 2013-01-08 23:24:32

0

這發生在我和幾個團隊成員多次...通常當在同一個分支上工作並頻繁提交時。

我們爲我們的客戶使用SmartGit,會發生什麼,即使SmartGit顯示一個乾淨的回購,git status顯示了一些修改後的隨機文件。

我剛碰到這個,又發現git checkout .修復了我的問題。它拋棄了這些「看不見的本地變化」,讓我繼續拉動(並重新發起我的離開提交)。

我決定把它寫下來供將來參考。 Ofc,我認爲你犯了你的故意改變,你可以放棄無意的改變。如果是這樣的話,一個git checkout .應該(希望)這樣做。

乾杯