如何在一组Git补丁中修改文件路径?

时间:2010-07-29 21:52:23

标签: git

我正在开发一个使用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,等)

3 个答案:

答案 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