我为了测试目的创建了一个额外的分支。
在开始工作之前,我切换回主分支,喝完茶后开始在主分支中添加文件和修改其他一些文件。
只有在提交后,我才想起自己应该在开始更改之前切换到我的第二个分支。
请问能否将此提交发送到第二分支并从主分支中删除它?
谢谢。
我为了测试目的创建了一个额外的分支。
在开始工作之前,我切换回主分支,喝完茶后开始在主分支中添加文件和修改其他一些文件。
只有在提交后,我才想起自己应该在开始更改之前切换到我的第二个分支。
请问能否将此提交发送到第二分支并从主分支中删除它?
谢谢。
如果我理解正确,您可以做这样的事情:
git checkout master
git log
now check hash commit you want to move - for example: 0123456
git checkout branch
git cherry-pick 0123456
git checkout master
git revert 0123456
就这些。
git reset
步骤,是专门针对“您在错误分支的顶端进行了提交”的情况。 - torek$ git checkout newbranch
$ git cherry-pick master
此时,您将在 newbranch
分支上,并且提交记录已被复制。现在,您需要处理 master
分支上的旧提交记录。
如果您还没有在任何地方发布(推送或让其他人拉取)此提交记录,您只需“回滚”即可:
$ git checkout master
$ git reset --hard HEAD^ # be careful here! I always run "git status" first
git reset --hard
会清除任何正在进行的工作。1除非使用-n
或--no-commit
来抑制它,或者git无法进行相同的更改并告诉您存在冲突并让您自己解决。
这里是关于git及其提交和分支的事情。与大多数其他版本控制系统不同,git在分支上执行提交时,分支名称实际上不是提交的一部分。2 您分配分支名称(或标签,无论您想如何称呼这些),但实际的分支结构 -“结构性分支”-是由每个提交的历史记录形成的。
A <-- B <-- C <-- master
^
\
D <-- branch
D
是分支branch
的最新版本,并将其父提交指向C
。提交C
将其父提交指向B
,B
将其父提交指向初始提交A
(根提交,没有父提交)。A
到C
(这次我不会用那么多箭头画出它们,只需假定箭头一般指向左边)。A - B - C <-- HEAD=master
这次我添加了HEAD=
,以展示git如何跟踪你所在的分支。(在.git
目录下的HEAD
文件只包含分支的名称:cat .git/HEAD
,通常会看到ref:refs/heads/master
或其他类似的内容。)如果你现在运行git checkout -b 分支名
,你会得到如下结果:
A - B - C <-- master, HEAD=branch
现在.git/HEAD
包含的是分支而不是主分支master
。
当你创建一个新的提交(包括使用cherry-pick和revert创建的任何新提交)时,Git会查看HEAD
以确定你所在的分支以及该分支的SHA-1 ID。这就是“分支的末端”。然后,Git会创建一个新的提交,其父提交是旧的分支末端,并将新的提交ID写入分支文件中,使得分支名称指向新的提交。(当然,HEAD
仍然只有分支名称。)
因此,如果你“在分支branch
上”并创建一个新的提交D
,那么你会得到以下结果:
A - B - C <-- master
\
D <-- HEAD=branch
如果你出了一点差错,并且处于“主分支 master
”上,你会得到以下结果:
A - B - C <-- branch
\
D <-- HEAD=master
master
的指针指向branch
所在的位置,让branch
指向master
所在的位置,并将HEAD
切换为显示branch
而不是master
。branch
以便更改master
。然后将master
重命名为branch
,并将branch
的新名称重命名为master
:$ git branch -m branch temp
$ git branch -m master branch
$ git branch -m temp master
branch
为temp
。第二步更改master
为branch
(并且您仍然在其中,因此也会重写HEAD
)。最后一步更改temp
为master
,从而为您最初想要的提交DAG和标签设置。与其他部分一样,您应仅尝试对未发布(未推送)的提交进行此类“标签交换”。这样做的原因很简单:当您发布提交时,它是通过名称到提交ID映射来完成的。如果您重新洗牌标签并“重新发布”,则提交ID不会更改,但名称到ID的映射会更改,因此任何捡起您先前广告的人,例如 master
表示 bb71dde ...
,现在获得一个与旧映射不“快进相关”的新映射. 人们和git都希望分支映射发生变化,但通常只以“快进方式”进行。例如,在Mercurial中,分支名称实际上记录在提交数据内。push
到只有您可以访问的存储库中,则可以使用后续的push -f
覆盖它。 - kjogit reset HEAD^
,不带 --hard
,然后再提交你本来想提交的内容。(我想。我还在学习这个东西。我可能会将其作为单独的答案发布。) - Steve Summit
git reset --soft HEAD^
,git checkout second-branch
和git commit
。 - Dogbert