我有一个包含
的git仓库我们正在使用功能分支,并且通常会关注gitflow。
我们有很多生产服务器正在运行特定的SHA / master提交,它们并非都运行相同的生产服务器,因为不同的客户端对更新有不同的需求。
这些相同的客户端也有测试服务器,他们喜欢从开发分支中试用新功能。这很少是HEAD。但通常是在开发中更强大的提交,我们已经做了一些额外的努力来确保客户可以看到软件(所以是Alpha / Beta版本,但不是原始开发版本)。
由于我们拥有相当多的服务器,因此我们拥有自动部署脚本,可以将特定的提交部署到服务器。
在原始git命令中,它将类似于下面的内容(非常简化)
日期X
客户端测试服务器(已在开发分支上):
git pull --rebase
git checkout <SPECIFIC_ALPHA_BETA_SHA> .
现在客户A正在测试和试用,1个月过去了,现在客户B要求新的试用版
日期X + 1个月(或左右)
客户端B测试服务器(已在开发分支上):
git pull --rebase
git checkout <SPECIFIC_ALPHA_BETA_SHA_LATER_THAN_CLIENT_A> .
问题
有没有办法可以获得签出实际文件的工作副本SHA?
git rev-parse HEAD不起作用,因为它报告的是HEAD的实际修订版,而不是已检出的文件。
因此,如果我们假设在git pull / git checkout time (保持SHA数字只是为了更容易说明它们的顺序)
HEAD = 999
ALPHA_BETA试验= 900
git pull --rebase (now at 999)
git checkout 900 .
如果我使用 git rev-parse HEAD
它会给我999
我想要的是900。
是否有一个git命令可以对已检出的文件进行修订?
背景
我们最近从Subversion迁移到Git,所以这个问题受到Subversion以前的做法以及对Git如何运作的误解的影响。
对于客户端“演示/测试”服务器,我们以前使用修订号作为TAG而不是在Subversion中实际标记(因为标记每个客户端安装会导致我们有100个标签)。作为部署“修订/提交/ TAG”的一部分,此修订版本标记在版本文件中。
现在我们已经转移到git,客户仍然要求频繁更新他们的“演示/测试”系统。我们不希望将“演示/测试”系统的更新作为标记/版本进行跟踪,但希望继续使用“revision / SHA”作为标记。
在版本文件中标记修订时,我们不会从参数输入到部署脚本中获取此值,因为部署脚本不是“事务安全”,并且致命错误可能使存储库保留在一个修订版本中版本文件说明另一个修订版。因此,为了确保版本文件报告了文件系统上文件的实际“修订版”,我们之前已要求修订控制系统向我们提供workingcopy当前的“修订版号”。
这个问题是在Git中询问如何做到这一点。
答案 0 :(得分:1)
有很多方法可以实现您的目标。可能最多&#34; gitish&#34;将使用标签,这样做是有道理的。根据您的描述,不同的客户正在运行不同的&#34;发布&#34;该软件(由SHA标识的每个版本)。
任何在其他地方记录SHA的尝试都可能会有点腐烂,丢失纸张等等。标记允许您保留&#34;这是ALPHA_BETA_TRIAL_1&#34;与git存储库中的SHA紧密相关。这样,随着其他计算机/用户随着时间的推移克隆或获取更新,它随代码一起传播。并且在单行日志中查找相关提交会更容易。
因此
$ git tag -a -m "ALPHA_BETA_TRIAL_1" ALPHA_BETA_TRIAL_1
$ git push --tags
清楚标明您的上游(客户克隆),以供所有人查看。
如果你真的需要SHA,那么
$ git show-ref ALPHA_BETA_TRIAL_1
只需要。
相反,如果您在提交消息中记录修订信息,则可以使用
$ git log --grep="Revision\:" --oneline --decorate
仅使用字符串&#34;修订版:&#34;来获取那些提交的日志。在他们的提交消息中。 &#34; oneline&#34;和&#34;装饰&#34;命令将提供一个很好的密集日志输出,它为每个与模式匹配的提交提供简短的SHA,提交摘要和任何相关的标记。
答案 1 :(得分:1)
如果我正确地解释了这个问题,那么你对git checkout $SPECIFIC_ALPHA_BETA_SHA -- .
所做的是一个未记录的合并,使用合并策略“覆盖上游历史中的每个当前文件,同时忽略它的删除”。 Git没有自己的战略名称,那么呢?这很容易,你已经在做了,唯一剩下的就是正确记录它:
# Merge from $SPECIFIC_ALPHA_BETA_SHA using our own merge strategy:
git merge -s ours --no-commit $SPECIFIC_ALPHA_BETA_SHA
# our merge strategy:
git checkout $SPECIFIC_ALPHA_BETA_SHA -- .
# commit the result
git commit -m "Incorporating upstream"
现在git的工具包总是知道在哪里寻找相关的提交。
在一组非常受欢迎的日志选项中保存自己的一些输入,
git config --global alias.lgdo 'log --graph --decorate --oneline'
(--global
不会制作系统范围的别名,它只是你,但你可以在任何地方使用它)
列出影响签出路径内容的提交的各种方法:
git lgdo -1 --no-merges -- path/to/file # last ordinary commit affecting path
git lgdo --no-merges -- path/to/file # all ordinary commits affecting path
git lgdo -- path/to/file # above, plus full merge history
# ordinary commits as above plus all searched commits w/ branch or tag names
git lgdo --no-merges --simplify-by-decoration -- path/to/file
虽然对于你可以搜索内容变化的方式几乎没有开始,但我认为其中一个或多个将在这里服务。
答案 2 :(得分:0)
对于一个可能更有可能的可能性,每个客户端基于其中一个上游分支维护一个私有分支,你不需要git pull --rebase
,因为它会重新绑定到获取的分支的顶端。取而代之的是,
git fetch # just fetch
git rebase $SPECIFIC_ALPHA_BETA_SHA # rebase to specific stable commit
git merge-base @ @{u} # show where my history meets upstream's
使用最后一个命令获得一点点发言者
git log --oneline --decorate -1 $(git merge-base @ @{u})
将显示合并基础的提交主题以及该提交上的任何标记或其他引用。
答案 3 :(得分:0)
根据此处的输入,我想在经过一些试验和错误后,我会分享最终为我们工作的内容。
在单个客户端服务器上,当我们想要为构建脚本定位特定修订时,我们会创建一个新的&#34; local&#34;该服务器上的分支。
如果我们感兴趣的修订/提交是7d65769ae9ba4ac9f92349feca8be3c70aacfcd6,那么我们运行以下命令
git checkout -b 7d65769ae9ba4ac9f92349feca8be3c70aacfcd6 7d65769ae9ba4ac9f92349feca8be3c70aacfcd6
这为我们提供了一个本地分支,其最新修订号为7d65769ae9ba4ac9f92349feca8be3c70aacfcd6
正在运行
git rev-parse --abbrev-ref HEAD
返回预期的修订/提交(显然是7d65769ae9ba4ac9f92349feca8be3c70aacfcd6),因此构建脚本会运行。我们不添加任何远程跟踪(因为没有远程等效分支,并且我们不将此本地分支推送到原点)因此我们不会使用分支或标记来污染远程/源,这实际上是指向客户端特定测试的指针安装。
总之 - 结合
git checkout -b <commitSHA> <commitSHA>
git rev-parse --abbrev-ref
提供与旧的subversion命令相同的结果
svn up -r <revisionNumber>
svn info -R | grep "Revision\:" | sort -k2nr | head -n1
(get revision info recursively, order by revision number desc, limit 1)
感谢所有花时间回答的人。