假设我的工作目录中有未提交的更改。我怎样才能在不创建提交的情况下从这些补丁中制作补丁?
7 回答
如果您尚未提交更改,则:
git diff > mypatch.patch
但有时您正在做的部分事情是未跟踪的新文件,不会出现在您的git diff
输出中。因此,进行补丁的一种方法是为新提交(git add
每个文件或只是git add .
)暂存所有内容,但不进行提交,然后:
git diff --cached > mypatch.patch
如果您想将二进制文件添加到补丁中(例如 mp3 文件),请添加 'binary' 选项:
git diff --cached --binary > mypatch.patch
您可以稍后应用补丁:
git apply mypatch.patch
git diff
对于未分阶段的更改。
git diff --cached
对于分阶段的变化。
git diff HEAD
对于分阶段和非分阶段的更改。
git diff
并且git 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 中创建相同补丁的方法(我不建议使用该工具):
- 提交您的工作变更
- 右键单击分支根目录,然后单击
Tortoise Git
->Create Patch Serial
- 选择任何有意义的范围(
Since
:FETCH_HEAD
如果您同步良好,则可以使用) - 创建补丁
- 选择任何有意义的范围(
- 右键单击分支根目录,然后单击
Tortise Git
->Show Log
- 右键单击临时提交之前的提交,然后单击
reset "<branch>" to this...
- 选择
Mixed
选项
以及如何应用它们:
- 右键单击分支根目录,然后单击
Tortoise Git
->Apply Patch Serial
- 选择正确的补丁并应用它们
- 右键单击分支根目录,然后单击
Tortise Git
->Show Log
- 右键单击补丁提交之前的提交,然后单击
reset "<branch>" to this...
- 选择
Mixed
选项
要使用修改过的文件和新文件(暂存)创建补丁,您可以运行:
git diff HEAD > file_name.patch
我喜欢:
git format-patch HEAD~<N>
其中<N>
是最后一次提交的数量以保存为补丁。
如何使用该命令的详细信息在文档中
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 .
如果要执行二进制,--binary
请在运行时给出一个选项git diff
。
我们还可以指定文件,以仅包含具有相对更改的文件,特别是当它们跨越多个目录时
git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch
我发现答案或评论中没有指定这一点,这些都是相关且正确的,因此选择添加它。显式比隐式好!