将 git 分支转换为 git 标签
我正在寻找将 git 分支转换为 git 标签的最佳和最安全的方法。当手动移植 svn 存储库时,我基本上复制了所有分支,并且每个次要版本(1.1、1.2、1.3)都有一个分支,老实说,这可能不是最好的方法,但为了速度,当时我对分支比标签更满意。我现在有分支 1.5、1.6、1.7、1.8,但是由于我们在任何给定时间只部署了 1 个版本的代码,我可能只需要最后一个版本作为分支,以防任何修补程序需要进入该版本已部署。所以我正在寻找将 git 分支转换为 git 标签的最佳方法。我想我有办法,但确定它有多好。
到目前为止我所做的是对于我想要转换为标签的每个分支,我已经检查以确保那些不在主分支中的分支中没有提交,所以我做了:
git log 1.5 ^master
git log 1.6 ^master
git log 1.7 ^master
所有这些都没有返回给我任何内容我相信这意味着这些分支中的所有提交都存在于 master 中。我这样做是因为我假设如果那些分支中存在不在 master 中的提交,那么当将分支转换为标签时我会丢失它们,因为标签只是指向一个提交的“指针”而不是开发线。看起来不错,我的假设是我只需要这样做:
git tag 1.5v 1.5
git tag 1.6v 1.6
git tag 1.7v 1.7
然后我只需要在本地删除分支并将这些更改推送到远程存储库。这是将 git 分支转换为 git 标签的最佳方法吗?
我还担心的一个问题是,如果有人从 1.7 版本创建了一个分支(没有人应该这样做),并且他们提取了删除该分支的更改,他们是否能够将这些更改合并到另一个分支(例如 master)中,或者会这样吗?打破他们创建的分支?这种情况不应该发生,因为除了最后一个版本(在本例中为 1.8)之外,不应从任何分支版本创建分支,但人们并不总是正确遵循程序,所以我想确保有一种方法如果发生这种情况,请修复此问题。
I am looking for the best and safest way to convert a git branch to a git tag. When porting over a svn repository by hand, I basically copied over all our branches and we had a branch for each minor release (1.1, 1.2, 1.3) which in all honesty probably was not the best way of doing that but for the sake of speed, I was more comfortable with branches than tags at the time. I now have branches 1.5, 1.6, 1.7, 1.8 however since we only ever have 1 version of the code deployed at any given time, I probably only need the last version to be a branch incase any hot fixes need to go into that version that is deployed. So I am looking for the best way to convert a git branch to a git tag. I think I have a way but done sure how good it is.
What I have done so far is for each branch I want to convert to a tag, I have checked to make sure there are no commits in those branches that are not in the master branch, so I did:
git log 1.5 ^master
git log 1.6 ^master
git log 1.7 ^master
All of these return me nothing which I believe means all of the commits in those branches exist in master. I did this because I assumed if there were commits in those branches that were not in master, I would lose them when converting the branch to a tag as a tag is just a "pointer" to one commit and not a development line. With that seeming good, my assumption is that I would just have to do:
git tag 1.5v 1.5
git tag 1.6v 1.6
git tag 1.7v 1.7
Then I would just have to delete the branches locally and push those changes to the remote repository. Is this the best way of converting a git branch to a git tag?
Also one concern I have is if someone created a branch from say 1.7 (which no one should of) and they pull the changes that delete that branch, would they be able to merge those changes into another branch (say master) or would that kind of break the branch they created? This is a case that should not happen since no one should be created branches off of any branch version other than the version last one, in this case 1.8, but people do not always following procedure properly so I want to make sure there is a way to fix this if it happens.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简短回答:这不是问题。按照您建议的方式创建标签是可以的,尽管我建议您使用
-m
选项来创建带有注释的带注释标签(请参阅man git-tag
),如下所示这将创建一个“first class”标签,将由 git describe 等使用,无需额外参数。长答案:
远程分支不会直接影响本地分支。如果我从公共存储库中的分支或标签创建分支,当您删除该分支并获取您的存储库时,我会看到您的分支已消失,但我的分支在我的存储库中仍然完整。
括号只是 git 存储库中提交的符号名称,当您提交 HEAD 时,您正在处理的分支指向新提交。标签也是提交的符号名称,但这是不可更改的(虽然可以删除它,但不能更改),因此它指向历史记录中的固定位置,而分支则指向移动头历史上的一行。由于 git 中的提交有零个、一个或多个父提交(零个用于初始提交,一个用于正常提交,多个用于合并),即使原始分支或标签从远程删除,您的本地存储库仍然有一个指向本地分支的指针,从中您可以找到一个共同的祖先(假设分支首先是相关的),因此您仍然可以将对任何分支所做的更改合并到主分支中。
从 svn 到 git 一开始可能会有点混乱。听起来你仍在用 svn 术语思考,这让一切变得更加混乱。我认为,如果您将 git 更多地视为一种高级文件系统(这就是 Linus Torvalds 编写它时的情况),而不是源代码控制工具,那就更容易了。我还建议你花一些时间阅读(或浏览)计算机科学家的 git,它并不像听起来那么令人畏惧;更好地理解它的实际工作原理将帮助您以“正确的方式”思考。 ;)
Short answer: it's not a problem. And creating tags the way you propose is okay, although I suggest you use the
-m
option to create an annotated tag with a comment (seeman git-tag
), as this will create a "first class" tag that will be used bygit describe
etc. without additional arguments.Long answer:
Remote branches will not affect the local branches directly. If I create a branch from a branch or a tag from your public repo, when you delete that branch, and I fetch your repo, I will see that your branch is gone, but my branch is still complete in my repo.
Brances are only symbolic names for the a commit in a git repo, when you commit the HEAD and the branch you're working on points to the new commit. A tag is also a symbolic name for a commit, but this is not changeable (you can delete it, though, but it cannot be changed), so it points to a fixed location in the history, while a branch point to the moving head of one line in the history. Since commits in git have zero, one or more parent commits (zero for initial commit, one for a normal commit, more than one for a merge), even if the original branch or tag is deleted from the remote your local repo still have a pointer to you local branch and from this you can find a common ancestor (assuming the branches are related in the first place), so you can still merge in changes done to any of your branches into master.
Coming from svn to git can be a bit confusing at first. It sounds like you're still thinking in svn terms, making everything more confusing. I think it's easier if you think of git more as an advanced filesystem (which is what Linus Torvalds were when he wrote it), instead of a source control tool. I also suggest you take some time to read (or skim through) git for computer scientists, it's not as daunting as it sounds; and having a better understanding of how it actually works will help you thinking the "correct way". ;)
据我了解,您希望创建标签而不是分支,从而防止其他人继续在这些分支上提交。
不幸的是,你无法阻止人们从他们想要的任何地方创建分支,特别是因为 Git 是一个分散的 VCS。但是,您可以决定是否可以将提交推送到中央存储库。因此,您可以编写钩子来禁止在其祖先中具有特定提交的提交。
As I understand it, you want to create tags instead of branches and thereby prevent others to continue committing on these branches.
Unfortunately, you cannot prevent people from creating branches from wherever they want, especially since Git is a decentralized VCS. However, you can decide whether a commit can be pushed to a central repository. So you could write hooks that would forbid commits that have specific commits in their ancestors.