我正在开发一个使用git svn
从SVN仓库中提取的Git仓库。许多月前,SVN repo是从原始(上游)项目的源tarball创建的。原始项目具有如下文件结构:
/
COPYING
README
src/
...many source files...
然而,当创建SVN repo时,README文件等被剥离,并且以src/
为根创建了应用程序,因此repo现在看起来像:
/
...many source files
我最近将这个SVN repo转换为Git仓库。原始项目也在Git仓库中,我想开始跟踪上游更改,以便我可以轻松查看已进行的自定义更改(并将修补程序提交回原始项目,如果适用)。我在上游回购中找到了我们的SVN repo创建的提交,所以现在我想将我们的更改应用于该提交(在分支中)。我可以使用git format-patch
轻松创建一组补丁,并将它们应用于克隆的上游repo ...除了文件结构不同,因此补丁不再指向正确的文件。有没有办法将补丁从git format-patch
应用到克隆仓库中的src/
目录? (请注意,Git补丁也有必要的信息,如原始作者姓名,电子邮件和日期,我也想申请,而不必手动,即通过弄乱GIT_AUTHOR_EMAIL
,等)
答案 0 :(得分:6)
在我看来,您应该能够使用git filter-branch
来更改先前克隆的SVN仓库中的路径。然后,在更新所有文件路径之后,您现在可以使用git format-patch
创建将应用于新克隆的上游存储库的补丁。
尝试:
git filter-branch --tree-filter 'mkdir src; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files src'
答案 1 :(得分:3)
我最近遇到了类似的问题。我的解决方案是创建一个带有src
子目录的新目标存储库,然后在源存储库中创建了一组补丁:
/data/source-repository$ git format-patch -k --root
然后将这些补丁应用于目标存储库中的src
目录:
/data/target-repository$ git am -k --committer-date-is-author-date --directory src ../source-repository/*.patch
源存储库中的所有补丁都以目标存储库中的src
结束,即所有路径都相应地进行了调整。
从那里你可以再次创建补丁并将它们导入分支内的上游存储库。
答案 2 :(得分:2)
我必须做一次非常相似的事情,不是很漂亮,但它是可以管理的。我最终做的是:
git format-patch <commitish> --stdout > patches-for-upstream.mbox
$EDITOR patches-for-upstream.mbox
在编辑器中,我查看了哪些位是常见的并且需要更改以使“git am”做我想要的。在每次提交中,每个文件都提交了三行:
diff --git a/path/to/file b/path/to/file
--- a/path/to/file
+++ b/path/to/file
此时编辑器需要做的是通过这些行并进行必要的更改,以便将所有修补程序应用于其他Git存储库。
我在Vim中使用了三个快速输入的宏YMMV。有点像:
diff --git a/
a
b/
后转到斜杠(从a
文件转到下一个空格,然后/
)---
)a/
+++
)b/
重复直到文件完成。在Vim中,只需将其放入宏(qq<long string of commands>q
),尝试一次(@q
),然后对整个文件(999@q
)执行此操作。
保存文件,进入其他Git仓库,然后尝试git am
。