moving committed (but not pushed) changes to a new branch after pull
我做了不少工作("你的分支机构比‘起源/主人’领先37个承诺"),这应该是属于自己的分支机构,而不是属于master。这些承诺只存在于我的本地机器上,没有被推到origin上,但是情况有些复杂,因为其他开发人员一直在推到origin/master上,我已经完成了这些更改。
我如何将我的37项本地承诺追溯到新的分支机构?基于文档,似乎git rebase --onto my-new-branch master或...origin/master应该这样做,但两者都给了我一个错误"致命:需要一次修订"。man git-rebase没有提到提供rebase的修订版本,它的示例没有这样做,所以我不知道如何解决这个错误。
(请注意,这不是将现有的未提交工作移动到Git中的新分支或如何将本地未提交的更改合并到另一个Git分支的副本?因为这些问题处理的是本地工作树中未提交的更改,而不是本地提交的更改。)
这应该很好,因为你还没有把你的承诺推到任何其他地方,而且你可以自由地在origin/master之后重写你的分支的历史。首先,我会运行一个git fetch origin,以确保origin/master是最新的。假设你现在在master上,你应该能够做到:
1
| git rebase origin/master |
…这将把你所有不在origin/master中的承诺重放到origin/master中。REBASE的默认操作是忽略合并提交(例如,您的git pull可能引入的提交),它将尝试将每个提交引入的补丁应用到origin/master。(您可能需要解决一些冲突。)然后您可以根据结果创建新分支:
号
…然后将你的master重置回origin/master:
1 2
| # Use with care - make sure"git status" is clean and you're still on master:
git reset --hard origin/master |
在使用git branch和git reset等操作分支时,我发现经常使用gitk --all或类似工具查看提交图很有用,只是为了检查我是否理解所有不同的引用指向何处。
或者,您可以根据您的主机在第一个位置(git branch new-work-including-merges)创建一个主题分支,然后如上所述重置master。但是,由于您的主题分支将包含来自origin/master的合并,并且您还没有推动您的更改,所以我建议您做一个重新平衡,以使历史更加整洁。(同样,当您最终将主题分支合并回master时,更改将更加明显。)
- 如果使用第二种方法,即让新分支指向合并提交,则可以始终将该分支重置为指向该提交的正确父级——毕竟,分支只是指向特定提交的指针。然而,如果你无论如何都要重新平衡它,那么仅仅做重新平衡可能是有意义的。
- @戴夫:没问题:)
- @安德鲁:我读到这个问题的意思是,发问者在同一时间内抽了好几次车,他现在参加合并委员会的情况不一定是这样的。(再读一遍,我发现前者实际上并不清楚。)无论如何,如果我的假设是正确的,那么主题分支是否指向合并提交并没有多大区别,因为无论如何,以前都会有未经处理的合并。但我同意你的观点:)
- @马克:好的,我显然不会那样读。关于Git,我真正喜欢的一点是它足够灵活,这样的东西完全可以修复,更不用说以许多不同的方式了:)另外,+1表示建议使用gitk。
- 为了澄清,是的,你正确理解了,马克:自从我开始脱离师父以来,我已经拉了好几次车。
- @戴夫舍罗曼,当你说工作很有魅力的时候,你是使用了替代方案还是第一个解决方案。我也处于同样的情况。
- @戴夫舍罗曼,你说得对,第一个选择就像一个魅力!感谢马克的回答。我希望我能投更多的票!
- 我开始遵循这些步骤,但到了reset --hard的部分,看不出我的承诺是如何从master转移到newBranch的。看来,如果我重新设置,我将失去我的承诺。我不需要一些命令把我的承诺转移到新牧场吗?status告诉我,我在master分公司工作,在origin/master前面,由承诺。也许我想要你的选项B,但我不理解它是一套有序的步骤。你能编辑一下吗?谢谢!
- 同样,在上述(主要,非替代)步骤中,git branch new-work不应该是git checkout -b new-work吗?这不是将所有当前工作转移到新分支的步骤吗?看来,正如文中所述,我们创建了一个新的分支,但从未在它上面做过任何工作。对不起,如果我是无知/幼稚的话;我只是不遵循"承诺的改变转移到new-work分支"部分。
- @奥利真的!事实上,我似乎因为这个损失了2天的工作,让我们看看我的日食历史可以给我什么。GRR
- @奥利:不,根据问题中的假设和我在答案顶部列出的假设,答案是正确的。应该在一个单独的新分支上的提交已经在master中;rebase重写master分支,使新提交线性地位于origin/master的顶部,然后git branch new-work创建一个new-work分支,指向master的尖端(当前分支),从而没有将当前分支切换到new-work。所以现在new-work包含了所有新的承诺。然后,重置将当前分支(仍为master)移回origin/master。
- @如果你丢了工作,我很抱歉,但我相信这个答案对最初提问者描述的情况是正确的。(我刚刚回复了奥利的话,希望能澄清一下。)无论如何,为了防止它有助于你的工作回来,我应该说,如果你的工作是在过去几天内(在这个问题和答案的假设之一),你应该能够很容易地通过git reflog检索到它。
- @奥利:也许更好的解释方法是:Git中的分支就像是指向特定提交的标签;如果您在该分支上创建它们,或者可以使用git reset和其他各种方式移动它们,它们会自动移动到新提交。git branch new-work只是说"在我留在当前分支(在本例中是master)的时候创建一个指向这个提交的分支"。所以不需要有一个将提交从master移动到新分支的命令-您只需在那里创建一个新分支,当您重置master时,新分支将保留在master所在的位置。
- 它会类似于做REBASE,然后重置软,然后签出-B新牧场吗?
- 参加聚会有点晚了,但是@olie,仅仅因为在新的分支机构上的Git状态没有显示出领先于master的承诺并不意味着他们实际上不在那里(假设这就是你担心的原因)。尝试将新分支推到源站:您将看到提交存在
- @F&233;lixgagnon grenier,不要担心"迟到"——总是有人在寻找旧问题,每次澄清都会有帮助。谢谢!:)
- @F&233;lixgagnon grenier-实际上,在本地也有承诺,您只需要切换到使用git checkout new-work创建的分支。在意识到这一点之前,我也曾有过一丝恐惧。
- 为了确保git status在git reset之前是干净的,可以使用git stash,然后在重置完成后弹出"git stash"。
如果你的承诺很低,而且你不在乎这些承诺是否被合并成一个巨大的承诺,那么这会很好地工作,并不像git rebase那样可怕:
取消文件的存储(将1替换为提交的)
。
创建新分支
1
| git checkout -b NewBranchName |
添加更改
。
做出承诺
- 要显示易于理解的图形,请使用git log --all --decorate --oneline --graph。
- 嘿@eliux-我错过了相关信息。你能扩张吗?
- 这是一个有用的东西来检查你是否在你所做的事情中得到了想要的结果。
- 谢谢你!!这是一个非常简单的解决方案,而且非常有效!!
我坚持同样的问题。我找到了最简单的解决方案,我喜欢分享。
1)用您的更改创建新的分支。
1
| git checkout -b mybranch |
。
2)在远程服务器上推送新的分支代码。
1
| git push origin mybranch |
号
3)退房到总分行。
号
4)使用远程服务器重置主分支代码并删除本地提交。
1
| git reset --hard origin/master |
号
- 这真是最简单的方法
- 你可以省去第二步。我想,自最高级的答案以来,Git已经改变了,以前不允许这样做。
还有一条路假定Branch1-是具有已提交更改的分支分支2-是理想的分支
1 2
| git fetch && git checkout branch1
git log |
。
选择需要移动的提交ID
1 2 3
| git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push |
现在从初始分支恢复未执行的提交
1 2
| git fetch && git checkout branch1
git reset --soft HEAD~1 |
。
- cherry-pick实际上是最好的"复制/移动单个提交"命令,尤其是当历史对于您的目的来说是一个包袱时。
- 这是迄今为止对这个问题最方便的回答。谢谢你的命令!
- 您是否可以更新上一条评论,其中1或n是未提交的提交数?对于这个问题,这仍然是一个很好的解决方案。
或者,在您提交到错误的分支之后,执行以下步骤:
埃多克斯1〔25〕
埃多克斯1〔26〕
埃多克斯1〔27〕
埃多克斯1〔28〕
江户十一〔29〕号
我可以想象,对于步骤1和步骤2有一个更简单的方法。
怎么办:
从当前头部分支。
确保你是师父,而不是你的新分支。
git reset返回到开始进行更改之前的最后一次提交。
git pull只需重新拉你在重置时丢弃的远程更改。
或者当你试图重新合并分支时会爆炸吗?
- 啊,这基本上是上面@mark longair描述的选项b
我一直使用的一种更简单的方法(假设您希望移动4个提交):
号
(查看您对4个.patch文件执行最后一个命令的目录)
1 2 3
| git reset HEAD~4 --hard
git checkout -b tmp/my-new-branch |
号
然后:
1
| git apply /path/to/patch.patch |
号
按你想要的顺序。
对我来说,这是最好的方法:
检查更改和合并冲突git fetch。
创建一个新的分支git branch my-changes,并将其推送到远程
上游改为新建分支git master -u upstream-branch remotes/origin/my-changes。
把你的承诺推到新的上游分支。
切换回前一个上游git branch master --set-upstream-to remotes/origin/master。
签出你的源的新副本
江户十一〔16〕号
从所需位置创建分支
埃多克斯1〔17〕埃多克斯1〔18〕
添加远程存储库
埃多克斯1〔19〕
获取远程源
埃多克斯1〔20〕
签出所需分支
江户十一〔21〕号
合并源
埃多克斯1〔22〕