簡體   English   中英

從整個git歷史記錄中刪除文件

[英]Remove a file from whole git history

我知道已經問過這個問題,但是在每個答案中,我發現情況都與我的略有不同,並且我不知道如何適應它。

所以這是問題所在:

我克隆了一個存儲庫,並添加了一個要在其中使用的文件夾。 在此文件夾中,我添加了.csv文件和使用csv文件的.py文件。 我試圖推動這一點,但意識到只要2個csv文件非常大,它就花費了很長時間。 所以我

git rm files

然后提交。 我嘗試再次推送,然后才意識到刪除文件不會將其從git歷史記錄中刪除。//現在,從上一次完成的推送中,我有2次提交:1在其中添加文件,1在刪除位置一些.csv。

我希望您能幫助您刪除最近的兩次提交。 那可行嗎? 謝謝

我發現git filter-branch文檔中的第一個示例非常適合您的上下文。 看一看( 來源 ):

假設您要從所有提交中刪除文件(包含機密信息或侵犯版權的文件):

git filter-branch --tree-filter 'rm filename' HEAD
# and see also the variant further in the example description
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

(請參閱文檔頁面上的詳細信息,我避免在此處復制粘貼整個內容)

如我們所建議,如果要談論Biiiig歷史,可以使用filter-branch。 如果我們只討論少數修訂,則可以通過修改修訂(添加文件和切入選擇的修訂)來實現(刪除文件),或者重新設置交互基礎。

一個例子.....說我在master〜2上添加了a.txt文件。 我不想在歷史上了。

git checkout master~2 git rm --cached a.txt git commit --amend --no-edit git cherry-pick master~2..master git branch -f master # point master in this revision git checkout master

那應該足夠了。

...我想...刪除最后2次提交。 那可行嗎?

您不能完全刪除提交,但是可以輕松地告訴Git 忘記它們。

最后,這種工作方式非常簡單。 我們首先注意到每個提交都保存一個快照,並且還存儲其父提交的哈希ID(以及您的提交日志消息和您作為作者的名稱,依此類推)。 這形成了一個向后的提交鏈。

如果我們讓單個大寫字母代表提交哈希ID,則可以繪制此鏈:

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

請注意,在這種情況下, 分支名稱 master是存儲鏈中最后一次提交的哈希ID。 (當某物存儲提交的哈希ID時,我們說該東西指向該提交,因此是箭頭。名稱master指向HH指向G ,依此類推。)

Git找到這些提交的方式是從master讀取H的哈希ID,該哈希ID找到提交H ,然后讀取提交H並顯示它。 然后,在讀取H ,Git具有提交G的哈希ID,因此Git可以讀取G並顯示它,依此類推。

當我們進行新的提交時,Git實際上通過以下方式做到這一點:

  • 寫出快照;
  • 寫出作者和日志消息等;
  • 點回到當前提交;
  • 最后也是最重要的一點是,將提交的哈希ID寫入分支名稱。

因此,如果我們有:

...--F--G--H

並且我們添加了--I

...--F--G--H--I

然后Git更改了名稱 master來存儲提交I的哈希ID。 最終我們有了:

...--F--G--H--I--J   <-- master

如果我們進行了幾次不需要的提交,我們可以告訴Git: 將名稱master為指向提交H而不是提交J 有幾種方法可以做到這一點,但是在這種情況下,第一個可以實現的方法是git reset --hard (在我們檢查了master同時,請確保您沒有擔心丟失的任何東西,因為git reset --hard告訴Git放棄所有內容 ):

git checkout master
git reset --hard HEAD~2

~2后綴告訴Git的數后退了兩步,從技術上來說,兩個第一父步驟,當我們有一些合並在我們的承諾鏈,其重要的,但在這里,我們不這樣也沒關系。 如果master當前指向J ,則Git計數兩次: JI ,然后IH 混帳然后替換我們的工作與承諾內容H 使名字, master ,指向H ,而不是J

             I--J
            /
...--F--G--H   <-- master

現在J很難找到 ,它似乎已被刪除。

這樣做的缺點是,如果我們讓Git告訴其他Git: 在這里,復制提交IJ則其他Git具有兩個提交,即使我們的Git已經完成,它們也將重新引入到我們自己的Git中。忘記了他們。 但是,如果我們從未成功地將這兩個提交發送到其他任何地方,那么我們將是唯一擁有它們的人,因此,如果我們忘記了它們,它們就和過去一樣出色。

(如果我們推他們,我們有我們的Git,和他們的Git,並已經把它們撿起來,因為其他每一個Git的所有的忘記他們, 然后他們將會消失,但顯然這很快變得很難。)

暫無
暫無

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

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