为什么git rebase放弃了我的提交? [英] Why is git rebase discarding my commits?

查看:292
本文介绍了为什么git rebase放弃了我的提交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在master之上重建一个分支,这是我以前做过的一千次。但今天,它不工作:

 > git status 
在分支mystuff
你的分支和'master'分别有
和6个和2个不同的提交。
(使用git pull将远程分支合并到你的)

没有提交,工作目录干净

> git rebase
首先,倒带头重播你的作品......

> git status
在分支mystuff
你的分支是最新的'master'。

未记录的文件:
(使用git add< file> ...来包含将要提交的内容)

[项目中的目录]

没有添加提交但未跟踪的文件存在(使用git add跟踪)

>

一切都像正常一样开始,但是Git完成了rebase而没有提交任何提交。我的分支mystuff最终与master相同。



显而易见的结论是,我的提交已经在某个地方。但他们不是,我发誓。我回顾了历史。在其他几个功能分支上提交 ,但它们不在任何位置的主人历史记录中。 (而且我可以告诉他们在主人签出时无论如何都不会受到文件状态的影响)。

因此,如果提交尚未完成在我的上游历史,否则为什么 git的重订拒绝堆顶我提交?



奇怪的是,如果我一个接一个地挑选主人,这很有效。然后我可以将mystuff分支移动到最后,然后再回到原来的位置。 (但为什么我需要这样做?)



编辑

<关于 git rebase 的文档说明了这一点:


当前分支被重置至<上游> < newbase> 如果提供了code>选项。这具有为 GIT中的复位 - 硬<完全相同的效果;上游> (或< newbase> )。 ORIG_HEAD 被设置为在重置前指向分支的顶端。



先前保存的提交然后将临时区域依次重新应用到当前分支。请注意,在 HEAD 其中引入相同的文本改变为任何提交在提交HEAD ..<上游> 是省略(即一个已经接受上游补丁的不同提交消息或时间戳将被跳过)。

这将与行为我看到如果提交确实存在于上游......但它们不是。正如评论中所提到的, git rebase master 可以正常工作并应用所有提交。但是 git rebase 没有 master 不会,即使master设置为上游分支。



我的分行配置:

  [branchmaster] 
remote =原始
合并=参考/头/主
[分支mystuff]
远程=。
合并=参/头/主


解决方案

在某个git升级后,这已经让我至少陷入了十几次。在 git rebase git rebase master 现在是差异 c>:前者改为使用相同的花式叉点机械。在回答这个问题时有详细的解释:



今天我第一次想出了重现它的具体步骤。 >

我的情景:我有4次提交 master ,我决定现在应该进入主题分支,我想对它们重新排序。如果我这样做...


  1. 创建一个新的主题分支,跟踪当前分支( master

      git checkout  - b主题-t 


  2. 倒退主人 back:

      git checkout master 
    git reset --hard origin / master

      git checkout topic 
    git status#您的分支在4次提交之前超过'master'Good!
    git rebase --interactive


......然后交互式分拣画面出现这个不祥的提交列表:

 #no-op 

呃 - 哦...我保存文件并继续。是的,看起来git再次抛弃了我的工作。 主题现在指向与 master origin / master


  1. 升级git


  2. 您在 master 分支上完成了类似于第2步的操作。


    在我的外行人的理解中, fork-point 机器通过reflog搜索并注意到这些提交已从上游分支中移除,并得出结论认为要将您的主题分支更新,它们也应该在那里被移除。



    解决方案是,而不是:

      git rebase 
      git rebase --no-fork-point 
    git rebase master

    但是我怀疑像我一样,你会每次都这样做。 (我的意思是,我们设置了一个上游分支是有原因的,对吧?)因此,您只需学会识别何时发生此灾难,请使用 git reflog git reset --hard 来恢复,然后然后使用上面的命令。



    现在要小心 - 我认为这是非常危险的。我曾经有过几次重新设计大型分支机构,并且一些承诺从一开始就悄然消失,而我几天没有注意到!我非常乐意挖掘 git reflog 来完成灾难恢复,但我不确定每个人都是如此。我不知道git是否已经开始在这里很聪明。


    I'm trying to rebase a branch on top of master, something I've done a thousand times before. But today, it's not working:

    > git status
    On branch mystuff
    Your branch and 'master' have diverged,
    and have 6 and 2 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)
    
    nothing to commit, working directory clean
    
    > git rebase
    First, rewinding head to replay your work on top of it...
    
    > git status
    On branch mystuff
    Your branch is up-to-date with 'master'.
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
        [a directory from the project]
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    >
    

    Everything starts like normal, but then Git finishes the rebase without putting any of my commits there; my branch mystuff ends up on the same commit as master.

    The obvious conclusion would be that my commits are already in master somewhere. But they're not, I swear. I've gone back through the history. The commits are on a couple of other feature branches, but they're not in the history of master anywhere. (And I can tell they're not in master anyway by the state of the files when I have master checked out.)

    So, if the commits aren't already in my upstream history, why else would git rebase refuse to stack my commits on top?

    Oddly enough, if I cherry-pick the commits onto master one-by-one, that works. And then I can move my mystuff branch to the end, and back master up to where it was. (But why would I need to do it that way?)

    EDIT:

    The documentation on git rebase says this:

    The current branch is reset to <upstream>, or <newbase> if the --onto option was supplied. This has the exact same effect as git reset --hard <upstream> (or <newbase>). ORIG_HEAD is set to point at the tip of the branch before the reset.

    The commits that were previously saved into the temporary area are then reapplied to the current branch, one by one, in order. Note that any commits in HEAD which introduce the same textual changes as a commit in HEAD..<upstream> are omitted (i.e., a patch already accepted upstream with a different commit message or timestamp will be skipped).

    This would be consistent with the behavior I'm seeing if the commits actually existed upstream...but they don't. And as mentioned in the comments, git rebase master works correctly and applies all the commits. But git rebase without master doesn't, even though master is set as the upstream branch.

    Configuration of my branches:

    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [branch "mystuff"]
        remote = .
        merge = refs/heads/master
    

    解决方案

    This has bitten me at least a dozen times after a certain git upgrade. There is now a difference between git rebase and git rebase master: the former was changed to use same fancy "fork-point" machinery. There is a detailed explanation in answer to this question:

    Today for the first time I figured out concrete steps to reproduce it.

    MY SCENARIO: I have 4 commits on master which I've decided should now move into a topic branch, plus I want to reorder them. If I do it this way...

    1. Create a new topic branch, tracking the current branch (master)

      git checkout -b topic -t
      

    2. Rewind master back :

      git checkout master
      git reset --hard origin/master
      

    3. Reorder the commits on topic

      git checkout topic
      git status  # "Your branch is ahead of 'master' by 4 commits" Good!
      git rebase --interactive
      

    ... then the interactive rebase screen comes up with this ominous list of commits:

        # no-op
    

    Uh-oh... I save the file and continue anyway. Yup, looks like git's thrown away my work again. topic now points to the same commit as master and origin/master.

    So I presume what triggered this for you is:

    1. upgrading git

    2. You had done something like my step 2 on your master branch.

    In my lay-man's understanding, the fork-point machinery searches back through the reflog and notices that those commits had been removed from the upstream branch, and comes to the conclusion that to bring your topic branch "up to date" they should be removed there too.

    The solution is, instead of:

    git rebase
    

    Use one of:

    git rebase --no-fork-point
    git rebase master
    

    But I suspect like me you wouldn't do this every time. (I mean, we set an upstream branch for a reason, right?) So you'd just learn to recognise when this disaster strikes, use git reflog and git reset --hard to recover, and then use the above command.

    Still, you need to be careful now - I think this is extremely dangerous. I have had times when I've rebased a large branch and a few commits silently disappeared from the beginning, and I didn't notice for days! I'm fairly comfortable mining git reflog to do disaster recovery, but I'm not sure everyone is. I wonder if git has started being too clever here.

    这篇关于为什么git rebase放弃了我的提交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆