2016-05-03 36 views
3

我欺騙了作者信息。第一次提交。如果它是分支中唯一的提交,我該如何刪除第一個和唯一的提交?

但是,似乎大部分rebase或樹的修改操作都依賴於其他一些已經存在的commit。

即使我運行Git的交互式rebase命令,我在我的小提交列表中看到的只有一行,「noop」。 :/(運行我對底墊解決了這個混帳樹的rootgit rebase -i --root,但刪除行的第一次提交我做實際上並沒有從樹中刪除它。)

衍合上root頂部或第一提交,不起作用。

[[email protected] vagrant]$ git rebase -i HEAD~1 
fatal: Needed a single revision 
invalid upstream HEAD~1 
[[email protected] vagrant]$ git rebase -i HEAD 
Unknown command: rnoop 
Please fix this using 'git rebase --edit-todo'. 
[[email protected] vagrant]$ git rebase --edit-todo 
[[email protected] vagrant]$ git rebase --abort 

下看起來像一個相關的可能的備選答案,但我想更多的東西,或者至少更具體的,是值得爲這個特殊情況下的答案:

Delete commits from a branch in Git

這對方的回答(How do you undo the last commit?)得到如下:

[[email protected] vagrant]$ git reset --soft HEAD~ 
fatal: ambiguous argument 'HEAD~': unknown revision or path not in the working tree. 
Use '--' to separate paths from revisions, like this: 
'git <command> [<revision>...] -- [<file>...]' 
[[email protected] vagrant]$ git reset --soft HEAD 

在這裏,對於那些仍然在閱讀本,是VIM緩衝與noop我前面提到的:

noop 

# Rebase 3d1c632..3d1c632 onto 3d1c632 (1 command(s)) 
# 
# Commands: 
# p, pick = use commit 
# r, reword = use commit, but edit the commit message 
# e, edit = use commit, but stop for amending 
# s, squash = use commit, but meld into previous commit 
# f, fixup = like "squash", but discard this commit's log message 
# x, exec = run command (the rest of the line) using shell 
# 
# These lines can be re-ordered; they are executed from top to bottom. 
# 
# If you remove a line here THAT COMMIT WILL BE LOST. 
# 
# However, if you remove everything, the rebase will be aborted. 
# 
# Note that empty commits are commented out 

對於那些想知道爲什麼我不只是編輯的文件,並將它們重新添加到提交,或什麼的,我有不正確的作者信息,只有我糾正我有後運行「git commit」,並在我提交消息打開進行編輯時更改了作者信息。

也許我可以嘗試刪除整個.git文件夾或其他東西,但我更喜歡更優雅的方式。

另外,如果我不刪除整個.git文件夾,我保留我的鉤子和東西,我有一種感覺,這類問題的答案會說明Git中的基本設計原則,我可能還不瞭解。

+1

如果您對單一個人進行欺騙,則僅在您的回購協議中提交。你能不能使用'git commit --amend'?我很可能誤解你的問題的基礎。 – castis

回答

3

您可以變基上的--root頂部:

git rebase -i --root 

要簡單地改變筆者對最後提交,使用此:

git commit --amend --no-edit --author="The Name <[email protected]>" 
+0

//,'git commit --amend --no-edit --author =「...','Twerked,在項目的頂層目錄中輸入如下:'$ git commit --amend --no-edit --author =「Nathan Bassanese <[email protected]>」'然而,'git rebase -i --root',不是那麼多。在我刪除了交互式rebase的提交之後,它仍然存在。 –

+0

//,當我嘗試刪除交互式rebase中的提交行後,我嘗試應用「fixup」,以查看是否會以某種方式刪除日誌條目:'[vagrant @ localhost vagrant] $ git rebase -i --root' 'Can not 'fixup'without ...'但是它失敗了,無論如何,感謝你的深思熟慮的答案,但我不認爲我可以,良心良知,將它標記爲已接受,直到我可以成功測試它爲止。 –

+0

//值得注意的是,帶有'--amend'和'--author'標誌的'git commit'命令在一個分支中改變了提交,但是在另一個分支中沒有提交。在每個分支上都有它。 –

2

我看你已經通過固定的機制工作一個特別的問題。

我會盡量滿足你的更普遍的問題,但:

...我有回答到這類問題將在GIT中的基本設計原則說話,我可能還不明白的感覺。

這裏是涉及這個特定過程的所有棘手的位。

  1. 名稱(如master)是指向一個特定可動提交的指針。
  2. 每個提交指向其父提交。 A 提交,根據定義,沒有父項。 (這裏沒有,但是有關需要了解的:一個合併提交被簡單地定義爲任何有至少兩個家長提交。)
  3. 要創建任何承諾,我們需要一個分支,但創建一個提交,其中沒有父,我們需要讓分支沒有提交 - 但看到點#1:分支名稱指向提交。
  4. 工作衍合做重複git cherry-pick操作,從--onto目標生長的匿名分支。通過版本比較提交反對(一旦重複櫻桃採摘完成後,新的匿名分支的頂端承諾取代了原來的分支的頂端承諾,即我們重新點的分支新的提示。)
  5. git cherry-pick作品其家長。例如,如果父文件有三個文件,並且提交的文件有四個文件,則提交文件會添加一個新文件。如果三個結轉文件中只有一個是不同的,那麼在該文件中改變的任何內容都會構成該提交的其餘部分(呃,提交的作者和其他元數據也是如此:這些文件也在cherry-挑)。說完轉身原來提交到一組更改,Git的然後應用相同改變一些其他(已經存在的)承諾,使新提交了這一點。新提交的父代是另一個提交。

這些原則創建Gordian knot that --root slices through。值得注意的是,--root在Git 1.6.2版本中是新的,並且在1.7.12中進行了大量修改(我隱約記得在此之前使用rebase並遇到一些問題)。

Git總是必須解決#1和#3之間的緊張關係(當git checkout增長--orphan選項時,解決方案本身得到了改進,並且在某個時候正確地形式化了)。這裏的技巧是,在所謂的「未出生的分支」的時候,在Git的HEAD照常記錄當前分支,但保留本身未創建的分支名。 (這裏有助於瞭解 - 儘管這是一個你不應該擔心的實現細節 - 分支指針當前存儲在兩個地方中的一個或兩個地方,Git存儲這些名稱到ID的映射在.git/refs/和/或一個純文本文件,.git/packed-refs小的單個文件。如果一個分支名稱既不符合的地方,但HEAD,Git會認爲這是「未出生的分支」。)

當進行新的提交,如果當前狀態是「在未出生的分支」,Git會進行一次根提交。新的提交ID成爲現在創建的分支的ID,我們現在擺脫了分支上的自相矛盾的狀態,但沒有提交。

我們仍然有問題git cherry-pick是通過比較提交給其父。這就是爲什麼,如果你想摘櫻桃合併提交,你必須指定其中父:合併是具有兩個或更多的家長提交,因此目前尚不清楚哪一個diff的反對。但是,一個根提交和它的所有零計數 - '零 - 零的父母呢?

Git通過比較櫻桃採摘的根提交和the empty tree來解決此特定問題。由於空樹是空的,所以每個文件都是新添加的,這對於櫻桃挑選來說是正確的結果。

因此,爲了與--root重新綁定,我們想創建一個孤立分支,然後櫻桃挑選根提交,然後照常提交所有其他提交。但git rebase使用匿名分支。創建孤立分支的唯一正常方式是名稱,但是rebase使用「分離HEAD」模式。而且,包括第一個選項在內的每個選項都需要對現有的提交進行更改,但爲了創建新的根提交,我們必須避免使用一些現有的父項。

這個棘手的內部是在this answer from VonC找到(間接),其中鏈接到this commit to the Git code。 rebase腳本創建一個真正空的根提交(使用空樹和內部「plumbing」命令創建一個具有用戶指定的父ID的提交對象),然後生成一個內部「壓扁」操作以挑選現有的根提交(用櫻桃選擇區別於同一棵空樹)並將其與虛擬空根提交結合使用。

(這也有助於注意到,重訂時的「南瓜」操作是指「修訂之前的承諾」,一拉git commit --amend--amend操作告訴git commit作出新的承諾,現有一個不能改變的,但使新的提交的父母匹配現有提交的父母,這樣做會影響舊的提交:分支現在指向新的提交,它指向「已修改」提交的父對象,修改後的提交仍然存在在存儲庫中,但除非有其他方法可以找到它,否則不再可見。)

(這兩步技巧意味着作者信息是專門處理的。)


對於本權利要求的目的,至少,在分離的HEAD模式是(git checkout hashgit checkout --detach branchname後,例如)計數爲在其它特殊的匿名分支,其尖端是當前提交的散列。

+0

//當我睡得更久時,我會閱讀這篇文章,但我的第一印象是,除去「第一次」提交的困難來自上面第1點和第3點之間的矛盾。感謝您將「空樹」引起我的注意,並提出深思熟慮的答案。 –

+2

Git通過不讓分支指針移動直到出現替換提交,即從未真正刪除第一次提交,從而「解決了」。 (事實上​​,除了'git gc'和它的管道之外,git從不刪除*任何提交或任何其他對象,它是圍繞*添加新東西*構建的,並且不會對任何現有對象進行更改。 ),當計劃從現有的提交'E'開始並添加新的挑選提交時,並且您的第一個選擇結果應該是無父項的,但是您有問題。 :-) – torek

+0

//,我想一個確定的答案,我是否可以,確實,刪除第一次提交將是一個堅實的「不」,然後呢? –

相關問題