Git Aliases for Clean Commits

Today I'd love to introduce three useful Git aliases to maintain clean code and intelligent staging.

Quick Setup

# 1. Remove trailing whitespace from modified files
git config --global alias.cleanup '!git -c color.status=false status -s | grep -v "^D\|^.D" | cut -c4- | xargs -r -I {} sed -i "s/[[:space:]]*$//" {}'

# 2. Stage only substantive changes (ignore whitespace)  
git config --global alias.stagewhitespace '!git reset . && git add -N . && git diff -w -b | git apply --cached'

# 3. Combine both operations
git config --global alias.smartadd '!git cleanup && git stagewhitespace'

Usage

git cleanup         # Clean trailing spaces only
git stagewhitespace # Stage content changes only
git smartadd        # Clean + smart staging

What Each Alias Does

cleanup

  • Removes trailing whitespace from all modified files
  • Skips deleted files to avoid errors
  • Handles ANSI color codes in git status output

stagewhitespace

  • Resets staging area
  • Marks new files as intent-to-add
  • Stages only meaningful content changes
  • Ignores pure whitespace modifications

smartadd

  • Runs cleanup first, then stagewhitespace
  • One command for clean, intelligent staging

Key Features

  • Safe: Filters out deleted files to prevent errors
  • Smart: Handles new files correctly
  • Clean: Maintains consistent code formatting
  • Focused: Stages only substantive changes

Technical Details

The aliases handle several edge cases:

  • ANSI color codes in git output (disabled with -c color.status=false)
  • Deleted files that would cause sed errors (filtered with grep -v "^D\|^.D")
  • New untracked files (handled with git add -N)
  • Empty file lists (handled with xargs -r)

Perfect for teams that want clean commits without manual whitespace management.

网友语录 - 第42期 - 伟大成就需要的是以年为单位的积累,而不是每周都冲刺

这里记录我的一周分享,通常在周六发布。


梨梨原上草 @svuoalnalnis 公司把保洁外包给一间公司,常来的就那么几个面孔。时间长了,你就能体会她们之间的差别。

有时候一走进厨房,你就知道今天来上班的肯定是其中的某一个。而另外一些天,不用具体看脸也知道来摸鱼的是哪几个……

其实想对其中几个说,你们可能干啥都会做得很好,不限于保洁。只要时间允许,我的活也能干。


还真是这样。一生要是每本书都一字一句的读完,确实读不了几千本。但真正值得一字一句读完的书完全没有那么多,你需要略读上万本书(甚至可以更多)才能找出为数不多值得读一次又一次的那些书。一本书翻了几页放下,没什么,很多书没有读完,没什么。没有读完的那些书,书自己也有责任。


戚小诺 我问小九怎么表达他的愤怒,他说他的脑子里会有一个白色小人,一个黑色小人,黑色小人想要去干架:冲啊!我要干架!白色小人就在一边劝架:算了算了,不要打架,也许打不赢会受伤,爸爸妈妈还会担心。然后自己就会冷静很多。——头脑特工队没白看哈😂😂


memoryza 人们天生就是高效的改进者,而只有极少数会愿意从零开始


失败不可怕,一蹶不振才可怕

反馈是变得更好的关键。正如蓝迪波什所说:"人之所以会改变,是因为获得了反馈"。"失败"的本质是一种强反馈,它告诉我们这样或者此时不行,我们需要调整。在这个世界上,只要我们的生命还在继续(留得青山在),就没有真正的失败(不怕没柴烧),有的只是不断调整的过程。一个人的成长速度,取决于他得到反馈的频率和质量。因此,我们应该勇于改变并珍视每一次的反馈,正是它们引导着我们一步步实现人生目标。


真正重要的工作都不是一口气完成的,而是反复回到同一主题,慢慢打磨。像居里夫人发现放射性元素那年夏天,也去乡下休假、爬山。伟大成就需要的是以年为单位的积累,而不是每周都冲刺。别被高强度伪忙碌欺骗,真正的生产力,是以自然节奏、长期愿景,持续推进关键事务


生活若总是愿意吃苦,就有吃不完的苦;若总是抱怨生活,就有抱怨不完的生活。总觉得前路还长,却不知不觉就进入四十几五十几。能改善生活质量的钱一定要尽早花,早花早享受


调查期望不是让用户畅想这产品能具有什么功能,而是为了满足现有需求应该具有什么功能


LLM 的注意力其实是个滑动窗口,不持续提醒,很容易跑偏,这一点就跟我们管理一个想法很多的员工一个道理。(哎!人的注意力也是个滑动窗口。)

Cloudflare DNS Update Script

Motivation: though reinstalling OS is rare, but I still want to automate the DNS update process.

Get API Token

  1. Go to https://dash.cloudflare.com/profile/api-tokens
  2. Click "Create Token"
  3. Use "Edit zone DNS" template
  4. Select your domain in "Zone Resources"
  5. Copy the generated token

Setup API Token in bashrc

Add to ~/.bashrc:

export CF_API_TOKEN="your_api_token_here"

Reload: source ~/.bashrc

Enhanced Update Script

Create update-dns.sh:

#!/bin/bash

# Usage function
usage() {
    echo "Usage: $0 <record_name> [ip_address]"
    echo "       $0 <domain> <subdomain> [ip_address]"
    echo "Examples:"
    echo "  $0 home.example.com                    # Uses Tailscale IP"
    echo "  $0 example.com                         # Root domain with Tailscale IP"
    echo "  $0 server.example.com 192.168.1.100   # Uses specified IP"
    echo "  $0 example.com home                    # Legacy format"
    echo "  $0 example.com @ 1.2.3.4              # Legacy root domain"
    exit 1
}

# Check parameters
if [ $# -lt 1 ]; then
    usage
fi

# Check if API token is set
if [ -z "$CF_API_TOKEN" ]; then
    echo "Error: CF_API_TOKEN not set. Add it to ~/.bashrc"
    exit 1
fi

# Parse arguments - detect format
FIRST_ARG="$1"
SECOND_ARG="$2"
THIRD_ARG="$3"

# Check if first argument contains multiple dots (FQDN format)
if [[ "$FIRST_ARG" == *.*.* ]] || ([[ "$FIRST_ARG" == *.* ]] && [[ "$SECOND_ARG" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]); then
    # FQDN format: script.sh home.example.com [ip]
    RECORD_NAME="$FIRST_ARG"
    CUSTOM_IP="$SECOND_ARG"
    
    # Extract domain by removing first subdomain part
    DOMAIN=$(echo "$RECORD_NAME" | cut -d'.' -f2-)
elif [[ "$FIRST_ARG" == *.* ]] && [ -z "$SECOND_ARG" ]; then
    # Root domain format: script.sh example.com
    RECORD_NAME="$FIRST_ARG"
    DOMAIN="$FIRST_ARG"
    CUSTOM_IP=""
elif [[ "$FIRST_ARG" == *.* ]] && [ -n "$SECOND_ARG" ] && [[ ! "$SECOND_ARG" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    # Legacy format: script.sh example.com home [ip]
    DOMAIN="$FIRST_ARG"
    SUBDOMAIN="$SECOND_ARG"
    CUSTOM_IP="$THIRD_ARG"
    
    if [ "$SUBDOMAIN" = "@" ]; then
        RECORD_NAME="$DOMAIN"
    else
        RECORD_NAME="$SUBDOMAIN.$DOMAIN"
    fi
else
    echo "Error: Invalid arguments format"
    usage
fi

# Get IP address
if [ -n "$CUSTOM_IP" ]; then
    NEW_IP="$CUSTOM_IP"
    echo "Using provided IP: $NEW_IP"
else
    if command -v tailscale >/dev/null 2>&1; then
        NEW_IP=$(tailscale ip -4)
        echo "Using Tailscale IP: $NEW_IP"
    else
        echo "Error: tailscale not found and no IP provided"
        exit 1
    fi
fi

# Validate IP format
if ! echo "$NEW_IP" | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' >/dev/null; then
    echo "Error: Invalid IP address format: $NEW_IP"
    exit 1
fi

echo "Updating DNS record: $RECORD_NAME -> $NEW_IP"

# Get Zone ID
echo "Getting Zone ID for $DOMAIN..."
ZONE_RESPONSE=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
    "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN")

ZONE_ID=$(echo "$ZONE_RESPONSE" | jq -r '.result[0].id')

if [ "$ZONE_ID" = "null" ] || [ -z "$ZONE_ID" ]; then
    echo "Error: Could not find zone for domain $DOMAIN"
    echo "Response: $ZONE_RESPONSE"
    exit 1
fi

echo "Zone ID: $ZONE_ID"

# Get Record ID
echo "Getting Record ID for $RECORD_NAME..."
RECORD_RESPONSE=$(curl -s -H "Authorization: Bearer $CF_API_TOKEN" \
    "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$RECORD_NAME&type=A")

RECORD_ID=$(echo "$RECORD_RESPONSE" | jq -r '.result[0].id')

if [ "$RECORD_ID" = "null" ] || [ -z "$RECORD_ID" ]; then
    echo "Error: Could not find A record for $RECORD_NAME"
    echo "Available records:"
    echo "$RECORD_RESPONSE" | jq -r '.result[] | "\(.name) (\(.type))"'
    exit 1
fi

echo "Record ID: $RECORD_ID"

# Update DNS record
echo "Updating DNS record..."
UPDATE_RESPONSE=$(curl -s -X PUT \
    "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
    -H "Authorization: Bearer $CF_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"A\",\"name\":\"$RECORD_NAME\",\"content\":\"$NEW_IP\"}")

SUCCESS=$(echo "$UPDATE_RESPONSE" | jq -r '.success')

if [ "$SUCCESS" = "true" ]; then
    echo "✅ DNS record updated successfully!"
    echo "   $RECORD_NAME now points to $NEW_IP"
else
    echo "❌ Failed to update DNS record"
    echo "Response: $UPDATE_RESPONSE"
    exit 1
fi

Make executable: chmod +x update-dns.sh

Usage Examples

# New FQDN format (recommended)
./update-dns.sh home.example.com                    # Uses Tailscale IP
./update-dns.sh server.example.com 192.168.1.100   # Uses custom IP
./update-dns.sh example.com                         # Root domain with Tailscale IP

# Legacy format (still supported)
./update-dns.sh example.com home                    # Subdomain with Tailscale IP
./update-dns.sh example.com @ 1.2.3.4              # Root domain with custom IP

# Multiple subdomains
./update-dns.sh web.example.com
./update-dns.sh api.example.com
./update-dns.sh db.example.com 10.0.0.5

Features

  • ✅ API token stored securely in .bashrc
  • ✅ Auto-discovers Zone ID and Record ID
  • ✅ Supports custom IP or auto-detects Tailscale IP
  • ✅ Supports root domain updates with @
  • ✅ Input validation and error handling
  • ✅ Clear success/failure messages
  • ✅ Usage help and examples

Alternative: Using flarectl

# Install
go install github.com/cloudflare/cloudflare-go/cmd/flarectl@latest

# Update (simpler)
export CF_API_TOKEN="your_token"
flarectl dns update --zone yourdomain.com --name subdomain --content $(tailscale ip -4) --type A

PopOS System Recovery and Partition Migration Notes

Background

Yesterday, my PopOS system broke unexpectedly. The refresh install option failed, and attempting to reinstall while preserving the old /var and /home partitions was unsuccessful.

Solution: Fresh Custom Installation

Performed a clean custom installation with:

  • /boot/efi - formatted
  • / - formatted
  • /recovery - formatted

This approach worked successfully, then migrated data from old partitions.

Partition Migration Process

Tools Used

parted --list    # Get partition information
blkid           # Get partition UUIDs

Note: Couldn't stop GDM or enter single-user mode (system would hang). Performed migration on running system instead.

1. Home Partition Migration (/dev/nvme0n1p8)

sudo mv /home /home.bak          # Backup current home
sudo mkdir /home
sudo mount /dev/nvme0n1p8 /home
ls /home                         # Confirm correct partition
sudo blkid /dev/nvme0n1p8       # Get UUID
sudo vi /etc/fstab

Added to /etc/fstab:

UUID=32e4ed56-6ed9-4f14-9585-ffff54f997b2 /home ext4 defaults 0 2

Rebooted to verify system stability.

2. Backup Partition Setup (/dev/nvme0n1p10)

sudo parted --list
sudo blkid /dev/nvme0n1p10
sudo vi /etc/fstab

Added to /etc/fstab:

UUID=8aba0dd5-7058-4036-8a08-fcd1e0e002bc /backup ext4 defaults 0 2
sudo mount -a                   # Test mount configuration

3. Var Partition Migration (/dev/nvme0n1p7)

# Mount old var partition and backup data
sudo mkdir /mnt/var
sudo mount /dev/nvme0n1p7 /mnt/var
sudo tar -czpvf /backup/old-var-backup.tar.gz -C /mnt var

or backup docker/crontabs only

sudo tar -czpvf /backup/old-docker-backup.tar.gz -C /mnt var/lib/docker
sudo tar -czpvf /backup/old-cron-backup.tar.gz -C /mnt var/spool/cron

# Prepare new var partition
sudo umount /mnt/var
sudo mkfs.ext4 /dev/nvme0n1p7   # Format old var partition

# Copy current var data to new partition
sudo mkdir /mnt/new-var
sudo mount /dev/nvme0n1p7 /mnt/new-var
sudo cp -av /var/* /mnt/new-var/

# Update fstab and switch to new partition
sudo blkid /dev/nvme0n1p7
sudo vi /etc/fstab              # Add var partition entry
sudo mv /var /var.old && sudo mkdir /var && sudo mount -a

Restore old var data

# update system
apt update && apt upgrade

sudo apt purge nano # enable vi EDITOR in visudo
sudo apt install curl

# re-enable davidwei ALL=(ALL:ALL) NOPASSWD:ALL

# install docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor --yes -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # add docker apt source
sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# add current user to docker group
sudo usermod -aG docker davidwei

# restore old docker/cron data
# 1. Stop Docker services properly
sudo systemctl stop docker.socket
sudo systemctl stop docker.service

# 2. Extract docker data in one command
sudo tar -xzpf /backup/old-var-backup.tar.gz -C / var/lib/docker
sudo tar -xzpf /backup/old-var-backup.tar.gz -C / var/spoon/cron

or if there are spearate backups:

sudo tar -xzpf /backup/old-var-backup.tar.gz -C / var/lib/docker
sudo tar -xzpf /backup/old-var-backup.tar.gz -C / var/spool/cron/crontabs

sudo chmod og+rx /var/spool/cron/crontabs/
sudo chown davidwei:davidwei /var/spool/cron/crontabs/davidwei
sudo systemctl restart cron

# 3. Start Docker services
sudo systemctl start docker.service
sudo systemctl start docker.socket

# 4. Verify
docker volume ls
docker images
docker ps -a

# re-install tailscale / set no-expiry / rename to xps / change cloudflare dns to new IP
curl -fsSL https://tailscale.com/install.sh | sh

# re-install google-chrome
sudo dpkg -i ~/Downloads/google-chrome-stable_current_amd64.deb

# reinstall other utils
sudo apt install tree ncdu vim gnome-sushi mc clang ninja-build mesa-utils libgtk-3-dev cmake mysql-client-core-8.0 libstdc++-12-dev build-essential pkg-config htop mc ssh meld

# reinstall fcitx
sudo apt install fcitx5-rime fcitx5-chinese-addons

Key Lessons Learned

  • Fresh installation with custom partitioning was more reliable than trying to preserve old partitions during install
  • System migration on a running system worked fine when rescue mode wasn't accessible
  • Always backup critical data before formatting partitions
  • Test each partition mount configuration before proceeding to the next step

Status: Migration completed successfully. System running normally with all data preserved.

Quick Tip: Get GitHub PR Diffs Easily

Need to share changes from a GitHub PR (even closed ones)? Just add .diff or .patch to the PR URL:

Original URL:

https://github.com/owner/repo/pull/123

For diff format:

https://github.com/owner/repo/pull/123.diff

For patch format:

https://github.com/owner/repo/pull/123.patch

Both work for open, closed, or merged PRs. Perfect for code reviews, investigations, or sharing changes with others.

For LLM/AI analysis: Use .diff format - it's cleaner and more standardized than .patch which includes extra email headers.