使git format-patch遵循git log --follow之类的重命名 [英] Making git format-patch follow renames like git log --follow

查看:179
本文介绍了使git format-patch遵循git log --follow之类的重命名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将文件从一个本地 git存储库移动到另一个项目的另一个本地git存储库,同时保留原始存储库中的历史记录.到目前为止,如果文件从未在源存储库中移动或重命名,则可以正常工作:

I am trying to move files from one local git repository to another local git repository for a different project while preserving history from the original repository. So far I have this, which is working fine if the file was never moved or renamed in the source repo:

# Executed from a directory in the target repository
( cd $SOURCE_REPOSITORY_DIRECTORY && git format-patch -B -M --stdout --root $SOURCE_FILENAME) | git am --committer-date-is-author-date

之所以起作用,是因为两个存储库的目录结构相同.如果它们不同,则必须创建补丁文件并使用sed之类的东西来修复目录名称.

This happens to work because the directory structures of the two repositories are the same. If they were different, I'd have to create patch files and fix up the directory names using sed or something.

无论如何,一切都变了,直到我点击了一个已重命名的文件.即使我指定了-B -M(并与-B -M -C --find-copies-harder取得了相同的结果),即使文件已经干净地移动(相似性索引为100%),我也没有从移动之前得到补丁.

Anyway, this is all swell until I hit a file that has been renamed. Even though I'm specifying the -B -M (and get the same results with -B -M -C --find-copies-harder) I do not get the patches from before the move, even though the file was cleanly moved (similarity index 100%).

这特别奇怪,因为git log --follow显示了所有提交,而git log --follow -p提供了所有差异.除非它以相反的顺序提供它们,所以我不能将它们输入到git am中.

This is particularly odd since git log --follow shows all the commits and git log --follow -p provides all the diffs. Except it provides them in reverse order so I cannot feed them into git am.

还请注意,git log --follow -p filename会显示以下补丁"以显示重命名:

Note also that git log --follow -p filename puts out the following "patch" to show the rename:

diff --git a/old_dir_name/dir1/dir2/filename b/new_dir_name/dir0/dir1/dir2/filename
similarity index 100%
rename from old_dir_name/dir1/dir2/filename
rename to new_dir_name/dir0/dir1/dir2/filename

现在,如果git log以正确的格式和正确的顺序显示补丁,以供git am应用,我可以使用它,但事实并非如此.使用git log --reverse --follow -p filename仅输出名称更改补丁,没有其他输出.

Now if git log would display the patches in the right format and right order for git am to apply them, I could just use that, but such is not the case. Using git log --reverse --follow -p filename only outputs the name change patch, nothing else.

因此,我如何才能真正遵循git format-patch重命名帮助文件/手册页所说的方式,而同时仅输出单个文件的补丁?我可以得到git log -p生成补丁的方式,可以将它们输入到git am中以重新创建具有历史记录的文件吗?

So, how do I get git format-patch to really follow renames the way the help file/man page says it should while at the same time only outputting patches for a single file? Alternately, how do I get git log -p to produce patches in a way I can feed them into git am to recreate a file with history?

我正在使用git版本1.8.4.3.

I'm using git version 1.8.4.3.

推荐答案

我最近遇到了与该问题相同的用例,并且我使用Bash实现了一个解决方案,因此我想与之分享,因为此代码可能对其他人.

I was recently faced with the same use case as this question and I implemented a solution using Bash, so I wanted to share it as this code could be useful for other people.

它包含一个脚本git-format-patch-follow https://github.com/erikmd/git-scripts ,可以按以下方式使用对于OP的问题:

It consists of a script git-format-patch-follow available on https://github.com/erikmd/git-scripts, which can be used as follows for the OP's question:

( cd "$SOURCE_REPOSITORY_DIRECTORY" && git format-patch-follow -B -M --stdout --root --follow -- "$SOURCE_FILENAME" ) | git am --committer-date-is-author-date

通常,语法为:

git format-patch-follow <options/revisions...> --follow -- <paths...>

因此,可以将这种Bash脚本视为运行@OldPro概述的算法的自动方式,我特别注意应对极端情况,例如带空格的文件名,在CLI上传递的多个文件或运行Git源仓库子目录中的脚本.

This Bash script can thus be viewed as an automated way to run the algorithm outlined by @OldPro, and I took special care to cope with corner cases, such as filenames with whitespace, multiples files passed on the CLI, or running the script from a sub-directory of the Git source repo.

最后,按照此博客文章,只要将这样的脚本放在一个PATH中,Git就可以像git子命令git format-patch-follow一样集成该脚本.

Finally as pointed by this blog post, it suffices to put such a script in one's PATH for Git to integrate the script like a git subcommand git format-patch-follow.

免责声明: git format-patch,从而git-format-patch-follow

Disclaimer: git format-patch, and thereby git-format-patch-follow, can't be applied to a non-linear history (involving merge commits).

这篇关于使git format-patch遵循git log --follow之类的重命名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆