James Lin
James Lin

Reputation: 26598

Does GIT ensure commit timestamp order?

Let's say 2 computers are pushing to the same git repo, computer A has the current date time and computer B has the datetime set to 1 year earlier.

Say computer A pushed some commits, and computer B check them out and add some more commits based on the same branch and push.

*A (dated 2020-07-28 by computer A push) ----> *B (dated 2019-07-28 by computer B)

What will happen? Does git makes sure the child commits' timestamp have to be later than the parent commits?

Upvotes: 7

Views: 735

Answers (1)

LeGEC
LeGEC

Reputation: 52206

There is no constraint on timestamps in commits.

A commit stores explicitly the id of its parent(s), and git allows a commit to have a timestamp smaller than one of its parents'

A commit actually has 2 timestamps :

  • a creation date, called "author date"
  • a modification date, called "committer date"

Several features of git allow you to rewrite the repo's history (git rebase, git cherry-pick, git commit --amend, git filter-branch ...), and as a result, all interleavings of timestamps are possible.


To give an illustrative example :

If you run git commit, and 1 hour later you run git commit --amend : the "author date" will be 1 hour ago, the "committer date" will be now.
Similarly, with git cherry-pick othercommit, or git rebase (which is roughly like running git cherry-pick in a loop) : the resulting "author date" will be the author date of the original commit, the "committer date" will be now.


When working from a single machine, you will most probably see a chronological order in the modification dates (note that it is not enforced though, if you set your system clock to "yesterday" git will happily indulge) ; when working accross several machines, git does not handle time shifts between the systems' clocks.


You can view the two timestamps with several commands :

  • for a single commit :

    # will display timestamps rendered in human format :
    git show -s --format=fuller <branch or commit id>   # default is head
    
    # will display raw unix timestamps as stored in the commit :
    git cat-file -p <branch or commit id>
    git cat-file -p HEAD
    
  • for each commit in a branch :

    git log --format=fuller
    git log --format=fuller branch1 branch2 ...
    
  • with rendering options of git log or git for-each-ref : see the --format paragraph for each of these commands

Most GUI frontends to git (e.g : gitk, git-kraken, git-extensions, sourcetree ...) will also display the two timestamps in a commit's details.

Upvotes: 4

Related Questions