Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Git repository's last commit

I have a central Git bare repository. 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). 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). 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.

like image 924
Jeebs24 Avatar asked Jun 22 '12 02:06

Jeebs24


People also ask

How can I see my last commit in git?

Viewing a list of the latest commits. If you want to see what's happened recently in your project, you can use git log . This command will output a list of the latest commits in chronological order, with the latest commit first.

How do you get commit ID of last commit in git?

To find a git commit id (or hash), you can simply use the git log command. This would show you the commit history, listing the commits in chronological order, with the latest commit first.

How do I see the last commit of a file?

Solution. 2.1 git log to display all the commit_id, the first one is the last commit_id, copy it. 2.2 git show commit_id --name-only to display all the files committed in the specified commit_id. 2.3 Undo the last commit with git reset --soft HEAD~1 , move the mistakenly committed files back to the staging area.

How do I get the last commit hash?

# open the git config editor $ git config --global --edit # in the alias section, add ... [alias] lastcommit = rev-parse HEAD ... From here on, use git lastcommit to show the last commit's hash.


3 Answers

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, i.e. when committing to master, refs/heads/master is updated.

So, let's develop a solution.

First task: find all branches (i.e. 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:

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.

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. Get this element with tail (only one item, therefore pass the -1 flag):

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. Feed this as delimiter into cut (-d " ") and tell it we need the second field (i.e. the file path, -f 2). For convenience, we'll store this file path in a variable called $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. cat does the job. Store the latest revision in $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.

Perhaps not the most elegant solution (probably someone will come up and tell you a much easier one-liner) but works for me.

like image 98
eckes Avatar answered Oct 05 '22 21:10

eckes


Adding --summary to your git log will produce the new and deleted file listing (git refers to them as "nodes"):

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. Unix cut is 1 indexed but I believe Debian cut is 0 indexed. If so, and if you are on a Debian box, change -f1 to -f0 and the branch command should work just fine

like image 26
Ben Roux Avatar answered Oct 05 '22 20:10

Ben Roux


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.

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).

For more information see the githooks(5) manpage on the update hook. 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. I do not see why you need to do a lot of find commands to accomplish that task.

like image 34
Jonas Schäfer Avatar answered Oct 05 '22 21:10

Jonas Schäfer