<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Command Line on Blog of Jérémie Litzler</title><link>https://iamjeremie.me/tags/command-line/</link><description>Recent content in Command Line on Blog of Jérémie Litzler</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 14 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://iamjeremie.me/tags/command-line/index.xml" rel="self" type="application/rss+xml"/><item><title>First Steps Pushing Dotfiles With Chezmoi</title><link>https://iamjeremie.me/post/2026-08/first-steps-pushing-dotfiles-with-chezmoi/</link><pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate><guid>https://iamjeremie.me/post/2026-08/first-steps-pushing-dotfiles-with-chezmoi/</guid><description>&lt;img src="https://iamjeremie.me/post/2026-08/first-steps-pushing-dotfiles-with-chezmoi/2026-08-14-a-child-taking-a-small-steps-up-a-staircase.jpg" alt="Featured image of post First Steps Pushing Dotfiles With Chezmoi" /&gt;&lt;p&gt;I’m making baby steps with &lt;a href="https://www.chezmoi.io/"&gt;chezmoi&lt;/a&gt;, the dotfiles manager. I already had a dotfiles repository set up with a minimal setup. I initialized it from a laptop I needed to reset but needed to keep my development setup. I was comfortable with one half of the workflow: pulling changes from the remote and applying them to my reset machine.&lt;/p&gt;
&lt;p&gt;What I hadn’t figured out yet was the other half—how do I save a change I made &lt;em&gt;locally&lt;/em&gt; back to the remote? Indeed, I didn’t use the steps I’m going to describe below while setting up the initial files.&lt;/p&gt;
&lt;p&gt;It turns out the answer is short, but it only makes sense once you own the mental model. So let me walk through the small steps I just took.&lt;/p&gt;
&lt;h2 id="the-mental-model"&gt;The Mental Model
&lt;/h2&gt;&lt;p&gt;The thing that confused me at first is that chezmoi juggles two different “states,” and I only understood one of them.&lt;/p&gt;
&lt;p&gt;There is the &lt;strong&gt;source state&lt;/strong&gt;, which lives in chezmoi’s own git repository—usually at &lt;code&gt;~/.local/share/chezmoi&lt;/code&gt;. This is my dotfiles repository checkout. Then there is the &lt;strong&gt;target state&lt;/strong&gt;, which is the actual dotfiles sitting in my home directory: &lt;code&gt;~/.bashrc&lt;/code&gt;, my editor config, my Claude setup and so on.&lt;/p&gt;
&lt;p&gt;Once I saw it that way, the commands I already used made sense. When I run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chezmoi update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;chezmoi is really doing two things in sequence:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It runs &lt;code&gt;git pull --autostash --rebase&lt;/code&gt; in the source directory,&lt;/li&gt;
&lt;li&gt;Then it applies the changes to my home directory. One command, two operations. That is why pulling always felt effortless—chezmoi collapsed the two steps into one for me (read &lt;a href="https://www.chezmoi.io/user-guide/daily-operations/"&gt;chezmoi daily operations&lt;/a&gt; for the full documentation).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What about going the &lt;em&gt;other&lt;/em&gt; direction has no single command? Well, it didn’t happen so. I have to do the two stages myself.&lt;/p&gt;
&lt;h2 id="capturing-a-local-change-into-the-source"&gt;Capturing a Local Change Into the Source
&lt;/h2&gt;&lt;p&gt;Say I edited &lt;code&gt;~/.bash_profile&lt;/code&gt; directly, the way I normally would. chezmoi doesn’t know anything happened yet, because I changed the target state, not the source state. To bring that edit back into the source repository, I run &lt;code&gt;chezmoi add&lt;/code&gt; with the path:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chezmoi add ~/.bash_profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;I first assumed I had to &lt;code&gt;cd&lt;/code&gt; into the folder where the dotfile lives before adding it. I didn’t. &lt;code&gt;chezmoi add&lt;/code&gt; takes a path, so I can run it from anywhere and let chezmoi resolve the location itself.&lt;/p&gt;
&lt;p&gt;The neat part is that, for a file that chezmoi &lt;em&gt;already&lt;/em&gt; manages, &lt;code&gt;chezmoi add&lt;/code&gt; simply re-imports it, picking up my local edits. That is exactly what I imagined.&lt;/p&gt;
&lt;h2 id="versioning-and-pushing"&gt;Versioning and Pushing
&lt;/h2&gt;&lt;p&gt;Capturing the change into the source repository is only stage one. The file is now updated inside &lt;code&gt;~/.local/share/chezmoi&lt;/code&gt;, but that is still just a local git repository. To version it, I jump into that repository and use plain git:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# drops me into the source repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chezmoi &lt;span class="nb"&gt;cd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# check what&amp;#39;s pending&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pick whatever you need before adding&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# you may not need everything.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# check first, commit after!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add dot_bash_profile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;add .bash_profile&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# leave the chezmoi shell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;chezmoi cd&lt;/code&gt; opens a subshell already sitting in the source directory, so the git commands are ordinary from there.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; When I’m done, &lt;code&gt;exit&lt;/code&gt; takes me back to where I started. If you see that the Git Bash (which I was using) behaves very slowly, then you didn’t run the steps of the above code block.&lt;/p&gt;
&lt;p&gt;Before committing, you preview what actually changed with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chezmoi diff
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;That shows the difference between the source and the target, so I can confirm I’m about to version the right thing.&lt;/p&gt;
&lt;h2 id="the-lazy-option-i-might-grow-into"&gt;The lazy option I might grow into
&lt;/h2&gt;&lt;p&gt;There is a way to let chezmoi handle the git steps for me. Two variables in the &lt;code&gt;git&lt;/code&gt; section of &lt;code&gt;~/.config/chezmoi/chezmoi.toml&lt;/code&gt; control it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;autoCommit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;autoPush&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Per the reference, &lt;code&gt;autoCommit&lt;/code&gt; will “commit changes to the source state after any change,” and &lt;code&gt;autoPush&lt;/code&gt; will “push changes to the source state after any change”—both default to &lt;code&gt;false&lt;/code&gt; (&lt;a href="https://www.chezmoi.io/reference/configuration-file/variables/"&gt;configuration variables&lt;/a&gt;). With those on, any &lt;code&gt;chezmoi add&lt;/code&gt;, &lt;code&gt;re-add&lt;/code&gt;, or &lt;code&gt;edit&lt;/code&gt; commits—and pushes—automatically.&lt;/p&gt;
&lt;p&gt;For now I’m leaving them off. As a beginner I would rather see my &lt;code&gt;git status&lt;/code&gt; and commit deliberately than have things fly off to the remote behind my back. Plus, I might not need everything from a dot file or dot folder.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;The whole outgoing workflow turned out to be four small moves: &lt;code&gt;chezmoi add&lt;/code&gt; the file into the source, &lt;code&gt;chezmoi cd&lt;/code&gt; into the repository, commit with git, and push. Pulling was one command because chezmoi hides the seam; pushing just asks me to see the seam for myself. That is the baby step I took today, and my dotfiles repository gets richer by the day as I learn to CLI my work.&lt;/p&gt;
&lt;p&gt;If you liked this article…&lt;/p&gt;
&lt;div class="jli-notice jli-notice-tip" id="Follow me" &gt;
&lt;p class="jli-notice-title"&gt;Follow me&lt;/p&gt;&lt;p&gt;Thanks for reading this article. Make sure to &lt;a href="https://x.com/LitzlerJeremie"&gt;follow me on X&lt;/a&gt;, &lt;a href="https://iamjeremie.substack.com/"&gt;subscribe to my Substack publication&lt;/a&gt; and bookmark my blog to read more in the future.&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Credit: Photo by Jep Gambardella on Pexels (&lt;code&gt;https://www.pexels.com/photo/a-cute-little-boy-sitting-on-the-wooden-stairs-while-looking-afar-6224250/&lt;/code&gt;).&lt;/p&gt;</description></item></channel></rss>