<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: squ94wk</title>
    <description>The latest articles on DEV Community by squ94wk (@squ94wk).</description>
    <link>https://dev.to/squ94wk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F225069%2F51f1ea53-4c6b-4f82-acb4-9b098c19f734.png</url>
      <title>DEV Community: squ94wk</title>
      <link>https://dev.to/squ94wk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/squ94wk"/>
    <language>en</language>
    <item>
      <title>How to git when you're offline: proxying through bare repositories</title>
      <dc:creator>squ94wk</dc:creator>
      <pubDate>Thu, 31 Oct 2019 13:48:38 +0000</pubDate>
      <link>https://dev.to/squ94wk/how-to-git-when-you-re-offline-proxying-through-bare-repositories-2kp7</link>
      <guid>https://dev.to/squ94wk/how-to-git-when-you-re-offline-proxying-through-bare-repositories-2kp7</guid>
      <description>&lt;p&gt;As of recent I've been working a lot on remote machines without an internet connection. This can be a real annoyance for many reasons, but it also forces you to really learn your tools and some of their often overlooked features.&lt;br&gt;
Through the following rather peculiar scenario, I will demonstrate how one can use bare git repositories as intermediate remotes to "proxy" to a remote git server.&lt;/p&gt;
&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Following scenario:&lt;/p&gt;

&lt;p&gt;Machine A:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;running Windows in a VM :(&lt;/li&gt;
&lt;li&gt;connected to a git server&lt;/li&gt;
&lt;li&gt;can login to machine B with ssh client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Machine B:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;running Linux :)&lt;/li&gt;
&lt;li&gt;cannot reach the git server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do you get a copy of the git repository from the git server to the Linux machine while maintaining a reasonably usable workflow?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One could &lt;code&gt;scp&lt;/code&gt; files (or git bundles) between the machines, but who really wants to do that all the time?&lt;/p&gt;
&lt;h2&gt;
  
  
  Using bare repositories
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;"Bare" repositories are git repositories without a working tree. Git servers use them behind the scenes, since they don't need to edit files and stage changes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is what I came up with:&lt;/p&gt;
&lt;h4&gt;
  
  
  Step 1
&lt;/h4&gt;

&lt;p&gt;On Windows I clone the repository in question into a bare repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@git-server:squ94wk/sample.git &lt;span class="nt"&gt;--bare&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This creates a directory &lt;code&gt;./sample.git&lt;/code&gt; with basically the contents of the &lt;code&gt;.git&lt;/code&gt; directory that you normally get with &lt;code&gt;clone&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2
&lt;/h4&gt;

&lt;p&gt;Then I create an empty bare repository on Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git init &lt;span class="nt"&gt;--bare&lt;/span&gt; remote/sample.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I created this in the &lt;code&gt;./remote&lt;/code&gt; directory, because this is not actually the repository I will be working with; rather, it acts as a "fake" remote in the sense that it isn't on another machine.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3
&lt;/h4&gt;

&lt;p&gt;I can now set up the bare repository on Linux (with ssh host alias "linuxvm") as a remote on the Windows machine and push to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add linux linuxvm:remote/sample.git
git push linux master:master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The contents of the master branch on Linux are now the same as on Windows and the git server alike.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4
&lt;/h4&gt;

&lt;p&gt;There is still no working tree though. To fix that I just clone the bare repository that exists locally on Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone ./remote/sample.git sample
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Workflow
&lt;/h2&gt;

&lt;p&gt;I can now make changes to my working tree, commit and push them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# cd sample&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"a change"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; file
git add file
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"add 'a change' to file"&lt;/span&gt;
git push &lt;span class="c"&gt;# origin master:master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The commit and the updated reference still needs to go to the Windows machine and to the git server.&lt;/p&gt;

&lt;p&gt;If Windows was running a ssh server I could push directly from the Linux machine to Windows (that would come with other benefits as well, like automating the next step with a &lt;code&gt;post-update&lt;/code&gt; hook). But since it only works the other way around, I fetch the changes from the Linux machine and push them to the git server manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch linux
git push origin linux/master:master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;linux/master&lt;/code&gt; is tracking the remote master branch of the bare repository on the Linux machine.&lt;/p&gt;

&lt;p&gt;It works the other way around, too. I fetch changes from the git server and push them to the bare repo on Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch origin
git push linux origin/master:master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There I can then fetch/pull the changes, hence updating my remote tracking branches and my working tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch
git merge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Done.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Now although this workaround is quite a stretch, it comes closest to the familiar "fetch-commit-push" workflow and is quite robust.&lt;br&gt;
Using &lt;code&gt;--bare&lt;/code&gt; saves you from having working trees everywhere that you don't use and would otherwise only get in the way.&lt;/p&gt;

&lt;p&gt;You might never have to use bare repositories yourself (or frankly even work in such an atrocious environment), but I hope you can still take something away.&lt;/p&gt;

</description>
      <category>git</category>
      <category>offline</category>
    </item>
  </channel>
</rss>
