Git 让樱桃摘不带来历史
所以我遇到了git的一个问题,当我重新设置基址或选择一个特定的提交时,我将获得比该特定提交更多的信息。这个问题在这里被很好地概括了: 这一切都很好,我明白这是在重温历史,因为我想要的承诺取决于历史的存在。我不明白的是如何避开它。我真的不希望cherry pick应用所有这些历史,我更希望它利用这些历史来找出这些线应该走到哪里,然后提出一个冲突,说它必须做一些可疑的事情才能使其适合 我有什么办法可以这样做吗?我找到的唯一方法是,我可以从提交中制作一个补丁并应用补丁,但我真的希望能够对我的树使用cherry pick和rebase 为了说明我的示例,您可以在空目录中对git存储库进行反斜体化,然后向存储库中添加一行文本文件。然后在3个单独的提交中再向文件添加3行,这样您的文件中将有4个提交和4行。我的文件看起来像:Git 让樱桃摘不带来历史,git,git-merge,git-rebase,Git,Git Merge,Git Rebase,所以我遇到了git的一个问题,当我重新设置基址或选择一个特定的提交时,我将获得比该特定提交更多的信息。这个问题在这里被很好地概括了: 这一切都很好,我明白这是在重温历史,因为我想要的承诺取决于历史的存在。我不明白的是如何避开它。我真的不希望cherry pick应用所有这些历史,我更希望它利用这些历史来找出这些线应该走到哪里,然后提出一个冲突,说它必须做一些可疑的事情才能使其适合 我有什么办法可以这样做吗?我找到的唯一方法是,我可以从提交中制作一个补丁并应用补丁,但我真的希望能够对我的树使用c
line 1
line 2
line 3
line 4
现在执行git checkout HEAD~3,这样您只有
line 1
然后打电话给git cherry pick HEAD,你会遇到冲突。我在上面发布的链接中概述了为什么会发生这种情况。您的文件将如下所示:
line 1
<<<<<<< HEAD
=======
line 2
line 3
line 4
>>>>>>> 6fe905b... Commit 4
第1行
>6fe905b。。。承诺4
但这是不好的,因为如果在一个真实的例子中出现这种情况,您的合并冲突会说Commit 4比Commit 4中实际包含的内容多得多。那么,我有没有办法修复它,这样cherry pick会给我一个更符合逻辑的合并冲突?在我即将出版的现实世界中,它发生在我做重基的时候。如果我可以为cherry pick解决这个问题,那么我的逻辑是,这一问题的根本原因也应该为rebase解决。运行
git rebase
和git cherry pick
的结果通常不相同
运行git-rebase
通常会重写历史记录,并且可能会出现移动整个分支的情况。这很可能是你所看到的不受欢迎的历史的根源
相反,git cherry pick
重放存储库历史记录中其他地方的一个或多个提交的增量。典型的用例是选择一个提交来创建另一个新的提交。我需要了解有关您正在运行的命令的更多具体信息,以了解您对结果的失望程度
将多提交主题分支压缩为单个提交的有用命令是
git merge--squash
。另一种选择是一个重基,然后是另一个交互式重基。[注:编辑以添加diff3
,重新编辑问题的最新编辑;请参阅最下面的部分]
cherry pick
命令将提交ID列表作为其参数:
git cherry pick[--edit][n][m父编号][s][x][--ff]
但你说你正在使用:
git cherry-pick branch-name commit-hash
这意味着您要让git挑选两个樱桃:一个是与命名分支的尖端相关联的樱桃(分支名称解析为SHA-1 ID),另一个是与给定的提交哈希相关联的樱桃
换句话说,请先运行以下命令:
git rev-list --no-walk branch-name commit-hash
rev list
的输出实际上是cherry pick
所看到的
git-rebase
做的事情比git-cherry-pick
更广泛。通常,人们通过运行此命令将“分支臂”(这是我刚刚编的一个术语)从一个点移动到另一个点:
A - B - C - D - E <-- origin/master
\
K - L <-- local
(然后您环顾四周,看到提交的D
和E
,因此您希望将您的本地主机更新为最新版本):
(本地主机现在是最新的,现在您决定重新设置分支local
):
Rebase基本上是一种自动化的“反复挑选直到完成,然后更改分支标签”操作。给定我在上面绘制的提交图,它首先执行一个分离的-HEAD
git checkout
以获得提交E
,然后执行提交K
的git cherry pick
,重复提交L
,并且(如果一切顺利)最后调整本地分支标签local
,以指向新提交的最后一个分支:
[开始]
A - B - C - D - E <-- master, origin/master
\
K - L <-- HEAD=local
[第二步,选择一份L
,给出:]
A - B - C - D - E <-- master, origin/master
\ \
\ K' <-- HEAD [detached]
\
K - L <-- local
A - B - C - D - E <-- master, origin/master
\ \
\ K'-L' <-- HEAD [detached]
\
K - L <-- local
A - B - C - D - E <-- master, origin/master
\ \
\ K'-L' <-- HEAD=local
\
K - L <-- [no label, abandoned]
有些人喜欢diff3
风格,足以git config--global
(我自己也在考虑:-)。我添加了一些信息。我看到的问题是樱桃采摘和重基,发生的方式完全相同。它是一个单独的文件,它得到的更改比你从一个樱桃采摘中所期望的要多。Rebase对那个单独的文件也会有同样的效果。这个答案很棒,但它并没有完全解决我的问题,尽管我感谢你们在cherry pick和Rebase上提供了一些不错的外卖。我在我的问题中添加了更多的信息来更好地说明我的问题,我想我很难表达我的问题。除非你说的是我不能做我想做的事,那就是认真选择我的承诺,不要让冲突看起来有误导性。这让我的冲突更具可读性。对于加分,我有没有办法设置它,以便它能够自动解决这些冲突?如中所示,添加cherry picked commit与其父级之间的差异,以便得到第1行\n第4行的结果?不,这对git来说太难了,它确实希望看到相同的上下文。在其他一些情况下,使用patience
合并策略会有所帮助(但不是此特定策略)。重新编辑:您可能希望将merge.conflictstyle
设置为diff3
。
A - B - C - D - E <-- master, origin/master
\ \
\ K' <-- HEAD [detached]
\
K - L <-- local
A - B - C - D - E <-- master, origin/master
\ \
\ K'-L' <-- HEAD [detached]
\
K - L <-- local
A - B - C - D - E <-- master, origin/master
\ \
\ K'-L' <-- HEAD=local
\
K - L <-- [no label, abandoned]
$ echo 'line 1' > file && git add file && git commit -m 'add file with 1 line'
[master 72f46c5] add file with 1 line
1 file changed, 1 insertion(+)
create mode 100644 file
$ echo 'line 2' >> file && git add file && git commit -m 'add line 2'
[master 134cdd1] add line 2
1 file changed, 1 insertion(+)
$ echo 'line 3' >> file && git add file && git commit -m 'add line 3'
[master e8634fc] add line 3
1 file changed, 1 insertion(+)
$ echo 'line 4' >> file && git add file && git commit -m 'add line 4'
[master 50810b6] add line 4
1 file changed, 1 insertion(+)
$ git checkout master~3
...
HEAD is now at 72f46c5... add file with 1 line
$ git config merge.conflictstyle diff3
$ git cherry-pick master
error: could not apply 50810b6... add line 4
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'
$ cat file
line 1
<<<<<<< HEAD
||||||| parent of 50810b6... add line 4
line 2
line 3
=======
line 2
line 3
line 4
>>>>>>> 50810b6... add line 4