如何为源代码控制中的旧标签创建补丁?

20

假设我大约一年前发布了软件的一个版本,并在 Git 中将其标记为 2.3。

所以我不断添加功能和修复错误,不知不觉中,软件现在已经升级到版本 3.0。但现在我发现软件版本 2.3 有一个错误,需要修复它的人还没有准备好升级到版本 3.0。

就Git而言,管理如何应用补丁到2.3并创建软件的版本2.3.1,而不改变Git存储库的历史记录是什么?

例如,我无法检出版本2.3,应用补丁,然后将其标记为2.3.1并将其推送上去,因为那样会创建新的分支。

开发者通常如何管理他们软件的旧版本?

编辑

好的,所以我遵循@AnoE的建议,现在我的工作流程如下,适用于修补早期版本。欢迎提出建议。

git checkout v2.3.0
// Make code changes
git add -A
git commit -m "Fixed a bug in old app"
// Do something to verify the changes work on a different environment
git checkout -b v2_3_1
git tag -a v2.3.1 -m "Fixed small bug."
git push origin v2_3_1
git push --tags

我不得不创建一个分支的原因是,标签在我们的代码库托管解决方案Kiln上无法显示。我不知道其他提供商如Bitbucket或Github是否会显示没有关联分支的标签,或者这是否只是Git存储方式的副作用。当我运行git tag -l时,标签在本地显示,但在Web界面中不可见。在我推送了分支和标签之后,我只是删除了分支,然后它就可以从Web界面正确显示了。

git push --delete v2_3_1
如果有人能解释为什么会发生这样的事情,将不胜感激。

默认情况下,git push命令不会将标签传输到远程服务器。您需要运行:git push origin <tagname>。同样,git tag -d <tagname>只能进行本地删除,而--delete则用于远程删除。如果您仅在本地删除它,则任何git clone操作都会使旧标签重新出现。 - Eran Or
3个回答

20

检查版本2.3,应用补丁,标记为2.3.1,这正是你要做的。

创建一个新的head(或者说是新的分支),对于git来说并不是问题。请注意,“HEAD”在git中没有结构上的意义,它之所以突出,是因为它是当前工作目录中处于活动状态的唯一提交。Git只关心提交,在结构上,你可以拥有任意数量的“顶级”提交。

所以:

git checkout 2.3    # gives you a "detached HEAD" 
git checkout -b dev_2.3    # a new branch, more for convenience
...modify files...
git add ... ; git commit ...
git tag 2.3.1
git branch -D dev_2.3     # get rid of it if you have a feeling that you won't be comming back soon

请记住,在git中,分支和标签都没有什么特别之处。它们只是指向提交的便利贴。以这种方式创建一个(也许是临时的)分支只是更方便,因为如果你进行的回退涉及超过一个快速提交,你可以轻松地在该分支之间切换。


为了补充AnoE非常好的回答。如果您需要将标签推送到远程,请使用:git push origin <tag_name> - bwl1289

0

在Git中,处理发布有两种方式:标签和分支。

标签的一个优点是它们是不可变的(你只能删除/重新创建它们,而分支可以不断增长),然而,出于以下原因,我倾向于使用分支而不是标签来进行发布:

  • 如果您需要基于标签打补丁,则最终会得到一些是标签,一些是分支的版本。这可能会让人感到困惑,特别是如果您不得不进行第二次修补。这时,您将检查第一个补丁分支,因此如果您需要为不熟悉Git的人编写修补程序,则可能会很棘手。
  • 通常,git工具(Gitlab、BitBucket等)都有列出各个分支的页面,并比较前/后提交的工具,使用分支作为参考。虽然也可以用标签做同样的事情,但与分支相比,这并不容易,因为您必须手动选择每个标签。当您想确保旧版本上的补丁存在于最新版本上时,这特别有用。
  • 打补丁不需要创建新分支。通常,补丁不会导致向后兼容性问题,因此您可以将提交添加到release_2.3分支中(仅更新POM从2.3.0到2.3.1),而无需为该补丁创建新分支,使父分支变得无用(除非某些客户端不想要该补丁!)
有人可能会认为标签允许避免创建分支和“污染”存储库中不再使用的发布分支,但考虑到“污染”将取而代之为补丁,这是一个小缺点,我们都知道补丁可以像发布一样多 :)
编辑:您可以完全避免使用分支,并使用100%的标签,但是,如果您需要修补旧版本,则必须进行变基和重写历史记录,我不建议这样做。

0

是的,你更新后的工作流是Gitlab的一个可行解决方案!如果需要cherry-pick(或新的提交/修复),我的fix-old-tag工作的证明如下:

git fetch origin --tags --force
git checkout -b TASK-1063/locale-pkg 1.0.0
git cherry-pick bb8a527 --no-commit
git push --set-upstream origin TASK-1063/locale-pkg
git tag -a 1.1.0 -m "Add locales"
git push origin 1.1.0
git push -d origin TASK-1063/locale-pkg

在此之后,新的1.1.0标签已经发布了,而HEAD仍然是最新的develop分支上的2.0.1标签,因此没有破坏性的更改!

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接