仅当没有其他提交更新由 cherry-picked 提交更新的文件时,如何进行 cherry-pick?

How to do cherry-pick only if no other commits update the files updated by the cherry-picked commit?

例如,考虑以下目录:

one
two
three

并且该目录具有以下提交历史和分支:

dev                           master
 |                              |
commit1 --> other commits --> commit-wanted

commit-wanted 更新文件 twothree.

签出 dev 分支后,我希望 commit-wanted 的 cherry-pick 只有在 commit1commit-wanted 之间的其他提交不更新 twothree 个文件。

可能吗?

如果存在合并冲突,

git cherry-pick 确实会失败(请参见下面的示例),但是如果您想要更保守的检查失败,即使可以合并对文件的更改,您也必须编写一个你自己。

打印提交所触及的文件名列表(参见):

git diff-tree --no-commit-id --name-only -r "$COMMIT"

打印一个范围内的提交列表(参见):

git rev-list dev..master

使用这两个命令,您应该能够将您想要的检查作为一个简单的脚本来实现。编写脚本留给 reader.

作为练习

合并冲突示例:

$ git init
Initialized empty Git repository in /home/user/tmp/.git/
$ printf '1\n2\n' > foo.txt
$ git add .
$ git commit -m 'Add foo.txt'
[master (root-commit) f41e149] Add foo.txt
 1 file changed, 2 insertions(+)
 create mode 100644 foo.txt
$ printf '1\n2\n3\n' > foo.txt
$ git add .
$ git commit -m 'Append a line'
[master ce20740] Append a line
 1 file changed, 1 insertion(+)
$ printf '1\n2\n3\n4\n' > foo.txt
$ git add .
$ git commit -m 'Append another line'
[master 9738459] Append another line
 1 file changed, 1 insertion(+)
$ git checkout -b dev HEAD^^
Switched to a new branch 'dev'
$ git cherry-pick master || printf 'git cherry-pick returned nonzero status\n'
Auto-merging foo.txt
CONFLICT (content): Merge conflict in foo.txt
error: could not apply 9738459... Append another line
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
git cherry-pick returned nonzero status
$ git cherry-pick --abort

其实你不需要git diff-treegit rev-list已经有了你需要的

git rev-list dev..master^ -- two three

-- 之后,您可以指定目标提交更改的文件。因此,此命令 returns dev(排除)和 master(排除)之间修改 twothree.

的所有提交

最终,您可以通过 运行 来自 dev 的简单命令来解决该问题:

test -z $(git rev-list dev..master^ -- two three) && git cherry-pick master