-
Notifications
You must be signed in to change notification settings - Fork 0
/
gitbuch_footnotes.adoc
1036 lines (870 loc) · 58.7 KB
/
gitbuch_footnotes.adoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
////
All book footnotes have been externalized to custom attributes definitions and
placed in this file to centralise them for easier maintenance.
The footnotes of each book chapter are enclosed within a tag region in order to
allow their selective inclusion on a per-chapter basis (instead of including
them in the main entry file), and each chapter includes the required footnotes
using tags. This allows to build individual chapters without loosing their
footnotes.
////
// =============================================================================
// Preface (footnotes: 1-7)
// =============================================================================
// tag::Preface[]
:fn1: {wj}footnote:[https://git-scm.com[^]]
:fn2: {wj}footnote:[http://vger.kernel.org/vger-lists.html#git[^]]
:fn3: {wj}footnote:[https://git.wiki.kernel.org/index.php/Main_Page[^]]
:fn4: {wj}footnote:[https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools[^]]
:fn5: {wj}footnote:[https://git.wiki.kernel.org/index.php/GitFaq[^]]
:fn6: {wj}footnote:[https://git.wiki.kernel.org/index.php/GitSvnCrashCourse[^]]
:fn7: {wj}footnote:[https://stackoverflow.com[^]]
// end::Preface[]
// =============================================================================
// Chapter 1 (footnotes: 8-11)
// =============================================================================
// tag::Chapter_1[]
////
Auch wenn Sie das Beispiel exakt nachvollziehen, werden Sie nicht dieselben SHA-1-Prüfsummen erhalten, da diese unter anderem aus dem Inhalt des Commits, dem Autor, und dem Commit-Zeitpunkt errechnet werden.
////
:fn8: {wj}footnote:[ \
Even if you follow the example exactly, you will not get the same SHA-1 checksums, since they are calculated from the contents of the commit, the author, and the commit time, among other things.]
////
Sie können die nutzerspezifische Konfiguration alternativ auch unter dem XDG-konformen Pfad `.config/git/config` im Home-Verzeichnis ablegen (oder entsprechend relativ zu Ihrer gesetzten Umgebungsvariable `$XDG_CONFIG_HOME`).
////
:fn9: pass:a,q[{wj}footnote:[ \
Alternatively, you can store the user-specific configuration under the XDG-compliant path `.config/git/config` in your home directory (or relative to your set environment variable `$XDG_CONFIG_HOME`).]]
////
Sofern vorhanden, werden auch Einstellungen aus `/etc/gitconfig` eingelesen (mit niedrigster Priorität).
Setzen kann man Optionen in dieser Datei über den Parameter `--system`, wofür aber Root-Rechte notwendig sind.
Systemweit Git-Optionen zu setzen ist aber unüblich.
////
:fn10: pass:a,q[{wj}footnote:[ \
If available, settings from `/etc/gitconfig` are also read in (with lowest priority). \
You can set options in this file using the `--system parameter`, but you need root privileges to do this. \
Setting git options system-wide is unusual.]]
////
"`i18n`" ist eine gebräuchliche Abkürzung für das Wort "`Internationalization`" -- die 18 steht für die Anzahl der ausgelassenen Buchstaben zwischen dem ersten und dem letzten Buchstaben des Wortes.
////
:fn11: pass:a,q[{wj}footnote:[ \
"`i18n`" is a common abbreviation for the word "`internationalization`" -- the 18 stands for the number of omitted letters between the first and last letter of the word.]]
// end::Chapter_1[]
// =============================================================================
// Chapter 2 (footnotes: 12-28)
// =============================================================================
// tag::Chapter_2[]
////
Standardmäßig sind Wörter durch ein oder mehr Leerzeichen getrennt; Sie können aber einen anderen regulären Ausdruck angeben, um zu bestimmen, was ein Wort ist: `git diff --word-diff-regex=<regex>`.
Siehe hierzu auch die Man-Page `git-diff(1)`.
////
:fn12: pass:a,q[{wj}footnote:[ \
By default, words are separated by one or more spaces, but you can specify another regular expression to determine what a word is: `git diff --word-diff-regex=<regex>`. \
See also the `git-diff(1)` man page.]]
////
Das ist eine Anweisung für den Kernel, welches Programm zum Interpretieren des Scripts verwendet werden soll.
Typische Shebang-Zeilen sind etwa `#!/bin/sh` oder `#!/usr/bin/perl`.
////
:fn13: pass:a,q[{wj}footnote:[ \
This is an instruction for the Kernel, telling it which program to use to interpret the script. \
Typical shebang lines include `#!/bin/sh` or `#!/usr/bin/perl`.]]
////
Genaugenommen führt die Option `-p` direkt in den _Patch-Mode_ des _Interactive-Mode_ von `git add`.
Der Interactive-Mode wird aber in der Praxis -- im Gegensatz zu dem Patch-Mode -- sehr selten verwendet und ist deswegen hier nicht weiter beschrieben.
Die Dokumentation dazu finden Sie in der Man-Page `git-add(1)` im Abschnitt "`Interactive Mode`".
////
:fn14: pass:a,q[{wj}footnote:[ \
Strictly speaking, the `-p` option leads directly to the _patch mode_ of ``git add``{wj}`'s _interactive mode_. \
However, the interactive mode is rarely used in practice -- in contrast to the patch mode -- and is therefore not described further here. \
The documentation for this can be found in the `git add(1)` man page in the "`Interactive Mode`" section.]]
////
Git öffnet dann den Hunk in einem Editor; unten sehen Sie eine Anleitung, wie Sie den Hunk editieren: Um gelöschte Zeilen (mit `-` präfigiert) zu löschen -- also nicht dem Index hinzuzufügen, sie aber im Working Tree zu behalten! --, ersetzen Sie das Minuszeichen durch ein Leerzeichen (die Zeile wird zu "`Kontext`").
Um `+`-Zeilen zu löschen, entfernen Sie diese einfach aus dem Hunk.
////
:fn15: pass:a,q[{wj}footnote:[ \
Git then opens the hunk in an editor; below is a guide to editing the hunk: To delete deleted lines (prefixed with `-`) -- i.e. not add them to the index, but keep them in the working tree! -- replace the minus sign with a space (the line becomes "`context`"). \
To delete `+` lines, simply remove them from the hunk.]]
////
Sie können Hunks in der Regel aber nicht beliebig teilen.
Zumindest eine Zeile _Kontext_, also eine Zeile ohne Präfix `+` oder `-`, muss dazwischen liegen.
Wollen Sie den Hunk dennoch teilen, müssen Sie mit `e` für _edit_ arbeiten.
////
:fn16: pass:a,q[{wj}footnote:[ \
However, you can usually not split hunks arbitrarily. \
At least one line of _context_, i.e. a line without prefix `+` or `-`, must be in between. \
If you still want to split the hunk, you have to use `e` for _edit_.]]
////
Sie können diese Informationen u.a. in `gitk` sehen oder mit dem Kommando `git log --pretty=fuller`.
////
:fn17: pass:a,q[{wj}footnote:[ \
You can see this information in `gitk` or with the command `git log --pretty=fuller`.]]
////
Tatsächlich erstellt Git einen neuen Commit, dessen Änderungen eine Kombination der Änderungen des alten Commits und des Index ist.
Der neue Commit _ersetzt_ dann den alten.
////
:fn18: pass:a,q[{wj}footnote:[ \
In fact, Git creates a new commit whose changes are a combination of the changes made to the old commit and the index. \
The new commit then _replaces_ the old one.]]
////
Durch `git rm` löschen Sie eine Datei mit dem nächsten Commit; sie bleibt jedoch im Commit-Verlauf erhalten.
Wie man eine Datei vollständig, also auch aus der Versionsgeschichte, löscht, ist in Abschnitt 8.4.1, £Sensitive Informationen nachträglich entfernen£ nachzulesen.
////
:fn19: pass:a,q[{wj}footnote:[ \
`git rm` deletes a file with the next commit, but it remains in the commit history. \
For information on how to delete a file completely, including from the version history, see xref:gitbuch_08.adoc#sec.fb-censor[].]]
////
Dieses und die folgenden Beispiele stammen aus dem Git-Repository.
////
:fn20: {wj}footnote:[This and the following examples are from the Git repository.]
////
Sie können das Repository, das auf den folgenden Seiten detailliert untersucht wird, mit dem Befehl `git clone git://github.com/gitbuch/objektmodell-beispiel.git` herunterladen.
////
:fn21: pass:a,q,p[{wj}footnote:[ \
You can download the Git repository, which is examined in detail on the following pages, with the command: + \
`git clone git://github.com/gitbuch/objektmodell-beispiel.git`]]
////
https://de.wikipedia.org/wiki/Secure_Hash_Algorithm, "`Schwächen`".
////
:fn22: pass:a,q[{wj}footnote:[ \
https://en.wikipedia.org/wiki/SHA-1[^], "`Attacks`".]]
////
http://kerneltrap.org/mailarchive/git/2006/8/27/211001
////
:fn23: {wj}footnote:[https://web.archive.org/web/20120701221412/http://kerneltrap.org/mailarchive/git/2006/8/27/211001[^]]
////
Die technische Dokumentation bietet die Man-Page `gittutorial-2(7)`.
////
:fn24: pass:a,q[{wj}footnote:[ \
The technical documentation is provided in the man page `gittutorial-2(7)`.]]
////
Das Tag-Objekt wird hier nicht dargestellt, da es für das Verständnis der Objektstruktur nicht notwendig ist.
Sie finden es stattdessen in Abbildung 3.4, "Das Tag-Objekt".
////
:fn25: {wj}footnote:[ \
The tag object is not shown here because it is not necessary for understanding the object structure. \
Instead, you will find it in <<fig.tag-object>>.]
////
Git speichert sämtliche Objekte unterhalb von `.git/objects`.
Man unterscheidet zwischen _Loose Objects_ und _Packfiles_.
Die "`losen`" Objekte speichern den Inhalt in einer Datei, deren Name der SHA-1-Summe des Inhalts entspricht (Git speichert pro Objekt eine Datei).
Im Gegensatz dazu sind Packfiles komprimierte _Archive_ von vielen Objekten.
Das geschieht aus Performancegründen: Nicht nur ist die Übertragung bzw. Speicherung dieser Archive effizienter, auch wird das Dateisystem entlastet.
////
:fn26: pass:a,q[{wj}footnote:[ \
Git stores all objects under `.git/objects`. \
A distinction is made between _loose objects_ and _packfiles_. \
"`Loose`" objects store the content in a file whose name corresponds to the SHA-1 sum of the content (Git stores one file per object). \
In contrast, packfiles are compressed _archives_ of many objects. \
This is done for performance reasons: Not only is the transfer or storage of these archives more efficient, but the file system is also relieved.]]
////
Intern kennt Git natürlich Mechanismen, um Blobs als Deltas anderer Blobs zu erkennen und diese platzsparend zu _Packfiles_ zusammenzuschnüren.
////
:fn27: pass:a,q[{wj}footnote:[ \
Internally, of course, Git has mechanisms to recognize blobs as deltas of other blobs and to tie them together to _packfiles_ to save space.]]
////
Diese beiden Eigenschaften _gerichtet_ und _azyklisch_ sind die einzig notwendige Beschränkung, die man an einen Graphen stellen muss, der Änderungen über Zeit abbildet: Weder kann man zukünftige Änderungen referenzieren (Richtung der Kanten zeigt immer in die Vergangenheit), noch kann man irgendwann an einem Punkt ankommen, von dem aus der Weg schon vorgezeichnet ist (Zirkelschluss).
////
:fn28: pass:a,q[{wj}footnote:[ \
These two properties, _directional_ and _acyclic_, are the only necessary constraint to be placed on a graph that represents changes over time: Neither can future changes be referenced (the direction of the edges always points to the past), nor can you arrive at a point from which the path is already marked (circular reasoning).]]
// end::Chapter_2[]
// =============================================================================
// Chapter 3 (footnotes: 29-53)
// =============================================================================
// tag::Chapter_3[]
////
Das hindert Sie natürlich nicht, einen Branch auf einen Commit "`irgendwo in der Mitte`" zu setzen, was auch sinnvoll sein kann.
////
:fn29: pass:a,q[{wj}footnote:[ \
Of course, this does not prevent you from setting a branch to a commit "`somewhere in the middle,`" which can also be useful.]]
////
Aufgrund der Tatsache, dass bei einem Merge die Reihenfolge der direkten Vorfahren gespeichert wird, ist es wichtig, immer vom kleineren _in_ den größeren Branch zu mergen, also z.B.``topic`` nach `master`. \
Wenn Sie dann mit `master^^` Commits im Master-Branch untersuchen wollen, landen Sie nicht auf einmal auf Commits aus dem Topic-Branch (siehe auch Abschnitt 3.3, "Branches zusammenführen: Merges").
////
:fn30: pass:q,a[{wj}footnote:[ \
Due to the fact that the order of the direct ancestors is stored during a merge, it is important to always merge from the smaller _to_ the larger branch, e.g. `topic` to `master`. \
If you then want to use `master^^` to examine commits in the master branch, don't land on commits from the topic branch all at once (see also xref:gitbuch_03.adoc#sec.merge[]).]]
////
Wie Git eine Referenz auf Gültigkeit überprüft, können Sie bei Bedarf in der Man-Page `git-check-ref-format(1)` nachlesen.
////
:fn31: pass:a,q[{wj}footnote:[ \
To find out how Git checks a reference for validity, see the `git-check-ref-format(1)` man page.]]
////
Wie lange sie dort verweilen, bestimmen Sie mit entsprechenden Einstellungen für die _Garbage Collection_ (Wartungsmechanismen), siehe Abschnitt B.1, "Aufräumen".
////
:fn32: pass:a,q[{wj}footnote:[ \
How long they stay there is determined by corresponding settings for the _garbage collection_ (maintenance mechanisms), see xref:gitbuch_13.adoc#sec.gc[].]]
////
Eine detaillierte Übersicht der Vor- und Nachteile der beiden Schemata sowie eine Beschreibung des Release-Prozesses usw. finden Sie im Kapitel 6 des Buches _Open Source Projektmanagement_ von Michael Prokop (Open Source Press, München, 2010).
////
:fn33: pass:a,q[{wj}footnote:[ \
A detailed overview of the advantages and disadvantages of both schemes as well as a description of the release process etc. can be found in chapter 6 of the book _Open Source Projektmanagement_ by Michael Prokop (Open Source Press, Munich, 2010).]]
////
Um einen solchen getaggten Blob in ein Repository aufzunehmen, bedienen Sie sich des folgenden Kommandos: \
`git tag -am "<beschreibung>" <tag-name> $(git hash-object -w <datei>)`.]]
////
:fn34: pass:a,q[{wj}footnote:[ \
To add such a tagged blob to a repository, use the following command: \
`git tag -am "<description>" <tag-name> $(git hash-object -w <file>)`.]]
////
Es handelt sich hierbei um die Commits, die mit `git log v1.7.1..28ba96a` erfasst werden.
////
:fn35: pass:a,q[{wj}footnote:[ \
These are the commits captured with `git log v1.7.1..28ba96a`.]]
////
Um zu überprüfen, dass die Änderungen in Ihrem neuen Branch denen des alten entsprechen, verwenden Sie `git diff <reorder-feature> <feature>` -- wenn das Kommando keine Ausgabe erzeugt, dann enthalten die Branches identische Änderungen.
////
:fn36: pass:a,q[{wj}footnote:[ \
To verify that the changes in your new branch are the same as the old one, use `git diff <reorder-feature> <feature>` -- if the command does not produce output, the branches will contain identical changes.]]
////
Es ist nicht zwingend notwendig, dass eine Merge-Basis existiert; wenn Sie zum Beispiel mehrere Root-Commits in einem Repository verwalten (siehe auch Abschnitt 4.7, "Mehrere Root-Commits") und dann die darauf aufgebauten Branches mergen, gibt es -- sofern vorher noch kein Merge stattfand -- keine gemeinsame Basis. \
In diesem Fall erzeugt eine Datei, die auf beiden Seiten in verschiedenen Versionen vorliegt, einen Konflikt.
////
:fn37: pass:a,q[{wj}footnote:[ \
It is not absolutely necessary that a merge base exists; for example, if you manage multiple root commits in a repository (see xref:gitbuch_04.adoc#sec.multi-root[]) and then merge the branches built on top of them, there will be no common base if no merge has taken place before. \
In this case, a file that exists in different versions on both sides creates a conflict.]]
////
Die nachfolgende Beschreibung erläutert die Vorgehensweise der `resolve`-Strategie. Sie unterscheidet sich nur wenig von der Standard-Strategie `recursive`, siehe auch die Detailbeschreibung dieser Strategie in Abschnitt 3.3.3, "Merge-Strategien".
////
:fn38: pass:a,q[{wj}footnote:[ \
The following description explains the approach of the `resolve` strategy. \
It differs only slightly from the standard `recursive` strategy, see also the detailed description of this strategy in xref:gitbuch_03.adoc#sec.merge-strategies[].]]
////
Die `recursive`-Strategie geht also nur dann wesentlich intelligenter als `resolve` vor, wenn die _Topologie_ der Commits (d.h. die Anordnung, wo abgezweigt und zusammengeführt wurde) wesentlich komplizierter ist als ein bloßes Abzweigen und anschließendes Zusammenführen.
////
:fn39: pass:a,q[{wj}footnote:[ \
The `recursive` strategy is therefore only much more intelligent than `resolve` if the _topology_ of the commits (i.e., the order in which they branched and merged) is much more complicated than simply branching and then merging.]]
:fn40: pass:a,q[{wj}footnote:[ \
Die für den Merge relevanten Commits, die etwas an der Datei `output.c` geändert haben, kann Beatrice mit `git log --merge -p -- output.c` auflisten.]]
:fn41: {wj}footnote:[http://kdiff3.sourceforge.net[^]]
:fn42: {wj}footnote:[https://meld.sourceforge.net[^]]
////
In Vimdiff können Sie mit `Strg+W` und anschließender Bewegung mit den Pfeiltasten oder `h`, `j`, `k`, `l` das Fenster in die entsprechende Richtung wechseln. \
Mit `dp` bzw. `do` schieben Sie Änderungen auf die andere Seite oder übernehmen sie von dort (_diff put_ -- _diff obtain_).
////
:fn43: pass:a,q[{wj}footnote:[ \
In Vimdiff you can use kbd:[Ctrl+W] followed by movement with the arrow keys or kbd:[h], kbd:[j], kbd:[k], kbd:[l] to move the window in the appropriate direction. \
With kbd:[d]kbd:[p] or kbd:[d]kbd:[o] you move changes to the other side or apply them from there (_diff put_ -- _diff obtain_).]]
////
Die Meldung `Automatic merge failed` bedeutet lediglich, dass ein Konflikt auftrat, der _nicht_ durch einen 3-Wege-Merge gelöst werden konnte. \
Da Rerere keine sinnvolle Lösung garantieren kann, wird die Lösung nur "`bereitgestellt`", nicht aber als ultimative Lösung des Konflikts angesehen.
////
:fn44: pass:a,q[{wj}footnote:[ \
The message `Automatic merge failed` simply means that a conflict occurred that could _not_ be solved by a 3-way merge. \
Since Rerere cannot guarantee a meaningful solution, the solution is only "`provided,`" but not considered the ultimate solution of the conflict.]]
////
Weitere nützliche Tipps finden Sie in Kapitel 6, Workflows.
////
:fn45: {wj}footnote:[More useful tips can be found in <<ch.workflows>>.]
////
AsciiDoc ist eine simple, wiki-ähnliche Markup-Sprache: `http://www.methods.co.nz/asciidoc/`. \
Die Git-Dokumentation liegt in diesem Format vor und wird in HTML-Seiten und Man-Pages konvertiert, und auch dieses Buch wurde in AsciiDoc geschrieben!
////
:fn46: pass:a,q[{wj}footnote:[ \
AsciiDoc is a simple, wiki-like markup language: https://asciidoc.org[^]. \
The Git documentation is in this format and is converted to HTML pages and man pages, and this book was also written in AsciiDoc!]]
////
Das Repository des Git-Projekts selbst verwaltet zum Beispiel die autogenerierte HTML-Dokumentation in einem Branch `html`, der von den Entwicklungsbranches vollständig abgekoppelt ist. \
So kann es bei Merges zwischen den Code-Branches nicht zu Konflikten wegen unterschiedlich kompilierter HTML-Dokumentation kommen. \
Wie Sie solche "`entkoppelten`" Branches erstellen, beschreiben wir in Abschnitt 4.7, "Mehrere Root-Commits".
////
:fn47: pass:a,q[{wj}footnote:[ \
For example, the repository of the Git project itself manages the autogenerated HTML documentation in a branch `html`, which is completely separated from the development branches. \
This way, merges between the code branches cannot lead to conflicts due to differently compiled HTML documentation. \
How to create such "`decoupled`" branches is described in xref:gitbuch_04.adoc#sec.multi-root[].]]
////
Das liegt daran, dass das Merge-Kommando nicht jeden Commit einzeln untersucht. \
Stattdessen werden drei Trees verglichen, in denen _unter anderen_ diese Änderungen enthalten sind, siehe Abschnitt 3.3.1, "Zwei Branches verschmelzen".
////
:fn48: pass:a,q[{wj}footnote:[ \
This is because the merge command does not examine each commit individually. \
Instead, it compares three trees that contain these changes _among others_, see xref:gitbuch_03.adoc#sec.merge-detail[].]]
////
Das liegt daran, dass Rebase intern mit `cherry-pick` arbeitet, was wiederum erkennt, wenn die Änderungen, die durch den Commit eingebracht würden, schon vorhanden sind. \
Eine ähnliche Funktionalität bietet auch `git cherry` bzw. `git patch-id`, das fast gleiche Patches erkennen kann.
////
:fn49: pass:a,q[{wj}footnote:[ \
This is because rebase works internally with `cherry-pick`, which recognizes when the changes that would be introduced by the commit are already present. \
A similar functionality is provided by `git cherry` or `git patch-id`, which can detect almost identical patches.]]
////
Möglicherweise besitzt das Zeichen `^` in Ihrer Shell eine besondere Bedeutung (dies ist z.B. in der Z-Shell oder rc-Shell der Fall). Dann müssen Sie das Zeichen maskieren, also das Argument in Anführungszeichen einfassen oder einen Backslash voranstellen. \
In der Z-Shell existiert außerdem das Kommando `noglob`, das Sie `git` voranstellen, um die Sonderbedeutung von `^` aufzuheben.
////
:fn50: pass:a,q[{wj}footnote:[ \
Maybe the character `^` has a special meaning in your shell (this is for example the case in the Z-Shell or rc-Shell). \
In this case you have to mask the character, i.e. enclose the argument in quotation marks or prefix it with a backslash. \
In the Z-Shell, there is also the command `noglob`, which you use to precede `git` to remove the special meaning of `^`.]]
////
Dies ist nicht nötigerweise ein Commit -- das können auch Tags oder Blobs sein.
////
:fn51: {wj}footnote:[This is not necessarily a commit -- these can also be tags or blobs.]
////
Ob die Commits nicht schon aufgrund ihres Alters herausgefallen sind, hängt natürlich davon ab, wie oft Sie eine _Garbage-Collection_ per `git gc` durchführen. \
Siehe auch Abschnitt B.1, "Aufräumen".
////
:fn52: pass:a,q[{wj}footnote:[ \
Whether or not the commits have fallen out because of their age depends, of course, on how often you perform a _garbage collection_ via `git gc`. \
See also xref:gitbuch_13.adoc#sec.gc[].]]
////
Wollen Sie alle Commits der letzten zwei Wochen auflisten, verwenden Sie stattdessen `git log --since='two weeks ago'`.
////
:fn53: pass:a,q[{wj}footnote:[ \
If you want to list all commits in the last two weeks, use `git log --since='two weeks ago'` instead.]]
// end::Chapter_3[]
// =============================================================================
// Chapter 4 (footnotes: 54-64)
// =============================================================================
// tag::Chapter_4[]
////
Wenn Sie Patch-Stacks mit Git verwalten, bei denen potentiell Konflikte auftreten können, sollten Sie sich in jedem Fall das Feature _Reuse Recorded Resolution_ ansehen, kurz _rerere_. \
_Rerere_ speichert Konfliktlösungen und korrigiert Konflikte automatisch, wenn schon eine Lösung gespeichert wurde, siehe auch Abschnitt 3.4.2, "rerere: Reuse Recorded Resolution".
////
:fn54: pass:a,q[{wj}footnote:[ \
If you're managing patch stacks with Git that have potential conflicts, you should definitely take a look at the _Reuse Recorded Resolution_ feature, in short, _rerere_. \
_Rerere_ saves conflict resolutions and automatically corrects conflicts if a resolution has already been saved, see also xref:gitbuch_03.adoc#sec.rerere[].]]
////
Indem zum Beispiel der Branch in ein öffentlich verfügbares Repository hochgeladen wird, siehe Abschnitt 5.4, "Commits hochladen: git push".
////
:fn55: {wj}footnote:[ \
For example, by uploading the branch to a publicly available repository, see xref:gitbuch_05.adoc#sec.uploading-commits[].]
////
Im letzteren Fall machen Sie z.B. einfach ein `git remote update` (die neuen Commits werden in den Branch `origin/master` geladen) und bauen anschließend Ihren eigenen Branch von neuem auf `origin/master` auf. \
Siehe auch Abschnitt 5.1, "Wie funktioniert verteilte Versionsverwaltung?".
////
:fn56: pass:a,q[{wj}footnote:[ \
In the latter case, for example, you simply do a `git remote update` (the new commits are loaded into the `origin/master` branch) and then build your own branch from scratch to `origin/master`. \
See also xref:gitbuch_05.adoc#sec.distributed-systems[].]]
////
Den Quellcode finden Sie unter http://repo.or.cz/w/topgit.git.
////
:fn57: {wj}footnote:[ \
You can find the source code at https://repo.or.cz/w/topgit.git[^].]
////
Kurz `stg` oder StGit, erreichbar unter http://www.procode.org/stgit/
////
:fn58: pass:a,q[{wj}footnote:[ \
Short `stg` or StGit, reachable under https://stacked-git.github.io[^].]]
////
Das funktioniert auch problemlos, sofern alle Abzweigungen und Zusammenführungen _oberhalb_ der neuen Referenz sind (also nur Commits enthalten sind, von denen aus man die neue Basis erreichen kann).
Sonst schlägt Rebase bei jedem Commit fehl, der schon in der Geschichte enthalten ist (Fehlermeldung: "`nothing to commit`"); diese müssen dann stets mit einem `git rebase --continue` übersprungen werden.
////
:fn59: pass:a,q[{wj}footnote:[ \
This also works fine as long as all branches and merges are _above_ the new reference (i.e. only commits are included from which you can reach the new base). \
Otherwise, rebase will fail for every commit already in history (error message: "`nothing to commit`"); these must always be skipped with a `git rebase --continue`.]]
////
Weitere Beispiele finden Sie auf der Man-Page zu `gitignore(5)` und unter http://help.github.com/git-ignore/.
////
:fn60: pass:a,q[{wj}footnote:[ \
More examples can be found on the `gitignore(5)` man page and at https://docs.github.com/en/free-pro-team@latest/github/using-git/ignoring-files[^].]]
////
Das Verhalten wird unterbunden, indem Sie die Einstellung `clean.requireForce` auf `false` setzen.
////
:fn61: pass:a,q[{wj}footnote:[ \
This behavior can be prevented by setting the `clean.requireForce` setting to `false`.]]
////
Das Kommando sucht zuerst alle Commit-Objekte heraus, die nicht mehr erreichbar sind, und schränkt die Liste dann auf diejenigen ein, die Merge-Commits sind und deren Commit-Message die Zeichenkette `WIP` enthält -- die Eigenschaften, die ein Commit-Objekt aufweist, das als Stash erstellt wurde, vgl. Abschnitt 4.5.7, "Wie ist der Stash implementiert?".
////
:fn62: pass:a,q[{wj}footnote:[ \
The command first selects all commit objects that are no longer accessible, and then restricts the list to those that are merge commits and whose commit message contains the string `WIP` -- the properties that a commit object created as a stash has, see xref:gitbuch_04.adoc#sec.stash-implementation[].]]
////
Das stimmt nicht ganz; Sie können unter `refs/notes/commits` nur eine Notiz pro Commit speichern, zusätzlich aber z.B. unter `refs/notes/bts` noch weitere Notizen, die sich auf das Bug-Tracking-System beziehen -- dort aber auch nur eine pro Commit.
////
:fn63: pass:a,q[{wj}footnote:[ \
That's not quite true; you can only store one note per commit under `refs/notes/commits`, but you can store additional notes under e.g. `refs/notes/bts` that relate to the bug tracking system, and only one per commit there.]]
////
Dieser Commit muss natürlich nicht den Kern der Regression ausmachen, sie wurde möglicherweise durch einen ganz anderen Commit vorbereitet.
////
:fn64: {wj}footnote:[ \
Of course, this commit need not be the core of the regression, it may have been prepared by a completely different commit.]
// end::Chapter_4[]
// =============================================================================
// Chapter 5 (footnotes: 65-87)
// =============================================================================
// tag::Chapter_5[]
////
Wir haben den Spickzettel im Zusammenhang mit verschiedenen Git-Workshops erarbeitet.
Er steht unter einer Creative-Commons-Lizenz und wird mit der Git-Hosting-Plattform Github, die wir in Kapitel 11, Github beschreiben, verwaltet.
////
:fn65: pass:a,q[{wj}footnote:[ \
We developed the cheat sheet in connection with various Git workshops. \
It is licensed under a Creative Commons License and is managed with the Git hosting platform GitHub, which we describe in xref:gitbuch_11.adoc#ch.github[] beschreiben, verwaltet.]]
////
Genau genommen checkt Git nicht "`blind`" den Branch `master` aus.
Tatsächlich schaut Git nach, welchen Branch der `HEAD` der Gegenseite referenziert, und checkt diesen aus.
////
:fn66: pass:a,q[{wj}footnote:[ \
Strictly speaking, Git does not "`blindly`" check out the `master` branch. \
In fact, Git looks up which branch the `HEAD` of the other side references and checks it out.]]
////
Weitere Informationen zu dem Git-Protokoll finden Sie in Abschnitt 7.1.1, "Das Git-Protokoll" (siehe auch Abschnitt 3.1.1, "HEAD und andere symbolische Referenzen").
////
:fn67: pass:a,q[{wj}footnote:[ \
For more information on the Git protocol, see xref:gitbuch_07.adoc#sec.git-protocol[] (see also xref:gitbuch_03.adoc#sec.branch-refs[]).]]
////
Eine vollständige Auflistung der möglichen URLs finden Sie in der Man-Page `git-clone(1)` im Abschnitt "`Git URLs`".
////
:fn68: pass:a,q[{wj}footnote:[ \
For a complete list of possible URLs, see the `git-clone(1)` man page in the "`Git URLs`" section.]]
////
Der Stern (`*`) wird wie bei der Shell auch als _Wildcard_ interpretiert und zieht alle Dateien in einem Verzeichnis in Betracht.
////
:fn69: pass:a,q[{wj}footnote:[ \
The asterisk (`*`) is also interpreted as a _wildcard_ like the Shell and considers all files in a directory.]]
////
Remote-Tracking-Branches sind nur dazu gedacht, die Branches in einem Remote zu verfolgen. \
Das Auschecken eines Remote-Tracking-Branches führt zu einem Detached-Head-State samt entsprechender Warnung.
////
:fn70: {wj}footnote:[ \
Remote tracking branches are only intended to track the branches in a remote. \
Checking out a remote tracking branch will result in a detached head state and warning.]
////
Das Mergen von `origin/master` nach `master` ist ein ganz normaler Merge-Vorgang. \
Im obigen Beispiel wurden in der Zwischenzeit keine weiteren lokalen Commits getätigt und von daher auch keine Merge-Commits erstellt. \
Der `master` wurde per Fast-Forward auf `origin/master` vorgerückt.
////
:fn71: pass:a,q[{wj}footnote:[ \
Merging from `origin/master` to `master` is a normal merging process. \
In the example above, no further local commits have been made in the meantime and therefore no merge commits have been created. \
The `master` has been fast-forwarded to `origin/master`.]]
////
Das "`Forcieren`" findet aber nur lokal statt: Der Empfänger-Server kann trotz Angabe der Option `-f` das Hochladen unterbinden. \
Dafür ist die Option `receive.denyNonFastForwards` zuständig, bzw. die Rechtezuweisung `RW` bei Gitolite (siehe Abschnitt 7.2.2, "Gitolite-Konfiguration").
////
:fn72: pass:a,q[{wj}footnote:[ \
But the "`forcing`" only takes place locally: The recipient server can prevent the upload despite the specification of the option `-f`. \
This is done with the `receive.denyNonFastForwards` option, or the `RW` rights assignment for Gitolite (see xref:gitbuch_07.adoc#sec.gitolite-config[]).]]
////
Dies ist das Standard-Verhalten seit Version 2.0 (`push.default=simple`). \
Frühere Git-Versionen verwendeten ohne weitere Konfiguration die Einstellung `push.default=matching`, die besonders für Anfänger fehlerträchtig sein kann.
////
:fn73: pass:a,q[{wj}footnote:[ \
This is the default behavior since version 2.0 (`push.default=simple`). \
Earlier Git versions used the `push.default=matching` setting without any further configuration, which can be buggy, especially for beginners.]]
////
Im Git-Jargon werden solche Remotes als _Anonymous_ bezeichnet.
////
:fn74: pass:a,q[{wj}footnote:[ \
In Git jargon such remotes are called _anonymous_.]]
////
Die Syntax `<tag>^{}` dereferenziert ein Tag-Objekt, liefert also das Commit-, Tree- oder Blob-Objekt, auf das das Tag zeigt.
////
:fn75: pass:a,q[{wj}footnote:[ \
The syntax `<tag>^{}` dereferences a tag object, so returns the commit, tree or blob object to which the tag points.]]
////
Zum Beispiel mit dem Alias `push = push --tags`.
////
:fn76: pass:a,q[{wj}footnote:[ \
For example with the alias `push = push --tags`.]]
////
Wie Sie die Nummerierung, den Text und das Datei-Suffix anpassen, finden Sie in der Man-Page `git-format-patch(1)`.
////
:fn77: pass:a,q[{wj}footnote:[ \
See the `git-format-patch(1)` man page for information on how to customize the numbering, text and file suffix.]]
////
Die Zahl `n` ist die Gesamtzahl an Patches, die exportiert wurden, und `m` ist die Nummer des aktuellen Patches. \
In der Betreff-Zeile des dritten Patch von fünf steht dann z.B.``[PATCH 3/5\]``.
////
:fn78: pass:a,q[{wj}footnote:[ \
The number `n` is the total number of patches exported and `m` is the number of the current patch. \
For example, the subject line of the third patch of five would read `[PATCH 3/5\]`.]]
////
Sie sehen in Abbildung 5.10, "Patch-Serie als Mail-Thread" eine etwas andere Reihenfolge der Patches als in den bisherigen Beispielen. \
Das liegt daran, dass die erste Version der Patch-Serie aus nur zwei Patches bestand, und das dritte erst nach dem Feedback von der Git-Mailingliste dazukam. \
Die Serie wurde dann erweitert und per Rebase auf den Stand gebracht, wie sie in diesem Abschnitt abgebildet ist.]
////
:fn79: {wj}footnote:[ \
You can see in <<fig.mail-thread>> a slightly different order of patches than in the previous examples. \
This is because the first version of the patch series consisted of only two patches, and the third one was added after feedback from the Git mailing list. \
The series was then expanded and rebased to the state as shown in this section.]
////
Sofern auf Ihrem System kein _Mail Transfer Agent_ (MTA) installiert bzw. für den E-Mail-Versand konfiguriert ist, können Sie auch einen externen SMTP-Server verwenden. \
Passen Sie dafür die in der Sektion "`Use GMail as the SMTP server`" der bereits erwähnten Man-Page beschriebenen Einstellungen an.
////
:fn80: pass:a,q[{wj}footnote:[ \
If no _Mail Transfer Agent_ (MTA) is installed on your system or configured to send e-mail, you can also use an external SMTP server. \
To do so, adjust the settings described in the section "`Use GMail as the SMTP server`" of the already mentioned man page.]]
:fn81: {wj}footnote:[https://dpaste.com[^]]
:fn82: {wj}footnote:[https://gist.github.com[^]]
////
Nützliche Tipps und Tricks für diverse MUAs finden Sie in der Datei `Documentation/SubmittingPatches` im Git-via-Git-Repository im Abschnitt "`MUA specific hints`" sowie in der Man-Page von `git-format-patch(1)` in den Abschnitten "`MUA-specific Hints`" und "`Discussion`".
////
:fn83: pass:a,q[{wj}footnote:[ \
Useful tips and tricks for various MUAs can be found in the `Documentation/SubmittingPatches` file in the Git-via-Git repository in the "`MUA specific hints`" section, and in the `git-format-patch(1)` man page in the "`MUA specific hints`" and "`Discussion`" sections.]]
////
Für das Git-Projekt finden Sie diese unter: `Documentation/SubmittingPatches` im Quellcode-Repository.
////
:fn84: pass:a,q[{wj}footnote:[ \
For the Git project, you can find them at `Documentation/SubmittingPatches` in the source code repository.]]
////
Die `libgit.a` wird beim Kompilieren von Git erzeugt und versammelt alle Funktionen, die in Git "`öffentlich`" sind.
Sie ist allerdings nicht _reentrant_ oder Thread-sicher, so dass sie nur eingeschränkt verwendet werden kann. \
Diese Einschränkungen hat `libgit2` nicht.
////
:fn85: pass:a,q[{wj}footnote:[ \
The `libgit.a` is created when compiling Git and gathers all functions that are "`public`" in Git. \
However, it is not _reentrant_ or thread-safe, so its use is limited. \
`libgit2` does not have these restrictions.]]
////
Das Kommando ist kein Standard-Kommando von Git, wird aber von einigen Linux-Distributionen (z.B. Debian, Archlinux) sowie im Windows-Git-Installer automatisch mit installiert. \
Überprüfen Sie durch einen Aufruf von `git subtree`, ob das Kommando installiert ist. \
Falls nicht, können Sie das Script unter `/usr/share/doc/git/contrib/subtree/` suchen, oder aus dem Quellcode von Git (unter `contrib/subtree`) kopieren.
////
:fn86: pass:a,q[{wj}footnote:[ \
The command is not a standard command of Git, but is installed automatically by some Linux distributions (e.g. Debian, Archlinux) and in the Windows Git installer. \
Check by calling `git subtree` whether the command is installed. \
If not, you can search for the script under `/usr/share/doc/git/contrib/subtree/`, or copy it from the source code of Git (under `contrib/subtree`).]]
////
Achten Sie daher darauf, dass Sie mit dieser Technik nur Inhalte einbinden, die Sie auch weitergeben _dürfen_. \
Je nach Lizenz ist die Benutzung einer Software möglicherweise erlaubt, aber nicht die Weiterverbreitung (engl. _Distribution_).
////
:fn87: pass:a,q[{wj}footnote:[ \
Therefore, make sure that you only include content that you are _allowed_ to pass on using this technology. \
Depending on the license, the use of a software may be allowed, but not the distribution.]]
// end::Chapter_5[]
// =============================================================================
// Chapter 6 (footnotes: 88-91)
// =============================================================================
// tag::Chapter_6[]
////
Zu empfehlen ist u.a. das dritte Kapitel von _Open Source Projektmanagement_ von Michael Prokop (Open Source Press, München, 2010). \
Auch das _Manifesto for Agile Software Development_ hält unter http://agilemanifesto.org/ aufschlussreiche Hinweise bereit.
////
:fn88: pass:a,q[{wj}footnote:[ \
Among others, the third chapter of _Open Source Projektmanagement_ by Michael Prokop (Open Source Press, Munich, 2010) is recommended. \
The Manifesto for Agile Software Development also provides informative information at http://agilemanifesto.org[^].]]
////
Eine Ausnahme besteht, wenn Sie eine neue Entwicklung in der Mainline in Ihrem Topic-Branch benötigen; in dem Fall können Sie allerdings auch überlegen, den Topic-Branch per Rebase neu aufzubauen, so dass er die benötigte Funktionalität schon beinhaltet.
////
:fn89: {wj}footnote:[ \
An exception is if you need a new development in the mainline in your topic branch, but in that case you can consider rebuilding the topic branch via rebase so that it already contains the required functionality.]
////
Weitere Anregungen finden Sie im Kapitel 6 des Buches _Open Source Projektmanagement_ von Michael Prokop (Open Source Press, München, 2010).
////
:fn90: pass:a,q[{wj}footnote:[ \
You can find further suggestions in chapter 6 of the book _Open Source Projektmanagement_ by Michael Prokop (Open Source Press, Munich, 2010).]]
////
Jeder Commit referenziert genau einen Tree. \
Allerdings verhält sich `git archive` verschieden, je nachdem, ob Sie einen Commit (der einen Tree referenziert) oder einen Tree direkt angeben: Der Zeitpunkt der letzten Modifikation, der im Archiv aufgenommen wird, ist bei Trees die Systemzeit -- bei einem Commit allerdings wird der Zeitpunkt des Commits gesetzt.
////
:fn91: pass:a,q[{wj}footnote:[ \
Each commit references exactly one tree. \
However, `git archive` behaves differently depending on whether you specify a commit (which references a tree) or a tree directly: For trees, the time of the last modification included in the archive is the system time -- but for a commit, the time of the commit is set.]]
// end::Chapter_6[]
// =============================================================================
// Chapter 7 (footnotes: 92-105)
// =============================================================================
// tag::Chapter_7[]
////
Eine genauere Beschreibung findet sich im Git-Quellrepository im Verzeichnis `Documentation/technical`.
Dort finden sich drei Dateien, die das Packfile-Format erklären, teilweise entstanden aus Erklärungen von Linus Torvalds im IRC: `pack-format.txt`, `pack-heuristics.txt`, `pack-protocol.txt`.
Moderne Versionen von Git verwenden außerdem zusätzlich einen "`Bitmap Reachability Index`", der in `bitmap-format.txt` erklärt ist.
////
:fn92: pass:a,q[{wj}footnote:[ \
A more detailed description can be found in the Git source repository in the `Documentation/technical` directory. \
There you can find three files that explain the packfile format, partly based on explanations by Linus Torvalds on IRC: `pack-format.txt`, `pack-heuristics.txt`, `pack-protocol.txt`. \
Modern versions of Git also use an additional "`Bitmap Reachability Index,`" which is explained in `bitmap-format.txt`.]]
////
Die hier beschriebene Installation und Konfiguration bezieht sich auf Gitolite in Version 3.6.
Seit Gitolite Version 1.5, das in der ersten Auflage dieses Buches beschrieben wurde, gab es einige inkompatible Änderungen, die Sie hier nachlesen können: http://gitolite.com/gitolite/migr.html]
////
:fn93: {wj}footnote:[ \
The installation and configuration described here refers to Gitolite version 3.6. \
Since Gitolite version 1.5, which was described in the first edition of this book, there have been some incompatible changes, which you can read about here: https://gitolite.com/gitolite/migr.html[^]]
////
Ein Nutzer kann sich nur mit seinem privaten Schlüssel bei einem SSH-Server authentifizieren, wenn er eine mit seinem öffentlichen (und bei Gitolite hinterlegten) Schlüssel verschlüsselte Nachricht entschlüsseln kann. \
Anhand des Schlüssels, gegen den sich der Nutzer authentifiziert, kann Gitolite also den internen Nutzernamen ableiten.
////
:fn94: {wj}footnote:[ \
A user can only authenticate to an SSH server with his private key if he can decrypt a message encrypted with his public (and Gitolite's) key. \
Gitolite can derive the internal user name from the key the user authenticates against.]
////
Einige Distributionen stellen auch vorgefertigte Pakete von Gitolite zur Verfügung. \
Von deren Einsatz ist allerdings eher abzuraten, weil sie meist veraltet sind und außerdem global und mit einer bestimmten Konfiguration installiert werden. \
Wenn Sie dann einen anderen Nutzernamen als den von den Entwicklern ausgesuchten wählen, müssen Sie einen erheblichen Mehraufwand betreiben, um Gitolite zum Laufen zu bringen.
////
:fn95: {wj}footnote:[ \
Some distributions also provide ready-made packages of Gitolite. \
However, it is not recommended to use them because they are usually outdated and are installed globally and with a certain configuration. \
If you then choose a different username than the one chosen by the developers, you will have to spend a lot of extra effort to get Gitolite working.]
////
Ein _Release Candidate_ einer Software ist eine Vorab-Version eines neuen Releases, das der Öffentlichkeit (und nicht nur einer kleinen Gruppe von Beta-Testern) zugänglich gemacht wird. \
In das finale Release fließen dann nur noch Bugfixes ein. \
Auf Version 1.0 RC 1 (`v1.0-rc1`) folgt RC 2 (`v1.0-rc2`) usw., bis Version 1.0 herausgegeben wird (`v1.0`).
////
:fn96: pass:a,q[{wj}footnote:[ \
A _release candidate_ of a software is a pre-release version of a new release that is made available to the public (and not only to a small group of beta testers). \
Only bug fixes are then incorporated into the final release. \
Version 1.0 RC 1 (`v1.0-rc1`) is followed by RC 2 (`v1.0-rc2`) etc. until version 1.0 is released (`v1.0`).]]
////
Den _lesenden_ Zugriff auf ein Unterverzeichnis kann Gitolite natürlich nicht verbieten; das würde das Konzept des Git-Objekt-Modells mit seiner kryptografisch garantierten Integrität ad absurdum führen.
////
:fn97: pass:a,q[{wj}footnote:[ \
Of course, Gitolite cannot prohibit _read-only_ access to a subdirectory; this would make the concept of the Git object model with its cryptographically guaranteed integrity absurd.]]
////
Beachten Sie auch, dass es hier wieder zu Problemen bei der Erstellung von Branches kommen kann, s.o.
////
:fn98: {wj}footnote:[ \
Please also note that this may again cause problems when creating branches, see above.]
////
Die Dokumentation findet sich unter http://gitolite.com/. \
Der Autor hat außerdem das Buch "`Gitolite Essentials`"veröffentlicht (Packt Publishing, 2014).
////
:fn99: pass:a,q[{wj}footnote:[ \
The documentation can be found at https://gitolite.com[^]. \
The author has also published the book _Gitolite Essentials_ (Packt Publishing, 2014).]]
////
Streng genommen ist es dafür nötig, dass der kopierte `HEAD` mit dem der Gegenseite übereinstimmt. Besser noch überprüfen Sie ein von einem Entwickler signiertes Versions-Tag.
////
:fn100: pass:a,q[{wj}footnote:[ \
Strictly speaking, it is necessary for the copied `HEAD` to match that of the opposite side. \
Better still, check a version tag signed by a developer.]]
////
In manchen Distributionen, wie z.B. Debian, heißt der Daemon `openbsd-inetd`.
////
:fn101: pass:a,q[{wj}footnote:[ \
In some distributions, such as Debian, the daemon is called `openbsd-inetd`.]]
////
Das Programm `sv` ist Teil des Init-Frameworks _runit_ (http://smarden.org/runit/). \
Es ersetzt die Funktionalität des SysV-Init, kann aber auch darin integriert werden.
////
:fn102: pass:a,q[{wj}footnote:[ \
The program `sv` is part of the init framework _runit_ (http://smarden.org/runit/[^]). \
It replaces the functionality of SysV-Init, but can also be integrated into it.]]
////
Beachten Sie, dass eine Instanz des Git-Daemons nicht "`teuer`" ist. \
Das Zusammenpacken der angeforderten Objekte ist es allerdings. \
Nur weil Ihr Server also mehrere Dutzend HTTP-Abfragen pro Sekunde schafft, heißt das nicht, dass er auch dieselbe Anzahl Git-Verbindungen schafft.
////
:fn103: pass:a,q[{wj}footnote:[ \
Note that an instance of the Git daemon is not "`expensive.`" \
Packing the requested objects together is, however. \
So just because your server can handle dozens of HTTP requests per second doesn't mean it can handle the same number of Git connections.]]
////
Beachten Sie, dass die Reihenfolge in der `alias.url`-Direktive wichtig ist. \
Wenn Sie die Zeile `{quot}/{quot} => ...` nach oben verschieben, startet Lighttpd nicht mehr bzw. die Alias-Zuordnung wird nicht die gewünschte sein.
////
:fn104: pass:a,q[{wj}footnote:[ \
Note that the order in the `alias.url` directive is important. \
If you use the line `{quot}/{quot} => ...` to the top, Lighttpd will no longer start or the alias assignment will not be the desired one.]]
////
Das Tool `checkinstall` baut automatisch Debian- oder RPM-Pakete, die alle Dateien enthalten, die durch `make install` installiert worden wären. \
Homepage des Programmes: http://www.asic-linux.com.mx/~izto/checkinstall/
////
:fn105: pass:a,q[{wj}footnote:[ \
The tool `checkinstall` automatically builds Debian or RPM packages containing all files that would have been installed by `make install`. \
Homepage of the program: https://www.asic-linux.com.mx/~izto/checkinstall/[^]]]
// end::Chapter_7[]
// =============================================================================
// Chapter 8 (footnotes: 106-116)
// =============================================================================
// tag::Chapter_8[]
////
Sie können das Programm `indent` aus dem GNU-Projekt von http://www.gnu.org/software/indent/ herunterladen.
////
:fn106: pass:a,q[{wj}footnote:[ \
You can download the program `indent` from the GNU project from https://www.gnu.org/software/indent/[^].]]
////
Das Kommando `convert` ist Teil der ImageMagick-Suite. \
Wenn Sie `-clone 1-2` durch `-clone 0,2` ersetzen, werden die unterschiedlichen Bereiche aus dem _alten_ Bild kopiert.
////
:fn107: pass:a,q[{wj}footnote:[ \
The `convert` command is part of the ImageMagick suite. \
If you replace `-clone 1-2` with `-clone 0.2`, the different areas are copied from the _old_ image.]]
////
Die Grafiken wurden zum Release von Kernel 2.0 von Larry Ewing erstellt und finden sich unter http://www.isc.tamu.edu/~lewing/linux/.
////
:fn108: {wj}footnote:[ \
The graphics were created for the release of Kernel 2.0 by Larry Ewing and can be found at https://www.isc.tamu.edu/~lewing/linux/[^].]
////
"`Serverseitig`" heißt hier nur, dass sie nicht im lokalen Repository ausgeführt werden, sondern auf der "`Gegenseite`".
////
:fn109: pass:a,q[{wj}footnote:[ \
"`Server-side`" here only means that they are not executed in the local repository, but on the "`opposite side`".]]
////
Würde Git die kompletten Zugriffsrechte aufnehmen, dann wäre eine Datei gleichen Inhalts bei zwei verschiedenen Entwicklern, die unterschiedliche `umask(2)`-Einstellungen verwenden, nicht der gleiche Blob. \
Um das zu verhindern, verwendet Git ein vereinfachtes Rechtemanagement.
////
:fn110: pass:a,q[{wj}footnote:[ \
If Git were to include full permissions, then a file with the same contents would not be the same blob for two different developers using different `umask(2)` settings. \
To prevent this from happening, Git uses a simplified permission management system.]]
////
Sie können Ihre Shell-Scripte z.B. auf http://www.shellcheck.net/ automatisch überprüfen lassen.
////
:fn111: {wj}footnote:[ \
For example, you can have your shell scripts automatically checked at https://www.shellcheck.net/[^].]
////
Die _Debian Alquimist Shell_, ein Fork der _Alquimist Shell_, ist eine besonders kleine, schnelle Shell, die POSIX-kompatibel ist. \
Sie stellt auf vielen modernen Debian-Systemen sowie auf Ubuntu die Standard-Shell `/bin/sh`.
////
:fn112: pass:a,q[{wj}footnote:[ \
The _Debian Alquimist Shell_, a fork of the _Alquimist Shell_, is a very small, fast shell which is POSIX compatible. \
It provides the standard Shell `/bin/sh` on many modern Debian systems as well as on Ubuntu.]]
:fn113: {wj}footnote:[https://github.com/gitbuch/buch-scripte[^]]
////
Es gibt noch weitere Flags (`U`, `T` und `B`), die aber in der Praxis meist keine Rolle spielen.
////
:fn114: pass:a,q[{wj}footnote:[ \
There are other flags (`U`, `T` and `B`), but in practice they usually play no role.]]
:fn115: {wj}footnote:[https://git.wiki.kernel.org/index.php/Aliases[^]]
////
Sie können prinzipiell auch _gar keinen_ Vorgänger angeben. \
Dann wird der entsprechende Commit zu einem Root-Commit.
////
:fn116: pass:a,q[{wj}footnote:[ \
In principle, you _cannot_ specify a predecessor. \
Then the corresponding commit becomes a root commit.]]
// end::Chapter_8[]
// =============================================================================
// Chapter 9 (footnotes: 117-133)
// =============================================================================
// tag::Chapter_9[]
:fn117: {wj}footnote:[ \
https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Interaction_with_other_Revision_Control_Systems[^]]
:fn118: {wj}footnote:[http://rsvndump.sourceforge.net/[^]]
////
Existieren mehrere Verzeichnisse, die Branches und/oder Tags enthalten, so geben Sie diese durch mehreren Argumente `-t` bzw. `-b` an.
////
:fn119: pass:a,q[{wj}footnote:[ \
If there exist several directories, which contain branches and/or tags, you specify them by several arguments `-t` or `-b`.]]
////
Haben Sie bei der Konvertierung keinen Trunk per `-T` oder `--stdlayout` angegeben, wird ein einziger Branch namens `remotes/git-svn` generiert.
////
:fn120: pass:a,q[{wj}footnote:[ \
If you did not specify a trunk per `-T` or `--stdlayout` during conversion, a single branch called `remote/git-svn` will be generated.]]
////
Das Script ist in der Scriptsammlung für dieses Buch enthalten. \
Siehe: https://github.com/gitbuch/buch-scripte.
////
:fn121: {wj}footnote:[ \
The script is included in the script collection for this book. \
See: https://github.com/gitbuch/buch-scripte[^].]
////
Grundsätzlich können Sie diese Operationen auch direkt mit dem Kommando `mv` unterhalb von `.git/refs/` ausführen. \
Die Plumbing-Kommandos machen es aber möglich, auch "`exotische`" Fälle wie "`Packed Refs`" bzw. \
Referenzen, die Symlinks sind, korrekt zu behandeln. \
Außerdem schreibt `git update-ref` entsprechende Einträge in das Reflog und gibt Fehlermeldungen aus, falls etwas schiefgeht. \
Siehe hierzu auch Abschnitt 8.3, "Eigene Git-Kommandos schreiben".
////
:fn122: pass:a,q[{wj}footnote:[ \
Basically you can also perform these operations directly with the command `mv` below `.git/refs/`. \
However, the plumbing commands make it possible to handle "`exotic`" cases like "`Packed Refs`" or references that are symlinks correctly. \
In addition, `git update-ref` writes corresponding entries in the reflog and issues error messages if something goes wrong. \
See also xref:gitbuch_08.adoc#sec.scripting[].]]
////
Auch dieses Script finden Sie in der Scriptsammlung: https://github.com/gitbuch/buch-scripte.
////
:fn123: {wj}footnote:[ \
You can also find this script in the script collection: https://github.com/gitbuch/buch-scripte[^].]
:fn124: {wj}footnote:[https://github.com/nothingmuch/git-svn-abandon[^]]
:fn125: {wj}footnote:[https://gist.github.com/hartwork/fa275bedf8c2addeeb57[^]]
:fn126: {wj}footnote:[https://web.archive.org/web/20160118021532/http://gitorious.org/svn2git/svn2git[^]]
////
Im Git-via-Git Repository unter `contrib/svn-fe`
////
:fn127: pass:a,q[{wj}footnote:[ \
In the Git-via-Git repository under `contrib/svn-fe`]]
////
Vergleiche das Kommando: `svn copy trunk tags/v2.0`
////
:fn128: pass:a,q[{wj}footnote:[ \
Compare the command: `svn copy trunk tags/v2.0`]]
////
Vergleiche das Subversion-Kommando: `svn merge -r 23:25 branches/feature trunk`
////
:fn129: pass:a,q[{wj}footnote:[ \
Compare the Subversion command: `svn merge -r 23:25 branches/feature trunk`]]
////
Eine detaillierte technische Dokumentation finden Sie in der Man-Page `git-fast-import(1)`.
////
:fn130: pass:a,q[{wj}footnote:[ \
For detailed technical documentation, see the `git-fast-import(1)` man page.]]
////
Über die Option `--date-format` können Sie bei Bedarf andere Datumsformate zulassen.
////
:fn131: pass:a,q[{wj}footnote:[ \
You can use the `--date-format` option to allow other date formats if required.]]
////
Das führt zwar zu etwas mehr Rechenaufwand, vereinfacht aber die Struktur des Import-Programms wesentlich. \
Unter dem Gesichtspunkt, dass Import-Software in der Regel nur selten ausgeführt wird und Zeit keine kritische Rolle spielt, ist dieser Ansatz also sinnvoll.
////
:fn132: {wj}footnote:[ \
Although this leads to a little more computing effort, it simplifies the structure of the import program considerably. \
From the point of view that import software is usually rarely executed and time does not play a critical role, this approach makes sense.]
////
Das Script ist als Teil unserer Scriptsammlung unter https://github.com/gitbuch/buch-scripte verfügbar.
////
:fn133: {wj}footnote:[ \
The script is available as part of our script collection at https://github.com/gitbuch/buch-scripte[^].]
// end::Chapter_9[]
// =============================================================================
// Chapter 10 (footnotes: 134-137)
// =============================================================================
// tag::Chapter_10[]
////
Benutzen Sie `git-svn`, können Sie das Script anweisen, statt des Upstream-Branchs den SVN-Upstream (`remotes/git-svn`) für den Vergleich zu verwenden (sofern dieser vorhanden ist), indem Sie die Variable auf den Wert `auto` setzen.
////
:fn134: pass:a,q[{wj}footnote:[ \
If you use `git-svn`, you can tell the script to use the SVN upstream (`remotes/git-svn`) for comparison (if it exists) instead of the upstream branch by setting the variable to the value `auto`.]]
////
Die Man-Page `zshcompsys(1)` beschreibt, wie Sie die Completion noch weiter anpassen. \
Besonders die Optionen `group-name` und `menu-select` sind zu empfehlen.
////
:fn135: pass:a,q[{wj}footnote:[ \
The `zshcompsys(1)` man page describes how to further customize the completion. \
Especially the options `group-name` and `menu-select` are recommended.]]
////
Eine Liste der verfügbaren Systeme erhalten Sie mit einem Aufruf der Funktion `vcs_info_printsys`.
////
:fn136: pass:a,q[{wj}footnote:[ \
A list of available systems can be obtained by calling the `vcs_info_printsys` function.]]
:fn137: {wj}footnote:[https://github.com/gitbuch/buch-scripte[^]]
// end::Chapter_10[]
// =============================================================================
// Chapter 11 (footnotes: 138-150)
// =============================================================================
// tag::Chapter_11[]
:fn138: {wj}footnote:[https://github.com[^]]
:fn139: {wj}footnote:[https://web.archive.org/web/20150303192558/http://gitorious.org[^]]
:fn140: {wj}footnote:[https://repo.or.cz[^]]
:fn141: {wj}footnote:[https://sourceforge.net[^]]
:fn142: {wj}footnote:[https://www.berlios.de[^]]
:fn143: {wj}footnote:[https://curl.se[^]]
:fn144: {wj}footnote:[https://rubyonrails.org[^]]
:fn145: {wj}footnote:[https://jquery.com[^]]
:fn146: {wj}footnote:[https://github.com/gollum/gollum[^]]
:fn147: {wj}footnote:[https://github.com/github/markup[^]]
////
Nicht als Projekt-Fork misszuverstehen, bei dem sich ein Projekt aufgrund interner Differenzen spaltet.
////
:fn148: {wj}footnote:[ \
Not to be misunderstood as a project fork, where a project splits due to internal differences.]
:fn149: {wj}footnote:[https://github.com/blog/817-behold-image-view-modes[^]]
:fn150: {wj}footnote:[https://help.github.com[^]]
// end::Chapter_11[]
// =============================================================================
// Appendix A (footnotes: 151-153)