2

I'm doing this to get all changes of a certain file in a fresh clonend repo

git diff HEAD 'HEAD@{2020-01-01 ago}' -- file

but I get warning: Log for 'HEAD' only goes back to and not everything that changed.

What did I do wrong?

EDIT:

Thanks for all the suggestions. I got some good results from: git diff $(git rev-list -n1 --until="timestamp" HEAD --) file

  • 1
    Does this answer your question? [How can I get the diff between all the commits that occurred between two dates with Git?](https://stackoverflow.com/questions/1161609/how-can-i-get-the-diff-between-all-the-commits-that-occurred-between-two-dates-w) – evolutionxbox Jan 19 '21 at 13:21

2 Answers2

2

Git - gitrevisions Documentation

@

@ alone is a shortcut for HEAD.

[<refname>]@{}, e.g. master@{yesterday}, HEAD@{5 minutes ago}

A ref followed by the suffix @ with a date specification enclosed in a brace pair (e.g. {yesterday}, {1 month 2 weeks 3 days 1 hour 1 second ago} or {1979-02-26 18:30:00}) specifies the value of the ref at a prior point in time. This suffix may only be used immediately following a ref name and the ref must have an existing log ($GIT_DIR/logs/). Note that this looks up the state of your local ref at a given time; e.g., what was in your local master branch last week. If you want to look at commits made during certain times, see --since and --until.

Note that that documentation says about "local" ref. Basically you can use this expression to refer to reflog of branches in local repository. Reflog is not shared with remote repository so it was not downloaded during clone.

So when you have fresh clone of repository you can use expression HEAD@{date} only if date refers after clone was made. You can use only dates when specific branch was updated on your local repository. That is why you get this warning: Log for 'HEAD' only goes back to, since reflog of fresh clone has only one entry for HEAD (date of clone).

Basically you have to refer to required commit by other means (for example: use hash of the commit).

Marek R
  • 32,568
  • 6
  • 55
  • 140
0

The TL;DR version of Marek R's answer is that the @{date} syntax is unable to do what you want; don't try to use it for this purpose.

The link in evolutionxbox's comment goes to a rather old question whose answer contains most of what you need, though git whatchanged has been deprecated in favor of git log --raw. The accepted answer has the key notion: --since (and --until, if you want it) is the way to do commit limiting by date.

You did however also specify a certain file (with the -- pathspec option). Be aware that when using this with git log, Git will perform History Simplification, which will prune entire sub-graphs as it walks the Git commit graph. Essentially, upon encountering a merge, Git will prune away any leg of the merge that doesn't match the then-current version of the file, unless that takes all legs of the merge. That is, suppose we have:

...--o--o--◎
            \
             M--o--...
            /
...--o--o--●

where commits and were merged to make commit M. In commit M, there is a file named file. This file appears in both and . The copy in , however, exactly matches the copy in M, while the copy in is different. The git log command, with the default history simplification turned on, will follow the top row of this diagram and completely ignore the bottom row.

This is because Git thinks you are looking for commits that resulted in the version of the file you see in commit M. That is: how did we get this version of the file? We got it because commit M completely ignored the branch that led up to the version that appears in commit , so git log should likewise ignore that branch.

If this is what you want, that's good! If not, be sure to use extra git log options to control or defeat the history simplification. (The most straightforward option is --full-history, which does what it says.)

torek
  • 448,244
  • 59
  • 642
  • 775