2010-12-23 246 views
159

恐怕我找不到像這種特殊情況的東西。如何從git存儲庫中刪除舊的歷史記錄?

我有一個有很多歷史的git倉庫:500多個分支,500多個標籤,回到2007年中期。它包含約19,500次提交。我們希望在2010年1月1日之前刪除所有歷史記錄,以使它更小並且更容易處理(我們會在歸檔存儲庫中保存完整的歷史記錄副本)。

我知道我希望成爲新存儲庫根目錄的提交。然而,我不能找出正確的git mojo來截斷回購從那個提交開始。我猜

的一些變種
git filter-branch 

涉及移植物將是必要的;可能還需要對待我們要分開保存的200多個分支中的每一個,然後將回購補丁一起回收(我需要知道如何執行)。

有沒有人做過這樣的事情?如果有問題,我已經得到了git 1.7.2.3。

回答

93

只需創建一個新的根提交的父代的graft父代(或空的提交,例如您的存儲庫的真正的根提交)。例如。 echo "<NEW-ROOT-SHA1>" > .git/info/grafts

創建嫁接後,立即生效;你應該能夠看到git log,看到不想要的舊提交已經消失:

$ echo 4a46bc886318679d8b15e05aea40b83ff6c3bd47 > .git/info/grafts 
$ git log --decorate | tail --lines=11 
commit cb3da2d4d8c3378919844b29e815bfd5fdc0210c 
Author: Your Name <[email protected]> 
Date: Fri May 24 14:04:10 2013 +0200 

    Another message 

commit 4a46bc886318679d8b15e05aea40b83ff6c3bd47 (grafted) 
Author: Your Name <[email protected]> 
Date: Thu May 23 22:27:48 2013 +0200 

    Some message 

如果一切如預期,你可以做一個簡單的git filter-branch -- --all使其永久化。

當心:過濾分支步驟之後,所有提交的IDS纔會有那麼使用舊的回購人絕不能使用新的回購任何合併改變。

+5

如今,它似乎是「git的過濾分支 - --all」 ... – aanno 2012-12-18 15:01:55

+1

好,營造出「的.git /信息/移植文件和過濾器分支後,我仍然需要一個」 git的克隆 - - 沒有本地 - 無硬鏈接「的副本(在此之前製作所有本地跟蹤分支)。簡單地刪除'.git/info/grafts'並不能解決問題! – aanno 2012-12-18 16:18:51

+2

你可能想,當你想縮小到交叉檢查http://stackoverflow.com/questions/7654822/remove-refs-original-heads-master-from-git-repo-after-filter-branch-tree-filte您的存儲庫大小。 – aanno 2012-12-20 08:08:09

41

試試這個方法How to truncate git history

#!/bin/bash 
git checkout --orphan temp $1 
git commit -m "Truncated history" 
git rebase --onto temp $1 master 
git branch -D temp 

這裏$1是SHA-1的承諾,你要保持和腳本將創建一個包含$1master,所有的舊的歷史之間的所有提交新的分支下降。請注意,這個簡單的腳本假定您沒有名爲temp的現有分支。另請注意,此腳本不會清除舊歷史記錄的git數據。確認您確實想要丟失所有歷史記錄後,運行git gc --prune=all && git repack -a -f -F -d。您可能還需要rebase --preserve-merges,但請注意,該功能的git實現並不完美。如果你使用它,手動檢查結果。

47

method很容易理解和正常工作。該腳本的參數($1)是一個參考(標記,散列,...)到您想要保留歷史記錄的提交。

#!/bin/bash 
git checkout --orphan temp $1 # create a new branch without parent history 
git commit -m "Truncated history" # create a first commit on this branch 
git rebase --onto temp $1 master # now rebase the part of master branch that we want to keep onto this branch 
git branch -D temp # delete the temp branch 

# The following 2 commands are optional - they keep your git repo in good shape. 
git prune --progress # delete all the objects w/o references 
git gc --aggressive # aggressively collect garbage; may take a lot of time on large repos 

注意舊標籤將依然存在;所以你可能需要手動刪除它們

備註:我知道這幾乎和@yoyodin一樣,但是這裏有一些重要的額外命令和信息。我試圖編輯答案,但由於這是對@ yoyodin的答案的一個實質性改變,我的編輯被拒絕了,所以這裏是信息!

-8
  1. 刪除git的數據,RM git的
  2. 的git的init
  3. 添加遠程Git
  4. 力推
42

也許爲時已晚來發表回覆,但此頁面Google的第一個結果,它可能仍然有幫助。

如果你想在你的git倉庫中釋放一些空間,但不想重建所有的提交(rebase或者移植),並且仍然能夠從擁有完整倉庫的人推/拉/合併,你可以使用 克隆(- 深參數)。

; Clone the original repo into limitedRepo 
git clone file:///path_to/originalRepo limitedRepo --depth=10 

; Remove the original repo, to free up some space 
rm -rf originalRepo 
cd originalRepo 
git remote rm origin 

您可以到淺現有的回購協議,通過以下步驟:

; Shallow to last 5 commits 
git rev-parse HEAD~5 > .git/shallow 

; Manually remove all other branches, tags and remotes that refers to old commits 

; Prune unreachable objects 
git fsck --unreachable ; Will show you the list of what will be deleted 
git gc --prune=now  ; Will actually delete your data 

PS:混帳的舊版本不支持克隆/推/從/拉至淺回購。

15

如果你想保持上游庫與完整的歷史,但地方小籤,做一淺克隆與git clone --depth=1 [repo]

推提交後,你可以做

  1. git fetch --depth=1修剪老的提交。這使舊提交及其對象無法訪問。
  2. git reflog expire --expire-unreachable=now --all。要過期的所有舊的提交及其對象
  3. git gc --aggressive --prune=all刪除舊的對象

How to remove local git history after a commit?見。

請注意,您無法將此「淺」存儲庫推送到其他位置:「淺度更新不允許」。請參閱Remote rejected (shallow update not allowed) after changing Git remote URL。如果你想這樣做,你必須堅持嫁接。

1

變基頭/主這個錯誤可能發生

remote: GitLab: You are not allowed to access some of the refs! 
To [email protected]:main/xyz.git 
! [remote rejected] master -> master (pre-receive hook declined) 
error: failed to push some refs to '[email protected]:main/xyz.git' 

要解決的git儀表板這個問題應該從「受保護的分支」

刪除主分支

enter image description here

the n您可以運行此命令

git push -f origin master 

git rebase --onto temp $1 master 
8

我需要讀幾個答案以及其他一些信息,瞭解我在做什麼。

1.不顧一切超過一定年長提交

文件.git/info/grafts可以定義假父母提交。只有一個提交ID的行說,提交沒有父項。如果我們想說,我們只關心最後的2000次提交,我們可以輸入:

git rev-parse HEAD~2000 > .git/info/grafts 

混帳REV-解析爲我們提供了目前提交的第2000父的提交ID。上述命令將覆蓋移植文件(如果存在)。檢查它是否在第一位。

2.重寫提交歷史(可選)

如果你想使這個嫁接假父一個真實的,然後運行:

git filter-branch -- --all 

它會改變所有提交的ID。該存儲庫的每個副本都需要進行強制更新。

3.清理磁盤空間

我沒有做第3步。我想我的副本留在上游兼容。我只是想節省一些磁盤空間。爲了忘記所有的舊提交:

git prune 
git gc 

備選:淺拷貝

如果您有其他倉庫的淺拷貝,只是想節省一些磁盤空間,您可以更新.git/shallow。但要小心,沒有任何東西指向之前的提交。所以你可以運行這樣的事情:

git fetch --prune 
git rev-parse HEAD~2000 > .git/shallow 
git prune 
git gc 

淺層作品的入口像移植。但要小心不要同時使用移植物和淺層。至少,在那裏沒有相同的條目,它會失敗。

如果你仍然有一些老引用(標籤,分支機構,遠程頭)那點舊的承諾,他們將不會被清理,你會不會節省更多的磁盤空間。

-1

可以刪除的目錄,文件,也關係到目錄或使用下面提到的jar文件的整個歷史[下載]和命令

bfg.jar文件: https://rtyley.github.io/bfg-repo-cleaner/

混帳克隆--bare回購網址 CD repo_dir Java的罐子bfg.jar --delete文件夾文件夾名 混帳引用日誌到期--expire =現在--all & &混帳GC --prune =現在--aggressive 混帳推--mirror repo_url

相關問題