Graduate Program KB

Storage

  • git init Initialises a git repository

  • Objects are stored using SHA1 hashing which generates a 40 digit hexadecimal key

  • Types of Objects

    • blob - Compressed contents of a file

      • Metadata: identifier, size, \0 delimiter, file contents
      • Only 1 copy of identical files are stored, since they generate the same SHA1 key
      ----------------------
      |   blob   |   size  |
      ----------------------
      | \0                 |
      | file contents      |
      ----------------------
      
    • tree - The hierarchy structure between files in git

      • Contains pointers (to blobs, to trees) along with metadata: pointer type (blob, tree), file/directory name, mode, \0 delimiter and size
      ----------------------
      |   tree   |   size  |
      ----------------------
      | \0                 |
      ---------------------|
      | blob | SHA1 | file |
      | tree | SHA1 | dir  |
      ----------------------
      
    • commit - Snapshots of the git repository

      • Contains pointer to a tree along with metadata: author, committer, date, message, one or more parent commits
      • The SHA1 key is generated based off all the metadata
      ----------------------
      |  commit  |   size  |
      ----------------------
      |   tree   |   SHA1  | 
      |  parent  |   SHA1  |
      |  author  |   name  |
      |  message |   ".."  |
      ----------------------
      

Areas

  • Working area contains untracked files, it's not managed by git

  • Staging area contains files that have undergone changes and are part of the next commit

  • Repository contains commit history and up-to-date files managed by git

  • git add Stage file for commit

  • git add -p Stage files into chunks, useful for large changes

  • git rm Remove file from staging area

  • git mv Rename file

  • git ls-files -s Display changes in staging area

Stashing

  • Save uncommited work and protect from destructive operations
  • git stash Stash working directory
  • git stash list Show stash list
  • git stash show stash@{n} Show specific stash contents
  • git stash apply Apply latest stash
  • git stash apply stash@{n} Apply specific stash
  • git stash --include-untracked Include untracked files, recommended to use
  • git stash --all Stash all files, even from .gitignore
  • git stash save {name} Save stash with name
  • git stash branch {branch} Start branch with stash applied
  • git checkout {branch} -- {file} Checkout file from stash and overwrites
  • git stash pop Remove latest stash and apply changes
  • git stash drop Remove latest stash
  • git stash drop stash@{n} Remove specific stash
  • git stash clear Remove all stashes

References

  • Tags and branches point to commits, stored in ./git/refs/heads/ and .git/refs/tags respectively
  • HEAD points to the current commit or current branch if checking out
  • cat .git/HEAD Shows where HEAD is pointing to
  • git branch {new-branch} Create new branch
  • git checkout {branch} Checkout to branch
  • git checkout -b {new-branch} Create new branch and checkout after

Tags

  • Lightweight tags contain a pointer to a commit

    • git tag {name}
  • Annotated tags can also store additional information, such as the author, message and date

    • git tag -a {name} -m {message}
  • git tag List all tags

  • git show-ref --tags Show all tags and associated commit

  • git tag --points-at {commit} Show all tags pointing to that commit

  • git show {tag-name} Show contents of the tag

Detached HEAD

Checking out to a specific commit or tag can create dangling commits, since they have no branches referencing them. Git will periodically garbage collect them
  • To prevent this, make a new branch for the dangling commit
    • git branch {branch-name} {commit}

Merging

  • Merges are types of commits

  • Fast forward

    • If git finds a clear path between the commit and branch then git will just move the HEAD pointer
    • This doesn't store the history of changes leading up to that commit
    • To retain history, force a merge commit: git merge --no-ff
  • Merge conflicts occur when there are competing changes to files

  • git rerere (Reuse, Recorded, Resolution) can save how a conflict was resolved and reuse that resolution for future conflicts

  • git config rerere.enabled true Enables git rerere, can use --global flag to enable for all projects

Logs

  • A good commit history preserves the code base and is useful for debugging/reviews
  • git log Display commit history of repository
  • git log --name-status --follow -- {file} Log files that have been moved/renamed
  • git log --grep {regex} Filter commit message fitting regular expression
  • git log --diff-filter={type} --stat Filter commits including/excluding the filter type
    • A - Added
    • D - Deleted
    • M - Modified

Commits

  • git commit -m {description} Snapshots working area, description should be thoughtful
  • git show {commit} Show commit information
  • git show {commit} --stat Shows number of changes in file
  • git show {commit}:{file} Look at file from another commit
  • git diff Show unstaged changes between commits, staging area and repository
  • git diff --staged Show staged changes
  • git branch --merged master Show which branches are merged with master and can be cleaned up
  • git branch --no-merged master Show which branches aren't merged with master

Checkout

  • Checkout can be used to restore working tree files, it changes HEAD to point at a new branch and copies the commit snapshot to the staging area
  • git checkout -- {file} Copy content from staging to working area, overwriting files
  • git checkout {commit} -- {file} Update staging area to match commit, then copies to working area to overwrite files
  • git checkout {deleting-commit}^ -- {file} Restore a deleted file based off the commit that it occurred, referencing the parent commit

Reset

  • git reset --soft HEAD~ Moves HEAD to the previous commit

  • git reset --mixed HEAD~ Can omit --mixed flag. Moves HEAD to the previous commit, then copies the files to the staging area

  • git reset --hard HEAD~ Moves HEAD to the previous commit, then copies the files to the staging and working area

    • This is a dangerous operation, it can overwrite files
  • git reset {file} Only moves file to staging area

  • git reset {commit} -- {file} Only moves file from a specific commit

  • git reset ORIG_HEAD Restores the original state, add --merge flag to preserve uncommitted changes

    • Useful when using git reset accidentally

Revert

  • Saves the commit that undos the previous changes, useful for commits that have accidentally been shared
  • History doesn't change and riginal commit is still in repository
  • git revert {commit} :

Amend

  • Can make changes to previous commit, doesn't 'edit' because the SHA1 hash will be different
  • Rather, a new commit containing the old changes is created and the old commit dangles
  • git commit --amend After adding changes to the staging area, the last commit will amend

Rebase

  • Pulls changes from master and apply commits on top by changing the parent of the commits

  • git rebase master Rebase from feature branch, rewinds HEAD to point at commit

  • git rebase -i {commit}^ Opens an interactive rebase editor

  • To amend arbitrary commits:

    • Add files
    • git commit --fixup {SHA1} Creates new commit with message starting with 'fixup!'
    • git rebase -i --autosquash {SHA1}^ References parent commit
  • git rebase -i -exec {tests} {commit} Run tests and stop rebase if a case fails

  • git rebase --abort Stops rebase before completion

  • git reset {branch} --hard Use if rebase 'succeeds' but something is working

    • Good idea to create a backup branch before rebasing

Remote

  • Remote is a git repository stored somewhere else, like the web or GitHub
  • Fork repository for pull requests
  • git clone {url} Clone repository to local machine
  • git remote -v View remote repository
  • git remote add upstream {url} Pull new changes from remote repository, not set by default
  • git push -u origin {branch} Push changes to branch
  • git fetch Pulls changes from remote repository, doesn't change local repository
  • git pull Performs fetch then merges with local repository
  • git pull --rebase Performs fetch and replays commits on top of local branch
  • git cherry -v Shows commits which haven't been pushed upstream