从当前工作目录中的更改创建一个git补丁

vri*_*h88 789 git git-patch

假设我的工作目录中有未提交的更改.如何在不必创建提交的情况下从那些补丁中创建补丁?

jca*_*llo 1690

如果您尚未提交更改,则:

git diff > mypatch.patch
Run Code Online (Sandbox Code Playgroud)

但有时候你正在做的部分事情是新文件,这些文件是未跟踪的,不会出现在你的git diff输出中.因此,执行补丁的一种方法是为新提交暂存所有内容(但不执行提交),然后:

git diff --cached > mypatch.patch
Run Code Online (Sandbox Code Playgroud)

如果要将二进制文件添加到补丁(例如mp3文件),请添加"二进制"选项:

git diff --cached --binary > mypatch.patch
Run Code Online (Sandbox Code Playgroud)

您可以稍后应用补丁:

git apply mypatch.patch
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你的例子.与已接受的答案相反,您会显示命令如何执行而不仅仅是说话.非常有帮助,为我工作完美:) (112认同)
  • @Vitaly:如果用文本编辑器打开它,你的补丁是否可读?它应该是干净的,没有奇怪的字符,例如,如果设置了color.diff设置,你的补丁会有一些'颜色字符',可以使'git apply'失败,在这种情况下尝试`git diff --no-color` .否则,它看起来像编码问题. (6认同)
  • 这让我从一个奇怪的合并/ rebase地狱很容易,谢谢:) (5认同)
  • 我完成了那个并且在执行git apply时得到了"致命的:无法识别的输入".知道什么可以导致这个以及如何解决它? (4认同)
  • 与"未跟踪的新文件"相关:"git diff"和"git diff --cached"仅在首先调用"git add <file>"时才有效.(我是git的新手,想知道为什么我每次都得到一个空的补丁) (3认同)
  • 要从已经暂存的更改中创建补丁,您还可以执行 `git diff --staged &gt; mypatch.patch`,因为 `--staged` 是 `--cached` 的同义词。我觉得更容易记住。 (2认同)

sig*_*ice 363

git diff对于未分级的更改. git diff --cached分阶段的变化.

  • Terse接近讽刺,下面的答案更有帮助. (131认同)
  • `git format-patch`还包括二进制差异和一些元信息.实际上,这将是创建补丁的最佳选择,但是afaik这仅适用于已签入的源/更改,对吧? (32认同)
  • git diff> a.patch将其写入文件 (27认同)
  • 有时,相对于当前目录创建补丁可能很有用.要实现这一点,请使用`git diff --relative` (20认同)
  • 是的,git diff是git apply的反转 (12认同)
  • 这不是很有帮助.`git diff`不会创建补丁,它只显示更改.以下答案实际上回答了问题. (4认同)

Mer*_*ham 80

git diff并将git apply用于文本文件,但不适用于二进制文件.

您可以轻松创建完整的二进制补丁,但您必须创建临时提交.完成临时提交后,可以使用以下命令创建补丁:

git format-patch <options...>
Run Code Online (Sandbox Code Playgroud)

制作补丁后,运行以下命令:

git reset --mixed <SHA of commit *before* your working-changes commit(s)>
Run Code Online (Sandbox Code Playgroud)

这将回滚您的临时提交.最终结果会使您的工作副本(故意)变脏,并使用您最初的相同更改.

在接收方,您可以使用相同的技巧将更改应用于工作副本,而无需提交历史记录.只需应用补丁,和git reset --mixed <SHA of commit *before* the patches>.

请注意,您可能必须完全同步才能使整个选项生效.我在应用补丁程序时看到了一些错误,因为制作它们的人并没有像我那样有太多的变化.可能有办法让它发挥作用,但我没有深入研究它.


以下是如何在Tortoise Git中创建相同的补丁(不是我建议使用该工具):

  1. 提交您的工作变更
  2. 右键单击分支根目录,然后单击Tortoise Git- >Create Patch Serial
    1. 可以任意选择范围是有道理的(Since:FETCH_HEAD将工作,如果你是良好的同步)
    2. 创建补丁
  3. 右键单击分支根目录,然后单击Tortise Git- >Show Log
  4. 临时提交之前右键单击提交,然后单击reset "<branch>" to this...
  5. 选择Mixed选项

以及如何应用它们:

  1. 右键单击分支根目录,然后单击Tortoise Git- >Apply Patch Serial
  2. 选择正确的补丁并应用它们
  3. 右键单击分支根目录,然后单击Tortise Git- >Show Log
  4. 在修补程序的提交之前右键单击提交,然后单击reset "<branch>" to this...
  5. 选择Mixed选项

  • 从技术上讲,这确实需要创建OP要求避免的提交,但这是一个临时的提交,无论如何答案都是有用的. (5认同)

小智 30

要创建包含已修改和新文件(暂存)的修补程序,您可以运行:

git diff HEAD > file_name.patch
Run Code Online (Sandbox Code Playgroud)


Eug*_*kov 11

我喜欢:

git format-patch HEAD~<N>
Run Code Online (Sandbox Code Playgroud)

哪里<N>是保存为补丁的最后提交次数。

有关如何使用该命令的详细信息,请参见DOC。

UPD
在这里,您可以找到如何应用它们。

UPD对于那些不了解format-patch
添加别名的人:

git config --global alias.make-patch '!bash -c "cd ${GIT_PREFIX};git add .;git commit -m ''uncommited''; git format-patch HEAD~1; git reset HEAD~1"'
Run Code Online (Sandbox Code Playgroud)

然后在项目存储库的任何目录下运行:

git make-patch
Run Code Online (Sandbox Code Playgroud)

该命令将0001-uncommited.patch在您当前的目录中创建。修补程序将包含所有更改和未跟踪的文件,这些内容和下一条命令可见:

git status .
Run Code Online (Sandbox Code Playgroud)

  • 有一种比创建提交和取消提交更简单的方法。git diff --cached --binary (2认同)

小智 9

如果要执行二进制,请--binary在运行时提供选项git diff.


Ans*_*mar 5

我们也可以指定文件,只包含有相对变化的文件,特别是当它们跨越多个目录时,例如

git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch
Run Code Online (Sandbox Code Playgroud)

我发现答案或评论中没有说明这一点,这些都是相关且正确的,所以选择添加它。显式优于隐式!