简体   繁体   English

获取Git存储库的最后一次提交

[英]Get Git repository's last commit

I have a central Git bare repository. 我有一个中央的Git裸存储库。 When a push is made to that repo I want to run a post-receive hook. 当对该回购进行推送时,我想运行后接收挂钩。 What that hook will do is create a message on a Basecamp project (using their API). 该钩子将做什么是在Basecamp项目上创建一条消息(使用他们的API)。 I want info on the update that was just performed. 我想要了解刚刚执行的更新的信息。 Right now I think git log -2 --stat is good enough but would like a little more info (branch that was updated, file created, files removed). 现在我认为git log -2 --stat足够好但想要更多信息(更新的分支,文件创建,文件被删除)。 Can anyone help with the command(s) I need to do to get all the info? 任何人都可以帮助我获取所有信息我需要做的命令吗? Performing multiple commands is fine with with me, there probably isn't a single command that will get me all the information. 执行多个命令对我很好,可能没有一个命令可以获取所有信息。

You could find the latest commit by examining and sorting the files under .git/refs/heads : every time a new commit is made, the corresponding refs/heads file is changed, ie when committing to master , refs/heads/master is updated. 您可以通过检查和排序.git/refs/heads下的文件来找到最新的提交:每次进行新的提交时,相应的refs/heads文件都会更改,即提交到masterrefs/heads/master会更新。

So, let's develop a solution. 那么,让我们开发一个解决方案。

First task: find all branches (ie all files under refs/heads and print out when they were last changed. You're talking about hooks, so we give the path relative to the .git/hooks directory: 第一个任务:查找所有分支(即refs/heads下的所有文件,并在上次更改时打印出来。你在谈论钩子,所以我们给出了相对于.git/hooks目录的路径:

find ../refs/heads -type f -printf '%T@ %p\n'

This produces a list of all branches along with their change date. 这将生成所有分支的列表及其更改日期。 See the man page of find for an explanation of the parameters. 有关参数的说明,请参见find手册页

Second Task: sort the obtained list 第二任务:对获得的列表进行排序

find ../refs/heads -type f -printf '%T@ %p\n' |\
sort

Third Task: we need the newest element in that list. 第三项任务:我们需要该列表中的最新元素。 Since sort sorts from old to new, our desired item is at the bottom of the list. 由于sort从旧到新sort ,我们所需的项目位于列表的底部。 Get this element with tail (only one item, therefore pass the -1 flag): 获取带tail this元素(只有一个项,因此传递-1标志):

find ../refs/heads -type f -printf '%T@ %p\n' |\
sort    |\
tail -1

Fourth Task: drop the date in the obtained line. 第四项任务:在获得的行中删除日期。 From our printf statement we know that date and path are separated with a space. 从我们的printf语句中我们知道日期和路径是用空格分隔的。 Feed this as delimiter into cut ( -d " " ) and tell it we need the second field (ie the file path, -f 2 ). 将此作为分隔符输入cut-d " " )并告诉它我们需要第二个字段(即文件路径, -f 2 )。 For convenience, we'll store this file path in a variable called $LATESTHEAD : 为方便起见,我们将此文件路径存储在名为$LATESTHEAD的变量中:

LATESTHEAD=$(\
    find ../refs/heads -type f -printf '%T@ %p\n' |\
    sort    |\
    tail -1 |\
    cut -d ' ' -f 2 )

Fifth Task: Now we know the filename, but we need the content. 第五个任务:现在我们知道文件名,但我们需要内容。 This is the latest revistion that could be passed to git log . 这是可以传递给git log的最新修订。 cat does the job. cat做的工作。 Store the latest revision in $LATESTREV 将最新版本存储在$LATESTREV

LATESTHEAD=$(\
    find ../refs/heads -type f -printf '%T@ %p\n' |\
    sort    |\
    tail -1 |\
    cut -d ' ' -f 2 )
LATESTREV=$(cat $LATESTHEAD)

Now, you could use $LATESTREV to do any dirty things you want. 现在,您可以使用$LATESTREV来做任何你想要的脏东西。

Perhaps not the most elegant solution (probably someone will come up and tell you a much easier one-liner) but works for me. 也许不是最优雅的解决方案(可能有人会出现并告诉你一个更简单的单行)但对我有用。

Adding --summary to your git log will produce the new and deleted file listing (git refers to them as "nodes"): 在您的git日志中添加--summary将生成新的和已删除的文件列表(git将它们称为“节点”):

git log --stat --summary -1

To get the branch, try running: 要获得分支,请尝试运行:

git branch --contains `git log --oneline -1 |cut -f1 -d\ ` |cut -b3-

Note: I am testing this on my mac. 注意:我在我的Mac上测试它。 Unix cut is 1 indexed but I believe Debian cut is 0 indexed. Unix cut是1索引但我认为Debian cut是0索引。 If so, and if you are on a Debian box, change -f1 to -f0 and the branch command should work just fine 如果是这样,如果你在Debian框中,将-f1更改为-f0并且branch命令应该可以正常工作

If there is no specific reason why you use post-receive , I would rather suggest using update , which gets the old ref, the new ref and the branch as command line arguments. 如果你没有使用post-receive具体原因,我宁愿建议使用update ,它将旧的ref,新的ref和branch作为命令行参数。

So you can just get the whole log using the git log commands suggested here and giving oldref..newref as argument (replacing oldref and newref respectively). 因此,您可以使用此处建议的git log命令获取整个日志,并将oldref..newref作为参数(分别替换oldrefnewref )。

For more information see the githooks(5) manpage on the update hook . 有关更多信息,请参阅更新挂钩上的githooks(5)联机帮助页 You even can abort the update at that point if you need to. 如果需要,您甚至可以在此时中止更新。

Actually, you get the same information in the post-receive hook on stdin. 实际上,您在stdin上的post-receive钩子中获得了相同的信息。 I do not see why you need to do a lot of find commands to accomplish that task. 我不明白为什么你需要做很多find命令来完成这个任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM