<?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: Pato</title>
    <description>The latest articles on DEV Community by Pato (@rmpato).</description>
    <link>https://dev.to/rmpato</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%2F23690%2Fc4cdaed6-4b6d-41eb-8d38-735e61cf8393.jpg</url>
      <title>DEV Community: Pato</title>
      <link>https://dev.to/rmpato</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rmpato"/>
    <language>en</language>
    <item>
      <title>A new use case for git submodules</title>
      <dc:creator>Pato</dc:creator>
      <pubDate>Wed, 05 Feb 2020 17:13:43 +0000</pubDate>
      <link>https://dev.to/rmpato/a-new-use-case-for-git-submodules-3do1</link>
      <guid>https://dev.to/rmpato/a-new-use-case-for-git-submodules-3do1</guid>
      <description>&lt;p&gt;Git submodules are a gray area to me: not because of how they work, but because of identifying a situation they suit up nicely, and that is, without feeling I'm complicating things unnecessarily. &lt;/p&gt;

&lt;p&gt;Some time ago I wrote &lt;a href="https://gabac.blog/posts/git-pull-many-repos-at-once/"&gt;this article in my blog&lt;/a&gt;, and also on &lt;a href="https://dev.to/rmpato/git-pull-multiple-repositories-at-once-4l68"&gt;dev.to&lt;/a&gt; which is kind of a sloppy solution to a problem that deserved a better one. So, now I've got time to revisit it, and yes: this time we approach with (oh, you got it already!) git submodules!&lt;/p&gt;

&lt;p&gt;Now, instead of running this hard to memorize and not so extensible command I came up with before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-mindepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 1 &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-print&lt;/span&gt; &lt;span class="nt"&gt;-exec&lt;/span&gt; git &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; pull &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, I can just do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodules foreach &lt;span class="nb"&gt;command&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;command&lt;/code&gt; would be anything we want to run across all the repos.   &lt;/p&gt;

&lt;p&gt;So, this post is about solving what was already solved, this time with a better, more extensible approach: &lt;br&gt;
A simple yet useful approach with submodules.&lt;/p&gt;
&lt;h2&gt;
  
  
  Git submodules
&lt;/h2&gt;

&lt;p&gt;So, this is what we'll be doing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new repo &lt;/li&gt;
&lt;li&gt;Add in every repo we want to manage as a submodule&lt;/li&gt;
&lt;li&gt;Checkout a branch on every submodule/repo - one command!&lt;/li&gt;
&lt;li&gt;Get the status of each submodule from top-level repo - one command!&lt;/li&gt;
&lt;li&gt;Check all submodule repos status - one command!&lt;/li&gt;
&lt;li&gt;Pull changes for every submodule - one command!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alright then, let's do it!&lt;/p&gt;
&lt;h3&gt;
  
  
  Create a new repo
&lt;/h3&gt;

&lt;p&gt;Just cd into a new dir, and init a new repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir platform-repo &amp;amp;&amp;amp; git init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Add every repo you want to control as a submodule
&lt;/h3&gt;

&lt;p&gt;Repeat this as many times as repos you wish to add. Each repo will be mounted in a new directory (similarly as git clone does).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git submodule add repo_url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Checkout a branch on every submodule
&lt;/h3&gt;

&lt;p&gt;Now, we need to point our submodules to a branch. Depending on your git version, by default submodules have a detached head (meaning they don't point to any branch). I'm assuming you would be pointing them  to either &lt;code&gt;dev&lt;/code&gt; or &lt;code&gt;master&lt;/code&gt; branch, but you can point them to wichever branch you wish to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; git submodule foreach git checkout dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Check the status of the submodules
&lt;/h3&gt;

&lt;p&gt;from the 'top-level' repo, just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; git status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It will show every submodule and its status. As you work on your submodules, you will see different statuses: new commits (since the moment you add them as submodules), untracked changes (not commited, nor staged), or yet pristine.&lt;br&gt;&lt;br&gt;
When a submodule shows new commits, it means it has them since the moment you added the submodule to the top-level repo. It works like this, because the top-level repo holds a reference to a commit in the submodule repo, and when it detects newer commits than the one it is holding its reference into, it shows the difference.&lt;br&gt;
If you want it to show no new commits, you just need to create a commit in the top-level repo. You can read more about that &lt;a href="https://unix.stackexchange.com/questions/214879/git-submodule-shows-new-commits-submodule-status-says-nothing-to-commit"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  See each submodule status
&lt;/h3&gt;

&lt;p&gt;To get submodules status as if it were an independant repo, you should:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; git submodule foreach git status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And you are golden.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pull changes for every submodule
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; git submodule foreach git pull --rebase --autostash origin branch_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This way, &lt;code&gt;--autostash&lt;/code&gt; will assure to add your changes to stash, pull, then rebase on your branch and pop changes out of stash. And all of that automatically, so you don't need to commit or stash your changes manually.&lt;br&gt;&lt;br&gt;
 This is useful because when running commands with the &lt;code&gt;git submodule foreach command&lt;/code&gt; expression, if the command exits with an error code, it might cancel the whole foreach chain. This way we ensure it doesn't exit as an error, by reducing chances for failling of the pull.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other cases
&lt;/h2&gt;

&lt;p&gt;For any other case, you can always cd into each submodule and see it still is a normal repository. So you can work from there as you usually do. Just keep that in mind when running git submodule foreach commands from the top level repo. I.E not all submodules might be in the same branch, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Here is another approach to work with many repositories at once. We could reach a similar thing if working with monorepos, but this wasn't an option at the place I was working at the moment I wrote this post. So, I found this approach, which you can maybe think about 'simulating a monorepo'. &lt;/p&gt;

&lt;p&gt;Just by adding a set of repos as submodules, you can work around it nicely. &lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;You can read in depth about git submodules &lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Submodules"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post was originally posted &lt;a href="https://https://gabac.blog/posts/git-submodules/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>git</category>
      <category>tutorial</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Git pull multiple repositories at once</title>
      <dc:creator>Pato</dc:creator>
      <pubDate>Tue, 03 Dec 2019 17:10:26 +0000</pubDate>
      <link>https://dev.to/rmpato/git-pull-multiple-repositories-at-once-4l68</link>
      <guid>https://dev.to/rmpato/git-pull-multiple-repositories-at-once-4l68</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Update:&lt;/strong&gt; I wrote about another approach to achieve this and some extras, with git submodules. You can find it here &lt;a href="https://dev.to/rmpato/a-new-use-case-for-git-submodules-3do1"&gt;here&lt;/a&gt;.
&lt;/h2&gt;

&lt;p&gt;I usually work with many repos at the same time and generally group them within a same directory, named after the company. &lt;/p&gt;

&lt;p&gt;In example, if I'm working for "Great Employer INC." I'll have a directory probably named &lt;code&gt;greatemployerinc&lt;/code&gt; and one directory for each repo I work within. Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;greatemployerinc
├── greatemployerinc-web
├── greatemployerinc-auth
├── greatemployerinc-core-service
├── greatemployerinc-email-service
├── ...more repos
└── greatemployerinc-gateway

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Instead of navigating each one of them with &lt;code&gt;cd&lt;/code&gt; and then manually run &lt;code&gt;git pull branch&lt;/code&gt;, I came out with the following command that I run from &lt;code&gt;greatemployerinc&lt;/code&gt; -the repos containing directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;find . -mindepth 1 -maxdepth 1 -type d -print -exec git -C {} pull \;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It will find any subdirectory in the current one (greatemployerinc), without going deeper than the first level (delimited by mindepth 1 and maxdepth 1) and execute  a &lt;code&gt;git pull&lt;/code&gt; in the corresponding git dir (if its a repo). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to see more on the &lt;code&gt;git -C&lt;/code&gt; option, you can check &lt;a href="https://stackoverflow.com/questions/5083224/git-pull-while-not-in-a-git-directory"&gt;this post on SO&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep in mind it will run a &lt;em&gt;git pull&lt;/em&gt; on the current branch that each repository is actually stepping on. Also, consider the pull might fail if you have pending changes (it will be shown on the console output, anyway) and you might need to handle those cases manually, or considering adding an &lt;code&gt;--autostash&lt;/code&gt; option to the provided command. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, I can't memorize that command!
&lt;/h2&gt;

&lt;p&gt;Then you and I have something in common :) &lt;/p&gt;

&lt;p&gt;To avoid memorizing it, I created an alias. If you are working with ZSH you can just add this line to your &lt;code&gt;~/.zshrc&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias multipull="find . -mindepth 1 -maxdepth 1 -type d -print -exec git -C {} pull \;"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then close your current terminal and open a new one (so the changes on &lt;code&gt;.zshrc&lt;/code&gt; take effect), go to your equivalent &lt;code&gt;greatemployerinc&lt;/code&gt; directory and do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multipull
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And drink your favorite infusion while your repos pull from remote :) &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;So, we created a quick small command to run a pull in multiple repos at once, then we created an alias for it so it is more easy to run later. &lt;/p&gt;

&lt;p&gt;If you are willing to take it further, you can tweak it a little bit around if you want to customize the branch you pull from/into, run a different command, or try and make it run in parallel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updates
&lt;/h3&gt;

&lt;p&gt;If you are interested on "resourcing" your terminal without closing/opening it, see &lt;a href="https://dev.to/jpblancodb/comment/ieo3"&gt;this comment from JPBlancoDB&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you are interested on more complex scenarios, you can use a tool like &lt;code&gt;myrepos&lt;/code&gt; just like &lt;a href="https://dev.to/alerque/comment/igbd"&gt;Caleb Maclennan points out in this comment&lt;/a&gt; &lt;/p&gt;

</description>
      <category>git</category>
      <category>learning</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Recording a terminal session</title>
      <dc:creator>Pato</dc:creator>
      <pubDate>Thu, 28 Nov 2019 19:17:27 +0000</pubDate>
      <link>https://dev.to/rmpato/recording-a-terminal-session-19n2</link>
      <guid>https://dev.to/rmpato/recording-a-terminal-session-19n2</guid>
      <description>&lt;p&gt;Whether you are writing a tutorial post on some blog, willing being able to reproduce a set of commands, just taking personal notes, or whatever the reason, it is helpful to record your terminal session, with all its commands and outputs.    &lt;/p&gt;

&lt;p&gt;For such a task, I've come across the &lt;code&gt;script&lt;/code&gt; command, which according to its man page, just makes a typescript of terminal session.&lt;/p&gt;

&lt;p&gt;You can start with a minimal expression, such as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script pepe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;pepe&lt;/code&gt; will be the output file. &lt;/p&gt;

&lt;p&gt;Once you are done recording your terminal work, you can stop recording with &lt;code&gt;exit&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Then you can &lt;code&gt;cat pepe&lt;/code&gt; and see how it went. &lt;/p&gt;

&lt;p&gt;You might find unwanted text and keystrokes as &lt;code&gt;Script started, output file is pepe&lt;/code&gt;. I recommend seeing the man pages (&lt;code&gt;man script&lt;/code&gt;) to learn how to improve the expected result and adapt it to your needs and taste.&lt;/p&gt;

&lt;p&gt;In my case, I'm writing complementary material for an online course I'm working on, so it is helpful to record the terminal, instead of copying and pasting as I go, so I can quickly create guides. The form of the command I'm more frequently using is based on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script -q -k pepe 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-q&lt;/code&gt; option suppress messages such as the script started and the script finished.  &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;-k&lt;/code&gt; option logs keys sent to the program as well as output, omitting the datetime stamp. &lt;/p&gt;

&lt;p&gt;Super interesting thing: you can record sessions with a particular format and reproduce them with &lt;code&gt;scriptreplay&lt;/code&gt;. Still thinking of ways this can help me create course material.  &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>cli</category>
      <category>learning</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
