115

How do I check the date and time of the latest git pull that was executed? I frequently need to know when the code changed on a server when something goes wrong.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Chirag Patel
  • 5,819
  • 8
  • 35
  • 38

13 Answers13

174
stat -c %Y .git/FETCH_HEAD

Will give you a unix timestamp of the last modification of that file. Git writes the FETCH_HEAD file every time you pull or fetch, even if there was nothing to pull.

smoove
  • 3,920
  • 3
  • 25
  • 31
  • 19
    Unix timestamp of modified time on OSX: `stat -f '%m' .git/FETCH_HEAD` – jpillora Aug 06 '13 at 22:39
  • 1
    Or cross platform using node: `node -p 'require("fs").statSync("./.git/FETCH_HEAD").mtime.getTime()'` – jpillora Aug 06 '13 at 22:48
  • 21
    Git writes FETCH_HEAD _before_ the actual fetch/pull... So if pull failed or was cancelled then FETCH_HEAD would not represent the actual repository state. This is especially problematic when the original repo URL isn't working, as every pull would fail but FETCH_HEAD will be updated on every attempt. – rustyx Jan 20 '14 at 15:29
  • 12
    Date of modified time on OS X: `stat -f '%Sm' $(git rev-parse --show-toplevel)/.git/FETCH_HEAD` – Colin vH May 10 '15 at 18:07
  • 10
    You can also check `.git/refs/heads/master` which will have its timestamp change when `git pull` results in changes coming in from the remote `master` branch, but the timestamp won't change when `git pull` reports there are no changes. – Malvineous Aug 15 '16 at 08:47
  • 6
    For anyone using this in a script: If a fetch or pull haven't been done yet then FETCH_HEAD won't exist yet and stat will return exit code 1. – MajicBob Nov 18 '16 at 22:33
  • this is actually the answer I came to see, e.g. I have a cron running a git pull and I actually want to know whether it ran without looking at sys/cron logs. – sabujp Jun 05 '18 at 23:08
  • 1
    @Malvineous Obviously, if you have another branch checked out then you should look at `.git/refs/heads/YOUR_BRANCH_NAME` instead. Obvious, but it still tripped me up. :-/ So I thought I would mention it here. :-) – Bennett McElwee Jun 13 '18 at 00:50
  • 3
    human-readable on a bash: `date -d @$(stat -c %Y .git/FETCH_HEAD)` – Matthias Sep 11 '18 at 12:18
  • To have a script check whether there has been a recent pull: `[[ $(( $(date +%s) - $(stat -c %Y .git/FETCH_HEAD) )) -gt 172800 ]] && echo "Last pulled more than 2 days ago"` – Steve Jorgensen Mar 07 '19 at 03:47
  • `stat -c %Y .git/FETCH_HEAD .git/HEAD 2>/dev/null | head -1` will fallback to `.git/HEAD` modification time if `.git/FETCH_HEAD` does not exist. – Jaakko Mar 24 '20 at 12:09
66

On a hunch, I tried "stat -c %y .git/FETCH_HEAD", and got a human-readable printout of the time:

> stat -c %y .git/FETCH_HEAD
2015-02-24 17:42:08.072094410 -0500

Furthermore, you can add when = !stat -c %y .git/FETCH_HEAD to the [alias] section in your ~/.gitconfig file (it's safest to do this automatically by running the following command line in any git repo)

git config --global alias.when '!stat -c %y .git/FETCH_HEAD'

and then you are able to find this info with your new "command", anytime:

> git when
2015-02-23 15:07:53.086254218 -0500

[Then it occurred to me to do "man stat", and I found that there are a bunch of other % parameters available for the 'stat' program. YMMV.]

Starman
  • 336
  • 2
  • 11
Paul McMullin
  • 669
  • 5
  • 3
38

The git show command shows the date of the most recent commit. This isn't the date at which the commit was pulled to the local repository, but Git doesn't keep such pull information.

You may be able to find the time of the last pull using the ctime (creation time) of the files on the server. For example:

ls -lct

shows the ctime of each file, sorted with the most recent first.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 21
    This doesn't answer the question -- see smoove's answer below. – Wilfred Hughes Sep 06 '12 at 15:21
  • 1
    `git show` shows the date of the tip commit of the current branch, which is not necessary the most recent commit in the repo, let alone the date of latest fetch/pull. I also recommend to check smoove's answer. – Stefaan Oct 08 '12 at 12:37
  • 4
    I beg to differ. This does answer the question. While it does not give you the date of the latest pull, it does give you the date of the commit that was the most recent when you last pulled. For the use case in the original question, this is perfectly suitable. You want to know when you last updated the code on a server via git pull, i.e., which version of the code is currently on the server. `git show` tells you which commit your local clone is at. (I know this is old, but I ended up here via search.) – Dietmar Jun 21 '17 at 11:39
14
git show -1 --stat  

This git command shows the latest changes commits time and date with message

sachin_ur
  • 2,375
  • 14
  • 27
12

In a non-bare repository (and a bare repository doesn't make sense for git pull), git logs all changes to branch tips and the current branch idea in "reflogs", in .git/logs. You can view these using git log -g.

However, although the log files do have timestamps, it doesn't appear that git log -g will print it. However, if you take a look at .git/logs/HEAD for example, you'll see that the format is quite simple to parse- it consists of what the ref (or HEAD) changed from, changed to, who changed it, when and an activity message.

araqnid
  • 127,052
  • 24
  • 157
  • 134
3

Use python: python -c "import os;print os.stat('.git/FETCH_HEAD').st_mtime"

widerin
  • 86
  • 1
  • 4
  • needs some formatting, but a completely valid answer for freebsd where stat doesn't work the ways described above. – Endre Dec 29 '16 at 16:23
3

Cross Platform (OSX/Linux) Bash Solution

Heavily inspired by @smooves answer: https://stackoverflow.com/a/9229377/622276 and comments.

But I am maintaining my own bash prompt git integration

With the source here: https://github.com/neozenith/dotfiles/blob/master/bash-scripts/function_parse_git_prompt.sh

msys version in Git Bash for Windows works identical to the linux version.

I'm compiling the cross platform options into a case statement. So it will fork a fetch process on any git repo I navigate into that is older than fifteen minutes since last fetch so the rest of my prompt script knows if I have stuff to pull.

Git radar used to to this but it required saving a file with timestamp of when the last fetch was called. This writes no temporary files.

git rev-parse --show-toplevel just means if I'm anywhere in a git repo it will get the repo root so we can reference the .git folder path.

# No repo == no more work 
local REPO_ROOT=`git rev-parse --show-toplevel 2> /dev/null`
if [[ -n $REPO_ROOT && -e "$REPO_ROOT/.git/FETCH_HEAD" ]]; then

    case $OSTYPE in
      darwin*)
        local LAST_FETCH="$(stat -f '%m' $REPO_ROOT/.git/FETCH_HEAD)" 
        local FETCH_THRESHOLD="$(date -v-15m +%s)"  
      ;;
      *)
        local LAST_FETCH="$(stat -c %Y $REPO_ROOT/.git/FETCH_HEAD)" 
        local FETCH_THRESHOLD="$(date -d'15 minutes ago' +%s)"  
      ;;
    esac

    # Fork fetch process in background
    if [[ $LAST_FETCH -lt $FETCH_THRESHOLD ]]; then
      git fetch --all --quiet --prune 2> /dev/null &
    fi

fi
Josh Peak
  • 5,898
  • 4
  • 40
  • 52
2
python -c "import os, datetime ;print datetime.datetime.fromtimestamp(os.stat('.git/FETCH_HEAD').st_mtime)"

or

python3 -c "import os, datetime ;print(datetime.datetime.fromtimestamp(os.stat('.git/FETCH_HEAD').st_mtime))"
RedEyed
  • 2,062
  • 1
  • 23
  • 26
1

Here's a small git wrapper. Install it with the name git and with rights chmod a+x git. Then add last_successful_fetch to .git/info/exclude.

When you want to see the result, use stat last_successful_fetch.

#!/bin/sh

# This script just invokes git as expected, plus one additional action:
# If there stands last_successful_fetch in .git/info/exclude, then
# this file will be touched in top dir.

"`which --all git | uniq | head -n 2 | tail -n 1`" "$@"
status=$?

if [ _"$1" = _pull -o _"$1" = _fetch ]; then
    if grep last_successful_fetch "`git rev-parse --git-dir`/info/exclude" >/dev/null 2>&1; then
        [ $status = 0 ] && touch last_successful_fetch
    fi
fi
jifb
  • 142
  • 2
  • 6
0
$ # for the latest pull even if there's nothing new
$ stat -c %y .git/FETCH_HEAD
2017-12-15 11:24:25.000000000 +0100
$ 
$ # for records of updated references
$ git reflog --date=iso
db2bba84 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2017-12-14 11:28:39 +0100}: pull: Fast-forward
37fe73ad HEAD@{2017-12-03 17:09:32 +0100}: pull: Fast-forward
c4107fcd HEAD@{2017-11-27 18:53:40 +0100}: clone: from https://github.com/macports/macports-base
$ 
$ # for a more detailed view of the latter
$ git log -g
commit db2bba84d5e8cd82ec94a19129deb91ef62287bb (HEAD -> master, origin/master, origin/HEAD)
Reflog: HEAD@{0} (me <me@machine.local>)
Reflog message: pull: Fast-forward
Author: Ryan Schmidt <ryandesign@macports.org>
Date:   Wed Dec 13 10:23:47 2017 -0600

    portutil.tcl: Fix renames that supply the -force option

    Treat $options as a list not as a string.

    See: https://trac.macports.org/ticket/55492

[snip]
1.61803
  • 413
  • 8
  • 15
0

As suggested by user: https://stackoverflow.com/users/83646/smoove, you can find when git pull was last called on the repo by checking the modification timestamp of: .git/FETCH_HEAD as: git writes the .git/FETCH_HEAD file every time you pull or fetch, even if there was nothing to pull.

Example: {master} vinegupt@bhling69(/imsgit_local/work/vinegupt/ims_18.5a/ims_common)$ stat -c %y .git/FETCH_HEAD

2018-02-12 02:01:50.487160386 +0530

  • Fo OSX 10.9.5 I needed to do this: `stat -f %Sm .git/FETCH_HEAD` but seems to work well for me. – Josh Mar 26 '18 at 15:13
  • You should upvote @smoove’s answer instead of copy/pasting it in your own "answer". – bfontaine Apr 16 '18 at 16:23
  • Right now, I don't have any reputation points to upvote that answer. Plus I showed how command worked in my system just to reinforce how that solution was working. – Vineet Gupta Jun 19 '21 at 19:35
0

In my case I had to go back to get the second to last pull (previous-1), so used this reflog command, note that reflogs expire in 90 days by default. Hope this will be helpful to someone.

 master ± -> git reflog --date=iso|grep pull
67718cc11 HEAD@{2022-01-25 10:14:31 +0530}: pull: Fast-forward
9bb64364a HEAD@{2021-12-13 18:22:17 +0530}: pull: Fast-forward
f5cf7c887 HEAD@{2021-11-29 13:08:14 +0530}: pull: Fast-forward

then you can checkout that hash and create a branch. (detached head in below command)

git checkout 9bb64364a 
dimuthu
  • 865
  • 11
  • 15
0

why not use the simplest

ls -l .git/FETCH_HEAD 

it works as long it's less than 1 year old
and you only need the date (time hh:mm is only displayed if less than 1 day old)

should work on any OS (system), any FS (FileSystem) with any shell
except if someone messes up inside the .git folder

By the way, ls -c may use status change datetime to sort and/or print not creation datetime (it may matches in some conditions).
man ls
-c Use time when file status was last changed for sorting or printing.

Lionel-fr
  • 124
  • 1
  • 1
  • 5