如何获取使用Git在两个日期之间发生的所有提交之间的差异?


116

还是只是两个日期之间发生的所有提交?在SVN中,您可以执行以下操作

svn diff -r{date}:{date}

去做吧!我似乎找不到等效的Git。

具体来说,我正在研究编写脚本以发送每日电子邮件,其中包含当天提交的所有代码以及由谁提交。

Answers:


159

你可以用 git whatchanged --since="1 day ago" -p

这也需要一个--until论点。

文件


谢谢!这是我想要的,它甚至带有--committer参数,尽管那没有在其文档中列出!另外,'git whatchanged'没有出现在'git help'中!不知道为什么...再次感谢。
克里斯,2009年

5
您应该将此作为您选择的答案,以便塞思得到一些因果报应。
斯科特,2009年

18
@brbob我知道很久以前就已经回答了这个问题,但是对于一个偶然发现这个问题的人(就像我一样),Git帮助说:The command is kept primarily for historical reasons; fingers of many people who learned Git long before git log was invented by reading Linux kernel mailing list are trained to type it. 因此,文档鼓励使用git log而不是git whatchanged;最后一条命令还使用git log的--no-merge选项,因此它们输出相同的结果。
拉姆西斯(Ramses)2014年


2
git whatchanged从最新的最新版本2.21.0开始不推荐使用。所有git whatchanged实现的目标都可以实现,git log并且仅出于历史原因可以保留。查看详细信息git-scm.com/docs/git-whatchanged/2.21.0
Devy '19

60

先前的建议有一些缺点。基本上,我正在寻找与相等的东西cvs diff -D"1 day ago" -D"2010-02-29 11:11"。在收集越来越多的信息的同时,我找到了解决方案。

我尝试过的事情:

  • git whatchanged --since="1 day ago" -p这里

    但是,即使一个文件中有多个提交,这也会为每个提交提供差异。我知道git中的“ date”有点松散,我认为必须有某种方法可以做到这一点。

  • git diff 'master@{1 day ago}..master给出一些警告warning: Log for 'master' only goes back to Tue, 16 Mar 2010 14:17:32 +0100.,但不显示所有差异。

  • git format-patch --since=yesterday --stdout 没有给我任何东西。

  • revs=$(git log --pretty="format:%H" --since="1 day ago");git diff $(echo "$revs"|tail -n1) $(echo "$revs"|head -n1) 可以以某种方式工作,但看起来很复杂,并且不限于当前分支。

最后:

  • git diff $(git rev-list -n1 --before="1 day ago" master)似乎可以正常工作,并且是执行类似操作默认方式,尽管比我想象的要复杂。

有趣的是,git-cvsserver不支持“ cvs diff -D”(除非在某处有记录)。


4
为+1 git rev-list,这对于解决我所看到的非常相似的问题大有帮助。
me_and

这不应该是公认的答案,塞思的方法更为简洁正确。
ctford 2014年

6
@ctford,在我看来,这是不正确的。它可能会报告一个文件的多个差异,而不是像svn / cvs差异那样每个文件一个差异。
Weidenrinde 2014年

1
@Weidenrinde +1,这要聪明得多
rostamn739 '16

1
git diff 'master@{1 day ago}..master语法的意思是“检查的引用日志,并找出其中的分支master用来点在本地资源库 1 day ago ”。具体来说,将不使用当前branch的实际提交历史记录master。这是您真正想要的东西很少。
Mikko Rantalainen

22

“日期”在git中有点宽松。提交的作者日期可能早在某人实际将提交/提交到其存储库中之前的某个时间,而且提交可能会被重新建立基础并更新为明显新的提交之上。

提交还具有提交日期,如果以某种方式对提交进行了重新设置或修改,则提交日期将被更新。这些提交更有可能按照某种时间顺序排列,但是您仍然受提交者的支配,因为他在计算机上设置了正确的时间,即使如此,未经修改的提交也可以无限期地坐在远程存储库中的功能分支上被合并到中央存储库的master分支中。

对您而言,最有用的是特定存储库中的更新日志日期。如果启用了每个分支的刷新日志(请参阅参考资料git config core.logAllRefUpdates),则可以使用ref@{date}语法来指代特定时间分支的位置。

例如

git log -p master@{2009-07-01}..master@{now}

您还可以使用“模糊”描述,例如:

git log -p "master@{1 month ago}..master@{yesterday}"

这些命令将显示在存储库的给定分支中“已出现”的所有提交,无论它们根据其作者和提交日期实际处于多大年龄。

请注意,每个分支的reflog是特定于存储库的,因此,如果您在克隆上运行log命令,并且您没有拉(比如说)一个月,则一次拉出最后一个月的所有更改,那么上个月的所有更改都会显示在一个@{1 hour ago}..@{now}范围内。如果您能够在人们推送到的“中央”记录上运行log命令,那么它可能会做您想要的。


很好的写作和对所陈述问题的好的答案...但是我认为这样做对brbob的意图没有太大帮助。
2009年

这取决于他是否真的想解析推送到某个中央存储库中某个分支的内容以及在该存储库上运行log命令,这可能会有所帮助。我认为编辑工作已经准备就绪……
CB Bailey

“如果以某种方式对提交进行了重新修改或修改,则更新提交日期”,实际上,该日期永远不会更改;整个提交将被另一个提交替换(尽管树可能是相同的)。
哈森

2
@hasen j:从技术上讲,您是对的。提交是一成不变的。在对提交进行基础更改或修改并创建新提交时,通常会从旧提交中复制现有提交消息,作者详细信息和作者日期,就好像您要使用新提交ID和提交日期来更新提交一样
CB Bailey 2010年

请注意,@{time spec}语法始终引用您的本地reflog。它不引用实际的提交历史记录(DAG)。如果您不了解它们之间的区别,请不要使用此语法!
Mikko Rantalainen

14
git diff --stat @{2013-11-01}..@{2013-11-30}

要么

git diff --stat @{2.weeks.ago}..@{last.week}

这取决于引用日志吗?因为如果这样做,那么如果您正在运行此命令的存储库比其包含的提交历史记录新(即,新克隆的)存储库,则您将无法实际使用它。

2
是的,这完全取决于引用日志。是的,这仅在本地复制历史记录中有效,但是有点方便。
AA。

1
是的,我绝对同意这很方便,只要您的reflog条目足够老以支持它。

谢谢AA。使用您的答案,我能够做到:git注释--stat .. @ {2017-08-8}文件名| less; git注释--stat .. @ {5.days.ago}文件名;这样我就可以看到上下文的变化。
克里斯(Chris

请注意,@{time spec}语法始终引用您的本地reflog。它不引用实际的提交历史记录(DAG)。如果您不了解它们之间的区别,请不要使用此语法!
Mikko Rantalainen


3

我相信一般的解决方案是使用:

git rev-list -n1 --first-parent --until=<a date string> <a ref>

如果没有--first-parent,您可能会从一个分支中获得一个提交,该分支后来被合并到,a ref但截至时尚未被合并a date string

这是使用--childrengrep代替的替代方法-n1

mlm_git_ref_as_of() {
    # # Examples #
    #
    # Show all commits between two dates:
    #
    #     git log $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    #
    # Show diffs of all commits between two dates:
    #
    #     git diff $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    local as_of="$1"
    local ref="${2:-HEAD}"
    # Get the most recent commit (--children, grep -v ' ') that was on
    # the given branch ($ref, --first-parent) as of a given date
    # ($as_of)
    git rev-list --children --first-parent --until="$as_of" "$ref" | grep -v ' '
}

git whatchanged在阅读此问答之前,我并不熟悉,但是它给我带来了截然不同的结果,因此我不确定它在做什么。



2

这更是一个有趣的答案,因为可能有更好的方法。这将显示今天的所有提交哈希值。

git log --pretty="format:%H %ai" | grep `date +"%Y-%m-%d"` | awk {'print $1'}`

;·)



2

为了观看分支上Git文件的最新变化,请使用以下公式:

  1. 结帐您的分支。
  2. 从远程存储库中提取和更新更改
  3. 从日期到日期范围观看差异文件

配方

git checkout <branch>
git pull
git diff --stat @{fromDate}..@a{toDate}

请注意,日期采用YYYY-MM-DD格式:

git diff --stat @{2019-08-20}..@a{2019-08-21}

如果您想观察特定时间范围内特定文件的变化(观看代码中的差异),只需浏览当前文件即可:

范例

git diff @{2019-01-01}..@{2019-01-02} ~/dev/myApp/package.json

0

我将以这种方式进行抛出: git log因为日期为您提供了当前分支的提交哈希值。然后,我只使用类似的东西git diff 8fgdfg8..565k4l5,使我可以通过文件汇总适当的差异。希望这会有所帮助,尽管测试不多

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.