{"id":102478,"date":"2019-05-06T07:00:00","date_gmt":"2019-05-06T14:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102478"},"modified":"2020-07-02T07:03:19","modified_gmt":"2020-07-02T14:03:19","slug":"20190506-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190506-00\/?p=102478","title":{"rendered":"Mundane git commit-tree tricks, Part 1: Building a commit manually out of a tree"},"content":{"rendered":"<p>When it comes time to make a public update to the <a href=\"https:\/\/github.com\/Microsoft\/Windows-universal-samples\/\"> UWP samples repo<\/a>, I take a snapshot of what&#8217;s in our internal staging repo and push it to the public repo. All of the intermediate steps are squashed out, so that the public repo isn&#8217;t cluttered with noisy history.<\/p>\n<p>I accomplish this with a local repo with two remotes. One remote is the public repo and the other repo is our private repo. When it&#8217;s time to make a public release, I go through these steps.<\/p>\n<p>First: Freshen my local master with the latest public. This technically isn&#8217;t necessary because nobody should be pushing to public except me, so my local master should always be up to date. But hey, it doesn&#8217;t hurt to check, because occasionally somebody else will push something to master.<\/p>\n<pre>git checkout master\r\ngit pull --ff-only public\r\n<\/pre>\n<p>Next, I update my private remote so it has a copy of the source code that we want to make public.<\/p>\n<pre>git fetch private\r\n<\/pre>\n<p>Now the fun part: Commit the latest private tree onto the latest public tree.<\/p>\n<pre>git commit-tree private\/master^{tree} -p master -m \"comment\"\r\n(this prints a hash)\r\n<\/pre>\n<p><b>Note<\/b>: If using the Windows <code>CMD<\/code> command prompt, you need to type<\/p>\n<pre>git commit-tree private\/master^^{tree} -p master -m \"comment\"\r\n<\/pre>\n<p>The doubling of the <code>^<\/code> character is necessary because <code>^<\/code> is the escape character for <code>CMD.EXE<\/code>. The point is that you want the first parameter to commit-tree to be <code>private\/master^{tree}<\/code> after the command line has had its say of escaping.<\/p>\n<p>(It&#8217;s too bad that <code>commit-tree<\/code> requires a tree. Would be nice if they could relax this requirement so it can accept any tree-ish.)<\/p>\n<p>I can then fast-forward to the newly-created commit and bingo, it&#8217;s as if I did a super-squash of the private repo onto the public repo.<\/p>\n<pre>git merge --ff-only \u2329hash\u232a\r\n<\/pre>\n<p>In reality, my workflow is a little funkier than this, and I have to update multiple branches and make each one merge into the next. We&#8217;ll look some more at the workflow next time.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A little bit of plumbing.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-102478","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>A little bit of plumbing.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102478","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=102478"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102478\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=102478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}