git archive master | bzip2 > project.tar.bz2

if a particular version of a file is in the git directory, it’s considered committed
if it’s modified but has been added to the staging_area, it is staged
if it was changed since it was checked out but has not been staged, it is modified

                                |     |
                                |     |
                                Λ     V
    +------------+           +-----------+           +--------------+
    +------------+           +-----------+           +--------------+
           Λ                                                |
            ------------------- checkout ------------------- 

to remove a file from Git, you have to remove it from your staging_area and then commit
the 'git rm' command does that and also removes the file from your working_area

if you modified the file and added it to the stage_area already, you must force the removal with the -f option
this is a safety feature to prevent accidental removal of data that hasn’t yet been recorded in a snapshot

you may want to keep the file on your hard drive but not have Git track it anymore
to do this, use the --cached option

if you want to rename a file in Git, you can run something like this:
$> git mv file_from file_to


if you use filename then git copies this file from commit_area into working_area AND into staging_area

git checkout HEAD~0 foo.c

it copies file 'foo.c' from the parent of the current commit

if you don't use commit name then file will be copied from staging_area to working_area

git checkout foo.c

to hop to an old state briefly:

$> git checkout 82f5[...]

this takes you back in time, while preserving newer commits. however, like time travel in a science-fiction movie, if you now edit and commit, you will be in an alternate reality, because your actions are different to what they were the first time around. this alternate reality is called "branch"

you can choose only to restore particular files and subdirectories by appending them after the command:

$> git checkout 82f5[...] some.file another.file

if you don't use file name, no commit name, no old branch name, but

you will have "detached HEAD" as result

now if you switch to master branch you will lost your detached HEAD. if you want to save this branch you can create on it basis the new branch:

git checkout -b newnamebranch


between working_area | staging_area since last 'git add '

> git diff

note that it doesn't show all changes made since your last commit — only changes that are still unstaged

between working_area | staging_area since last 'git commit '

> git diff --cached

you can see what is about to be committed

between last_commit | working_area

> git diff HEAD


git stash let you save your local uncommitted changes, and reset working area to HEAD~0 receiving clean working copy

after receiving from origin repo (with all new commits)
you take your hidden changes
and put them in new working area by command git stash apply

after that you kill your stash by command git stash drop

save your local modifications to a new stash

> git stash
> git stash save

restore the changes recorded in the stash on top of the current working tree state

> git stash apply

restore the changes from the most recent stash, and remove it from the stack of stashed changes

> git stash pop

list all current stashes

> git stash list

show the contents of a stash (accepts all diff args):

> git stash show -p

delete the stash

> git stash drop [stash-name]

delete all current stashes

> git stash clear

unmodifying a modified file

what if you realize that you don’t want to keep your changes to the file?

how can you easily unmodify it - revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working_area)?

$> git checkout -- somefilename

you should also realize that this is a dangerous command: any changes you made to that file are gone — you just have written another file over it

so never use this command unless you are absolutely sure that you don’t want the current file content anymore

so if I commit the original patch for X and then immediately realize: "I need to make a fix, before I start working on Y". it’s easy:

$> vim A # implement X $> git commit -m 'Implemented X' # apply patch # discover problem in X $> vim A # fix X $> git commit --amend # amend original patch

more typically, it’s only while I’m working on Y that I’ll realize I need to fix X then it’s more complicated to amend the original commit:

$> vim A # implement X $> git commit -m 'Implemented X' # applay patch $> vim B # start working on Y # discover problem in X $> git stash # stash away half-completed work on Y $> vim A # fix X $> git commit --amend # amend original patch for X $> git stash apply # restore work on Y $> vim B # continue working on Y


undo the last 'git add ...' commands
remove changes from stage but keep them in the working area :

$> git reset --soft

redo previous commit
including changes you've staged (by commands 'git add <>) in the meantime :

$> git commit --amend

undo the last commit
and erase all newer commits permanently :

$> git reset --hard

server repo

$> git clone --bare . mystuff.git
$> scp -r mystuff.git
$> git remote add someremname

after that you can:

$> git push someremname
$> git pull someremname branchname

repository on USB

$> cd /path/to/your/repository
$> mkdir /path/to/usb/stick/repository.git
$> git clone --bare . /path/to/usb/stick/repository.git
$> git remote add usb file:///path/to/usb/stick/repository.git
$> git push usb master

$> git push usb

mount the USB stick, and use a file URL for the repository:

cloning the repository on the USB stick

$> git clone file:///path/to/usb/stick/repository.git

> git log --graph --pretty=oneline
> git log --before='MM DD YYYY'
> git log --after='MM DD YYYY'


the rules for the patterns you can put in the .gitignore file are as follows:

  • - blank lines or lines starting with # are ignored
  • - standard patterns work
  • - you can end patterns with a forward slash (/) to specify a directory
  • - you can negate a pattern by starting it with an exclamation point (!)

    patterns are like simplified regular expressions that shells use:

  • - an asterisk * matches zero or more characters
  • - [abc] matches any character inside the brackets (in this case a, b, or c)
  • - a question mark ? matches a single character
  • - brackets enclosing characters separated by a hyphen [0-9] matches any character in the range (in this case 0 through 9)


    command functionality useful command useful functionality
    git branch foo creates but does nothing with it git checkout -b foo creates branch and switches to it
    git remote shows names of remotes git remote -v shows names and URLs of remotes
    git stash stores modifications to tracked files git stash -u also does the same to untracked files
    git branch lists names of local branches git branch -rv lists local and remote tracking branches;
    shows latest commit message
    git rebase destroy history blindfolded git rebase -i lets you rewrite the upstream history, choosing which commits to keep, squash or ditch
    git reset foo unstages files git reset ––hard
    git reset ––soft
    discards local modifications
    returns to another commit, but doesn’t touch working_area.
    git add nothing – prints warning git add .
    git add -A
    stages all local modifications/additions
    stages all local modifications/additions/deletions