Git format-patch生成的补丁在不同仓库之间不能使用LFS。

8
我们目前正在从CVS迁移到git存储库。然而,由于其新功能需要大量移动带有历史记录的文件,而CVS在历史上并不擅长此类操作,因此其中一个团队已经一年前使用了cvs2git来处理他们的存储库。这两个存储库都应该使用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

当我尝试应用该补丁时,会发生以下情况:
$ 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

我的下一个想法是使用原始仓库,并使用 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".

所以我的问题是:我是否可以将LFS对象添加到远程服务器,还是必须"取消-lfs"用于创建.patch文件的存储库,这样二进制差异将存储在.patch文件中?

我们真的想保留历史记录,目前大约有1600个提交的补丁,手动完成会很困难。

如果我漏掉了某些明显的方法,我很乐意接受任何建设性的意见。

1个回答

1
我知道这个问题很老,但今天我才遇到了这种情况。以下是我解决问题的方法,也许有更好的方法,但对我来说这个方法有效。基本步骤如下:
1. 提交(但不推送)更改。 2. 对应该放入LFS的文件进行lfs迁移。 3. 撤销提交(假设您希望将文件放在LFS中)。 4. 恢复要放在LFS中的文件的.gitattribute更改。 5. 重新提交文件。
注意:第二步中会丢失任何未提交的工作,请小心。
假设我在存储库的顶层有一个名为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

请继续 添加提交 作为补丁一部分的文件。 您可以执行以下操作以了解哪些文件将在 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:

因此,在我创建补丁之前,我将这个文件(以及其他任何文件)添加到排除列表中:

[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.          

现在再次检查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:

现在创建补丁:
[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

现在您可以撤销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

注意:您的补丁还将从LFS中排除文件,因此您可能需要通过重置提交、编辑.gitattributes然后重新提交来修复该问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接