仅当没有其他提交更新由 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
更新文件 two
和 three
.
签出 dev
分支后,我希望 commit-wanted
的 cherry-pick 只有在 commit1
和 commit-wanted
之间的其他提交不更新 two
和 three
个文件。
可能吗?
如果存在合并冲突,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-tree
,git rev-list
已经有了你需要的
git rev-list dev..master^ -- two three
在 --
之后,您可以指定目标提交更改的文件。因此,此命令 returns dev
(排除)和 master
(排除)之间修改 two
或 three
.
的所有提交
最终,您可以通过 运行 来自 dev
的简单命令来解决该问题:
test -z $(git rev-list dev..master^ -- two three) && git cherry-pick master
例如,考虑以下目录:
one
two
three
并且该目录具有以下提交历史和分支:
dev master
| |
commit1 --> other commits --> commit-wanted
commit-wanted
更新文件 two
和 three
.
签出 dev
分支后,我希望 commit-wanted
的 cherry-pick 只有在 commit1
和 commit-wanted
之间的其他提交不更新 two
和 three
个文件。
可能吗?
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-tree
,git rev-list
已经有了你需要的
git rev-list dev..master^ -- two three
在 --
之后,您可以指定目标提交更改的文件。因此,此命令 returns dev
(排除)和 master
(排除)之间修改 two
或 three
.
最终,您可以通过 运行 来自 dev
的简单命令来解决该问题:
test -z $(git rev-list dev..master^ -- two three) && git cherry-pick master