3 Notes

3.1 C notes

  • char *: pointer to char
  • char * const: const pointer to char
  • const char *, char const *: pointer to const char
  • const char * const: const pointer to const char

3.2 TCP socket programming notes

epoll event:

EPOLLHUP: the other end of a pipe called close(2); both direction of a TCP connection are closed (sent and received FIN?)

EPOLLRDHUP: stream peer closed their writing connection (peer sent FIN)

send(2) returns 0: stream peer closed their writing connection (peer sent FIN)

errno:

ECONNABORTED: TCP enters TCP_CLOSE due to RST, timeout or ICMP error during connect

ECONNRESET: received RST while not in TCP_SYN_SENT (ECONNREFUSED) or TCP_CLOSE_WAIT (EPIPE)

also EPIPE: send on a shutdown writing half

3.3 Git Notes

Git version 2.28.0

3.3.1 Work In Progress

3.3.1.1 Inspect WIP

  1. git status shows the list of files with staged and unstaged changes and untracked files.
  2. git diff shows unstaged changes (worktree v index)
  3. git diff --staged show staged changes (index v HEAD)
  4. git diff @ shows unstaged and staged changes (worktree, index v HEAD). (@ is a shortcut for HEAD. See gitrevisions)
  5. <pathspec> add be added at the end, e.g., :/ stands for repository root.

3.3.1.2 Discard WIP

  1. git clean -f <path> removes untracked files
  2. git restore <pathspec> discards unstaged changes (working => index)
  • alternatively, git checkout <pathspec>
  1. Undo git add: git restore --staged <pathspec> unstages staged changes (index => HEAD) or git rm --cached <pathspec> if a new file was added
  • alternatively, git reset <pathspec>, git reset (the whole repository), git reset -p (interactively select chunks to unstage)
  1. git restore --source=HEAD --staged --worktree <pathspec> discards unstaged and staged changes (worktree, index => HEAD). Shorthand: git restore -s@ -SW <pathspec>
  • alternatively, git checkout @ <pathspec> and git reset --hard (the whole repository).

Note: git reset “resets current HEAD to the specified state” (and changes the worktree and the index accordingly) while git restore does not move HEAD.

3.3.1.3 Save and reapply WIP

  1. git stash stashes unstaged and staged changes (untracked files are excluded) to a stash stack
  • git stash -u includes untracked files (excluding ignored files); git statsh -a includes even ignored files
  • git stash -p is interactive
  1. git stash pop applies the most recent local stash (previously staged changes are restored as unstaged) and drops it from the stash stack
  • git stash pop --index restores staged changes as staged
  1. git stash apply applies the most recent local stash but
  2. git stash drop drops the most recent local stash from the stash stack
  • git stash list lists saved stashes
  • git stash show n inspects n-th stash (0-th is the most recent one)
  • git stash apply n applies the n-th stash from the stash stack
  • git stash clear clears the stash stack

3.3.1.4 (Somewhat odd) alternative to git stash

git worktree add -b hotfix ../hotfix
cd ../hotfix
# work on it ...
git commit -m "fix #xxx"
# change to previous worktree
git reset --soft hotfix # WIP in current worktree untouched but HEAD updated
git push
git worktree remove ../hotfix

3.3.2 History

3.3.2.1 Inspect history

  1. git log --stat
  2. git log -p
  3. git log <file>

3.3.2.2 Rewrite history

3.3.2.2.1 Rewrite, undo and revert last commit
  1. git commit --amend replaces your last commit with a new commit.
  • supply -m to change commit message or --no-edit to keep it unchanged
  1. git reset --hard @~ rolls HEAD back to the second last commit and restores the worktree and the index.
  2. git revert @ makes a new commit to revert the changes introduced in last commit.
3.3.2.2.2 Squash, split, and rewrite past commits
  1. git rebase --root -i. See Rewriting History of Pro Git.
  • Squash all commits: git reset $(git commit-tree @^{tree} -m "Squash all commits") creates a new commit out of the tree object corresponding to HEAD and resets HEAD to it (source: StackOverflow). Note that some unreachable past commits are still available in your local reflog and unreachable objects are available in your local object database, which will expire by default. Reflogs and unreachable objects are not transfered by git push.

3.3.3 Working with long histories

  1. git clone --depth 1 <repos>
  2. git fetch origin <remote_branch>:<local_branch>
  3. git clone --depth 1 --no-single-branch <repos> (equivalent to 1. and git fetch --depth 1 origin 'refs/heads/*:refs/remotes/origin/*')
  4. git fetch --deepen 1

3.4 WebDav Server for Zotero Library

2021-01-21

  1. Motivation: Zotero Library’s free space is only 300MB.
  2. Caveat: Group Library is not supported.

3.4.1 Prerequisitives

  1. server with publicly accessible IP
  2. domain name

3.4.2 Steps

  1. Install vanilla caddy per https://caddyserver.com/docs/install#debian-ubuntu-raspbian, which contains systemd service files
  2. Install caddy compiled with webdav module. You can customize included modules at https://caddyserver.com/download. Unfortunately, this step has to be repeated whenever caddy is upgraded.
curl -o /tmp/caddy 'https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmholt%2Fcaddy-webdav'
sudo install -o root -m 755 /tmp/caddy /usr/bin/caddy
  1. Generate password for HTTP Basic Authentication caddy hash-password > passwd_hash # input your passwd on stdin
  2. sudo mkdir -p /var/www/zotero
  3. Put in /etc/caddy/Caddyfile:
example.com {
    basicauth {
        # username passwd_hash
        zotero xxxx
    }
    root /zotero/* /var/www
    webdav /zotero/*
}
  1. Reload caddy config sudo systemctl reload caddy

3.4.3 Testing

cadaver is a command-line WebDav client, suitable for testing: cadaver https://example.com/zotero/

3.4.4 Other clients compatible with Zotero Library

Papership has macOS and iOS apps that can sync with Zotero and personal WebDav servers. You should run sudo touch /var/www/zotero/lastsync.txt on the WebDav server on first use.