【问题标题】:Why current branch is not moved while rebasing?为什么在变基时不移动当前分支?
【发布时间】:2020-10-29 13:51:21
【问题描述】:

我目前在dev 分支上,在local/dev 分支上有一些变化。

...

我做了rebase:

$ git rebase dev local/dev
Created autostash: 92915886
Applied autostash.
Successfully rebased and updated detached HEAD.

提交被重新定位,但dev 指针未更新:

阅读man git rebase

由当前分支中的提交所做但不在 中的所有更改 保存到临时区域

**这是第二张图片上标记为>的提交

当前分支被重置为 ...

** upstreamdev。所以我现在在dev

然后将提交重新应用到当前分支

** 提交被重新应用到dev

为什么dev 指针没有与HEAD 一起移到顶部?

我应该应用一些选项来将我当前的devHEAD 一起移动吗?

更新
这是非常非常战略性的。当devlocal/dev 不同的班轮并且可以被快速转发时,我的dev 被移动到顶部,因为我预计会工作。没有任何多余的

git branch -f dev
git checkout dev

rebase 之前的历史看起来如何: 以及变基后如何:

【问题讨论】:

  • “重置到上游”并不意味着“检查上游”。您正在变基的分支指向上游分支指向的同一提交。你只会影响你正在变基的分支,而不是你要变基的分支。
  • @LasseV.Karlsen:1. 好的,它不会结帐到dev。所以没有当前分支。 man 说:then reapplied to the current branch 是什么意思? 2.You will only affect the branch you're rebasing。我在上游的local/dev 处重新提交提交。变基后的分支local/dev 保持不变。你的意思是它会受到影响?谢谢。

标签: git git-rebase


【解决方案1】:

为什么dev 指针没有与HEAD 一起移到顶部?——因为它在变基期间不是当前分支。

仔细阅读documentation of git rebase。它在第一段中解释:

git rebase [-i | --interactive] [<options>] [--exec <cmd>]
        [--onto <newbase> | --keep-base] [<upstream> [<branch>]]`

如果指定了&lt;branch&gt;git rebase 将在执行任何其他操作之前自动执行git switch &lt;branch&gt;。否则它会保留在当前分支上。

简单来说,如果git rebase 被两个分支(&lt;upstream&gt;&lt;branch&gt;)调用,它首先切换到第二个分支,然后在第一个分支之上重新设置它。*

这意味着:

git rebase dev local/dev

是一个快捷方式:

git switch local/dev
git rebase dev

rebase 期间的当前分支是local/dev;它是唯一受 rebase 影响的分支。


*&lt;upstream&gt; 不需要是分支。任何标识提交的引用(分支、标记、提交、HEADHEAD^2HEAD@{1} 等)都可以用作&lt;upstream&gt;

另一方面,&lt;branch&gt; 需要成为一个分支,因为作为 rebase 的结果,它将移动到不同的提交。


更新

您错误地解释了文档。你在问题中说:

当前分支被重置为&lt;upstream&gt; ...

** 上游是 dev。所以我现在正在开发中

该点的当前分支不一定是dev(实际上是local/dev,如上所述)。

“当前分支被重置为&lt;upstream&gt; 并不意味着&lt;upstream&gt; 成为当前分支,而是当前分支(local/dev)被移动到由@ 标识的提交987654348@。 Git此时所做的相当于git reset --hard &lt;upstream&gt;


更新 #2

上面的分析忽略了local/dev是一个远程分支的事实。最初我没有注意到。
命名远程 local 有什么意义?这是误导。

因为local/dev 不是本地分支,所以git switch local/dev 将repo 带入detached HEAD 状态。其余的变基按照文档中的描述发生,但最后你有一个新的历史行并且没有指向它的分支(HEAD 除外)。如果切换分支,rebase 的结果会丢失。

有两种方法可以解决问题:

  • 在当前提交上移动分支dev。有几种方法可以做到这一点,但最简单的方法是使用git branch -f dev

  • 放弃更改,切换到 dev 分支并正确执行 rebase:

    git switch dev
    git rebase local/dev
    

真正的解决方案

总而言之,整个情况出现是因为你在命令行中把分支的顺序不正确。应该是:

git rebase local/dev dev

这会检出dev 分支,然后将可从dev 访问的提交移动到local/dev 之上,而不能从local/dev 访问,同时将dev 分支保留在移动的提交之上。一眼看去,好像分支 dev 是从分支 local/dev 的分叉处切下的,然后将这块嫁接在 local/dev 的顶部。

【讨论】:

  • 非常详细的解释。现在我明白发生了什么。谢谢
  • 我更新了这个问题。有一种情况是我的git rebase dev local/devdev 分支移动到顶部
  • local 是在 remote 上设置的名称。这不是 git 以某种方式设置的东西。当一个遥控器被添加到你正在处理的那个 repo 中时使用它,如果开发人员想要在所述 repo 上添加一个将其命名为local 的远程 repo,git 会拒绝谁?所以,有人在那个 repo 上运行了这个,回到过去:git remote add local https://blahblah/url/to/repo。当然,这不是命名遥控器的最佳选择。
【解决方案2】:

local/dev 是一个远程分支。它不会仅仅因为你想重新设置它而移动。它将在detached HEAD 中完成,然后由你来推入local/dev

git push local -f HEAD:dev

您也可以将dev 移动到HEAD 然后结帐:

git branch -f dev
git checkout dev

【讨论】:

  • 我不想更改local/dev。我说的是dev
  • 更是如此......你没有要求重新设置dev,你在那里运行的是要求重新设置local/dev dev。如果您想在操作完成后将 dev 设置在您所在的位置,那么您需要运行 git branch -f dev。然后你可能会考虑检查一下。
  • 投票,但删除了接受的答案,因为没有答案如何自动完成
  • 我更新了问题。这是我的git rebase 在没有这些额外命令的情况下工作的情况
【解决方案3】:

如果您想移动 dev 以获取应用于 local/dev 的修订,您可以这样做:

git checkout dev
git cherry-pick $( git merge-base HEAD local/dev )..local/dev

应该这样

【讨论】:

    【解决方案4】:

    我没有找到将dev 分支自动移动到HEAD 的选项。

    但是在变基之后,我可以返回到dev,然后快进到c1692f

    $ git checkout dev
    $ git merge --ff-only c1692f
    

    结果如下:

    【讨论】:

    • git branch -f dev; git checkout dev。无需离开您所在的位置。
    • @eftshift0:我刚才添加给您的回答相同:D
    • 是的,注意到了。谢谢
    猜你喜欢
    • 2017-09-30
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 2017-10-28
    • 2020-10-15
    • 1970-01-01
    相关资源
    最近更新 更多