我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。
假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。
我们在工作中使用SVN,但在我的个人项目中,我决定使用Git。所以我昨天安装了Git,我想知道Git中对应的版本号是多少。
假设我们在3.0.8版本上工作,当我们讨论这个错误修复时,每个错误修复都有自己的修订号。那么,如果我在Git中将代码标记为3.0.8,那么我可以使用什么作为修订号或其他更详细的标识?我发现哈希对人类不太友好。
当前回答
不管对你来说是好消息还是坏消息,哈希值就是修订号。当我从SVN切换到git时,我也遇到了这个问题。
你可以在git中使用“tagging”将某个修订标记为特定版本的“release”,这样就可以方便地引用该修订。看看这篇博客文章。
要理解的关键是git不能有修订号——想想去中心化的本质。如果用户A和B都提交到他们的本地存储库,git如何合理地分配一个连续的修订号?在他们相互推动/拉动对方的变化之前,A对B一无所知。
另一件需要考虑的事情是用于修复错误的分支的简化分支:
从一个版本开始:3.0.8。然后,在释放之后,这样做:
git branch bugfixes308
这将为错误修复创建一个分支。检查分支:
git checkout bugfixes308
现在进行任何您想要的错误修复更改。
git commit -a
提交它们,然后切换回主分支:
git checkout master
然后从另一个分支中导入这些更改:
git merge bugfixes308
这样,您就有了一个单独的特定于发行版的错误修复分支,但是您仍然将错误修复更改拉到您的主开发主干中。
其他回答
我只是想指出另一种可能的方法-那就是使用git git-notes(1),自v 1.6.6 (Self - git的注释)以来就存在(我使用的是git版本1.7.9.5)。
基本上,我使用git svn克隆了一个具有线性历史的svn存储库(没有标准布局、没有分支、没有标记),并且我想比较克隆的git存储库中的修订号。默认情况下,这个git克隆没有标签,所以我不能使用git describe。这里的策略可能只适用于线性历史-不确定它将如何与合并等;但基本策略如下:
Ask git rev-list for list of all commit history Since rev-list is by default in "reverse chronological order", we'd use its --reverse switch to get list of commits sorted by oldest first Use bash shell to increase a counter variable on each commit as a revision counter, generate and add a "temporary" git note for each commit Then, browse the log by using git log with --notes, which will also dump a commit's note, which in this case would be the "revision number" When done, erase the temporary notes (NB: I'm not sure if these notes are committed or not; they don't really show in git status)
首先,让我们注意到git有一个默认的笔记位置-但你也可以为笔记指定一个ref(erence) -它会将它们存储在.git下的另一个目录中;例如,在git repo文件夹中,你可以调用git notes get-ref来查看该目录:
$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever
需要注意的是,如果你的注释添加了——ref,你也必须在之后再次使用该引用-否则你可能会得到像“没有为对象XXX找到注释…”这样的错误。
对于这个示例,我选择将注释的引用称为“linrev”(用于线性修订)——这也意味着该过程不太可能干扰已经存在的注释。我也使用——git-dir开关,因为是一个git新手,我有一些问题理解它-所以我想“记住以后”:);并且我还使用——no-pager来抑制生成较少时使用git日志。
假设你在一个目录下,子文件夹myrepo_git是一个git仓库;你可以这样做:
### check for already existing notes:
$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision
$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
echo "$TCMD"; \
eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"
### check status - adding notes seem to not affect it:
$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../
### check notes again:
$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)
### note is saved - now let's issue a `git log` command, using a format string and notes:
$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000: >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000: >>initial test message 1<< (r1)
### test git log with range:
$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 << (r15)
### erase notes - again must iterate through rev-list
$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
TCMD="$TCMD remove $ih"; \
echo "$TCMD"; \
eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33
### check notes again:
$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
因此,至少在我的完全线性历史没有分支的特定情况下,修订号似乎与这种方法相匹配-此外,似乎这种方法将允许使用修订范围的git log,同时仍然获得正确的修订号- YMMV具有不同的上下文,尽管…
希望这能帮助到一些人, 干杯!
编辑:好的,这里稍微简单一点,上面的循环有git别名,叫做setlinrev和unsetlinrev;当在你的git仓库文件夹中,do(注意讨厌的bash转义,参见#16136745 -添加一个包含分号的git别名):
cat >> .git/config <<"EOF"
[alias]
setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
TCMD=\"git notes --ref linrev\"; \n\
TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
#echo \"$TCMD\"; \n\
eval \"$TCMD\"; \n\
done; \n\
echo \"Linear revision notes are set.\" '"
unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
TCMD=\"git notes --ref linrev\"; \n\
TCMD=\"$TCMD remove $ih\"; \n\
#echo \"$TCMD\"; \n\
eval \"$TCMD 2>/dev/null\"; \n\
done; \n\
echo \"Linear revision notes are unset.\" '"
EOF
... 所以你可以在尝试做线性修订笔记的日志之前简单地调用git setlinrev;和git unsetlinrev删除这些笔记当你完成;一个来自git repo目录的例子:
$ git log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 <<
$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.
$ git log --notes=linrev --format=format:"%h: %an: %ad: >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000: >>test message 15 <<
shell完成这些别名所需的时间取决于存储库历史记录的大小。
对于有Ant构建流程的人,您可以通过以下目标在git上生成项目的版本号:
<target name="generate-version">
<exec executable="git" outputproperty="version.revisions">
<arg value="log"/>
<arg value="--oneline"/>
</exec>
<resourcecount property="version.revision" count="0" when="eq">
<tokens>
<concat>
<filterchain>
<tokenfilter>
<stringtokenizer delims="\r" />
</tokenfilter>
</filterchain>
<propertyresource name="version.revisions" />
</concat>
</tokens>
</resourcecount>
<echo>Revision : ${version.revision}</echo>
<exec executable="git" outputproperty="version.hash">
<arg value="rev-parse"/>
<arg value="--short"/>
<arg value="HEAD"/>
</exec>
<echo>Hash : ${version.hash}</echo>
<exec executable="git" outputproperty="version.branch">
<arg value="rev-parse"/>
<arg value="--abbrev-ref"/>
<arg value="HEAD"/>
</exec>
<echo>Branch : ${version.branch}</echo>
<exec executable="git" outputproperty="version.diff">
<arg value="diff"/>
</exec>
<condition property="version.dirty" value="" else="-dirty">
<equals arg1="${version.diff}" arg2=""/>
</condition>
<tstamp>
<format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
</tstamp>
<echo>Date : ${version.date}</echo>
<property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />
<echo>Version : ${version}</echo>
<echo file="version.properties" append="false">version = ${version}</echo>
</target>
结果如下所示:
generate-version:
[echo] Generate version
[echo] Revision : 47
[echo] Hash : 2af0b99
[echo] Branch : master
[echo] Date : 2015-04-20.15:04:03
[echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03
当生成版本号时有文件未提交时,此处会出现脏标志。因为通常,当构建/打包应用程序时,每个代码修改都必须在存储库中。
我们使用这个命令从git中获取版本和修订:
git describe --always --tags --dirty
它返回
当没有使用标记时提交哈希作为修订(例如gcc7b71f) 当标签上的标签名称为版本时(例如v2.1.0,用于版本) 标签名称,自上一个标签以来的修订号,以及在标签之后提交哈希(例如v5.3.0-88-gcc7b71f) 如果工作树有局部修改(例如v5.3.0-88-gcc7b71f-dirty),则与上述相同,加上“dirty”标签。
参见:https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt
每个提交都有一个唯一的散列。除此之外,git中没有修订号。如果您想要更加用户友好,就必须自己标记提交。
提交的SHA1哈希值相当于Subversion修订号。