git format-patch是svn兼容的吗?


96

有什么办法可以使git format-patch创建的补丁与svn兼容,以便我可以将其提交给svn仓库?

我正在github上的一个svn存储库中,想将我的更改提交回主存储库。我需要创建一个补丁来执行此操作,但是由于git格式与svn的补丁方式不同,因此无法应用该补丁。有没有我尚未发现的秘密?

更新:尽管目前尚无脚本或本机git方法可以做到这一点,但我确实设法在今年早些时候找到了有关如何手动完成此操作的文章。我已经按照说明进行操作,并且成功获取了git补丁以使用svn。

如果有人可以通过编写脚本来完成此任务并为git项目做贡献,那么我将非常感谢每个人。

http://kerneltrap.org/mailarchive/git/2008/1/15/570308/thread#mid-570308


我无法正常工作...您能张贴所有需要的步骤吗?谢谢!
Mauricio Scheffer,2009年

1
嗨,安东尼。您是否考虑将已接受的答案更改为尼古拉斯的答案?
西蒙·伊斯特

我赞同西蒙的建议,将尼古拉斯·史密斯的答案作为公认的答案将使所有人受益,因为它更加实用。
Albireo 2014年

Answers:


90

我总是必须向Google提出此要求,但是我发现最适合我的方法是:

  • 使用来创建补丁git diff --no-prefix master..branch > somefile.diff,master和branch部分是可选的,取决于您如何获取差异。
  • 随时随地发送并申请patch -p0 < somefile.diff

对于我来说,它似乎总是运行良好,并且似乎是我遇到的最简单的方法。


1
这是使用Git生成SVN兼容补丁的规范方法。应该将其标记为答案。
mloskot 2014年

--no-pager不再是的选择git diff
naught101 '09

它最初发布时没有--no-pager,我不确定为什么要在编辑中添加它。--no-pager不管怎样,对我来说总是很好。
尼古拉斯·史密斯

2
仅针对特定的提交:git diff --no-prefix 056a1ba5140 7d939289b80 >my.patch为我工作(上一次的sha-1和git中的特定提交在此处056a1ba51407d939289b80)。
Ed Randall

@Lilás这是SVN的问题。SVN中的差异/补丁从未能够处理已删除的文件
Toofy


17

这是一个帮助脚本,用于与最新的svn变更集和给定的提交进行比较:http : //www.mail-archive.com/dev@trafficserver.apache.org/msg00864.html

#!/bin/sh
#
# git-svn-diff
# Generate an SVN-compatible diff against the tip of the tracking branch
TRACKING_BRANCH=`git config --get svn-remote.svn.fetch | sed -e 's/.*:refs\/remotes\///'`
REV=`git svn find-rev $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH)`
git diff --no-prefix $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH) $* |
sed -e "s/^+++ .*/&    (working copy)/" -e "s/^--- .*/&    (revision $REV)/" \
-e "s/^diff --git [^[:space:]]*/Index:/" \
-e "s/^index.*/===================================================================/"

1
我发现如果您不使用最新的svn修订版,则REV值不正确。我更正了它,改为使用git svn info这种方式: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin

1
这太棒了!非常感谢。我不得不做出一个改变,它的工作导入我的补丁到鱼眼镜头的坩埚中,这是一个标签,以取代之前的空间“(修订版”代替。
Zugwalt

10

SVN可能无法理解的输出git diff -p,但是您可以求助于蛮力:

  1. 为您的仓库制作两个副本
  2. 在一个克隆中查看您的最新资料
  3. 在另一个克隆检出中,等于上游的svn。如果您已预先计划,则可以在其自己的分支上拥有svn上游的副本,或者您已标记了最新的svn版本。如果您尚未提前计划,请使用date或gitk来找到最接近svn状态的git SHA1哈希。
  4. 现在,通过运行diff -r两个克隆来计算真实补丁。

12
或者只是按照@ Nicholas-smith的建议,git diff --no-prefix > somefile.diff在您的git repo中运行,并将其发送给任何svn用户,让他们patch -p0 < somefile.diff在项目根目录中应用补丁。
DavidG

10

Subversion <1.6没有补丁支持。看来Subversion 1.7将允许应用补丁,并且git / hg扩展名对统一差异位于我们的TODO列表中。


4

确实是2008年初的功能要求

莱纳斯·托瓦尔兹(Linus Torvalds)当时说:

因此,我认为您需要更强的说“不要做git diff”,这也应至少禁止重命名检测。
坦率地说,任何愚蠢的程序都不接受当前的git补丁(例如TortoiseSVN),那么我们该死的不应该只是禁用其中最琐碎的部分。我们应该确保不启用任何相当重要的扩展:
即使ToirtoiseSVN会忽略它们,即使忽略它们也意味着它误解了diff,则根本不应该允许它。

那可能就是为什么

 git-format-patch: add --no-binary to omit binary changes in the patch.

已于2008年5月/ 7月在Git1.5.6中引入(尽管我尚未对其进行测试)



0

Nicholas提供的公认答案很好用,除非a)diff中存在二进制文件或b)您在Windows Git中工作且目录中带有空格。为了解决这个问题,我必须添加一个嵌套的git diff命令来忽略二进制文件,并使用sed命令来转义空格。编写起来有点麻烦,所以我创建了一个别名:

[alias]
svnpatch = "!f() { git diff --name-only --no-prefix master...$1 | grep -Ev \"\\.sdf|\\.Doc|\\.dll|\\.zip|\\.exe\" | sed 's_\\s_\\\\\\\\ _g'  | xargs git diff --no-prefix master...$1 > $1.patch; echo "Created $1.patch"; }; f"

如果输入,请输入:

git svnpatch Feature123

...将创建一个补丁文件Feature123.patch,其中分支母版和分支Feature123的合并基础之间存在差异。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.