Kle*_*ger 7 git format-patch git-lfs
我们目前正在从 CVS 迁移到 git 存储库。然而,一个团队大约一年前已经将 cvs2git 用于他们的存储库,因为他们的新功能需要大量具有历史记录的移动文件,而 CVS 在历史上并不擅长。然后,两个存储库都应该将 GIT-LFS 用于我们更大的签入源(例如,预先构建的外部库)
我们的想法是创建相同的起点,以便在迁移后将所有更改与历史记录合并到我们的存储库中。
所以我已经有了起点的精确复制品;这个想法是现在使用 git format-patch 创建所有补丁文件。现在大多数补丁都运行良好,问题仅在于使用 git lfs 的补丁。
一个例子:
diff --git a/Foo/bar/baz.zip b/Foo/bar/baz.zip
new file mode 100644
index 00000000000..6fce3f4bd05
--- /dev/null
+++ b/Foo/bar/baz.zip
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c90b657621e07fa40476186d94e2f6e06f055b49294b83ee976f73dfac120d86
+size 116056
--
2.13.2.windows.1
Run Code Online (Sandbox Code Playgroud)
当我尝试应用该补丁时,会发生以下情况:
$ git am ../patches/mypatch.patch
Applying: #someTfsId: myCommit
Downloading Foo/bar/baz.zip (113.34 KB)
Error downloading object: Foo/bar/baz.zip (c90b657): Smudge error: Error opening media file.: open D:\repositories\myrepo\.git\lfs\objects\c9\0b\c90b657621e07fa40476186d94e2f6e06f055b49294b83ee976f73dfac120d86: The system cannot find the file specified.
Errors logged to D:\repositories\myrepo\.git\lfs\objects\logs\20171006T110837.3254847.log
Use `git lfs logs last` to view the log.
error: external filter 'git-lfs filter-process' failed
fatal: Foo/bar/baz.zip: smudge filter lfs failed
user@machine MINGW64 /d/repositories/myrepo (develop|AM 1/1)
$ git am --abort
Run Code Online (Sandbox Code Playgroud)
我的下一个想法是使用原始存储库并使用 GIT_TRACE=1 git lfs fetch --all 获取所有 lfs 对象之后我尝试复制该对象(用于测试目的),这导致
user@machine MINGW64 /d/repositories/myrepo (develop)
$ git am ../patches/mypatch.patch
error: Foo/bar/baz.zip: already exists in working directory
Applying: #someTfsId: myCommit
Patch failed at 0001 #someTfsId: myCommit
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Run Code Online (Sandbox Code Playgroud)
所以我想问题是:我是否可以将 LFS 对象添加到远程服务器,或者我是否必须“取消”用于创建 .patch 文件的存储库,以便存储二进制差异在 .patch 文件中?
我们真的很想保留历史记录,目前补丁的数量大约是 1600 次提交,这很难手动完成。
如果我遗漏了一些明显的方式,我很高兴提供任何建设性的意见
我知道这个问题已经很老了,但我今天才遇到这种情况。
这就是我解决问题的方法,也许有更好的方法,但这对我有用。
基本步骤是:
注意:任何未提交的工作都将在步骤 2 中丢失,所以要小心
假设我在存储库中有一个名为opensrc/src/make-4.3.tar.gz的文件,并且我位于存储库的顶层。我想创建一个补丁,其中包含该文件以及随之更改的其他文件,但我跟踪的文件是:
[root@localhost]# git lfs track
Listing tracked patterns
*.gz (.gitattributes)
*.sbr (.gitattributes)
*.tgz (.gitattributes)
*.exe (.gitattributes)
Listing excluded patterns
Run Code Online (Sandbox Code Playgroud)
继续添加并提交将成为补丁一部分的文件。您可以通过执行以下命令找出哪些文件将位于 LFS 中:
[root@localhost]# git lfs status
On branch master
Objects to be pushed to origin/master:
opensrc/src/make-4.3.tar.gz (e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19)
Objects to be committed:
Objects not staged for commit:
Run Code Online (Sandbox Code Playgroud)
因此,在创建补丁之前,我将此文件(以及任何其他文件)添加到排除列表中:
[root@localhost]# git lfs migrate export --include opensrc/src/make-4.3.tar.gz
migrate: override changes in your working copy? All uncommitted changes will be lost! [y/N] y
migrate: changes in your working copy will be overridden ...
migrate: Fetching remote refs: ..., done.
migrate: Sorting commits: ..., done.
migrate: Rewriting commits: 100% (1/1), done.
master 526f3a2488679349653bea096fc311c5f42c38dd -> 3734d32f6226c542f470e252aedfcafd5e0950cf
migrate: Updating refs: ..., done.
migrate: checkout: ..., done.
prune: 341 local object(s), 341 retained, done.
e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19 (2.3 MB)
e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19 (2.3 MB), done.
prune: Deleting objects: 100% (1/1), done.
Run Code Online (Sandbox Code Playgroud)
现在再次检查 lfs 状态:
[root@localhost]# git lfs status
On branch master
Objects to be pushed to origin/master:
Objects to be committed:
Objects not staged for commit:
Run Code Online (Sandbox Code Playgroud)
现在创建补丁:
[root@localhost]# git format-patch HEAD -1
0001-Update-make.patch
[root@localhost]# **ls -l 0001-Update-make.patch**
-rw-r--r--. 1 root root 2986800 Oct 21 18:44 0001-Update-make.patch
Run Code Online (Sandbox Code Playgroud)
现在您可以恢复 LFS 更改并重新提交原始更改,以便您的文件最终位于 LFS 中:
[root@localhost]# git reset HEAD^
Unstaged changes after reset:
M .gitattributes
M opensrc/Makefile
M opensrc/config.common.mk
M opensrc/rootproject/Makefile
[root@localhost]# git diff .gitattributes
diff --git a/.gitattributes b/.gitattributes
index 893a1726c..f94922c84 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -12,3 +12,4 @@
*.sbr filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
+opensrc/src/make-4.3.tar.gz !text !filter !merge !diff
[root@localhost]# git checkout .gitattributes
Updated 1 path from the index
[root@localhost]# git add .
[root@localhost]# git commit -v -s
Run Code Online (Sandbox Code Playgroud)
注意:您的补丁还将从 LFS 中排除文件,因此您可能必须通过重置提交、编辑 .gitattributes 然后重新提交来修复该问题