<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Oliver Davies</title>
    <description></description>
    <link>https://www.oliverdavies.uk/blog</link>
    <atom:link href="https://www.oliverdavies.uk/rss/blog.xml" rel="self" type="application/rss+xml" />
          <item>
        <title>Fixing typos in my previous command</title>
        <link>https://www.oliverdavies.uk/blog/2026/fixing-typos</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/fixing-typos</guid>
        <description>&lt;p&gt;TIL that you can easily fix typos in your previous terminal command and re-run it.&lt;/p&gt;

&lt;p&gt;This is my original command that I typoed, where I misspelt the word &lt;code&gt;upstream&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;shell&quot;&gt;$ git help upstreasm

No manual entry for gitupstreasm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Typing and running &lt;code&gt;^easm^eam&lt;/code&gt; fixed and re-ran the incorrect command - replacing the incorrect letters &lt;code&gt;easm&lt;/code&gt; with &lt;code&gt;eam&lt;/code&gt; to get my original intended result:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;shell&quot;&gt;$ ^easm^eam

git help upstream

&#039;upstream&#039; is aliased to &#039;rev-parse --abbrev-ref --symbolic-full-name @{u}&#039;
&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Thu, 11 Jun 2026 14:13:00 GMT</pubDate>
      </item>
          <item>
        <title>Writing books and live streaming</title>
        <link>https://www.oliverdavies.uk/blog/2026/writing-books-live-streaming</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/writing-books-live-streaming</guid>
        <description>&lt;p&gt;&lt;img src=&quot;https://www.oliverdavies.uk/assets/post-images/2026/writing-books-live-streaming/thumbnail.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It&#039;s been a while since my last live stream, but I&#039;ll be spending a couple of hours tomorrow morning working on my &lt;a href=&quot;https://books.oliverdavies.uk/test-driven-drupal&quot;&gt;Test-Driven Drupal eBook&lt;/a&gt; and decided to live stream it on &lt;a href=&quot;https://www.youtube.com/@opdavies&quot;&gt;my YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I really enjoyed being on &lt;a href=&quot;https://www.oliverdavies.uk/blog/2026/talking-drupal-again/&quot;&gt;the Talking Drupal podcast&lt;/a&gt; again this week which was recorded live, and made me think again about doing more live streams of my own.&lt;/p&gt;

&lt;p&gt;If you&#039;re interested in learning about Drupal, automated testing or test-driven development, feel free to join the stream and ask any questions in the chat.&lt;/p&gt;
</description>
        <pubDate>Thu, 11 Jun 2026 00:39:00 GMT</pubDate>
      </item>
          <item>
        <title>How to easily get back to the root of a Git repo</title>
        <link>https://www.oliverdavies.uk/blog/2026/git-root</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/git-root</guid>
        <description>&lt;p&gt;Have you ever been in a directory within a Git repository and you needed to get back to the top level?&lt;/p&gt;

&lt;p&gt;To find the path, run &lt;code&gt;git rev-parse --show-toplevel&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, when I&#039;m within the repository for this website:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;shell&quot;&gt;Code/oliverdavies.uk/app/config &amp;gt; git rev-parse --show-toplevel
/home/opdavies/Code/oliverdavies.uk
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have this set as a Git alias called &lt;code&gt;root&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;shell&quot;&gt;$ git help root

&#039;root&#039; is aliased to &#039;rev-parse --show-toplevel&#039;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, anywhere within a repository, I can run &lt;code&gt;cd $(git root)&lt;/code&gt; and easily get back to the top level.&lt;/p&gt;
</description>
        <pubDate>Thu, 11 Jun 2026 00:21:00 GMT</pubDate>
      </item>
          <item>
        <title>Talking Drupal again</title>
        <link>https://www.oliverdavies.uk/blog/2026/talking-drupal-again</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/talking-drupal-again</guid>
        <description>&lt;p&gt;I&#039;m excited to be a guest on the &lt;a href=&quot;https://www.talkingdrupal.com?ref=www.oliverdavies.uk&quot;&gt;Talking Drupal podcast&lt;/a&gt; again next week.&lt;/p&gt;

&lt;p&gt;I recently converted my free 10-day automated testing email course to an eBook - which is what we&#039;re going to be discussing during the episode.&lt;/p&gt;

&lt;p&gt;This will be the fourth time I&#039;ve been a guest on the podcast, and it&#039;s great to be invited again.&lt;/p&gt;

&lt;p&gt;Here are the previous episodes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.talkingdrupal.com/175?ref=www.oliverdavies.uk&quot;&gt;Episode 175 - Automated Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.talkingdrupal.com/204?ref=www.oliverdavies.uk&quot;&gt;Episode 204 - A Few Things&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.talkingdrupal.com/338?ref=www.oliverdavies.uk&quot;&gt;Episode 338 - Tailwind CSS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This episode is going to be live on the &lt;a href=&quot;https://www.youtube.com/watch?v=ZRB4IeIWAug?ref=www.oliverdavies.uk&quot;&gt;Talking Drupal YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The current version of the eBook is available to &lt;a href=&quot;https://books.oliverdavies.uk/test-driven-drupal?ref=www.oliverdavies.uk&quot;&gt;view online and download&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Fri, 05 Jun 2026 22:11:00 GMT</pubDate>
      </item>
          <item>
        <title>4,000 dotfiles commits</title>
        <link>https://www.oliverdavies.uk/blog/2026/4000-dotfiles-commits</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/4000-dotfiles-commits</guid>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/post-images/2026/4000-dotfiles-commits/forgejo-nix-config.png&quot; alt=&quot;A screenshot of my nix-config repository.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I made &lt;a href=&quot;https://git.oliverdavies.uk/opdavies/nix-config/commit/da6754da407b01c3966747c49ed84228c30eb701#diff-a5cc2925ca8258af241be7e5b0381edf30266302&quot;&gt;the first commit&lt;/a&gt; to my dotfiles repository in July 2015, adding my .gitignore and .gitconfig files.&lt;/p&gt;

&lt;p&gt;In 2022, I started to use Nix and, soon after, NixOS.&lt;/p&gt;

&lt;p&gt;Yesterday, I made my 4,000th commit to the repository, which is now called &lt;a href=&quot;https://git.oliverdavies.uk/opdavies/nix-config&quot;&gt;nix-config&lt;/a&gt; and contains my laptop and homelab NixOS configurations, my Home Manager user configurations, and my Neovim configuration.&lt;/p&gt;

&lt;p&gt;To learn more about Nix and how I use it in development projects, watch my &lt;a href=&quot;https://www.oliverdavies.uk/presentations/nix-for-php-developers&quot;&gt;Nix for PHP Developers (and everyone else) talk&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 26 May 2026 18:06:00 GMT</pubDate>
      </item>
          <item>
        <title>Nixing splitsh/lite</title>
        <link>https://www.oliverdavies.uk/blog/2026/nixing-splitsh</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/nixing-splitsh</guid>
        <description>&lt;p&gt;I&#039;m a fan of monorepos and use them for my &lt;a href=&quot;https://git.oliverdavies.uk/opdavies/presentations&quot;&gt;presentations&lt;/a&gt; and &lt;a href=&quot;https://git.oliverdavies.uk/opdavies/books&quot;&gt;books&lt;/a&gt; rather than creating a new Git repository for every book and presentation.&lt;/p&gt;

&lt;p&gt;I&#039;ve done the same for the &lt;a href=&quot;https://git.oliverdavies.uk/opdavies/drupal-gather&quot;&gt;Drupal Gather project&lt;/a&gt; - a Drupal distribution that I&#039;ve started building for meetup and user group websites that contains an example project, an installation profile and several recipes - all stored and developed in the same Git repository.&lt;/p&gt;

&lt;p&gt;For deployment and consumption via Composer, I want each sub-project to be available in its own standalone repository, so I need a way to split each project from the monorepo when needed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/post-images/2026/nixing-splitsh/drupal-gather-repositories.png&quot; alt=&quot;A screenshot of the Drupal Gather repositories on Forgejo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Git has the &lt;code&gt;subtree split&lt;/code&gt; command, but it is slow and although it&#039;s improved by the &lt;code&gt;--rejoin&lt;/code&gt; option, it creates additional commits in the repository for both the split code and a merge commit containing the metadata.&lt;/p&gt;

&lt;p&gt;I&#039;ve also had several caching errors when trying to perform a split - even from a fresh clone - that have prevented me from deploying changes, so I wanted to look for other options.&lt;/p&gt;

&lt;h2 id=&quot;splitsh%2Flite&quot;&gt;splitsh/lite&lt;/h2&gt;

&lt;p&gt;Fabien Potencier - the creator of Symfony - &lt;a href=&quot;https://www.youtube.com/watch?v=ZVsDA6GhKOU&quot;&gt;has spoken about&lt;/a&gt; how Symfony uses a combination of a monorepo and many-repo strategies and has &lt;a href=&quot;https://github.com/splitsh/lite&quot;&gt;open sourced a tool&lt;/a&gt; based on the one used by Symfony.&lt;/p&gt;

&lt;p&gt;It&#039;s written in Go and uses &lt;code&gt;libgit2&lt;/code&gt;, but has some versioning challenges.&lt;/p&gt;

&lt;p&gt;From the README:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;First, you need to install &lt;code&gt;libgit2&lt;/code&gt;, preferably using your package manager of choice.&lt;/p&gt;
  
  &lt;p&gt;If you get &lt;code&gt;libgit2&lt;/code&gt; version 1.5, you&#039;re all set and jump to the compilation step below. If not, you first need to change the &lt;code&gt;git2go&lt;/code&gt; version used in the code. Using the table on the &lt;a href=&quot;https://github.com/libgit2/git2go#which-go-version-to-use&quot;&gt;libgit2&lt;/a&gt; repository, figure out which version of the git2go you need based on the &lt;code&gt;libgit2&lt;/code&gt; library you installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This seemed like a great use case for Nix and its reproducible build system.&lt;/p&gt;

&lt;h2 id=&quot;adding-a-nix-flake&quot;&gt;Adding a Nix flake&lt;/h2&gt;

&lt;p&gt;The current version of &lt;code&gt;libgit2&lt;/code&gt; in nixpkgs is 1.9.2 - too new for the tool to use and for &lt;code&gt;git2go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By pinning nixpkgs to the 22.11 channel, I was able to get the required 1.5 version of &lt;code&gt;libgit2&lt;/code&gt; and create a package based on it and &lt;code&gt;pkg-config&lt;/code&gt; - both of which are needed to build the project.&lt;/p&gt;

&lt;p&gt;Now I can easily build the project using &lt;code&gt;nix build&lt;/code&gt; or create and use a dev shell with &lt;code&gt;nix develop&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;submitting-a-pull-request&quot;&gt;Submitting a pull request&lt;/h2&gt;

&lt;p&gt;I have created &lt;a href=&quot;https://github.com/splitsh/lite/pull/87&quot;&gt;a pull request&lt;/a&gt; to add the Nix flake to the main project repository.&lt;/p&gt;

&lt;p&gt;If it&#039;s not added, I&#039;ll create a standalone flake in its own repository.&lt;/p&gt;

&lt;p&gt;In the meantime, you can test it from my forked version using either &lt;code&gt;nix run github:opdavies/splitsh-lite/add-nix-flake&lt;/code&gt; or &lt;code&gt;nix shell github:opdavies/splitsh-lite/add-nix-flake&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you need any assistance, feel free to get in touch.&lt;/p&gt;
</description>
        <pubDate>Wed, 06 May 2026 20:57:00 GMT</pubDate>
      </item>
          <item>
        <title>Adding a JSON feed for blog posts</title>
        <link>https://www.oliverdavies.uk/blog/2026/jsonfeed</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/jsonfeed</guid>
        <description>&lt;p&gt;As well as &lt;a href=&quot;/rss/blog.xml&quot;&gt;RSS&lt;/a&gt;, you can now read and subscribe to my blog via a &lt;a href=&quot;https://www.oliverdavies.uk/blog.json&quot;&gt;new JSON feed&lt;/a&gt; - based on the &lt;a href=&quot;https://www.jsonfeed.org&quot;&gt;JSON Feed specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was very easy to add to my website by creating this file at &lt;code&gt;source/blog.json.twig&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;twig&quot;&gt;---
permalink: /blog.json
use: [posts]
---

{
  &quot;version&quot;: &quot;https://jsonfeed.org/version/1.1&quot;,
  &quot;title&quot;: &quot;Blog | {{ site.name }} - {{ site.slogan }}&quot;,
  &quot;icon&quot;: &quot;{{ site.url }}/assets/images/social-avatar-blue.jpg&quot;,
  &quot;home_page_url&quot;: &quot;https://www.jsonfeed.org&quot;,
  &quot;feed_url&quot;: &quot;{{ site.url }}/blog.json&quot;,
  &quot;items&quot;: [
    {% for post in data.posts %}
      {
        &quot;id&quot;: &quot;{{ site.url }}{{ post.url }}&quot;,
        &quot;title&quot;: &quot;{{ post.title }}&quot;,
        &quot;content_html&quot;: {{ post.blocks.content|json_encode|raw }},
        &quot;date_published&quot;: &quot;{{ post.date|date(&quot;c&quot;) }}&quot;,
        &quot;url&quot;: &quot;{{ site.url }}{{ post.url }}&quot;
      }{% if not loop.last %},{% endif %}
    {% endfor %}
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;It was also easy to configure Caddy to return the appropriate &lt;code&gt;application/feed+json&lt;/code&gt; content type:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;caddy&quot;&gt;@blogfeed {
  path /blog.json
}

header @blogfeed Content-Type application/feed+json
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&#039;m a big proponent of the Open Web and people owning their content, so I want to make it as easy as possible for everyone to find and consume my posts, and will probably add more JSON feeds for my &lt;a href=&quot;/presentations&quot;&gt;presentation content&lt;/a&gt; and book updates in the future.&lt;/p&gt;

&lt;p&gt;I may also create it as a standalone Sculpin plugin, as it&#039;s not specific to my website and would allow others to share their content in the same way.&lt;/p&gt;
</description>
        <pubDate>Tue, 05 May 2026 19:10:00 GMT</pubDate>
      </item>
          <item>
        <title>Configuring Git with environment variables</title>
        <link>https://www.oliverdavies.uk/blog/2026/configuring-git-with-environment-variables</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/configuring-git-with-environment-variables</guid>
        <description>&lt;p&gt;As well as commands like &lt;code&gt;git config --local&lt;/code&gt;, Git can also be configured using environment variables.&lt;/p&gt;

&lt;p&gt;Whilst working for client projects, I often need to change my email address or clone repositories using a different SSH key.&lt;/p&gt;

&lt;p&gt;With environment variables, I can do this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;export GIT_AUTHOR_EMAIL=&quot;oliver@foo.bar&quot;
export GIT_SSH_COMMAND=&quot;ssh -i ~/.ssh/foo -o IdentitiesOnly=yes&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works well when used with &lt;a href=&quot;https://direnv.net&quot;&gt;direnv&lt;/a&gt; - a tool that manages environment variables based on directory.&lt;/p&gt;

&lt;p&gt;This means I can create one &lt;code&gt;.envrc&lt;/code&gt; file for the directory containing that client&#039;s projects, and it will automatically use the correct SSH key and email address.&lt;/p&gt;
</description>
        <pubDate>Sun, 26 Apr 2026 14:41:00 GMT</pubDate>
      </item>
          <item>
        <title>Test-Driven Drupal re-launched as an eBook</title>
        <link>https://www.oliverdavies.uk/blog/2026/test-driven-drupal-relaunched</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/test-driven-drupal-relaunched</guid>
        <description>&lt;p&gt;The &quot;Test-Driven Drupal&quot; project has been re-launched as a &quot;perpetually published&quot; eBook, based on my previous Automated Testing in Drupal email course (ATDC).&lt;/p&gt;

&lt;p&gt;It is still free and can be viewed at &lt;a href=&quot;https://www.oliverdavies.uk/books/test-driven-drupal&quot;&gt;https://www.oliverdavies.uk/books/test-driven-drupal&lt;/a&gt; and downloaded as a PDF or EPUB.&lt;/p&gt;

&lt;p&gt;As I work on it, it will evolve from the email course content into a more detailed version, including new topics such as testing existing Drupal websites with Drupal Test Traits that I couldn&#039;t fit into the email course version.&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Apr 2026 18:05:00 GMT</pubDate>
      </item>
          <item>
        <title>Using Neovim as a terminal multiplexer</title>
        <link>https://www.oliverdavies.uk/blog/2026/using-neovim-terminal-multiplexer</link>
        <guid isPermaLink="true">https://www.oliverdavies.uk/blog/2026/using-neovim-terminal-multiplexer</guid>
        <description>&lt;p&gt;Since &lt;a href=&quot;https://www.youtube.com/watch?v=W6R5sDtjlZk&quot;&gt;watching this video&lt;/a&gt;, I&#039;ve experimented using Neovim as a terminal multiplexer, using terminals within panes and tabs in Neovim with &lt;code&gt;:term&lt;/code&gt; rather than tmux.&lt;/p&gt;

&lt;p&gt;I can also create a new terminal tab with &lt;code&gt;:tabnew | term&lt;/code&gt; and splits with &lt;code&gt;:spl | term&lt;/code&gt; and &lt;code&gt;:vsp | term&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I can zoom into panes using &lt;code&gt;&amp;lt;C-w&amp;gt; |&lt;/code&gt; or &lt;code&gt;&amp;lt;C-w&amp;gt; _&lt;/code&gt;, and reset them to equal sizes with &lt;code&gt;&amp;lt;C-w&amp;gt; =&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Doing everything in Neovim gives me consistent keybindings to move between windows, panes and tabs, and full use of my regular Neovim setup with text objects, highlighting and copying and pasting.&lt;/p&gt;

&lt;p&gt;As I&#039;m not using a tmux session launcher, I&#039;ve added &lt;a href=&quot;https://zoxide.org&quot;&gt;zoxide&lt;/a&gt; and use the &lt;code&gt;z&lt;/code&gt; and &lt;code&gt;zi&lt;/code&gt; commands to get fast access to my directories.&lt;/p&gt;

&lt;p&gt;It feels odd not to have tmux installed (It&#039;s been in my dotfiles since 2019), but I&#039;m liking this setup so far - let&#039;s see if it sticks.&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Apr 2026 16:00:00 GMT</pubDate>
      </item>
      </channel>
</rss>