git 使用分布式版本控制时的构建顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/122424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:04:13  来源:igfitidea点击:

Build sequencing when using distributed version control

gitbuild-processdvcs

提问by sfink

Right now, we are using Perforce for version control. It has the handy feature of a strictly increasing change number that we can use to refer to builds, eg "you'll get the bugfix if your build is at least 44902".

现在,我们使用 Perforce 进行版本控制。它有一个方便的特性,即严格递增的更改编号,我们可以用它来指代构建,例如“如果您的构建至少为 44902,您将获得错误修复”。

I'd like to switch over to using a distributed system (probably git) to make it easier to branch and to work from home. (Both of which are perfectly possible with Perforce, but the git workflow has some advantages.) So although "tributary development" would be distributed and not refer to a common revision sequencing, we'd still maintain a master git repo that all changes would need to feed into before a build was created.

我想切换到使用分布式系统(可能是 git),以便更轻松地进行分支和在家工作。(这两者在 Perforce 中都是完全可能的,但是 git 工作流程有一些优势。)因此,尽管“支流开发”将是分布式的,而不是指共同的修订顺序,但我们仍然会维护一个主 git 存储库,所有更改都会需要在创建构建之前输入。

What's the best way to preserve strictly increasing build ids? The most straightforward way I can think of is to have some sort of post-commit hook that fires off whenever the master repo gets updated, and it registers (the hash of) the new tree object (or commit object? I'm new to git) with a centralized database that hands out ids. (I say "database", but I'd probably do it with git tags, and just look for the next available tag number or something. So the "database" would really be .git/refs/tags/build-id/.)

保留严格增加的构建 ID 的最佳方法是什么?我能想到的最直接的方法是有某种提交后钩子,每当主存储库更新时就会触发,它会注册(散列)新的树对象(或提交对象?我是新手git) 带有一个分发 ID 的集中式数据库。(我说“数据库”,但我可能会用 git 标签来做,然后只查找下一个可用的标签号或其他东西。所以“数据库”实际上是 .git/refs/tags/build-id/。 )

This is workable, but I'm wondering if there is an easier, or already-implemented, or standard/"best practice" way of accomplishing this.

这是可行的,但我想知道是否有更简单的,或已经实施的,或标准/“最佳实践”的方式来实现这一点。

采纳答案by J?rg W Mittag

I second the suggestion of using git describe. Provided that you have a sane versioning policy, and you don't do any crazy stuff with your repository, git describewill always be monotonic (at least as monotonic as you can be, when your revision history is a DAG instead of a tree) and unique.

我支持使用git describe. 如果你有一个健全的版本控制策略,并且你没有对你的存储库做任何疯狂的事情,git describe将永远是单调的(至少尽可能单调,当你的修订历史是一个 DAG 而不是一棵树时)和独特的.

A little demonstration:

一个小示范:

git init
git commit --allow-empty -m'Commit One.'
git tag -a -m'Tag One.' 1.2.3
git describe    # => 1.2.3
git commit --allow-empty -m'Commit Two.'
git describe    # => 1.2.3-1-gaac161d
git commit --allow-empty -m'Commit Three.'
git describe    # => 1.2.3-2-g462715d
git tag -a -m'Tag Two.' 2.0.0
git describe    # => 2.0.0

The output of git describeconsists of the following components:

的输出git describe由以下组件组成:

  1. The newest tag reachable from the commit you are asking to describe
  2. The number of commits between the commit and the tag (if non-zero)
  3. The (abbreviated) id of the commit (if #2 is non-zero)
  1. 从您要求描述的提交中可获得的最新标签
  2. 提交和标签之间的提交次数(如果非零)
  3. 提交的(缩写)id(如果#2 非零)

#2 is what makes the output monotonic, #3 is what makes it unique. #2 and #3 are omitted, when the commit isthe tag, making git describealso suitable for production releases.

#2 是使输出单调的原因,#3 是使其独特的原因。#2 和 #3 被省略,当提交标签时,制作git describe也适用于生产版本。

回答by squadette

Monotonically increasing number corresponding to the current commit could be generated with

可以生成与当前提交相对应的单调递增数

git log --pretty=oneline | wc -l

which returns a single number. You can also append current sha1 to that number, to add uniqueness.

它返回一个数字。您还可以将当前的 sha1 附加到该数字,以增加唯一性。

This approach is better than git describe, because it does not require you to add any tags, and it automatically handles merges.

这种方法比 好git describe,因为它不需要你添加任何标签,而且它会自动处理合并。

It could have problems with rebasing, but rebasing is "dangerous" operation anyway.

变基可能会出现问题,但无论如何变基都是“危险的”操作。

回答by joegiralt

    git rev-list BRANCHNAME --count

this is much less resource intensive than

这比资源密集程度要低得多

    git log --pretty=oneline | wc -l

回答by webmat

git tagmay be enough for what you need. Pick a tag format that everyone will agree not to use otherwise.

git tag可能足以满足您的需要。选择一种每个人都同意不以其他方式使用的标签格式。

Note: when you tag locally, a git pushwill not update the tags on the server. Use git push --tagsfor that.

注意:当您在本地标记时,agit push不会更新服务器上的标记。git push --tags为此使用。

回答by CB Bailey

You should investigate git describe. It gives a unique string that describes the current branch (or any passed commit id) in terms of the latest annotated tag, the number of commits since that tag and an abbreviated commit id of the head of the branch.

你应该调查一下git describe。它给出了一个唯一的字符串,它根据最新的带注释的标签、自该标签以来的提交次数以及分支头的缩写提交 id 来描述当前分支(或任何传递的提交 id)。

Presumably you have a single branch that you perform controlled build releases off. In this case I would tag an early commit with a known tag format and then use git describe with the --match option to describe the current HEAD relative to a the known tag. You can then use the result of git describe as is or if you really want just a single number you can use a regex to chop the number out of the tag.

大概你有一个分支,你可以执行受控的构建发布。在这种情况下,我将使用已知标签格式标记早期提交,然后使用带有 --match 选项的 git describe 来描述相对于已知标签的当前 HEAD。然后,您可以按原样使用 git describe 的结果,或者如果您真的只想要一个数字,您可以使用正则表达式将数字从标签中剔除。

Assuming that you never rewind the branch the number of following commits will always identify a unique point in the branch's history.

假设您从不倒回分支,后续提交的数量将始终标识分支历史中的唯一点。

e.g. (using bash or similar)

例如(使用 bash 或类似的)

# make an annotated tag to an early build in the repository:
git tag -a build-origin "$some_old_commitid"

# describe the current HEAD against this tag and pull out a build number
expr "$(git describe --match build-origin)" : 'build-origin-\([0-9]*\)-g'

回答by foxxtrot

I'd use "Labels" Create a label whenever you have a successful (or even unsuccessful) build, and you'll be able to identify that build forever. It's not quite the same, but it does provide those build numbers, while still providing the benefits of distributed development.

我会使用“标签”在您成功(甚至不成功)构建时创建一个标签,并且您将能够永远识别该构建。它并不完全相同,但它确实提供了那些内部版本号,同时仍然提供了分布式开发的好处。

回答by EfForEffort

As you probably know, git computes a hash (a number) that uniquely identifies a node of the history. Using these, although they are not strictly increasing, seems like it would be good enough. (Even better, they alwayscorrespond to the source, so if you have the hash, you have the same code.) They're big numbers, but mostly you can get by with 6 or so of the leading digits.

您可能知道,git 计算唯一标识历史节点的哈希(数字)。使用这些,虽然它们没有严格增加,但似乎已经足够了。(更好的是,它们总是对应于源,所以如果你有散列,你就有相同的代码。)它们是很大的数字,但大多数情况下你可以得到 6 个左右的前导数字。

For example,

例如,

That bug was fixed at 064f2ea...

该错误已在 064f2ea 处修复...

回答by yanjost

With Mercurial you can use the following command :

使用 Mercurial,您可以使用以下命令:

# get the parents id, the local revision number and the tags
[yjost@myhost:~/my-repo]$ hg id -nibt
03b6399bc32b+ 23716+ default tip

See hg identify

汞识别