Skip to content

Git

Related pages: GitHub β€’ Bash β€’ Issue tracking β€’ Reproducibility stack

Resources

Quick links:

Cheatsheets:

Tutorials:

Books:

Snapshotting

Recording changes

Reverting Changes

To reset commits, run:

git reset --soft HEAD~1

To restore files to a previous commit, run:

git restore --source=HEAD~1 <pathspec>

There are a few ways to specify the tree that you want to use when you revert changes, restore files, or check out files:

# HEAD ----
HEAD                # current commit (the state of your working branch)

# Parents `^` ----
HEAD^               # the first parent of HEAD (most succinct)
HEAD^1              # the first parent of HEAD (HEAD^ is probably easier)
HEAD^2              # the second parent of HEAD (useful when current commit is a merge commit)
HEAD^^              # a grandparent commit (equivalent to HEAD~2 or HEAD^1^1)
HEAD^1^2            # a grandparent commit (you can follow ^ with 1 or 2 as explained above)

# Ancestors `~` ----
HEAD~1              # one commit before HEAD (equivalent to HEAD^ or HEAD^1)
HEAD~2              # two commits before HEAD (equivalent to HEAD^^ or HEAD^1^1)
HEAD~1^2            # a grandparent commit in a hybrid form, equivalent to HEAD^1^2

# Reflog-based ----
HEAD@{1}            # where HEAD was before the last move (from reflog)
HEAD@{2.days.ago}   # the version of HEAD from two days ago (time-based reflog)

# Commit hashes ----
abc1234             # specific commit hash (abbreviated or full)

# Branches and remotes ----
main                # latest commit on the 'main' branch
dev                 
origin/main         # latest commit on the remote-tracking 'main'

# Tags ----
v1.0                # tag pointing to a release or milestone

Stashing changes

git stash           # stash away changes
git stash pop       # restore changes
git stash apply     # restore changes but keep them in the stash list
git stash list      # list all stashed changes
git stash clear     # clear all stashes
git stash show stash@{0}
git stash apply stash@{0}
git stash pop stash@{0}
git stash drop stash@{0}

If you're using the powerlevel10k prompt theme, the number of stashes appears after the asterisk:

master *3

Branch management

Switching to another branch

To switch to another branch interactively through fuzzy search, run:

git branch -a | fzf | xargs git switch

To check out a specific commit, run:

git checkout 1b1b1b1

Removing local branches after remote deletion

To clean up local branches whose remote has been deleted, run the commands below:

git fetch --prune
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d
  • git fetch --prune removes references to remote branches that no longer exist.
  • git branch -vv lists all local branches with their tracking status.
    • Each ouput row looks like: main a1a1a1a [origin/main] #100 xxxxxx.
  • grep ': gone]' filters in only those where the remote is marked as : gone].
  • awk '{print $1}' extracts the branch name.
    • awk splits each line by whitespace (spaces or tabs).
    • '{print $1}' means β€œprint the first field (column),” which is the branch name.
  • xargs git branch -D deletes each branch locally.

To clean up stubborn branches that Git refuses to delete with -d, you can run the force-delete version:

git fetch --prune
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D

Configurations

Viewing configurations

To view Git configurations, run one of the following commands:

git config --list --local
git config --list --global
git config --list --system
git config --list --show-scope # show {worktree/local/global/system/command}
git config --list --show-origin # show config origin (e.g., `file:.git/config`)

Editing .gitattributes

Editing .gitignore

A few important rules to keep in mind:

  • The slash "/" is used as the directory separator.

  • If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.

  • An asterisk "*" matches anything except a slash. The character "?" matches any one character except "/". The range notation, e.g. [a-zA-Z], can be used to match one of the characters in a range.

A rule of thumb for adding * in front is:

  • For file extensions or files that start with a dot ., you should add * to target a broader set. (e.g., *.out, *.DS_Store)
  • For files or folders with exact names, don't add *, to prevent targeting more than needed. (e.g., Rplots.pdf)
.gitignore
# ------------------------------------------------------------------------------
# User-specific configuration and external files
# ------------------------------------------------------------------------------

# User-specific external paths
/external
output_local/

# Template configuration file
/local_env.sh

# Other configuration files
.vscode/
.lintr

# ------------------------------------------------------------------------------
# Temporary, intermediate, log, and backup files generated by various programs
# ------------------------------------------------------------------------------

# Temporary by design
temp/

# R
.Rhistory
.Rapp.history
.Rproj.user/
Rplots.pdf

# Stata
*.stswp

# Python
*.pyc

# LaTeX
*.aux
*.bbl
*.blg
*.out
*.fdb_latexmk
*.fls
*.synctex.gz
*.nav
*.snm
*.toc
*.lof
*.lot
**/source/*.log
**/source/*.pdf

# LyX
*.lyx~
*.lyx#
*.lyx.emergency

# Jupyter Notebook
*.ipynb_checkpoints/

# macOS
*.DS_Store

Hooks

Git LFS

  • Git Large File Storage

    Git Large File Storage (LFS) replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server like GitHub.com or GitHub Enterprise

Introductions:

Discussions:

Checking what files are tracked by Git LFS

git lfs ls-files

Pulling files with Git LFS

git lfs pull

Tracking files with Git LFS

git lfs track "<pattern>"

Stop tracking files with Git LFS

git lfs untrack "<pattern>"
git rm --cached "<pattern>"

Alternatives to Git

Perforce

Mercurial

Discussions: