Git handling of commit times
list1 at gjunka.com
Thu May 30 10:12:39 UTC 2019
On 30/05/2019 07:48, Xin Li wrote:
> On 5/29/19 10:08, Ed Maste wrote:
>> On Wed, 29 May 2019 at 11:40, Grzegorz Junka <list1 at gjunka.com> wrote:
>>> Timestamp alone doesn't give much information. What matters is when the
>>> branch in which the commit was added has been merged with other branches
>>> (shown as merge commits in the history).
>> Our history is mostly devoid of merges though, but your broader point
>> is certainly valid - the relationship that's actually important is the
>> parent/child commits, not the order of either date stamp.
>>> Bear in mind that commits are local (by the virtue of git being
>>> distributed scm). You can certainly write a git hook that verifies local
>>> time to be approximately the same as server time and stop the commit if
>>> that's not the case. But that's clunky and patronizing in my opinion\
>>> (e.g. someone won't be able to commit when on a train and off the grid).
>> I'm not suggesting that we require the commit time to be close to the
>> server time, just that we could disallow two actually invalid cases:
>> - commit time is earlier than parent(s)
>> - commit time is later than the (accurate) server time
>> If you have local commits made while on the train and someone else
>> pushes to the canonical repository before you're back online you're
>> going to have to merge or rebase, and will then have an updated commit
>> The solution to this issue triggering is easy - just make sure the
>> client has the correct time.
> Or, have the server perform the required operation (a merge, or a
> rebase) on behalf of the user, based on CI result, etc.
Neither would work.
Merge doesn't change existing commits, it just creates a new commit.
Therefore incorrect timestamp would remain incorrect on the server.
In order to do a rebase on the server you would need to push the branch
to rebase to the server first. If it contains incorrect commits then you
end up with two different histories (different commit hashes and
timestamps) in two different branches. That renders the branch you
pushed useless. The developer would need to abandon their branch and
create a new one for new changes. Now good luck explaining all
developers that their branches can only be pushed once and then need to
be deleted. If they reuse the branch they may end up with a massive
conflict where they need to merge the rebased changes and the new
changes on top of already updated branch. You should never rebase a
branch that has already been pushed to remote.
>>> Git commits are joined by hashes, timestamp is only some metadata. It
>>> makes sens to talk about amount of commits since a particular hash but
>>> not so much about amount of commits since a particular date.
>> Indeed, but that said developers like to think in terms like "commits
>> since a particular date", and we should provide a good experience
>> there if we can do so without restricting realistic workflows.
> Assuming the dates are trustworthy (e.g. the merge or rebase was
> performed by the server), that can be accomplished with e.g. git log
> --since. Practically, I think it's more useful to do e.g. git log
> release/11.1..HEAD and I'm not particularly worried if the dates were
> not that accurate.
Assuming that a developer wants to execute this command on their
machine, then they would need to pull all changes from the server first
(since server has just updated them). If they just pushed their changes
from local to remote, they would first need to remove these changes from
their repo somehow (e.g. delete relevant branches). Then pull the
changes updated on the server and then perform the command. Or clone the
repo again. In either way it's quite a hassle and not how developers are
used to working with git.
Git is a distributed SCM. If you want the server to be an authoritative
source of truth use SVN, not Git. In Git you need to assume that each
and every repo is a local copy of the same repo with additional local
modifications. Incorrect timestamps may happen. Embrace them. Or prevent
them from happening in that particular copy of the repo, not just in the
copy that happened to be on the server.
More information about the freebsd-git