我有这个项目,远程仓库有主要的开发分支,我有一个包含实验分支的分支.rebase
在推到我的前叉之前,我需要从开发分支更改为我的实验分支.它就像:
git checkout experimentalbranch
git fetch remoterepo
git rebase remoterepo/developmentbranch
Run Code Online (Sandbox Code Playgroud)
到这个时候,我遇到了冲突.但是,我不熟悉任何这些变化(我正在改变几周的变化,因为他们没有立即合并我的更改).而且,这是我第一次这样做rebase
.我比较习惯merge
.
在meld中,它通常就像<<LOCAL||REMOTE>>
是merge
,听起来非常直观.但在rebase
,它是<<HEAD||COMMIT MESSAGE>>
.是谁HEAD
?它是HEAD
开发分支吗?它是开发分支或其他地方的最新代码吗?
tor*_*rek 83
从根本上说,整个事情至少有点令人困惑,因为Git让它的内部工作能够直接显示给你.
请注意,我们在这里关注的情况发生在您运行时:
git checkout somebranch; git rebase origin/their-branch
Run Code Online (Sandbox Code Playgroud)
或类似的.rebase暂时停止以强制您解决合并冲突,之后您应该git add
解决冲突并运行git rebase --continue
.(如果你使用一些合并工具git mergetool
或一个花哨的GUI界面,那个界面可能会以某种其他方式为你做一些或所有这些,但在下面,它是git add
解析后的文件并运行git rebase --continue
.)
在一开始,HEAD
承诺为他们的分支,所以,如果你使用git checkout --ours
或git checkout --theirs
,--ours
意味着他们 -the最终提交的origin/their-branch
-while --theirs
意味着你的,第一次提交你基础重建.这是Git每天正常的混乱(请参阅git 中"我们的"和"他们的"的确切含义是什么?)并不是导致原始问题的原因.
然而,后来,HEAD
提交实际上是一种混合.这是在最新提交时复制一些提交的结果.您现在正在使用自己部分构建的新系列提交与您自己的原始提交之间发生冲突.这种冲突的根源通常是"他们"所做的事情(在此过程中发生了变化origin/their-branch
).您仍然需要解决此冲突.当你这样做时,你可能会看到在以后的提交中再次出现相同的冲突.
此外,HEAD
或local
或者--ours
是提交的是重订已结合你的变化及其变化建成,其他承诺(remote
或>>>>>>>
或--theirs
)是你自己的承诺,重订,这是试图复制之上HEAD
.
合并时(包括重新定位,这是内部重复"合并"的特殊情况),涉及两个"头"(两个特定的分支提示).让我们把这些your-branch
和origin/their-branch
:
G - H -------- <-- HEAD=your-branch
/ \
... - E - F M <-- desired merge commit [requires manual merge]
\ /
I - J - K - L <-- origin/their-branch
Run Code Online (Sandbox Code Playgroud)
这一点通常(并且不足为奇)令人困惑,尽管如此标记这一点已经足够清楚了.
但是,更糟糕的是,git 在合并期间使用--ours
并--theirs
引用两个头部提交,H
当你运行时git merge
,"我们的"是你所处的(提交),而"他们的"就是他们的(提交L
).但是当你正在做一个反叛时,两个头是相反的,所以"我们的"是你正在改变的头,即他们更新的代码 - 而"他们的"是你目前正在改变的提交,即你自己的代码.
这是因为rebase实际上使用了一系列的挑选操作.你从很多相同的图片开始:
G - H <-- HEAD=your-branch
/
... - E - F
\
I - J - K - L <-- origin/their-branch
Run Code Online (Sandbox Code Playgroud)
什么混帐需要做的,是要复制提交的效果G
和H
,即git cherry-pick
提交G
,然后提交再做一遍H
.但要做到这一点,git必须首先在内部切换到提交L
(使用"分离的HEAD"模式):
G - H <-- your-branch
/
... - E - F
\
I - J - K - L <-- HEAD, origin/their-branch
Run Code Online (Sandbox Code Playgroud)
现在它可以通过比较提交树F
和G
(看你改变了什么),然后比较F
vs L
(看看你的某些作品是否已经存在L
)并进行任何尚未进行的更改L
并添加它来启动rebase操作.这是内部的"合并"操作.
G - H <-- your-branch
/
... - E - F G' <-- HEAD
\ /
I - J - K - L <-- origin/their-branch
Run Code Online (Sandbox Code Playgroud)
如果合并不顺利,HEAD
仍然处于提交状态L
(因为提交G'
尚不存在).因此,是的,HEAD
是他们发展部门的负责人 - 至少现在是这样.
G
但是,一旦存在副本HEAD
移动到G'
并且git尝试以H
相同的方式复制更改(diff G
vs H
,则diff F
vs G'
,并合并结果):
G - H <-- your-branch
/
... - E - F G' - H' <-- HEAD
\ /
I - J - K - L <-- origin/their-branch
Run Code Online (Sandbox Code Playgroud)
同样,如果合并失败,并且需要帮助,你留下了HEAD
指向G'
,而不是H'
因为H'
尚不存在.
一旦合并成功并提交G'
并H'
确实存在,git your-branch
将从提交中删除标签H
,并使其指向提交H'
:
G - H
/
... - E - F G' - H' <-- HEAD=your-branch
\ /
I - J - K - L <-- origin/their-branch
Run Code Online (Sandbox Code Playgroud)
而你现在已经重新定位,并HEAD
再次成为你所期待的.但是在rebase期间,HEAD
要么是他们的分支提示(提交L
),要么是其中一个新提交被复制并追加到他们的分支提示之外; 并且--ours
意味着在L
while 结束时生成的分支--theirs
意味着从(G
或H
上面)复制提交.
(这基本上是暴露了它如何做它的原始机制的git ,这在git中发生了很多.)
在本节中,我们将看到我们被要求回答的缺陷:
头是谁?
HEAD
:您的存储库当前的提交。大多数时候 HEAD 指向分支中的最新提交,但情况不一定如此。
HEAD
实际上只是意味着“我的仓库当前指向什么”。
如果提交HEAD
引用的不是任何分支的顶端,则称为“ detached head
”。
是开发部门的负责人吗?
在进行合并或变基时,HEAD
立即传递指向创建或重构的提交,因此将指向开发分支。
在git bash
我们可以看到的HEAD
情况下,列出提交:
# Normal commit list
git log
# List of commit in a single line
git log --oneline
# All commits graphically-linear (Recommended as alias)
git log --all --graph --decorate --oneline
Run Code Online (Sandbox Code Playgroud)
在本节中,我们将了解用户执行的一些操作的工作原理
当用户继续:
# Command to change from the branch to the current one to experimentalbranch
git checkout experimentalbranch
# Command that traverses the typical workflow to synchronize its local repository with the main branch of the central repository (remoterepo)
git fetch remoterepo
# git fetch origin
# git fetch origin branch:branch
# With the command git rebase, you can take all the changes confirmed in one branch (remoterepo), and reapply them over another developmentbranch
git rebase remoterepo/developmentbranch
Run Code Online (Sandbox Code Playgroud)
这时候我就遇到了矛盾。但是,我不熟悉这些更改中的任何一个(我正在重新调整数周的更改,因为它们没有立即合并我的更改)。另外,这是我第一次做rebase。我更习惯于合并。
分支的联合有两种方式完成:
git合并
git 变基。
笔记:
对于示例,我们将使用以下树:
* a122f6d (HEAD -> remoterepo) Commit END
* 9667bfb Commit MASTER
| * b9bcaf0 (origin/experimentalbranch, experimentalbranch) Commit 3
| * 110b2fb Commit 2
| * e597c60 Commit 1
|/
* 0e834f4 (origin/remoterepo) First commit
Run Code Online (Sandbox Code Playgroud)
最著名的形式是git merge
,它对每个分支的最后两个快照和两个分支的共同祖先之间的三个带进行融合,创建具有混合更改的新提交。
例如 :
git checkout remoterepo
git merge experimentalbranch
Run Code Online (Sandbox Code Playgroud)
它会产生我们:
* 003e576 (HEAD -> remoterepo) Merge branch 'experimentalbranch' in remoterepo
|\
| * b9bcaf0 (origin/experimentalbranch, experimentalbranch) Commit 3
| * 110b2fb Commit 2
| * e597c60 Commit 1
* | a122f6d Commit END
* | 9667bfb Commit MASTER
|/
* 0e834f4 (origin/remoterepo) First commit
Run Code Online (Sandbox Code Playgroud)
git rebase
基本上它的作用就是一一收集一个分支中确认的更改,然后将它们重新应用到另一个分支上。
每当将 rebase应用于本地且尚未上传到任何远程存储库的提交时,使用 rebase 可以帮助我们避免冲突。如果您对后者不小心并且合作伙伴使用了受影响的更改,那么您肯定会遇到问题,因为这些类型的冲突通常很难修复。
例如 :
git checkout remoterepo
git rebase experimentalbranch
* f8a74be (HEAD -> remoterepo) Commit END
* 4293e9d Commit MASTER
* b9bcaf0 (origin/experimentalbranch, experimentalbranch) Commit 3
* 110b2fb Commit 2
* e597c60 Commit 1
* 0e834f4 (origin/remoterepo) First commit
Run Code Online (Sandbox Code Playgroud)
什么是起源?
origin
:git 为您的主远程存储库提供的默认名称。您的盒子有自己的存储库,您很可能会推送到您和所有同事推送到的某个远程存储库。该远程存储库几乎总是称为 origin,但不一定如此。
归档时间: |
|
查看次数: |
16814 次 |
最近记录: |