我想将我已承诺掌握的最后几个提交移动到新的分支,并在做出这些提交之前将master重新带回去。 不幸的是,我的Git-fu还不够坚固,有什么帮助吗?

即我该如何去

master A - B - C - D - E

对此吗?

newbranch     C - D - E/
master A - B

#1楼

移至现有分支

如果要将提交移至现有分支 ,则它将如下所示:

git checkout existingbranch
git merge master         # Bring the commits here
git checkout master
git reset --keep HEAD~3  # Move master back by 3 commits.
git checkout existingbranch

--keep选项保留您可能在不相关的文件中进行的所有未提交的更改,或者如果必须将这些更改覆盖而中止,则中止-与git checkout相似。 如果异常终止, git stash您的更改--hard试,或使用--hard来丢失更改(即使来自提交之间未更改的文件!)

移至新分支

此方法通过使用第一个命令( git branch newbranch )创建一个新分支但不切换到该git branch newbranch 。 然后,我们回滚当前分支(主节点)并切换到新分支以继续工作。

git branch newbranch      # Create a new branch, containing all current commits
git reset --keep HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits
# Warning: after this it's not safe to do a rebase in newbranch without extra care.

但是,请确保要返回多少次提交。 或者,代替HEAD~3 ,可以简单地提供的提交的哈希(或类似的参考origin/master )要恢复到,例如:

git reset --keep a1b2c3d4

警告:在Git 2.0版及更高版本中,如果稍后git rebase将新分支重新设置为原始( master )分支,则在重新设置过程中可能需要显式的--no-fork-point选项,以避免丢失从主分支。 branch.autosetuprebase always设置branch.autosetuprebase always使其更有可能。 有关详细信息,请参见John Mellor的答案 。


#2楼

只是这种情况:

Branch one: A B C D E F     J   L M  \ (Merge)
Branch two:             G I   K     N

我执行了:

git branch newbranch
git reset --hard HEAD~8
git checkout newbranch

我以为我将成为HEAD,但是现在是L了……

为了确保在历史记录中找到正确的位置,使用提交的哈希值比较容易

git branch newbranch
git reset --hard #########
git checkout newbranch

#3楼

从技术上讲,这并不是“移动”它们,但是具有相同的效果:

A--B--C  (branch-foo)\    ^-- I wanted them here!\D--E--F--G  (branch-bar)^--^--^-- Opps wrong branch!While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)A--B--C  (branch-foo)\\D-(E--F--G) detached^-- (branch-bar)Switch to branch-foo
$ git cherry-pick E..GA--B--C--E'--F'--G' (branch-foo)\   E--F--G detached (This can be ignored)\ /D--H--I (branch-bar)Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:A--B--C--E'--F'--G'--L--M--N--... (branch-foo)\\D--H--I--J--K--.... (branch-bar)

#4楼

另一种方法,仅使用2个命令。 还可以保持您当前的工作树完整无缺。

git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit

旧版本 -在我了解git branch -f

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit

能够push . 是个不错的窍门。


#5楼

为此,无需重写历史记录(例如,如果您已经推送了提交):

git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>

然后可以不加力地推开两个分支!


#6楼

先前的大多数答案都是危险的错误提示!

不要这样做:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

下次运行git rebase (或git pull --rebase )时,这3个提交将被从newbranch静默丢弃! (请参阅下面的说明)

而是这样做:

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
  • 首先,它丢弃最近的3次提交( --keep类似于--hard ,但更安全,因为失败而不是丢弃未提交的更改)。
  • 然后它分叉newbranch
  • 然后,将这3次提交重选到newbranch 。 由于它们不再被分支引用,因此可以使用git的reflog来做到这一点: HEAD@{2}HEAD以前引用2个操作的提交,即在我们1.检出newbranch和2.使用git reset以丢弃3次提交。

警告:默认情况下已启用reflog,但是如果您手动禁用了reflog(例如,通过使用“裸露”的git存储库),则在运行git reset --keep HEAD~3后,您将无法取回3次提交git reset --keep HEAD~3

不依赖引用日志的替代方法是:

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3

(如果您愿意,可以编写@{-1} -先前签出的分支-代替oldbranch )。


技术说明

为什么在第一个示例之后git rebase丢弃3次提交? 这是因为不带参数的git rebase默认情况下会启用--fork-point选项,该选项使用本地reflog尝试对强行推入的上游分支保持鲁棒性。

假设您在包含提交M1,M2,M3的情况下分支了Origin / master,然后自己进行了三个提交:

M1--M2--M3  <-- origin/master\T1--T2--T3  <-- topic

但是随后有人通过强制按原点/原版来重写历史记录以删除M2:

M1--M3'  <-- origin/master\M2--M3--T1--T2--T3  <-- topic

使用本地reflog, git rebase可以看到您是从origin / master分支的较早版本分支出来的,因此M2和M3提交实际上不是您的主题分支的一部分。 因此,可以合理地假设由于M2已从上游分支中删除,因此一旦主题分支重新建立基础,您就不再希望在主题分支中使用它:

M1--M3'  <-- origin/master\T1'--T2'--T3'  <-- topic (rebased)

这种行为是有道理的,并且在重新定基时通常是正确的做法。

因此以下命令失败的原因:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

是因为它们使reflog处于错误状态。 Git认为newbranch在包含3个提交的修订版本中分叉了上游分支,然后reset --hard重写了上游的历史记录以删除提交,因此,下次运行git rebase它将像其他提交一样丢弃它们已从上游移除。

但是在这种特殊情况下,我们希望将这3个提交视为主题分支的一部分。 为此,我们需要在不包含3个提交的早期版本中分叉上游。 这就是我建议的解决方案所做的,因此它们都使reflog保持正确的状态。

有关更多详细信息,请参见git rebase和git merge-base文档中的--fork-point定义。


#7楼

使用git stash更简单的解决方案

这是提交错误分支的简单得多的解决方案。 从具有三个错误提交的分支master节点开始:

git reset HEAD~3
git stash
git checkout newbranch
git stash pop

什么时候使用?

  • 如果您的主要目的是回滚master
  • 您想保留文件更改
  • 您不在乎有关错误提交的消息
  • 你还没推
  • 您希望这容易记住
  • 您不希望出现诸如临时/新分支,查找和复制提交散列以及其他麻烦之类的复杂情况

这是做什么的,按行号

  1. 撤消对master的最后三次提交(及其消息),但所有工作文件保持不变
  2. 整理所有工作文件的更改,使master工作树与HEAD〜3状态完全相等
  3. 切换到现有分支newbranch
  4. 将隐藏的更改应用于工作目录并清除隐藏

现在,您可以像平常一样使用git addgit commit 。 所有新的提交都将添加到newbranch

这不行

  • 它不会使随机的临时树枝杂乱无章
  • 它不会保留错误的提交消息,因此您需要向此新提交添加新的提交消息。

目标

OP指出,目标是“在做出这些提交之前将主服务器重新带回”而不会丢失更改,而此解决方案可以做到这一点。

我这样做至少每周一次,当我不小心做出新的提交给master ,而不是develop 。 通常我只有一个提交回滚,在这种情况下,在第1行使用git reset HEAD^是回滚一个提交的更简单方法。

如果您将主控的更改推到上游,请不要这样做

其他人可能已经撤消了这些更改。 如果仅重写本地母版,将其推入上游不会有任何影响,但是将重写的历史记录推向协作者可能会引起头痛。


#8楼

您可以做到这只是我使用的3个简单步骤。

1)在要提交最近更新的位置创建新分支。

git branch <branch name>

2)查找要在新分支上提交的最近提交ID。

git log

3)复制该提交ID,请注意,最新提交列表位于顶部。 这样您就可以找到自己的提交。 您也可以通过消息找到它。

git cherry-pick d34bcef232f6c...

您还可以提供一定范围的提交ID。

git cherry-pick d34bcef...86d2aec

现在您的工作完成了。 如果您选择了正确的ID和正确的分支,那么您将成功。 因此,在执行此操作之前请先小心。 否则可能会发生另一个问题。

现在您可以推送代码

git push


#9楼

1)创建一个新分支,它将所有更改移到new_branch。

git checkout -b new_branch

2)然后回到旧分支。

git checkout master

3)做git rebase

git rebase -i <short-hash-of-B-commit>

4)然后打开的编辑器包含最后3个提交信息。

...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...

5)更改pickdrop所有这3个提交。 然后保存并关闭编辑器。

...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...

6)现在,最后3个提交已从当前分支( master )中删除。 现在用力推分支,在分支名称前加+号。

git push origin +master

#10楼

我该如何去

A - B - C - D - E |master

对此吗?

A - B - C - D - E |           |master      newbranch

用两个命令

  • git branch -m主newbranch

给予

A - B - C - D - E |newbranch

  • git分支主管B

给予

A - B - C - D - E|           |master      newbranch

#11楼

如果您只需要将所有未推送的提交移动到新分支 ,则只需,

  1. 从当前分支 创建一个新分支git branch new-branch-name

  2. 推送您的新分支git push origin new-branch-name

  3. 您的旧(当前)分支 恢复到上一推送/稳定状态: git reset --hard origin/old-branch-name

有些人还有其他upstreams而不是origin ,应该使用适当的upstream


#12楼

对于那些想知道它为什么起作用的人(就像我刚开始那样):

您想回到C,然后将D和E移到新分支。 最初的样子是这样的:

A-B-C-D-E (HEAD)↑master

git branch newBranch

    newBranch↓
A-B-C-D-E (HEAD)↑master

git reset --hard HEAD~2之后:

    newBranch↓
A-B-C-D-E (HEAD)↑master

由于分支只是一个指针,因此master指向最后一次提交。 当您创建newBranch时 ,您仅创建了指向最后一次提交的新指针。 然后使用git reset指针移回两次提交。 但是由于您没有移动newBranch ,所以它仍然指向它最初执行的提交。


#13楼

一般来说...

在这种情况下,sykora公开的方法是最佳选择。 但是有时不是最简单的方法,也不是通用方法。 对于一般方法,请使用git cherry-pick

为了实现OP想要的功能,它需要两个步骤:

第1步-记下您想要在新newbranch上提交的master提交的newbranch

执行

git checkout master
git log

注意在newbranch想要的(假设3)提交的哈希值。 在这里我将使用:
C提交: 9aa1233
D提交: 453ac3d
E提交: 612ecb3

注意:您可以使用前七个字符或整个提交哈希

第2步-将它们放在新newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

或(在Git 1.7.2+上,使用范围)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git cherry-pick将这三个提交应用于newbranch。

使用Git将最新提交移至新分支相关推荐

  1. 11、git查看往日提交以及删除分支ID命令

    git查看往日提交以及删除分支ID  git reflog --date=iso

  2. git cherry-pick 把提交到A分支的部分commit 再提交到B分支上

    应用环境: 有一个主分支 master (这个分支只是用来合并其他通过测试的分支,及上线打版本) 另一个分支 dev (开发提交的分支) 当你通过一番挣扎终于搞定一个bug,顺手提交到 git 服务器 ...

  3. git将代码提交到远程分支(非主分支)

    一个仓库可以包含多个分支,有一个默认的主分支:master 若想提交代码至远程仓库的某个分支(非主分支) 先查看下本地分支以及远程分支:git branch -a 由本地分支(非主分支master)提 ...

  4. git 挽救忘记提交到哪个分支的代码

    2019独角兽企业重金招聘Python工程师标准>>> 代码丢失了,总是让人感觉神情恍惚,跟女朋友漏气一样的心情.没办法,只能找回了,不然昨天的工作就白干了,免不了头头还可能说昨天汇 ...

  5. git push时提示:更新被拒绝,因为您当前分支的最新提交落后于其对应的远程分支

    在对本地库中的文件执行修改后,想git push推送到远程库中,结果在git push的时候提示出错: ! [rejected]        master -> master (non-fas ...

  6. git常用命令(克隆、分支、tag标签、推送、日志查看,常用命令总结)、将本地代码第一次提交到远程git仓库、过滤掉不提交的内容

    1.1 克隆Git代码 $ git clone http://xxxx.git --branch master 为自己的写新项目添加git版本控制,进入项目目录执行以下命令: git init . 2 ...

  7. git常用操作--分支同步master 本地库提交到远程分支

    1.分支同步master git clone [项目地址] //克隆远程代码库到本地 cd [刚刚克隆的项目文件夹] //进入本地仓库 git checkout -b dev // 创建分支dev(或 ...

  8. IDEA Git 复制分支到新分支 提交到新分支

    目录 前言:在原有代码基础改出来另一个版本 该出的版本不能提交到当前分支,需要提交到新的分支 所以要新建个分支原来分支上的数据也要在 之前对git的操作不够熟练忙活一上午 才搞明白 下面记录一下怎么操 ...

  9. git提交本地项目gitlab合并分支提交代码合并分支时的冲突解决git拉取新项目

    总结:选中右键 git add commit pull 运行 push 一.把dev(主分支)合并到本地自己的分支 1.选中要提交的对象(可以是整个项目,也可以是单模块提交) 2.右键-Git-Add ...

最新文章

  1. 全球及中国高压和超高压波纹铝护套交联聚乙烯电缆行业产销现状与投资策略建议报告2021-2027年版
  2. tp5视图里写原生php,tp5中使用原生sql查询总结
  3. Oracle NVL与Coalesce函数的区别
  4. 使用CodeDom生成程序集
  5. php 前置匹配,浅析PHP正则表达式匹配的特定实现
  6. CSS3 -- display:flex
  7. html纵向固定导航菜单代码,CSS3单页面垂直固定导航
  8. 24个整点报时_大连交通广播整点报时广告怎么做?大连交通广播全新广告价格...
  9. WPF内嵌WCF服务对外提供接口
  10. error LNK2001: 无法解析的外部符号 __iob_func
  11. 跨域 SameSite secure
  12. 【学习笔记】Kruskal 重构树(BZOJ3551【ONTAK2010】Peaks加强版)
  13. 文字转语音,有什么软件好用?
  14. flask后台开发之数据库交互
  15. 周志华----机器学习2
  16. Matlab龚珀兹曲线模型预测,指数曲线模型的讲解=.pptx
  17. 解压apk后各文件夹含义
  18. python中pprint模块
  19. CentOS7安装OpenStack(Rocky版)-02.安装Keyston认证服务组件(控制节点)
  20. 三菱CC-link IE field basic 控制伺服轴

热门文章

  1. 算法-----------乘积最大子数组(Java版本)
  2. 2019计算机原理及应用期末自测题,微机原理期末自测题答案.ppt
  3. python requests库用法_python之requests库的使用
  4. (0094)iOS开发之本地文件预览的三种方法(2)
  5. Flutter开发之布局-3-center(17)
  6. linux sleep alarm,Linux环境编程之信号处理(三、利用alarm()和pause()函数实现sleep()函数)...
  7. Codeforces 479【E】div3
  8. Uva1627 Team them up!
  9. [CF816B] Karen and Coffee(前缀和,思维)
  10. Difference between prop and attr in different version of jquery