我正在对源代码进行回归。我想告诉 Git:“根据参数化的日期/时间检查源代码”。这可能吗?
我也对我目前的观点进行了一些我不想失去的改变。理想情况下,我想在当前源和基于先前日期的某个我感兴趣的版本之间来回切换。
我正在对源代码进行回归。我想告诉 Git:“根据参数化的日期/时间检查源代码”。这可能吗?
我也对我目前的观点进行了一些我不想失去的改变。理想情况下,我想在当前源和基于先前日期的某个我感兴趣的版本之间来回切换。
您可以使用git stash
. 你不会用git stash pop
它来取回它。或者您可以(如carleeto所说)git commit
将它放到一个单独的分支中。
rev-parse
您可以使用如下方式在特定日期签出提交:
git checkout 'master@{1979-02-26 18:30:00}'
有关可用选项的更多详细信息,请参阅git-rev-parse
。
如评论中所述,此方法使用 reflog 在您的历史记录中查找提交。默认情况下,这些条目会在 90 天后过期。尽管使用 reflog 的语法不那么冗长,但您只能返回 90 天。
另一个不使用 reflog 的选项是用于rev-list
在特定时间点获取提交:
git checkout `git rev-list -n 1 --first-parent --before="2009-07-27 13:37" master`
如果您只想要历史记录而不想要合并带来的版本,请注意--first-parent 。这就是你通常想要的。
安迪的解决方案对我不起作用。在这里,我找到了另一种方法:
git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`
看起来你需要类似这样的东西: Git checkout based on date
换句话说,您使用rev-list
查找提交,然后使用结帐来实际获取它。
如果您不想丢失分阶段的更改,最简单的方法是创建一个新分支并将它们提交到该分支。您始终可以在分支之间来回切换。
编辑:链接已关闭,所以这里是命令:
git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`
对于那些喜欢管道而不是命令替换的人
git rev-list -n1 --before=2013-7-4 master | xargs git checkout
在我的情况下,该-n 1
选项不起作用。在 Windows 上,我发现以下命令序列可以正常工作:
git rev-list -1 --before="2012-01-15 12:00" master
这将返回给定日期的适当提交的 SHA,然后:
git checkout SHA
git rev-parse
如果您感兴趣的日期是提交的日期,@Andy 提出的解决方案可以正常工作。但是,如果您想根据作者的日期结帐,那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 }
)
(如果您还想$1 >= "2016-04-12" && $2 >= "11:37"
在awk谓词中指定时间使用。)
rev-list
如果您想从您的主分支找到最新的合并提交到您的生产分支(作为一个纯粹的假设示例),则进一步使用该选项:
git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production`
我需要找到截至给定日期在生产服务器上的代码。这为我找到了它。
如果您希望能够在进行构建时返回到存储库的精确版本,最好标记您进行构建的提交。
其他答案提供了将存储库返回到某个时间分支中最近提交的技术——但它们可能并不总是足够的。例如,如果您从一个分支构建,然后删除该分支,或者从一个稍后重新调整的分支构建,那么您构建的提交可能会在 git 中从任何当前分支变得“不可访问”。压缩存储库时,最终可能会删除 git 中无法访问的对象。
在提交上放置标签意味着它永远不会变得无法访问,无论您之后对分支做什么(除非删除标签)。
git rev-list -n 1 --before="2009-07-27 13:37" origin/master
获取打印的字符串(例如 XXXX)并执行以下操作:
git checkout XXXX
如果你达到了 reflog 的限制,你只需要做一点改变(你克隆 repo 的日期或 90 天的历史记录,从其他注释看来)
git checkout `git rev-list -1 --before="Jan 17 2020" HEAD`
你也可以使用
git checkout `git rev-list -1 --before="Jan 17 2020 8:06 UTC-8" HEAD`
它将检查与您输入的日期或日期时间相关的先前提交,看看您可以使用修饰符作为日期,我猜如果您不使用 UTC+-N 它只使用 UTC 时间。
看到我只把master改成HEAD,即使你没有reflog到你想检查的日期,它似乎也能工作!!!
如果要在特定日期检出单个文件,可以将文件路径传递给这两个命令。
git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master FILEPATH` FILEPATH
要从结帐中创建新分支,请使用带有新分支名称的 -b 选项。
git checkout -b 19July2021 `git rev-list -n1 --before=2021-7-19 master`
git switch
当您处于“分离 HEAD”状态时,您可以避免
提醒,从 Git 2.23(2019 年 8 月)开始
按日期从过去的提交切换到新分支:
git switch -c newBranch $(git rev-list -n1 --before=yyyy-mm-dd main)
在当前工作树中恢复过去日期的文件
git restore -SW -s $(git rev-list -n1 --before=yyyy-mm-dd main) -- path/to/file
不要在 2021/2022 年 使用旧的、过时且令人困惑的git checkout
命令git switch
:并git restore
准确描述他们在做什么(仅使用 的分支git switch
,仅使用 的文件git restore
)
不要使用 ``:比过时的反引号语法更喜欢更现代的$(command substitution)
语法。
这是我用来按相对时间结帐的别名版本:
[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)\""
test
这使您可以使用以下命令将2 个月前的更改签出到名为的新分支中:
git codate '2 months ago' -b test
这不适用于浅克隆,因此首先使用以下方法使其不浅:
git fetch --unshallow
如果你得到一个不浅的错误,你可能会从git fatal: error in object: unshallow的优秀答案中找到帮助
Requires GNU coreutils and works on Linux and macOS using brew.
Install on macos using brew install coreutils
.