Git Toolbox

Setting up a new repository

  • git init [--bare] <PATH>
    • Adds a new git repository in the current folder
    • --bare means a repo with no working directory will be created

💍 Trying to make a commit?

  • git add -A <PATH>

    • add all changed (new, modified and deleted) files to staging area
    • <PATH> is optional, will include whole repository if left out
    • nice variants
      • git add --no-all <PATH> ignore deleted files
      • git add -u <PATH> ignore new files
  • git commit -m "<COMMENT>"

    • commit files in staged area with <COMMENT>
  • git commit --amend

    • Add current staged changes to previous commit with new message
  • git commit --amend -C HEAD

    • Reuse the previous commit message and add current staged changes to commit

🍒 Copying commit from one branch to another

Lets say that you have some commit in one branch, but you don't have it in another branch, and you don't want to merge the branches, then you can simplye extract that commit using git cherry-pick {commit-hash}

1
2
3
git log # to figure out commit that you need for example : 281eb6600f92564994293e57d1632ffc8e45acf2
git checkout some-branch-that-doesnt-have-that-commit
git cherry-pick 281eb6600f92564994293e57d1632ffc8e45acf2 # this will merge that specific commit into some-branch-that-doesnt-have-that-commit branch

📝 Working Directory management

Note

States of files in git repository: untracked files > unstaged changes > staged changes > commited changes

  • git status
    • show <CURRENT_BRANCH> and list showing which files are staged, unstaged, and untracked

🔍 Showing Code Differences with git diff

  • git diff <PATH>

    • show changes between unstaged and staged
    • <PATH> is optional, will show all files if left out
  • git diff --cached <PATH>

    • show changes between staged and last commit
    • <PATH> is optional, will show all files if left out
  • git diff HEAD <PATH>

    • show changes between unstaged (working directory) and last commit (this will include staged)
    • <PATH> is optional, will show all files if left out
  • git diff -w --word-diff-regex=[^[:space:]] master src

    • show changes between current branch and master
    • only show changes in the src directory
    • ignore all whitespace changes
  • git diff --name-status

    • show a list of files that are different
    • letter code to show how they are different
      • Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B).

Reset changes in working directory and/or staging area

  • git reset <PATH>

    • Remove <PATH> from staging area (does not affect working directory)
  • git reset --hard <PATH>

    • reset staging area and changes in working directory to latest commit (does not affect untracked files in working directory)
  • git reset --keep <PATH>

    • A safer option that reset --hard.
  • git clean -d(n|f|i) <PATH>

    • delete untracked files and untracked directories from the current directory
    • -d also directories
    • -n dry-run - don't do anything, only show what would be done if used with -f
    • -f force - git will delete only with -f (or -i)
    • -i interactive - ask before every file
  • git checkout -- <PATH>

    • reset changes in working directory to latest commit
  • git reset --soft HEAD@{1}

    • If you haven't pushed, to reset Git to the state it was in before you made your last commit (while keeping your staged changes)

🗃 Temporarily hiding working changes without a commit

Git's stash is a temporary holding area to hide away working changes if you need to quickly move them to one side while you perform another task.

Common use cases are if a pull would conflict with working changes, or if you have an emergency fix to apply.

  • git stash

    • Moves current working changes into the stash
  • git stash pop

    • Moves current stashed changes to the working directory

🔍 Getting info, history and comparisons of past commits

  • git log

    • show commits log
  • git log --graph

    • show commits log with graph displaying relationships
  • git log -S "string to find"

    • find a string in any commit message
  • git log --author=<NAME/EMAIL>

  • git log --committer=<NAME/EMAIL>

    • find commits by author or committer details
  • git show <REVISION>

    • show changes made by <REVISION> commit
    • <REVISION> is optional, will show last commit if left out
  • git diff [--name-status] <REVISION_1> <REVISION_2> <PATH>

    • show changes between <REVISION_1> and <REVISION_2>
    • <PATH> is optional, will show all files if left out
    • --name-status is optional, will show one line per file changed

🌵 Fun with branches!

  • git branch -v

    • list branches in local repository
  • git branch -a

    • list all branches local and remote
  • git checkout <BRANCH>

    • switch to <BRANCH> (by updating staging area, working directory, and pointing HEAD at <BRANCH>)
  • git checkout -b <NEW_BRANCH>

    • create <NEW_BRANCH> from <CURRENT_BRANCH> and switch to it
  • git diff [--name-status] <BRANCH>

    • Show the differences between your current branch and <BRANCH>
    • --name-status is optional, will show one line per file changed
  • git checkout -b <BRANCH> <COMMIT_SHA1>

    • create a branch from a commit
  • git branch -m new-name

    • rename the current branch

👌👈 Merge branches

  • git merge <BRANCH>

    • merge <BRANCH> into <CURENT_BRANCH>
    • save and close vim with :wq
  • git merge --abort

    • abort the current merge in progress

🏝 Remote repositories

  • git remote -v

    • show available remote repositories
  • git remote add <REMOTE_REPO> <REPO_URL>

    • <REMOTE_REPO>: give remote repository name used locally
    • <REPO_URL>: ssh://username@hostname.co.uk:9418/absolute/path/to/repository
  • git pull <REMOTE_REPO> <CURRENT_BRANCH>

    • Fetch <CURRENT_BRANCH> from <REMOTE_REPO> and merge it into <LOCAL_REPO>
  • git push <REMOTE_REPO> <CURRENT_BRANCH>

    • push <CURRENT_BRANCH> to <REMOTE_REPO>
  • git fetch <REMOTE_REPO> <REMOTE_BRANCH>

    • fetch commits from <REMOTE_BRANCH> in <REMOTE_REPO> into local repository
    • omit <REMOTE_BRANCH> to fetch all branches from <REMOTE_REPO>
    • fetched commits are stored as remote branches instead of local branches, i.e. it will not merge them into local branches unless you git pull <REMOTE_REPO> <CURRENT_BRANCH>
    • variants:
      • git fetch --all
        • fetch commits from all remote branches into local repository (carefull, this can make git branch -r uncomfortably long)

🐑🐑 Git clone

  • git clone <REPO> <PATH>
    • <REPO> The repository you are cloning.
    • <PATH> The path the repository will clone into.
      • If blank a new directory will be made.
      • Use . for current directory.
  • git clone ssh://user@some.domain:1234/file/path
    • This would clone with from a domain some.domain specifying a port 1234.
    • A password prompt would be required for the user user.

Git Tagging

  • git tag

    • list current tags
  • git tag -a 1.0 -m "my 1.0 git tag message"

    • create a new tag
  • git tag -a 1.0 a6b4c97498bd301d84096da251c98a07c7723e65

    • create a tag from a specified commit
  • git push origin 1.0

    • push your created tag to origin

⚙ Handy git configurations

  • git config --global color.ui auto
    • Adds colour to git's output: red for deletion, green for addition