git 拉 *after* git 变基?
git pull *after* git rebase?
我有一个功能分支和一个主分支。
主分支已经发展,我的意思是让这些更新尽可能少地与主分支分开。
所以我在两个分支中 git pull
,git checkout feature/branch
最后 git rebase master
。
现在我要么希望一切顺利要么出现冲突,我需要在继续变基之前解决这些冲突,直到所有主提交都在功能分支上成功重新应用。
现在在我的案例中真正发生的事情是我不明白的:
$>git rebase master
First, rewinding head to replay your work on top of it...
Applying: myFirstCommitDoneOnTheBranch
Applying: myOtherCommitDoneOnTheBranch
$>git status
On branch feature/branch
Your branch and 'origin/feature/feature' have diverged,
and have 27 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
$>git pull
*load of conflicts*
现在,据我所知,拉动后他会发生很多冲突;我不明白拉的必要性。从逻辑上讲,它应该在分支时回滚到 master,保存在分支上所做的提交,转发到 master 上的最新提交,然后应用保存的提交。
我不明白 Applying
消息指的是什么:什么在哪个版本上应用提交?
have 27 and 2 different commits each
告诉您现在有来自 master
的 27 个新提交和分支中的 2 个新提交,这些提交在 origin/<yourbranch>
.
中不存在
因为 origin/<yourbranch>
已经被 rebase 大量改变,它不再与 origin/<yourbranch>
有共同的基础。因此,您不想在变基后从 origin/<yourbranch>
中提取更改,因为如您所见,所有 H*** 都松动了。
如果您知道 origin/<yourbranch>
中有您需要在本地分支中进行的更改,请在变基之前拉取这些更改。
如果您确定自上次推送以来没有人更改 origin/<yourbranch>
(如果这是您自己的功能分支,这是一个安全的赌注),您可以使用 push --force
将它们再次同步。然后 origin/<yourbranch>
将再次与您的本地分支具有相同的基础,并且该基础将包含所有最新的 master
更改。
如果 master
和 feature/branch
的远程版本分别是最新的,那么只需重置您的本地功能分支
git checkout feature/branch
git fetch origin feature/branch
git reset --hard origin/feature/branch
然后,如果您想在 master
分支中进行更改,
git rebase origin/master
tl;dr 您应该将 master
和 feature
更新为 git pull
和 git pull --rebase
在 重新设置 feature
在 master
之上之前。 git pull
之后你已经重新设置了feature
b运行ch master
的顶部。
在您当前的工作流程中,git status
告诉您的原因是:
Your branch and 'origin/feature' have diverged,
and have 27 and 2 different commits each, respectively.
是因为你的 rebased feature
b运行ch 现在有 25 新的提交,这些提交无法从 origin/feature
访问(因为他们来自 master
) 上的 rebase 加上 2 提交 可从 origin/feature
访问,但具有不同的提交 ID。这些提交包含相同的更改(即它们是 等效补丁 )但它们具有不同的 SHA-1 哈希,因为它们基于 origin/feature
中的不同提交而不是那个提交您在本地存储库中将它们重新定位。
举个例子。假设这是您的历史 before doing git pull
on master
:
A - B - C (master)
\
D - E (feature)
在 git pull
之后,master
得到了提交 F
:
A - B - C - F (master, origin/master)
\
D - E (feature)
此时,您在 master
之上变基 feature
, 适用 D
和 E
:
A - B - C - F (master, origin/master)
\
D - E (feature)
与此同时,远程 b运行ch origin/feature
仍然基于提交 C
:
A - B - C - F (master, origin/master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
如果你在 feature
上做 git status
,Git 会告诉你你的 feature
b运行ch 已经偏离 origin/feature
与 3 (F
, D'
, E'
) 和 2 (D
, E
) 分别提交。
Note that D'
and E'
contain the same changes as D
and E
but have different commit IDs because they have been rebased on top of F
.
解决方案是在 master
和 feature
之前都做 git pull
,然后 在 [=19= 上重新设置 feature
].但是,由于您可能在 feature
上提交了尚未推送到 origin
的内容,因此您需要执行以下操作:
git checkout feature && git pull --rebase
避免在 origin/feature
和本地 feature
之间创建 合并提交 。
关于变基后果的更新:
根据 ,我扩展了不同的 b运行ches。 git status
报告 feature
和 origin/feature
diverge 的原因是因为 rebase 带来了对 [=20 的新提交=],加上它 重写 之前推送到 origin/feature
的提交。
考虑在拉动但变基之前的情况:
A - B - C - F (master)
\
D - E (feature, origin/feature)
此时,feature
和 origin/feature
指向同一个提交 E
——换句话说,它们在“sync”。在 master
之上重新设置 feature
后,历史将如下所示:
A - B - C - F (master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
如您所见,feature
和 origin/feature
有 分歧 ,它们的共同祖先是提交 C
。这是因为 feature
现在包含来自 master
的新提交 F
加上 D'
和 E'
(读作“D prime”和“E prime”)是在F
之上应用的提交D
和E
。即使它们包含相同的更改,Git 也认为它们是不同的,因为它们具有不同的提交 ID。同时,origin/feature
仍然引用 D
和 E
.
此时,您已经重写了历史:您已经通过变基修改了现有的提交,有效地创建了 "new" 个。
现在,如果您在 feature
运行 git pull
会发生以下情况:
A - B - C - F (master)
\ \
\ D' - E'- M (feature)
\ /
D - E - (origin/feature)
由于 git pull
执行 git fetch
+ git merge
,这将导致创建合并提交 M
,其父级为 E'
和 E
.
如果您 运行 git pull --rebase
(即 git fetch
+ git rebase
),那么 Git 将:
- 移动
feature
提交 C
(feature
和 origin/feature
的共同祖先)
- 从
origin/feature
应用 D
和 E
- 应用
F
、D'
和E'
但是,注意到 D'
和 E'
包含与 D
和 E
相同的更改,Git 会丢弃它们,从而导致历史看起来像这样:
A - B - C - F (master)
\
D - E - F' (feature)
^
(origin/feature)
请注意之前可从 feature
访问的提交 F
如何在 origin/feature
之上应用导致 F'
。此时,git status
会告诉你:
Your branch is ahead of 'origin/feature' by 1 commit.
该提交当然是 F'
。
当您在 master 之上重新设置您的功能分支时,您创建了一堆新的提交。但是,您的 origin/feature
分支仍然指向旧分支。这是rebase后的情况:
C' (feature)
B'
A'
* (master, origin/master)
*
*
| C (origin/feature)
| B
| A
|/
* some base commit
虽然提交 A'
包含与提交 A
相似的更改集,但它绝不是同一个提交。它包含不同的树,并且有不同的父级。
现在,当您再次尝试拉取 feature
时,您会尝试创建此历史记录:
* (feature)
|\
C'|
B'|
A'|
* | (master, origin/master)
* |
* |
| C (origin/feature)
| B
| A
|/
* some base commit
您正在合并两个引入了非常相似但不同更改的分支。除了毫无意义之外,这肯定会造成大量冲突。
您需要做的是使用 git push -f
通知您的上游仓库有关变基的信息。 这将丢失旧历史,并用重写的历史替换它。
另一种方法是避免在已推送到任何其他存储库的分支上使用 git rebase
,或者完全避免使用 git rebase
。 这是更简洁的方法:它会产生已经发生的历史,而不是像 git rebase
那样对历史撒谎。这至少是我喜欢的。
出现这个错误是因为调用了git checkout feature/branch
之后还没有调用git fetch origin
。为避免以后出现此错误,您可以按顺序执行以下命令:
git checkout feature/branch
git fetch origin
git rebase master
我有一个功能分支和一个主分支。
主分支已经发展,我的意思是让这些更新尽可能少地与主分支分开。
所以我在两个分支中 git pull
,git checkout feature/branch
最后 git rebase master
。
现在我要么希望一切顺利要么出现冲突,我需要在继续变基之前解决这些冲突,直到所有主提交都在功能分支上成功重新应用。
现在在我的案例中真正发生的事情是我不明白的:
$>git rebase master
First, rewinding head to replay your work on top of it...
Applying: myFirstCommitDoneOnTheBranch
Applying: myOtherCommitDoneOnTheBranch
$>git status
On branch feature/branch
Your branch and 'origin/feature/feature' have diverged,
and have 27 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
$>git pull
*load of conflicts*
现在,据我所知,拉动后他会发生很多冲突;我不明白拉的必要性。从逻辑上讲,它应该在分支时回滚到 master,保存在分支上所做的提交,转发到 master 上的最新提交,然后应用保存的提交。
我不明白 Applying
消息指的是什么:什么在哪个版本上应用提交?
have 27 and 2 different commits each
告诉您现在有来自 master
的 27 个新提交和分支中的 2 个新提交,这些提交在 origin/<yourbranch>
.
因为 origin/<yourbranch>
已经被 rebase 大量改变,它不再与 origin/<yourbranch>
有共同的基础。因此,您不想在变基后从 origin/<yourbranch>
中提取更改,因为如您所见,所有 H*** 都松动了。
如果您知道 origin/<yourbranch>
中有您需要在本地分支中进行的更改,请在变基之前拉取这些更改。
如果您确定自上次推送以来没有人更改 origin/<yourbranch>
(如果这是您自己的功能分支,这是一个安全的赌注),您可以使用 push --force
将它们再次同步。然后 origin/<yourbranch>
将再次与您的本地分支具有相同的基础,并且该基础将包含所有最新的 master
更改。
如果 master
和 feature/branch
的远程版本分别是最新的,那么只需重置您的本地功能分支
git checkout feature/branch
git fetch origin feature/branch
git reset --hard origin/feature/branch
然后,如果您想在 master
分支中进行更改,
git rebase origin/master
tl;dr 您应该将 master
和 feature
更新为 git pull
和 git pull --rebase
在 重新设置 feature
在 master
之上之前。 git pull
之后你已经重新设置了feature
b运行ch master
的顶部。
在您当前的工作流程中,git status
告诉您的原因是:
Your branch and 'origin/feature' have diverged, and have 27 and 2 different commits each, respectively.
是因为你的 rebased feature
b运行ch 现在有 25 新的提交,这些提交无法从 origin/feature
访问(因为他们来自 master
) 上的 rebase 加上 2 提交 可从 origin/feature
访问,但具有不同的提交 ID。这些提交包含相同的更改(即它们是 等效补丁 )但它们具有不同的 SHA-1 哈希,因为它们基于 origin/feature
中的不同提交而不是那个提交您在本地存储库中将它们重新定位。
举个例子。假设这是您的历史 before doing git pull
on master
:
A - B - C (master)
\
D - E (feature)
在 git pull
之后,master
得到了提交 F
:
A - B - C - F (master, origin/master)
\
D - E (feature)
此时,您在 master
之上变基 feature
, 适用 D
和 E
:
A - B - C - F (master, origin/master)
\
D - E (feature)
与此同时,远程 b运行ch origin/feature
仍然基于提交 C
:
A - B - C - F (master, origin/master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
如果你在 feature
上做 git status
,Git 会告诉你你的 feature
b运行ch 已经偏离 origin/feature
与 3 (F
, D'
, E'
) 和 2 (D
, E
) 分别提交。
Note that
D'
andE'
contain the same changes asD
andE
but have different commit IDs because they have been rebased on top ofF
.
解决方案是在 master
和 feature
之前都做 git pull
,然后 在 [=19= 上重新设置 feature
].但是,由于您可能在 feature
上提交了尚未推送到 origin
的内容,因此您需要执行以下操作:
git checkout feature && git pull --rebase
避免在 origin/feature
和本地 feature
之间创建 合并提交 。
关于变基后果的更新:
根据 git status
报告 feature
和 origin/feature
diverge 的原因是因为 rebase 带来了对 [=20 的新提交=],加上它 重写 之前推送到 origin/feature
的提交。
考虑在拉动但变基之前的情况:
A - B - C - F (master)
\
D - E (feature, origin/feature)
此时,feature
和 origin/feature
指向同一个提交 E
——换句话说,它们在“sync”。在 master
之上重新设置 feature
后,历史将如下所示:
A - B - C - F (master)
\ \
\ D' - E' (feature)
\
D - E (origin/feature)
如您所见,feature
和 origin/feature
有 分歧 ,它们的共同祖先是提交 C
。这是因为 feature
现在包含来自 master
的新提交 F
加上 D'
和 E'
(读作“D prime”和“E prime”)是在F
之上应用的提交D
和E
。即使它们包含相同的更改,Git 也认为它们是不同的,因为它们具有不同的提交 ID。同时,origin/feature
仍然引用 D
和 E
.
此时,您已经重写了历史:您已经通过变基修改了现有的提交,有效地创建了 "new" 个。
现在,如果您在 feature
运行 git pull
会发生以下情况:
A - B - C - F (master)
\ \
\ D' - E'- M (feature)
\ /
D - E - (origin/feature)
由于 git pull
执行 git fetch
+ git merge
,这将导致创建合并提交 M
,其父级为 E'
和 E
.
如果您 运行 git pull --rebase
(即 git fetch
+ git rebase
),那么 Git 将:
- 移动
feature
提交C
(feature
和origin/feature
的共同祖先) - 从
origin/feature
应用 - 应用
F
、D'
和E'
D
和 E
但是,注意到 D'
和 E'
包含与 D
和 E
相同的更改,Git 会丢弃它们,从而导致历史看起来像这样:
A - B - C - F (master)
\
D - E - F' (feature)
^
(origin/feature)
请注意之前可从 feature
访问的提交 F
如何在 origin/feature
之上应用导致 F'
。此时,git status
会告诉你:
Your branch is ahead of 'origin/feature' by 1 commit.
该提交当然是 F'
。
当您在 master 之上重新设置您的功能分支时,您创建了一堆新的提交。但是,您的 origin/feature
分支仍然指向旧分支。这是rebase后的情况:
C' (feature)
B'
A'
* (master, origin/master)
*
*
| C (origin/feature)
| B
| A
|/
* some base commit
虽然提交 A'
包含与提交 A
相似的更改集,但它绝不是同一个提交。它包含不同的树,并且有不同的父级。
现在,当您再次尝试拉取 feature
时,您会尝试创建此历史记录:
* (feature)
|\
C'|
B'|
A'|
* | (master, origin/master)
* |
* |
| C (origin/feature)
| B
| A
|/
* some base commit
您正在合并两个引入了非常相似但不同更改的分支。除了毫无意义之外,这肯定会造成大量冲突。
您需要做的是使用 git push -f
通知您的上游仓库有关变基的信息。 这将丢失旧历史,并用重写的历史替换它。
另一种方法是避免在已推送到任何其他存储库的分支上使用 git rebase
,或者完全避免使用 git rebase
。 这是更简洁的方法:它会产生已经发生的历史,而不是像 git rebase
那样对历史撒谎。这至少是我喜欢的。
出现这个错误是因为调用了git checkout feature/branch
之后还没有调用git fetch origin
。为避免以后出现此错误,您可以按顺序执行以下命令:
git checkout feature/branch
git fetch origin
git rebase master