如何将 git 补丁从一个存储库应用到另一个存储库?
我有两个存储库,一个是库的主存储库,另一个是使用该库的项目。
如果我在从属项目中进行修复,我想要一种简单的方法来将该补丁应用回上游。
该文件在每个存储库中的位置都不同。
- 主要仓库:
www.playdar.org/static/playdar.js
- 项目:
playlick.com/ lib/playdar.js
我尝试在 playlick 项目上使用 git format-patch -- lib/playdar.js
,然后 git am
在主 playdar 存储库上,但补丁文件中的不同文件位置引发了错误。
有没有一种简单的方法可以将给定文件上的给定提交的补丁应用到其他地方的另一个任意文件?
为了加分,如果您要应用补丁的文件不在 git 存储库中怎么办?
I have two repositories, one is the main repo for a library, and the other is a project using that library.
If I make a fix to the in the subservient project, I'd like an easy way to apply that patch back upstream.
The file's location is different in each repository.
- Main repo:
www.playdar.org/static/playdar.js
- Project:
playlick.com/lib/playdar.js
I tried using git format-patch -- lib/playdar.js
on the playlick project, and then git am
on the main playdar repo, but the differing file locations in the patch file raised an error.
Is there an easy way to apply the patch from a given commit on a given file to another arbitrary file elsewhere?
For bonus points, what if the file you want to apply the patch to isn't in a git repository?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果手动编辑补丁文件是不可能或不可行的,可以使用标准选项来完成(在
git apply
、git format-patch
和 GNU中提供)补丁
)。-p
从补丁中的路径中删除n
个前导目录。处理
-p
后,--directory=
在应用之前将root
附加到补丁中的每个路径。因此,对于您的示例
,要获取最初位于
static/playdar.js
上的补丁并将其应用到lib/playdar.js
,您将运行:If manually editing the patch file is out of the question or infeasible, this can be done with standard options (available in
git apply
,git format-patch
and GNUpatch
).-p<n>
removesn
leading directories from the paths in the patch.After processing
-p
,--directory=<root>
prependsroot
to each of the paths in the patch before applying.Example
So, for your example, to take a patch that was originally on
static/playdar.js
and apply it tolib/playdar.js
, you would run:由 git format-patch 生成的补丁只是一个文本文件——您可以编辑 diff 标头,以便它修改不同的路径。
例如,它会生成如下内容:
您所要做的就是将
lib/playdar.js
更改为static/playdar.js
,然后通过 < code>git am"对于没有
git
的人来说,标准 GNU 补丁实用程序应该可以读取该补丁——但不运行format-patch< /code> 与
-M
、-C
等选项在这种情况下生成重命名补丁,因为对它们的支持并不通用。The patch produced by
git format-patch
is simply a text file-- you can edit the diff headers so that it modifies a different path.So for instance it would have produced something like this:
All you have to do is change
lib/playdar.js
tostatic/playdar.js
and then run the patch throughgit am"
The patch should be readable by the standard GNU patch utility for people who don't have
git
--- but don't runformat-patch
with the-M
,-C
etc. options to produce rename patches in that case, because the support for them isn't universal.使用
format-patch
的--relative
选项可以改进抽象(隐藏有关生成补丁的存储库的不相关详细信息)。我发现应用补丁时需要使用
--3way
选项(以避免索引中不存在
错误)——您的情况可能会有所不同。 仅当您的目标路径不是存储库的根目录时才需要使用--directory=(...)
。format-patch
将从“base”开始每次提交到当前分支创建一个补丁文件。--relative
选项的文档似乎在某些情况下丢失,但它似乎无论如何都可以工作(从版本 2.7.4 开始)。Using the
--relative
option toformat-patch
can improve the abstraction (hide irrelevant details about the repository from which the patch was generated).I have found the
--3way
option to be required when applying the patch (to avoiddoes not exist in index
error) -- your mileage may vary. Using--directory=(...)
is likely only necessary if your target path is not the root of the repository.format-patch
will create one patch file per commit to the current branch since 'base'.The documentation for the
--relative
option seems to be missing in some cases, but it appears to work anyway (as of version 2.7.4).假设这两个项目都是 git 项目,听起来 子模块 将非常适合你。 这允许一个 git 项目动态链接到另一个 git 项目,本质上是在另一个 git 存储库中烘焙一个 git 存储库,两者都有自己独特的生命周期。
换句话说,将“main repo”添加为“project”中的子模块。 每当您在“主存储库”中提交/推送新内容时,您只需
git pull
它们回到“项目”中。Assuming both projects are git projects, it sounds like that submodules would be the perfect fit for you. This allows a git project dynamically link to another git project, essentially baking a git repo right inside another git repo, both having their own distinct lives.
In other words, add "main repo" as a submodule in "project". Whenever you commit/push new stuff in "main repo", you just
git pull
them back into "project".完成Henrik的回答,并获取奖励积分
如果您有权访问来自 git 存储库的补丁的候选文件的目录,您可以首先将该目录/文件树转换为 git 存储库本身! (“
git init
”:git 存储库毕竟只是根目录中的 .git)。然后,您可以将该存储库设置为主项目的子模块。
To complete Henrik's answer, and to go for the bonus point
If you have access to the directories of the file candidate for a patch coming from a git repository, you could first transform that tree of directories/files into a git repository itself! ('
git init
': a git repository is just a .git within a root directory after all).Then you would set that repo as a submodule for your main project.
您可以添加一个新的遥控器并从中拉出。 包含详细信息的文章。
You can add a new remote and pull from it. Article with details.
您可以暂时删除(重命名)主存储库。
You can just remove (rename) temporarily the main repository.