为什么当前分支在变基时没有移动?
Why current branch is not moved while rebasing?
我目前在 dev
分支上并且在 local/dev
分支上有一些变化。
...
我做了变基:
$ git rebase dev local/dev
Created autostash: 92915886
Applied autostash.
Successfully rebased and updated detached HEAD.
提交已变基,但 dev
指针未更新:
阅读man git rebase
:
All changes made by commits in the current branch but that are not in <upstream>
are saved to a temporary area
**这是在第二张图片
上标记为>
的提交
The current branch is reset to <upstream> ...
** upstream
是 dev
。所以我现在在dev
The commits are then reapplied to the current branch
** 提交重新应用于 dev
为什么 dev
指针没有用 HEAD
移动到顶部?
我是否应该应用一些选项将我当前的 dev
移动到 HEAD
的顶部?
更新
这是非常非常有策略的。当 dev
和 local/dev
不同的衬里并且可以快速转发时,然后我的 dev
被移到顶部,因为我期望工作。没有任何额外的
git branch -f dev
git checkout dev
变基之前的历史情况:
以及变基后如何:
local/dev
是远程分支。它不会因为你想改变它而移动。它将在 detached HEAD
完成,然后由您推入 local/dev
git push local -f HEAD:dev
您也可以将dev
移动到HEAD
然后结帐:
git branch -f dev
git checkout dev
我找不到将 dev
分支自动移动到 HEAD
的选项。
但在变基后我可以返回到 dev
并快进到 c1692f
:
$ git checkout dev
$ git merge --ff-only c1692f
结果如下:
为什么 dev
指针没有用 HEAD
移动到顶部? -- 因为它是 而不是 变基期间的当前分支。
仔细阅读documentation of git rebase
。它在第一段中解释:
git rebase [-i | --interactive] [<options>] [--exec <cmd>]
[--onto <newbase> | --keep-base] [<upstream> [<branch>]]`
If <branch>
is specified, git rebase
will perform an automatic git switch <branch>
before doing anything else. Otherwise it remains on the current branch.
用简单的英语来说,如果使用两个分支(<upstream>
和 <branch>
)调用 git rebase
,它首先切换到第二个分支,然后将其重新定位到第一个分支的顶部.*
这意味着:
git rebase dev local/dev
是以下的快捷方式:
git switch local/dev
git rebase dev
变基期间的当前分支是local/dev
;它是唯一受变基影响的分支。
* <upstream>
不需要是分支。任何标识提交的引用(分支、标记、提交、HEAD
、HEAD^2
、HEAD@{1}
等)都可以用作 <upstream>
.
另一方面,<branch>
需要成为一个分支,因为作为 rebase 的结果,它将移动到不同的提交。
更新
您对文档的解释不正确。你在问题中说:
The current branch is reset to <upstream>
...
** upstream is dev. So I am on dev at this point
该点的当前分支不一定是 dev
(事实上,如上所述,它是 local/dev
)。
“当前分支重置为<upstream>
”并不是说<upstream>
成为当前分支而是当前分支(local/dev
) 被移动到由 <upstream>
标识的提交中。 Git 此时所做的相当于 git reset --hard <upstream>
.
更新#2
上面的分析忽略了local/dev
是远程分支这一事实。我一开始没注意到。
命名遥控器有什么意义 local
?这是误导。
因为 local/dev
不是本地分支,git switch local/dev
使回购处于 detached HEAD
状态。 rebase 的其余部分按照文档中的描述发生,但最后你有一个新的历史行并且没有指向它的分支(HEAD
除外)。如果你切换分支,rebase 的结果将丢失。
有两种方法可以解决问题:
在当前提交上移动分支 dev
。有几种方法可以做到这一点,但最简单的方法是使用 git branch -f dev
.
放弃更改,切换到 dev
分支并正确进行变基:
git switch dev
git rebase local/dev
真正的解决方案
总而言之,整个情况的出现是因为你在命令行中把分支的顺序放错了。应该是:
git rebase local/dev dev
这会检查 dev
分支,然后将可从 dev
访问但无法从 local/dev
访问的提交移到 local/dev
之上,同时保留 dev
在移动的提交之上分支。快速浏览一下,分支 dev
似乎是从分支 local/dev
的分叉处剪下的,然后该片段被嫁接在 local/dev
.
之上
如果您想移动 dev
以获取应用于 local/dev
的修订,您可以这样做:
git checkout dev
git cherry-pick $( git merge-base HEAD local/dev )..local/dev
应该可以
我目前在 dev
分支上并且在 local/dev
分支上有一些变化。
我做了变基:
$ git rebase dev local/dev
Created autostash: 92915886
Applied autostash.
Successfully rebased and updated detached HEAD.
提交已变基,但 dev
指针未更新:
阅读man git rebase
:
All changes made by commits in the current branch but that are not in <upstream> are saved to a temporary area
**这是在第二张图片
上标记为>
的提交
The current branch is reset to <upstream> ...
** upstream
是 dev
。所以我现在在dev
The commits are then reapplied to the current branch
** 提交重新应用于 dev
为什么 dev
指针没有用 HEAD
移动到顶部?
我是否应该应用一些选项将我当前的 dev
移动到 HEAD
的顶部?
更新
这是非常非常有策略的。当 dev
和 local/dev
不同的衬里并且可以快速转发时,然后我的 dev
被移到顶部,因为我期望工作。没有任何额外的
git branch -f dev
git checkout dev
变基之前的历史情况:
local/dev
是远程分支。它不会因为你想改变它而移动。它将在 detached HEAD
完成,然后由您推入 local/dev
git push local -f HEAD:dev
您也可以将dev
移动到HEAD
然后结帐:
git branch -f dev
git checkout dev
我找不到将 dev
分支自动移动到 HEAD
的选项。
但在变基后我可以返回到 dev
并快进到 c1692f
:
$ git checkout dev
$ git merge --ff-only c1692f
结果如下:
为什么 dev
指针没有用 HEAD
移动到顶部? -- 因为它是 而不是 变基期间的当前分支。
仔细阅读documentation of git rebase
。它在第一段中解释:
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase> | --keep-base] [<upstream> [<branch>]]`
If
<branch>
is specified,git rebase
will perform an automaticgit switch <branch>
before doing anything else. Otherwise it remains on the current branch.
用简单的英语来说,如果使用两个分支(<upstream>
和 <branch>
)调用 git rebase
,它首先切换到第二个分支,然后将其重新定位到第一个分支的顶部.*
这意味着:
git rebase dev local/dev
是以下的快捷方式:
git switch local/dev
git rebase dev
变基期间的当前分支是local/dev
;它是唯一受变基影响的分支。
* <upstream>
不需要是分支。任何标识提交的引用(分支、标记、提交、HEAD
、HEAD^2
、HEAD@{1}
等)都可以用作 <upstream>
.
<branch>
需要成为一个分支,因为作为 rebase 的结果,它将移动到不同的提交。
更新
您对文档的解释不正确。你在问题中说:
The current branch is reset to
<upstream>
...** upstream is dev. So I am on dev at this point
该点的当前分支不一定是 dev
(事实上,如上所述,它是 local/dev
)。
“当前分支重置为<upstream>
”并不是说<upstream>
成为当前分支而是当前分支(local/dev
) 被移动到由 <upstream>
标识的提交中。 Git 此时所做的相当于 git reset --hard <upstream>
.
更新#2
上面的分析忽略了local/dev
是远程分支这一事实。我一开始没注意到。
命名遥控器有什么意义 local
?这是误导。
因为 local/dev
不是本地分支,git switch local/dev
使回购处于 detached HEAD
状态。 rebase 的其余部分按照文档中的描述发生,但最后你有一个新的历史行并且没有指向它的分支(HEAD
除外)。如果你切换分支,rebase 的结果将丢失。
有两种方法可以解决问题:
在当前提交上移动分支
dev
。有几种方法可以做到这一点,但最简单的方法是使用git branch -f dev
.放弃更改,切换到
dev
分支并正确进行变基:git switch dev git rebase local/dev
真正的解决方案
总而言之,整个情况的出现是因为你在命令行中把分支的顺序放错了。应该是:
git rebase local/dev dev
这会检查 dev
分支,然后将可从 dev
访问但无法从 local/dev
访问的提交移到 local/dev
之上,同时保留 dev
在移动的提交之上分支。快速浏览一下,分支 dev
似乎是从分支 local/dev
的分叉处剪下的,然后该片段被嫁接在 local/dev
.
如果您想移动 dev
以获取应用于 local/dev
的修订,您可以这样做:
git checkout dev
git cherry-pick $( git merge-base HEAD local/dev )..local/dev
应该可以