{"id":12114,"date":"2016-05-25T06:00:00","date_gmt":"2016-05-25T13:00:00","guid":{"rendered":"https:\/\/www.sapien.com\/blog\/?p=12114"},"modified":"2016-05-25T23:22:44","modified_gmt":"2016-05-26T06:22:44","slug":"how-git-branches-affect-files-on-disk","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2016\/05\/25\/how-git-branches-affect-files-on-disk\/","title":{"rendered":"How Git branches affect files on disk"},"content":{"rendered":"<p>When I started using Git back in 2012, I wasn&#8217;t new to source control systems. I used a database-backed source control system back in the 80&#8217;s and, at Microsoft, I used Visual Source Safe (VSS) and Team Foundation Server (TFS). I was a whiz at checking files in and out, examining and comparing versions, and restoring versions.<\/p>\n<p>Still, when I started to use Git for the Azure &#8220;help drawer&#8221; docs, I was totally unprepared for the effect of changing branches on Git-managed files on disk.<\/p>\n<h3>Git Checkout &#8212; An Example<\/h3>\n<p>Here&#8217;s an example. I&#8217;m working in my fork (my online copy) of the PSScriptAnalyzer repository. I&#8217;ve created a clone, that is, a working directory or copy on disk, of the files in my fork. <\/p>\n<p>To switch from my &#8216;development&#8217; branch to my &#8216;AddHelpTest&#8217; branch, I use the <b>git checkout<\/b> command. Despite the name, the <b>git checkout<\/b> command doesn&#8217;t check out any files &#8212; not in the traditional sense &#8212; but it checks out or switches branches.<\/p>\n<pre lang=\"PowerShell\">git checkout AddHelpTest<\/pre>\n<p>When I do a &#8216;dir&#8217; to list the subdirectories and files in the PSScriptAnalyzer directory, I can see the Pester test file that I added, Module.Help.Tests.ps1.<\/p>\n<p>After some work on the files, I switch back to my development branch:<\/p>\n<pre lang=\"PowerShell\">git checkout development<\/pre>\n<p>Now, when I do a &#8216;dir&#8217;, the Module.Help.Tests.ps1 file is gone. It&#8217;s not hidden or anything. It is just not there.<\/p>\n<blockquote><p><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/05\/clip_image001-3.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"clip_image001\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/05\/clip_image001_thumb-3.png\" alt=\"clip_image001\" width=\"592\" height=\"741\" border=\"0\" \/><\/a><\/p><\/blockquote>\n<p>No fear! When you switch back to the AddHelpTest branch:<\/p>\n<pre lang=\"PowerShell\">git checkout AddHelpTest<\/pre>\n<p>&#8230; the Module.Help.Tests.ps1 file is back.<\/p>\n<h3>Git Checkout replaces files on disk<\/h3>\n<p>When I first started using Git, I expected that creating a branch in a repository (or in a fork of a repository) would create a separate subdirectory in my files on disk.<\/p>\n<p>Something like this:<\/p>\n<pre>C:\\GitHub\\CoolRepo\r\nC:\\GitHub\\CoolRepo\\BranchA\r\n    ... Branch A files ...\r\nC:\\GitHub\\CoolRepo\\BranchB\r\n    ... Branch B files ...\r\n<\/pre>\n<p>But, that&#8217;s not how it works.<\/p>\n<p>Your files on disk represent <b>only<\/b> the files in the current or active branch &#8212; the branch that you have checked out. So, if you have different files in Branch A and Branch B, when you use &#8216;git checkout&#8217; to switch from Branch A to Branch B, Git effectively deletes the Branch A files on disk and replaces them with Branch B files.<\/p>\n<pre>git checkout BranchA:\r\nC:\\GitHub\\CoolRepo\r\n    ... Branch A files ...\r\n\r\ngit checkout BranchB:\r\nC:\\GitHub\\CoolRepo\r\n    ... Branch B files ...<\/pre>\n<p>When I first saw this behavior, I thought I had lost my work in BranchA, but it&#8217;s still out there in the big Git repo in the cloud.<\/p>\n<p>And, when you check out the files in BranchA, Git removes the files on disk from Branch B and replaces them with the files from BranchA. Nothing is lost.<\/p>\n<pre>git checkout BranchA:\r\nC:\\GitHub\\CoolRepo\r\n    ... Branch A files ...<\/pre>\n<p>Whew!<\/p>\n<p>In fact, changing branches is a local operation. All of the branches and their history are stored in files in the .git directory. You don&#8217;t need an internet connection to switch branches and see the effect in your local directory.<\/p>\n<p>As explained in the excellent, professionally written <a href=\"https:\/\/www.atlassian.com\/git\/tutorials\/using-branches\/git-checkout\" target=\"_new\">Git tutorials by Atlassian<\/a> (I highly recommend them!):<\/p>\n<blockquote><p><em>&#8220;Checking out a branch updates the files in the working directory to match the version stored in that branch, and it tells Git to record all new commits on that branch.&#8221;<\/em><\/p><\/blockquote>\n<p>That&#8217;s not what I expected, but it&#8217;s predictable, and I&#8217;ve never seen it fail.<\/p>\n<p>By the way, to list branches, use the <b>git branch<\/b> command. To combine branches, use the <b>git merge<\/b> command. I&#8217;ll tackle that one in another post.<\/p>\n<p><em>June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at <\/em><a href=\"mailto:juneb@sapien.com\"><em>juneb@sapien.com <\/em><\/a><em>or follow her on Twitter at <\/em><a href=\"https:\/\/www.twitter.com\/juneb_get_help\"><em>@juneb_get_help<\/em><\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I started using Git back in 2012, I wasn&#8217;t new to source control systems. I used a database-backed source control system back in the 80&#8217;s and, at Microsoft, I used Visual Source Safe (VSS) and Team Foundation Server (TFS). I was a whiz at checking files in and out, examining and comparing versions, and [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[932,1107,1108,283],"tags":[786,1114,896,934],"class_list":["post-12114","post","type-post","status-publish","format-standard","hentry","category-beginners","category-git","category-github","category-howto","tag-git","tag-git-checkout","tag-github","tag-juneb"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/12114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=12114"}],"version-history":[{"count":14,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/12114\/revisions"}],"predecessor-version":[{"id":12159,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/12114\/revisions\/12159"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=12114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=12114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=12114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}