我正在源代码中的回归工作。我想告诉Git:“根据参数化的日期/时间签出源代码”。这可能吗?

我目前的观点也有阶段性的变化,我不想失去这些变化。理想情况下,我希望在当前源文件和基于之前日期的某个我感兴趣的版本之间来回切换。


当前回答

下面是我用来按相对时间签出的别名版本:

[alias]
    parsedate = "!set -x ;arg1=\"$1\" && shift && which gdate &> /dev/null && gdate -d \"$arg1\" || date -d \"$arg1\""
    codate = "!d=\"$(git parsedate \"$1\")\" && shift && git checkout \"$(git rev-list -n1 --first-parent --before=\"$d\" HEAD)\""

这允许您使用以下命令将2个月前的更改检出到名为test的新分支中:

git codate '2 months ago' -b test

这不会工作在一个浅克隆,所以不浅它首先与:

git fetch --unshallow

如果你得到一个非浅错误,你可能会从git fatal: error in object: unshallow中找到帮助

需要GNU coreutils,并使用brew在Linux和macOS上工作。

使用brew Install coreutils在macos上安装。

其他回答

保持当前的更改

你可以把你的工作藏起来,不用承诺,git stash。你 也不会用少管所的赃物把它拿回来。或者你也可以(如carleeto所说)git将它提交到一个单独的分支。

使用rev-parse按日期签出

你可以使用rev-parse在特定日期签出一个提交,就像这样:

git checkout 'master@{1979-02-26 18:30:00}'

关于可用选项的更多细节可以在git-rev-parse中找到。

正如评论中提到的,这个方法使用reflog来查找历史记录中的提交。默认情况下,这些条目在90天后过期。虽然使用reflog的语法没有那么冗长,但只能回溯到90天前。

使用rev-list按日期退房

另一个不使用reflog的选项是使用rev-list来获得在特定时间点的提交:

git checkout `git rev-list -n 1 --first-parent --before="2009-07-27 13:37" master`

如果你只想要你的历史记录而不是合并带来的版本,请注意——first-parent。这就是你通常想要的。

如果你感兴趣的日期是提交的日期,@Andy提出的git rev-parse解决方案可以很好地工作。然而,如果你想根据作者的日期签出,rev-parse将不起作用,因为它没有提供使用该日期来选择提交的选项。相反,您可以使用以下方法。

git checkout $(
  git log --reverse --author-date-order --pretty=format:'%ai %H' master |
  awk '{hash = $4} $1 >= "2016-04-12" {print hash; exit 0 }
)

(如果你还想指定时间,在awk谓词中使用$1 >= "2016-04-12" && $2 >= "11:37")

看起来你需要这样的东西: 基于日期的Git签出

换句话说,您使用rev-list来查找提交,然后使用签出 真正理解它。

如果您不想丢失阶段性更改,最简单的方法就是这样做 创建一个新分支,并将它们提交给该分支。你可以随时换回去 在树枝间来回。

编辑:链接断开了,下面是命令:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

在我的例子中,-n 1选项不起作用。在Windows上,我发现下面的命令序列工作得很好:

git rev-list -1 --before="2012-01-15 12:00" master

这将返回给定日期的适当提交的SHA,然后:

git checkout SHA

进一步使用rev-list选项,如果你想找到最近的合并提交从你的主分支到你的生产分支(作为一个纯粹的假设的例子):

git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production`

我需要找到特定日期的生产服务器上的代码。这为我找到了它。