在git中我想“标记”某些提交。例如,我想“标记”破坏软件REST API的提交,这样我就可以记住碰到主要版本号。 (我使用semantic versioning)。
理想情况下,我应该能够发出一个git命令来查看自上次发布/标记以来的任何提交是否包含“标记”,因为我知道下一个版本没有。应该碰到主要的号码。
“标记”不是标记(以git术语表示),因为标记是唯一的。我预计,自上次发布以来可能会有几个相同的“标记”,表示API已被破坏。
目前的解决方法是在提交消息中写入“MAJOR:”或“MINOR:”。
对于我如何使用git有什么建议吗?
答案 0 :(得分:1)
标签名称必须是唯一的 - 但是 mark/
以<{1>}开头的 1 的唯一标签名称是无限的,例如{{1 },mark/1
等等。或者,您可以使用不在mark/2
中的引用名称;或者你可以使用Git的“注释”,虽然更容易检测标签或其他引用是否是一个提交的祖先和另一个提交的后代:
refs/tags/
(这假设您永远不会使用highmark=$(git for-each-ref --format='%(refname)' refs/marks | wc -l)
nextmark=$((highmark + 1)
git update-ref refs/marks/m$nextmark HEAD
删除任何这些标记 - 如果您执行“高分”计算,则必须找到现有的最高数字而不是简单计数。要测试标记$ N是否在标记T1和HEAD之间“
git update-ref -d
或者,您可以在存储库中或存储库外部存储,如果在存储库中,在普通blob中 - 一个blob是Git的原始文件数据的内部格式 - 一个只包含所有“标记”的哈希ID的文件提交。文件本身可以存储在标记或以其他方式引用的提交中,该提交可以但不必是在任何分支上;或者你可以标记blob本身。例如:
if git merge-base --is-ancestor T1 refs/marks/m$N &&
git merge-base --is-ancestor refs/marks/m$N HEAD; then
... mark N is at or beyond tag T1 and at or before HEAD ...
else
... mark N is not between those two points (inclusive) ...
fi
如果将blob存储在提交下,则可以通过为每个新更新的“标记ID”文件进行新提交来保留标记历史记录。这在某种程度上类似于git show marks > /tmp/all-marks # extract existing marks
git rev-parse HEAD >> /tmp/all-marks # add a new mark
git tag -f marks $(git hash-object -w --stdin < /tmp/all-marks)
的工作方式,但不是编写名称为提交ID的文件,而是编写一个名为“marks”的文件(通过树然后指向的文件存储)通过提交,标记引用 - 无论是git notes
之类的标记,如上面的标记示例,还是像refs/tags/marks
之类的引用,如上面的refs/marks
系列引用,但仅使用一个参考)。由于每个提交都有一个父指针,您可以保存先前的提交,这将保存以前的树,这将保存以前的blob / marks文件,您甚至可以在这些提交上运行m
,以查看谁更新了标记,何时等等。
1 嗯,有限,但仅限于磁盘空间和名称模式。这里提出的模式,在单个名称空间中的文件名中以十进制计数,在典型的Unix-ish文件系统上只能计数10 254 ,其255个字节的组件名称长度限制。实际上,在将名称分层之前,你可能不想超过一千左右,例如,git log
一旦你进入几百万个标记的提交。
操作系统也会施加最大路径长度,但是在达到提交ID之前很久就会用完提交ID:2 160 仅为1 461 501 637 330 902 918 203 684 832 716 283 019 655 932在short scale命名法中,542 976,或大约1.462 sexdecillion。更糟糕的是,无论如何,在几个quintillion对象之后你发生哈希冲突的可能性太大了,所以我们只需计算10个 18 。