Here I keep technical notes on things that I have discovered or learned. While mostly for my own reference, I am making them public on the off chance that someone else also finds them useful.

These notes are written in a style that is very bare-bones. There is just enough context to tell you what you need to do, and nothing more. Consulting the official documentation may give you more context as to the history or "why" of a particular tool or technique.

Catppuccin admonitions and theme

To use mdbook with the theme seen on this site, please consult the catppuccin mdbook site


These notes are licensed under creative commons zero (CC0). You may reuse these notes for anything you wish. The code for these notes is open-source and may be found in this repository

Made with Codeberg badge

Setting up mdBook

For full documentation see: https://rust-lang.github.io/mdBook/index.html


cargo install mdbook

To uninstall, run

cargo uninstall mdbook

Create a book

mdbook init my-first-book

Editing the book

All edits should be made in the src directory, and new notes should be created from the SUMMARY.md file, which should be present after initialization. Once the SUMMARY.md file is saved, and mdbook serve is fun, appropriate markdown files will automatically be created.

For example,

- [setting-up-mdbook](./setting-up-mdbook.md)

The markdown files themselves can be edited using any standard markdown syntax.

Git Base Commands



  • Get the files in a commit git checkout
  • Get difference from parent git show
  • Merge with another commit git merge
  • Look at parents git log



git diff only shows the difference in unstaged files and git commit -a does not add new files that are untracked

  • See all changes that have yet to be committed git diff HEAD
  • See all staged changes git git diff --cached


Branches consist of three things

  1. A name (such as main, development, or a particular feature)
  2. The latest commit
  3. A reflog that shows how the branch has changed over time

To remove commits from a branch use git reset

The branch should be setup to display in the command prompt, or somewhere else within the development environment to reduce the risk of forgetting which branch you are commiting to.

The current branch is stored in .git/HEAD, and will either be a branch name, or a commit hash if you are in a detached HEAD state.

Detached HEAD States

You can end up in this state through three mechanisms, tag, tracking a remote branch, or checking out a particular commit of a remote.


To avoid losing any changes made while in this state, just create a new branch using git checkout -b new_branch_name


There are three mechanisms for a merge:

  1. Rebase
  2. Merge
  3. Squash

The biggest difference is that rebase will not create merge commits, while merge will. Squash is useful to combine multiple commits into one.


The remote can be any repository that is pulled/pushed from. It is usually hosted on a platform like GitHub or Codeberg. The configuration for the remote is stored in .gitconfig for the repository and consists of a name and url.

[remote 'origin']
url = "https://codeberg.org/mark-pitblado/notes.git"


Adding push.autoSetupRemote = True within .gitconfig will enable new branches to automatically be tracked once pushed.

Fix Diverged Remotes

  1. Combine the changes through a merge mechanism covered above
  2. Destroy local changes.
    git switch main
    git reset --hard origin/main
  3. Throw away remote changes: git push --force


git reset can be used to undo things.

Taking a local repository and publishing it

There are two basic steps.

  1. The remote location needs to be created
  2. The remote location needs to be setup as the remote origin for the local repository.

Creating a new repository on GitHub

Creating a new repository on Github can be done through the GUI. There is no need to setup a README.md, license etc, however a description can be added since this is not part of the repo itself.

Linking the local repository to the newly created GitHub repo

If the directory has not already been initialized with git, then running git init is needed. The commit message can of course be anything, but init seems somewhat standardized. Note that if a README.md or LICENSE.md was created, the -f (force) may be required on git push.

git init
git add -A
git commit -m 'init'
git remote add origin https://github.com/mark-pitblado/notes.git 
git push -u origin main

The above uses https to connect, however if ssh is desired, then the link would be replaced with something like git@github.com:mark-pitblado/notes.git.



Lazygit allows the use of a terminal user interface to perform git operations.


This can be used to install on Ubuntu

LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep -Po '"tag_name": "v\K[^"]*')
curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz"
tar xf lazygit.tar.gz lazygit
sudo install lazygit /usr/local/bin


Instead of listing all the commands here, it is much easier to use ? from within the lazygit interface. This brings up the shortcuts for all keys. I will cover the top ones that I use.

<space>adds/removes the file current selected
ccommit, brings up interface to add message
pgit pull
Pgit push

How to setup a GPG key in Git

This page is going to assume that a key has already been created on the system and added to GitHub through the web interface.

To set the list of keys on the system

gpg --list-secret-keys --keyid-format=long

To configure git to use the key

git config --global user.signingkey <keyid-from-step-above>

To set git to sign commits by default

git config --global commit.gpgsign true

To add the key to the .zshrc (or .bashrc)

#In ~/.zshrc
export GPG_TTY=$(tty)

If "keep my email private" has been enabled in GitHub, then the email associated with the key must match the no-reply email provided by GitHub.

Terminal Commands

cmp - Compares to see if two files are equivalent


List active sessions

tmux ls

Kill a session

tmux kill-session -t session_id

Kill a process running on localhost

First, find the process using

lsof -i :3000

Then, kill the process via the PID

kill <PID> 

How to Insert a Unicode Character into the Terminal

To insert a unicode character in the terminal, press Ctrl + Shift + U then enter the code for the character you wish to enter. For example, the em-dash is U+2024. Hit enter once the number is typed out to see the character appear.

Create a new user with sudo ubuntu

Create the new user. Need to use sudo if not signed in as root.

adduser <newuser>

Give sudo priveleges

usermod -aG sudo <newuser>


Setup keypair with remote server

Create a key


Copying the public key to the server


Assumes that the user can authenticate with a password

ssh-copy-id username@remote_host


On client

cat ~/.ssh/id_rsa.pub

On server

mkdir -p ~/.ssh
echo public_key_string >> ~/.ssh/authorized_keys

Adding a key to the ssh-agent

For services like git, it may look to the ssh-agent to see that the appropriate key is present. To add a new key run

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/<keyname>


On Mac, the following will add the key to the keychain and tell the ssh-agent to always use the keychain.

ssh-add --apple-use-keychain ~/.ssh/[private-key]

And the following in .ssh/config. Many keys can be added by having more than one IdentityFile.

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/[private-key]

Upgrade containers in docker compose

In order to upgrade containers running in an existing docker-compose.yml file, run the following:

docker-compose pull
docker-compose up --force-recreate --build -d
docker image prune -f

Useful keyboard shortcuts in firefox

ForwardCtrl + ]
BackCtrl + [
ReloadCtrl + R
Quick Find/
Focus searchbarCtrl + K
Close tabCtrl + W
Tab to the leftCtrl + PageUp
Tab tot he rightCtrl + PageDwn
QuitCtrl + Q
New TabCtrl + T



Find and Replace in Neovim

Current Line - First Occurrence

Where foo is what you want to replace and bar is what you want to replace it with. If what you need to search for uses / then | can be used a seperated instead.


Current Line - All Occurrences


Entire File


Remove Occurrences


Spell plugin

In neovim, to use the spell plugin enter:

:set spell

To cycle between incorrectly spelled words use ]s and [s. To see suggestions for an incorrectly spelled work, press =z (lowercase z).

For further reading:



Combine dictionary A and dictionary B without overwriting dictionary A's values with dictionary B's.

    for key, value in isle_mapping.items():
        if key in cart:
            cart[key] = value



Flatten an Array which may contain None values

def flatten(iterable):
    flattened_list = []
    for item in iterable:
        if isinstance(item, list):
        elif item is not None: 
    return flattened_list



Check if an object value is missing pd.isna()

Changing columns

Change a column based on a condition in another column

df['column'] = df.apply(lambda x: "value" if x['column'] == 'something' else 'other string', axis=1)

Clean Dates

Can use the pandas to_datetime() method. Documentation

Count the number of unique values in a column

Use nunqiue() as a method on a pandas dataframe to get the number of unique values per column


GNU Stow


On Mac

brew stow

On Linux (Debian)

sudo apt install stow


I currently use stow to manage dotfiles. First, create a directory ~/dotfiles and then navigatte into that directory. Then run the following to create the symlinks.

stow .


The structure of the dotfiles repository should be the same as the home directory.

Ignoring files

Files that should not be synced by stow should be placed in .stow-local-ignore. This will prevent symlinks from being created. I use this for shell scripts that are used to install things but should not be synced up to my home directory. The formatting for this file is the same as .gitignore.


An easy way to get the help information a particular command. Works by brute forcing --help -h --version etc.


cargo install halp


Starship is a fast command line prompt written in rust, compatible with bash, zsh and powershell (plus others)


To install, you may use cargo or install directly using a .sh file.

cargo install starship --locked


Simply place the following at the bottom of the .zshrc (or .bashrc etc) and reload the terminal.

eval "$(starship init zsh)"


Create the configuration directory

mkdir -p ~/.config && touch ~/.config/starship.toml

Then make any cofiguration changes desired in that .toml file. A custom path can also be defined by setting a custom configuration directory

export STARSHIP_CONFIG=~/example/non/default/path/starship.toml


This is a rust command line tool for navigating matrix chats with vim motions


cargo install --locked iamb


See iamb.chat for full documentation


repo: https://github.com/ajeetdsouza/zoxide


Zoxide is a tool that remembers previous paths that you have been to through cd, allowing you to more easily navigate between directories. It can be aliased to cd so that it essentially functions like a smarter version of the same command.


For zoxide itself cargo install zoxide --locked

For fzf sudo apt install fzf

Within .zshrc

eval "$(zoxide init --cmd cd zsh)"

Note that this will allow for the use of cd as normal, so that on systems that do not have zoxide installed, cd muscle memory is maintained.


z foo              # cd into highest ranked directory matching foo
z foo bar          # cd into highest ranked directory matching foo and bar
z foo /            # cd into a subdirectory starting with foo

z ~/foo            # z also works like a regular cd command
z foo/             # cd into relative path
z ..               # cd one level up
z -                # cd into previous directory

zi foo             # cd with interactive selection (using fzf)

z foo<SPACE><TAB>  # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)

Linked Documentation

Youtube video: https://www.youtube.com/watch?v=aghxkpyRVDY



Change font

Alacritty has all the configuration done in alacritty.toml. To change the font, just add the following after installing the font on the machine.

size = 14.0

family = "Fira Mono Nerd Font"
style = "Medium"


An extremely fast Python package installer and resolver.

Github repo: https://github.com/astral-sh/uv


pip install uv


Create a virtual environment

The following will create a virutal environment at .venv

uv venv

Activate virtual environment

source .venv/bin/activate 

Install packages into virtual environment

uv pip install flask



An easy way to view csv files in the terminal.

Repository: https://github.com/YS-L/csvlens


It can be installed view cargo

cargo install csvlens


csvlens <filename>
hjkl (or ← ↓ ↑→ )Scroll one row or column in the given direction
Ctrl + f (or Page Down)Scroll one window down
Ctrl + b (or Page Up)Scroll one window up
Ctrl + d (or d)Scroll half a window down
Ctrl + u (or u)Scroll half a window up
Ctrl + hScroll one window left
Ctrl + lScroll one window right
Ctrl + ←Scroll left to first column
Ctrl + →Scroll right to last column
G (or End)Go to bottom
g (or Home)Go to top
<n>GGo to line n
/<regex>Find content matching regex and highlight matches
n (in Find mode)Jump to next result
N (in Find mode)Jump to previous result
&<regex>Filter rows using regex (show only matches)
*<regex>Filter columns using regex (show only matches)
TABToggle between row, column or cell selection modes
>Increase selected column's width
<Decrease selected column's width
Shift + ↓ (or Shift + j)Sort rows by the selected column
# (in Cell mode)Find and highlight rows like the selected cell
@ (in Cell mode)Filter rows like the selected cell
Enter (in Cell mode)Print the selected cell to stdout and exit
-SToggle line wrapping
rReset to default view (clear all filters and custom column widths)
H (or ?)Display help


Russ is a rust based tui for reading RSS feeds.




cargo install russ --git https://github.com/ckampfe/russ


russ read

Cargo Update


A tool to automatically update all cargo installed tools on the system.


Run cargo install --list to see a list of all cargo packages installed globally



cargo install cargo-update


Update all packages.

cargo install-update -a

Update cargo-install


Git Guardian

Scan for secrets in a git repo ggshield secret scan repo .

Upgrade existing installation

pip install --user --upgrade ggshield


A command line interface for Vikunja

Source code: Gitlab


python -m pip install --user vja


python -m pip install --user vja --upgrade


Set the following as the config file, vja.rc. Change the url to the instance url.


You can define a custom location for the config file. I have chosen ~/.config/vikunja. This needs to be set as an environment variable through .zshrc.