Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The purpose of <code>git subtree split</code> is to create some new commits (representing “local” changes originally made in the subtree’s local directory) on top of the subtree’s original history. Since it directly involves the subtree’s original history (as the parent commit of the first rewritten local commit that touches the subtree), the split operation can not be done without the subtree’s original history itself being present.</p> <p>Think about what you will be doing with the history that <code>git subtree split</code> generates. You will probably want to push it to a repository where you can merge it into the rest of the “upstream” history. In order for this merge operation to make sense, the split history needs to be based on the original history itself<sup>1</sup>.</p> <p>Probably the most reliable way to arrange for users to have the subtree’s original history is to publish the URL for the subtree’s upstream repository in your documentation and have them define a remote for it (it is perfectly fine to have “unrelated” remotes in a single repository). E.g.</p> <blockquote> <p>If you need to work with the “upstream” of <code>Some/Sub/Dir</code> (to pull in external changes or push out local changes), please define and update a remote for the library’s repository before using <code>git subtree</code>:</p> <pre><code>git remote add lib git@host:the-lib-repository &amp;&amp; git fetch lib </code></pre> </blockquote> <p>You would need to do something like this even if you were not using <code>--squash</code> since users would need to know where to get new upstream commits (and where (ultimately) to push new split-generated commits).</p> <p>Using <code>--squash</code> gives you a “clean” history in your main project and means that only those users that need to deal with the subtree’s “upstream” actually have to have its objects in their repositories.</p> <hr> <p>It seems like you have a good understanding of the object model. You are correct that the history that <code>git subtree add --squash</code> pulls in will become dangling<sup>2</sup> but that <code>git subtree split</code> can still use it until it is pruned away.</p> <p>(with reference to your reproduction script)<br> You are able to successfully split in your <code>repoMainClone</code> only because local clones automatically hardlink (or copy) all the files in <code>.git/objects/</code> (thus getting access to <code>repoMain</code>’s copies of the dangling (or nearly dangling<sup>2</sup>) objects from <code>repoLib</code>) instead of using the usual “pack protocol” transport (which would limit the transferred objects to only those needed for the transferred refs; i.e. omitting anything from <code>repoLib</code>). Your <code>repoMainPull</code> is effectively equivalent cloning <code>file://"$(pwd)"/repoMain repoMainCloneFile</code> (the <code>file://</code> URL forces local clones to use pack-based transfers instead of just linking/copying everything).</p> <hr> <p><sup>1</sup> Actually, you can directly merge unrelated histories, but you lose the ability to do three-way merges (since there is no common ancestor). This would be quite a sacrifice.</p> <p>Your proposed <code>git subtree split -P Some/Sub/Dir 43b3eb7^.. --ignore-joins …</code> (where 43b3eb7 is the synthetic commit that resulted from <code>git subtree add --squash …</code>), would generate an unrelated history (except it needs to be <code>43b3eb7..</code> since <code>43b3eb7^</code> means “the first parent of 43b3eb7” and 43b3eb7 has no parents). I am not sure that <code>git subtree split</code> was designed to take ranges like this though. The documentation for <code>git subtree split</code> just says <code>&lt;commit&gt;</code>, but never really mentions its purpose. Reading the code shows that it defaults to HEAD, which might indicate that it is intended to be a single commit specifying the “tip” of the history that should be processed for splitting. Also, turning on the debug output shows a message <code>incorrect order:</code> which might indicate that using a range argument is putting the split operation in an unexpected situation (it is expecting to have processed all of the parents of a commit before processing the commit itself, but the range ensures that 43b3eb7 (which is the parent of the subtree merge commit) is never processed). I think you can just use <code>--ignore-splits</code> and leave off the range if you want to generate “unrelated” history and try to use it in some way: <code>git subtree split -P Some/Sub/Dir --ignore-joins …</code>.</p> <p><sup>2</sup> They are not actually dangling immediately after <code>git subtree add --squash</code> because they are still referenced by FETCH_HEAD. Once an unrelated fetch is done, however, they will become truly dangling.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload