├── styles ├── .gitignore ├── toc.after.html ├── toc.before.html ├── dblatex.sty ├── chunked.xsl ├── common.xsl └── gitbuch.css ├── .gitignore ├── bilder_ebook ├── clone.png ├── fetch.png ├── gitk.png ├── graph.png ├── index.png ├── pull.png ├── push.png ├── sha.png ├── tags.png ├── bsp-ff.png ├── commit.png ├── objekte.png ├── zentral.png ├── bsp-no-ff.png ├── ff-nachher.png ├── ff-vorher.png ├── gitk-basic.png ├── struktur.png ├── svn_rebase.png ├── tux-diff.png ├── branch-model.png ├── git-dir-crop.png ├── mail-thread.png ├── meld-example.png ├── pull_rebase.png ├── svn_dcommit.png ├── cgit-commitdiff.png ├── cgit-overview.png ├── git-gui-blame.png ├── github-download.png ├── github-gollum.png ├── github-network.png ├── github-workflow.png ├── gitweb-overview.png ├── graph-mit-refs.png ├── merge-nachher.png ├── rebase-nachher.png ├── rebase-vorher.png ├── relative-refs.png ├── tag-screenshot.png ├── developer-public.png ├── git-branches-crop.png ├── gitweb-commitdiff.png ├── merge-base-commit.png ├── patches-per-mail.png ├── stash-screenshot.png ├── svn-branches-crop.png ├── describe-screenshot.png ├── ff-no-ff-vergleich.png ├── git-svn-merge-demo.png ├── objekte-zusammenhang.png ├── rebase-onto-nachher.png ├── rebase-onto-vorher.png ├── remote-tracking-gitk.png ├── svn-stdlayout-crop.png ├── git-convert-refs-after.png ├── git-svn-tag-fix-after.png ├── git-svn-tag-fix-before.png ├── github-image-diff-2up.png ├── svn-nonstdlayout-crop.png ├── git-convert-refs-before.png ├── github-image-diff-swipe.png ├── gitk-screen-format-patch.png ├── screenshot-rebase-nachher.png ├── screenshot-rebase-vorher.png ├── objektmodell-programm-crop.png └── revision-list-commit-graph-gitk.png ├── asciidoc.conf ├── bilder_quelldaten ├── diagramme │ ├── clone.dia │ ├── fetch.dia │ ├── graph.dia │ ├── index.dia │ ├── pull.dia │ ├── push.dia │ ├── sha.dia │ ├── tags.dia │ ├── commit.dia │ ├── objekte.dia │ ├── zentral.dia │ ├── ff-nachher.dia │ ├── ff-vorher.dia │ ├── struktur.dia │ ├── svn_rebase.dia │ ├── branch-model.dia │ ├── pull_rebase.dia │ ├── svn_dcommit.dia │ ├── github-workflow.dia │ ├── graph-mit-refs.dia │ ├── merge-nachher.dia │ ├── rebase-nachher.dia │ ├── rebase-vorher.dia │ ├── relative-refs.dia │ ├── developer-public.dia │ ├── merge-base-commit.dia │ ├── patches-per-mail.dia │ ├── objekte-zusammenhang.dia │ ├── rebase-onto-nachher.dia │ ├── rebase-onto-vorher.dia │ ├── EXPORTING │ ├── global-sw-map │ ├── Makefile │ └── remap-sw ├── screenshots │ ├── gitk.png │ ├── bsp-ff.png │ ├── tux-diff.png │ ├── bsp-no-ff.png │ ├── gitk-basic.png │ ├── cgit-overview.png │ ├── git-gui-blame.png │ ├── github-gollum.png │ ├── mail-thread.png │ ├── meld-example.png │ ├── cgit-commitdiff.png │ ├── github-download.png │ ├── github-network.png │ ├── gitweb-overview.png │ ├── tag-screenshot.png │ ├── ff-no-ff-vergleich.png │ ├── git-svn-merge-demo.png │ ├── gitweb-commitdiff.png │ ├── stash-screenshot.png │ ├── describe-screenshot.png │ ├── remote-tracking-gitk.png │ ├── git-convert-refs-after.png │ ├── git-convert-refs-before.png │ ├── git-svn-tag-fix-after.png │ ├── git-svn-tag-fix-before.png │ ├── github-image-diff-2up.png │ ├── github-image-diff-swipe.png │ ├── gitk-screen-format-patch.png │ ├── screenshot-rebase-nachher.png │ ├── screenshot-rebase-vorher.png │ └── revision-list-commit-graph-gitk.png └── dir-listing │ ├── git-dir-crop.png │ ├── git-branches-crop.png │ ├── svn-branches-crop.png │ ├── svn-stdlayout-crop.png │ ├── svn-nonstdlayout-crop.png │ ├── objektmodell-programm-crop.png │ ├── template.tex │ ├── svn-stdlayout.tex │ ├── objektmodell-programm.tex │ ├── git-branches.tex │ ├── svn-branches.tex │ ├── svn-nonstdlayout.tex │ ├── git-dir.tex │ ├── Makefile │ ├── dirtree.sty │ └── dirtree.tex ├── TODO ├── git.txt ├── asciidoc-pdf.conf ├── Makefile ├── README.md ├── installation.txt ├── github.txt ├── gitdir.txt ├── vorwort.txt ├── workflows.txt ├── shell.txt └── erste_schritte.txt /styles/.gitignore: -------------------------------------------------------------------------------- 1 | toc.html 2 | -------------------------------------------------------------------------------- /styles/toc.after.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.sw[nop] 2 | *.html 3 | *~ 4 | *.xml 5 | git.chunked/ 6 | *.epub 7 | git.pdf 8 | -------------------------------------------------------------------------------- /styles/toc.before.html: -------------------------------------------------------------------------------- 1 |
2 |

Startseite

3 | -------------------------------------------------------------------------------- /bilder_ebook/clone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/clone.png -------------------------------------------------------------------------------- /bilder_ebook/fetch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/fetch.png -------------------------------------------------------------------------------- /bilder_ebook/gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/gitk.png -------------------------------------------------------------------------------- /bilder_ebook/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/graph.png -------------------------------------------------------------------------------- /bilder_ebook/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/index.png -------------------------------------------------------------------------------- /bilder_ebook/pull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/pull.png -------------------------------------------------------------------------------- /bilder_ebook/push.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/push.png -------------------------------------------------------------------------------- /bilder_ebook/sha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/sha.png -------------------------------------------------------------------------------- /bilder_ebook/tags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/tags.png -------------------------------------------------------------------------------- /bilder_ebook/bsp-ff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/bsp-ff.png -------------------------------------------------------------------------------- /bilder_ebook/commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/commit.png -------------------------------------------------------------------------------- /bilder_ebook/objekte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/objekte.png -------------------------------------------------------------------------------- /bilder_ebook/zentral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/zentral.png -------------------------------------------------------------------------------- /asciidoc.conf: -------------------------------------------------------------------------------- 1 | [replacements] 2 | (^-- )=–  3 | (\n-- )|( -- )|( --\n)= –  4 | -------------------------------------------------------------------------------- /bilder_ebook/bsp-no-ff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/bsp-no-ff.png -------------------------------------------------------------------------------- /bilder_ebook/ff-nachher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/ff-nachher.png -------------------------------------------------------------------------------- /bilder_ebook/ff-vorher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/ff-vorher.png -------------------------------------------------------------------------------- /bilder_ebook/gitk-basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/gitk-basic.png -------------------------------------------------------------------------------- /bilder_ebook/struktur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/struktur.png -------------------------------------------------------------------------------- /bilder_ebook/svn_rebase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/svn_rebase.png -------------------------------------------------------------------------------- /bilder_ebook/tux-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/tux-diff.png -------------------------------------------------------------------------------- /bilder_ebook/branch-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/branch-model.png -------------------------------------------------------------------------------- /bilder_ebook/git-dir-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-dir-crop.png -------------------------------------------------------------------------------- /bilder_ebook/mail-thread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/mail-thread.png -------------------------------------------------------------------------------- /bilder_ebook/meld-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/meld-example.png -------------------------------------------------------------------------------- /bilder_ebook/pull_rebase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/pull_rebase.png -------------------------------------------------------------------------------- /bilder_ebook/svn_dcommit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/svn_dcommit.png -------------------------------------------------------------------------------- /bilder_ebook/cgit-commitdiff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/cgit-commitdiff.png -------------------------------------------------------------------------------- /bilder_ebook/cgit-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/cgit-overview.png -------------------------------------------------------------------------------- /bilder_ebook/git-gui-blame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-gui-blame.png -------------------------------------------------------------------------------- /bilder_ebook/github-download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/github-download.png -------------------------------------------------------------------------------- /bilder_ebook/github-gollum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/github-gollum.png -------------------------------------------------------------------------------- /bilder_ebook/github-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/github-network.png -------------------------------------------------------------------------------- /bilder_ebook/github-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/github-workflow.png -------------------------------------------------------------------------------- /bilder_ebook/gitweb-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/gitweb-overview.png -------------------------------------------------------------------------------- /bilder_ebook/graph-mit-refs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/graph-mit-refs.png -------------------------------------------------------------------------------- /bilder_ebook/merge-nachher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/merge-nachher.png -------------------------------------------------------------------------------- /bilder_ebook/rebase-nachher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/rebase-nachher.png -------------------------------------------------------------------------------- /bilder_ebook/rebase-vorher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/rebase-vorher.png -------------------------------------------------------------------------------- /bilder_ebook/relative-refs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/relative-refs.png -------------------------------------------------------------------------------- /bilder_ebook/tag-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/tag-screenshot.png -------------------------------------------------------------------------------- /bilder_ebook/developer-public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/developer-public.png -------------------------------------------------------------------------------- /bilder_ebook/git-branches-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-branches-crop.png -------------------------------------------------------------------------------- /bilder_ebook/gitweb-commitdiff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/gitweb-commitdiff.png -------------------------------------------------------------------------------- /bilder_ebook/merge-base-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/merge-base-commit.png -------------------------------------------------------------------------------- /bilder_ebook/patches-per-mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/patches-per-mail.png -------------------------------------------------------------------------------- /bilder_ebook/stash-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/stash-screenshot.png -------------------------------------------------------------------------------- /bilder_ebook/svn-branches-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/svn-branches-crop.png -------------------------------------------------------------------------------- /bilder_ebook/describe-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/describe-screenshot.png -------------------------------------------------------------------------------- /bilder_ebook/ff-no-ff-vergleich.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/ff-no-ff-vergleich.png -------------------------------------------------------------------------------- /bilder_ebook/git-svn-merge-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-svn-merge-demo.png -------------------------------------------------------------------------------- /bilder_ebook/objekte-zusammenhang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/objekte-zusammenhang.png -------------------------------------------------------------------------------- /bilder_ebook/rebase-onto-nachher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/rebase-onto-nachher.png -------------------------------------------------------------------------------- /bilder_ebook/rebase-onto-vorher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/rebase-onto-vorher.png -------------------------------------------------------------------------------- /bilder_ebook/remote-tracking-gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/remote-tracking-gitk.png -------------------------------------------------------------------------------- /bilder_ebook/svn-stdlayout-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/svn-stdlayout-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/clone.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/clone.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/fetch.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/fetch.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/graph.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/graph.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/index.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/index.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/pull.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/pull.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/push.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/push.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/sha.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/sha.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/tags.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/tags.dia -------------------------------------------------------------------------------- /bilder_ebook/git-convert-refs-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-convert-refs-after.png -------------------------------------------------------------------------------- /bilder_ebook/git-svn-tag-fix-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-svn-tag-fix-after.png -------------------------------------------------------------------------------- /bilder_ebook/git-svn-tag-fix-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-svn-tag-fix-before.png -------------------------------------------------------------------------------- /bilder_ebook/github-image-diff-2up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/github-image-diff-2up.png -------------------------------------------------------------------------------- /bilder_ebook/svn-nonstdlayout-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/svn-nonstdlayout-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/commit.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/commit.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/objekte.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/objekte.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/zentral.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/zentral.dia -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/gitk.png -------------------------------------------------------------------------------- /bilder_ebook/git-convert-refs-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/git-convert-refs-before.png -------------------------------------------------------------------------------- /bilder_ebook/github-image-diff-swipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/github-image-diff-swipe.png -------------------------------------------------------------------------------- /bilder_ebook/gitk-screen-format-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/gitk-screen-format-patch.png -------------------------------------------------------------------------------- /bilder_ebook/screenshot-rebase-nachher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/screenshot-rebase-nachher.png -------------------------------------------------------------------------------- /bilder_ebook/screenshot-rebase-vorher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/screenshot-rebase-vorher.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/ff-nachher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/ff-nachher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/ff-vorher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/ff-vorher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/struktur.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/struktur.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/svn_rebase.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/svn_rebase.dia -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/bsp-ff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/bsp-ff.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/tux-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/tux-diff.png -------------------------------------------------------------------------------- /bilder_ebook/objektmodell-programm-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/objektmodell-programm-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/branch-model.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/branch-model.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/pull_rebase.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/pull_rebase.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/svn_dcommit.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/svn_dcommit.dia -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/bsp-no-ff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/bsp-no-ff.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/gitk-basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/gitk-basic.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/github-workflow.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/github-workflow.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/graph-mit-refs.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/graph-mit-refs.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/merge-nachher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/merge-nachher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/rebase-nachher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/rebase-nachher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/rebase-vorher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/rebase-vorher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/relative-refs.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/relative-refs.dia -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/git-dir-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/dir-listing/git-dir-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/cgit-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/cgit-overview.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/git-gui-blame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/git-gui-blame.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/github-gollum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/github-gollum.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/mail-thread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/mail-thread.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/meld-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/meld-example.png -------------------------------------------------------------------------------- /bilder_ebook/revision-list-commit-graph-gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_ebook/revision-list-commit-graph-gitk.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/developer-public.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/developer-public.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/merge-base-commit.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/merge-base-commit.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/patches-per-mail.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/patches-per-mail.dia -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/cgit-commitdiff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/cgit-commitdiff.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/github-download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/github-download.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/github-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/github-network.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/gitweb-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/gitweb-overview.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/tag-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/tag-screenshot.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/objekte-zusammenhang.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/objekte-zusammenhang.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/rebase-onto-nachher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/rebase-onto-nachher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/rebase-onto-vorher.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/diagramme/rebase-onto-vorher.dia -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/git-branches-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/dir-listing/git-branches-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/svn-branches-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/dir-listing/svn-branches-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/svn-stdlayout-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/dir-listing/svn-stdlayout-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/ff-no-ff-vergleich.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/ff-no-ff-vergleich.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/git-svn-merge-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/git-svn-merge-demo.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/gitweb-commitdiff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/gitweb-commitdiff.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/stash-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/stash-screenshot.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/describe-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/describe-screenshot.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/remote-tracking-gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/remote-tracking-gitk.png -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/svn-nonstdlayout-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/dir-listing/svn-nonstdlayout-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/git-convert-refs-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/git-convert-refs-after.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/git-convert-refs-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/git-convert-refs-before.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/git-svn-tag-fix-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/git-svn-tag-fix-after.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/git-svn-tag-fix-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/git-svn-tag-fix-before.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/github-image-diff-2up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/github-image-diff-2up.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/github-image-diff-swipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/github-image-diff-swipe.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/gitk-screen-format-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/gitk-screen-format-patch.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/screenshot-rebase-nachher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/screenshot-rebase-nachher.png -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/screenshot-rebase-vorher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/screenshot-rebase-vorher.png -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/objektmodell-programm-crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/dir-listing/objektmodell-programm-crop.png -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/EXPORTING: -------------------------------------------------------------------------------- 1 | 1) Die .dia-Dateien sind die "richtige" Version 2 | 2) PNG-Export mit expliziter Größenangabe! 3 | for f (*.dia) dia $f -s 2000x -e ${f:r}.png 4 | -------------------------------------------------------------------------------- /bilder_quelldaten/screenshots/revision-list-commit-graph-gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitbuch/gitbuch_cc/HEAD/bilder_quelldaten/screenshots/revision-list-commit-graph-gitk.png -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Form und Funktionalität 2 | ======================= 3 | 4 | * Fußnoten sollten nicht nach unten springen, sondern lieber eine Art Popup 5 | produzieren oder in einer Randspalte dargestellt werden 6 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/template.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | 12 | } 13 | 14 | 15 | \end{document} 16 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/svn-stdlayout.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | .1 /. 12 | .2 trunk/. 13 | .2 branches/. 14 | .2 tags/. 15 | } 16 | 17 | 18 | \end{document} 19 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/objektmodell-programm.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | .1 /. 12 | .2 hello.py. 13 | .2 README. 14 | .2 test/. 15 | .3 test.sh. 16 | } 17 | 18 | 19 | \end{document} 20 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/git-branches.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | .1 .git/refs/remotes/origin. 12 | .2 bugfix. 13 | .2 feature. 14 | .2 trunk. 15 | .2 tags/. 16 | .3 v1.0. 17 | .3 v2.0. 18 | } 19 | 20 | 21 | \end{document} 22 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/svn-branches.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | .1 /. 12 | .2 branches/. 13 | .3 bugfix/. 14 | .3 feature/. 15 | .2 tags/. 16 | .3 v1.0/. 17 | .3 v2.0/. 18 | .2 trunk/. 19 | } 20 | 21 | 22 | \end{document} 23 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/svn-nonstdlayout.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | .1 /. 12 | .2 trunk/. 13 | .3 projekt1/. 14 | .3 projekt2/. 15 | .2 branches/. 16 | .3 projekt1/. 17 | .3 projekt2/. 18 | .2 tags/. 19 | .3 projekt1/. 20 | .3 projekt2/. 21 | } 22 | 23 | 24 | \end{document} 25 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/git-dir.tex: -------------------------------------------------------------------------------- 1 | 2 | \documentclass{book} 3 | 4 | \usepackage{dirtree} 5 | 6 | \begin{document} 7 | 8 | \thispagestyle{empty} 9 | 10 | \dirtree{% 11 | .1 .git/. 12 | .2 HEAD. 13 | .2 config. 14 | .2 hooks/. 15 | .2 index. 16 | .2 info/. 17 | .2 logs/. 18 | .3 HEAD. 19 | .3 refs/. 20 | .2 objects/. 21 | .3 info/. 22 | .3 pack/. 23 | .2 refs/. 24 | .3 heads/. 25 | .3 remotes/. 26 | .3 tags/. 27 | } 28 | 29 | 30 | \end{document} 31 | -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/global-sw-map: -------------------------------------------------------------------------------- 1 | # old new :-) 2 | 000099 000000 3 | 4b4444 333333 4 | 666666 888888 5 | 699768 ffffff 6 | 757575 666666 7 | 8086ac 666666 8 | 9eec9e dddddd 9 | a6b1ed aaaaaa 10 | a7a2a2 333333 11 | a9e5a1 aaaaaa 12 | acdaaa aaaaaa 13 | b5b5b5 888888 14 | b7cccc aaaaaa 15 | be8cdd aaaaaa 16 | c0c0c0 aaaaaa 17 | c3c5cf aaaaaa 18 | c5919b aaaaaa 19 | cef5ce ffffff 20 | d8e5e5 ffffff 21 | e4c8c8 ffffff 22 | e6f0f0 cccccc 23 | e9a963 ffffff 24 | f1bc5a ffffff 25 | f6f687 ffffff 26 | ffffbb ffffff 27 | -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/Makefile: -------------------------------------------------------------------------------- 1 | DIAS = branch-model clone commit developer-public fetch ff-nachher ff-vorher \ 2 | github-workflow graph graph-mit-refs index merge-base-commit merge-nachher \ 3 | objekte objekte-zusammenhang patches-per-mail pull pull_rebase push \ 4 | rebase-nachher rebase-onto-nachher rebase-onto-vorher rebase-vorher \ 5 | relative-refs sha struktur svn_dcommit svn_rebase tags zentral 6 | 7 | all: $(addsuffix .png,$(DIAS)) 8 | 9 | %.png: %.dia 10 | dia $< -s 2000x -e ../../bilder_ebook/$@ 11 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/Makefile: -------------------------------------------------------------------------------- 1 | files=objektmodell-programm-crop\ 2 | svn-stdlayout-crop\ 3 | svn-nonstdlayout-crop\ 4 | svn-branches-crop\ 5 | git-branches-crop\ 6 | git-dir-crop 7 | 8 | pdfs=$(addsuffix .pdf, $(files)) 9 | pngs=$(addsuffix .png, $(files)) 10 | 11 | all: $(pdfs) $(pngs) 12 | 13 | clean: 14 | -rm -fv *.pdf *.aux *.log 15 | 16 | %.pdf : %.tex 17 | pdflatex $< 18 | 19 | %-crop.pdf : %.pdf 20 | pdfcrop $< 21 | 22 | %-crop.png : %-crop.pdf 23 | convert -density 1000 $< -flatten ../../bilder_ebook/$@ 24 | -------------------------------------------------------------------------------- /git.txt: -------------------------------------------------------------------------------- 1 | Git 2 | === 3 | :subtitle: Verteilte_Versionskontrolle_für_Code_und_Dokumente 4 | :author: Valentin_Haenel_und_Julius_Plenz 5 | :doctype: book 6 | :revnumber: 3.0 7 | :lang: de 8 | 9 | [preface] 10 | include::vorwort.txt[] 11 | 12 | include::erste_schritte.txt[] 13 | 14 | include::grundlagen.txt[] 15 | 16 | include::praxis.txt[] 17 | 18 | include::advanced.txt[] 19 | 20 | include::remote.txt[] 21 | 22 | include::workflows.txt[] 23 | 24 | include::server.txt[] 25 | 26 | include::automatisierung.txt[] 27 | 28 | include::zusammenspiel.txt[] 29 | 30 | include::shell.txt[] 31 | 32 | include::github.txt[] 33 | 34 | [appendix] 35 | include::installation.txt[] 36 | 37 | [appendix] 38 | include::gitdir.txt[] 39 | 40 | // vim:set tw=72 ft=asciidoc: 41 | -------------------------------------------------------------------------------- /bilder_quelldaten/diagramme/remap-sw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | usage() { 4 | echo "usage: "$(basename $0)" [...]" >&2 5 | exit 1 6 | } 7 | 8 | # check all files 9 | for f in "$@"; do 10 | [ -f "$f" ] || usage 11 | done 12 | [ $# -ge 1 ] || usage 13 | 14 | anchor='&2; exit 2; } 17 | 18 | SED='' 19 | while read old new; do 20 | [ $old != \# ] || continue # skip comments 21 | SED="${SED}s/${anchor}${old}/${anchor}${new}/g;" 22 | done < global-sw-map 23 | 24 | for f in "$@"; do 25 | t="$(mktemp .dia.XXXXXX)" 26 | zcat "$f" | sed "$SED" | gzip - > "$t" 27 | 28 | echo -n "creating PNG... " 29 | dia "$t" -s 2000x -e "../../bilder/$(basename "$f" .dia).png" 30 | 31 | rm -fv $t 32 | done 33 | -------------------------------------------------------------------------------- /asciidoc-pdf.conf: -------------------------------------------------------------------------------- 1 | # Slightly modified from /etc/asciidoc/docbook45.conf as suggested by 2 | # https://groups.google.com/forum/#!topic/asciidoc/zHXHvWXaCPY 3 | [image-blockmacro] 4 | {title} 5 | {title%}{pgwide-option?} 6 | # DocBook XSL Stylesheets custom processing instructions. 7 | 8 | 9 | 10 | 11 | 12 | 13 | {alt={target}} 14 | 15 | {title#} 16 | {title%} 17 | 18 | -------------------------------------------------------------------------------- /styles/dblatex.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This style is derived from the docbook one. 3 | %% 4 | \NeedsTeXFormat{LaTeX2e} 5 | \ProvidesPackage{asciidoc}[2008/06/05 AsciiDoc DocBook Style] 6 | 7 | %% Just use the original package and pass the options. 8 | \RequirePackageWithOptions{docbook} 9 | 10 | \usepackage{ebgaramond} 11 | 12 | % Sidebar is a boxed minipage that can contain verbatim. 13 | % Changed shadow box to double box. 14 | \renewenvironment{sidebar}[1][0.95\textwidth]{ 15 | \hspace{0mm}\newline% 16 | \noindent\begin{Sbox}\begin{minipage}{#1}% 17 | \setlength\parskip{\medskipamount}% 18 | }{ 19 | \end{minipage}\end{Sbox}\doublebox{\TheSbox}% 20 | } 21 | 22 | % For DocBook literallayout elements, see `./dblatex/dblatex-readme.txt`. 23 | \usepackage{alltt} 24 | 25 | \pagestyle{fancy} 26 | \fancyhf{} 27 | \fancyhead[RO,LE]{\thepage} 28 | \fancyhead[LO]{\leftmark} 29 | \fancyhead[RE]{\rightmark} 30 | \renewcommand{\footrulewidth}{0pt} 31 | 32 | \newcommand\edhead{} 33 | \renewcommand{\maketitle}{ 34 | \begin{titlepage} 35 | \thispagestyle{empty} 36 | \vspace{10cm} 37 | \begin{center} 38 | {\Huge\bfseries\sffamily Git}\\ 39 | \vspace{1cm} 40 | {\large\sffamily Verteilte Versionskontrolle f\"{u}r Code und Dokumente}\\ 41 | \vspace{1cm} 42 | Valentin Haenel und Julius Plenz\\ 43 | \vspace{3cm} 44 | {\small Version vom \today{}.}\\ 45 | {\small Homepage: \url{http://gitbu.ch/}}\\ 46 | \vspace{3cm} 47 | {\small Lizensiert unter der \emph{CreativeCommons Attribution-NonCommercial-ShareAlike 4.0 International}\\ (CC BY-NC-SA 4.0)} 48 | \end{center} 49 | \end{titlepage} 50 | } 51 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: git.chunked 2 | all: git.chunked git.html 3 | 4 | git.txt: advanced.txt automatisierung.txt erste_schritte.txt gitdir.txt \ 5 | github.txt grundlagen.txt installation.txt praxis.txt remote.txt \ 6 | server.txt shell.txt vorwort.txt workflows.txt zusammenspiel.txt 7 | touch $@ 8 | 9 | git.html: git.txt asciidoc.conf 10 | asciidoc -a numbered -a data-uri -a toclevels=3 $< 11 | 12 | # ARE YOU OUT OF YOUR MIND? ARE YOU NOT CAPABLE OF WRITING UTTERLY 13 | # SIMPLE XSL TEMPLATES TO ACHIEVE THIS SIMPLE THING? –– No. I’ve tried and failed. 14 | styles/toc.html: git.chunked-prereq 15 | ( cat styles/toc.before.html; \ 16 | xmllint --html --xpath '//div[@class="toc"]/dl[@class="toc"]' git.chunked/index.html; \ 17 | cat styles/toc.after.html ) > $@ 18 | 19 | git.chunked-prereq: git.txt styles asciidoc.conf 20 | rm -f styles/toc.html 21 | a2x -f chunked --xsl-file styles/chunked.xsl --resource styles --stylesheet=gitbuch.css git.txt 22 | 23 | git.chunked: git.chunked-prereq styles/toc.html 24 | a2x -f chunked --xsl-file styles/chunked.xsl --resource styles --stylesheet=gitbuch.css git.txt 25 | 26 | epub: git.epub 27 | 28 | git.epub: git.txt 29 | a2x -fepub --epubcheck $< 30 | 31 | pdf: git.pdf 32 | 33 | git.pdf: git.txt styles/dblatex.sty 34 | a2x -fpdf --dblatex-opts "-P latex.output.revhistory=0 \ 35 | -P doc.publisher.show=0 \ 36 | -P latex.class.book=book \ 37 | -P geometry.options=margin=3cm \ 38 | -P latex.class.options=12pt \ 39 | -s styles/dblatex.sty" \ 40 | --asciidoc-opts="-f asciidoc-pdf.conf" $< 41 | 42 | clean: 43 | rm -rf git.html git.chunked style/toc.html git.epub.d git.epub git.pdf 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Quelldaten für das Git-Buch 2 | =========================== 3 | 4 | Eine gerenderte Version findet sich auf [gitbu.ch](http://gitbu.ch/pr01.html). 5 | 6 | Pull-Requests sind willkommen; es handelt sich allerdings um ein Buch, das 7 | wiederholt professionell lektoriert wurde. Diesen Qualitäts-Standard wollen wir 8 | natürlich halten. Bevor Du also tiefgreifende Änderungen/Erweiterungen 9 | vornimmst, [kontaktiere uns](mailto:kontakt@gitbu.ch), damit wir entscheiden 10 | können, wie wir vorgehen. Fehlerkorrekturen oder kleine Updates sind natürlich 11 | immer gerne gesehen! 12 | 13 | Falls Du ein DocBook-Experte und/oder Webprogrammierer bist, und denkst: Das 14 | Design könnte man ja wohl mal professionalisieren – dann gerne! Ich habe aus 15 | den Quelldateien nur schnell eine halbwegs ansehnliche Webseite 16 | zusammengestoppelt. 17 | 18 | Bauen 19 | ===== 20 | 21 | Voraussetzungen: Installiertes `asciidoc`, `dblatex` und `texlive-fonts-extra` (für PDF). 22 | 23 | Bauen: 24 | * `make` erstellt die HTML Version. 25 | * `xdg-open git.chunked/pr01.html` öffnet das Ergebnis im Browser. 26 | 27 | * `make epub` erstellt die EPUB-Version. 28 | * `xdg-open git.epub` öffnet das EPUB. 29 | 30 | * `make pdf` erstellt die PDF-Version. 31 | * `xdg-open git.pdf` öffnet das PDF. 32 | 33 | Mac OS X 34 | -------- 35 | 36 | Zur Vorbereitung (mit [Homebrew](http://brew.sh/)): 37 | * `brew install asciidoc xmlstarlet epubcheck` 38 | * [xmllint fixen](https://groups.google.com/forum/#!topic/asciidoc/FC-eOwU8rYg): 39 | * `sudo mkdir /etc/xml` 40 | * `sudo ln -s /usr/local/etc/xml/catalog /etc/xml/catalog` 41 | 42 | Lizenz 43 | ====== 44 | 45 | Lizensiert unter der [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 46 | International License](http://creativecommons.org/licenses/by-nc-sa/4.0/). 47 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/dirtree.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `dirtree.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% dirtree.dtx (with options: `latex-wrapper') 8 | %% 9 | %% IMPORTANT NOTICE: 10 | %% 11 | %% For the copyright see the source file. 12 | %% 13 | %% Any modified versions of this file must be renamed 14 | %% with new filenames distinct from dirtree.sty. 15 | %% 16 | %% For distribution of the original source see the terms 17 | %% for copying and modification in the file dirtree.dtx. 18 | %% 19 | %% This generated file may be distributed as long as the 20 | %% original source files, as listed above, are part of the 21 | %% same distribution. (The sources need not necessarily be 22 | %% in the same archive or directory.) 23 | %% 24 | %% Package `dirtree.dtx' 25 | %% ----------------------------------------------- 26 | %% Copyright (C) 2004-2006 Jean-C\^ome Charpentier 27 | %% ----------------------------------------------- 28 | %% 29 | %% This work may be distributed and/or modified under the 30 | %% conditions of the LaTeX Project Public License, either version 1.3 31 | %% of this license or (at your option) any later version. 32 | %% The latest version of this license is in 33 | %% http://www.latex-project.org/lppl.txt 34 | %% and version 1.3 or later is part of all distributions of LaTeX 35 | %% version 2003/12/01 or later. 36 | %% 37 | %% See CTAN archives in directory macros/latex/base/lppl.txt. 38 | %% 39 | %% CONTENTS: 40 | %% This work consists of the files dirtree.ins and dirtree.dtx. 41 | %% Derived files are dirtree.tex and dirtree.sty. 42 | %% 43 | %% DESCRIPTION: 44 | %% dirtree is a package displaying directory trees. 45 | %% 46 | \def\fileversion{0.2} 47 | \def\filedate{2006/01/25} 48 | \NeedsTeXFormat{LaTeX2e}[1995/06/01] 49 | \ProvidesPackage{dirtree}[\filedate\space v\fileversion\space 50 | package wrapper for dirtree] 51 | \newcommand*\DT@fromsty{} 52 | \input{dirtree.tex} 53 | \ProvidesFile{dirtree.tex} 54 | [\filedate\space v\fileversion\space `dirtree' (jcc)] 55 | \endinput 56 | %% 57 | %% End of file `dirtree.sty'. 58 | -------------------------------------------------------------------------------- /styles/chunked.xsl: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | images/icons/ 15 | images/icons/ 16 | 17 | 18 | 19 | yes 20 | 1 21 | 22 | 23 | 24 | 28 | 29 | 30 | hyphenate 31 | 32 | 33 | 34 | 35 | 36 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /styles/common.xsl: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 1 15 | 0 16 | 17 | 18 | 19 | 20 | 21 | 22 | images/icons/ 23 | 0 24 | 25 | 26 | 27 | 0 28 | #E0E0E0 29 | 30 | 31 | 32 | images/icons/ 33 | 34 | 35 | margin-left: 0; margin-right: 10%; 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 77 | 78 | 79 | 80 | article toc,title 81 | book toc,title 82 | 83 | 84 | chapter toc,title 85 | part toc,title 86 | preface toc,title 87 | qandadiv toc 88 | qandaset toc 89 | reference toc,title 90 | sect1 toc 91 | sect2 toc 92 | sect3 toc 93 | sect4 toc 94 | sect5 toc 95 | section toc 96 | set toc,title 97 | 98 | 99 | 100 | article nop 101 | book nop 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /installation.txt: -------------------------------------------------------------------------------- 1 | [[sec.installation]] 2 | == Installation == 3 | 4 | Die Installation von Git ist einfach und geht schnell vonstatten, da 5 | für die meisten Systeme bereits vorkonfigurierte Pakete bereitgestellt 6 | werden. Der Vollständigkeit halber wollen wir aber die wichtigsten 7 | Handgriffe unter Linux, Mac OS X und Windows dokumentieren. 8 | 9 | [[linux]] 10 | === Linux === 11 | 12 | Aufgrund der Vielzahl der Linux-Distributionen wird hier nur die 13 | Installation auf Debian-, Fedora- sowie Gentoo-Systemen beschrieben. 14 | Für andere Distributionen schauen Sie ggf. in der Dokumentation bzw. 15 | in der Paketverwaltung nach; natürlich können Sie Git auch aus dem 16 | Quellcode übersetzen und installieren. 17 | 18 | [[sec.debian-ubuntu]] 19 | ==== Debian/Ubuntu ==== 20 | 21 | Debian und Ubuntu stellen fertige Pakete zur Verfügung, die mit dem 22 | Debian-Paketmanagementsystem komfortabel und schnell zu installieren 23 | sind. Dabei wird die Git-Installation modularisiert, Sie können also 24 | bei Bedarf nur bestimmte Teile von Git installieren. 25 | 26 | 27 | `git`:: Hauptpaket, enthält Kernbefehle (vormals `git-core`) 28 | 29 | `git-email`:: Zusatz zum Verschicken von Patches per E-Mail 30 | 31 | `git-gui`:: Grafische Benutzerschnittstelle 32 | 33 | `git-svn`:: Subkommando `svn`, um mit Subversion-Repositories zu 34 | interagieren 35 | 36 | `git-cvs`:: Interaktion mit CVS 37 | 38 | `git-doc`:: Dokumentation (wird unter `/usr/share/doc` installiert) 39 | 40 | `gitk`:: Programm Gitk 41 | 42 | 43 | Darüber hinaus gibt es noch ein Meta-Paket `git-all`, das alle 44 | relevanten Pakete installiert. Auf einer regulären Workstation sollten 45 | Sie also Git wie folgt installieren: 46 | 47 | [subs="macros,quotes"] 48 | -------- 49 | $ *sudo aptitude install git-all* 50 | -------- 51 | 52 | Unter Ubuntu können Sie analog das Paket `git-all` über die 53 | grafische Paketverwaltung 'Synaptic' installieren. 54 | 55 | [[sec.fedora]] 56 | ==== Fedora ==== 57 | 58 | Auf einem Fedora-System sollten Sie Git über den Paketmanager 59 | `yum` installieren: 60 | 61 | [subs="macros,quotes"] 62 | -------- 63 | $ *sudo yum install git* 64 | -------- 65 | 66 | Analog zur Aufteilung in kleinere Pakete wie bei Debian, sind gewisse 67 | Zusatzfunktionen für Git in separaten Paketen erhältlich. Um alle 68 | Kommandos zu installieren, sollten Sie das Paket `git-all` 69 | installieren. 70 | 71 | [[sec.gentoo]] 72 | ==== Gentoo ==== 73 | 74 | Gentoo stellt den Ebuild `dev-vcs/git` zur Verfügung. Das 75 | grafische Tool zum Erstellen von Commits (`git gui`) sowie der 76 | Zusatz zum Verschicken von E-Mails (`git send-email`) werden 77 | per Default installiert. Wenn Sie zusätzlich noch eine grafische 78 | Benutzerschnittstelle zum Betrachten und Bearbeiten der Geschichte 79 | (`gitk`) haben möchten, aktivieren Sie das 'USE-Flag'{empty}{nbsp}`tk`. Sollten Sie vorhaben, die Subversion-Schnittstelle zu 80 | verwenden, aktivieren Sie das USE-Flag `subversion`. Zur 81 | Installation via Portage geben Sie folgenden Befehl ein: 82 | 83 | [subs="macros,quotes"] 84 | -------- 85 | $ *sudo emerge dev-vcs/git* 86 | -------- 87 | 88 | [[sec.quellcode-installation]] 89 | ==== Installation aus den Quellen ==== 90 | 91 | Wenn Ihre Distribution kein Paket für Git anbietet, dieses veraltet 92 | ist oder Sie keine Root-Rechte auf dem System haben, sollten Sie 93 | Git direkt aus den Quellen installieren. 94 | 95 | Git hängt von den fünf Bibliotheken `expat` (XML-Parser), 96 | `curl` (Datentransfer), `zlib` (Kompression), `pcre` (reguläre 97 | Ausdrücke) und `openssl` (Verschlüsselung/Hashing) ab. Deren Sourcen müssen 98 | Sie ggf. vorher kompilieren und die Bibliotheken entsprechend 99 | installieren, bevor Sie fortfahren. 100 | 101 | Laden Sie zuerst den Tarball der aktuellen Git Version herunter{empty}footnote:[http://www.kernel.org/pub/software/scm/git/] 102 | und entpacken Sie ihn: 103 | 104 | [subs="macros,quotes"] 105 | -------- 106 | $ *wget pass:quotes[https://www.kernel.org/pub/software/scm/git/git-2.1.0.tar.gz]* 107 | $ *tar xvf git-2.1.0.tar.gz* 108 | -------- 109 | 110 | Wechseln Sie nun in das Verzeichnis `git-2.1.0/` und 111 | kompilieren Sie den Quellcode; anschließend führen Sie `make 112 | install` aus: 113 | 114 | [subs="macros,quotes"] 115 | -------- 116 | $ *cd git-2.1.0/* 117 | $ *make -j8* 118 | $ *make install* 119 | -------- 120 | 121 | Mit `make prefix=` können Sie Git nach 122 | `` installieren (Default: `$HOME`). 123 | 124 | [[sec.osx]] 125 | === Mac OS X === 126 | 127 | Das Projekt 'Git for OS X' stellt ein Installationsprogramm im 128 | Diskimage-Format (DMG) zur Verfügung.footnote:[http://code.google.com/p/git-osx-installer/] 129 | Sie können es also wie gewohnt installieren. 130 | 131 | [[sec.windows]] 132 | === Windows === 133 | 134 | Das Projekt 'Git for Windows' stellt ein Installationsprogramm für 135 | Microsoft Windows zur Verfügung: 'msysGit'. Sie können das 136 | Programm herunterladen{empty}footnote:[https://msysgit.github.io/] 137 | und wie gewohnt installieren. 138 | 139 | -------------------------------------------------------------------------------- /bilder_quelldaten/dir-listing/dirtree.tex: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `dirtree.tex', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% dirtree.dtx (with options: `tex') 8 | %% 9 | %% IMPORTANT NOTICE: 10 | %% 11 | %% For the copyright see the source file. 12 | %% 13 | %% Any modified versions of this file must be renamed 14 | %% with new filenames distinct from dirtree.tex. 15 | %% 16 | %% For distribution of the original source see the terms 17 | %% for copying and modification in the file dirtree.dtx. 18 | %% 19 | %% This generated file may be distributed as long as the 20 | %% original source files, as listed above, are part of the 21 | %% same distribution. (The sources need not necessarily be 22 | %% in the same archive or directory.) 23 | %% 24 | %% Package `dirtree.dtx' 25 | %% ----------------------------------------------- 26 | %% Copyright (C) 2004-2006 Jean-C\^ome Charpentier 27 | %% ----------------------------------------------- 28 | %% 29 | %% This work may be distributed and/or modified under the 30 | %% conditions of the LaTeX Project Public License, either version 1.3 31 | %% of this license or (at your option) any later version. 32 | %% The latest version of this license is in 33 | %% http://www.latex-project.org/lppl.txt 34 | %% and version 1.3 or later is part of all distributions of LaTeX 35 | %% version 2003/12/01 or later. 36 | %% 37 | %% See CTAN archives in directory macros/latex/base/lppl.txt. 38 | %% 39 | %% CONTENTS: 40 | %% This work consists of the files dirtree.ins and dirtree.dtx. 41 | %% Derived files are dirtree.tex and dirtree.sty. 42 | %% 43 | %% DESCRIPTION: 44 | %% dirtree is a package displaying directory trees. 45 | %% 46 | \def\fileversion{0.2} 47 | \def\filedate{2006/01/25} 48 | \message{`dirtree' v\fileversion, \filedate\space (jcc)} 49 | \edef\DTAtCode{\the\catcode`\@} 50 | \catcode`\@=11 51 | \long\def\LOOP#1\REPEAT{% 52 | \def\ITERATE{#1\relax\expandafter\ITERATE\fi}% 53 | \ITERATE 54 | \let\ITERATE\relax 55 | } 56 | \let\REPEAT=\fi 57 | \expandafter\ifx\csname DT@fromsty\endcsname\relax 58 | \def\@namedef#1{\expandafter\def\csname #1\endcsname} 59 | \def\@nameuse#1{\csname #1\endcsname} 60 | \long\def\@gobble#1{} 61 | \fi 62 | \def\@nameedef#1{\expandafter\edef\csname #1\endcsname} 63 | \newdimen\DT@offset \DT@offset=0.2em 64 | \newdimen\DT@width \DT@width=1em 65 | \newdimen\DT@sep \DT@sep=0.2em 66 | \newdimen\DT@all 67 | \DT@all=\DT@offset 68 | \advance\DT@all \DT@width 69 | \advance\DT@all \DT@sep 70 | \newdimen\DT@rulewidth \DT@rulewidth=0.4pt 71 | \newdimen\DT@dotwidth \DT@dotwidth=1.6pt 72 | \newdimen\DTbaselineskip \DTbaselineskip=\baselineskip 73 | \newcount\DT@counti 74 | \newcount\DT@countii 75 | \newcount\DT@countiii 76 | \newcount\DT@countiv 77 | \def\DTsetlength#1#2#3#4#5{% 78 | \DT@offset=#1\relax 79 | \DT@width=#2\relax 80 | \DT@sep=#3\relax 81 | \DT@all=\DT@offset 82 | \advance\DT@all by\DT@width 83 | \advance\DT@all by\DT@sep 84 | \DT@rulewidth=#4\relax 85 | \DT@dotwidth=#5\relax 86 | } 87 | \expandafter\ifx\csname DT@fromsty\endcsname\relax 88 | \def\DTstyle{\tt} 89 | \def\DTstylecomment{\rm} 90 | \else 91 | \def\DTstyle{\ttfamily} 92 | \def\DTstylecomment{\rmfamily} 93 | \fi 94 | \def\DTcomment#1{% 95 | \kern\parindent\dotfill 96 | {\DTstylecomment{#1}}% 97 | } 98 | \def\dirtree#1{% 99 | \let\DT@indent=\parindent 100 | \parindent=\z@ 101 | \let\DT@parskip=\parskip 102 | \parskip=\z@ 103 | \let\DT@baselineskip=\baselineskip 104 | \baselineskip=\DTbaselineskip 105 | \let\DT@strut=\strut 106 | \def\strut{\vrule width\z@ height0.7\baselineskip depth0.3\baselineskip}% 107 | \DT@counti=\z@ 108 | \let\next\DT@readarg 109 | \next#1\@nil 110 | \dimen\z@=\hsize 111 | \advance\dimen\z@ -\DT@offset 112 | \advance\dimen\z@ -\DT@width 113 | \setbox\z@=\hbox to\dimen\z@{% 114 | \hsize=\dimen\z@ 115 | \vbox{\@nameuse{DT@body@1}}% 116 | }% 117 | \dimen\z@=\ht\z@ 118 | \advance\dimen0 by\dp\z@ 119 | \advance\dimen0 by-0.7\baselineskip 120 | \ht\z@=0.7\baselineskip 121 | \dp\z@=\dimen\z@ 122 | \par\leavevmode 123 | \kern\DT@offset 124 | \kern\DT@width 125 | \box\z@ 126 | \endgraf 127 | \DT@countii=\@ne 128 | \DT@countiii=\z@ 129 | \dimen3=\dimen\z@ 130 | \@namedef{DT@lastlevel@1}{-0.7\baselineskip}% 131 | \loop 132 | \ifnum\DT@countii<\DT@counti 133 | \advance\DT@countii \@ne 134 | \advance\DT@countiii \@ne 135 | \dimen\z@=\@nameuse{DT@level@\the\DT@countii}\DT@all 136 | \advance\dimen\z@ by\DT@offset 137 | \advance\dimen\z@ by-\DT@all 138 | \leavevmode 139 | \kern\dimen\z@ 140 | \DT@countiv=\DT@countii 141 | \count@=\z@ 142 | \LOOP 143 | \advance\DT@countiv \m@ne 144 | \ifnum\@nameuse{DT@level@\the\DT@countiv} > 145 | \@nameuse{DT@level@\the\DT@countii}\relax 146 | \else 147 | \count@=\@ne 148 | \fi 149 | \ifnum\count@=\z@ 150 | \REPEAT 151 | \edef\DT@hsize{\the\hsize}% 152 | \count@=\@nameuse{DT@level@\the\DT@countii}\relax 153 | \dimen\z@=\count@\DT@all 154 | \advance\hsize by-\dimen\z@ 155 | \setbox\z@=\vbox{\@nameuse{DT@body@\the\DT@countii}}% 156 | \hsize=\DT@hsize 157 | \dimen\z@=\ht\z@ 158 | \advance\dimen\z@ by\dp\z@ 159 | \advance\dimen\z@ by-0.7\baselineskip 160 | \ht\z@=0.7\baselineskip 161 | \dp\z@=\dimen\z@ 162 | \@nameedef{DT@lastlevel@\the\DT@countii}{\the\dimen3}% 163 | \advance\dimen3 by\dimen\z@ 164 | \advance\dimen3 by0.7\baselineskip 165 | \dimen\z@=\@nameuse{DT@lastlevel@\the\DT@countii}\relax 166 | \advance\dimen\z@ by-\@nameuse{DT@lastlevel@\the\DT@countiv}\relax 167 | \advance\dimen\z@ by0.3\baselineskip 168 | \ifnum\@nameuse{DT@level@\the\DT@countiv} < 169 | \@nameuse{DT@level@\the\DT@countii}\relax 170 | \advance\dimen\z@ by-0.5\baselineskip 171 | \fi 172 | \kern-0.5\DT@rulewidth 173 | \hbox{\vbox to\z@{\vss\hrule width\DT@rulewidth height\dimen\z@}}% 174 | \kern-0.5\DT@rulewidth 175 | \kern-0.5\DT@dotwidth 176 | \vrule width\DT@dotwidth height0.5\DT@dotwidth depth0.5\DT@dotwidth 177 | \kern-0.5\DT@dotwidth 178 | \vrule width\DT@width height0.5\DT@rulewidth depth0.5\DT@rulewidth 179 | \kern\DT@sep 180 | \box\z@ 181 | \endgraf 182 | \repeat 183 | \parindent=\DT@indent 184 | \parskip=\DT@parskip 185 | \DT@baselineskip=\baselineskip 186 | \let\strut\DT@strut 187 | } 188 | \def\DT@readarg.#1 #2. #3\@nil{% 189 | \advance\DT@counti \@ne 190 | \@namedef{DT@level@\the\DT@counti}{#1}% 191 | \@namedef{DT@body@\the\DT@counti}{\strut{\DTstyle{#2}\strut}}% 192 | \ifx\relax#3\relax 193 | \let\next\@gobble 194 | \fi 195 | \next#3\@nil 196 | } 197 | \catcode`\@=\DTAtCode\relax 198 | \endinput 199 | %% 200 | %% End of file `dirtree.tex'. 201 | -------------------------------------------------------------------------------- /styles/gitbuch.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS stylesheet for XHTML produced by DocBook XSL stylesheets. 3 | */ 4 | 5 | body { 6 | font-family: Georgia,serif; 7 | } 8 | 9 | code, pre { 10 | font-family: "Courier New", Courier, monospace; 11 | font-size: 90%; 12 | } 13 | 14 | span.strong { 15 | font-weight: bold; 16 | } 17 | 18 | body blockquote { 19 | margin-top: .75em; 20 | line-height: 1.5; 21 | margin-bottom: .75em; 22 | } 23 | 24 | html body { 25 | margin: 1em auto; 26 | width: 70em; 27 | line-height: 1.2; 28 | } 29 | 30 | body div { 31 | margin: 0; 32 | } 33 | 34 | body p { 35 | text-align: justify; 36 | hyphens: auto; 37 | } 38 | 39 | h1, h2, h3, h4, h5, h6 40 | { 41 | color: #527bbd; 42 | font-family: Arial,Helvetica,sans-serif; 43 | } 44 | 45 | div.toc p:first-child, 46 | div.list-of-figures p:first-child, 47 | div.list-of-tables p:first-child, 48 | div.list-of-examples p:first-child, 49 | div.example p.title, 50 | div.sidebar p.title 51 | { 52 | font-weight: bold; 53 | color: #527bbd; 54 | font-family: Arial,Helvetica,sans-serif; 55 | margin-bottom: 0.2em; 56 | } 57 | 58 | div.tip { 59 | /* we need !important to override the hardcoded style="..." */ 60 | margin-left: 5% !important; 61 | margin-right: 5% !important; 62 | padding: .2em 1em; 63 | border: 1px solid #c0c0c0; 64 | } 65 | 66 | body h1 { 67 | margin: .0em 0 0 -4%; 68 | line-height: 1.3; 69 | border-bottom: 2px solid silver; 70 | } 71 | 72 | body h2 { 73 | margin: 0.5em 0 0 -4%; 74 | line-height: 1.3; 75 | border-bottom: 2px solid silver; 76 | } 77 | 78 | body h3 { 79 | margin: .8em 0 0 -3%; 80 | line-height: 1.3; 81 | } 82 | 83 | body h4 { 84 | margin: .8em 0 0 -3%; 85 | line-height: 1.3; 86 | } 87 | 88 | body h5 { 89 | margin: .8em 0 0 -2%; 90 | line-height: 1.3; 91 | } 92 | 93 | body h6 { 94 | margin: .8em 0 0 -1%; 95 | line-height: 1.3; 96 | } 97 | 98 | body hr { 99 | border: none; /* Broken on IE6 */ 100 | } 101 | div.footnotes hr { 102 | border: 1px solid silver; 103 | } 104 | 105 | div.navheader th, div.navheader td, div.navfooter td { 106 | font-family: Arial,Helvetica,sans-serif; 107 | font-size: 0.9em; 108 | font-weight: bold; 109 | color: #527bbd; 110 | } 111 | div.navheader img, div.navfooter img { 112 | border-style: none; 113 | } 114 | div.navheader a, div.navfooter a { 115 | font-weight: normal; 116 | } 117 | div.navfooter hr, div.cc-license hr{ 118 | border: 1px solid silver; 119 | } 120 | 121 | div.toc { 122 | position: absolute; 123 | left: 0; 124 | top: 0; 125 | width: 25em; 126 | padding: 1em .5em 1em .5em; 127 | border-right: 1px solid #c0c0c0; 128 | border-bottom: 1px solid #c0c0c0; 129 | font-size: 80%; 130 | } 131 | 132 | div.toc dl.toc dd { 133 | margin-left: 20px; 134 | } 135 | 136 | div.navheader, div.navfooter, div.chapter, div.preface, div.appendix, div.cc-license { 137 | margin-left: 25em; 138 | } 139 | 140 | div.cc-license p { 141 | text-align: center; 142 | } 143 | 144 | body td { 145 | line-height: 1.2 146 | } 147 | 148 | body th { 149 | line-height: 1.2; 150 | } 151 | 152 | ol { 153 | line-height: 1.2; 154 | } 155 | 156 | ul, body dir, body menu { 157 | line-height: 1.2; 158 | } 159 | 160 | html { 161 | margin: 0; 162 | padding: 0; 163 | } 164 | 165 | body h1, body h2, body h3, body h4, body h5, body h6 { 166 | margin-left: 0 167 | } 168 | 169 | body pre { 170 | margin: 0.5em 1em 0.5em 1em !important; 171 | line-height: 1.0; 172 | color: navy; 173 | } 174 | 175 | tt.literal, code.literal { 176 | color: navy; 177 | } 178 | 179 | .programlisting, .screen { 180 | border: 1px solid silver; 181 | background: #f4f4f4; 182 | margin: 0.5em 10% 0.5em 0; 183 | padding: 0.5em 1em; 184 | } 185 | 186 | div.sidebar { 187 | background: #ffffee; 188 | margin: 1.0em 10% 0.5em 0; 189 | padding: 0.5em 1em; 190 | border: 1px solid silver; 191 | } 192 | div.sidebar * { padding: 0; } 193 | div.sidebar div { margin: 0; } 194 | div.sidebar p.title { 195 | margin-top: 0.5em; 196 | margin-bottom: 0.2em; 197 | } 198 | 199 | div.bibliomixed { 200 | margin: 0.5em 5% 0.5em 1em; 201 | } 202 | 203 | div.glossary dt { 204 | font-weight: bold; 205 | } 206 | div.glossary dd p { 207 | margin-top: 0.2em; 208 | } 209 | 210 | dl { 211 | margin: .8em 0; 212 | line-height: 1.2; 213 | } 214 | 215 | dt { 216 | margin-top: 0.5em; 217 | } 218 | 219 | dt span.term { 220 | font-style: normal; 221 | color: navy; 222 | } 223 | 224 | div.variablelist dd p { 225 | margin-top: 0; 226 | } 227 | 228 | div.itemizedlist li, div.orderedlist li { 229 | margin-left: -0.8em; 230 | margin-top: 0.5em; 231 | } 232 | 233 | ul, ol { 234 | list-style-position: outside; 235 | } 236 | 237 | div.sidebar ul, div.sidebar ol { 238 | margin-left: 2.8em; 239 | } 240 | 241 | div.itemizedlist p.title, 242 | div.orderedlist p.title, 243 | div.variablelist p.title 244 | { 245 | margin-bottom: -0.8em; 246 | } 247 | 248 | div.revhistory table { 249 | border-collapse: collapse; 250 | border: none; 251 | } 252 | div.revhistory th { 253 | border: none; 254 | color: #527bbd; 255 | font-family: Arial,Helvetica,sans-serif; 256 | } 257 | div.revhistory td { 258 | border: 1px solid silver; 259 | } 260 | 261 | /* Keep TOC and index lines close together. */ 262 | div.toc dl, div.toc dt, 263 | div.list-of-figures dl, div.list-of-figures dt, 264 | div.list-of-tables dl, div.list-of-tables dt, 265 | div.indexdiv dl, div.indexdiv dt 266 | { 267 | line-height: normal; 268 | margin-top: 0; 269 | margin-bottom: 0; 270 | } 271 | 272 | /* 273 | Table styling does not work because of overriding attributes in 274 | generated HTML. 275 | */ 276 | div.table table, 277 | div.informaltable table 278 | { 279 | margin-left: 0; 280 | margin-right: 5%; 281 | margin-bottom: 0.8em; 282 | } 283 | div.informaltable table 284 | { 285 | margin-top: 0.4em 286 | } 287 | div.table thead, 288 | div.table tfoot, 289 | div.table tbody, 290 | div.informaltable thead, 291 | div.informaltable tfoot, 292 | div.informaltable tbody 293 | { 294 | /* No effect in IE6. */ 295 | border-top: 3px solid #527bbd; 296 | border-bottom: 3px solid #527bbd; 297 | } 298 | div.table thead, div.table tfoot, 299 | div.informaltable thead, div.informaltable tfoot 300 | { 301 | font-weight: bold; 302 | } 303 | 304 | div.mediaobject img { 305 | margin-bottom: 0.8em; 306 | } 307 | div.figure p.title, 308 | div.table p.title 309 | { 310 | margin-top: 1em; 311 | margin-bottom: 0.4em; 312 | } 313 | 314 | div.figure { 315 | width: 117%; 316 | } 317 | 318 | div.figure p.title { 319 | display: block; 320 | text-align: none; 321 | width: 14%; 322 | float: right; 323 | font-size: 75%; 324 | } 325 | 326 | div.figure div.figure-contents { 327 | text-align: center; 328 | } 329 | 330 | div.calloutlist p 331 | { 332 | margin-top: 0em; 333 | margin-bottom: 0.4em; 334 | } 335 | 336 | a img { 337 | border-style: none; 338 | } 339 | 340 | @media print { 341 | div.navheader, div.navfooter { display: none; } 342 | } 343 | 344 | span.aqua { color: aqua; } 345 | span.black { color: black; } 346 | span.blue { color: blue; } 347 | span.fuchsia { color: fuchsia; } 348 | span.gray { color: gray; } 349 | span.green { color: green; } 350 | span.lime { color: lime; } 351 | span.maroon { color: maroon; } 352 | span.navy { color: navy; } 353 | span.olive { color: olive; } 354 | span.purple { color: purple; } 355 | span.red { color: red; } 356 | span.silver { color: silver; } 357 | span.teal { color: teal; } 358 | span.white { color: white; } 359 | span.yellow { color: yellow; } 360 | 361 | span.aqua-background { background: aqua; } 362 | span.black-background { background: black; } 363 | span.blue-background { background: blue; } 364 | span.fuchsia-background { background: fuchsia; } 365 | span.gray-background { background: gray; } 366 | span.green-background { background: green; } 367 | span.lime-background { background: lime; } 368 | span.maroon-background { background: maroon; } 369 | span.navy-background { background: navy; } 370 | span.olive-background { background: olive; } 371 | span.purple-background { background: purple; } 372 | span.red-background { background: red; } 373 | span.silver-background { background: silver; } 374 | span.teal-background { background: teal; } 375 | span.white-background { background: white; } 376 | span.yellow-background { background: yellow; } 377 | 378 | span.big { font-size: 2em; } 379 | span.small { font-size: 0.6em; } 380 | 381 | span.underline { text-decoration: underline; } 382 | span.overline { text-decoration: overline; } 383 | span.line-through { text-decoration: line-through; } 384 | -------------------------------------------------------------------------------- /github.txt: -------------------------------------------------------------------------------- 1 | [[sec.github]] 2 | == Github == 3 | 4 | Es gibt derzeit mehrere Hosting-Websites, die kostenfreies Git-Hosting 5 | für Open-Source-Projekte anbieten. Die mit Abstand bekannteste von 6 | allen ist 7 | 'Github'.footnote:[https://github.com/] 8 | Zwei andere bekannte reine Git-Hoster sind 9 | 'Gitorious'{empty}footnote:[http://gitorious.org/] 10 | und 11 | 'repo.or.cz'{empty}footnote:[http://repo.or.cz/]. 12 | Aber auch bereits etablierte Hosting-Seiten wie 13 | 'Sourceforge'{empty}footnote:[http://sourceforge.net/] 14 | und 15 | 'Berlios'{empty}footnote:[http://www.berlios.de/] 16 | bieten mittlerweile Git-Hosting an. 17 | 18 | Github wurde 2008 von Chris Wanstrath, 19 | P.J. Hyett und Tom Preston-Werner 20 | gegründet. Die in Ruby on Rails entwickelte Plattform hat über 21 | drei Millionen Nutzer und hostet über zehn Millionen 22 | Repositories. 23 | Auch wenn man bedenkt, dass viele dieser Repositories sogenannte 24 | 'Forks' (Klone) anderer Repositories oder sogenannte 'Gists' 25 | (Quellcode-Schnipsel) sind, ist das trotzdem eine beachtliche Anzahl. 26 | Viele namhafte Projekte 27 | verwenden heutzutage Github, um ihren Quelltext zu verwalten, unter 28 | anderem das Kommandozeilen-Tool 29 | 'Curl'{empty}footnote:[http://curl.haxx.se/], 30 | das Web-Framework 'Ruby on 31 | Rails'{empty}footnote:[http://rubyonrails.org/] und 32 | die JavaScript-Bibliothek 33 | 'jQuery'{empty}footnote:[http://jquery.com/]. 34 | 35 | Das kostenfreie Angebot umfasst unbegrenzte Git-Repositories -- mit 36 | der Einschränkung, dass diese öffentlich verfügbar sind 37 | ('Public Repositories'). Zusätzlich bietet Github 38 | kostenpflichtige Optionen für Einzelpersonen und Firmen, die es 39 | erlauben, zugriffsbeschränkte Repositories ('Private 40 | Repositories') anzulegen und zu nutzen. Großen Unternehmen bietet 41 | Github eine Lösung namens 'GitHub Enterprise' an. 42 | 43 | Github bietet alle wesentlichen Features, die Sie von einer 44 | Projekt-Hosting-Plattform erwarten, darunter auch Projekt-Wiki und 45 | Issue-Tracker. Das besondere daran ist aber, dass das Wiki-System 46 | 'Gollum'{empty}footnote:[https://github.com/github/gollum] 47 | als Backend keine Datenbank, sondern lediglich ein Git-Repository 48 | verwendet. Als Markup bietet Github mehrere 49 | Syntax-Optionen{empty}footnote:[https://github.com/github/markup] 50 | an, unter anderem 'Markdown', 'Textile', 'Mediawiki' 51 | und 'Asciidoc'. 52 | 53 | Der Issue-Tracker ist auf Git ausgelegt und listet auch über das 54 | Webinterface erstellte Pull-Requests. Zusätzlich wurde in den 55 | Issue-Tracker ein E-Mail-Backend eingearbeitet. Ihre Antworten auf die 56 | eingehenden E-Mails werden automatisch von Github verarbeitet und auch 57 | im Webinterface angezeigt. Was Github jedoch nicht anbietet, sind 58 | Mailinglisten -- dafür müssen Sie auf Alternativen ausweichen. 59 | 60 | 61 | .Github-Seite von Gollum 62 | image::bilder_ebook/github-gollum.png[id="fig.github-gollum",scaledwidth="100%",width="100%"] 63 | 64 | 65 | In <> sehen Sie einen Ausschnitt der 66 | Projektseite von Gollum. Wichtig sind die Menüpunkte 67 | 'Source' (Quellcode-Übersicht), 'Commits', 'Network' 68 | (Forks des Projekts mit Änderungen), 'Pull-Requests', 69 | 'Issues', 'Wiki' und 'Graphs' (statistische Graphen). 70 | Andere wichtige Bedienelemente sind der Button 'Fork' sowie 71 | 'Downloads' und auch die Anzeige der Klon-URL. 72 | 73 | Bei Github steht zunächst der Entwickler im Mittelpunkt: Repositories 74 | sind immer Usern zugeordnet. Das ist ein großer Unterschied zu 75 | etablierten Hosting-Plattformen, bei denen grundsätzlich die Projekte 76 | im Vordergrund stehen, und die Nutzer diesen untergeordnet sind. (Es 77 | ist aber auch in Github möglich, Projekt-Konten anzulegen, denen dann 78 | wiederum User zugeordnet werden -- beliebt bei privaten Repositories 79 | und größeren Projekten.) 80 | 81 | Github bietet viele Möglichkeiten, Veränderungen auszutauschen. 82 | Zwar ist es mit Github möglich, einen zentralisierten Ansatz (siehe 83 | <>) zu verfolgen, indem Sie Anderen 84 | Zugriff auf Ihre eigenen Repositories ermöglichen -- die jedoch am 85 | meisten genutzte Form des Austausches ist eher ein 86 | Integration-Manager-Workflow (siehe 87 | <>). 88 | 89 | .Workflow bei Github 90 | image::bilder_ebook/github-workflow.png[id="fig.github-workflow",scaledwidth="70%",width="70%"] 91 | 92 | 93 | . Ein potentieller Contributor 94 | 'forkt'{empty}footnote:[Nicht als Projekt-Fork 95 | misszuverstehen, bei dem sich ein Projekt aufgrund interner 96 | Differenzen spaltet.] ein Repository bei Github. 97 | 98 | . Das öffentliche Repository wird wiederum geklont, Veränderungen 99 | werden eingepflegt. 100 | 101 | . Commits werden in das öffentliche Repository hochgeladen. 102 | 103 | . Dem Projekt-Autor wird ein Pull-Request geschickt. Diese können, wie 104 | bereits erwähnt, direkt im Web-Interface erstellt und verschickt 105 | werden. 106 | 107 | . Der Autor lädt die Neuerungen aus dem öffentlichen Repository, 108 | überprüft, ob sie seinen Qualitätsansprüchen genügen und integriert 109 | sie ggf. per Merge oder Cherry-Pick lokal. 110 | 111 | . Die Veränderungen des Contributors werden in das öffentliche 112 | Repository des Autors hochgeladen und verschmelzen so mit der 113 | Software. 114 | 115 | . Der Contributor gleicht sein lokales Repository mit dem öffentlichen 116 | Repository des Autors ab. 117 | 118 | Das Github Webinterface bietet einiges an Web-2.0-Komfort. So können 119 | Sie z.B. statt der Schritte 5. und 6. mit einem 120 | einzigen Klick direkt über das Webinterface einen Merge vollziehen. 121 | Selbstverständlich wird vorher überprüft, ob der Merge konfliktfrei 122 | bewerkstelligt werden kann -- falls nicht, erscheint statt der Option 123 | zum Mergen eine Warnung. 124 | 125 | Seit kurzem ist es auch möglich, die Schritte 1., 2., 126 | 3. und 4. vollständig im Webinterface durchzuführen. 127 | Dafür klicken Sie in einem fremden Repository auf den Button 128 | 'Fork and edit this file' -- das Repository wird automatisch für 129 | Ihr Benutzerkonto geforkt, und es tut sich ein web-basierter Editor 130 | auf, in dem Sie Ihre Veränderungen sowie eine Commit-Message 131 | eintragen. Danach werden Sie automatisch auf die Pull-Request Seite 132 | weitergeleitet. 133 | 134 | Da Sie bei vielen Forks schnell den Überblick verlieren, stellt Github 135 | eine grafische Darstellung der Forks mit noch ausstehenden Änderungen 136 | bereit, den sogenannten 'Network-Graph': 137 | 138 | .Der Github Network-Graph 139 | image::bilder_ebook/github-network.png[id="fig.github-network",scaledwidth="100%",width="100%"] 140 | 141 | Github bietet Ihnen unter 'Graphs' noch weitere Visualisierungen. 142 | Unter 'Languages' wird angezeigt, welche Programmiersprachen das 143 | Projekt einsetzt. Die Grafik 'Impact' (engl. Auswirkung) zeigt, 144 | welcher Entwickler wann und wie viel geleistet hat. 'Punchcard' 145 | (Lochkarte) zeigt die Commit-Aktivität für Wochentage und Tageszeiten. 146 | 'Traffic' (Verkehr) schließlich listet die Anzahl der 147 | Projektseitenaufrufe während der letzten drei Monate auf. 148 | 149 | Wie das Motto 'Social Coding' schon andeutet, hat Github mehrere 150 | Features, die Sie auch in sozialen Netzwerken finden. Zum Beispiel 151 | können Sie sowohl einzelnen Usern als auch Repositories folgen (engl. 152 | 'follow'). Sie erhalten dann in Ihrem 'Dashboard' 153 | (Armaturenbrett) über eine Art Github-Newsticker: Meldungen über neue und 154 | geschlossene Pull-Requests, neue Commits, die hochgeladen wurden, 155 | Forks usw. Die Newsfeeds der User und Repositories sind aber auch als 156 | RSS-Feed verfügbar, sollten Sie externe Newsreader vorziehen. 157 | 158 | Ein kleines, noch relativ unbekanntes Projekt kann daher über Github 159 | sehr schnell bekannt werden, wenn eine kritische Anzahl an 160 | ``Followern'' erreicht ist. 161 | 162 | // Das Dogma der Gründer war: "Mache es leicht mitzuarbeiten, und 163 | // die Leute werden mitarbeiten." Dieses Phänomen wird als 164 | // 'Github-Effect' bezeichnet. 165 | 166 | Github bietet auch einen Pastebin-Dienst an, den 'Gist' 167 | (Kernaussage). Im Gegensatz jedoch zu anderen Pastebin-Diensten ist 168 | bei Github jeder Gist ein vollwertiges Git-Repository. Besonders für 169 | Code-Schnipsel ist dies eine interessante Neuerung. 170 | 171 | Auch bei der Anbindung an externe Dienste leistet Github ganze Arbeit. 172 | Es gibt 50 sogenannte 'Service Hooks', mit denen Sie Nachrichten 173 | bzgl. eines Repositorys an externe Dienste weiterleiten. Dabei sind 174 | unter anderem altbewährte Klassiker wie E-Mail und IRC, aber auch 175 | modernere Alternativen wie Twitter und Jabber. 176 | 177 | Github bietet aber noch zusätzliche ``Gimmicks'', die sehr 178 | praktisch sind. So werden aus Tags automatisch Quellcode-Archive zum 179 | Herunterladen. Wie Sie in <> 180 | sehen, sowohl als `tar.gz` als auch als `.zip` Archiv. 181 | 182 | .Aus Tags erstellte Downloads 183 | image::bilder_ebook/github-download.png[id="fig.github-downloads",scaledwidth="65%",width="65%"] 184 | 185 | 186 | 187 | Für Entwickler, die oft mit Bildern arbeiten, bietet Github sogenannte 188 | 'Image View 189 | Modes'.footnote:[https://github.com/blog/817-behold-image-view-modes] 190 | Sie zeigen Unterschiede zwischen zwei Versionen einer Grafik an, 191 | ähnlich dem in <> vorgestellten Script. Es gibt folgende 192 | Modi: 193 | 194 | 195 | '2-up':: Die zwei verschiedenen Versionen werden nebeneinander 196 | dargestellt, siehe <>. Auch Größenunterschiede sind 197 | ersichtlich. 198 | + 199 | .Modus '2-up' 200 | image::bilder_ebook/github-image-diff-2up.png[id="fig.github-2up",scaledwidth="90%",width="90%"] 201 | 202 | 203 | 'Swipe':: Das Bild wird in der Mitte geteilt. Links sehen Sie die alte 204 | Version und rechts die neue. Schieben Sie den Regler hin und her, um 205 | die Änderungen zu beobachten. Siehe <>. 206 | + 207 | .Modus 'Swipe' 208 | image::bilder_ebook/github-image-diff-swipe.png[id="fig.github-swipe",scaledwidth="90%",width="90%"] 209 | 210 | 'Onion Skin':: Auch hier kommt ein Regler zum Einsatz, diesmal wird 211 | jedoch die neue Version eingeblendet, es entsteht also ein fließender 212 | Übergang zwischen alt und neu. 213 | 214 | 'Difference':: Zeigt nur die Pixel an, die verändert wurden. 215 | 216 | 217 | 218 | 219 | Die Programmierer hinter Github feilen weiter am Webinterface und so 220 | kommen regelmäßig innovative Verbesserungen hinzu. Die Seite hat eine 221 | eigene 222 | Hilfe-Seite{empty}footnote:[http://help.github.com/], auf 223 | der Arbeitsschritte mit dem Webinterface detailliert mit Screenshots 224 | erklärt werden. 225 | 226 | 227 | // vim:set tw=72 ft=asciidoc: -------------------------------------------------------------------------------- /gitdir.txt: -------------------------------------------------------------------------------- 1 | [[sec.git-repository-layout]] 2 | == Struktur eines Repositorys == 3 | 4 | Git speichert die Objektdatenbank, die zugehörigen Referenzen usw. im 5 | sogenannten 'Git-Directory', oft auch als `$GIT_DIR` 6 | bezeichnet. Standardmäßig ist dies `.git/`. Es existiert 7 | für jedes Git-Repository nur einmal, d.h. es werden keine 8 | zusätzlichen `.git/`-Verzeichnisse in Unterverzeichnissen 9 | angelegt.footnote:[Da ein Bare-Repository 10 | (siehe <>) keinen Working Tree besitzt, 11 | bilden die Inhalte, die normalerweise in `.git` liegen, die 12 | oberste Ebene in der Verzeichnisstruktur, und es gibt kein 13 | zusätzliches Verzeichnis `.git`.] Es enthält unter anderem 14 | folgende Einträge: 15 | 16 | 17 | `HEAD`:: Der `HEAD`, siehe <>. Neben `HEAD` liegen 18 | ggf. auch andere wichtige symbolische Referenzen auf oberster Ebene, 19 | z.B.{empty}{nbsp}`ORIG_HEAD` oder `FETCH_HEAD`. 20 | 21 | `config`:: Die Konfigurationsdatei des Repositorys, siehe 22 | <>. 23 | 24 | `hooks/`:: Enthält die für dieses Repository gesetzten Hooks, siehe 25 | <>. 26 | 27 | `index`:: Der Index bzw. Stage, siehe <>. 28 | 29 | `info/`:: Zusätzliche Repository-Informationen, z.B. zu ignorierende 30 | Muster (siehe <>) und auch Grafts (siehe 31 | <>). Sie können eigene Informationen dort ablegen, wenn 32 | andere Tools damit umgehen können (siehe z.B. der Abschnitt über 33 | Caching von CGit, <>). 34 | 35 | 36 | .Die wichtigsten Einträge in `.git` 37 | image::bilder_ebook/git-dir-crop.png[id="fig.git-dir-listing",scaledwidth="20%",width="20%"] 38 | 39 | 40 | `logs/`:: Protokoll der Veränderungen an Referenzen; zugänglich über 41 | das Reflog, siehe <>. Enthält eine Logdatei für jede 42 | Referenz unter `refs/` sowie `HEAD`. 43 | 44 | 45 | 46 | `objects/`:: Die Objektdatenbank, siehe <>. Aus 47 | Performance-Gründen sind die Objekte in Unterverzeichnisse, die einem 48 | Zwei-Zeichen-Präfix ihrer SHA-1-Summe entsprechen, einsortiert (der 49 | Commit `0a7ba55...` liegt also unter `0a/7ba55...`). Im 50 | Unterverzeichnis `pack/` finden Sie die Packfiles und zugehörigen 51 | Indizes, die u.a. von der Garbage-Collection (s.u.) erstellt 52 | wird. Im Unterverzeichnis `info/` legt Git bei Bedarf eine Auflistung 53 | vorhandener Packfiles ab. 54 | 55 | `refs/`:: Alle Referenzen, unter anderem Branches in `refs/heads/`, 56 | siehe <>, Tags in `refs/tags/`, siehe <> 57 | sowie Remote-Tracking-Branches unter `refs/remotes/`, siehe 58 | <>. 59 | 60 | 61 | Eine ausführliche technische Beschreibung finden Sie in der 62 | Man-Page `gitrepository-layout(5)`. 63 | 64 | [[sec.gc]] 65 | === Aufräumen === 66 | 67 | 68 | 69 | Wie beispielsweise schon in <> erwähnt, sind 70 | Commits, die nicht mehr referenziert werden (sei es durch Branches 71 | oder andere Commits), nicht mehr zu erreichen. In der Regel ist das der 72 | Fall, wenn Sie einen Commit löschen wollten (oder Commits mit Rebase 73 | umgebaut haben). Git löscht diese nicht sofort aus der 74 | Objektdatenbank, sondern belässt sie per Default zwei Wochen dort, 75 | auch wenn sie nicht mehr erreichbar sind. 76 | 77 | Intern verwendet Git die Kommandos `prune`, 78 | `prune-packed`, `fsck`, `repack`{empty}{nbsp}u.a. 79 | Allerdings werden die Tools mit entsprechenden Optionen 80 | automatisch von der 'Garbage Collection' (``Müllabfuhr'') 81 | ausgeführt: `git gc`. Folgende Aufgaben erledigt das Tool: 82 | 83 | 84 | * 'Dangling' und 'Unreachable Objects' löschen. 85 | Diese entstehen bei diversen Operationen und können in der Regel 86 | nach einiger Zeit gelöscht werden, um Platz zu sparen (Default: 87 | nach zwei Wochen). 88 | 89 | * 'Loose Objects' neu packen. Git verwendet sog. 90 | 'Packfiles', um mehrere Git-Objekte zusammenzuschnüren. (Dann 91 | existiert nicht mehr eine Datei unterhalb von `.git/objects/` 92 | pro Blob, Tree und Commit -- diese werden in einer großen, 93 | 'zlib'-komprimierten Datei zusammengefasst). 94 | 95 | * Existierende Packfiles nach alten (unerreichbaren) Objekten 96 | durchsuchen und die Packfiles entsprechend ``ausdünnen''. 97 | Ggf. werden mehrere kleine Packfiles zu großen kombiniert. 98 | 99 | * Referenzen packen. Es entstehen sog. 'Packed Refs', 100 | siehe auch <>. 101 | 102 | * Alte Reflog-Einträge löschen. Das geschieht per Default 103 | nach 90 Tagen. 104 | 105 | * Alte Konflikt-Resolutionen (siehe Rerere, 106 | <>) werden entsorgt (15/60 Tage Haltezeit für 107 | ungelöst/gelöst). 108 | 109 | 110 | Die Garbage Collection kennt drei Modi: automatisch, normal und 111 | aggressiv. Den automatischen Modus rufen Sie per `git gc 112 | --auto` auf -- der Modus überprüft, ob es wirklich eklatante 113 | Mängel im Repository gibt. Was ``eklatant'' bedeutet, ist 114 | konfigurierbar. Über folgende Konfigurationseinstellungen können Sie 115 | (global oder per Repository) bestimmen, ab wann, d.h. ab welcher 116 | Anzahl ``kleiner'' Dateien der automatische Modus aufräumt, 117 | also diese in große Archive zusammenfasst. 118 | 119 | 120 | `gc.auto` (Default: 6700 Objekte):: Objekte zu einem Packfile 121 | zusammenfassen 122 | 123 | `gc.autopacklimit` (Default: 50 Packs):: Packs zu einem großen 124 | Packfile zusammenfassen 125 | 126 | 127 | Der automatische Modus wird häufig aufgerufen, u.a. von 128 | `receive-pack` und `rebase` (interaktiv). In den 129 | meisten Fällen tut der automatische Modus allerdings nichts, da die 130 | Defaults sehr konservativ sind. Wenn doch, sieht das so aus: 131 | 132 | [subs="macros,quotes"] 133 | -------- 134 | $ *git gc --auto* 135 | Auto packing the repository for optimum performance. You may also 136 | run "git gc" manually. See "git help gc" for more information. 137 | ... 138 | -------- 139 | 140 | [[sec.gc-performance]] 141 | === Performance === 142 | 143 | Sie sollten entweder die Schwellen, ab denen die automatische Garbage 144 | Collection greift, deutlich herabsetzen, oder von Zeit zu Zeit 145 | `git gc` aufrufen. Dies hat einen offensichtlichen Vorteil, 146 | nämlich dass Plattenplatz gespart wird: 147 | 148 | [subs="macros,quotes"] 149 | -------- 150 | $ *du -sh .git* 151 | 20M .git 152 | $ *git gc* 153 | Counting objects: 3726, done. 154 | Compressing objects: 100% (1639/1639), done. 155 | Writing objects: 100% (3726/3726), done. 156 | Total 3726 (delta 1961), reused 2341 (delta 1279) 157 | Removing duplicate objects: 100% (256/256), done. 158 | $ *du -sh .git* 159 | 6.3M .git 160 | -------- 161 | 162 | Einzelne Objekte unterhalb von `.git/objects/` wurden zu einem 163 | Packfile zusammengefasst: 164 | 165 | [subs="macros,quotes"] 166 | -------- 167 | $ *ls -lh .git/objects/pack/pack-a97624dd23<...>.pack* 168 | -r-------- 1 feh feh 4.6M Jun 1 10:20 .git/objects/pack/pack-a97624dd23<...>.pack 169 | $ *file .git/objects/pack/pack-a97624dd23<...>.pack* 170 | .git/objects/pack/pack-a97624dd23<...>.pack: Git pack, version 2, 3726 objects 171 | -------- 172 | 173 | Sie können sich per `git count-objects` ausgeben lassen, aus 174 | wie vielen Dateien die Objektdatenbank besteht. Hier nebeneinander vor 175 | und nach dem obigen Packvorgang: 176 | 177 | [subs="macros,quotes"] 178 | -------- 179 | $ *git count-objects -v* 180 | count: 1905 count: 58 181 | size: 12700 size: 456 182 | in-pack: 3550 in-pack: 3726 183 | packs: 7 packs: 1 184 | size-pack: 4842 size-pack: 4716 185 | prune-packable: 97 prune-packable: 0 186 | garbage: 0 garbage: 0 187 | -------- 188 | 189 | Nun ist Plattenplatz billig, ein auf 30% komprimiertes Repository 190 | also kein großer Gewinn. Der Performance-Gewinn ist allerdings nicht 191 | zu verachten. In der Regel zieht ein Objekt (z.B. ein Commit) 192 | weitere Objekte nach sich (Blobs, Trees). Wenn Git also pro Objekt 193 | eine Datei öffnen muss (bei _n_ verwalteten Dateien also mindestens 194 | _n_ Blob-Objekte), dann sind dies _n_ Lese-Vorgänge auf dem 195 | Dateisystem. 196 | 197 | Packfiles haben zwei wesentliche Vorteile: Erstens legt Git zu jedem 198 | Packfile eine Indizierung an, die angibt, welches Objekt in welchem Offset 199 | der Datei zu finden ist. Zusätzlich hat die Packroutine noch eine 200 | gewisse Heuristik um die Objektplatzierung innerhalb der Datei zu optimieren 201 | (so dass bspw. ein Tree-Object und die davon referenzierten Blob-Objekte 202 | ``nah'' beieinander liegen). 203 | Dadurch kann Git einfach das Packfile in den Speicher mappen 204 | (Stichwort: ``sliding mmap''). Die Operation ``suche 205 | Objekt X'' ist dann nichts weiter als eine Lookup-Operation im 206 | Pack-Index und ein entsprechendes Auslesen der Stelle im Packfile, 207 | d.h. im Speicher. Dies entlastet das Datei- und Betriebssystem 208 | erheblich. 209 | 210 | Der zweite Vorteil der Packfiles liegt in der Delta-Kompression. So 211 | werden Objekte möglichst als 'Deltas' ('Veränderungen') 212 | anderer Objekte gespeichert.footnote:[Das ist nicht zu verwechseln mit 213 | Versionskontrollsystemen, die inkrementelle Versionen einer Datei 214 | speichern. Innerhalb von Packfiles werden die Objekte unabhängig von 215 | ihrem semantischen Zusammenhang, d.h. speziell ihrer zeitlichen 216 | Abfolge, gepackt.] Das spart Speicherplatz, ermöglicht aber 217 | andererseits auch Kommandos wie `git blame`, 218 | ``kostengünstig'', also ohne großen Rechenaufwand, Kopien 219 | von Code-Stücken zwischen Dateien zu entdecken. 220 | 221 | Der aggressive Modus sollte nur in begründeten Ausnahmefällen 222 | eingesetzt werden.footnote:[Eine ausführliche 223 | Auseinandersetzung mit dem Thema finden Sie unter 224 | http://metalinguist.wordpress.com/2007/12/06/the-woes-of-git-gc-aggressive-and-how-git-deltas-work/] 225 | 226 | [TIP] 227 | ======== 228 | Lassen Sie auf Ihren öffentlich zugänglichen Repositories auch 229 | regelmäßig, z.B. per Cron, ein `git gc` laufen. Commits werden über 230 | das Git-Protokoll immer als Packfiles übertragen, die 'on demand', das 231 | heißt zum Zeitpunkt des Abrufs, erzeugt werden. Wenn das gesamte 232 | Repository schon als ein großes Packfile vorliegt, können Teile daraus 233 | schneller extrahiert werden, und ein kompletter Clone des Repositorys 234 | benötigt keine zusätzlichen Rechenoperationen (es muss kein riesiges 235 | Packfile gepackt werden). Eine regelmäßige Garbage Collection kann 236 | also die Auslastung Ihres Servers senken, außerdem wird der 237 | Clone-Vorgang der Nutzer beschleunigt. 238 | 239 | Ist das Repository besonders groß, kann es bei einem `git clone` sehr 240 | lange dauern, bis der Server alle Objekte gezählt hat. Dies können Sie 241 | beschleunigen, indem Sie regelmäßig per Cron-Job `git repack -A -d -b` 242 | aufrufen: Git erstellt dann zusätzlich zu den Pack-Files eine 243 | Bitmap-Datei, die diesen Vorgang um ein bis zwei Größenordnungen 244 | beschleunigt. 245 | ======== 246 | 247 | -------------------------------------------------------------------------------- /vorwort.txt: -------------------------------------------------------------------------------- 1 | [[chap.vorwort]] 2 | == Vorwort == 3 | 4 | 5 | Git wurde Anfang 2005 von Linus Torvalds, dem Initiator 6 | und heutigen Maintainer des Linux-Kernels, entwickelt. Für die 7 | Verwaltung der Kernel-Quellen hatte sich das Entwickler-Team zunächst 8 | für das kommerzielle Versionsverwaltungssystem 'BitKeeper' 9 | entschieden. Probleme traten auf, als die Firma hinter BitKeeper, die 10 | das Tool dem Projekt kostenfrei zur Verfügung stellte, einen 11 | Entwickler beschuldigte, die Mechanismen der Software durch 12 | 'Reverse Engineering' offenzulegen. Daraufhin beschloss 13 | Torvalds, ein neues Versionskontrollsystem zu schreiben. 14 | 15 | Der bloße Umstieg auf ein anderes System bot sich nicht an: Die 16 | Alternativen hatten eine zentralistische Architektur und skalierten 17 | nicht gut genug. Die Anforderungen des Kernel-Projekts an ein 18 | Versionskontrollsystem sind allerdings auch gewaltig: Zwischen einem 19 | kleinen Versionssprung (z.B. 2.6.35 nach 2.6.36) liegen über 20 | 500000 geänderte Zeilen in knapp 1000 Dateien. Verantwortlich 21 | dafür sind über 1000 Einzelpersonen. 22 | 23 | Welche also waren die 'Design Goals' des neuen Programms? Zwei 24 | Eigenschaften kristallisierten sich rasch als Design-Ziele heraus: 25 | Schnelligkeit bzw. Performance und überprüfbare Integrität der 26 | verwalteten Daten. 27 | 28 | Nach nur wenigen Wochen Arbeit war eine erste Version von Git in der 29 | Lage, den eigenen Quellcode zu verwalten. Als kleine 30 | Shell-Script-Sammlung mit performance-kritischen Teilen in C 31 | implementiert war die Version von einem ``ausgewachsenen'' 32 | Versionskontrollsystem jedoch noch weit entfernt. 33 | 34 | Seit Version 1.5 (Februar 2007) bietet Git ein neues und 35 | aufgeräumteres Nutzer-Interface sowie umfangreiche Dokumentation, was 36 | auch Leuten die Benutzung erlaubt, die nicht unmittelbar in die 37 | Entwicklung von Git involviert sind. 38 | 39 | Die Grundkonzepte sind bis in aktuelle Versionen dieselben geblieben: 40 | Allen voran das Objektmodell und der Index, wesentliche Merkmale, die 41 | Git von anderen VCS unterscheidet. Die Unix-Philosophie ``Ein 42 | Tool, ein Job'' findet sich auch hier konsequent umgesetzt; die 43 | Subkommandos von Git sind jeweils eigenständige, ausführbare 44 | Programme oder Scripte. Auch in der 2.0er-Version sind noch (wie zu 45 | Beginn der Entwicklung) einige Subkommandos mit Shell-Scripten 46 | implementiert (z.B.{empty}{nbsp}`git pull`). 47 | 48 | Linus Torvalds selbst programmiert heute kaum noch an Git; wenige 49 | Monate nach dem ersten Release hat Junio C. Hamano die 50 | Aufgabe des Maintainers übernommen. 51 | 52 | Nicht nur der revolutionäre Ansatz von Git, auch die Tatsache, dass 53 | die gesamte Kernel-Entwicklung schnell und erfolgreich nach Git 54 | migriert wurde, hat Git einen steilen Aufstieg beschert. Viele, teils 55 | sehr große Projekte setzen heute Git ein und profitieren von der 56 | damit gewonnenen Flexibilität. 57 | 58 | [[sec.leser]] 59 | === An wen richtet sich dieses Buch? === 60 | 61 | Das Buch wendet sich gleichermaßen an professionelle 62 | Softwareentwickler wie Anwender, die kleine Scripte, Webseiten oder 63 | andere Dokumente bearbeiten oder aktiv in die Arbeit bei einem 64 | (Open-Source-)Projekt einsteigen wollen. Es vermittelt grundlegende 65 | Techniken der Versionsverwaltung, führt in die Grundlagen von Git ein 66 | und erläutert alle wesentlichen Anwendungsfälle. 67 | 68 | Arbeit, die Sie nicht mit einem Versionskontrollsystem verwalten, ist 69 | Arbeit, die Sie möglicherweise noch einmal machen müssen – sei es, 70 | weil Sie versehentlich eine Datei löschen oder Teile als obsolet 71 | betrachten, die Sie später doch wieder benötigen. Für jede Form 72 | produktiver Text- und Entwicklungsarbeit benötigen Sie ein Werkzeug, 73 | das Veränderungen an Dateien aufzeichnen und verwalten kann. Git ist 74 | flexibel, schnell und für kleine Projekte von Einzelpersonen genauso 75 | gut geeignet wie für umfangreiche Projekte mit Hunderten von 76 | Entwicklern wie z.B. den Linux-Kernel. 77 | 78 | Entwickler, die bereits mit einem anderen Versionskontrollsystem 79 | arbeiten, können von einer Umstellung auf Git profitieren. Git 80 | ermöglicht eine wesentlich flexiblere Arbeitsweise und ist in vielen 81 | Belangen nicht so restriktiv wie vergleichbare Systeme. Es unterstützt 82 | echtes Merging und garantiert die Integrität der verwalteten Daten. 83 | 84 | Auch Open-Source-Projekten bietet Git Vorteile, weil jeder Entwickler 85 | über sein eigenes Repository verfügt, was Streit um Commit-Rechte 86 | vorbeugt. Außerdem erleichtert Git Neulingen den Einstieg deutlich. 87 | 88 | Auch wenn sich die vorgestellten Beispiele und Techniken größtenteils 89 | auf Quellcode beziehen, besteht kein grundlegender Unterschied zur 90 | Verwaltung von Dokumenten, die in LaTeX, HTML, AsciiDoc oder 91 | verwandten Formaten geschrieben sind. 92 | 93 | [[sec.struktur]] 94 | === Wie ist das Buch zu lesen? === 95 | 96 | <> gibt einen kurzen Überblick: Wie initialisiert 97 | man ein Git-Repository und verwaltet Dateien darin? Außerdem werden 98 | die wichtigsten Konfigurationseinstellungen behandelt. 99 | 100 | <> behandelt zwei wesentliche Konzepte von Git: Den 101 | Index und das Objektmodell. Neben weiteren wichtigen Kommandos, die 102 | dort vorgestellt werden, ist das Verständnis dieser beiden Konzepte 103 | von großer Wichtigkeit für den sicheren Umgang mit Git. 104 | 105 | In <> geht es um praktische Aspekte der Versionsverwaltung. 106 | Vor allem werden die in Git so zentralen Branches und Merges 107 | behandelt. Auch auf die Behebung von Merge-Konflikten wird detailliert 108 | eingegangen. 109 | 110 | <> setzt sich mit fortgeschrittenen Konzepten auseinander, 111 | allen voran das Rebase-Kommando, ein unerlässliches Werkzeug für jeden 112 | Git-Profi. Es folgen weitere wichtige Kommandos, wie Blame, Stash und 113 | Bisect. 114 | 115 | Erst <> beschäftigt sich mit den verteilten Aspekten von 116 | Git: Wie kann man Veränderungen zwischen Repositories austauschen, wie 117 | können Entwickler zusammenarbeiten? Das anschließende <> 118 | gibt außerdem einen Überblick zu Strategien, wie Sie 119 | Entwicklungsarbeit in einem Projekt koordinieren. 120 | 121 | Wir empfehlen Ihnen, zumindest die ersten fünf Kapitel hintereinander 122 | zu lesen. Sie beschreiben alle wichtigen Konzepte und Techniken, um Git 123 | auch in großen Projekten sicher einzusetzen. Die nachfolgenden Kapitel 124 | können Sie, je nach Interesse und Bedarf, in beliebiger Reihenfolge 125 | lesen. 126 | 127 | <> behandelt Installation und Wartung von 128 | Git-Diensten: zwei Web-basierte Repository-Browser und die 129 | Zugriffsverwaltung für gehostete Repositories mit Gitolite. 130 | 131 | <> fasst diverse Aspekte der Automatisierung zusammen: Wie 132 | Sie Hooks und eigene Git-Kommandos schreiben und bei Bedarf die 133 | komplette Versionsgeschichte umschreiben. 134 | 135 | Schließlich geht es in <> um die Migration von anderen 136 | Systemen zu Git. Im Vordergrund steht hier die Konvertierung 137 | existierender Subversion-Repositories sowie die Möglichkeit, aus Git 138 | heraus mit Subversion zu sprechen. 139 | 140 | Die Anhänge beschäftigen sich mit der Installation und der 141 | Integration von Git in die Shell. Ein Ausblick auf den Hosting-Service 142 | 'Github' sowie eine detaillierte Beschreibung der Struktur und 143 | Wartungsmechanismen eines Git-Repositorys liefern weitere 144 | Hintergrundinformationen. 145 | 146 | [[sec.konventionen]] 147 | === Konventionen === 148 | 149 | Die Beispiele führen wir ausschließlich auf der Shell aus. Auch wenn 150 | einige Editoren und IDEs mittlerweile eine recht gelungene 151 | Git-Integration bieten und auch eine Vielzahl grafischer Frontends für Git 152 | existiert, sollten Sie doch zunächst die Grundlagen mit den echten 153 | Git-Kommandos erlernen. 154 | 155 | Das Shell-Prompt ist ein einzelnes Dollar-Zeichen (`$`); 156 | Tastatureingaben sind halbfett gedruckt, also z.B. so: 157 | 158 | [subs="macros,quotes"] 159 | --------- 160 | $ *git status* 161 | --------- 162 | 163 | 164 | Um sich in der Shell schneller und besser zurechtzufinden, empfehlen 165 | wir dringend, die Shell um Git-Funktionalität zu erweitern, wie z.B. 166 | die Anzeige des Branches im Prompt (siehe dazu 167 | <>). 168 | 169 | Sofern nicht anders vermerkt, beziehen wir uns auf Git in der 170 | Version 2.0. 171 | Die Beispiele laufen allesamt mit englischsprachigen 172 | Lokaleneinstellungen. Zwar gibt es seit 2012 für die Ausgabe-Texte der meisten 173 | Git-Kommandos auch deutsche Übersetzungen – diese klingen aber sehr 174 | gestelzt und sind aufgrund der Wortwahl häufig verwirrend. 175 | Außerdem finden Sie für originale, also 176 | englische Fehlermeldungen online schneller Hilfe. 177 | 178 | Neu eingeführte Begriffe sind 'kursiv' gesetzt, teilweise mit 179 | deutscher Entsprechung in Klammern dahinter. Die meisten 180 | Git-spezifischen Termini verwenden wir im Original mit von der 181 | Übersetzung abgeleitetem Artikel, z.B. der ``Branch'' statt der ``Zweig''. 182 | 183 | [[sec.install-git-repo]] 184 | === Installation und ``das Git-Repository'' === 185 | 186 | Die Installation von Git beschreiben wir ausführlich in <>. 187 | Einige Beispiele verwenden das 188 | Quell-Repository von Git, also das Repository, in dem Git aktiv 189 | entwickelt wird. In englischsprachiger Dokumentation heißt dieses 190 | Repository auch 'Git-via-Git' oder 'git.git'. 191 | 192 | Nachdem Sie Git installiert haben, können Sie sich das Repository mit 193 | folgendem Befehl herunterladen: 194 | 195 | [subs="macros,quotes"] 196 | ------------ 197 | $ *git clone git://git.kernel.org/pub/scm/git/git.git* 198 | ------------ 199 | 200 | Der Vorgang dauert je nach Verbindungsgeschwindigkeit und Auslastung 201 | des Servers einige Minuten. 202 | 203 | //\label{sec:hilfe} 204 | [[sec.doku]] 205 | === Dokumentation und Hilfe === 206 | 207 | Eine umfangreiche Dokumentation von Git liegt in Form vorinstallierter 208 | Man-Pages vor. Fast jedes Subkommando hat eine eigene Man-Page, die 209 | Sie auf drei äquivalente Weisen aufrufen können, hier z.B. für das 210 | Kommando `git status`: 211 | 212 | [subs="macros,quotes"] 213 | ------------ 214 | $ *git help status* 215 | $ *git status --help* 216 | $ *man git-status* 217 | ------------ 218 | 219 | Auf der 220 | Git-Webseite{empty}footnote:[http://git-scm.com/] 221 | finden Sie außerdem Links zum offiziellen Tutorial sowie zu anderen 222 | freien Dokumentationen. 223 | 224 | Rund um Git hat sich eine große, lebhafte Community gebildet. Die 225 | Git-Mailingliste{empty}footnote:[http://vger.kernel.org/vger-lists.html#git] 226 | ist Dreh- und Angelpunkt der Entwicklung: Dort werden 227 | Patches eingeschickt, Neuerungen diskutiert und auch Fragen zur 228 | Benutzung beantwortet. Allerdings ist die Liste, mit zuweilen über 100 teils sehr technischen E-Mails am Tag, nur eingeschränkt für Anfänger 229 | geeignet. 230 | 231 | Das 232 | Git-Wiki{empty}footnote:[https://git.wiki.kernel.org/index.php/Main_Page] 233 | enthält neben Dokumentation auch eine umfangreiche Linksammlung der 234 | Tools, die auf Git 235 | basieren{empty}footnote::[https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools], 236 | sowie 237 | FAQs{empty}footnote:[https://git.wiki.kernel.org/index.php/GitFaq]. 238 | 239 | Alternativ bietet der IRC-Kanal `#git` im Freenode-Netzwerk 240 | einen Anlaufpunkt, Fragen loszuwerden, die nicht schon in den FAQs 241 | oder in der Dokumentation beantwortet wurden. 242 | 243 | Umsteigern aus dem Subversion-Umfeld ist der 'Git-SVN Crash 244 | Course'{empty}footnote:[https://git.wiki.kernel.org/index.php/GitSvnCrashCourse] 245 | zu empfehlen, eine Gegenüberstellung von Git- und 246 | Subversion-Kommandos, mit der Sie Ihr Subversion-Wissen in die 247 | Git-Welt übertragen. 248 | 249 | Außerdem sei auf 250 | 'Stack Overflow'{empty}footnote:[http://stackoverflow.com] 251 | hingewiesen, eine Plattform von Programmierern für Programmierer, auf 252 | der technische Fragestellungen, u.a. zu Git, erörtert werden. 253 | 254 | [[sec.kontakt]] 255 | === Downloads und Kontakt === 256 | 257 | Die Beispiel-Repositories der ersten beiden Kapitel sowie eine 258 | Sammlung aller längeren Scripte stehen unter 259 | http://gitbu.ch/ zum Download bereit. 260 | 261 | Bei Anmerkungen kontaktieren Sie uns gerne per E-Mail unter einer der folgenden Adressen: 262 | kontakt@gitbu.ch, valentin@gitbu.ch bzw. julius@gitbu.ch. 263 | 264 | [[sec.dank]] 265 | === Danksagungen === 266 | 267 | Zunächst gilt unser Dank allen Entwicklern und Maintainern des 268 | Git-Projekts sowie der Mailing-Liste und dem IRC-Kanal. 269 | 270 | Vielen Dank an Sebastian Pipping und Frank Terbeck für Anmerkungen und 271 | Tipps. Besonders danken wir Holger Weiß für seine Durchsicht des 272 | Manuskripts und hilfreiche Ideen. Wir danken dem gesamten 273 | Open-Source-Press-Team für die gute und effiziente Zusammenarbeit. 274 | 275 | Unser Dank gilt vor allem unseren Eltern, die uns stets unterstützt 276 | und gefördert haben. 277 | 278 | Valentin Haenel und Julius Plenz – Berlin, Juni 2011 279 | 280 | [[chap.vorwort-2te-auflage]] 281 | === Vorwort zur 2. Auflage === 282 | 283 | Wir haben uns in der 2. Auflage darauf beschränkt, die 284 | Veränderungen in der Benutzung von Git, die bis Version 2.0 eingeführt 285 | wurden, behutsam aufzunehmen – tatsächlich sind heute viele Kommandos und 286 | Fehlermeldungen konsistenter, so dass dies an einigen 287 | Stellen einer wesentlichen Vereinfachung des Textes entspricht. 288 | Eingestreut finden sich, inspiriert von Fragen aus Git-Schulungen und 289 | unserer eigenen Erfahrung, neue Hinweise auf Probleme, Lösungsansätze 290 | und interessante Funktionalitäten. 291 | 292 | Wir danken allen Einsendern von Korrekturen an der ersten Auflage: 293 | Philipp Hahn, Ralf Krüdewagen, Michael Prokop, Johannes Reinhold, Heiko 294 | Schlichting, Markus Weber. 295 | 296 | Valentin Haenel und Julius Plenz – Berlin, September 2014 297 | 298 | [[chap.vorwort-cc-ausgabe]] 299 | === Vorwort zur CreativeCommons-Ausgabe === 300 | 301 | Der Verlag 'Open Source Press', der uns initial überzeugte, überhaupt 302 | dieses Buch zu schreiben und es die vergangenen Jahre über verlegte, hat 303 | zum 31.12.2015 den Betrieb eingestellt, und sämtliche Rechte an den 304 | veröffentlichten Texten an die Autoren zurückübertragen. Wir danken 305 | insbesondere Markus Wirtz für die immer gute und produktive 306 | Zusammenarbeit, die uns über viele Jahre verbunden hat. 307 | 308 | Aufgrund hauptsächlich sehr positiven Feedbacks zu diesem Text haben wir 309 | uns entschieden, diesen unter einer CreativeCommons-Lizens frei verfügbar 310 | zu machen. 311 | 312 | Valentin Haenel und Julius Plenz – Berlin/Sydney, Januar 2016 313 | 314 | // vim:set tw=72 ft=asciidoc: 315 | -------------------------------------------------------------------------------- /workflows.txt: -------------------------------------------------------------------------------- 1 | [[sec.workflows]] 2 | == Workflows 3 | 4 | Mit 'Workflows' (dt. 'Arbeitsabläufe') werden in der 5 | Software-Entwicklung in der Regel Strategien bezeichnet, die 6 | Arbeitsabläufe im Team definieren (z.B. die 'Agile 7 | Softwareentwicklung'). Wir können uns bei diesem Thema allgemein 8 | hier nur auf Literaturhinweise 9 | beschränken.footnote:[Zu empfehlen ist u.a. 10 | das dritte Kapitel von 'Open Source Projektmanagement' von 11 | Michael Prokop (Open Source Press, München, 2010). Auch das 12 | 'Manifesto for Agile Software Development' hält unter 13 | http://agilemanifesto.org/ aufschlussreiche Hinweise 14 | bereit.] 15 | 16 | In Git kann man ``Workflows'' unter zwei Aspekten sehen: 17 | Abläufe (Kommandosequenzen), die den einzelnen Nutzer betreffen, sowie 18 | projektbezogene Arbeitsabläufe (z.B. Release-Management). Auf beide 19 | Aspekte wird im Folgenden eingegangen. 20 | 21 | [[sec.workflows-user]] 22 | === Anwender === 23 | 24 | Nachfolgend finden Sie eine Auflistung genereller 25 | Entwicklungsstrategien (ohne bestimmte Reihenfolge): 26 | 27 | 28 | 'Machen Sie möglichst kleine, eigenständige Commits':: Unterteilen Sie 29 | Ihre Arbeit in kleine, logische Schritte und tätigen Sie für jeden 30 | Schritt einen Commit. Die Commits sollten unabhängig von zukünftigen 31 | Commits sein und möglichst alle Tests (sofern vorhanden) bestehen. Das 32 | erleichtert es Ihren Kollegen bzw. den Maintainern, nachzuvollziehen, 33 | was Sie gemacht haben. Außerdem steigert es den Wirkungsgrad von 34 | Kommandos, die die Geschichte untersuchen, bspw. `git bisect` und `git 35 | blame`. Haben Sie keine Angst, zu kleine Commits zu tätigen. Es ist im 36 | Nachhinein einfacher, mehrere kleine Commits mit `git rebase 37 | --interactive` zusammenzufassen als einen großen in mehrere kleine zu 38 | teilen. 39 | 40 | 'Entwickeln Sie in Topic-Branches':: Branching geht in Git leicht, 41 | schnell und intuitiv vonstatten. Anschließendes Mergen funktioniert 42 | problemlos, auch wiederholt. Nutzen Sie diese Flexibilität von Git: 43 | Entwickeln Sie nicht direkt in `master`, sondern jedes Feature in 44 | seinem eigenen Branch, genannt 'Topic-Branch'. 45 | + 46 | Dadurch bieten sich einige Vorteile: Sie können Features unabhängig 47 | voneinander entwickeln; Sie erhalten einen wohldefinierten Zeitpunkt 48 | der Integration (Merge); Sie können die Entwicklung per Rebase 49 | ``stromlinienförmig'' und übersichtlich gestalten, bevor Sie sie 50 | veröffentlichen; Sie erleichtern es anderen Entwicklern, ein neues 51 | Feature isoliert zu testen. 52 | 53 | 'Verwenden Sie Namespaces':: Sie können durch `/`-Zeichen im 54 | Branch-Namen verschiedene Klassen von Branches kreieren. In einem 55 | zentralen Repository können Sie sich durch Ihre Initialen einen 56 | eigenen Namensraum schaffen (z.B.{empty}{nbsp}`jp/refactor-base64`) oder Ihre 57 | Features je nach Stabilität unter `experimental/` oder `pu/` (s.u.) 58 | ablegen. 59 | 60 | 'Rebase early, Rebase often':: Wenn Sie auf Topic-Branches häufig mit 61 | Rebase arbeiten, erzeugen Sie eine deutlich lesbarere 62 | Versionsgeschichte. Das ist für Sie und andere Entwickler praktisch 63 | und hilft, den eigentlichen Programmiervorgang in logische Einheiten 64 | aufzuteilen. 65 | + 66 | Verschmelzen Sie Kleinstcommits, wenn sie zusammengehören. Nehmen Sie 67 | sich bei Bedarf die Zeit, große Commits noch einmal sinnvoll 68 | aufzuteilen (siehe <>). 69 | + 70 | Verwenden Sie allerdings Rebase nur für eigene Commits: Verändern Sie 71 | keinesfalls bereits veröffentlichte Commits oder die Commits anderer 72 | Entwickler. 73 | 74 | 'Unterscheiden Sie bewusst zwischen FF- und regulären Merges':: 75 | Integrieren Sie Änderungen aus dem Upstream immer per Fast-Forward 76 | (Sie spulen die lokale Kopie der Branches einfach vor). Integrieren 77 | Sie im Gegensatz dazu neue Features durch reguläre Merges. Hilfreich 78 | für die Unterscheidung sind auch die in <> vorgestellten 79 | Aliase. 80 | 81 | 'Beachten Sie die Merge-Richtung':: Das Kommando `git merge` zieht 82 | einen oder mehrere Branches in den aktuellen hinein. Beachten Sie 83 | daher immer die Richtung, in der Sie einen Merge durchführen: 84 | Integrieren Sie Topic-Branches in die 'Mainline' (den Branch, auf dem 85 | Sie das stabile Release vorbereiten), nicht umgekehrt.footnote:[Eine 86 | Ausnahme besteht, wenn Sie eine neue Entwicklung in der Mainline in 87 | Ihrem Topic-Branch benötigen; in dem Fall können Sie allerdings auch 88 | überlegen, den Topic-Branch per Rebase neu aufzubauen, so dass er die 89 | benötigte Funktionalität schon beinhaltet.] Auf diese Weise können 90 | Sie auch im Nachhinein noch die Geschichte eines Features von der 91 | Mainline isolieren (`git log topic` listet nur die relevanten Commits 92 | auf). 93 | + 94 | 'Criss-Cross-Merges' (überkreuzte Merges) sind nach Möglichkeit zu 95 | vermeiden: Sie entstehen, wenn Sie einen Branch A in einen Branch B 96 | und eine ältere Version von B in A integrieren. 97 | 98 | 'Testen Sie die Verträglichkeit von Features per Throw-Away-Integration':: 99 | Erstellen Sie einen neuen (Wegwerf-)Branch 100 | und mergen Sie die Features, deren Kompatibilität Sie testen 101 | wollen. Lassen Sie die Testsuite laufen oder testen Sie das 102 | Zusammenspiel der neuen Komponenten auf andere Weise. Den Branch 103 | können Sie anschließend löschen und die Features weiter getrennt 104 | voneinander entwickeln. Solche 'Throw-Away'-Branches werden in der 105 | Regel nicht veröffentlicht. 106 | 107 | Gewisse Arbeitsschritte tauchen wieder und wieder auf. Im Folgenden 108 | ein paar allgemeine Lösungsstrategien: 109 | 110 | 111 | 'Einen kleinen Bug fixen':: Wenn Sie einen kleinen 112 | Bug bemerken, den Sie schnell korrigieren wollen, können Sie das 113 | auf zwei Arten tun: vorliegende Änderungen per Stash in den 114 | Hintergrund schieben (siehe <>), den 115 | entsprechenden Branch auschecken, den Bug beheben, wieder den 116 | Branch wechseln und den Stash anwenden. 117 | + 118 | Die andere Möglichkeit besteht darin, auf dem Branch, auf dem Sie 119 | gerade arbeiten, den Fehler zu beheben und nachträglich den/die 120 | entsprechenden Commit(s) per Cherry-Pick oder Rebase-Onto (siehe 121 | <> bzw. <>) 122 | in den dafür vorgesehenen Bugfix- oder Topic-Branch zu übernehmen. 123 | 124 | 'Einen Commit korrigieren':: Mit `git commit --amend` können Sie den letzten Commit anpassen. Die Option `--no-edit` bewirkt, dass die Beschreibung beibehalten und nicht erneut zur Bearbeitung angeboten wird. 125 | + 126 | Um tiefer liegende Commits zu korrigieren, verwenden Sie entweder 127 | interaktives Rebase und das `edit`-Keyword (siehe 128 | <>) oder Sie erstellen für jede 129 | Korrektur einen kleinen Commit, ordnen diese schließlich im 130 | interaktiven Rebase entsprechend an und versehen sie mit der 131 | Aktion `fixup`, um den ursprünglichen Commit zu 132 | korrigieren. 133 | 134 | 'Welche Branches sind noch nicht in'{empty}{nbsp}`master`?:: Verwenden Sie `git branch -vv --no-merged`, um herauszufinden, welche Branches noch nicht in den aktuellen Branch integriert sind. 135 | 136 | 'Mehrere Änderungen aus unterschiedlichen Quellen zusammenfassen':: 137 | Nutzen Sie den Index, um mehrere Änderungen 138 | zusammenzufassen, z.B. Änderungen, die einander 139 | ergänzen, aber in verschiedenen Branches oder als Patches 140 | vorliegen. Die Kommandos `git apply`, `git 141 | cherry-pick --no-commit` sowie `git merge --squash` 142 | wenden die entsprechenden Änderungen nur auf den Working Tree bzw. 143 | Index an, ohne einen Commit zu erzeugen. 144 | 145 | 146 | 147 | [[sec.branch-modell]] 148 | === Ein Branching-Modell === 149 | 150 | Der folgende Abschnitt stellt ein Branching-Modell vor, das an das in 151 | der Man-Page `gitworkflows(7)` beschriebene Modell 152 | angelehnt ist. Das Branching-Modell bestimmt, welcher Branch 153 | welche Funktionen erfüllt, wann und wie Commits aus einem Branch übernommen 154 | werden, welche Commits als Releases getaggt werden sollen usw. Es ist flexibel, 155 | skaliert gut und kann bei Bedarf erweitert werden (s.u.). 156 | 157 | In seiner Grundform besteht das Modell aus vier Branches: 158 | `maint`, `master`, `next`, und `pu` 159 | ('Proposed Updates'). Der `master`-Branch dient vor allem 160 | der Vorbereitung des nächsten Releases und zum Sammeln trivialer 161 | Änderungen. `pu`-Branch(es) dienen der Feature-Entwicklung 162 | (Topic-Branches). In dem Branch `next` werden halbwegs 163 | stabile neue Features gesammelt, im Verbund auf Kompatibilität, 164 | Stabilität und Korrektheit getestet und bei Bedarf verbessert. Auf dem 165 | `maint`-Branch werden kritische Bug-Fixes für vorangegangene 166 | Versionen gesammelt und als Maintenance-Releases veröffentlicht. 167 | 168 | Prinzipiell werden Commits immer durch einen Merge in einen anderen 169 | Branch integriert (in <> durch Pfeile 170 | angedeutet). Im Gegensatz zum Cherry-Picking werden dabei Commits 171 | nicht gedoppelt, und Sie können einem Branch leicht ansehen, ob er 172 | einen bestimmten Commit schon enthält oder nicht. 173 | 174 | Das folgende Diagramm ist eine schematische Darstellung des zehn 175 | Punkte umfassenden Workflows, der unten detailliert erläutert wird. 176 | 177 | 178 | .Branch-Modell gemäß `gitworkflows (7)` 179 | image::bilder_ebook/branch-model.png[id="fig.branch-model",scaledwidth="90%",width="90%"] 180 | 181 | . Neue Topic-Branches entstehen von 182 | wohldefinierten Punkten, z.B. getaggten Releases, auf dem 183 | `master`. 184 | + 185 | [subs="macros,quotes"] 186 | -------- 187 | $ *git checkout -b pu/cmdline-refactor v0.1* 188 | -------- 189 | 190 | . Hinreichend stabile Features werden aus ihrem 191 | jeweiligen `pu`-Branch nach `next` übernommen 192 | ('Feature Graduation'). 193 | + 194 | [subs="macros,quotes"] 195 | -------- 196 | $ *git checkout next* 197 | $ *git merge pu/cmdline-refactor* 198 | -------- 199 | 200 | . Releasevorbereitung: Wenn sich genügend neue Features in 201 | `next` (featuregetriebene Entwicklung) angesammelt haben, wird 202 | `next` nach `master` gemergt und ggf. ein Release-Candidate-Tag 203 | (RC-Tag) erzeugt (Suffix `-rc`). 204 | + 205 | [subs="macros,quotes"] 206 | -------- 207 | $ *git checkout master* 208 | $ *git merge next* 209 | $ *git tag -a v0.2-rc1* 210 | -------- 211 | 212 | . Von nun an werden nur noch sogenannte 'Release-Critical Bugs' 213 | (RC-Bugs) direkt im `master` korrigiert. Es handelt sich hierbei um 214 | ``Show-Stopper'', also Bugs, die die Funktionalität der Software 215 | maßgeblich einschränken oder neue Features unbenutzbar machen. 216 | Gegebenenfalls können Sie Merges von problematischen Branches wieder 217 | rückgängig machen (siehe <>). 218 | + 219 | Was während der Release-Phase mit `next` passiert, hängt von 220 | der Größe des Projekts ab. Sind alle Entwickler damit beschäftigt, 221 | die RC-Bugs zu beheben, so bietet sich ein Entwicklungsstopp für 222 | `next` an. Bei größeren Projekten, wo während der 223 | Release-Phase schon die Entwicklung für das übernächste Release 224 | vorangetrieben wird, kann `next` weiterhin als 225 | Integrations-Branch für neue Features dienen. 226 | 227 | . Sind alle RC-Bugs getilgt, wird der `master` als Release getaggt und 228 | ggf. als Quellcode-Archiv, Distributions-Paket usw. veröffentlicht. 229 | Außerdem wird `master` nach `next` gemergt, um alle Fixes für RC-Bugs 230 | zu übertragen. Wurden in der Zwischenzeit keine weiteren Commits auf 231 | `next` getätigt, so ist dies ein Fast-Forward-Merge. Nun können auch 232 | wieder neue Topic-Branches aufgemacht werden, die auf dem neuen 233 | Release basieren. 234 | + 235 | [subs="macros,quotes"] 236 | -------- 237 | $ *git tag -a v0.2* 238 | $ *git checkout next* 239 | $ *git merge master* 240 | -------- 241 | 242 | . Feature-Branches, die es nicht ins Release 243 | geschafft haben, können nun entweder in den `next`-Branch 244 | gemergt werden, oder aber, falls sie noch nicht fertig sind, per 245 | Rebase auf eine neue, wohldefinierte Basis aufgebaut werden. 246 | + 247 | [subs="macros,quotes"] 248 | -------- 249 | $ *git checkout pu/numeric-integration* 250 | $ *git rebase next* 251 | -------- 252 | 253 | . Um Feature-Entwicklung sauber von Bug-Fixes und 'Maintenance' 254 | (``Instandhaltung'') zu trennen, werden Bug-Fixes, die eine 255 | vorangegangene Version betreffen, im Branch `maint` getätigt. Dieser 256 | Maintenance-Branch zweigt, wie die Feature-Branches auch, an 257 | wohldefinierten Stellen von `master` ab. 258 | 259 | . Haben sich genügend Bug-Fixes angesammelt oder wurde ein kritischer 260 | Bug behoben, z.B. ein Security-Bug, wird der aktuelle Commit auf dem 261 | `maint`-Branch als Maintenance-Release getaggt und kann über die 262 | gewohnten Kanäle publiziert werden. 263 | + 264 | [subs="macros,quotes"] 265 | -------- 266 | $ *git checkout maint* 267 | $ *git tag -a v0.1.1* 268 | -------- 269 | + 270 | Manchmal kommt es vor, dass Bug-Fixes, die auf `master` gemacht 271 | wurden, auch in `maint` gebraucht werden. In diesem Fall ist es 272 | in Ordnung, diese per `git cherry-pick` dorthin zu übertragen. 273 | Das sollte aber eher die Ausnahme als die Regel sein. 274 | 275 | . Damit Bug-Fixes auch künftig verfügbar sind, wird der `maint`-Branch 276 | nach einem Maintenance-Release nach `master` gemergt. 277 | + 278 | [subs="macros,quotes"] 279 | -------- 280 | $ *git checkout master* 281 | $ *git merge maint* 282 | -------- 283 | + 284 | Sind die Bug-Fixes sehr dringend, können sie mit `git cherry-pick` in 285 | den entsprechenden Branch (`next` oder `pu/*`) übertragen 286 | werden. Wie bei einem `git cherry-pick` nach `maint` auch, sollte 287 | dies nur selten passieren. 288 | 289 | . Bei einem neuen Release wird der `maint`-Branch per Fast-Forward auf 290 | den Stand von `master` gebracht, so dass `maint` nun auch alle Commits 291 | enthält, die das neue Release ausmachen. Ist hier kein Fast-Forward 292 | möglich, ist das ein Anzeichen dafür, dass sich noch Bug-Fixes in 293 | `maint` befinden, die nicht in `master` sind (siehe Punkt 9). 294 | + 295 | [subs="macros,quotes"] 296 | -------- 297 | $ *git checkout maint* 298 | $ *git merge --ff-only master* 299 | -------- 300 | 301 | Das Branching-Modell können Sie beliebig erweitern. Ein Ansatz, den 302 | man oft antrifft, ist die Verwendung von 'Namespaces' (siehe 303 | <>) im Zusatz zu den 304 | `pu/*`-Branches. Das hat den Vorteil, dass jeder Entwickler 305 | einen eigenen Namensraum verwendet, der per Konvention abgegrenzt ist. 306 | Eine andere, sehr beliebte Erweiterung ist es, für jede vorangegangene 307 | Version einen eigenen `maint`-Branch zu erhalten. Dadurch wird 308 | es möglich, beliebig viele ältere Versionen zu pflegen. Dazu wird vor 309 | dem Merge von `maint` nach `master` in Punkt 9 310 | ein entsprechender Branch für die Version erstellt. 311 | 312 | [subs="macros,quotes"] 313 | -------- 314 | $ *git branch maint-v0.1.2* 315 | -------- 316 | 317 | 318 | 319 | 320 | 321 | Bedenken Sie aber, dass diese zusätzlichen Maintenance-Branches einen 322 | erhöhten Wartungsaufwand bedeuten, da jeder neue Bug-Fix geprüft 323 | werden muss. Ist er auch für eine ältere Version relevant, muss er per 324 | `git cherry-pick` in den Maintenance-Branch für die Version 325 | eingebaut werden. Außerdem muss ggf. eine neue Maintenance-Version 326 | getaggt und veröffentlicht werden. 327 | 328 | 329 | 330 | 331 | [[sec.releases-management]] 332 | === Releases-Management === 333 | 334 | Sobald ein Projekt mehr als nur ein, zwei Entwickler hat, ist es in 335 | der Regel sinnvoll, einen Entwickler mit dem Management der Releases 336 | zu beauftragen. Dieser 'Integration Manager' entscheidet nach 337 | Rücksprache mit den anderen (z.B. über die Mailingliste), welche 338 | Branches integriert und wann neue Releases erstellt werden. 339 | 340 | Jedes Projekt hat eigene Anforderungen an den Release-Ablauf. 341 | Nachfolgend einige generelle Tipps, wie Sie die Entwicklung überwachen 342 | und den Release-Prozess teilweise automatisieren können.footnote:[Weitere Anregungen finden Sie im 343 | Kapitel 6 des Buches 'Open Source Projektmanagement' von Michael 344 | Prokop (Open Source Press, München, 2010).] 345 | 346 | [[sec.release-check-branches]] 347 | ==== Aufgaben sondieren ==== 348 | 349 | Der Maintainer einer Software muss einen guten Überblick über die 350 | Features haben, die aktiv entwickelt und bald integriert werden 351 | sollen. In den meisten Entwicklungsmodellen 'graduieren' Commits 352 | von einem Branch auf den nächsten -- im oben vorgestellten Modell 353 | zunächst aus den `pu`-Branches nach `next` und dann 354 | nach `master`. 355 | 356 | Zunächst sollten Sie Ihre lokalen Branches immer aufräumen, um nicht 357 | den Überblick zu verlieren. Dabei hilft besonders das Kommando 358 | `git branch --merged master`, das alle Branches auflistet, 359 | die schon vollständig in `master` (oder einen 360 | anderen Branch) integriert sind. Diese können Sie in der Regel 361 | löschen. 362 | 363 | Um einen groben Überblick zu erhalten, welche Aufgaben anstehen, 364 | empfiehlt es sich, `git show-branch` einzusetzen. Ohne weitere 365 | Argumente listet es alle lokalen Branches auf, jeden mit einem 366 | Ausrufezeichen (`!`) in eigener Farbe. Der aktuelle Branch 367 | erhält einen Stern (`*`). Unterhalb der Ausgabe werden alle 368 | Commits ausgegeben sowie für jeden Branch in der jeweiligen Spalte ein 369 | Plus (`+`) bzw. ein Stern (`*`), wenn der Commit Teil 370 | des Branches ist. Ein Minus (`-`) signalisiert Merge-Commits. 371 | 372 | 373 | 374 | [subs="macros,quotes"] 375 | -------- 376 | $ *git show-branch* 377 | ! [for-hjemli] initialize buf2 properly 378 | * [master] Merge branch \'stable' 379 | ! [z-custom] silently discard "error opening directory" messages 380 | --- 381 | + [for-hjemli] initialize buf2 properly 382 | -- [master] Merge branch \'stable' 383 | +* [master\^2] Add advice about scan-path in cgitrc.5.txt 384 | +* [master\^2\^] fix two encoding bugs 385 | +* [master\^] make enable-log-linecount independent of -filecount 386 | +* [master\~2] new_filter: correctly initialise ... for a new filter 387 | +* [master\~3] source_filter: fix a memory leak 388 | + [z-custom] silently discard "error opening directory" messages 389 | + [z-custom^] Highlight odd rows 390 | + [z-custom\~2] print upstream modification time 391 | + [z-custom\~3] make latin1 default charset 392 | +*+ [master~4] CGIT 0.9 393 | -------- 394 | 395 | 396 | Es werden nur so viele Commits gezeigt, bis eine gemeinsame 397 | Merge-Basis aller Commits gefunden wird (im Beispiel: 398 | `master~4`). Wollen Sie nicht alle Branches 399 | gleichzeitig untersuchen, sondern z.B. nur die Branches unter 400 | `pu/`, dann geben Sie dies explizit als Argument an. 401 | `--topics ` bestimmt `` als 402 | Integrations-Zweig, dessen Commits nicht explizit angezeigt werden. 403 | 404 | Das folgende Kommando zeigt Ihnen also alle Commits aller 405 | `pu`-Branches und deren Relation zu `master`: 406 | 407 | [subs="macros,quotes"] 408 | -------- 409 | $ *git show-branch --topics master "pu/*"* 410 | -------- 411 | 412 | 413 | 414 | [TIP] 415 | ======== 416 | Es lohnt sich, die Kommandos, die Sie zum Release-Management 417 | verwenden, zu dokumentieren (so dass andere Ihre Aufgaben eventuell 418 | weiterführen können). Außerdem sollten Sie gängige Schritte durch 419 | Aliase abkürzen. 420 | 421 | Das o.g. Kommando könnten Sie wie folgt in ein Alias `todo` 422 | umwandeln: 423 | 424 | [subs="macros,quotes"] 425 | -------- 426 | $ *git config --global alias.todo \* 427 | *"!git rev-parse --symbolic --branches | \* 428 | *xargs git show-branch --topics master"* 429 | -------- 430 | ======== 431 | 432 | 433 | Das Kommando `git show-branch` erkennt allerdings nur 434 | 'gleiche', das heißt identische Commits. Wenn Sie einen Commit 435 | per `git cherry-pick` in einen anderen Branch übernehmen, sind 436 | die Änderungen fast die gleichen, `git show-branch` würde dies 437 | aber nicht erkennen, da sich die SHA-1-Summe des Commits ändert. 438 | 439 | Für diese Fälle ist das Tool `git cherry` zuständig. Es 440 | verwendet intern das kleine Tool `git-patch-id`, das einen 441 | Commit auf seine bloßen Änderungen reduziert. Dabei werden 442 | Whitespace-Änderungen sowie die kontextuelle Position der Hunks 443 | (Zeilennummern) ignoriert. Das Tool liefert also für Patches, die 444 | essentiell die gleiche Änderung einbringen, die gleiche ID. 445 | 446 | In der Regel wird `git cherry` eingesetzt, wenn sich die Frage 447 | stellt: Welche Commits wurden schon in den Integrations-Branch 448 | übernommen? Dafür wird das Kommando `git cherry -v 449 | ` verwendet: Es listet alle Commits aus `` auf, 450 | und stellt ihnen ein Minus (`-`) voran, wenn sie schon in 451 | `` sind, ansonsten ein Plus (`+`). Das sieht z.B. 452 | so aus: 453 | 454 | [subs="macros,quotes"] 455 | -------- 456 | $ *git cherry --abbrev=7 -v master z-custom* 457 | + ae8538e guess default branch from HEAD 458 | - 6f70c3d fix two encoding bugs 459 | - 42a6061 Add advice about scan-path in cgitrc.5.txt 460 | + cd3cf53 make latin1 default charset 461 | + 95f7179 Highlight odd rows 462 | + bbaabe9 silently discard "error opening directory" messages 463 | -------- 464 | 465 | 466 | Zwei der Patches wurden schon nach `master` übernommen. Das 467 | erkennt `git cherry`, obwohl sich die Commit-IDs dabei geändert 468 | haben. 469 | 470 | 471 | 472 | 473 | 474 | [[sec.release-create]] 475 | ==== Release erstellen ==== 476 | 477 | Git bietet die folgenden zwei nützlichen Werkzeuge, um ein Release 478 | vorzubereiten: 479 | 480 | 481 | `git shortlog`:: Fasst die Ausgabe von `git log` zusammen. 482 | 483 | `git archive`:: Erstellt automatisiert ein Quellcode-Archiv. 484 | 485 | 486 | 487 | Zu einem guten Release gehört ein sogenanntes 'Changelog', also 488 | eine Zusammenfassung der wichtigsten Neuerungen inklusive 489 | Danksagungen an Personen, die Hilfe beigesteuert haben. Hier kommt 490 | `git shortlog` zum Einsatz. Das Kommando zeigt die jeweiligen 491 | Autoren, wie viele Commits jeder gemacht hat und die Commit-Messages 492 | der einzelnen Commits. So ist sehr gut ersichtlich, wer was gemacht 493 | hat. 494 | 495 | [subs="macros,quotes"] 496 | -------- 497 | $ *git shortlog HEAD~3..* 498 | Georges Khaznadar (1): 499 | bugfix: 3294518 500 | 501 | Kai Dietrich (6): 502 | delete grammar tests in master 503 | updated changelog and makefile 504 | in-code version number updated 505 | version number in README 506 | version number in distutils setup.py 507 | Merge branch \'prepare-release-0.9.3' 508 | 509 | Valentin Haenel (3): 510 | test: add trivial test for color transform 511 | test: expose bug with ID 3294518 512 | Merge branch \'fix-3294518' 513 | -------- 514 | 515 | 516 | Mit der Option `--numbered` bzw. `-n` wird die 517 | Ausgabe, statt alphabetisch, nach der Anzahl der Commits sortiert. Mit 518 | `--summary` bzw. `-s` fallen die Commit-Nachrichten 519 | weg. 520 | 521 | Sehen Sie aber im Zweifel davon ab, einfach die Ausgabe von 522 | `git log` oder `git shortlog` in die Datei 523 | `CHANGELOG` zu schreiben. Gerade bei vielen, technischen 524 | Commits ist das Changelog dann nicht hilfreich (wen diese 525 | Informationen interessieren, der kann immer im Repository 526 | nachschauen). Sie können aber die Ausgabe als Grundlage nehmen, 527 | unwichtige Änderungen löschen und die restlichen zu sinnvollen 528 | Gruppen zusammenfassen. 529 | 530 | 531 | [TIP] 532 | ======== 533 | Oft stellt sich für den Maintainer die Frage, was sich seit dem 534 | letzten Release verändert hat. Hier hilft 535 | `git-describe` (siehe <>), das in 536 | Verbindung mit `--abbrev=0` das erste erreichbare Tag vom 537 | `HEAD` aus ausgibt: 538 | 539 | [subs="macros,quotes"] 540 | -------- 541 | $ *git describe* 542 | wiki2beamer-0.9.2-20-g181f09a 543 | $ *git describe --abbrev=0* 544 | wiki2beamer-0.9.2 545 | -------- 546 | 547 | In Kombination mit `git shortlog` lässt sich die gestellte 548 | Frage sehr einfach beantworten: 549 | 550 | [subs="macros,quotes"] 551 | -------- 552 | $ *git shortlog -sn $(git describe --abbrev=0)..* 553 | 15 Kai Dietrich 554 | 4 Valentin Haenel 555 | 1 Georges Khaznadar 556 | -------- 557 | ======== 558 | 559 | Das Kommando `git archive` hilft beim Erstellen eines 560 | Quellcode-Archivs. Das Kommando beherrscht sowohl das Tar- als auch 561 | das Zip-Format. Zusätzlich können Sie mit der Option 562 | `--prefix=` ein Präfix für die zu speichernden Dateien 563 | setzen. Die oberste Ebene des Repositorys wird dann unterhalb dieses 564 | Präfix abgelegt, üblicherweise der Name und die Versionsnummer der 565 | Software: 566 | 567 | [subs="macros,quotes"] 568 | -------- 569 | $ *git archive --format=zip --prefix=wiki2beamer-0.9.3/ HEAD \* 570 | *> wiki2beamer-0.9.3.zip* 571 | $ *git archive --format=tar --prefix=wiki2beamer-0.9.3/ HEAD \* 572 | *| gzip > wiki2beamer-0.9.3.tgz* 573 | -------- 574 | 575 | Als zwingendes Argument erwartet das Kommando einen Commit (bzw. einen 576 | Tree), der als Archiv gepackt werden soll. Im o.g. Beispiel ist das 577 | `HEAD`. Es hätte aber auch eine Commit-ID, eine Referenz 578 | (Branch oder Tag) oder direkt ein Tree-Objekt sein können.footnote:[Jeder Commit referenziert 579 | genau einen Tree. Allerdings verhält sich `git archive` 580 | verschieden, je nachdem, ob Sie einen Commit (der einen Tree 581 | referenziert) oder einen Tree direkt angeben: Der Zeitpunkt der 582 | letzten Modifikation, der im Archiv aufgenommen wird, ist bei Trees 583 | die Systemzeit -- bei einem Commit allerdings wird der Zeitpunkt des 584 | Commits gesetzt.] 585 | 586 | Auch hier können Sie `git describe` einsetzen, nachdem Sie 587 | einen Release-Commit getaggt haben. Bei einem geeigneten Tag-Schema 588 | `-` wie oben reicht dann folgendes Kommando: 589 | 590 | [subs="macros,quotes"] 591 | -------- 592 | $ *version=$(git describe)* 593 | $ *git archive --format=zip --prefix=$version/ HEAD > $version.zip* 594 | -------- 595 | 596 | 597 | Es kann sein, dass nicht alle Dateien, die Sie in Ihrem Git-Repository 598 | verwalten, auch in den Quellcode-Archiven vorkommen sollten, z.B. 599 | die Projekt-Webseite. Sie können zusätzlich noch Pfade angeben -- um 600 | also das Archiv auf das Verzeichnis `src` und die Dateien 601 | `LICENSE` und `README` zu beschränken, verwenden Sie: 602 | 603 | [subs="macros,quotes"] 604 | -------- 605 | $ *version=$(git describe)* 606 | $ *git archive --format=zip --prefix=$version/ HEAD src LICENSE README \* 607 | *> $version.zip* 608 | -------- 609 | 610 | 611 | Git speichert, sofern Sie einen Commit als Argument angeben, die 612 | SHA-1-Summe mit im Archiv ab. Im Tar-Format wird dies als 613 | 'Pax-Header-Eintrag' mit eingespeichert, den Git mit dem Kommando 614 | `git get-tar-commit-id` wieder auslesen kann: 615 | 616 | [subs="macros,quotes"] 617 | -------- 618 | $ *zcat wiki2beamer-0.9.3.tgz | git get-tar-commit-id* 619 | 181f09a469546b4ebdc6f565ac31b3f07a19cecb 620 | -------- 621 | 622 | In Zip-Dateien speichert Git die SHA-1-Summe einfach im Kommentarfeld: 623 | 624 | [subs="macros,quotes"] 625 | -------- 626 | $ *unzip -l wiki2beamer-0.9.3.zip | head -5* 627 | Archive: wiki2beamer-0.9.3.zip 628 | 181f09a469546b4ebdc6f565ac31b3f07a19cecb 629 | Length Date Time Name 630 | --------- ---------- ----- ---- 631 | 0 05-06-2011 20:45 wiki2beamer-0.9.3/ 632 | -------- 633 | 634 | [TIP] 635 | ======== 636 | Ein Problem, das Sie bedenken sollten, ist, dass zum Beispiel 637 | `.gitignore`-Dateien automatisch mit gepackt werden. Da sie aber 638 | außerhalb eines Git-Repositorys keine Bedeutung haben, lohnt es sich, 639 | sie mit dem Git-Attribut (siehe <>) `export-ignore` 640 | auszuschließen. Das geschieht durch einen Eintrag `.gitignore 641 | export-ignore` in `.git/info/attributes`. 642 | 643 | Auch können Sie vor dem Einpacken des Archivs automatische 644 | Keyword-Ersetzungen vornehmen (siehe 645 | <>). 646 | ======== 647 | 648 | 649 | // vim:set tw=72 ft=asciidoc: 650 | -------------------------------------------------------------------------------- /shell.txt: -------------------------------------------------------------------------------- 1 | [[sec.shell-integration]] 2 | == Shell-Integration == 3 | 4 | Da Sie Git-Kommandos zumeist auf der Shell ausführen, sollten Sie 5 | diese um Funktionalität erweitern, um mit Git zu interagieren. Gerade 6 | für Git-Anfänger ist ein solches Zusammenspiel zwischen Shell und Git 7 | sehr hilfreich, um nicht den Überblick zu verlieren. 8 | 9 | In zwei Bereichen kann die Shell Ihnen besonders helfen: 10 | 11 | * Anzeige wichtiger Informationen zu einem Repository im 12 | 'Prompt' (Eingabeaufforderung). So müssen Sie nicht allzu 13 | häufig `git status` und Konsorten aufrufen. 14 | 15 | * Eine maßgeschneiderte 'Completion' (automatische 16 | Vervollständigung) hilft, Git-Kommandos direkt richtig 17 | einzugeben, auch wenn die genaue Syntax nicht bekannt ist. 18 | 19 | 20 | 21 | 22 | Ein gutes Prompt sollte zusätzlich zum aktuellen Branch den Zustand 23 | des Working Tree signalisieren. Gibt es Veränderungen, die noch nicht 24 | gespeichert sind? Befinden sich schon Veränderungen im Index? 25 | 26 | Eine gute Completion sollte etwa bei der Eingabe von `git 27 | checkout` und dem anschließenden Drücken der Tab-Taste nur Branches 28 | aus dem Repository zur Vervollständigung anbieten. Wenn Sie aber 29 | `git checkout --` eingeben, sollten nur Dateien vervollständigt 30 | werden. Das spart Zeit und schützt vor Tippfehlern. Auch andere 31 | Vervollständigungen sind sinnvoll, z.B. die vorhandenen 32 | Remotes bei `git push` und `git pull`. 33 | 34 | In diesem Kapitel stellen wir grundlegende Rezepte für zwei 35 | beliebte Shells vor: die 'Bash' und die 36 | 'Z-Shell'. Anleitungen für andere interaktive Shells finden Sie 37 | ggf. im Internet. 38 | 39 | Das Thema Shell-Integration ist sehr umfangreich, daher stellen die 40 | hier vorgestellten Anleitungen lediglich Anhaltspunkte und Ideen dar 41 | und erheben keinen Anspruch auf Vollständigkeit. Es kommt erschwerend 42 | hinzu, dass die Git-Community die Benutzerschnittstelle -- also die 43 | vorhandenen Subkommandos und deren Optionen -- sehr schnell 44 | weiterentwickelt. Bitte wundern Sie sich daher nicht, wenn die 45 | Completion teilweise ``hinterherhinkt'' und brandneue 46 | Subkommandos und Optionen (noch) nicht verfügbar sind. 47 | 48 | [[sec.bash-integration]] 49 | === Git und die Bash === 50 | 51 | Sowohl die Funktionalität für die Completion als auch die 52 | Status-Kommandos für das Prompt sind in einem Script namens 53 | `git-completion.bash` implementiert. Es wird zusammen mit den 54 | Quellen für Git verwaltet. Sie finden die Datei im Verzeichnis 55 | `contrib/completion` des 56 | Git-Projekts. Häufig wird die Completion auch 57 | schon von Ihrer Distribution bzw. dem Git-Installer für Ihr 58 | Betriebssystem bereitgestellt. Haben Sie bei Debian oder Ubuntu das 59 | Paket `git` installiert, sollte die Datei bereits unter 60 | `/usr/share/bash-completion/completions/git` vorliegen. In Gentoo installieren 61 | Sie die Datei über das USE-Flag `bash-completion` von 62 | `dev-vcs/git`. Der aktuelle Maintainer ist Shawn O. Pearce. 63 | 64 | [[sec.bash-completion]] 65 | ==== Completion ==== 66 | 67 | Um die Completion zu aktivieren, laden Sie das Script mit dem Befehl 68 | `source` und übergeben als Argument die entsprechende Datei, 69 | also z.B.: 70 | 71 | -------- 72 | source ~/Downloads/git-2.1.0/contrib/completion/git-completion.bash 73 | -------- 74 | 75 | 76 | 77 | Die Completion vervollständigt unter anderem: 78 | 79 | 80 | 81 | Git-Subkommandos:: Geben Sie bspw. `git pu[TAB]` ein, 82 | bietet Ihnen die Bash `pull` und `push` an: 83 | + 84 | [subs="macros,quotes"] 85 | -------- 86 | $ *git pu[TAB]* 87 | pull push 88 | -------- 89 | + 90 | Anmerkung: Nur die 'Porcelain'-Kommandos sowie 91 | Benutzeraliase sind verfügbar. Externe- und 92 | 'Plumbing'-Kommandos sind nicht implementiert. Subkommandos, die 93 | selber über weitere Subkommandos verfügen, z.B.{empty}{nbsp}`git remote` 94 | oder `git stash`, werden ebenfalls vervollständigt: 95 | + 96 | [subs="macros,quotes"] 97 | -------- 98 | $ *git remote [TAB]* 99 | add prune rename rm set-head show update 100 | -------- 101 | 102 | Lokale Branches und Tags:: Nützlich für Subkommandos, wie 103 | `checkout` und `rebase`, die eine lokale Referenz 104 | erwarten: 105 | + 106 | [subs="macros,quotes"] 107 | -------- 108 | $ *git branch* 109 | * master 110 | refactor-cmd-line 111 | refactor-profiling 112 | $ *git checkout refactor-[TAB]* 113 | refactor-cmd-line refactor-profiling 114 | -------- 115 | 116 | 117 | Konfigurierte Remotes:: Kommandos wie `git fetch` und 118 | `git remote` werden oft mit einem Remote als Argument aufgerufen. Auch hier 119 | hilft die Completion weiter: 120 | + 121 | [subs="macros,quotes"] 122 | -------- 123 | $ *git remote show [TAB]* 124 | github sourceforge 125 | -------- 126 | 127 | 128 | Remote Branches und Tags:: Die Completion kann auch auf der 129 | Remote-Seite ``nachsehen'', welche Referenzen vorhanden sind. 130 | Das erfolgt zum Beispiel beim Kommando `git pull`, das eine 131 | Remote-Referenz bzw. eine Refspec erwartet: 132 | + 133 | [subs="macros,quotes"] 134 | -------- 135 | $ *git pull origin v1.7.1[TAB]* 136 | v1.7.1 v1.7.1.2 v1.7.1.4 v1.7.1-rc1 137 | v1.7.1.1 v1.7.1.3 v1.7.1-rc0 v1.7.1-rc2 138 | -------- 139 | + 140 | Das funktioniert natürlich nur, wenn das Remote-Repository verfügbar 141 | ist. In den meisten Fällen ist eine Netzwerkverbindung sowie 142 | mindestens Lesezugriff notwendig. 143 | 144 | Optionen:: Die meisten Subkommandos verfügen 145 | über diverse 'Long Options' wie z.B.{empty}{nbsp}`--bare`. 146 | Die Completion kennt diese in der Regel und vervollständigt sie 147 | entsprechend: 148 | + 149 | [subs="macros,quotes"] 150 | -------- 151 | $ *git diff --color[TAB]* 152 | --color --color-words 153 | -------- 154 | + 155 | 'Short Options', wie z.B.{empty}{nbsp}`-a`, werden nicht komplettiert. 156 | 157 | Dateien:: Für Git-Kommandos, die Dateinamen erwarten. Gute 158 | Beispiele sind `git add` sowie `git checkout`: 159 | + 160 | [subs="macros,quotes"] 161 | -------- 162 | $ *git add [TAB]* 163 | .git/ hello.py README test/ 164 | $ *git checkout -- [TAB]* 165 | .git/ hello.py README test/ 166 | -------- 167 | 168 | Git-Konfigurationsoptionen:: Die Bash-Completion für Git 169 | vervollständigt auch Konfigurationsoptionen, die Sie mit `git 170 | config` einstellen: 171 | + 172 | [subs="macros,quotes"] 173 | -------- 174 | $ *git config user.[TAB]* 175 | user.email user.name user.signingkey 176 | -------- 177 | 178 | Wie bei der Bash-Completion üblich, wird die Eingabe automatisch 179 | vervollständigt, sobald sie eindeutig ist. Existiert nur der Branch 180 | `feature`, führt die Eingabe von `git checkout fe[TAB]` 181 | dazu, dass `fe` vervollständigt wird; der Befehl `git 182 | checkout feature` steht dann auf der Kommandozeile -- drücken Sie 183 | auf Enter, um den Befehl auszuführen. Nur wenn die Eingabe nicht 184 | eindeutig ist, zeigt die Bash die möglichen Vervollständigungen an. 185 | 186 | [[sec.bash-prompt]] 187 | ==== Prompt ==== 188 | 189 | Neben der Completion gibt es ein weiteres Script, um Infos über das 190 | Git-Repository im Prompt anzuzeigen. Dafür müssen Sie die Datei 191 | `contrib/completion/git-prompt.sh` laden (ggf. ist diese auch von Ihrer 192 | Distribution installiert, z.B. unter `/usr/lib/git-core/git-sh-prompt`). 193 | Setzen Sie anschließend -- wie in folgendem Beispiel -- einen 194 | Aufruf der Funktion `__git_ps1` in die Variable `PS1` 195 | ein. Als Argument nimmt die Funktion einen sogenannten 196 | 'Format-String-Ausdruck' entgegen -- d.h. die Zeichenfolge 197 | `%s` wird durch Git-Infos ersetzt, alle anderen Zeichen werden 198 | übernommen. 199 | 200 | -------- 201 | source /usr/lib/git-core/git-sh-prompt 202 | PS1='\u@\h \w$(__git_ps1 " (%s)") $ ' 203 | -------- 204 | 205 | 206 | Die Zeichen werden wie folgt ersetzt: `\u` ist der 207 | Benutzername, `\h` der Rechnername, 208 | `\w` ist das aktuelle Arbeitsverzeichnis und 209 | `$(__git_ps1 " (%s)")` sind die Git-Infos, die ohne 210 | zusätzliche Konfiguration (s.u.) nur aus dem Branch-Namen bestehen: 211 | 212 | [subs="macros,quotes"] 213 | -------- 214 | pass:quotes[esc@creche] \~ $ *cd git-working/git* 215 | pass:quotes[esc@creche] ~/git-working/git (master) $ 216 | -------- 217 | 218 | Mit dem Format-String-Ausdruck passen Sie die Darstellung der 219 | Git-Infos an, indem Sie zusätzliche Zeichen oder aber Farbcodes 220 | nutzen, z.B. mit folgendem Prompt: 221 | 222 | -------- 223 | PS1='\u@\h \w$(__git_ps1 " (git)-[%s]") $ ' 224 | -------- 225 | 226 | Das sieht dann so aus: 227 | 228 | -------- 229 | esc@creche ~/git-working/git (git)-[master] $ 230 | -------- 231 | 232 | Ist der aktuelle Commit nicht durch einen Branch referenziert 233 | (Detached-HEAD), wird entweder das Tag oder die abgekürzte 234 | SHA-1-Summe angezeigt, jeweils von einem Klammerpaar umgeben: 235 | 236 | -------- 237 | esc@creche ~/git-working/git (git)-[(v1.7.1.4)] $ 238 | esc@creche ~/git-working/git (git)-[(e760924...)] $ 239 | -------- 240 | 241 | Befinden Sie sich innerhalb des `$GIT_DIR` oder in einem 242 | Bare-Repository, wird dies entsprechend signalisiert: 243 | 244 | -------- 245 | esc@creche ~/git-working/git/.git (git)-[GIT_DIR!] $ 246 | esc@creche ~/git-working/git.git/.git (git)-[BARE:master] $ 247 | -------- 248 | 249 | Außerdem wird angezeigt, wenn Sie sich mitten in einem Merge-Vorgang, 250 | einem Rebase oder einem ähnlichem Zustand befinden, bei dem nur 251 | bestimmte Operationen möglich sind: 252 | 253 | -------- 254 | esc@creche ~/git-working/git (git)-[master|REBASE-i] $ 255 | -------- 256 | 257 | 258 | Sie können die Anzeige auch erweitern, um sich den Zustand des Working 259 | Trees durch verschiedene Symbole anzeigen zu lassen. Sie müssen dazu 260 | folgende Umgebungsvariablen auf einen 'Non-Empty'-Wert setzen, also 261 | z.B. auf `1`. 262 | 263 | 264 | `GIT_PS1_SHOWDIRTYSTATE`:: Bei Veränderungen, die noch nicht im Index 265 | sind ('unstaged'), wird ein Sternchen (`*`) angezeigt. Bei 266 | Veränderungen, die bereits im Index sind ('staged'), wird ein Plus 267 | (`+`) angezeigt. Die Anzeige erfordert, dass der Working Tree gelesen 268 | wird -- dadurch verlangsamt sich die Shell evtl. bei großen 269 | Repositories (Git muss jede Datei auf Modifikationen überprüfen). Sie 270 | können dieses Verhalten daher mit der Git-Variable 271 | `bash.showDirtyState` für einzelne Repositories deaktivieren: 272 | + 273 | [subs="macros,quotes"] 274 | -------- 275 | $ *git config bash.showDirtyState false* 276 | -------- 277 | 278 | 279 | `GIT_PS1_SHOWSTASHSTATE`:: Sollten Sie einen oder 280 | mehrere Stashes angelegt haben, wird dies im Prompt durch das 281 | Dollar-Zeichen (`$`) signalisiert. 282 | 283 | `GIT_PS1_SHOWUNTRACKEDFILES`:: Die Existenz 284 | unbekannter Dateien ('untracked files') wird mit 285 | Prozent-Zeichen (`%`) angezeigt. 286 | 287 | 288 | Alle diese Zusatzinformationen können Sie wie folgt aktivieren: 289 | 290 | -------- 291 | GIT_PS1_SHOWDIRTYSTATE=1 292 | GIT_PS1_SHOWSTASHSTATE=1 293 | GIT_PS1_SHOWUNTRACKEDFILES=1 294 | -------- 295 | 296 | Wenn im Repository nun alles zutrifft (also 'unstaged', 297 | 'staged', 'stashed' und 'untracked') werden vier 298 | zusätzliche Zeichen (`*`, `+`, `$` und 299 | `%`) im Prompt angezeigt: 300 | 301 | -------- 302 | esc@creche ~/git-working/git (git)-[master *+$%] $ 303 | -------- 304 | 305 | In neueren Git-Versionen verfügt das Script über ein 306 | neues Feature, das die Beziehung zum Upstream-Branch 307 | (`@{upstream}`) anzeigt. Aktivieren Sie diese Funktion durch 308 | Setzen von `GIT_PS1_SHOWUPSTREAM` auf den Wert 309 | `git`.footnote:[Benutzen Sie 310 | `git-svn`, können Sie das Script anweisen, statt des 311 | Upstream-Branchs den SVN-Upstream (`remotes/git-svn`) für den 312 | Vergleich zu verwenden (sofern dieser vorhanden ist), indem Sie die 313 | Variable auf den Wert `auto` setzen.] Das Prompt 314 | signalisiert dann alle Zustände, die in <> 315 | beschrieben sind: 'up-to-date' mit dem Gleichheitszeichen 316 | (`=`); 'ahead' mit dem Größer-als-Zeichen (`>`); 317 | 'behind' mit dem Kleiner-als-Zeichen (`<`); 318 | 'diverged' mit sowohl einem Größer-als-Zeichen und einem 319 | Kleiner-als-Zeichen (`><`). Zum Beispiel: 320 | 321 | -------- 322 | esc@creche ~/git-working/git (git)-[master >] $ 323 | -------- 324 | 325 | 326 | Diese Funktion ist mit der Option `--count` des 327 | Plumbing-Kommandos `git rev-list` implementiert, die in alten 328 | Git-Versionen, etwa 1.7.1, noch nicht existiert. Haben Sie eine solche 329 | alte Git-Version, aber ein aktuelles Script und wollen diese Anzeige 330 | trotzdem verwenden, setzen Sie den Wert der Umgebungsvariablen auf 331 | `legacy` -- das Script verwendet dann eine alternative 332 | Implementation, die ohne die besagte Option auskommt. Wenn Sie 333 | außerdem noch wissen wollen, wie weit der Branch vorne bzw. zurück 334 | liegt, fügen Sie den Wert `verbose` hinzu. Das Prompt zeigt 335 | dann auch noch die Anzahl der unterschiedlichen Commits an: 336 | 337 | -------- 338 | esc@creche ~/git-working/git (git)-[master u+2] $ 339 | -------- 340 | 341 | 342 | Die gewünschten Werte sind der Umgebungsvariable als Liste zuzuweisen: 343 | 344 | -------- 345 | GIT_PS1_SHOWUPSTREAM="legacy verbose git" 346 | -------- 347 | 348 | [[sec.zsh-integration]] 349 | === Git und die Z-Shell === 350 | 351 | Sowohl Completion- als auch Prompt-Funktionen werden bei der Z-Shell 352 | immer mitgeliefert. 353 | 354 | [TIP] 355 | ======== 356 | Die Z-Shell verfügt über ein sehr nützliches Feature, um Man-Pages 357 | aufzurufen: die `run-help` Funktion. Sie wird im Emacs-Modus 358 | standardmäßig mit 'Esc+H' aufgerufen und zeigt für das 359 | Kommando, das bereits auf der Kommandozeile steht, die Man-Page an: 360 | 361 | [subs="macros,quotes"] 362 | -------- 363 | $ *man[ESC]+[h]* 364 | #Man-Page man(1) wird angezeigt 365 | -------- 366 | 367 | Da Git aber aus Subkommandos besteht und jedes Subkommando eine eigene 368 | Man-Page hat, funktioniert `run-help` nicht sonderlich gut -- 369 | es wird immer nur die Man-Page `git(1)` angezeigt. Hier schafft 370 | die mitgelieferte Funktion `run-help-git` Abhilfe: 371 | 372 | [subs="macros,quotes"] 373 | -------- 374 | $ *git rebase[ESC]\+[h]* 375 | #Man-Page git(1) wird angezeigt 376 | $ *unalias run-help* 377 | $ *autoload run-help* 378 | $ *autoload run-help-git* 379 | $ *git rebase[ESC]+[h]* 380 | #Man-Page git-rebase(1) wird angezeigt 381 | -------- 382 | ======== 383 | 384 | 385 | [[sec.zsh-completion]] 386 | ==== Completion ==== 387 | 388 | Um die Completion für Git zu aktivieren, laden Sie zunächst das Completion-System: 389 | 390 | [subs="macros,quotes"] 391 | -------- 392 | $ *autoload -Uz compinit && compinit* 393 | -------- 394 | 395 | 396 | Die Completion vervollständigt unter anderem: 397 | 398 | 399 | 400 | Git-Subkommandos:: Subkommandos werden in der Z-Shell ebenfalls 401 | vervollständigt. Der Unterschied zur Bash ist, dass die Z-Shell 402 | zusätzlich zum eigentlichen Kommando noch eine Kurzbeschreibung 403 | anzeigt: 404 | + 405 | [subs="macros,quotes"] 406 | -------- 407 | $ *git pu[TAB]* 408 | pull -- fetch from and merge with a remote repository 409 | push -- update remote refs along with associated objects 410 | -------- 411 | + 412 | Das gleiche gilt auch für Subkommandos, die wiederum selbst 413 | Subkommandos haben: 414 | + 415 | [subs="macros,quotes"] 416 | -------- 417 | $ *git remote [TAB]* 418 | add -- add a new remote 419 | prune -- delete all stale tracking branches for a given remote 420 | rename -- rename a remote from .git/config and update all... 421 | rm -- remove a remote from .git/config and all... 422 | show -- show information about a given remote 423 | update -- fetch updates for a set of remotes 424 | -------- 425 | + 426 | Sowie auch Benutzeraliase: 427 | + 428 | [subs="macros,quotes"] 429 | -------- 430 | $ *git t[TAB]* 431 | tag -- create tag object signed with GPG 432 | tree -- alias for \'log --oneline --graph --decorate -23' 433 | -------- 434 | 435 | Lokale Branches und Tags:: Die Z-Shell vervollständigt ebenfalls 436 | lokale Branches und Tags -- hier also kein Unterschied zur Bash. 437 | 438 | Konfigurierte Remotes:: Konfigurierte Remotes sind der Z-Shell 439 | bekannt. Für Subkommandos, bei denen nur ein konfiguriertes Remote in 440 | Frage kommt, z.B.{empty}{nbsp}`git remote show`, werden auch nur konfigurierte 441 | Remotes angezeigt. Sollte dies nicht eindeutig sein, wie z.B. bei 442 | `git pull`, dann greifen zusätzliche Mechanismen der Z-Shell und es 443 | wird meist eine lange Liste angezeigt, die sich unter anderem aus den 444 | Einträgen in den Dateien `.ssh/config` (die konfigurierten SSH-Hosts) 445 | und `.ssh/known_hosts` (Hosts, auf denen Sie sich schon mal eingeloggt 446 | haben) besteht. 447 | 448 | Optionen:: Im Gegensatz zur Bash kennt die Z-Shell sowohl lange als 449 | auch kurze Optionen und zeigt sie inklusive einer Kurzbeschreibung der 450 | Option. Hier ein Auszug: 451 | + 452 | [subs="macros,quotes"] 453 | -------- 454 | $ *git branch -[TAB]* 455 | -a -- list both remote-tracking branches and local branches 456 | --contains -- only list branches which contain the specified commit 457 | --force -f -- force the creation of a new branch 458 | -------- 459 | 460 | Dateien:: Die Z-Shell ist ebenfalls in der Lage, Dateinamen zu 461 | vervollständigen -- sie stellt sich aber etwas schlauer an als die 462 | Bash. Zum Beispiel werden für `git add` und `git checkout` nur Dateien 463 | angeboten, die tatsächlich Veränderungen haben -- also Dateien, die 464 | entweder dem Index hinzugefügt oder zurückgesetzt werden 465 | können. Dateien, die nicht in Betracht kommen, werden auch nicht 466 | angeboten. 467 | 468 | Git-Konfigurationsoptionen:: Die Z-Shell-Completion für Git 469 | vervollständigt, wie die Bash auch, sämtliche Konfigurationsoptionen 470 | für Git. Der Unterschied ist, dass auch hier eine Kurzbeschreibung 471 | der Optionen mit angezeigt wird: 472 | + 473 | [subs="macros,quotes"] 474 | -------- 475 | $ *git config user.[TAB]* 476 | email -- email address used for commits 477 | name -- full name used for commits 478 | signingkey -- default GPG key to use when creating signed tags 479 | -------- 480 | 481 | Ein großer Unterschied bei der Z-Shell ist die Art und Weise, wie 482 | vervollständigt wird. Die Z-Shell verwendet die sogenannte 483 | 'Menu-Completion'. Das bedeutet, dass Ihnen die Z-Shell durch 484 | erneutes Drücken der Tab-Taste jeweils die nächste mögliche 485 | Vervollständigung anbietet.footnote:[Die 486 | Man-Page `zshcompsys(1)` beschreibt, wie Sie die Completion 487 | noch weiter anpassen. Besonders die Optionen `group-name` und 488 | `menu-select` sind zu empfehlen.] 489 | 490 | [subs="macros,quotes"] 491 | -------- 492 | $ *git pu[TAB]* 493 | pull -- fetch from and merge with another repository or local branch 494 | push -- update remote refs along with associated objects 495 | $ *git pu[TAB]* 496 | $ *git pull[TAB]* 497 | $ git push 498 | -------- 499 | 500 | Die Z-Shell ist (noch) nicht in der Lage, Referenzen auf der 501 | Remote-Seite zu vervollständigen -- dies steht jedoch auf der 502 | To-do-Liste. Die Z-Shell ist aber heute schon in der Lage, Dateien über 503 | eine SSH-Verbindung hinweg zu vervollständigen. Besonders nützlich 504 | ist dies im Zusammenhang mit Public-Key-Authentifizierung und 505 | vorkonfigurierten SSH-Hosts. Angenommen, Sie haben folgenden Host in 506 | `.ssh/config` konfiguriert: 507 | 508 | -------- 509 | Host example 510 | HostName git.example.com 511 | User max 512 | -------- 513 | 514 | Auf dem Server in Ihrem Home-Verzeichnis befinden sich Ihre Projekte 515 | als Bare-Repositories: `projekt1.git` und 516 | `projekt2.git`. Außerdem haben Sie einen SSH-Schlüssel 517 | generiert und diesen in der Datei `.ssh/authorized_keys` auf 518 | dem Server abgelegt. Sie können nun die Vervollständigung über die 519 | SSH-Verbindung hinweg nutzen. 520 | 521 | [subs="macros,quotes"] 522 | -------- 523 | $ *git clone example:[TAB]* 524 | projekt1.git/ projekt2.git/ 525 | -------- 526 | 527 | 528 | Möglich wird dies durch die Completion-Funktionen der Z-Shell für 529 | `ssh`. 530 | 531 | 532 | [[sec.zsh-prompt]] 533 | ==== Prompt ==== 534 | 535 | Die Z-Shell beinhaltet Funktionen, um das Prompt mit Git-Infos zu 536 | versehen. Die Funktionalität ist Teil des umfangreichen 537 | `vcs_info`-Systems, das neben Git circa ein 538 | Dutzend anderer Programme zur Versionsverwaltung kennt, inklusive 539 | Subversion, CVS und Mercurial. Die ausführliche Dokumentation finden 540 | Sie in der Man-Page `zshcontrib(1)`, im Abschnitt 541 | ``Gathering Information From Version Control Systems''. Hier 542 | stellen wir nur die für Git relevanten Einstellungen und 543 | Anpassungsmöglichkeiten vor. 544 | 545 | Zunächst müssen Sie `vcs_info` laden und das Prompt so 546 | anpassen, dass Git-Infos angezeigt werden. Hierbei ist wichtig, dass 547 | die Z-Shell-Option `prompt_subst` gesetzt ist; sie sorgt 548 | dafür, dass Variablen im Prompt auch tatsächlich ersetzt werden, 549 | außerdem müssen Sie die Funktion `vcs_info` in der Funktion 550 | `precmd` aufrufen. `precmd` wird direkt vor 551 | der Anzeige des Prompts aufgerufen. Der Aufruf `vcs_info` 552 | darin sorgt dafür, dass die Git-Infos auch tatsächlich in der Variable 553 | `${vcs_info_msg_0_}` gespeichert werden. Fügen Sie Ihrer 554 | `.zshrc` folgende Zeilen hinzu, falls sie noch nicht enthalten 555 | sind: 556 | 557 | -------- 558 | # vcs_info laden 559 | autoload -Uz vcs_info 560 | # prompt_subst aktivieren 561 | setopt prompt_subst 562 | # precmd definieren 563 | precmd () { vcs_info } 564 | # Prompt setzten 565 | PS1='%n@%m %~${vcs_info_msg_0_} $ ' 566 | -------- 567 | 568 | Das Prompt setzt sich wie folgt zusammen: `%n` ist der 569 | Benutzername, `%m` ist der Rechnername, 570 | `%~` das aktuelle Arbeitsverzeichnis und die 571 | Variable `${vcs_info_msg_0_}` enthält die Git-Infos. 572 | Wichtig ist dabei, dass das Prompt mit einfachen Anführungszeichen 573 | ('single quotes') angegeben wird. Dadurch wird die 574 | 'Zeichenfolge'{empty}{nbsp}`${vcs_info_msg_0_}` und nicht der 575 | Wert der Variablen abgespeichert. Erst bei Anzeige des Prompt wird 576 | der Wert der Variablen -- also die Git-Infos -- substituiert. 577 | 578 | Die o.g. Einstellung für `PS1` sieht so aus: 579 | 580 | -------- 581 | esc@creche ~/git-working/git (git)-[master]- $ 582 | -------- 583 | 584 | 585 | Da `vcs_info` mit sehr vielen Versionsverwaltungssystemen 586 | funktioniert, lohnt es sich, nur diejenigen zu aktivieren, die Sie 587 | tatsächlich verwenden:footnote:[Eine Liste 588 | der verfügbaren Systeme erhalten Sie mit einem Aufruf der 589 | Funktion `vcs_info_printsys`.] 590 | 591 | -------- 592 | zstyle ':vcs_info:*' enable git 593 | -------- 594 | 595 | Zum Anpassen von `vcs_info` verwenden Sie einen sogenannten 596 | `zstyle`, einen hierarchischen Konfigurationsmechanismus der 597 | Z-Shell, der in der Man-Page `zshmodules(1)` beschrieben ist. 598 | 599 | Besondere Zustände wie Merge- oder Rebase-Vorgänge werden entsprechend 600 | signalisiert: 601 | 602 | -------- 603 | esc@creche ~/git-working/git (git)-[master|bisect]- $ 604 | -------- 605 | 606 | 607 | Auch bei einem Detached-HEAD wird entweder das Tag oder die 608 | abgekürzte SHA-1-Summe angezeigt: 609 | 610 | -------- 611 | esc@creche ~/git-working/git (git)-[v1.7.1.4] $ 612 | esc@creche ~/git-working/git (git)-[e760924...] $ 613 | -------- 614 | 615 | Die Z-Shell kann, wie die Bash auch, Zustände des Working Trees 616 | anzeigen. Schalten Sie dies mit folgender Zeile an: 617 | 618 | -------- 619 | zstyle ':vcs_info:git*:*' check-for-changes true 620 | -------- 621 | 622 | So zeigt `vcs_info` für Veränderungen, die noch nicht im Index 623 | sind ('unstaged'), ein `U` an und für Veränderungen, die 624 | Sie im Index aufgenommen haben ('staged'), ein `S`: 625 | 626 | -------- 627 | esc@creche ~/git-working/git (git)-[master]US- $ 628 | -------- 629 | 630 | 631 | Ein großer Vorteil von `vcs_info` ist, dass es sich sehr 632 | leicht anpassen lässt. Gefallen Ihnen etwa die Buchstaben `U` 633 | und `S` nicht, können Sie sie durch andere Zeichen z.B.{empty}{nbsp}`*` und `+` ersetzen: 634 | 635 | -------- 636 | zstyle ':vcs_info:git*:*' unstagedstr '*' 637 | zstyle ':vcs_info:git*:*' stagedstr '+' 638 | 639 | -------- 640 | 641 | Somit ähnelt das Zsh-Prompt nun immer mehr dem Beispiel aus dem 642 | Abschnitt zur Bash: 643 | 644 | -------- 645 | esc@creche ~/git-working/git (git)-[master]*+- $ 646 | -------- 647 | 648 | 649 | Um solche noch nicht gespeicherten Informationen anzuzeigen, 650 | muss `vcs_info` immer den Working Tree 651 | untersuchen. Da dies bei großen Repositories bekanntlich Probleme 652 | bereitet, können Sie bestimmte Muster ausschließen: 653 | 654 | -------- 655 | zstyle ':vcs_info:*' disable-patterns "/home/esc/git-working/linux-2.6(|/*)" 656 | -------- 657 | 658 | Vielleicht möchten Sie nun noch die Reihenfolge der Zeichen ändern. 659 | In dem Fall müssen Sie zwei Format-String Ausdrücke anpassen: 660 | `formats` und `actionformats`. Der erste ist das 661 | Standardformat, der zweite das Format, wenn Sie sich mitten in einem 662 | Merge-Vorgang, Rebase oder ähnlichem befinden: 663 | 664 | -------- 665 | zstyle ':vcs_info:git*:*' formats " (%s)-[%b%u%c]" 666 | zstyle ':vcs_info:git*:*' actionformats " (%s)-[%b|%a%u%c]" 667 | -------- 668 | 669 | Eine Auswahl der wichtigsten Zeichen finden Sie in der folgenden 670 | Tabelle. Eine detaillierte Auflistung bietet die oben erwähnte 671 | Man-Page. 672 | 673 | `%s`:: Versionsverwaltungssystem, in unserem Fall immer `git` 674 | 675 | `%b`:: Aktueller Branch, z.B.{empty}{nbsp}`master` 676 | 677 | `%a`:: Aktueller Vorgang, z.B.{empty}{nbsp}`merge` oder `rebase-i` (nur bei 678 | `actionformats`) 679 | 680 | `%u`:: Zeichen zur Anzeige von Veränderungen, die noch nicht im Index 681 | sind, z.B.{empty}{nbsp}`U` 682 | 683 | `%c`:: Zeichen zur Anzeige von Veränderungen, die schon im Index sind, z.B.{empty}{nbsp}`S` 684 | 685 | Mit der o.g. Einstellung sieht das Prompt dann so aus: 686 | 687 | -------- 688 | esc@creche ~/git-working/git (git)-[master*+] $ 689 | -------- 690 | 691 | 692 | Leider kann `vcs_info` standardmäßig die Existenz unbekannter 693 | Dateien und angelegter Stashes nicht signalisieren. Das System 694 | unterstützt aber ab Z-Shell Version 4.3.11 sogenannte 695 | 'Hooks' -- Erweiterungen, die zusätzliche Information in das 696 | Prompt einschleusen. Wir werden nun zwei solcher Hooks vorstellen, die 697 | die beiden genannten, fehlenden Features implementieren. 698 | 699 | Die Hooks für `vcs_info` werden als Shell-Funktionen 700 | geschrieben. Beachten Sie, dass der Funktionsname das Präfix 701 | `+vi-` hat, um mögliche Kollisionen zu vermeiden. Damit ein 702 | Hook auch wirklich funktioniert, muss er einen Wert im assoziativen 703 | Array `hook_com` verändern. In beiden Beispielen verändern wir 704 | den Wert des Eintrags `staged`, indem wir zusätzliche Zeichen 705 | anhängen, um bestimmte Zustände zu markieren. Wir verwenden das 706 | Prozent-Zeichen (`%`), um unbekannte Dateien zu signalisieren, 707 | und das Dollar-Zeichen (`$`) für angelegte Stashes. Das 708 | Prozentzeichen muss zweimal angegeben werden, damit die Z-Shell es 709 | nicht fälschlich als Formatierung wertet. Bei den Hooks greifen wir 710 | auf diverse Plumbing-Kommandos zurück (siehe <>). 711 | 712 | 713 | 714 | -------- 715 | +vi-untracked(){ 716 | if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \ 717 | [[ -n $(git ls-files --others --exclude-standard) ]] ; then 718 | hook_com[staged]+='%%' 719 | fi 720 | } 721 | +vi-stashed(){ 722 | if git rev-parse --verify refs/stash &> /dev/null ; then 723 | hook_com[staged]+='$' 724 | fi 725 | } 726 | -------- 727 | 728 | 729 | Wir aktivieren die Hooks, so dass sie beim Setzen der Git-Infos 730 | ausgewertet werden (`+set-message`): 731 | 732 | -------- 733 | zstyle ':vcs_info:git*+set-message:*' hooks stashed untracked 734 | -------- 735 | 736 | Wie beim Beispiel zu der Bash oben, werden ggf. ('unstaged', 737 | 'staged', 'stashed' und 'untracked') vier zusätzliche 738 | Zeichen (`*`, `+`, `$` und `%`) im 739 | Prompt angezeigt: 740 | 741 | -------- 742 | esc@creche ~/git-working/git (git)-[master*+$%] $ 743 | -------- 744 | 745 | Mit solchen Hooks ist es möglich, das Prompt nach Belieben zu 746 | erweitern. Zum Beispiel zeigt `vcs_info` standardmäßig nicht 747 | an, ob Sie sich innerhalb des `$GIT_DIR` oder aber in einem 748 | Bare-Repository befinden. Mit einem entsprechenden Hook bauen Sie 749 | diese Signale in das Prompt ein. 750 | 751 | Weitere Beispiele finden sich in der Datei 752 | `Misc/vcs_info-examples` des Z-Shell Repositorys, unter 753 | anderem auch ein Hook, der die Beziehung zum Upstream-Branch anzeigt 754 | (Abschnitt ``Compare local changes to remote changes''). Eine 755 | minimale Konfiguration für die Z-Shell entsprechend den Beispielen in 756 | diesem Abschnitt finden Sie in der Scriptsammlung für dieses 757 | Buch.footnote:[https://github.com/gitbuch/buch-scripte] 758 | 759 | /////////// 760 | FIXME: das muss hier alles ein dritter prüfen, der Ahnung von Shell hat, da kann soviel schief gehen. 761 | ////////// 762 | -------------------------------------------------------------------------------- /erste_schritte.txt: -------------------------------------------------------------------------------- 1 | [[ch.intro]] 2 | == Einführung und erste Schritte == 3 | 4 | Das folgende Kapitel bietet eine kompakte Einführung in Grundbegriffe 5 | und Konfigurationseinstellungen von Git. Ein kleines Beispielprojekt 6 | zeigt, wie Sie eine Datei mit Git unter Versionsverwaltung stellen und 7 | mit welchen Kommandos Sie die wichtigsten Arbeitsschritte erledigen. 8 | 9 | [[sec.begriffe]] 10 | === Grundbegriffe === 11 | 12 | Einige wichtige Fachbegriffe werden im Folgenden immer wieder 13 | vorkommen und bedürfen darum einer kurzen Erläuterung. Wenn Sie schon 14 | Erfahrung mit einem anderen Versionskontrollsystem gesammelt haben, 15 | werden Ihnen einige der damit verbundenen Konzepte bekannt sein, wenn 16 | vielleicht auch unter anderem Namen. 17 | 18 | 19 | 20 | 21 | 'Versionskontrollsystem' ('Version Control System', VCS):: Ein System 22 | zur Verwaltung und Versionierung von Software oder anderer digitaler 23 | Informationen. Prominente Beispiele sind Git, Subversion, CVS, 24 | Mercurial (hg), Darcs und Bazaar. Synonyme sind 'Software 25 | Configuration Management' (SCM) und 'Revision Control System'. 26 | + 27 | Wir unterscheiden zwischen 'zentralen' und 'verteilten' Systemen. In 28 | einem zentralen System, wie z.B. Subversion, muss es einen zentralen 29 | Server geben, auf dem die Geschichte des Projekts gespeichert 30 | wird. Alle Entwickler müssen sich mit diesem Server verbinden, um die 31 | Versionsgeschichte einzusehen oder Änderungen vorzunehmen. In einem 32 | verteilten System wie Git gibt es viele gleichwertige Instanzen des 33 | Repositorys, so dass jeder Entwickler über sein eigenes Repository 34 | verfügt. Der Austausch von Veränderungen ist flexibler und erfolgt 35 | nicht zwingend über einen zentralen Server. 36 | 37 | 'Repository':: Das Repository ist eine Datenbank, in der Git die 38 | verschiedenen Zustände jeder Datei eines Projekts über die Zeit hinweg 39 | ablegt. Insbesondere wird jede Änderung als Commit verpackt und 40 | abgespeichert. 41 | 42 | 'Working Tree':: Das 'Arbeitsverzeichnis' von Git (in anderen Systemen 43 | manchmal auch 'Sandbox' oder 'Checkout' genannt). Hier nehmen Sie alle 44 | Modifikationen am Quellcode vor. Oft findet man dafür auch die 45 | Bezeichnung 'Working Directory'. 46 | 47 | 'Commit':: Veränderungen am Working Tree, also z.B. modifizierte oder 48 | neue Dateien, werden im Repository als Commits gespeichert. Ein Commit 49 | enthält sowohl diese Veränderungen als auch Metadaten, wie den Autor 50 | der Veränderungen, Datum und Uhrzeit, und eine Nachricht ('Commit 51 | Message'), die die Veränderungen beschreibt. Ein Commit referenziert 52 | immer den Zustand 'aller' verwalteten Dateien zu einem bestimmten 53 | Zeitpunkt. Die verschiedenen Git-Kommandos dienen dazu, Commits zu 54 | erstellen, zu manipulieren, einzusehen oder die Beziehungen zwischen 55 | ihnen zu verändern. 56 | 57 | 58 | `HEAD`:: Eine symbolische Referenz auf den neuesten Commit im 59 | aktuellen Branch. Von dieser Referenz hängt ab, welche Dateien Sie im 60 | Working Tree zur Bearbeitung vorfinden. Es handelt sich also um den 61 | ``Kopf'' bzw. die Spitze eines Entwicklungsstrangs (nicht zu 62 | verwechseln mit `HEAD` in Systemen wie CVS oder SVN). 63 | 64 | 65 | 'SHA-1':: Der 'Secure Hash Algorithm' erstellt eine eindeutige, 160 66 | Bit lange Prüfsumme (40 hexadezimale Zeichen) für beliebige digitale 67 | Informationen. Alle Commits in Git werden nach ihrer SHA-1-Summe 68 | benannt ('Commit-ID'), die aus dem Inhalt und den Metadaten des 69 | Commits errechnet wird. Es ist sozusagen eine 'inhaltsabhängige' 70 | Versionsnummer, z.B.{empty}{nbsp}`f785b8f9ba1a1f5b707a2c83145301c807a7d661`. 71 | 72 | 73 | 74 | 'Objektmodell':: Ein Git-Repository lässt sich als Graph von Commits 75 | modellieren, der durch Git-Kommandos manipuliert wird. Durch diese 76 | Modellierung ist es sehr einfach, die Funktionsweise von Git 77 | detailliert zu beschreiben. Für eine ausführliche Beschreibung des 78 | Objektmodells siehe <>. 79 | 80 | 81 | 82 | 'Index':: Der Index ist eine Zwischenstufe zwischen Working Tree und 83 | Repository, in der Sie einen Commit vorbereiten. Der Index 84 | 'indiziert' also, welche Änderungen an welchen Dateien Sie als Commit 85 | verpacken wollen. Dieses Konzept ist einzigartig in Git und bereitet 86 | Anfängern und Umsteigern häufig Schwierigkeiten. Wir widmen uns dem 87 | Index ausführlich in <>. 88 | 89 | 90 | 91 | 'Clone':: Wenn Sie sich ein Git-Repository aus dem Internet 92 | herunterladen, erzeugen Sie einen Klon ('Clone') dieses Repositorys. 93 | Der Klon enthält alle Informationen, die im Ursprungsrepository 94 | enthalten sind, vor allem also die gesamte Versionsgeschichte 95 | einschließlich aller Commits. 96 | 97 | 98 | 99 | 'Branch':: Eine Abzweigung in der Entwicklung. Branches werden in der 100 | Praxis verwendet, um beispielsweise neue Features zu entwickeln, Releases 101 | vorzubereiten oder um alte Versionen mit Bugfixes zu versorgen. 102 | Branches sind -- ebenso wie das Zusammenführen von Branches ('Merge') 103 | -- in Git extrem einfach zu handhaben und ein herausragendes Feature 104 | des Systems. 105 | 106 | 107 | 108 | `master`:: Da Sie zum Arbeiten mit Git mindestens 109 | einen Branch brauchen, wird beim Initialisieren eines neuen 110 | Repositorys der Branch `master` erstellt. Der Name ist eine 111 | Konvention (analog zum `trunk` in anderen Systemen); Sie 112 | können diesen Branch beliebig umbenennen oder löschen, sofern 113 | mindestens ein anderer Branch zur Verfügung steht. Der 114 | `master` unterscheidet sich technisch in keiner Weise von 115 | anderen Branches. 116 | 117 | 118 | 119 | 'Tag':: Tags sind symbolische Namen für schwer zu 120 | merkende SHA-1-Summen. Wichtige Commits, wie z.B. Releases, 121 | können Sie mit Tags kennzeichnen. Ein Tag kann einfach nur ein 122 | Bezeichner, wie z.B.{empty}{nbsp}`v1.6.2`, sein, oder zusätzlich 123 | Metadaten wie Autor, Beschreibung und GPG-Signatur enthalten. 124 | 125 | 126 | 127 | [[sec.erste-schritte]] 128 | === Erste Schritte mit Git === 129 | 130 | Zum Einstieg wollen wir an einem kleinen Beispiel den Arbeitsablauf 131 | mit Git illustrieren. Wir erstellen ein Repository und entwickeln 132 | darin einen Einzeiler, ein ``Hello, World!''-Programm in Perl. 133 | 134 | Damit Git einen Commit einem Autor zuordnen kann, müssen Sie Ihren 135 | Namen und Ihre E-Mail-Adresse hinterlegen: 136 | 137 | 138 | 139 | [subs="macros,quotes"] 140 | -------- 141 | $ *git config --global user.name "Max Mustermann"* 142 | $ *git config --global user.email "max.mustermann@example.com"* 143 | -------- 144 | 145 | Beachten Sie, dass bei einem Aufruf von Git ein 'Subkommando' 146 | angegeben wird, in diesem Fall `config`. Git stellt alle 147 | Operationen durch solche Subkommandos zur Verfügung. Wichtig ist 148 | auch, dass bei einem Aufruf von `git config` kein Gleichheitszeichen verwendet wird. Folgender Aufruf ist also 149 | 'falsch': 150 | 151 | 152 | [subs="macros,quotes"] 153 | -------- 154 | $ *git config --global user.name = "Max Mustermann"* 155 | -------- 156 | 157 | Das ist besonders für Anfänger eine Stolperfalle, da Git keine 158 | Fehlermeldung ausgibt, sondern das Gleichheitszeichen als zu setzenden 159 | Wert übernimmt. 160 | 161 | 162 | [[sec.erstes-repo]] 163 | ==== Das erste Repository ==== 164 | 165 | Bevor wir mit Git Dateien verwalten, müssen wir ein Repository für das 166 | Beispiel-Projekt erstellen. Das Repository wird 'lokal' erstellt, 167 | liegt also nur auf dem Dateisystem des Rechners, auf dem Sie arbeiten. 168 | 169 | Es empfiehlt sich generell, den Umgang mit Git zunächst lokal zu üben 170 | und erst später in die dezentralen Eigenschaften und Funktionen von 171 | Git einzutauchen. 172 | 173 | 174 | 175 | [subs="macros,quotes"] 176 | -------- 177 | $ *git init beispiel* 178 | Initialized empty Git repository in /home/esc/beispiel/.git/ 179 | -------- 180 | 181 | Zunächst erstellt Git das Verzeichnis `beispiel/`, falls es 182 | noch nicht existiert. Danach initialisiert Git ein leeres Repository 183 | in diesem Verzeichnis und legt dafür ein Unterverzeichnis 184 | `.git/` an, in dem interne Daten verwaltet werden. Sollte das 185 | Verzeichnis `beispiel/` bereits existieren, erstellt Git darin 186 | ein neues Repository. Gibt es bereits sowohl das Verzeichnis wie auch 187 | ein Repository, macht Git gar nichts. Wir wechseln in das Verzeichnis und 188 | schauen uns mit `git status` den aktuellen Zustand an: 189 | 190 | 191 | 192 | 193 | [subs="macros,quotes"] 194 | -------- 195 | $ *cd beispiel* 196 | $ *git status* 197 | On branch master 198 | 199 | Initial commit 200 | 201 | nothing to commit (create/copy files and use "git add" to track) 202 | -------- 203 | 204 | Git weist uns darauf hin, dass wir vor dem ersten Commit stehen 205 | (`Initial commit`), hat aber nichts gefunden, was in diesen 206 | Commit einfließen könnte (`nothing to commit`). Dafür liefert 207 | es einen Hinweis, welche Schritte sich als nächste anbieten (das tun 208 | übrigens die meisten Git-Kommandos): ``Erstellen oder kopieren Sie 209 | Dateien, und verwenden Sie `git add`, um diese mit Git zu 210 | verwalten.'' 211 | 212 | [[sec.erster-commit]] 213 | ==== Der erste Commit ==== 214 | 215 | Übergeben wir Git nun eine erste Datei zur Verwaltung, und zwar ein 216 | ``Hello World!''-Programm in Perl. Selbstverständlich 217 | können Sie stattdessen auch ein beliebiges Programm in der 218 | Programmiersprache Ihrer Wahl schreiben. 219 | 220 | Wir erstellen zunächst die Datei `hello.pl` mit folgendem 221 | Inhalt 222 | 223 | -------- 224 | print "Hello World!\n"; 225 | -------- 226 | 227 | und führen das Script einmal aus: 228 | 229 | 230 | 231 | [subs="macros,quotes"] 232 | -------- 233 | $ *perl hello.pl* 234 | Hello World! 235 | -------- 236 | 237 | Damit sind wir bereit, die Datei mit Git zu verwalten. Schauen wir 238 | uns vorher aber noch die Ausgabe von `git status` an: 239 | 240 | 241 | 242 | [subs="macros,quotes"] 243 | -------- 244 | $ *git status* 245 | On branch master 246 | 247 | Initial commit 248 | 249 | Untracked files: 250 | (use "git add <file>..." to include in what will be committed) 251 | 252 | hello.pl 253 | nothing added to commit but untracked files present (use "git add" to track) 254 | -------- 255 | 256 | Zwar steht der erste Commit noch bevor, aber Git registriert, dass 257 | sich nun bereits Dateien in diesem Verzeichnis befinden, die dem System 258 | allerdings nicht bekannt sind -- Git nennt solche Dateien 259 | `untracked`. Es handelt sich hier natürlich um unser kleines 260 | Perl-Programm. Um es mit Git zu verwalten, nutzen wir den Befehl 261 | `git add `: 262 | 263 | 264 | 265 | [subs="macros,quotes"] 266 | -------- 267 | $ *git add hello.pl* 268 | -------- 269 | 270 | Das `add` steht generell für ``Änderungen hinzufügen'' 271 | -- Sie werden es also immer dann benötigen, wenn Sie Dateien 272 | bearbeitet haben, nicht nur beim ersten Hinzufügen! 273 | 274 | Git liefert bei diesem Befehl keine Ausgabe. Mit `git status` 275 | überprüfen Sie, ob der Aufruf erfolgreich war: 276 | 277 | 278 | [subs="macros,quotes"] 279 | -------- 280 | $ *git status* 281 | On branch master 282 | 283 | Initial commit 284 | 285 | Changes to be committed: 286 | (use "git rm --cached <file>..." to unstage) 287 | 288 | new file: hello.pl 289 | -------- 290 | 291 | Git wird die Veränderungen -- also unsere neue Datei -- beim nächsten 292 | Commit übernehmen. Allerdings ist dieser Commit noch nicht vollzogen 293 | -- wir haben ihn bisher lediglich vorbereitet. 294 | 295 | Um genau zu sein, haben wir die Datei dem 'Index' hinzugefügt, 296 | einer Zwischenstufe, in der Sie Veränderungen, die in den nächsten 297 | Commit einfließen sollen, sammeln. Weitere Erklärungen zu diesem 298 | Konzept in <>. 299 | 300 | Bei `git status` sehen Sie unter 301 | `Changes to be committed` immer, welche Dateien sich im Index 302 | befinden, also in den nächsten Commit übernommen werden. 303 | 304 | Alles ist bereit für den ersten Commit mit dem Kommando 305 | `git commit`. Außerdem übergeben wir auf der Kommandozeile die 306 | Option `-m` mit einer Commit-Nachricht ('Commit Message'), 307 | in der wir den Commit beschreiben: 308 | 309 | 310 | 311 | 312 | 313 | [subs="macros,quotes"] 314 | -------- 315 | $ *git commit -m "Erste Version"* 316 | [master (root-commit) 07cc103] Erste Version 317 | 1 file changed, 1 insertion(+) 318 | create mode 100644 hello.pl 319 | -------- 320 | 321 | Git bestätigt, dass der Vorgang erfolgreich abgeschlossen wurde und 322 | die Datei von nun an verwaltet wird. Die etwas kryptische Ausgabe 323 | bedeutet soviel wie: Git hat den initialen Commit 324 | (`root-commit`) mit der entsprechenden Nachricht erstellt. Es 325 | wurde eine Zeile in einer Datei hinzugefügt und die Datei mit den 326 | Unix-Rechten `0644` angelegt.{empty}footnote:[Auch 327 | wenn Sie das Beispiel exakt nachvollziehen, werden Sie nicht 328 | dieselben SHA-1-Prüfsummen erhalten, da diese unter anderem aus dem 329 | Inhalt des Commits, dem Autor, und dem Commit-Zeitpunkt errechnet 330 | werden.] 331 | 332 | Wie Sie mittlerweile sicher festgestellt haben, ist `git 333 | status` ein unerlässliches Kommando in der täglichen Arbeit -- wir 334 | nutzen es an dieser Stelle noch einmal: 335 | 336 | 337 | 338 | 339 | [subs="macros,quotes"] 340 | -------- 341 | $ *git status* 342 | On branch master 343 | nothing to commit, working directory clean 344 | -------- 345 | 346 | Unser Beispiel-Repository ist jetzt ``sauber'', denn es gibt 347 | weder Veränderungen im Working Tree noch im Index, auch keine Dateien, 348 | die nicht mit Git verwaltet werden ('Untracked Files'). 349 | 350 | [[sec.commits-einsehen]] 351 | ==== Commits einsehen ==== 352 | 353 | Zum Abschluss dieser kleinen Einführung stellen wir Ihnen noch zwei 354 | sehr nützliche Kommandos vor, die Sie häufig einsetzen werden, um die 355 | Versionsgeschichte von Projekten zu untersuchen. 356 | 357 | Zunächst erlaubt `git show` die Untersuchung eines einzelnen 358 | Commits – ohne weitere Argumente ist das der aktuellste: 359 | 360 | 361 | 362 | [subs="macros,quotes"] 363 | -------- 364 | $ *git show* 365 | commit 07cc103feb393a93616842921a7bec285178fd56 366 | Author: Valentin Haenel <pass:quotes[valentin.haenel@gmx.de]> 367 | Date: Tue Nov 16 00:40:54 2010 +0100 368 | 369 | Erste Version 370 | 371 | diff --git a/hello.pl b/hello.pl 372 | new file mode 100644 373 | index 0000000..fa5a091 374 | --- /dev/null 375 | pass:quotes[\+++ b/hello.pl] 376 | @@ -0,0 +1 @@ 377 | +print "Hello World!\n"; 378 | -------- 379 | 380 | Sie sehen alle relevanten Informationen zu dem Commit: die 381 | 'Commit-ID', den Autor, das Datum und die Uhrzeit des Commits, 382 | die Commit-Nachricht sowie eine Zusammenfassung der Veränderungen im 383 | 'Unified-Diff'-Format. 384 | 385 | Standardmäßig gibt `git show` immer den `HEAD` aus (ein 386 | symbolischer Name für den aktuellsten Commit); Sie könnten aber auch 387 | z.B. die Commit-ID, also die SHA-1-Prüfsumme des Commits, ein 388 | eindeutiges Präfix davon oder den Branch (in diesem Fall 389 | `master`) angeben. Somit sind in 390 | diesem Beispiel folgende Kommandos äquivalent: 391 | 392 | 393 | [subs="macros,quotes"] 394 | -------- 395 | $ *git show* 396 | $ *git show HEAD* 397 | $ *git show master* 398 | $ *git show 07cc103* 399 | $ *git show 07cc103feb393a93616842921a7bec285178fd56* 400 | -------- 401 | 402 | Wollen Sie mehr als einen Commit einsehen, empfiehlt sich `git 403 | log`. Um das Kommando sinnvoll zu demonstrieren, bedarf es weiterer 404 | Commits; andernfalls würde sich die Ausgabe kaum von `git show` 405 | unterscheiden, da das Beispiel-Repository im Moment nur einen einzigen 406 | Commit enthält. Fügen wir also folgende Kommentarzeile dem ``Hello 407 | World!''-Programm hinzu: 408 | 409 | -------- 410 | # Hello World! in Perl 411 | -------- 412 | 413 | Schauen wir uns der Übung halber noch einmal mit `git status` 414 | den aktuellen Zustand an: 415 | 416 | 417 | [subs="macros,quotes"] 418 | -------- 419 | $ *git status* 420 | On branch master 421 | Changes not staged for commit: 422 | (use "git add <file>..." to update what will be committed) 423 | (use "git checkout -- <file>..." to discard changes in working 424 | directory) 425 | 426 | modified: hello.pl 427 | 428 | no changes added to commit (use "git add" and/or "git commit -a") 429 | -------- 430 | 431 | Benutzen Sie danach, wie in der Ausgabe des Kommandos schon 432 | beschrieben, `git add`, um die Veränderungen dem Index 433 | hinzuzufügen. Wie bereits erwähnt, wird `git add` sowohl zum 434 | Hinzufügen neuer Dateien wie auch zum Hinzufügen von Veränderungen an 435 | Dateien, die bereits verwaltet werden, verwendet. 436 | 437 | 438 | [subs="macros,quotes"] 439 | -------- 440 | $ *git add hello.pl* 441 | -------- 442 | 443 | Erstellen Sie anschließend einen Commit: 444 | 445 | 446 | [subs="macros,quotes"] 447 | -------- 448 | $ *git commit -m "Kommentar-Zeile"* 449 | [master 8788e46] Kommentar-Zeile 450 | 1 file changed, 1 insertion(+) 451 | -------- 452 | 453 | Nun zeigt Ihnen `git log` die beiden Commits: 454 | 455 | 456 | [subs="macros,quotes"] 457 | -------- 458 | $ *git log* 459 | commit 8788e46167aec2f6be92c94c905df3b430f6ecd6 460 | Author: Valentin Haenel pass:quotes[<valentin.haenel@gmx.de>] 461 | Date: Fri May 27 12:52:58 2011 +0200 462 | 463 | Kommentar-Zeile 464 | 465 | commit 07cc103feb393a93616842921a7bec285178fd56 466 | Author: Valentin Haenel pass:quotes[<valentin.haenel@gmx.de>] 467 | Date: Tue Nov 16 00:40:54 2010 +0100 468 | 469 | Erste Version 470 | -------- 471 | 472 | [[chap.git-config]] 473 | === Git konfigurieren === 474 | 475 | Wie die meisten textbasierten Programme bietet Git eine Fülle an 476 | Konfigurationsoptionen. Es ist daher jetzt an der Zeit, einige 477 | grundlegende Einstellungen vorzunehmen. Dazu gehören Farbeinstellungen, 478 | die in neueren Versionen standardmäßig bereits eingeschaltet sind und 479 | die es Ihnen erleichtern, die Ausgabe von Git-Kommandos zu erfassen, 480 | sowie kleine Aliase (Abkürzungen) für häufig benötigte Kommandos. 481 | 482 | Git konfigurieren Sie über das Kommando `git config`. Die 483 | Konfiguration wird einem Format ähnlich einer INI-Datei gespeichert. 484 | Ohne Angabe weiterer Parameter gilt die Konfiguration nur für das 485 | aktuelle Repository (`.git/config`). Mit der Option `--global` wird sie in 486 | der Datei `.gitconfig` im Home-Verzeichnis des Nutzers abgelegt 487 | und gilt dann für alle Repositories.{empty}footnote:[Sie können die 488 | nutzerspezifische Konfiguration alternativ auch unter dem XDG-konformen 489 | Pfad `.config/git/config` im Home-Verzeichnis ablegen (oder 490 | entsprechend relativ zu Ihrer gesetzten Umgebungsvariable 491 | `$XDG_CONFIG_HOME`).] 492 | 493 | Wichtige Einstellungen, die Sie immer vornehmen sollten, sind Name 494 | und E-Mail-Adresse des Benutzers: 495 | 496 | 497 | 498 | [subs="macros,quotes"] 499 | -------- 500 | $ *git config --global user.name "Max Mustermann"* 501 | $ *git config --global user.email "max.mustermann@example.com"* 502 | -------- 503 | 504 | Beachten Sie, dass Sie Leerzeichen im Wert der Einstellung schützen 505 | müssen (durch Anführungszeichen oder Backslashes). Außerdem folgt der 506 | Wert direkt auf den Namen der Option -- ein Gleichheitszeichen ist auch 507 | hier nicht nötig. Das Ergebnis des Kommandos findet sich anschließend 508 | in der Datei `~/.gitconfig`: 509 | 510 | 511 | [subs="macros,quotes"] 512 | -------- 513 | $ *less ~/.gitconfig* 514 | [user] 515 | name = Max Mustermann 516 | email = pass:quotes[max.mustermann@example.com] 517 | -------- 518 | 519 | Die Einstellungen gelten nun ``global'', also für alle 520 | Repositories, die Sie unter diesem Nutzernamen bearbeiten. Wollen Sie 521 | für ein bestimmtes Projekt eine andere E-Mail-Adresse als Ihre global 522 | definierte angeben, ändern Sie dort einfach die Einstellung (diesmal 523 | natürlich ohne den Zusatz `--global`): 524 | 525 | 526 | [subs="macros,quotes"] 527 | -------- 528 | $ *git config user.email pass:quotes[maintainer@project.example.com]* 529 | -------- 530 | 531 | Bei der Abfrage einer Option geht Git so vor, dass es zuerst die 532 | Einstellung im aktuellen Repository nutzt, sofern vorhanden, 533 | andernfalls die aus der globalen `.gitconfig`; gibt es auch 534 | diese nicht, wird auf den Default-Wert 535 | zurückgegriffen.footnote:[Sofern vorhanden, 536 | werden auch Einstellungen aus `/etc/gitconfig` eingelesen 537 | (mit niedrigster Priorität). Setzen kann man Optionen in dieser 538 | Datei über den Parameter `--system`, wofür aber Root-Rechte 539 | notwendig sind. Systemweit Git-Optionen zu setzen ist aber 540 | unüblich.] Letzteren erhält man für alle Optionen in der Man-Page 541 | `git-config`. Eine Liste aller gesetzten Einstellungen fragen 542 | Sie per `git config -l` ab. 543 | 544 | Sie können die Datei `.gitconfig` (bzw. im Repository 545 | `.git/config`) auch von Hand editieren. Gerade zum Löschen 546 | einer Einstellung ist das sinnvoll -- zwar bietet `git config` 547 | auch eine Option `--unset`, die entsprechende Zeile in einem 548 | Editor zu löschen ist aber einfacher. 549 | 550 | [TIP] 551 | ================== 552 | Die Kommandos `git config -e` bzw. `git config --global -e` starten 553 | den für Git konfigurierten Editor auf der lokalen bzw. globalen 554 | Konfigurationsdatei. 555 | ================== 556 | 557 | Beachten Sie allerdings, dass Git beim 'Setzen' von Optionen 558 | durch ein entsprechendes Kommando problematische Zeichen im Wert der 559 | Option automatisch schützt, so dass keine fehlerhaften 560 | Konfigurationsdateien entstehen. 561 | 562 | [[sec.git-alias]] 563 | ==== Git Aliase ==== 564 | 565 | Git bietet Ihnen über 'Aliase' die Möglichkeit, einzelne 566 | Kommandos und sogar ganze Kommandosequenzen abzukürzen. Die Syntax lautet: 567 | 568 | 569 | [subs="macros,quotes"] 570 | -------- 571 | $ pass:quotes[*git config alias.<alias-name> <entsprechung>*] 572 | -------- 573 | 574 | Um etwa `st` als Alias für `status` zu setzen: 575 | 576 | 577 | [subs="macros,quotes"] 578 | -------- 579 | $ *git config --global alias.st status* 580 | $ *git st* 581 | On branch master 582 | ... 583 | -------- 584 | 585 | Sie können auch Optionen in ein Alias einbauen, z.B.: 586 | 587 | 588 | [subs="macros,quotes"] 589 | -------- 590 | $ *git config --global alias.gconfig \'config --global'* 591 | -------- 592 | 593 | Weitere nützliche Aliase finden Sie im weiteren Verlauf des Buches; 594 | wie Sie komplexere Aliase erstellen, ist in 595 | <> beschrieben. Vorab aber schon 596 | einige nützliche Abkürzungen: 597 | 598 | -------- 599 | [alias] 600 | st = status 601 | ci = commit 602 | br = branch 603 | co = checkout 604 | df = diff 605 | he = help 606 | cl = clone 607 | -------- 608 | 609 | 610 | [[chap.color-defaults]] 611 | ==== Farbe einstellen ==== 612 | 613 | Überaus hilfreich ist die Option `color.ui`, die prüft, ob Git 614 | die Ausgabe diverser Kommandos einfärben soll. So erscheinen gelöschte 615 | Dateien und Zeilen rot, neue Dateien und Zeilen grün, Commit-IDs 616 | gelb usw. In neueren Git-Versionen (ab 1.8.4) ist diese Einstellung 617 | bereits automatisch gesetzt, Sie müssen also nichts tun. 618 | 619 | Die Option `color.ui` sollte auf `auto` gesetzt sein 620 | -- erfolgt die Ausgabe von Git in ein Terminal, werden Farben 621 | verwendet. Schreibt das Kommando stattdessen in eine Datei oder wird 622 | die Ausgabe an ein anderes Programm gepipet, so gibt Git keine 623 | Farbsequenzen aus, da das die automatische Weiterverarbeitung 624 | behindern könnte. 625 | 626 | 627 | [subs="macros,quotes"] 628 | -------- 629 | $ *git config --global color.ui auto* 630 | -------- 631 | 632 | 633 | [[chap.config-encoding]] 634 | ==== Zeichensätze einstellen ==== 635 | 636 | Sofern nicht anders eingestellt, nimmt Git für alle Texte, also vor 637 | allem für die Namen der Autoren und die Commit-Nachricht, UTF-8 als 638 | Zeichenkodierung an. Wollen Sie 639 | ein anderes Encoding, sollten Sie dies explizit 640 | konfigurieren:footnote:[``i18n'' ist eine 641 | gebräuchliche Abkürzung für das Wort ``Internationalization'' -- 642 | die 18 steht für die Anzahl der ausgelassenen Buchstaben zwischen 643 | dem ersten und dem letzten Buchstaben des Wortes.] 644 | 645 | 646 | [subs="macros,quotes"] 647 | -------- 648 | $ *git config i18n.commitEncoding ISO-8859-1* 649 | -------- 650 | 651 | Analog bestimmt die Einstellung `i18n.logOutputEncoding`, in 652 | welchen Zeichensatz Git die Namen und Commit-Nachrichten konvertiert, 653 | bevor sie ausgegeben werden. 654 | 655 | Das Encoding der 'Dateien', die von Git verwaltet werden, spielt 656 | hier keine Rolle und wird von diesen Einstellungen nicht beeinflusst -- 657 | Dateien sind nur Bit-Streams, die Git nicht interpretiert. 658 | 659 | 660 | [TIP] 661 | ================ 662 | Wenn Sie in einer UTF-8-Umgebung mit Dateien, die nach ISO-8859-1 663 | kodiert sind, umgehen müssen, sollten Sie die Einstellung Ihres Pagers 664 | (s.u.) entsprechend anpassen. Für die Autoren bewährt sich die 665 | folgende Einstellung: 666 | 667 | [subs="macros,quotes"] 668 | -------- 669 | $ *git config core.pager \'env LESSCHARSET=iso8859 less'* 670 | -------- 671 | ================ 672 | 673 | [[sec.config-eol]] 674 | ==== Zeilenenden einstellen ==== 675 | 676 | Da Git auf Windows-Systemen wie auf unixoiden Systemen läuft, muss es 677 | das Problem verschiedener Zeilenende-Konventionen lösen. (Das betrifft 678 | nur Text-Dateien -- Binärdateien, die Git als solche erkennt, werden 679 | von dieser Behandlung ausgenommen.) 680 | 681 | Dafür ist im Wesentlichen die Einstellung `core.eol` relevant, 682 | die einen der Werte `lf`, `crlf` oder `native` 683 | annehmen kann. Die Standardeinstellung `native` lässt Git den 684 | System-Default verwenden -- Unix: nur Line Feed (`lf`), 685 | Windows: Carriage Return & Line Feed (`crlf`). Die Datei wird 686 | automatisch konvertiert, um nur Line Feeds zu erhalten, wird aber bei 687 | Bedarf mit CRLF ausgecheckt. 688 | 689 | Zwischen den beiden Varianten kann Git bei einem Checkout der Datei 690 | konvertieren; wichtig ist aber, dass die beiden Typen nicht vermischt 691 | werden. Dafür bietet die Option `core.safecrlf` einen 692 | Mechanismus, den Nutzer zu warnen (Wert `warn`) oder gar den 693 | Commit zu verbieten (Wert `true`). 694 | 695 | Eine sichere Einstellung, die auch mit älteren Git-Versionen unter 696 | Windows-Systemen funktioniert, ist `core.autocrlf` auf 697 | `input` zu setzen: Dadurch wird automatisch beim 698 | 'Einlesen' der Dateien vom Dateisystem CRLF durch LF ersetzt. Ihr 699 | Editor muss dann entsprechend mit LF-Enden umgehen können. 700 | 701 | Sie können diese Einstellungen auch explizit pro Datei bzw. 702 | Unterverzeichnis angeben, so dass das Format über alle Plattformen 703 | hinweg gleich ist (siehe dafür <>). 704 | 705 | [[chap.ext-tools]] 706 | ==== Editor, Pager und Browser einstellen ==== 707 | 708 | Git startet für bestimmte Aktionen automatisch einen Editor, Pager 709 | oder Browser. Meist werden vernünftige Defaults verwendet, wenn nicht, 710 | können Sie Ihr Wunschprogramm mit den folgenden 711 | Optionen konfigurieren: 712 | 713 | 714 | * `core.editor` 715 | * `core.pager` 716 | * `web.browser` 717 | 718 | 719 | Ein Wort zum Pager: Standardmäßig verwendet Git das Programm 720 | `less`, das auf den meisten Grundsystemen installiert ist. Das 721 | Kommando wird 'immer' gestartet, sobald ein Git-Kommando eine 722 | Ausgabe auf einem Terminal produziert. Allerdings wird `less` 723 | durch eine entsprechende Umgebungsvariable automatisch konfiguriert 724 | sich zu beenden, wenn die Ausgabe vollständig auf das Terminal passt. 725 | Falls ein Kommando also viel Ausgabe produziert, tritt `less` 726 | automatisch in den Vordergrund -- und bleibt sonst unsichtbar. 727 | 728 | Wird `core.pager` auf `cat` gesetzt, verwendet Git 729 | keinen Pager. Dieses Verhalten kann man aber auch von Kommando zu 730 | Kommando durch den Parameter `--no-pager` erreichen. 731 | Zusätzlich kann man z.B. per `git config pager.diff false` 732 | erreichen, dass die Ausgabe des Diff-Kommandos nie in den Pager 733 | geleitet wird. 734 | 735 | [[chap.conf-env]] 736 | ==== Konfiguration über Umgebungsvariablen ==== 737 | 738 | Einige Optionen lassen sich auch durch Umgebungsvariablen 739 | überschreiben. Auf diese Weise können in einem Shell-Script oder in 740 | einem Alias Optionen lediglich für ein einzelnes Kommando gesetzt 741 | werden. 742 | 743 | 744 | 745 | `GIT_EDITOR`:: der Editor, den Git z.B. zum 746 | Erstellen der Commit-Nachricht startet. Alternativ 747 | greift Git auf die Variable `EDITOR` zurück. 748 | 749 | 750 | `GIT_PAGER`:: der zu verwendende Pager. Der Wert 751 | `cat` schaltet den Pager aus. 752 | 753 | 754 | `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`:: 755 | verwendet die entsprechende E-Mail-Adresse für das Autor- bzw. 756 | Committer-Feld beim Erstellen eines Commits. 757 | 758 | 759 | `GIT_AUTHOR_NAME`, `GIT_COMMITTER_NAME`:: 760 | analog der Name. 761 | 762 | 763 | `GIT_DIR`:: 764 | Verzeichnis, in dem sich das Git-Repository befindet; nur sinnvoll, 765 | wenn explizit ein Repository unter einem anderen Verzeichnis als 766 | `.git` gespeichert wird. 767 | 768 | 769 | Die letztgenannte Variable ist beispielsweise praktisch, wenn Sie 770 | innerhalb eines Projekts auf die Versionsgeschichte eines anderen 771 | Repositorys zugreifen wollen, ohne das Verzeichnis zu wechseln: 772 | 773 | 774 | [subs="macros,quotes"] 775 | -------- 776 | $ *GIT_DIR="~/proj/example/.git" git log* 777 | -------- 778 | 779 | Alternativ können Sie über die Option `-c`{empty}{nbsp} 'vor dem Subkommando' eine 780 | Einstellung nur für diesen Aufruf überschreiben. So könnten Sie zum 781 | Beispiel Git anweisen, für den kommenden Aufruf die Option 782 | `core.trustctime` zu deaktivieren: 783 | 784 | [subs="macros,quotes"] 785 | -------- 786 | $ *git -c core.trustctime=false status* 787 | -------- 788 | 789 | [[chap.correct-errors]] 790 | ==== Automatische Fehlerkorrektur ==== 791 | 792 | Der Wert der Option `help.autocorrect` bestimmt, was Git tun 793 | soll, wenn es das eingegebene Subkommando nicht findet, der 794 | Nutzer also z.B. versehentlich `git statsu` statt `git 795 | status` tippt. 796 | 797 | Ist die Option auf eine Zahl `n` größer Null gesetzt und Git findet 798 | nur 'ein' Subkommando, das dem getippten Kommando ähnlich ist, so 799 | wird dieses Kommando nach `n` Zehntelsekunden ausgeführt. Ein Wert von 800 | `-1` führt das Kommando sofort aus. Ungesetzt oder mit dem Wert `0` 801 | werden nur die Möglichkeiten aufgelistet. 802 | 803 | Um also bei einem Vertipper das Kommando nach einer Sekunde zu 804 | korrigieren, setzt man: 805 | 806 | 807 | [subs="macros,quotes"] 808 | -------- 809 | $ *git config --global help.autocorrect 10* 810 | $ *git statsu* 811 | WARNING: You called a Git command named \'statsu', which does not exist. 812 | Continuing under the assumption that you meant \'status' 813 | in 1.0 seconds automatically... 814 | [...] 815 | -------- 816 | 817 | Sie können das Kommando natürlich während dieser Zeit mit 818 | 'Strg+C' abbrechen. 819 | 820 | 821 | // vim:set tw=72 ft=asciidoc: 822 | --------------------------------------------------------------------------------