GIT 是否确保提交时间戳顺序?

Jam*_*Lin 7 git

假设两台计算机正在推送到同一个 git 存储库,计算机 A 具有当前日期时间,计算机 B 的日期时间设置为 1 年前。

假设计算机 A 推送了一些提交,计算机 B 检查它们并基于相同的分支和推送添加更多提交。

*A (dated 2020-07-28 by computer A push) ----> *B (dated 2019-07-28 by computer B)
Run Code Online (Sandbox Code Playgroud)

会发生什么?git 是否确保子提交的时间戳必须晚于父提交?

LeG*_*GEC 4

提交中的时间戳没有限制。

提交显式存储其父级的 id,并且 git 允许提交的时间戳小于其父级之一的时间戳

一次提交实际上有 2 个时间戳:

  • 创建日期,称为“作者日期”
  • 修改日期,称为“提交者日期”

git 的几个功能允许您重写存储库的历史记录(git rebase、、、... ),因此,所有时间戳的交错都是可能的git cherry-pickgit commit --amendgit filter-branch


举一个说明性的例子:

如果您运行git commit,1 小时后运行git commit --amend:“作者日期”将是 1 小时前,“提交者日期”将是现在。
类似地,使用git cherry-pick othercommit, or git rebase(大致类似于git cherry-pick循环运行):生成的“作者日期”将是原始提交的作者日期,“提交者日期”将是现在。


当在一台机器上工作时,你很可能会在修改日期中看到时间顺序(请注意,虽然这不是强制的,如果你将系统时钟设置为“昨天”,git 会很高兴地放纵);当跨多台机器工作时,git 不处理系统时钟之间的时间转换。


您可以使用多个命令查看两个时间戳:

  • 对于单个提交:

    # 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
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于分支中的每个提交:

    git log --format=fuller
    git log --format=fuller branch1 branch2 ...
    
    Run Code Online (Sandbox Code Playgroud)
  • 渲染选项为git loggit for-each-ref:请参阅--format每个命令的段落

大多数 git 的 GUI 前端(例如:gitk、git-kraken、git-extensions、sourcetree ...)也会在提交详细信息中显示两个时间戳。

  • 如果你使用 `git commit`,1 小时后你使用 `git commit --amend` :“作者日期”将是 1 小时前,“提交者日期”将是现在。与 `gitcherry-pick othercommit` 类似:生成的“作者日期”将是原始提交的作者日期,“提交者日期”将是现在。 (3认同)