Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This answer show a workflow which uses local branches as an alternative to the stash mechanism. This is the approach I prefer myself.</p> <p>I'm going to assume that:</p> <ul> <li>Your public branch head is called <code>master</code></li> <li>This "atomic operation" is a script used for making releases.</li> <li>The release tag (<code>product-1.0.0</code>) needs to point to B in the end.</li> <li>The release commit (<code>E</code>) needs to be "added" to the tip of master, after <code>C</code> and <code>D</code>.</li> <li>You have <code>master</code> checked out and your working tree is clean.</li> </ul> <p>The history looks like this initially (the <code>origin</code> remote represents what's public, <code>HEAD</code> points to your currently checked out branch head):</p> <pre><code>(A)&lt;--(B)&lt;--(C)&lt;--(D) ^ ^ / \ master orgin/master ^ | HEAD </code></pre> <p>You need to be able to see this graph yourself. I usually use a git alias like this (<code>g</code> for "graph"):</p> <pre><code>git config --global alias.g "log --decorate --oneline --graph" </code></pre> <p>You can then get the picture above by invoking:</p> <pre><code>git g master origin/master </code></pre> <p>(That displays everything reachable from <code>master</code> and/or <code>origin/master</code>. Use <code>git g --all</code> to show everytihng.)</p> <p>First create a local temporary branch head called <code>temp</code> that points to <code>B</code>, and then check it out.</p> <pre><code>git branch temp &lt;SHA1 of B&gt; git checkout temp </code></pre> <p>The commit graph now looks like this:</p> <pre><code> HEAD | v temp | v (A)&lt;--(B)&lt;--(C)&lt;--(D) ^ ^ / \ master orgin/master </code></pre> <p>Run your release script which tags the current commit, makes a change (probably bumping up the release number or something), and then makes a commit of that change.</p> <pre><code>&lt;magic release script&gt; </code></pre> <p>If I understand your release script correctly, then the resulting graph should look like this:</p> <pre><code> HEAD | v temp | v tag: product-1.0.0 (E) \ / v v (A)&lt;--(B)&lt;--(C)&lt;--(D) ^ ^ / \ master orgin/master </code></pre> <p>It's now time to move back to <code>master</code> and to "carry over" the <code>E</code> commit:</p> <pre><code>git checkout master git cherry-pick &lt;SHA1 of E&gt; </code></pre> <p>The <code>cherry-pick</code> command treats a single commit as a patch. The "patch" contains the difference between the tree snapshot at <code>B</code> and the snapshot at <code>E</code>. This "patch" is then applied at whatever branch head you have checked out - in this case <code>master</code>. The changes in the patch are made into a new commit (<code>F</code>) with the same message, and author as the original one (<code>E</code>).</p> <pre><code> temp | v tag: product-1.0.0 (E) \ / v v (A)&lt;--(B)&lt;--(C)&lt;--(D)&lt;--(F) ^ ^ | | origin/master master ^ | HEAD </code></pre> <p>Note that the <code>F</code> commit is not identical to the <code>E</code> commit! It is only "the same in spirit", that is it introduces the same logical change.</p> <p>After this, review the final state and you should be ready to push the new <code>master</code> state to <code>origin</code> to make it public.</p> <pre><code>git push origin master:master </code></pre> <p>You can now remove the temporary <code>temp</code> branch head:</p> <pre><code>git branch -D temp </code></pre> <p>You usually use the <code>-d</code> option to delete a branch, but <code>git</code> won't let you use it here. The reason is that you will lose the <code>E</code> commit. In this case it is OK since we have "saved" <code>E</code> by using <code>cherry-pick</code>. As <code>git</code> considers <code>E</code> and <code>F</code> to be distinct commits it can't know that the "spirit of <code>E</code>" remains in <code>F</code> and no information would be lost. You need to tell <code>git</code> that you have made sure that you know what you are doing by using <code>-D</code> instead of <code>-d</code>.</p> <p>Finally you should have:</p> <pre><code> tag: product-1.0.0 | v (A)&lt;--(B)&lt;--(C)&lt;--(D)&lt;--(F) ^ ^ / \ origin/master master ^ | HEAD </code></pre>
    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. This table or related slice is empty.
    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