Git: Difference between revisions

From miki
Jump to navigation Jump to search
Line 33: Line 33:


== Terminology and Concepts ==
== Terminology and Concepts ==
; commit
: A commit is a snapshot of your working tree at some point in time. There are different ways to name a commit:
:* '''<tt>branchname</tt>''' &mdash; a branch name is an alias for most recent commit on that branch
:* '''<tt>tagname</tt>''' &mdash; similar to a branch alias, but that does not change in time
:* '''<tt>HEAD</tt>''' &mdash; currently checked out commit
:* '''<tt>c82a22c</tt>''' &mdash; the SHA-1 hash id of the commit (can be truncated as long as it remains unique)
:* '''<tt>name^</tt>''' &mdash; the parent of commit ''<tt>name</tt>''
:* '''<tt>name^^</tt>''' &mdash; the grand-parent of commit ''<tt>name</tt>'' (and so on)
:* '''<tt>name^2</tt>''' &mdash; the 2nd parent of commit ''<tt>name</tt>'' (and so on)
:* '''<tt>name~10</tt>''' &mdash; the 10th ancestor of commit ''<tt>name</tt>'' (same as <tt>name^^^^^^^^^^</tt>)
:* '''<tt>name:path</tt>''' &mdash; reference a specific file/directory in a given commit
:* '''<tt>name^{tree}</tt>''' &mdash; reference the tree held by a commit
:* '''<tt>name1..name2</tt>''' &mdash; a commit range, i.e. all commits reachable from ''<tt>name2</tt>'' back to, but no including, ''<tt>name1<tt>'' (if either name is omitted, use <tt>HEAD</tt> instead)
:* '''<tt>name1...name2</tt>''' &mdash; refers to all commits referenced by ''<tt>name1</tt>'' or ''<tt>name2</tt>'', but not by both. For <code>git diff</code>, refers to all commits between ''<tt>name2</tt>'' and the common ancestor of ''<tt>name1</tt>'' and ''<tt>name2</tt>''.
:* '''<tt>master..</tt>''' &mdash; to review changes made to the current branch
:* '''<tt>..master</tt>''' &mdash; after a <code>fetch</code>, to review all changes occured since last <code>rebase</code> or <code>merge</code>
:* '''<tt>--since="2 weeks ago"</tt>''' &mdash; all commits since a certain date
:* '''<tt>--until=”1 week ago”</tt>''' &mdash; all commits up to a certain date
:* '''<tt>--grep=pattern</tt>''' &mdash; all commits whose commit message matches the regular expression pattern.
:* '''<tt>--committer=pattern</tt>''' &mdash; all commits whose committer matches the pattern
:* '''<tt>--author=pattern</tt>''' &mdash; all commits whose author matches the pattern
:* '''<tt>--no-merges</tt>''' &mdash; all commits in a range that have only one pattern (i.e. ignore all merge commits)
; [http://sitaramc.github.com/concepts/detached-head.html detached head]
; [http://sitaramc.github.com/concepts/detached-head.html detached head]
: When <tt>HEAD</tt> is no longer a reference to anything (like <tt>ref: refs/heads/branch</tt>), but instead contains the actual hash of a commit.
: When <tt>HEAD</tt> is no longer a reference to anything (like <tt>ref: refs/heads/branch</tt>), but instead contains the actual hash of a commit.

Revision as of 22:49, 7 February 2011

References

Git cheat sheet

Introduction

Git Features:

  • Reliability
  • Performance
  • Distributed

Distributed

Originally from BitKeeper. Other distributed SCM is Mercurial.

  • No single repository. Everybody always has his own copy of the repository. The repository content is pulled from other people's repository.
  • No politics, no commit access control. All work is always done locally, so there is no need to define such politics.

Reliability

Every change, file, directory, etc. is cryptographically hashed (sha1sum).

  • Easy corruption detection. Any tampering to a file or directory content (either malicious or because of hardware failure) is immediately detected.
  • Easy distribution. Moreover because the repository is distributed all over the place, it is very easy to repair a given repository. You only need to drop all broken objects, and get all missing objects from a remote copy.

Performance

Very fast commit. Local repository

Terminology and Concepts

commit
A commit is a snapshot of your working tree at some point in time. There are different ways to name a commit:
  • branchname — a branch name is an alias for most recent commit on that branch
  • tagname — similar to a branch alias, but that does not change in time
  • HEAD — currently checked out commit
  • c82a22c — the SHA-1 hash id of the commit (can be truncated as long as it remains unique)
  • name^ — the parent of commit name
  • name^^ — the grand-parent of commit name (and so on)
  • name^2 — the 2nd parent of commit name (and so on)
  • name~10 — the 10th ancestor of commit name (same as name^^^^^^^^^^)
  • name:path — reference a specific file/directory in a given commit
  • name^{tree} — reference the tree held by a commit
  • name1..name2 — a commit range, i.e. all commits reachable from name2 back to, but no including, name1 (if either name is omitted, use HEAD instead)
  • name1...name2 — refers to all commits referenced by name1 or name2, but not by both. For git diff, refers to all commits between name2 and the common ancestor of name1 and name2.
  • master.. — to review changes made to the current branch
  • ..master — after a fetch, to review all changes occured since last rebase or merge
  • --since="2 weeks ago" — all commits since a certain date
  • --until=”1 week ago” — all commits up to a certain date
  • --grep=pattern — all commits whose commit message matches the regular expression pattern.
  • --committer=pattern — all commits whose committer matches the pattern
  • --author=pattern — all commits whose author matches the pattern
  • --no-merges — all commits in a range that have only one pattern (i.e. ignore all merge commits)
detached head
When HEAD is no longer a reference to anything (like ref: refs/heads/branch), but instead contains the actual hash of a commit.
git checkout -b newbranch           # To attach HEAD back on a new branch...
hunk
individual change within a file (basically a file diff output is made of a sequence of one or more hunks).

Install

Packages:

  • git-core — the main program
  • git-gui — a gui front-end
  • Web interface:
  • git-doc — documentation
  • Project management:

Other handy tools:

  • tig — a text-mode repository browser interface to git and color pager.
tig                                # launch browser
git show | tig                     # Use as pager. Colorize output of git-show

Configuring Git

References:

  • [htp://book.git-scm.com/5_customizing_git.html Git Community Boot - Customizing Git]
  • Git handy feedback on command-line

Global per-user configuration settings are stored in file ~/.gitconfig

  • Add color to git output for all commmands:
  • git config --global color.ui true
    
  • Define author/email
  • git config --global user.name "Your Name"
    git config --global user.email you@example.com
    

Tips - Working the git way

References:

  • Linus Torvalds [1]


  • Check project diff before commit -a:
  • git diff                          # First see what's in the working tree (or git status)
    git commit -a                     # Commit all changes
    
  • Give git commit a directory argument instead of using -a:
  • git commit fs/                     # Commit all changes in directory fs
    
  • Clean up an ugly sequence of commits ([2]).
  • Better than hunk-based commit because (1) each stage can be tested individually, (2) intermediate commits may contain changes that is not in the final one.
    1. First make sure that the ugly sequence is on some temporary branch target (what we aim for), and that end result is good and clean.
    2. Switch back to starting point, and do:
    3. git diff -R target > diff             # diff to target
      
    4. Edit diff file, to select only those changes we want to include in a first commit. Then do a git-apply diff
    5. Test, finalize the last changes before commits (redo git diff -R target if necessary).
    6. Commit, and repeat from step 2.