从 Git 提交历史中「恢复」文件修改时间

几个月之前,我贪图部署方便,把博客的部署方式,从本地编译推送更新变成了借助 Github 和 Travis-CI 自动部署

用了几个月一直相安无事,直到几天前我小小修改了一下主题,展示了文章的更新日期。

本地调试的时候一切正常,直到我把变更推到 Github,触发了自动部署。下图就是出乎意料的上线效果。

注意到所有的文章的更新日期都是同一天了吗?真是伤脑筋啊。没错,正如你猜测的那样,我的星座是人见人黑的处女座。

为什么会出现这种测试效果和上线效果不一致的情况呢?我们得从 Linux 系统中文件的几个时间属性说起。

在 POSIX 系统中,每个文件都有且仅有 3 个时间属性,最后访问时间,最后修改时间,最后状态变更时间。举个例子,这个文件的内容被访问了,比如用 cat 或者 less 读取内容,最后访问时间就会被更新;如果这个文件内容被修改了,比如用 vi 改了点东西然后保存,就会修改最后修改时间;如果用 chmod 改了权限什么的,更新的就是最后状态变更时间。

为什么没有「文件创建时间」?其实在一些现代的文件系统中,比如 ext4 或者 Btrfs 是保存了文件创建时间的,只不过由于默认的 POSIX 兼容性,我们一般都不去做特殊读取罢了,毕竟出于程序的可移植性考虑,我们不能把程序绑定在某几个文件系统上。

但是作为一个博客系统,Hexo 是需要知道文件的创建时间的。也许是出于上述原因,Hexo 没有依赖文件系统的特性去保存创建时间,而是直接把时间作为文章的元数据,放在文章开头的 YAML 区域里头了。

与此同时,Hexo 也提供了获取文章修改时间的 API,由于 POSIX 保证了能够问系统要到文件的最后修改时间,Hexo 就直接把这个功能交给系统代理,文件的最后修改时间就认为是文章的修改时间。

在博客的自动部署流程中,我们是把博客源码从 Github 上 clone 到 Travis-CI 的虚拟机里,然后使用 Hexo 编译出静态页面。显然这些 clone 出来的文件,它们的最后修改时间是这些文件在 Travis-CI 的虚拟机里的创建时间,而不是我当初修改并保存的时间。至于为什么 Git 不保存文件的修改时间,原因在这里

那么有没有什么办法恢复文件的修改时间呢?精确的恢复是不可能的,毕竟信息已经丢失了,丢失得很彻底。但是作为一个博客系统,对时间精确度的要求没那么高,近似一下,使用文件的 commit 时间作为修改时间,也是可以接受的。

Google 一下,神通广大的外国朋友已经给出了解决方案,当然我也不是啥都没做,我还是去掉了一些无用参数的!

git ls-files | while read file; do touch -d $(git log -1 --format="@%ct" "$file") "$file"; done

这个操作看起来也好理解,把当前 Git 仓库里正在跟踪的文件给列出来,然后依次「篡改」文件的最后修改时间。根据 git log 命令的文档%ct 是 committer date, UNIX timestamp 的占位符,代表提交时的时间戳,那么问题来了,为什么要在时间戳前面加上 @符号?

经过一番苦苦寻觅,我在 GNU Coreutils 的文档中找到了答案。原来从 Coreutils 5.3.0 开始,实用工具中只要是涉及时间的参数,都可以用 @+unix timestamp 的形式来替代,比如 touch -d 本来要带的参数是一个「人类可读」的时间描述,可以是 Sun, 29 Feb 2004 16:21:42 -0800 或者 2004-02-29 16:21:42,甚至 next Thursday 也行,但是我们还是可以任性地使用 @1078042902 作为时间输入。

于是最后的解决方案就是把上面这行代码添加到 .travis.yml中,在生成静态页面之前恢复一下文件的修改时间。

于是这个逼死处女座的问题总算解决了~

时间: 2024-11-01 10:41:56

从 Git 提交历史中「恢复」文件修改时间的相关文章

如何将winXP电脑中的BMP图片文件修改为jpg格式?

  我们知道,Windows系统中所包含的文件格式是很多样的,就拿咱们比较熟悉的一些文件格式来举例吧!文本文件,咱们就有word还有txt,图片文件就有bmp.jpg,当然,咱们这里无法完全的介绍出来,但是另一方面,虽然每种文件的格式比较多,但是在一定的条件,却可能只有一种格式是标准的,可以使用的,那么这个时候,咱们就需要对文件的格式进行转换了.例如今天这位使用winXP电脑的用户咨询说,要如何才能将自己XP电脑中个BMP图片文件修改为jpg格式,下面,小编就来介绍一个比较快捷的方法吧! 1.首

Visual Style中的shellstyle.dll文件修改方法_应用技巧

Visual Style中的shellstyle.dll文件修改  2007-3-8 11:25:00  作者: Silencer  shellstyle.dll修改 *部分内容参考自whistl3r的Shellstyle Tutorial 预备知识 1.shellstyle.dll的结构 UIFiles: UIFile1:定义窗体及任务列表样式 UIFile2:定义控制面板样式 Resources:资源文件列表 10,11,12:音乐文件夹 13,14,15:图片文件夹 16,17,18:查找

如何让数据在产品中「说话」

为什么眼下大量企业的数据案例难以凸显价值?其中很重要的一点是,产品经理不懂数据.很多的产品经理还停留在以前做产品的阶段,靠感觉来做产品并不知道如何用数据来改善产品,更没意识到数据巳经成为了做产品的核心原材料. 过去的IT时代我们只是简单的使用数据,很少为了解决问题而提炼过数据.为什么我要强调提炼过的数据?因为如果我们要让数据产生价值,让更贴身的数据分析框架去解决用户的实际问题,就需要将数据嵌入到产品或者生产流程中,在数据提炼的最后一公里,让数据在产品中"说话". 上个月,我乘坐晚上七点

Git 教程之查看提交历史详解_相关技巧

Git 查看提交历史 在使用 Git 提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,我们可以使用 git log 命令查看. 针对我们前一章节的操作,使用 git log 命令列出历史提交记录如下: $ git log commit 88afe0e02adcdfea6844bb627de97da21eb10af1 Merge: 14b4dca d7e7346 Author: w3cschool <w3c@w3cschool.cc> Date: Sun Mar 1 15:03:42

git 使用详解(5)-- get log 查看提交历史【转】

转自:http://blog.csdn.net/wh_19910525/article/details/7468549 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 限制输出长度 使用图形化工具查阅提交历史    git log  查看 提交历史 在提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,可以使用 Git log 命令查看. 接下来的例子会用我专门用于演示的 simplegit 项目,运行下面的命令获取该项目源代码: git clone git:

web编辑器提交过程中会变成原始textbox之后又恢复为编辑器如何解决

问题描述 web编辑器提交过程中会变成原始textbox之后又恢复为编辑器如何解决 未提交1.jpg 提交未点击alert的确定时2.jpg 点击确定后3.jpg (小弟编程菜鸟) 解决方案 那张是1那张是2?就只有一张图片. 而且不明白你说的什么.ke编辑器生成后是不会自动变为其他控件的 解决方案二: 我找出错了,原来是alert()插入的位置引起的...麻烦大哥了

在Mac中使用「dd」指令烧录ISO镜像文件到U盘

作者:超級efly   發布:2014-07-26 20:22   分類:電腦   閱讀:442   11條評論    大家在Windows系統下可以方便的使用UltraISO程式來燒錄「.ISO」,但在Mac下可就沒這麼方便了,今天本站就來教大家如何在Mac下使用 dd 指令燒錄「.ISO」格式鏡像至USB硬碟 教學 1.首先我們先打開「終端機」,然後輸入 diskutil list 來查看所有硬碟,從結果中我們可以看到我的USB硬碟的硬碟位置是「/dev/disk2」,並把這個位置牢牢記住

如何禁用MacOS High Sierra中的「重要地点」位置跟踪

最新的 macOS High Sierra 系统引入了诸多新功能,在这次更新中,大多数新功能都不止流於表面,而是根植于系统底层和内部.这意味着,很多用户完全不知道这些功能是什么或者在系统内部的作用.macOS High Sierra 的大多数新功能都非常精细化,例如:更高效的文件系统及其它调整等. MacOS High Sierra 的一项重要更新就是永远在线的位置跟踪器,这个功能听起来就令人毛骨悚然,但苹果却用「重要地点」这个选项名称将其作用打扮了一番.尽管名字变好听了,但这个功能却被深埋在了

sdk-xcode中使用git提交时报错The working copy&amp;amp;quot;H5Service.bundle&amp;amp;quot;

问题描述 xcode中使用git提交时报错The working copy"H5Service.bundle" The working copy"H5Service.bundle" failed to commit files.我用到了芝麻信用的SDK,需要导入H5Service.bundle,使用没问题,但是git提交时报了这么个错误,有知道怎么解决的吗? 解决方案 这个文件没意见加到版本控制吧 git add添加