Git Notes


Git Notes

Data in Git is like a set of snapshots of a mini filesystem, every commit is a snapshot of all the files at the moment, with reference stored for that snapsthot; Files that have not changed aren’t stored - instead just a link to the previous identical file that has been stored already.

Three States

Git has three main states for files:

Above states are reflected as three main sections of a Git project


Configuration at each level overrides values in the previous level.

Set Identity

Setting username and e-mail address:

git config --global "Name"
git config --global ""


git config --global core.editor vim

Diff Tool

git config --global merge.tool vimdiff

Check Settings

git config --list

Same keys in the config list may appear more than once because Git reads configurations from different files, the last value is used for each unique key.

Check the value for a particular key:

git config


Track existing project in Git:

git init

Adding files to version control:

git add *.swift
git add
git commit -m "Initial commit"

Clone existing repository:

git clone [REPO URL]

Which clones the project into a direcotry with repository name by default, to clone to a different directory:

git clone [REPO URL] [DIRECTORY]

Each file in working directory can be:

Checking status:

git status

Track file:

git add file

It’s a multipurpose command for tracking new files, staging files and other things like marking merge-conflicted files as resolved. If a file is modified after git add, it has to be added again to stage the latest version of the file.

Ignoring Files

Ignore all files with suffix .o or .a, all files that end with a tilde:

cat .gitignore
!lib.a  # do track lib.a, even though it's ignored before
build/  # everything inside build directory are ignored

Glob pattern:

Viewing Exact Changes

git diff compares what is in working directory with what is in staging area, showing the changes that haven’t been staged yet. If all changes are staged, git diff shows no output.

git diff --cached or git diff --staged (for Git 1.6.1 or later) compares staged changes to last commit.

Committing Changes

To commit staged changes:

git commit

This would launch pre-specified editor. To type commit message inline:

git commit -m "message"

To stage every file that is already tracked without git add:

git commit -a

Remove Files

To remove a file from Git, remove it from tracked files (staging area) and then commit. Removing the file (ie. rm file) would show up as “Changed but not updated”, then git rm file makes it “Changes to be committed”.

If a file has been modified and added to the index (ie. staged), Git need a force removal (-f) to remove the file, this is a feature to prevent accidental removal of data.

To keep the file in working tree but remove it from staging area:

git rm --cached file

It supports files, directories and file-glob patterns.

e.g. remove all .log files in log directory:

git rm log/\*.log (the backslash is necessary because Git does its own filename expansion in addition to shell’s filename expansion)

Moving Files

Git doesn’t track file movments, if a file is renamed, no metadata is stored for this fact but Git is smart enough to figure out.

Git has a mv command:

git mv from_file to_file

Git treats this as a rename, and this is equivalent to:

mv from_file to_file
git rm from_file
git add to_file

Viewing the Commit History

git log

git log -p -2

git log --stat

git log --pretty=oneline

author vs committer

Limiting Log Output


git log --pretty="%h:%s" --author=someone --since="2020-01-01" --before="2020-04-01" --no-merges -- sources/

Undoing Things

git commit --amend

Forgot Changes

git commit -m "my commit"
git add forgotten.txt
git commit --amend

Unstage a Staged File

git reset HEAD staged_file


git restore --staged file

Reset a Modified File

git checkout -- modified_file

Working with Remote

Remote repositories are versions of projects that are hosted on remote network.

Show Remote

Add Remote Repositories

git remote add shortname url

Fetching and Pulling

git fetch shortname

git pull

Pushing to Remotes

git push [remote-name] [branch-name]


git push origin master

Inspecting a Remote

git remote show origin

* remote origin
  URL: git://
  Remote branch merged with 'git pull' while on branch master
  Tracked remote branches

More complex example:

$ git remote show origin
* remote origin
  Remote branch merged with 'git pull' while on branch issues
  Remote branch merged with 'git pull' while on branch master
  New remote branches (next fetch will store in remote/origin)
  Stale tracking branches (use 'git remote prune')
  Tracked remote branches
  Local branch pushed with 'git push'

Above information shows:

Removing and Renaming Remotes

git remote rename old_name new_name

git remote rm name


Listing Tags

git tag

You can also search tags:

git tag -l v1.2.*

Createing Tags

Annotated Tags

`git tag -a v1.1 -m “release version 1.1”

git show v1.1
tag v1.1
Tagger: Full Name <>
Date: xxx
release version 1.1
commit <commit hash>
Merge: merge hashes
Author: Developer Name <>
Date: <date>

  Merge branch 'test'

Signed Tags

git tag -s v1.2 -m "signed release 1.2 tag"
You need a passphrase to unlock the secret key for user: "User Name <>"
1024-bit DSA key, ID F12C123, created 2020-02-01
git show v1.2
tag v1.2
Tagger: User Name <>
Date: <Date>

signed release 1.2 tag
Version: GnuPG v1.4.8 (Darwin)

<long signature here>
commit <commit hash>
Merge <commit hashes>
Author: Developer Name <>
Date: <Date>

  Merge branch 'test'

Lightweight Tags

Lightweight tags are basically commit checksums stored in a file without other information.

git tag v2.0
git tag
git show v2.0
commit <commit hash>
Merge: <commit hashes>
Author: Developer Name <>
Date: <date>

  Merge branch 'test'

Verifying Tags

Use GPG to verify the signature:

git tag -v [tag-name]

Tagging Commits in the Past

git tag -a v2.1 <commit hash>

Sharing Tags

git push origin v2.1

To push all tags:

it push origin --tags

Tips and Tricks


Git comes with auto-completion script in its source contrib/completion directory, copy it to home directory and add below to .bashrc file:

source ~/.git-completion.bash

To set up auto-completion for all users, copy the script to /opt/local/etc/bash_completion on Mac or /etc/bash_completion.d/ on Linux.

Git Aliases

Set up alias for commands using git config, for example:

git config --global checkout
git config --global branch
git config --global commit
git config --global status

(instead of git commit, you can use git ci, etc)

git config --global alias.unstage 'reset HEAD --'

is equivalent to:

git unstage fileA
git reset HEAD fileA

git config --global alias.last 'log -1 HEAD'

this makes it easy to see last commit:

git last

Git Branching

Branching is when you diverge from the main development line and continue to work without touching the main line.

Single Commit Diagram

C1 (tree, author, committer, messsage, etc)
+- tree (blob -> file/size)
    +- blob1 (file content)
    +- blob2 (file content)
    +- blob3 (file content)

Multiple Commits Diagram

C3 -> C2 -> C1

After commiting in testing branch:

C4 ->  C3 -> C2 -> C1

After checking out master:

C4 ->  C3 -> C2 -> C1

After adding commit to master:

   C3 -> C2 -> C1

Basic Branching and Merging

Create Branch

git checkout -b feature

is the same as:

git branch feature
git checkout feature

Switching to master branch and merge feature branch in:

git checkout master
git merge feature
Updating <hash>..<hash>
Fast forward
 file | 1 -
 X file changed, Y insertions(+), Z deletions(-)

To delete branch:

git branch -d feature

When development history has diverged from some older point:

       C5 -> C3
                C2 -> C1 -> C0
   master -> C4
git checkout master
git merge feature
       C5 -> C3
                C2 -> C1 -> C0
   master -> C4

Snapshot to merge into: master (C4)
Snapshot to merge in: feature (C5)

          C5 -> C3
          / \     \
           |       C2 -> C1 -> C0
           |       /
master --- C6 -> C4
git merge feature
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automerge failed; fix conflicts and then commit the result.

Git adds standard conflict-resolution markers to the files that have conflicts:

<<<<<<< HEAD:file.txt
Support email:
Support email:
>>>>>>> feature:file.txt

Branch Management

See a simple list of current branches:

$ git branch
* master

See last commit on each branch:

$ git branch -v
  feature <hash> message
* master <hash> Merge branch 'feature'

See the list of merged branches: git branch --merged

See the list of branches that haven’t been merged: git branch --no-merged