我有本地git存储库和大量文件(约400万,总大小约700GB(,我想将这些文件签入git。使用git过滤器,我不想跟踪文件的真实内容,只想跟踪对文件的一些引用(类似于git lfs
所做的(。添加和提交文件(分块(仍然需要很长时间,我希望通过使用git fast-import
来减少这段时间。
但是,我不知道如何使用git fast-import
来精确地复制git add <file> && git commit -m <message>
。让我们考虑以下情况:
mkdir /tmp/git_fast_test && cd /tmp/git_fast_test
git init
echo "1234" > testfile
现在我运行下面的python脚本,它将模式为644、内容为1234
的文件testfile
提交给git repo。现在,这应该与恰好对应于/tmp/git_fast_test/testfile
。
import subprocess
import time
proc = subprocess.Popen(["git", "fast-import"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd="/tmp/git_fast_test")
proc.stdin.write(b"commit refs/heads/mastern")
proc.stdin.write(b"committer Me <me@me.org> %d +0100n" % int(time.time()))
# commit message
proc.stdin.write(b"data 5n")
proc.stdin.write(b"abcden")
# add file a with content `1234`
proc.stdin.write(b"M 644 inline testfilen")
proc.stdin.write(b"data 4n")
proc.stdin.write(b"1234n")
proc.stdin.flush()
proc.stdin.close()
然而,在回购中,我看到的是:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: testfile
Untracked files:
(use "git add <file>..." to include in what will be committed)
testfile
尽管git似乎知道testfile:
$ git show testfile
commit 85f343fa205665e7304dfbad1725b640a0d03b01 (HEAD -> master)
Author: Me <me@me.org>
Date: Thu Jan 7 08:47:39 2021 +0100
abcde
diff --git a/testfile b/testfile
new file mode 100644
index 0000000..274c005
--- /dev/null
+++ b/testfile
@@ -0,0 +1 @@
+1234
No newline at end of file
那么,我如何调整我的git fast-import
脚本,使git相信文件/tmp/git_fast_test/testfile
正是存储在它的索引中的内容呢?
我在原始git源代码中发现了一个示例shell脚本,它应该几乎完全符合我的要求,并且该脚本也有同样的问题。所以我相信这就是git fast-import
的预期行为。。。
git fast-import
退出时,您有一堆提交,但Git的索引与其中任何一个都不匹配。如果你刚刚创建了存储库,Git的索引是完全空的,所以建议的下一个提交是一个空树。因此,与当前提交的比较将说";要修改当前提交以使其与建议的下一次提交相匹配,请删除每个文件";。
修复方法是运行git reset
(或git restore
或git read-tree
(来加载Git的索引。您也可以选择在此时重置工作树。