简体   繁体   中英

How does git tell the remote repository the time of the commit?

If you look at times of each commit on GitHub, and then run git log , you will see that the times of the commits between the remote and local repos are the exact same, even if you ran git push a few minutes after git commit . How does git tell the repository the time of the said commit?

The time is logged as soon as you run git commit for that commit. The push only updates github with your local commits, and as such the time of the push is not kept.

Edit: If you are asking about the specific mechanism, the time is simply passed with the commit along with the changes, your message, and the author(s)/contributor(s).

Let's look inside an actual commit. Here is a commit from the Git repository for Git itself:

$ git cat-file -p HEAD | sed 's/@/ /'
tree 8f78544663a8f3e9e3d4ee9125cf54a863498bfb
parent b4e245a17adc1b336269f7350e88eede6e713157
author Junio C Hamano <gitster pobox.com> 1605735205 -0800
committer Junio C Hamano <gitster pobox.com> 1605735205 -0800

Sixth batch

Signed-off-by: Junio C Hamano <gitster pobox.com>

The components of any commit are:

  • a full snapshot of every file: this is stored indirectly through the tree line;
  • metadata, including the name of the person who wrote the commit: here, we see some of that metadata on the author line, and some of it on the committer` line.

The metadata include the raw hash ID of the parent(s) of the commit; here, there is one parent, whose hash ID appears on the (single) parent line. The metadata can include additional header lines, but here, after the standard tree , parent , author , and committer , we see only the subject ( Sixth batch ) and body, set off by a blank line after the first set of header lines.

(One reason for storing the tree indirectly is that Git can then re-use it. For instance, a merge commit that changes nothing, or a revert that undoes the immediately previous commit, will make a new snapshot that exactly matches the previous snapshot. Here, Git can store the new commit without adding anything other than the new commit object.)

The date-and-time-stamp are part of the commit itself, just as kevin-robb said . These are encoded a bit oddly: they take the form of a number of seconds since 1 Jan 1970 00:00:00 UTC. Here, that's 1605735205 seconds since then, or Wed Nov 18 21:33:25 UTC 2020 . We also get a time-zone-offset: -0800 . This is expressed in hours and minutes, in decimal, with two digits for each, so the offset is 8 hours west of Greenwich, or Pacific Standard Time. Taking 8 hours from 9:33 PM, we get 1:33 PM, which is indeed what git log shows:

$ git log -n 1 | sed 's/@/ /'
commit faefdd61ec7c7f6f3c8c9907891465ac9a2a1475
Author: Junio C Hamano <gitster pobox.com>
Date:   Wed Nov 18 13:33:25 2020 -0800

    Sixth batch
    
    Signed-off-by: Junio C Hamano <gitster pobox.com>

Because the above is and will always be the exact data for the commit whose hash ID is faefdd61ec7c7f6f3c8c9907891465ac9a2a1475 , the time stamp of that commit must be the value we just saw:

$ (printf 'commit 279\0'; git cat-file -p HEAD) | shasum
faefdd61ec7c7f6f3c8c9907891465ac9a2a1475  -

(279 is the number of bytes in the commit data, as found by git cat-file -p HEAD | wc -c ).

If we take this commit and alter it to hold some other date-and-time stamp, and run it through Git's object hasher, we'll get some other hash—a commit whose hash ID is not faefdd61ec7c7f6f3c8c9907891465ac9a2a1475 .Commit faefdd61ec7c7f6f3c8c9907891465ac9a2a1475 will be dated 1605735205 -0800 . So any Git repository that has commit faefdd61ec7c7f6f3c8c9907891465ac9a2a1475 has it with that date and time and no other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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