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 |
--------------------------------------------------------------------------------