1

Make is purely timestamp-oriented: if a source is older than its target, the target gets rebuilt. This can cause long recompilations in big applications if one does some major version control detour.

Let me give you an example. Suppose I have an old feature branch which didn't get merged yet, and I want to see how it's doing. So starting from master, I would checkout that branch, then merge master into it, then compile. All very fine, and if the feature was small, then differences vs. master should be small as well. Except that if the feature branch was really old, I undid and then redid a lot of modifications in the file system.

As a second example, you might imagine bisecting large portions of code while looking for some complicated condition which is beyond git pickaxe but which does not require recompiling the code. After I found what I was looking for, I should be back at my master branch. But in between, many files might have been modified if the bisection window was large enough.

So what I'd like to know is this: is there some tool which would allow me to take a snapshot of modification times up front, and restore the mtimes for those files whose content was restored by these operations. Of course I'd have to tell it explicitely when I'm done, since the whole point of this is that the files may get changed in between.

I guess I'm looking for a tool which integrates with git, because for a generic tool, taking snapshots of a big source tree would also take considerable time, so it would have to be something which can keep track of files as they get modified, e.g. using some hook. On the other hand, if git status has to check the content of every file as well, then maybe the cost of a generic tool isn't that high.

Is there such a tool, or would I have to write one myself?

Note that Checking out old file WITH original create/modified timestamps does not seem exactly what I want, and would take too long in any case.

Community
  • 1
  • 1
MvG
  • 57,380
  • 22
  • 148
  • 276
  • "and restore the mtimes for those files whose content was restored by these operations" - This is unclear, especially "these operations". Fiddling with mtimes is all right, but what will that achieve? If you don't keep the object file derived from that particular source file version, you'll have to recompile. – laune Apr 24 '14 at 14:20
  • “these operations” means e.g. “switch branch then merge”, or “bisect then checkout head”. Something which modifies many files in between but few files if taken together. Is that any clearer? I do keep the object files, so I have to recompile if and only if the file *content* changed since I did the compile, but make will recompile if the *timestamp* changed. Changing the content then restoring it will change the timestamp but will cause no net change to the content. That's the relevant case for me. – MvG Apr 24 '14 at 14:34
  • Is going back to a previous version from "that time" in some (your) CM system really changing the timestamp from "that time" to "now"? Maybe I'm spoiled, but we never had that problem with the not-for-free system used at my company. – laune Apr 24 '14 at 14:38
  • @laune: The CM (git in this case) does nothing directly with the timestamps, but it changes the file content to what it was back then, which causes the OS to update the timestamp to the current time. When the content changes back, the timestamp is again updated to the current time, which is newer than my last compile so the objects seem out of date. – MvG Apr 24 '14 at 14:42
  • I remember seeing a project once that you could use in conjunction with `git` to capture metadata like permissions and timestamps. Don't remember the name, but perhaps hunting around [here](http://git-scm.com) would be a good starting point... – twalberg Apr 25 '14 at 19:29
  • @twalberg: One of those mentioned [here](http://stackoverflow.com/a/17583212/1468366)? In any case, that's not what I want: I *want* timestamp to become the current one if files change, because I have to trigger recompilation for those. I only want to treat multiple operation as a single atom with regard to what files got modified, which doesn't exactly fit what you describe. – MvG Apr 25 '14 at 19:31
  • Perhaps you need to update the question with your requirements, then, because either one of those appears like it would be able to "take a snapshot of modification times up front, and restore the mtimes for those files whose content was restored by these operations". Maybe I'm just not understanding your explanation... – twalberg Apr 25 '14 at 19:37
  • @twalberg: The way I read it, both of these restore mtimes *unconditionally* whereas I want to restore them only if file content didn't change. Should I print “for those files whose content was restored by these operations” in italics? – MvG Apr 25 '14 at 19:40
  • But for the files whose content didn't change, restoring the mtimes would essentially be a no-op... Is it just the efficiency / wasted work that is concerning about that? – twalberg Apr 25 '14 at 19:42
  • @twalberg: I think you got me wrong: if the file *content* changed, then I *don't* want to restore mtime. Only if the file *content* is the same as when taking the snapshot, then I want to restore the mtime from the snapshot as well, so that it looks as if the file got never modified in the first place. – MvG Apr 25 '14 at 19:45

2 Answers2

1

Finding no suitable tool, I ended up writing my own tool. It turned out to be less difficult than I thought, mostly because hashing the content of all these files was less expensive than I thought, at least with hot file system caches.

MvG
  • 57,380
  • 22
  • 148
  • 276
0

If the production of derived versions is too costly, and if this kind of branch switching and going back to some old baseline is something you do frequently (why?) then you should consider checking in these derived versions along with their inputs, and baseline-label them.

laune
  • 31,114
  • 3
  • 29
  • 42
  • Compilation is not prohibitively costly, only annoyingly so, and the source tree isn't mine. So no, checking in products is not an option. As for the why, features are developed in different branches, and I work on different features. So “switch to feature branch then merge master” is a common step. The longer I haven't worked on a given feature, the more differences there will be in between. – MvG Apr 24 '14 at 14:35