Re: How to check out the repository at a particular point in time
I'll basically reply from bottom up so you can see the motivation and then my suggestions for the solution.
R. Diez wrote:
Show 5 quoted lines
>
> 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.
> Say, for example, an hour ago I had temporarily checked out last
> year's versions, but half an hour ago I went back to this year's
> versions. If I check out at HEAD@{1 hour ago}, will I get then last
> year's version, or this year's?The @{date} and @{n} syntax refers to the reflog, which as the name tries to imply, is a log of where *your local ref* was at that time/step. Since the HEAD ref is by definition what you have checked out at the moment, HEAD@{1 hour ago} indeed refers to last year's version.
> Anyway, my real problem is with the mentioned --until option. "git
> checkout" does not understand that option, so I guess I need to feed
> the date to some other git command in order to get the commit ID for
> "git checkout", right? Can someone help me here?
It is a git-log option (or more precisely, revision walker option). The main problem is that your request is not very well-defined: in nonlinear history there will in general be more than one commit at the time requested.
---a----b----c----M---- (M is a merge)
\ /
d-----e----f ^---- April 1st
Suppose you ask git for "the newest commit as of April 1st" in this history. Is it supposed to give you b or d? [If you think nonlinear history is easy, try to figure out a good rule in the presence of time skew, where misconfigured clocks/timezones resulted in parents being younger than children.]
Hence:
> For extra karma points, git checkout could understand the --until option itself.
It probably never will, because that is an ill-defined request.
You can indeed say
git log -1 --until="april 1"
to get *one* commit that happened before April 1st, but which one is up to the order internally used by git. You can also say
git log -1 --first-parent --until="april 1"
to get the first such commit along the first-parent ancestry, which might suit the ticket.
But there is a more fundamental issue. Let me explain.
Show 6 quoted lines
> I'm writing a daily build script for all the OpenRISC components, so
> every day I need to check out several git repositories with the
> source code of many tools that depend on each other.
>
> The hole process takes hours. In order to minimize the risk of
> repository skew
Step back and consider the real problem here. In the simplest case you are getting two components A and B which depend on each other, e.g., A depends on B. But there is a race condition in the case where a user updates an API between them in a backward-incompatible way: she has to update both A and B, and an unfortunate coworker/buildbot may pull old-A and new-B (or vice versa) and get a broken build. [Incidentally this seems to be a frequent problem with SVN externals.]
You might say: if only we had a way to record the fact that the "blessed" version of B to go with old-A is old-B, and for new-A it's new-B.
And indeed we do. Submodules were invented to allow B to be "linked" into A's repository, such that a checkout of any commit of A "knows" the correct corresponding version of B. A user who updates the API can record the update to B inside the API-changing commit in A.
So while you can kludge your way around the problem with clever use of 'git log --until', submodules would be the "correct" solution.
--
Thomas Rast
trast@{inf,student}.ethz.ch