Git Basics: Ab in die Shell

_images/gitcloud.png

Was ist git?

  • Ein Versionsverwaltungssystem
  • Ein Protokoll
  • Ein abstraktes Filesystem
  • Linus: A distributed stupid content tracker

Was ist es nicht?

  • CVS (WWCVSND)
  • SVN (CVS done right.)

Erklärung:

Linus on GoogleTalk.

Zentraler Workflow

_images/central.png

Dezentraler Workflow

_images/decentral.png

git init

$ mkdir your-repo && cd your-repo
$ git init .
$ ls --all
.  ..  .git
$ tree .git
.git
├── branches
├── config
├── HEAD
├── index
├── [...]
├── logs
│   ├── HEAD
│   └── refs
├── objects
└── refs

git add

$ git add [your-file-or-dir-here]
_images/untracked_to_staged.png

Alle Bereiche interaktiv als HTML:

http://ndpsoftware.com/git-cheatsheet.html

git commit

$ echo "Hello Phil!" > README
$ git add README
$ git status
# On branch master
# Changes to be committed:
#   new file:   README
$ git commit --all --message "commit message"  # ausgechrieben
$ git commit -am "commit message"              # oder kürzer
$ git commit -a                                # lange messages
[Editor öffnet sich]
$ git status
# On branch master
nothing to commit, working directory clean

Was ist ein diff?

Freunde von git commit

Früher oder später will man etwas berichtigen

# Letzte Commit-Messages berichtigen
# to amend == berichtigen.
$ git commit --amend
# Änderungen an einem file zurücksetzen
# Working Tree -> Unmodified
$ git checkout -- your_file.txt
# "git add" rückgängig machen
# Index -> Working Tree
$ git reset your_file.txt
$ git stash       # Änderungen kurz wegsichern
$ git stash pop   # … später wieder hervorholen

Die Objektdatenbank #1

Vier unterschiedliche Objekttypen:

_images/simple_tree.png

Die Objektdatenbank #2

_images/simple_commit.png

Die Objektdatenbank #3

_images/simple_branch.png

Git Branching

_images/branch.png

Branches #1

Branches erstellt man mit:

$ git checkout -b <branch-name>

In bestehende branches wechseln:

$ git checkout <branch-name>

Branches auflisten:

$ git branch --all

Branches #2

Branches führt man zusammen mit:

$ git merge <target-branch>

git clone

$ git clone git://github.com/studentkittens/git-und-die-wolke.git

Cloning into 'git-und-die-wolke'...
remote: Counting objects: 94, done.
remote: Compressing objects: 100% (72/72), done.
remote: Total 94 (delta 36), reused 72 (delta 16)
Receiving objects: 100% (94/94), 5.70 MiB | 1.60 MiB/s, done.
Resolving deltas: 100% (36/36), done.

git remote

Entfernte Repositories verwalten:

# Alle remotes auflisten
$ git remote -v
origin  git@github.com:studentkittens/git-und-die-wolke.git (fetch)
origin  git@github.com:studentkittens/git-und-die-wolke.git (push)
# Neues remote adden
$ git remote add nullcat git@nullcat.de
$ git remote -v
…
nullcat git@nullcat.de (fetch)
nullcat git@nullcat.de (push)
# Bestehendes remote verändern
$ git remote set-url nullcat https://git.nullcat.de

git push

$ git push [<remote> [<local-branch>]]
$ git push
$ git push origin
$ git push origin master
_images/push.jpg

git pull

Hilfe?!

git bisect #1

Source:

bool is_odd(int number) {
    return !number % 2; /* Wrong! */
}

int main(int argc, char *argv[]) {
    printf("Odd numbers of arguments? %d!\n",
        is_odd(argc - 1) ? "Yes" : "No");
}

Test case:

void test_is_odd(void) {
    for(int i = -20; i < 20; ++i) {
        assert((is_odd(i) != 0) == (i % 2 != 0));
    }
}

git bisect #2

Find by binary search the change that introduced a bug

Aufgabe:

  • Finde heraus wann ein Fehler eingeführt wurde.
  • Schaue dir an was damals geändert wurde.
  • Leite daraus ab was der Fehler ist.

Funktionsweise:

  • Festlegen eines good/bad commits
  • Auschecken der Mitte, Testen, Links oder Rechts weitersuchen.

git bisect #3

$ git bisect start HEAD HEAD^^^
$ git bisect run make test
# ... viel output von $(make test) ...
5145c8 is the first bad commit
'bisect run' erfolgreich ausgeführt
$ git bisect reset    # Kehre zur normalen Arbeit zurück
$ git show 5145c8     # Zeige unterschiede im bad commit
commit 5145c8781e30057c8e2058d1c361363e213a17f4
Date:   Fri May 3 15:47:38 2013 +0200

    Made is_odd() better looking

diff --git a/is_odd.c b/is_odd.c

 bool is_odd(int number)
 {
-    return number % 2 == 1;
+    return !number % 2;
 }

git bisect #4

Was lernt man draus?

  • Immer kleine Commits machen!

  • Nehmt euch Zeit für eine sinnvolle Commit-Messages! Schlechte Beispiele (*):

    • Some changes - Riesiger diff.
    • minor changes - Complete Rewrite.
    • Merge. - Manuelles Merging.
  • git bisect ist ein gutes Argument für Unit-Tests.

* (Noch mehr davon: http://whatthecommit.com/)

Suchen und Beschuldigen

Suche background: in allen .css Dateien.

$ git grep -n 'background:' -- '*.css'
src/custom.css:56: background: -webkit-radial-gradient(#9cf, #369);
src/custom.css:57: background:    -moz-radial-gradient(#9cf, #369);
src/custom.css:58: background:         radial-gradient(#9cf, #369);

Herausfinden wer wann etwas geändert hat:

$ git blame -L 56,58 src/custom.css
# SHA1   (Autor LN) Content
77a79bbc (Elch  56) background: -webkit-radial-gradient(#9cf, #369);
64ac73cb (Katze 57) background:    -moz-radial-gradient(#9cf, #369);
77a79bbc (Elch  58) background:         radial-gradient(#9cf, #369);

→ Der Autor Katze ist für den Mozilla-Support zuständig.

git tag

Das GitFlow Branching Modell

_images/gitflow.png

---

---

_images/yoda.png

Tooling

Plugins

Standalone Tools

Best Practices #1

Best Practices #2

……

_images/af.jpg

git fetch

git rebase #1

Ausgangszustand:

_images/gitrebase-1.png

git rebase #2

Ohne Rebase, mit git merge:

$ git checkout master
$ git merge experiment
_images/gitrebase-2.png

git rebase #3

Mit Rebase:

$ git checkout experiment  # In 'experiment' wechseln
$ git rebase master        # Basis auf master verschieben
$ git checkout master      # In 'master' wechseln
$ git merge experiment     # Fast-Forward Merge zu 'experiment'
_images/gitrebase-3.png

---

---

_images/thanksobama.jpg

Ein Exkurs zu Storage as a Service mit git







SaaS mit git-annex: Git Annex: Dropbox fuer Harte