从当前工作目录中未提交的更改创建git补丁

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

722796 次浏览

git diff表示未暂存的更改。

git diff --cached用于分阶段更改。

git diff HEAD用于分阶段和未分阶段的更改。

git diffgit apply将适用于文本文件,但不适用于二进制文件。

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

git format-patch <options...>

完成补丁后,运行以下命令:

git reset --mixed <SHA of commit *before* your working-changes commit(s)>

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

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

请注意,您可能需要很好地同步才能使整个选项起作用。当制作补丁的人没有像我一样下拉那么多更改时,我在应用补丁时看到了一些错误。可能有方法可以让它起作用,但我还没有深入研究。


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

  1. 提交您的工作更改
  2. 右键单击分支根目录并单击Tortoise Git->Create Patch Serial
    1. 选择任何有意义的范围(SinceFETCH_HEAD将工作,如果你是同步良好)
    2. 创建补丁(es)
  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选项

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

如果您还没有提交更改,那么:

git diff > mypatch.patch

但有时会发生这样的情况,即您正在做的部分工作是未跟踪的新文件,并且不会出现在git diff输出中。因此,做补丁的一种方法是为新提交暂存所有内容(每个文件git add,或者只是git add .),但不做提交,然后:

git diff --cached > mypatch.patch

如果您想将二进制文件添加到补丁(例如mp3文件),请添加“二进制”选项:

git diff --cached --binary > mypatch.patch

您可以稍后应用补丁:

git apply mypatch.patch

要创建包含修改和新文件(分阶段)的补丁,您可以运行:

git diff HEAD > file_name.patch

我喜欢:

git format-patch HEAD~<N>

其中<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"'

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

git make-patch

此命令将在您当前的目录中创建0001-uncommited.patch。补丁将包含下一个命令可见的所有更改和未跟踪的文件:

git status .

我们还可以指定文件,仅包括具有相对更改的文件,特别是当它们跨越多个目录例如。

git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch

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

未粉碎

git diff --cached > name.patch

承诺(更有用)

git diff HEAD~commit_count > name.patch