Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can't get there from here (as the fellow giving directions said). More precisely, it does not make sense.</p> <p>The problem is that <code>git merge --squash</code> does not actually do a merge. Suppose your branch history looks like this, for instance (with branches <code>topic</code> and <code>devel</code>):</p> <pre><code> H ⬅ I ⬅ J &lt;-- topic ⬋ ⬅ F ⬅ G ⬉ K ⬅ L &lt;-- devel </code></pre> <p>If you check out <code>devel</code> and merge <code>topic</code> you get a new merge commit <code>M</code> that contains the result of the merge, and <code>M</code> has two parents:</p> <pre><code> H ⬅ I ⬅ J &lt;-- topic ⬋ ⬆ ⬅ F ⬅ G ⬆ ⬉ ⬆ K ⬅ L ⬅ M &lt;-- devel </code></pre> <p>But if you use <code>git merge --squash topic</code> you get, instead, a new commit (let's label it <code>S</code> for squash):</p> <pre><code> H ⬅ I ⬅ J &lt;-- topic ⬋ ⬅ F ⬅ G ⬉ K ⬅ L ⬅ S &lt;-- devel </code></pre> <p>where (as you already noted) the <em>contents</em> (the tree) of commit <code>S</code> makes all the files come out the same as they would in commit <code>M</code>. But there's no back-link (parent arrow) from S to <code>topic</code>. It's not a merge at all, it's just taking all the changes from <code>topic</code>, squashing them into a single change, and adding that as an entirely independent commit.</p> <p>Now, the other thing about <code>git merge --squash</code> is that it does not make the final commit. So you could create the <code>.git</code> files that git would on a "regular" merge, and do a commit that has the two parents you'd get on a "real" merge. And then you'd get ... exactly what you get if you run <code>git merge topic</code>, a commit (label it <code>S</code> or <code>M</code>, it does not matter) that has the same tree again, but now has two parent-arrows, pointing to <code>L</code> and <code>J</code>, just like <code>M</code>.</p> <p>In fact, running <code>git merge --squash</code> is almost exactly the same as running <code>git merge --no-commit</code>, except for the tracing files left behind when the merge is done (<code>git commit</code> uses some of these to set up the parents). The <code>squash</code> version does not write to <code>.git/MERGE</code>, <code>.git/MERGE_HEAD</code>, and <code>.git/MERGE_MODE</code>. (It does create <code>.git/MERGE_MSG</code>, the same as <code>git merge --no-commit</code>, and it also creates <code>.git/SQUASH_MSG</code>.)</p> <p>So, basically, you have your choice: a real merge (two or more parents on the final commit), or a squash (same tree-combining mechanisms, but only one parent on the final commit). And, since <code>git branch --merged</code> works by looking at the "parent arrows" of each commit stored in the repository, only a real merge is really a merge, so only a real merge can be discovered later by <code>git branch</code>.</p>
    singulars
    1. This table or related slice is empty.
    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.
 

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