<div dir="ltr">Hi Eli: I&#39;m trying to understand your point. Do I have this right?<div><br></div><div style>Background: The git history consists of a series checkpoints in time of the entire repository, not a collection of individual files. So, when I do &quot;git log x.rkt&quot; then what I get is essentially a filtered list (except where people didn&#39;t properly rebase, but lets ignore that) of those checkpoints: all the ones where &quot;x.rkt&quot; changed.</div>
<div style><br></div><div style>Big Question: The issue is, then, when we split up the current repo into smaller repos, what are the series of checkpoints that we&#39;re going to &quot;make up&quot; for the individual repos? Right? </div>
<div style><br></div><div style>Your Advice: And, IIUC, you&#39;re suggesting that the best way to deal with this question is to defer it until we are more sure of the actual split we want to make. So we don&#39;t mess with the history at all and instead just work at the level of some script that we can run to just use &quot;mv&quot; and company to move things around. When we know exactly what ends up going where, then we can figure out how to make up a new, useful history for the separate repositories.</div>
<div style><br></div><div style>Is that the point?</div><div style><br></div><div style>Robby</div><div style><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, May 23, 2013 at 4:41 AM, Eli Barzilay <span dir="ltr">&lt;<a href="mailto:eli@barzilay.org" target="_blank">eli@barzilay.org</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">9 hours ago, Matthew Flatt wrote:<br>
</div><div class="im">&gt; At Wed, 22 May 2013 14:50:41 -0400, Eli Barzilay wrote:<br>
&gt; &gt; That&#39;s true, but the downside of changing the structure and having<br>
&gt; &gt; files and directories move post structure change will completely<br>
&gt; &gt; destroy the relevant edit history of the files, since it will not<br>
&gt; &gt; be carried over to the repos once it&#39;s split.<br>
&gt;<br>
&gt; It&#39;s possible that we&#39;re talking past each other due to me not getting<br>
&gt; this point.<br>
<br>
</div>(Obligatory re-disclaimer: I consider the problem with forcing people<br>
to change their working environment much more severe.)<br>
<div class="im"><br>
<br>
&gt; Why is it not possible to carry over history?<br>
&gt;<br>
&gt; The history I want corresponds to `git log --follow&#39; on each of the<br>
&gt; files that end up in a repository. I&#39;m pretty sure that such a<br>
&gt; history of commits can be generated for any given set of files, even<br>
&gt; if no ready-made tool exists already (i.e., &#39;git&#39; is plenty flexible<br>
&gt; that I can script it myself).<br>
&gt;<br>
&gt; Or maybe I&#39;m missing some larger reason?<br>
<br>
</div>The thing to remember is just how simple git is...  There&#39;s no magical<br>
way to carry over a history artificially -- it&#39;s whatever is in the<br>
commits.<br>
<br>
To make this more concrete (and more verbose), in this context the<br>
point is that git filter-branch is a simple tool that basically<br>
replays the complete history, allowing you to plant various hooks to<br>
change the directory structure, commit messages or whatever.  The new<br>
history is whatever new commits are in the revised repository, with no<br>
way to make up a history with anything else.<br>
<br>
Now, to make my first point about the potential loss of history that<br>
is inherent in the process -- say that you want to split out a<br>
&quot;drracket&quot; repo in a naive way: taking just that one directory.  Since<br>
it&#39;s done naively, the resulting repository will not have the<br>
&quot;drscheme&quot; directory and its contents, which means that you lose all<br>
history of files that happened there.  To try that (in a fresh clone,<br>
of course) -- first, look at the history of a random file in it:<br>
<br>
  F=collects/drracket/private/app.rkt<br>
  git log --format=&#39;----%n%h %s&#39; --name-only --follow -- &quot;$F&quot;<br>
<br>
Now do the revision:<br>
<br>
  S=collects/drracket<br>
  git filter-branch --prune-empty --subdirectory-filter &quot;$S&quot; -- --all<br>
<br>
And look at the same log line again, the history is gone:<br>
<br>
  git log --format=&#39;----%n%h %s&#39; --name-only --follow -- &quot;$F&quot;<br>
<br>
If you look at the *new* file, you do see the history, but the<br>
revisions made in &quot;drscheme&quot; are gone:<br>
<br>
  git log --format=&#39;----%n%h %s&#39; --name-only --follow -- private/app.rkt<br>
<br>
In any case, this danger is there no matter what, especially in our<br>
case since code has been moving around in the &quot;racket&quot; switch.  I<br>
*hope* that most of it will be simple: like carrying along the<br>
&quot;drscheme&quot; directory with &quot;drracket&quot;, the &quot;scheme&quot; and &quot;mzlib&quot; with<br>
&quot;racket&quot;, etc.  Later on, if these things move to &quot;compat&quot; packages,<br>
the irrelevant directories get removed from the repo without<br>
surgeries, so the history will still be there.  This shows some of the<br>
tricks that might be involved in the current switch: if you&#39;d want to<br>
have some &quot;compat&quot; package *now*, the right thing to do would be:<br>
<br>
  * do a simple filter-branch to extract &quot;drscheme&quot; (and other such<br>
    collections) in a new repository for &quot;compat&quot;<br>
<br>
  * for &quot;drracket&quot;: do a filter-branch that keeps *both* directories<br>
    in, then commit a removal of &quot;drscheme&quot;.  (Optionally, use rebase<br>
    to move the deletion backward...)<br>
<br>
Going back to the repo structure change that you want and the reason<br>
that I said that doing moves between the package directories<br>
post-restructure is destructive should be clear now: say that you move<br>
collects/A/x into foo/A/x as part of the restructure.  Later you<br>
realize that A/x should go into the bar package instead so you just<br>
move it to bar/A/x.  The history is now in, including the rename, but<br>
later on when bar is split into a separate repo, the history of the<br>
file is gone.  Instead, it appears in the foo repository, ending up<br>
being deleted.<br>
<br>
One way to get around this is to avoid moving the file -- instead, do<br>
another filter-branch surgery.  This will be a mess since each such<br>
change will mean rebuilding the repository with all the pain that this<br>
implies.  Another way to get around it is to keep track of these<br>
moving commits, and when the time comes to split into package repos,<br>
you first do another surgery on the whole repo which moves foo/A/x to<br>
bar/A/x for all of the commits before the move (not after, since that<br>
could lead to other problems), and then do the split.<br>
<br>
This might work, but besides being very error-prone, it means doing<br>
the same kind of file-movement tracking that I&#39;m talking about anyway.<br>
So take this all as saying that the movement of files between packages<br>
needs to be tracked anyway -- but with my suggestion the movement is<br>
delayed until it&#39;s known to be final before the repo split, which<br>
makes it more robust overall.<br>
<br>
----<br>
<br>
But really, the much more tempting aspect for me is that this can be<br>
done now -- if you give me a list of packages and files, I can already<br>
do the movement script.<br>
<br>
Actually, in an attempt to tempt you more, here&#39;s what I can do now<br>
(as in the very near future):<br>
<br>
Start from the list of directories/files in your min repo as a<br>
specification of the contents of the core package, and decide that<br>
everything else is in another &quot;everything-else&quot; package.  (Since<br>
there&#39;s no actual file movements, it is cheap to use temporary names<br>
and partial specifications.)<br>
<br>
Then, change how the build works on the main machine (leave the other<br>
machines as is for now): after the initial few steps of updating<br>
version files etc the script doesn&#39;t use a repo -- it uses just the<br>
exported directory.  So after it exports the directory for building,<br>
the main machine will:<br>
<br>
  - run the script to get the package directories, so you get<br>
    something like (in $PLTHOME, whereever the build works):<br>
<br>
      collects \<br>
      doc       \  all of these<br>
      man       /  are empty<br>
      src      /<br>
      core/collects<br>
      core/man<br>
      core/src<br>
      everything-else/collects<br>
<br>
  - it now moves core/* up a level (and removes the empty &quot;core&quot;<br>
    directory)<br>
<br>
  - do the regular build: executables + raco setup<br>
<br>
  - next, move everything-else/* up a level too<br>
<br>
  - run another setup<br>
<br>
This means that now the build makes sure that the dependencies are<br>
fine: that the core doesn&#39;t depend on everything-else.  Later on, we<br>
can split another package out from everything-else, and insert it into<br>
the above sequence: build the core, add P, run setup, add everything<br>
else, run a final setup.  It can even get more sophisticated:<br>
<br>
  - build core,<br>
  - add P1, setup, move the built P1 out,<br>
  - add P2, setup, move the built P2 out,<br>
  - add everything-else and the built P1 &amp; P2, run a final setup<br>
<br>
Yes, this is duplicating the dependency info between the packages, but<br>
this is all done temporarily (and for a small number of packages)<br>
until the proper package-based build is working and replaces it.<br>
<br>
In other words -- not only is my suggestion implementable now, it<br>
allows the project to proceed faster: you can go on with doing the<br>
package build, while everyone need to deal with respecting<br>
dependencies (deciding on which package a file goes with, avoiding<br>
breaking these dependencies).<br>
<div class="im HOEnZb"><br>
--<br>
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:<br>
                    <a href="http://barzilay.org/" target="_blank">http://barzilay.org/</a>                   Maze is Life!<br>
</div><div class="HOEnZb"><div class="h5">_________________________<br>
  Racket Developers list:<br>
  <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
</div></div></blockquote></div><br></div>