<?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: Jon Kurinsky</title>
    <description>The latest articles on DEV Community by Jon Kurinsky (@krnsk0).</description>
    <link>https://dev.to/krnsk0</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%2F190641%2F6405546b-30fd-4970-9426-b6b6905d7ce9.jpeg</url>
      <title>DEV Community: Jon Kurinsky</title>
      <link>https://dev.to/krnsk0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/krnsk0"/>
    <language>en</language>
    <item>
      <title>Introducing `guser`: A CLI Tool for Git User-Switching</title>
      <dc:creator>Jon Kurinsky</dc:creator>
      <pubDate>Mon, 07 Sep 2020 20:19:45 +0000</pubDate>
      <link>https://dev.to/krnsk0/introducing-guser-a-cli-tool-for-git-user-switching-lf6</link>
      <guid>https://dev.to/krnsk0/introducing-guser-a-cli-tool-for-git-user-switching-lf6</guid>
      <description>&lt;p&gt;Do you manage multiple Git users on a single machine? Do you often switch between work projects and side projects and configure different repositories to use different accounts?&lt;/p&gt;

&lt;p&gt;If so, &lt;a href="https://www.npmjs.com/package/guser"&gt;you might benefit from &lt;code&gt;guser&lt;/code&gt;&lt;/a&gt;, a small CLI tool that helps make Git user-switching a tiny bit easier by remembering user/email combinations you've used in the past.&lt;/p&gt;

&lt;p&gt;As an added bonus, if you try out &lt;code&gt;guser&lt;/code&gt; you'll also be in a position to give me feedback on my very first CLI tool-- and also the first project I've published to NPM 😎.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Git users
&lt;/h2&gt;

&lt;p&gt;You probably recall configuring Git when first setting up your development environment: you likely set up an SSH key to allow Git to authenticate with Github or another remote, and you probably also configured Git with a username and email used to sign your commits.&lt;/p&gt;

&lt;p&gt;This second step you likely performed with the &lt;code&gt;git config&lt;/code&gt; tool that comes with Git, and it probably looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Margaret Hamilton"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email margaret@hamilton.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands created and/or edited a configuration file, &lt;code&gt;.gitconfig&lt;/code&gt;, in your home directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .gitconfig
&lt;span class="o"&gt;[&lt;/span&gt;user]
    name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Margaret Hamilton"&lt;/span&gt;
    email &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"margaret@hamilton.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This config file in your user directory is one of three such possible files Git might reference when authoring a commit to determine the username and email to use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/etc/gitconfig/&lt;/code&gt;, which configures Git for every user on the system&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~/.gitconfig&lt;/code&gt;, the aforementioned file, specific to the user who the containing directory belongs to&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[repository path]/.git/config&lt;/code&gt;, which sets a configuration specific to a particular repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you set up Git using &lt;code&gt;git config --global&lt;/code&gt;, you told the &lt;code&gt;config&lt;/code&gt; tool to create or write to the second, user-level file. But you might have passed &lt;code&gt;--system&lt;/code&gt; to write to the first system-wide file or &lt;code&gt;--local&lt;/code&gt; to write to a config file in a repo, provided your current working directory is inside such a repo.&lt;/p&gt;

&lt;p&gt;Importantly, values from a local config file (if present) override those from a user config file (if present), both of which in turn override values from a system-level config (if present). Note that we say "values", here: if a local file lacks a value for &lt;code&gt;user&lt;/code&gt; but has a value for &lt;code&gt;email&lt;/code&gt;, the local email will be used but the user will be pulled from either the user- or system-level config files, assuming one of these has a user present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing multiple users with &lt;code&gt;guser&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We often find ourselves with a default user and email set in &lt;code&gt;~/.gitconfig&lt;/code&gt; which we wish to override at the level of an individual repository.&lt;/p&gt;

&lt;p&gt;Perhaps we have a work email and username set in our user directory, but also wish to work on a personal project and author commits that match the username of a personal Github account. Or perhaps we need to manage multiple work-related Git accounts with different usernames-- for example, one for a Github enterprise instance and another authorized to access a private organization on &lt;code&gt;github.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ordinarily, this is as straightforward as running &lt;code&gt;git config&lt;/code&gt; with &lt;code&gt;--local&lt;/code&gt; flags for the user and email when inside the repository that needs to override user- or system-level configs. But this can get tedious when we have many accounts to manage or when we frequently clone new repositories (as &lt;code&gt;.git/config&lt;/code&gt; is not committed or pushed to the remote).&lt;/p&gt;

&lt;p&gt;This is where &lt;code&gt;guser&lt;/code&gt; can help. It's a thin wrapper over these &lt;code&gt;git config&lt;/code&gt; commands coupled with a means to persist frequently-used config/email pairs to a config file in your user directory, all behind an interactive CLI that lets you quickly choose the config to set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;guser
Checking &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;git config...
No &lt;span class="nb"&gt;local &lt;/span&gt;user &lt;span class="nb"&gt;set
&lt;/span&gt;No &lt;span class="nb"&gt;local &lt;/span&gt;email &lt;span class="nb"&gt;set&lt;/span&gt;
? What would you like to &lt;span class="k"&gt;do&lt;/span&gt;? › - Use arrow-keys. Return to submit.
❯   Set &lt;span class="nb"&gt;local &lt;/span&gt;git user config
    Remove user config from guser
    List configs &lt;span class="k"&gt;in &lt;/span&gt;guser
    Add user config to guser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alternatives to &lt;code&gt;guser&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Despite being a CLI tool, &lt;code&gt;guser&lt;/code&gt; doesn't really follow the &lt;a href="https://en.wikipedia.org/wiki/Unix_philosophy#:~:text=The%20Unix%20philosophy%20is%20documented,%2C%20as%20yet%20unknown%2C%20program."&gt;unix philosophy&lt;/a&gt;. While it does one thing and just one thing well, it opts for an interactive interface over pipeability and composability.&lt;/p&gt;

&lt;p&gt;If you would prefer a similar tool that can be driven entirely via flags and arguments, check out &lt;a href="https://github.com/WindomZ/gituser.js"&gt;WindomZ's &lt;code&gt;gituser.js&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you think?
&lt;/h2&gt;

&lt;p&gt;Lately, I've struggled to make progress with a number of overambitious side projects. &lt;code&gt;guser&lt;/code&gt; was born from a desire to quickly finish something small and hopefully useful to break this streak.&lt;/p&gt;

&lt;p&gt;I decided to go for a number of personal firsts, with this project: first time setting up  pipeline using Github Actions (by far the least time I've ever spent on this); first time publishing something to NPM (turns out it's pretty straightforward); first time attempting to get 100% test coverage of a codebase (as fun as it is to include green coverage badges in a readme, let's just say that next time, I'm foregoing a fair amount of unit testing in favor of typescript plus a smaller number of integration tests). Things worked out reasonably well on all three counts.&lt;/p&gt;

&lt;p&gt;But, more importantly, this is my first time releasing something outside of a work context that aims to actually useful to someone-- as opposed to learning projects and projects which aim only to delight and amuse. So, naturally, I'm hoping that you'll try it out and let me know what you think, whether via comments here or &lt;a href="https://github.com/krnsk0/guser"&gt;via Github&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; guser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>git</category>
      <category>cli</category>
      <category>github</category>
      <category>node</category>
    </item>
    <item>
      <title>A Thorough Introduction to Git's Interactive Patch Mode</title>
      <dc:creator>Jon Kurinsky</dc:creator>
      <pubDate>Sun, 28 Jul 2019 23:55:18 +0000</pubDate>
      <link>https://dev.to/krnsk0/a-thorough-introduction-to-git-s-interactive-patch-mode-4bl6</link>
      <guid>https://dev.to/krnsk0/a-thorough-introduction-to-git-s-interactive-patch-mode-4bl6</guid>
      <description>&lt;p&gt;You've been hacking away at a project when you realize: "I haven't committed in an hour." Or, perhaps worse still: "my unstaged changes represent multiple &lt;a href="https://jasonmccreary.me/articles/when-to-make-git-commit/"&gt;units of work&lt;/a&gt;"--  whether those units are features, steps in a refactor, or bugfixes. &lt;/p&gt;

&lt;p&gt;Suppose you run &lt;code&gt;git status&lt;/code&gt; and you see unstaged changes in multiple files. Suppose further that you can say with confidence that the changes are divided among the files in a way that corresponds to a division between discrete units of work. So far, so good; you're in a position to &lt;code&gt;git add&lt;/code&gt; and &lt;code&gt;git commit&lt;/code&gt; files separately, resulting in a history in which units of work are appropriately separated from one another.&lt;/p&gt;

&lt;p&gt;But what if changes representing separate units of work exist &lt;em&gt;within&lt;/em&gt; single files? Suppose, in your hour of undisciplined hacking, you added a new feature to &lt;em&gt;one&lt;/em&gt; function inside of &lt;code&gt;app.js&lt;/code&gt;, but also added a bugfix to a &lt;em&gt;different&lt;/em&gt; function found in the same file?&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;git add&lt;/code&gt;ing files separately can't help you; you need to be able to stage and commit &lt;em&gt;regions within files&lt;/em&gt;. These are called &lt;em&gt;hunks&lt;/em&gt;, in git. And to work with hunks, git gives us an &lt;em&gt;interactive patch mode&lt;/em&gt;, which we can enter with the commands &lt;code&gt;git add -patch&lt;/code&gt; or &lt;code&gt;git add -p&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Patch Mode
&lt;/h2&gt;

&lt;p&gt;Patch mode is a small CLI application which intelligently divides unstaged changes into hunks and presents these hunks to us in turn so we can decide whether or not to stage each one. (It is available directly via &lt;code&gt;git add -p&lt;/code&gt;, but also available within the &lt;code&gt;git add -interactive&lt;/code&gt; interface, not discussed in this post.)&lt;/p&gt;

&lt;p&gt;Let's say we start off with an &lt;code&gt;app.js&lt;/code&gt; that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countToNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Let's count to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`We counted to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;countToNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose we've made a few changes. After realizing that &lt;code&gt;countToNumber&lt;/code&gt; stops just short of the target, we change &lt;code&gt;&amp;lt;&lt;/code&gt; to &lt;code&gt;&amp;lt;=&lt;/code&gt; in the line that initializes the loop.&lt;/p&gt;

&lt;p&gt;Then we decide we don't want to invoke &lt;code&gt;countToNumber&lt;/code&gt;, in this file, but instead want to export a function that can produce side effects to the console for use elsewhere. We wrap the last three lines in a function, which we export:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;countToNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We also delete the &lt;code&gt;numbers&lt;/code&gt; array which we (perhaps) used to test our work, now that we're ready to export the function we've written. &lt;/p&gt;

&lt;p&gt;Finally, we decide we also want to expose a function for filtering numbers before printing to the console, so we add a filter function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having made these changes, we realize we want to split them up. So, we run &lt;code&gt;git add -p app.js&lt;/code&gt;, and git gives us back the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff --git a/app.js b/app.js
index eceb575..c97e738 100644
--- a/app.js
+++ b/app.js
@@ -1,13 +1,17 @@
 const countToNumber = number =&amp;gt; {
   console.log(`Let's count to ${number}`);
-  for (let i = 0; i &amp;lt; number; i += 1) {
+  for (let i = 0; i &amp;lt;= number; i += 1) {
     console.log(i);
   }
   console.log(`We counted to ${number}!`);
 };

-const numbers = [100, 1000, 50, 35];
+export const processNumbers = numbers =&amp;gt; {
+  numbers.forEach(number =&amp;gt; {
+    countToNumber(number);
+  });
+};

-numbers.forEach(number =&amp;gt; {
-  countToNumber(number);
-});
+export const filterNumbers = (numbers, maximum) =&amp;gt; {
+  return numbers.filter(n =&amp;gt; n &amp;lt; maximum);
+};
Stage this hunk [y,n,q,a,d,s,e,?]?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Don't read too much into the &lt;code&gt;diff --git&lt;/code&gt; line in the output; the &lt;code&gt;diff&lt;/code&gt; command has no such option. This is just a hard-coded string &lt;a href="http://www.gelato.unsw.edu.au/archives/git/0505/3880.html"&gt;in the &lt;code&gt;git diff&lt;/code&gt; output&lt;/a&gt; to help us understand what git is doing with reference to whatever knowledge we may have of &lt;code&gt;diff&lt;/code&gt;, and also to indicate a &lt;em&gt;format&lt;/em&gt; for this diff output (a variant of the &lt;a href="https://en.wikipedia.org/wiki/Diff#Unified_format"&gt;unified diff format&lt;/a&gt;). If you've used &lt;code&gt;git diff&lt;/code&gt;, then what you see here should be familiar to you. &lt;/p&gt;

&lt;p&gt;The output of &lt;code&gt;git diff&lt;/code&gt;, by the way, can be redirected into a file called a &lt;em&gt;patch&lt;/em&gt; which can be saved somewhere or passed to a friend before being later applied: &lt;code&gt;git diff &amp;gt; mypatch.patch&lt;/code&gt; and then &lt;code&gt;git apply mypatch.patch&lt;/code&gt;. (Or, if you want to do this with staged as opposed to unstaged changes, redirect &lt;code&gt;git diff --cached&lt;/code&gt;.) This is related to why the tool we're exploring  here is called 'patch mode', but a full exploration of how git works in this respect deserves its own post. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can see that git has decided to group all of the changes into a single hunk. But we want to split them up. We'll talk about all of the commands later; for now we'll choose &lt;code&gt;s&lt;/code&gt; (to [s]plit this hunk), and git shows us just the part we want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@@ -1,8 +1,8 @@
 const countToNumber = number =&amp;gt; {
   console.log(`Let's count to ${number}`);
-  for (let i = 0; i &amp;lt; number; i += 1) {
+  for (let i = 0; i &amp;lt;= number; i += 1) {
     console.log(i);
   }
   console.log(`We counted to ${number}!`);
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we're talking. Let's choose &lt;code&gt;y&lt;/code&gt;, to stage this hunk, and then &lt;code&gt;q&lt;/code&gt;, for '[q]uit'. This takes us out of interactive mode and back to the command line. If we run &lt;code&gt;git status&lt;/code&gt;, we'll see that there are both staged and unstaged changes in &lt;code&gt;app.js&lt;/code&gt;-- which is exactly what we want. We can commit our first unit of work using something like &lt;code&gt;git commit -m "fix bug which stopped count just short of number"&lt;/code&gt;, and then stage the next unit. &lt;/p&gt;

&lt;p&gt;So, we run &lt;code&gt;git add -p app.js&lt;/code&gt;. After splitting using &lt;code&gt;s&lt;/code&gt;, git isolates the changes to &lt;code&gt;processNumbers&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@@ -6,5 +6,9 @@
-const numbers = [100, 1000, 50, 35];
+export const processNumbers = numbers =&amp;gt; {
+  numbers.forEach(number =&amp;gt; {
+    countToNumber(number);
+  });
+};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we choose &lt;code&gt;y&lt;/code&gt; and then &lt;code&gt;q&lt;/code&gt;, as before, and then we can make a commit: &lt;code&gt;git commit -m "export function which wraps countToNumber"&lt;/code&gt;. We could go back into interactive mode, but we know the only remaining uncommitted change represents a single unit of work, so we can add it and commit in the usual way. &lt;/p&gt;

&lt;p&gt;Now we have a history in which our commits represent discrete units of work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit bc80191fe63bf75bae7d976b61cf1c24e9391097 (HEAD -&amp;gt; master)
Author: Dev.to Reader &amp;lt;dev.to@reader.com&amp;gt;
Date:   Sun Jul 28 10:48:37 2019 -0500

    export function for filtering lists of numbers

commit 6c36b351cc2a8cc0f6f3582b3221f5e427980fbc
Author: Dev.to Reader &amp;lt;dev.to@reader.com&amp;gt;
Date:   Sun Jul 28 10:47:02 2019 -0500

    export function which wraps countToNumber

commit 0b59f6917215a5c264735e4ed01cf6d1f3c977e4
Author: Dev.to Reader &amp;lt;dev.to@reader.com&amp;gt;
Date:   Sun Jul 28 10:40:25 2019 -0500

    fix bug which stopped count just short of number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Patch Mode Commands
&lt;/h2&gt;

&lt;p&gt;Running &lt;code&gt;?&lt;/code&gt; or &lt;code&gt;h&lt;/code&gt; will show us the commands available in patch mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
e - manually edit the current hunk
? - print help
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've seen &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;q&lt;/code&gt;, and &lt;code&gt;s&lt;/code&gt;, which allow us to stage hunks, quit, and split into smaller hunks, respectively. We'll return to the topic of splitting soon.&lt;/p&gt;

&lt;p&gt;Very commonly, after entering patch mode and splitting, I'll page through hunks with &lt;code&gt;jJkK&lt;/code&gt; to orient myself in a file, looking for patterns in the changes I can group together before staging a few and exiting. &lt;/p&gt;

&lt;p&gt;Importantly, patch mode can be called on a file (&lt;code&gt;git add -p app.js&lt;/code&gt;) or on the entire repository (&lt;code&gt;git add -p&lt;/code&gt;), so if you have changes in multiple files but know you want to hunkify changes in just one file, you can do so. &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt; are intended for use in a context in which we've entered patch mode with many files in our pathspec, as they help us deal with changes in a file in bulk. Generally, we probably wouldn't be in interactive mode if we wanted to deal with changes in bulk, according to the file in which they appear; thus I find myself using &lt;code&gt;d&lt;/code&gt; sometimes and &lt;code&gt;a&lt;/code&gt; almost never. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;g&lt;/code&gt; command gives us an interactive menu showing filenames and line numbers for all hunks. I also don't find myself using this one much, as I don't usually know just what files and lines I'm interested in staging prior to having them presented to me. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/&lt;/code&gt; command, however, can be very useful. When I'm going through a lot of changes and discover some work I'd like to group together sharing some common searchable feature--say, a reference to a particular variable or function--I'll pare down the changes using &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; until &lt;code&gt;/&lt;/code&gt; stops returning results. &lt;/p&gt;

&lt;p&gt;Selecting &lt;code&gt;e&lt;/code&gt; opens up the current hunk in whatever editor you have configured git to use (&lt;code&gt;git config --global core.editor&lt;/code&gt;) to allow line-by-line staging. This is most useful when you've reached the minimum hunk size that interactive mode will give you and need very fine control over what is being committed. We'll return to this in a moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intent to Add
&lt;/h2&gt;

&lt;p&gt;If you add a new file to a repository, add some contents, and then run &lt;code&gt;git diff&lt;/code&gt;, you won't see anything from your new file in the output. This is because &lt;code&gt;git diff&lt;/code&gt; shows us unstaged changes relative to the staging area, and if we haven't yet tracked a file, it's not yet available for comparison. &lt;/p&gt;

&lt;p&gt;Because interactive add mode is built around &lt;code&gt;git diff&lt;/code&gt;, changes to a new untracked file aren't at first visible in patch mode. We could of course &lt;code&gt;git add&lt;/code&gt; the file, but this leads to a conundrum, as now we'll have staged the entire file. There are a couple of ways to solve this. &lt;/p&gt;

&lt;p&gt;One less conventional solution might be to use &lt;code&gt;git reset -p&lt;/code&gt;-- as it turns out &lt;code&gt;git reset&lt;/code&gt; also has an interactive patch mode. We could use this to unstage all changes from the new file but the ones we intend to commit, and then make a commit. &lt;/p&gt;

&lt;p&gt;But this is cumbersome. A more conventional and faster solution is to use the command &lt;code&gt;git add --intent-to-add&lt;/code&gt; (or its shorthand &lt;code&gt;git add -N&lt;/code&gt;). This allows us add a file &lt;em&gt;but not its contents&lt;/em&gt; to the staging area, which means &lt;code&gt;git diff&lt;/code&gt; and &lt;code&gt;git add -p&lt;/code&gt; will give us what we want. &lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Workflow &amp;amp; Limits of Hunks
&lt;/h2&gt;

&lt;p&gt;The occasional need for &lt;code&gt;e&lt;/code&gt; shows some of the limits of interactive patch mode. &lt;a href="https://git-scm.com/docs/diff-config#diff-config-diffcontext"&gt;Options&lt;/a&gt; for &lt;code&gt;git diff&lt;/code&gt; let us specify some defaults for hunks: &lt;code&gt;git config --global diff.context&lt;/code&gt; lets us set the number of lines of context to provide around a change, while the &lt;code&gt;diff.interHunkContext&lt;/code&gt; option lets us set the number of lines which should appear between hunks, allowing us some control over hunk size.&lt;/p&gt;

&lt;p&gt;But, despite the control we get over defaults, git &lt;strong&gt;always&lt;/strong&gt; groups changes to adjacent lines together. If changes on consecutive lines represent different units of work, we'll need to manually edit the patch using &lt;code&gt;e&lt;/code&gt;, which gives us the most fine-grained control it is possible to exercise over the contents of our commits.&lt;/p&gt;

&lt;p&gt;Patches have some limits tightly coupled to the limits of git itself: the smallest unit of change in git is a line, and so if we have made multiple changes to a line which represent distinct units of work, git can't help us record these separately. &lt;/p&gt;

&lt;p&gt;But this is just to say that interactive patch mode is no substitute or an organized development process. While it can help us recover from the occasional session in which we have not exercised the kind of git discipline which a task or team demands of us, it can like any tool be mis- or over-used. So, don't let the availability of &lt;code&gt;git add -p&lt;/code&gt; replace thought and planning in your workflow. &lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
