git-book.md 8.9 KB

Git Book

Git Book

Chapter 1: Getting Started

  • Git tracks snapshots, not differences (virtual filesystem)
  • Nearly every operation is local
  • Has integrity included
  • Generally only adds data

Three states

Working Directory Staging area .git repository
<= = checkout= =<
stage >= =>
commit >= =>

First time setup

  • Global: /etc/gitconfig
  • Per-user: .gitconfig
  • Per-project: .git/config

    $ git config --global user.name "John Doe"
    $ git config --global user.email johndoe@example.com
    $ git config --global core.editor vim
    $ git config --list
    

Get help

  • git help 'verb'
  • git 'verb' --help
  • man git-'verb'

Chapter 2: Git Basics

Getting a Repository

  • New repositor: $ git init
  • Clone existing: $ git clone https://github.com/libgit2/libgit2 [mygitlib]

Reordering Changes

Untracked Unmodified Modified Staged
add the file >= == == =>
edit the file >= =>
stage the file >= =>
<= =< remove the file
<= == =< commit the file
  • Checking the status: $ git status
  • Adding file(s) $ git add . $ git add README.md $ git add *.c
  • Staging modified files $ git add modified.file
  • The same file can be staged and unstaged, if it was edited after staging!
  • Short status git status -s
    • Left letter: status of the staging area
    • Right letter: status of the working tree
    • ??: untracked
    • A : added to the staging area
    • MM: modified, staged, modified again
    • M: modified, not yet staged
    • M : modified and staged
  • ignore files over .gitignore Examples:
    • *.a: no a-files...
    • !lib.a: ...except for lib.a
    • /TODO: ignore TODO in the current directory, but not in other directories
    • build/: ignore all files in the build directory
    • doc/*.txt: ignore txt files in the doc directory
    • doc/**/*.pdf: ignore txt files in doc and all its subdirs

View staged and unstaged changes

  • See unstaged changes: $ git diff
  • See staged changed: $ git diff --staged or $ git diff --cached

Committing your changes

  • Commit staged files: $ git commit or $ got commit -m "my message"
  • Skip the staging area: $ git commit -a -m "my message"
    • it's equivalent to git add . followed by $ git commit -m "my message"

Removing files

  • $ git rm removes files from the staging area and removes it from the drive.
  • if you first remove a file with $ rm the change will be recorded. You must still type $ git rm to remove it from the stage area before committing.
  • if you modified a file and already added it to the staging area, you must use -f to force the removal. This is a security feature, because the data couldn't be recovered by git.
  • You can remove files from the staging area but keep it on the drive (e.g. if you forgot to put them in .gitignore). $ git rm --cached

Moving files

  • Git is smart about file moves. therefore the two options are equivalent:
    • $ git mv a b
    • $ mv a b followed by $ git rm a && git add b

Viewing the history

  • Generally with $ git log
  • show diffs of changes and limit to last N entries: $ git log -p -N
  • show abbreviated stats: $ git log --stat
  • use --pretty=keyword option. Keywords are

    • oneline
    • short
    • full
    • fuller
    • format

      $ git log --pretty=format:"%h - %an, %ar : %s"
      %H, %h:   Commit hash, abbrev. commit hash
      %T, %t:   Tree hash, abbrev. tree hash
      %P, %p:   Parent hash, abbrev. parent hash
      %an, %ae: Author name, author email
      %ad, %ar: Author date, author date, relative
      %cn, %ce: Committer name, committer email
      %cd, %cr: Committer date, committer date, relative
      %s:       Subject
      
  • Show graph: git log --pretty=format:"%h %s" --graph

  • other options:

    • -(n) show only the last n commits
    • --since, --after Limit to commits after a date
    • --until, --before Limit to commits before a date
    • --author Filter by author
    • --committer Filter by committer
    • --grep Filter by content of the commit string
    • -S Only show commits adding or removing code matching the string

Undoing things

  • You forgot to stage some files. Use $ git commit --amend to commit remaining files. Works only, if no changes were made since last commit.
  • Unstage a staged file: $ git reset HEAD <file>
  • Unmodify a modify file: 'git checkout -- <file>. Consider branching or stashing instead.

Working with remotes

  • Showing repositories: $ git remote -v
  • Adding remotes: $ git remote add <handle> <url>
  • Fetching from remotes (receive data you don't have yet): $ git fetch <handle>
  • Pulling from remotes (fetching and merging): $ git pull <handle>
  • Fetching and pulling by default works on tracked remote branches.
  • Pushing to remotes: $ git push origin master
  • Show information about a remote: $ git remote show origin
    • Fetch URL
    • Push URL
    • HEAD branch
    • Remote branches
    • Local branch configured for 'git pull'
    • Local ref configured for 'git push'
  • Renaming remotes: $ git remote rename pb paul
  • Removing remotes: $ git remote remove paul

Working with tags

  • listing tags: $ git tag
  • listing tags of a series: $ git tag -l "v1.8.5*"
  • There are two types of tags:
    • lightweight
    • annotated
  • A lightweight tag is like a branch that doesn't change.
  • An annotated tag is checksummed, contains tagger name, email and date. They have a tagging message and can be signed with GPG.
  • -m specifies the tag message.
  • creating an annotated tag: $ git tag -a v1.4 -m "my version 1.4"
  • creating a lightweight tag: $ git tag v1.4-lw
  • show information about a tag: $ git show v1.4
  • You can tag after other commits have been made:

    $ git log --pretty=oneline
    15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
    a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
    0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
    
    $ git tag -a v1.2 a6b4c9
    
  • sharing tags with remotes: $ git push origin v1.5

  • to push all tags at once: $ git push origin --tags

  • You can't check out tags in git. You must checkout a branch at a specific tag:

    • $ git checkout -b version2 v2.0.0

Aliases

  • Can be done with $ git config --global alias.co checkout
  • or in the .gitconfig file
  • usefull aliases:
    • co checkout
    • br branch
    • ci commit
    • st status
    • unstage reset HEAD --
    • last log -1 HEAD
    • visual !gitk

Chapter 3: Git Branches

What are branches

  • When committing, git stores an object with:
    • pointer to the snapshot of the content you staged
    • authors name and email
    • the message you typed
    • pointers to the commit(s) that directly came before this commit (parents)
    • zero parents for initial commit
    • one parent for normal commits
    • multiple parents for merges
  • Therefore, in git a branch is a lightweight pointer to one of these commits
  • The default branch name is master

Working with branches

  • Creating a new branch $ git branch testing
    • creates a new pointer to the same commit
  • HEAD is a special pointer that points at the commit you're currently on
  • Switch branches $ git checkout testing
    • This moves the HEAD cursor to testing
  • Creating a branch is lightweight (writing the 40byte hash + a newline to a file)
  • Shorthand for branching and switching $ git checkout -b testing
  • Switching is not allowed, if there are uncommitted changes in a branch

Basic merging

  • Merge another branch into the current one: $ git merge testing
  • If a file was edited in more than one branch, a conflict will result and needs to be resolved before the next checkin.
  • you can manually resolve the conflict or use $ git mergetool
  • After the resolution, you can commit the changes.

Branch management

  • $ git branch gives a list of current branches.
  • $ git branch -v gives the same list, but with the latest commit messages.
  • To see what branches are already merged, use $ git branch --merged
  • To see what branches that haven't been merged yet, use $ git branch --un-merged
  • Deleting branches that haven't been merged fails.

Branching workflows

  1. Long running branches
    • Used like different levels of hierarchy
    • Basically one long linear line of commits, branches used as tags.
    • Can be used to achieve different levels of stability
  2. Topic branches
    • Branches diverge at any point
    • allows to context-switch quickly
    • can keep different parts of development isolated for longer times
    • more challenging to merge.

Remote branches

  • Show remote references like branches and tags: $ git remote show [remote]
  • Remote-tracking branches are references to the state of remote branches.
    • They're moved every time you do a network communication.