我们有一种情况(对于这个例子)我们有一条直线的开发准备发布:
A --> B --> C --> D
^ HEAD
我们认为提交C
和D
过于思考,我们希望从B
发布。我们有一个工具可以返回并标记B
作为我们的发布版本,比如说product-1.0.0
,然后将许多版本控制文件更新为1.1.0
,或者下一个版本。< / p>
问题是标签的创建,以及文件的调整,都是原子操作。我们可以改变这一点,但这有点麻烦。
因此,虽然标记需要指向B
,但我们希望将文件更改弹出到新的提交中。我们现在有什么:
v detached, tagged, with local changes
|
A --> B --> C --> D
^ HEAD
但是,如果我们从目前的观点出发,我们最终会:
/--> E (a 'lost' commit)
/
A --> B --> C --> D
^ tag ^ HEAD
最简单的方法是,从“与本地更改分离”或“丢失提交”点,将我们的本地更改或新提交合并到公共分支,使其看起来像:
A --> B --> C --> D --> E
^ tag ^ NEW HEAD
提交C
和D
以及整个分支都是公开的 - 因此我们无法真正在E
和{{1}之间注入提交B
}}。如果这些提交(C
和C
)作为我们发布的产品的“更新”D
版本存在,那也没关系,我们只想在当前创建一个新提交1.0.0
。
有没有比存储更好的方法,查看HEAD
,然后弹出并提交?
答案 0 :(得分:1)
此答案显示了一个工作流程,它使用本地分支作为存储机制的替代方法。这是我喜欢的方法。
我将假设:
master
product-1.0.0
)最终需要指向B. E
和C
之后,需要将发布提交(D
)“添加”到主提示。master
签出,工作树干净。历史记录最初看起来像这样(origin
遥控器代表公开的内容,HEAD
指向您当前签出的分支机构负责人:
(A)<--(B)<--(C)<--(D)
^ ^
/ \
master orgin/master
^
|
HEAD
您需要自己查看此图表。我通常使用像这样的git别名(g
表示“graph”):
git config --global alias.g "log --decorate --oneline --graph"
然后您可以通过调用以下内容获取上述图片:
git g master origin/master
(显示从master
和/或origin/master
可以到达的所有内容。使用git g --all
显示每个人。)
首先创建一个名为temp
的本地临时分支头,指向B
,然后将其检出。
git branch temp <SHA1 of B>
git checkout temp
提交图现在看起来像这样:
HEAD
|
v
temp
|
v
(A)<--(B)<--(C)<--(D)
^ ^
/ \
master orgin/master
运行发布脚本,该脚本标记当前提交,进行更改(可能会增加版本号或其他内容),然后提交更改。
<magic release script>
如果我正确理解了您的发布脚本,那么结果图应如下所示:
HEAD
|
v
temp
|
v
tag: product-1.0.0 (E)
\ /
v v
(A)<--(B)<--(C)<--(D)
^ ^
/ \
master orgin/master
现在是时候回到master
并“继承”E
提交:
git checkout master
git cherry-pick <SHA1 of E>
cherry-pick
命令将单个提交视为补丁。 “补丁”包含B
处的树快照与E
处的快照之间的差异。然后将此“补丁”应用于您签出的任何分支头 - 在本例中为master
。修补程序中的更改将生成一个具有相同消息的新提交(F
),并将作者作为原始提交(E
)。
temp
|
v
tag: product-1.0.0 (E)
\ /
v v
(A)<--(B)<--(C)<--(D)<--(F)
^ ^
| |
origin/master master
^
|
HEAD
请注意,F
提交与E
提交不同!它只是“在精神上是一样的”,即它引入了相同的逻辑变化。
在此之后,请检查最终状态,您应该准备好将新的master
州推送到origin
以使其公开。
git push origin master:master
您现在可以删除临时temp
分支头:
git branch -D temp
您通常使用-d
选项删除分支,但git
不允许您在此处使用它。原因是您将丢失E
提交。在这种情况下,可以使用E
“保存”cherry-pick
。由于git
认为E
和F
是不同的提交,因此无法知道E
的精神仍然存在于F
中,并且不会提供任何信息丢失。您需要告诉git
您已使用-D
代替-d
确保知道自己在做什么。
最后你应该:
tag: product-1.0.0
|
v
(A)<--(B)<--(C)<--(D)<--(F)
^ ^
/ \
origin/master master
^
|
HEAD
答案 1 :(得分:0)
在你的标签处分支并将E放在该分支上并将branch_E合并回你的主分支,或者只是在D之后将主要分支上的提交E提交回来。