docs.daveops.net

Snippets for yer computer needs

Version Control

Git

Repositories

Create bare repository

mkdir -p project.git && cd project.git && git --bare init
git clone --bare -l non_bare_repo new_bare_repo
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git.example.com:/path/project.git

Branches

# Rename a branch -m FROM TO
git branch -m master main

# Push branch to remote server
git push origin branch_name

Checkout remote repository:

git fetch
git checkout -b local_branch_name remote/branch_name

Delete remote branch:

git push origin :branch_to_delete
git branch -d branch_to_delete

Add remote branch:

git remote add upstream <git://github.com/user/repo.git>

Remove branches already merged to main:

git branch --merged | grep -v \* | xargs git branch -D

Sequential versioning

git rev-list --reverse HEAD | awk "/$(git log -n 1 --pretty="format:%h")/ {print NR}"

Reset git to a specific commit

git reset [hash]
git reset --soft HEAD@{1}
git commit -m "revert to [hash]"
git reset --hard

If you just need to amend last commit,

git commit --amend

Make an empty commit

git commit --allow-empty -m 'just need to kick the CI'

Hooks

Push to website on git push:

On server, put this in hooks/post-receive

#!/bin/sh
GIT_WORK_TREE=/path/to/www.example.org git checkout -f

Tagging

# list tags
git tag
# Show current tag
git describe --tags
# Create a tag
git tag -a v1.0 -m "Creating v1.0 tag"
# push tags to remote
git push --tags
# Check out tag 'v1.0'
git checkout v1.0

Stashing

git stash list  # list stashes
git stash save "message here"  # create a stash
git stash show <stash>  # show stash diff
git stash apply stash@{1}  # apply the code you stashed
git stash drop <stash>  # delete specified stash
git stash clear  # delete all stashes

History

# Show nicely formatted changelog
git log --graph --oneline --abbrev-commit --decorate

# See commits from individual
git log --author="david"

# Get list of contributors
git shortlog -s -n

# Search git history
git log -S <search term>

Remove non-tracked files

git clean -n  # dry run
git clean -f  # delete the files

Squash commits into single commit

git rebase -i <hash>

Untrack files without deletion

echo "filename" >> .gitignore
git rm --cached filename
git add -u
git commit -m "removing filename from version control"

Load my dotfiles to the home directory

cd ~
git init
git remote add origin git@github.com:dafyddcrosby/dotfiles.git
git pull origin main

Get list of staged files for commit

git diff --cached --name-status | sed 's/.\s*//'

Diff remote repo

git diff <branch> <remote>/<branch>

Retrieve single file from a specific revision in git

git checkout <HASH> -- ./path/to/file

Objects

# See all objects
git rev-list --objects --all

misc

http://whatthecommit.com/

https://gitea.io

git-crypt

Running Gitlab in Docker

git bisect

# Visualize bisect
git bisect visualize
# Finish bisect
git bisect reset

Git LFS

https://git-lfs.github.com/

# Checking out files
git lfs fetch
git lfs checkout

Git commit signing

To sign off on a commit, put in the commit message:

Signed-off-by: David Crosby <email@example.com>
# sign a commit
git commit -S -m MESSAGE

# specify a default signing key
git config --global user.signingkey KEYID

# configure git to always sign commits
git config --global commit.gpgsign true

# Using X509 (a la smimesign + Git 2.19+)
git config --global gpg.x509.program smimesign
git config --global gpg.format x509

Importing

Importing a local SVN repo to git:

git svn clone file:///path/to/repo -T trunk -b branches -t tags

Import Sourceforge CVS repo:

rsync -av rsync://w3m.cvs.sourceforge.net/cvsroot/w3m/ w3m
git cvsimport -p x -v -d /absolute/path/to/w3m w3m

Git subtree

Subtrees are kind of like less janky submodules.

# Add a remote
git remote add -f subtreename https://github.com/dafyddcrosby/project.git
# Add the subtree
git subtree add --prefix path/to/subtree subtreename main
# Pull a subtree
git fetch subtreename main
git subtree pull --prefix path/to/subtree subtreename subtreename main
# Push a subtree
git subtree push --prefix=path/to/subtree subtreename main

Another way of importing another repo as a subtree without git subtree command

git remote add -f remote_name git@example.com:remote_repo.git
git merge -s ours --no-commit remote_name/main
git read-tree --prefix=newpath/ -u remote_name/main
git commit -m "Subtree merged in newpath"

GitHub

Templates and special files

file desc
README.md Initial documentation
CODEOWNERS Specify who has access
.github/dependabot.yml Configuration for Dependabot
docs/CODE_OF_CONDUCT.md Code of Conduct for the project
docs/FUNDING.yml Specify accounts for donations
docs/ISSUE_TEMPLATES/ Templates for issues
docs/pull_request_template.md Single template for a pull request
docs/PULL_REQUEST_TEMPLATE/ Multiple templates for pull requests
docs/SECURITY.md Security response documentation
docs/SUPPORT.md Let people know where to get help

You can use /docs or /.github

You can also create a template repository

Profile

If you create a repo with the same name as your account, you can have README.md at the top of your profile

Signing releases

git tag -s software-0.1
git push --tags
# publish a release
# download tarball
# verify tarball matches git
gpg --armor --detach-sign software-0.1.tar.gz
# add gpg signature to release

Get Atom feed of file changes

https://github.com/user/repo/commits/main/path/to/file.atom

GitHub - Enterprise

CLI:

# Set a message that's visible to everyone
ghe-announce -s MESSAGE
# Remove previously set message
ghe-announce -u
# Get webhook fails for a certain day
ghe-webhook-logs -f -a YYYYMMDD

Sapling

Cloning git repos

sl clone --git $REPO $DIR

Following remotes

[remotenames] publicheads=

Fossil

# initialize repo
fossil init foo.repo
# make a working directory, check out a local tree
mkdir working && cd working && fossil open ../foo.repo
cmd desc
add $file add file to upcoming commit
amend Amend commit metadata
branch manage branches for a repo
cat print file as it exists in the repo
clean delete “extra” files
clone clone another fossil repo
commit commit changes
delete/rm mark file no longer part of project
diff diff the files
extras show files not tracked in source tree
finfo shows file history
timeline print summary of activity
ui start web server
unversioned Manage unversioned artifacts in the repo
update Changes version of current checkout

Ignore glob

mkdir -p .fossil-settings
echo "ignore.this.file" > .fossil-settings/ignore-glob
fossil add .fossil-setings/ignore-glob

Import from git

git fast-export --all | fossil import --git new-repo.fossil

mercurial

# New repo
hg init $DIR

# Clone a repo
hg clone $REPO

# Add files to a commit
hg add $FILES

# Commit with message
hg commit -m "Changes"

# Push changes
hg push

CVS

Tagging:

# Tag an instance
cvs rtag -D "2010-1-28" tag_name module_name
# Untagging an instance
cvs rtag -d tag_name module_name

CVsync

http://www.openbsd.org/cvsync.html

# Check available modules
cvsync cvsync://<host>[:<port>]/</port></host>

SVN

# Get information about a repo
svnlookup info /path/to/repo
# latest revision number
svnlookup youngest /path/to/repo

diff

--patience  # use the patience algorithm
  1. Match the first lines of both if they’re identical, then match the second, third, etc. until a pair doesn’t match.
  2. Match the last lines of both if they’re identical, then match the next to last, second to last, etc. until a pair doesn’t match.
  3. Find all lines which occur exactly once on both sides, then do longest common subsequence on those lines, matching them up.
  4. Do steps 1-2 on each section between matched lines

From https://bramcohen.livejournal.com/73318.html

patch

To create patch

diff -Naur oldfile newfile >new-patch

To add patch

patch <new-patch