[英]Remove all information from a .git directory that can be re-downloaded
我有一個git存儲庫,當剛簽出時,即使在最淺的配置中也需要大約2.3 GiB,其中1.9 GiB在.git/objects/pack
。 工作樹文件大約是0.5 GiB。
考慮到我有一個遙控器,我可以根據需要重新獲取所有對象,問題是:
.git
然后我可以使用簡單的git命令從遠程安全地重新獲取所有內容? 測試了一下,我發現如果我刪除.git/objects/pack/
下的所有內容,它將通過簡單的git fetch
從遠程重新下載。
有一些抱怨如:
error: refs/heads/master does not point to a valid object!
error: refs/remotes/origin/master does not point to a valid object!
error: refs/remotes/origin/HEAD does not point to a valid object!
但隨后.git/objects/pack
重新填充,進一步調用git fetch
不再抱怨了。
核武.git/objects/pack*
這樣安全嗎?
假設:
目的是盡可能地減少工件從連續集成管道中占用的空間量,但保留足夠的信息,以便可以將這些工件下載並恢復到開發人員工作站中的工作順序(盡可能少)正常)命令。
刪除.git/
東西只會破壞事物。 它包含項目的完整歷史記錄,這些包文件是git如何節省空間的。 有很多,更好的方法來減少你的回購的規模。
首先是運行垃圾收集, git gc
。 這將做很多事情來減少磁盤上存儲庫的大小。 你不應該這樣,這定期運行,但它可能會有所幫助。
如果沒有,請嘗試淺層克隆,只能獲得歷史記錄的一部分。 這只會克隆來自master
的最新100次提交。
git clone --depth=100 <remote>
同樣,您可以克隆一個分支。
git clone --single-branch --branch master <remote>
這些可以在以后使用git-fetch
“加深”。
但最好的辦法是減少回購的大小。 Git在太空中非常有效,而且演出非常多。 它表明存儲庫中有很多非常大的二進制文件,圖像,視頻,電子表格和壓縮文件...... git無法有效壓縮。 要處理這個問題,有兩個工具, git-lfs (大文件支持)和BFG Repo Cleaner 。
git-lfs允許您將舊版本的大文件存儲在雲存儲中,而不是存儲在每個人的.git
目錄中。 這可以極大地減少存儲庫的大小......繼續。
BFG Repo Cleaner可讓您輕松重寫歷史記錄,包括刪除大文件的選項。
將它們放在一起,您可以使用BFG Repo Cleaner更改現有的大文件以使用git-lfs。 這可以極大地減少存儲庫的大小。 例如,這會將所有*.mp4
更改為使用git-lfs。
$ java -jar ~/bfg-1.12.15.jar --convert-to-git-lfs '*.mp4' --no-blob-protection
另一個重要的事情是不壓縮文件 。 你提到了持續集成工件,我願意打賭它們是壓縮的。 Git將自己進行更高效的壓縮,並且它可以確保歷史記錄中只有一個文件的副本,但它只能在文本上執行。 在提交之前解壓縮tarball和zipfiles。
如果絕對無法減小存儲庫的大小,那么剩下的選擇是讓每個人共享一個.git
目錄。 您可以使用--git-dir
選項或設置GIT_DIR
來執行此GIT_DIR
。
git --git-dir=/path/to/the/.git log
這是一個糟糕的主意。 雖然每個人都可以擁有自己的結賬,但他們都將共享相同的存儲庫狀態。 如果一個開發者進行了更改,其他開發人員將看到它,但現在使用不同的工作目錄。
例如,dev1添加一個文件。
$ touch this
$ GIT_DIR=~/tmp/foo/.git git add this
$ GIT_DIR=~/tmp/foo/.git git st
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: this
然后dev2突然看到了這一點。
$ GIT_DIR=~/tmp/foo/.git git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: this
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: this
他們共享相同的暫存區域,但不是相同的工作副本。 開發者將不斷地絆倒對方。
如果git clone --depth=1
仍然產生太大的repos,那么每個checkout中只有很多數據。 你無能為力。 如果淺克隆上的.git
是2演出,那么結賬將會更大。
至於在.git
上進行手術的想法,也許你可以通過刪除一些對象來逃避,並希望git fetch --deepen
可以修復它,但是在多個開發者中保持這個......這是一個維護噩夢。
那時,您可以完全刪除.git
。 現在您已經有效地導出了最新的提交。 有多種方法可以直接執行此操作 。
或者只是停止浪費時間和金錢並購買更大的硬盤。 花在這上面的每個人小時都是你可以購買的硬盤。
盡可能減少工件從連續集成管道中占用的空間量,但保留足夠的信息,以便可以使用盡可能少的(和正常的)命令將這些工件下載並恢復到開發人員工作站中的工作順序。可能
我不完全理解你的情況,但一種經常被遺忘的減少網絡數據大小和服務器內存使用的方法是:
--reference <path>
。 在正常的開發條件下(文本文件,並非每次提交都更新它們的所有fof),它比使用淺克隆更有效。
至於你問過的事情,我認為嘗試保存從存儲庫中刪除任何內容是沒有意義的。 大多數數據用於包裝,這是必需的,休息是無關緊要的。
PS:存儲庫只能通過git本身在臨時存儲中初始化:
CACHE_REPO=/tmp/repo
if ![ -d "$CACHE_REPO" ]; then
git clone --single-branch --no-checkout --branch=_BRANCH_ _REMOTE_ "$CACHE_REPO"
fi
_BRANCH_
是master
或其他一些你肯定不會強行推進的分支。 你可以試着把它變淺,它可能會也可能不會起作用,我不確定。
- 什么(以及如何)我可以從內部刪除.git然后我可以使用簡單的git命令從遠程安全地重新獲取所有內容?
如果您不想擔心.git
的內部以及某些內容是否可恢復,您可以保存足夠的信息以再次檢查它,並將工作區恢復到與運行時相比功能相似的狀態。 CI管道。
添加這樣的文件(讓我們稱之為degit.sh
)
#!/bin/bash
set -ex
GIT_REMOTE=$( git remote get-url origin )
GIT_BRANCH=$( git rev-parse --abbrev-ref HEAD )
GIT_COMMIT=$( git rev-parse HEAD )
# TABs, not spaces, indenting the block below:
cat <<-EOF > .gitrestore
set -ex
test ! -e .git
tmpclone=\$( mktemp -d --tmpdir=. )
git clone $GIT_REMOTE -n --branch=$GIT_BRANCH \$tmpclone
( cd \$tmpclone ; git reset --hard $GIT_COMMIT )
mv \$tmpclone/.git .
rm -rf "\$tmpclone"
rm -f \$0
EOF
rm -rf .git
然后,在您的Continous Integration(CI)工作空間的每個git repos的根目錄中,調用它以便生成.gitrestore
文件。
它看起來像這樣:
set -ex
test ! -e .git
tmpclone=$( mktemp -d --tmpdir=. )
git clone git@example.com:example/repo.git -n --branch=example-branch $tmpclone
mv $tmpclone/.git .
git reset --hard example-commit-hash
rm -rf "$tmpclone"
rm -f $0
請注意,它在成功運行后會自行破壞。 你不想運行它兩次。
現在,您的開發人員可以在每個存儲庫中獲取CI工件並運行:
bash .gitrestore
它將擁有一個看起來非常類似CI管道的存儲庫,除了更新的遙控器視圖,它允許開發人員比較CI與她擁有的內容。
這假設只有CI機器受空間限制,而不是開發人員機器(她的帶寬都沒有)。
如果要在開發人員端節省空間/帶寬,可以傳遞--depth=1
,它將僅克隆指定的分支(即,它意味着--single-branch
並將歷史記錄限制為單個提交。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.