Git重新基址尝试重新基址在目标提交之前发生的提交
我运行了git-rebase-I。进行更改后,我运行了Git重新基址尝试重新基址在目标提交之前发生的提交,git,Git,我运行了git-rebase-I。进行更改后,我运行了git-rebase--continue。Git然后正确地重新设置了15次提交中的15次。成功执行此操作后,我收到以下错误: error: could not apply <bad hash>... <commit message> When you have resolved this problem, run "git rebase --continue". If you prefer to skip this
git-rebase--continue
。Git然后正确地重新设置了15次提交中的15次。成功执行此操作后,我收到以下错误:
error: could not apply <bad hash>... <commit message>
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply <bad hash>... <commit message>
错误:无法应用。。。
解决此问题后,运行“git-rebase--continue”。
如果您希望跳过此修补程序,请运行“git-rebase--skip”。
要签出原始分支并停止重定基址,请运行“git-rebase--abort”。
无法应用。。。
我检查了提交与坏散列相关的内容。我发现这个提交发生在目标哈希之前大约3个月。那么为什么git rebase甚至会涉及到这个提交呢?我认为rebase只针对当前提交到目标哈希的目标提交
有人知道问题是什么吗?我是否对rebase有一个根本性的误解,或者有什么冲突?TL;博士
如果没有实际的存储库,很难说清楚,但您可能会在合并过程中重定基址
长的
Rebase不查看提交日期。理解Git rebase(无论是否交互式)的关键在于:
- 了解树枝如何生长李>
- 理解git cherry pick
;及
查看(并在其中选择提交)提交图,尤其是可达性的概念
这些有点贵。关于可达性概念的介绍,请参阅
理解Git提交
让我们先来看看简单提交的剖析。这里有一个来自Git存储库的Git:
$ git rev-parse HEAD
5be1f00a9a701532232f57958efab4be8c959a29
$ git cat-file -p 5be1f00a9a701532232f57958efab4be8c959a29 | sed 's/@/ /'
tree 8ccb7d4fa49449a843b00aca64baf99feb10e2ab
parent e7e80778e705ea3f9332c634781d6d0f8c6eab64
author Junio C Hamano <gitster pobox.com> 1516742470 -0800
committer Junio C Hamano <gitster pobox.com> 1516742470 -0800
First batch after 2.16
Signed-off-by: Junio C Hamano <gitster pobox.com>
这个“最后一个”指针就是Git所称的分支(或者更准确地说,分支名称)。分支名称只存储一个特定Git提交的哈希ID:即位于分支顶端的哈希ID。(因此,我们称之为提示提交。)
要增长分支,如通过git commit
,git将首先创建新的commit,为其写出树
对象(找到树的散列),然后从已知数据创建其余的commit:树,存储在last one
中的当前commit散列,您作为作者和提交者(使用“now”作为时间戳),以及提交消息。此提交进入存储库,存储库生成一个新的唯一哈希ID
新提交N
指向分支的上一个提示:
...--o--o--o--o <-- last-one
\
N
(然后我们可以画出这个,而不需要末端的弯曲)
樱桃采摘:复制提交
虽然提交是快照,但我们通常喜欢将其视为更改。要将提交视为更改,我们只需先获取提交父级的快照,然后获取提交本身的快照,并进行比较:
git diff <parent> <child>
这就是cherry pick的作用:它具有复制提交的效果
重新定基
有几种不同的重定基址用例,但它们都基于一个基本思想:我们可以复制提交。当我们进行复制时,就在实际提交(只读提交)之前,我们可以更改有关新副本的某些内容
第一个常见的用例是移植一个分支。假设我们没有像上面那样绘制分支1和2,而是像下面这样绘制它们:
C--D <-- develop (HEAD)
/
...--A--B--E--F--G <-- master
现在,我们在这里选择C
,制作一份C'
副本,该副本位于G
之后,并更新tmp
以指向新副本:
C--D <-- develop
/
...--A--B--E--F--G <-- master
\
C' <-- tmp (HEAD)
最后,我们告诉Git将标签develope
从commitD
上剥下来,并将其粘贴到commitD'
上,当Git处于该状态时,也扔掉临时名称,并再次使develope
成为HEAD
:
C--D [abandoned]
/
...--A--B--E--F--G <-- master
\
C'-D' <-- develop (HEAD)
这里的目标
通常是另一个分支名称。例如,为了实现上面绘制的rebase,我们将签出develope
并运行git-rebase-master
。master
部分告诉Git从何处开始复制临时分支所在的位置,当临时分支建立时,一个提交一个提交。但是这里缺少了一些重要的东西:git rebase如何知道要复制哪个提交?
答案在于Git使用的更一般的技巧。您将经常看到并使用它,例如,与git log
:您告诉它从何处开始,也告诉它从何处停止。如果您通过提交散列ID来执行此操作,则可以编写如下内容:
git log master ^1234567
git log master..develop
它告诉它从master
的顶端开始,但当它到达commit1234567
时停止,不管那是什么。您可以将其改为:
git log 1234567..master
因为它们的意思是一样的:从master
的顶端开始;停止使用1234567
这里棘手的部分是Git不必直接遇到提交1234567
本身。“stop”指令在Git到达从停止点可以到达的任何提交时停止Git。这让我们可以写以下内容:
git log master ^1234567
git log master..develop
即使master
包含develope
不包含的提交
在我们的例子中,git-rebase
使用这个双点符号将提交B
和更早的提交从复制过程中排除。(隐藏起来要复杂得多,但这一切都源于这个想法。)也就是说,我们让Git使用一个名称,master
,来选择要复制的内容和放置副本的位置:副本按照当前提示的master
,并复制可从HEAD
访问的提交,但无法从主机的顶端访问
如果有必要,您可以将这两部分分开,有时也是必要的:您可以使用git-rebase--on
来表示副本应该在target
标识的提交之后进行,但是在提交时停止停止时(或者从该点可以到达)应该从头部进行提交。这使您可以使用以下图形:
C--D <-- important-fix
/
A--B--E <-- feature1
/
...--o--F--G--H--I <-- mainline
Git将在HEAD
akagit checkout <somebranch> # first, ensure your HEAD is attached
git rebase <target> # then do the rebase-by-copy thing
git log master ^1234567
git log 1234567..master
git log master..develop
C--D <-- important-fix
/
A--B--E <-- feature1
/
...--o--F--G--H--I <-- mainline
$ git checkout important-fix
$ git rebase --onto mainline feature1
C--D [abandoned]
/
A--B--E <-- feature1
/
...--o--F--G--H--I <-- mainline
\
C'-D' <-- important-fix
D--E
/ \
A--B G--H <-- feature
/ \ /
/ C--F
/
...--o--o--o--o <-- mainline
D--E
/ \
A--B G--H [abandoned]
/ \ /
/ C--F
/
...--o--o--o--o <-- mainline
\
A'-B'-D'-E'-C'-F'-H' <-- feature
...--o--A--B--C---F--G <-- branch (HEAD)
\ /
D--E