git warning: Log for 'master' only goes back to a date? How to refer to remote branch instead of local branch?
TL;DR
This line:
commit a2d1acfe855899e7e9562a16b692aa5d1f44d5dd (HEAD -> master, origin/master)
indicates that your master
is already in sync with your origin/master
, so you're on the same commit. The one caveat is, this is from your Git's memory of their Git, the last time your Git talked to their Git. Run git fetch origin
any time to have your own Git get anything new from their (origin
's) Git and update your origin/*
names: now your Git's memory is up to date. (Of course, it could be out of date a few seconds later.)
Long
Git can be pretty confusing. The terminology is not very consistent and words get re-used with totally different meanings, all over the place.
In this case the warning message is just what you noted: master@{...}
uses what Git calls the reflogs. The reflogs are logs (unrelated to git log
) of refs or references. The name master
is a branch name, which is a specific form of reference. So this refers to the reflog for the ref refs/heads/master
, and refs/heads/master
is the long way of spelling out master
.
So we've just seen one problem: the word log might mean git log
, but it might mean something else. That's nothing, though, compared to the word branch! See, e.g., What exactly do we mean by "branch"?
To help clear up all the confusion, let's start with something more basic, though. When you use Git, there's more than one repository involved. You have your copy, I have mine, Fred has his, Alice has hers, and so on. Every one of these Git repositories has branches and commits and stuff like that. How can we keep them all straight?
There are only a few absolutes, in Git. The main one is those hash IDs you see in your git log
output:
commit 1cfee7bc5c292c09a108e0319ddcec8ab3608887
and:
commit a2d1acfe855899e7e9562a16b692aa5d1f44d5dd
These hash IDs are truly universal. If you have commit a2d1acfe855899e7e9562a16b692aa5d1f44d5dd
, your Git calls it a2d1acfe855899e7e9562a16b692aa5d1f44d5dd
. If Alice has it, her Git calls it a2d1acfe855899e7e9562a16b692aa5d1f44d5dd
too. Everyone who has that commit, calls it that same big ugly hash ID. They either have that, or they don't have anything with that big ugly hash ID.
Mere humans, of course, are terrible at dealing with these hash IDs. But we don't have to deal with them directly, most of the time: we have a computer. Why not have it remember the hash IDs? So Git does that—which is where branch names come in—but each Git repository has its own branch names. Your master
need not match Bob's master
. Your name master
will hold some big ugly hash ID, but it might be different from someone else's.
To deal with that, we have our Gits remember each other's branches. When you have your Git call up some other Git that you call origin
, your Git has their Git list out its branch names and hash IDs. Their Git may say my master
is a2d1acfe855899e7e9562a16b692aa5d1f44d5dd
. If so, your Git makes sure you have that commit (by hash ID), getting it from their Git if not, and then your Git sets your refs/remotes/origin/master
name to a2d1acfe855899e7e9562a16b692aa5d1f44d5dd
.
What this means in the end is that you can tell what their Git's master
was, the last time your Git talked to their Git, by checking to see what your Git's origin/master
is now. You can change which hash ID your master
is; your Git will leave your origin/master
—full name refs/remotes/origin/master
—alone, until you have your Git call up their Git again and find out where their master
is.
Your reflogs remember, for you, what your Git put in your references. Every time your Git updates your master
, your Git stores a new entry in your Git's refs/heads/master
reflog. This works for your remote-tracking names too: every time your Git updates your refs/remotes/origin/master
, your memory of origin
's master, your Git stores a new entry in your Git's refs/remotes/origin/master
reflog. So you can look in your reflogs, but that's to see what you used to have in your own refs. That does not look at any actual commits, at least not right away; these reflog entries hold one hash ID each, and you can use that to find commits.
Reflog entries are private to each Git. Your Git will not get reflog entries from their Git. You cannot see what they did to their refs over time, not this way anyway. You can only see what your Git did to your refs over time.
The @{xyz}
syntax checks the reflogs, those are logs of what refs have pointed at. All refs are local. @{2.days.ago}
is "what I had checked out in this repo 2 days ago". If instead you want "the last thing committed to origin's master at least 2 days ago." A good starter kit:
git rev-list -1 --before 2.days.ago origin/master
Depending on what you're looking for you, might also want --first-parent
and/or --author-date-order
.
You can also use specific dates, for instance
git checkout `git rev-list -1 --before="Apr 1 2020" HEAD`