-
Notifications
You must be signed in to change notification settings - Fork 0
/
Git-Book_8.html
1685 lines (1530 loc) · 685 KB
/
Git-Book_8.html
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
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.16">
<meta name="author" content="Valentin Haenel, Julius Plenz">
<title>Git Book — 7. Git Servers</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<link rel="stylesheet" href="style0.css" type="text/css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="style1.css" type="text/css">
<link rel="stylesheet" href="asciidoctor-chunker.css" type="text/css"></head>
<body class="book toc2 toc-left">
<div id="header">
<h1>Git: Distributed Version Control for Code and Documents</h1>
<div class="details">
<span id="author" class="author">Valentin Haenel</span><br>
<span id="author2" class="author">Julius Plenz</span><br>
<span id="revnumber">version 3.0</span>
<br><span id="revremark">Beta Preview</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="index.html">Title Page</a></li><li><a href="Git-Book_1.html">Preface</a>
<ul class="sectlevel2">
<li><a href="Git-Book_1.html#sec.reader">Who Is This Book Intended For?</a></li>
<li><a href="Git-Book_1.html#sec.structure">How to Read the Book?</a></li>
<li><a href="Git-Book_1.html#sec.conventions">Conventions</a></li>
<li><a href="Git-Book_1.html#sec.install-git-repo">Installation and “The Git-Repository”</a></li>
<li><a href="Git-Book_1.html#sec.docs">Documentation and Help</a></li>
<li><a href="Git-Book_1.html#sec.contact">Downloads and Contacts</a></li>
<li><a href="Git-Book_1.html#sec.acknowledgements">Acknowledgements</a></li>
<li><a href="Git-Book_1.html#sec.preface-2nd-edition">Preface to the 2nd Edition</a></li>
<li><a href="Git-Book_1.html#sec.preface-cc-edition">Preface to the Creative Commons Edition</a></li>
</ul>
</li>
<li><a href="Git-Book_2.html">1. Introduction and First Steps</a>
<ul class="sectlevel2">
<li><a href="Git-Book_2.html#sec.terminology">1.1. Basic Terminology</a></li>
<li><a href="Git-Book_2.html#sec.first-steps">1.2. First Steps with Git</a></li>
<li><a href="Git-Book_2.html#chap.git-config">1.3. Configuring Git</a></li>
</ul>
</li>
<li><a href="Git-Book_3.html">2. The Basics</a>
<ul class="sectlevel2">
<li><a href="Git-Book_3.html#sec.basics">2.1. Git Commands</a></li>
<li><a href="Git-Book_3.html#sec.object-model">2.2. The Object Model</a></li>
</ul>
</li>
<li><a href="Git-Book_4.html">3. Practical Version Control</a>
<ul class="sectlevel2">
<li><a href="Git-Book_4.html#sec.branches">3.1. References: Branches and Tags</a></li>
<li><a href="Git-Book_4.html#sec.undo">3.2. Restoring Versions</a></li>
<li><a href="Git-Book_4.html#sec.merge">3.3. Merging Branches</a></li>
<li><a href="Git-Book_4.html#sec.merge-conflicts">3.4. Resolving Merge Conflicts</a></li>
<li><a href="Git-Book_4.html#sec.cherry-pick">3.5. Taking over Individual Commits: Cherry Picking</a></li>
<li><a href="Git-Book_4.html#sec.visualization">3.6. Visualizing Repositories</a></li>
<li><a href="Git-Book_4.html#sec.reflog">3.7. Reflog</a></li>
</ul>
</li>
<li><a href="Git-Book_5.html">4. Advanced Concepts</a>
<ul class="sectlevel2">
<li><a href="Git-Book_5.html#sec.rebase">4.1. Moving commits — Rebase</a></li>
<li><a href="Git-Book_5.html#sec.rebase-i">4.2. Rewriting History — Interactive Rebase</a></li>
<li><a href="Git-Book_5.html#sec.blame">4.3. Who Made These Changes? — Git Blame</a></li>
<li><a href="Git-Book_5.html#sec.ignore">4.4. Ignoring Files</a></li>
<li><a href="Git-Book_5.html#sec.stash">4.5. Outsourcing Changes — Git Stash</a></li>
<li><a href="Git-Book_5.html#sec.notes">4.6. Annotating Commits — Git Notes</a></li>
<li><a href="Git-Book_5.html#sec.multi-root">4.7. Multiple Root Commits</a></li>
<li><a href="Git-Book_5.html#sec.bisect">4.8. Finding Regressions — Git Bisect</a></li>
</ul>
</li>
<li><a href="Git-Book_6.html">5. Distributed Git</a>
<ul class="sectlevel2">
<li><a href="Git-Book_6.html#sec.distributed-systems">5.1. How Does Distributed Version Control Work?</a></li>
<li><a href="Git-Book_6.html#sec.clone">5.2. Cloning Repositories</a></li>
<li><a href="Git-Book_6.html#sec.downloading-commits">5.3. Downloading Commits</a></li>
<li><a href="Git-Book_6.html#sec.uploading-commits">5.4. Uploading Commits: git push</a></li>
<li><a href="Git-Book_6.html#sec.remotes-check">5.5. Examining Remotes</a></li>
<li><a href="Git-Book_6.html#sec.multi-remote">5.6. Distributed Workflow with Multiple Remotes</a></li>
<li><a href="Git-Book_6.html#sec.managing-remotes">5.7. Managing Remotes</a></li>
<li><a href="Git-Book_6.html#sec.remote-tags">5.8. Exchanging Tags</a></li>
<li><a href="Git-Book_6.html#sec.patch-queue">5.9. Patches via E-mail</a></li>
<li><a href="Git-Book_6.html#sec.dictator">5.10. A Distributed, Hierarchical Workflow</a></li>
<li><a href="Git-Book_6.html#sec.subprojects">5.11. Managing Subprojects</a></li>
</ul>
</li>
<li><a href="Git-Book_7.html">6. Workflows</a>
<ul class="sectlevel2">
<li><a href="Git-Book_7.html#sec.workflows-user">6.1. User</a></li>
<li><a href="Git-Book_7.html#sec.branching-model">6.2. A Branching Model</a></li>
<li><a href="Git-Book_7.html#sec.releases-management">6.3. Release Management</a></li>
</ul>
</li>
<li class="current"><a href="Git-Book_8.html">7. Git Servers</a>
<ul class="sectlevel2">
<li class="current"><a href="Git-Book_8.html#sec.server">7.1. Hosting a Git Server</a></li>
<li class="current"><a href="Git-Book_8.html#sec.gitolite">7.2. Gitolite: Simple Git Hosting</a></li>
<li class="current"><a href="Git-Book_8.html#sec.git-daemon">7.3. Git Daemon: Anonymous Read-Only Access</a></li>
<li class="current"><a href="Git-Book_8.html#sec.gitweb">7.4. Gitweb: The Integrated Web Frontend</a></li>
<li class="current"><a href="Git-Book_8.html#sec.cgit">7.5. CGit — CGI for Git</a></li>
</ul>
</li>
<li><a href="Git-Book_9.html">8. Git Automation</a>
<ul class="sectlevel2">
<li><a href="Git-Book_9.html#sec.attributes">8.1. Git Attributes — Treating Files Separately</a></li>
<li><a href="Git-Book_9.html#sec.hooks">8.2. Hooks</a></li>
<li><a href="Git-Book_9.html#sec.scripting">8.3. Writing Your Own Git Commands</a></li>
<li><a href="Git-Book_9.html#sec.filter-branch">8.4. Rewriting Version History</a></li>
</ul>
</li>
<li><a href="Git-Book_10.html">9. Interacting with Other Version Control Systems</a>
<ul class="sectlevel2">
<li><a href="Git-Book_10.html#sec.subversion">9.1. Subversion</a></li>
<li><a href="Git-Book_10.html#sec.fast-import">9.2. Custom Importers</a></li>
</ul>
</li>
<li><a href="Git-Book_11.html">10. Shell Integration</a>
<ul class="sectlevel2">
<li><a href="Git-Book_11.html#sec.bash-integration">10.1. Git and the Bash</a></li>
<li><a href="Git-Book_11.html#sec.zsh-integration">10.2. Git and the Z-Shell</a></li>
</ul>
</li>
<li><a href="Git-Book_12.html">11. GitHub</a></li>
<li><a href="Git-Book_13.html">Appendix A: Installation</a>
<ul class="sectlevel2">
<li><a href="Git-Book_13.html#linux">A.1. Linux</a></li>
<li><a href="Git-Book_13.html#sec.osx">A.2. Mac OS X</a></li>
<li><a href="Git-Book_13.html#sec.windows">A.3. Windows</a></li>
</ul>
</li>
<li><a href="Git-Book_14.html">Appendix B: Repository Structure</a>
<ul class="sectlevel2">
<li><a href="Git-Book_14.html#sec.gc">B.1. Cleaning Up</a></li>
<li><a href="Git-Book_14.html#sec.gc-performance">B.2. Performance</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content"><div class="sect1">
<h2 id="ch.server"><a class="anchor" href="Git-Book_8.html"></a>7. Git Servers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following is about hosting Git repositories and <em>Gitolite</em>, which allows you to flexibly manage repository access rights via SSH public keys.
It also explains how to install and configure the two web interfaces <em>Gitweb</em> and <em>CGit</em>, alternatively for Apache or Lighttpd.</p>
</div>
<div class="sect2">
<h3 id="sec.server"><a class="anchor" href="Git-Book_8.html#sec.server"></a>7.1. Hosting a Git Server</h3>
<div class="paragraph">
<p>First some basics: How do repositories on a server differ from those of a normal user?
And how does Git exchange the changes?</p>
</div>
<div class="sect3">
<h4 id="sec.git-protocol"><a class="anchor" href="Git-Book_8.html#sec.git-protocol"></a>7.1.1. The Git Protocol</h4>
<div class="paragraph">
<p>Git is designed for decentralized repository management; the smallest unit for exchanging changes between repositories is commits.
However, since there are sometimes thousands of commits between two versions of a piece of software, and a single commit-by-commit transfer would generate a lot of overhead, commits are grouped together into so-called <em>packfiles</em> before being transferred.
These packfiles are a simple but effective format.<sup class="footnote">[<a id="_footnoteref_92" class="footnote" href="#_footnotedef_92" title="View footnote.">92</a>]</sup>
They are also used to store (older) commits on the hard disk in a space-saving way (<code>git gc</code> or <code>git repack</code>, see <a href="Git-Book_14.html#sec.gc">Sec. B.1, “Cleaning Up”</a>).</p>
</div>
<div class="paragraph">
<p>These packfiles are usually transmitted via the Git protocol, which runs on port 9418/TCP by default.
The Git protocol is deliberately kept very simple in design and offers only a few functions that are directly related to the structure of Git: What data to send or receive, and a way for the sender and receiver sides to agree on the smallest possible amount of data that needs to be transmitted to synchronize both sides.</p>
</div>
<div class="paragraph">
<p>Therefore, the Git protocol does <em>not</em> include any authentication option.
Instead, Git uses an already existing, secure and simple authentication structure: SSH, the <code>'Secure Shell'</code>.</p>
</div>
<div class="paragraph">
<p>So while the Git protocol can be used unencrypted and in raw form for anonymous <em>read-only</em> access, writing or uploading via Git protocol only works via SSH.</p>
</div>
<div class="paragraph">
<p>Git also supports transport via HTTP(S), FTP(S), and Rsync.
Although Rsync is now considered <em>deprecated</em>, and should not be used anymore, there are some use cases for HTTP(S): In particularly restrictive environments with very restrictive firewall rules, you may be able to access a repository via HTTP(S) (i.e. only on port 80 or 443) for both read and write operations.
Platforms like GitHub (see <a href="Git-Book_12.html">Ch. 11, <em>GitHub</em></a>) therefore offer HTTPS as default transport method.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.git-pack-same-machine"><a class="anchor" href="Git-Book_8.html#sec.git-pack-same-machine"></a>7.1.2. Repositories on the Same Computer</h4>
<div class="paragraph">
<p>If you want to synchronize changes to repositories on the same computer, this does not have to be done via detours: Git communicates directly with the other side via Unix pipes, negotiates a common basis and synchronizes the data.
(Of course, this requires that the user invoking the Git command has at least read permission to the other repository’s pack files).</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.bare-repos"><a class="anchor" href="Git-Book_8.html#sec.bare-repos"></a>7.1.3. Bare Repositories: Repositories Without Working Tree</h4>
<div class="paragraph">
<p>So far, you’ve probably worked mostly with Git repositories, which were working tree and repository in one: The repository-internal data is stored in the <code>.git</code> subdirectory, all other files belong to the working tree, i.e. you can edit them while Git observes and stores the changes to these files (<em>tracking</em>).</p>
</div>
<div class="paragraph">
<p>A so-called <em>bare repository</em>, i.e. a “mere” repository, has no assigned working tree.
It contains only the files and directories that are stored in a “regular” repository under <code>.git</code>.</p>
</div>
<div class="paragraph">
<p>You create such a bare repository with <code>git init --bare</code>.
Take a look at the difference between the two options:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>cd /tmp/ && mkdir init-test && cd init-test</strong>
$ <strong>git init</strong>
Initialized empty Git repository in /tmp/init-test/.git/
$ <strong>ls -AF</strong>
.git/
$ <strong>mkdir ../init-test-bare && cd ../init-test-bare</strong>
$ <strong>git init --bare</strong>
Initialized empty Git repository in /tmp/init-test-bare/
$ <strong>ls -AF</strong>
branches/ config description HEAD hooks/ info/ objects/ refs/</pre>
</div>
</div>
<div class="paragraph">
<p>To create a backup of one of your normal repositories, you can create a new bare repository (e.g. on a USB stick) and upload all your references (and thus all your commits):</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>git init --bare /mnt/usb/repo-backup/</strong>
$ <strong>git push --all /mnt/usb/repo-backup/</strong></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="sec.permissions"><a class="anchor" href="Git-Book_8.html#sec.permissions"></a>7.1.4. Repository Access Permissions</h4>
<div class="paragraph">
<p>With <code>git init</code> the files are usually created with read and write permission according to the <code>umask</code> setting.
This is also a convenient choice for the end user.
However, if you want to set up a repository on a server, you can use the <code>--shared</code> option to specify who (at the filesystem level) can access the repository.</p>
</div>
<div class="hdlist">
<table>
<tbody><tr>
<td class="hdlist1">
<code>umask</code>
</td>
<td class="hdlist2">
<p>Default, if <code>--shared</code> is not specified; uses the currently set <code>umask</code>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>group</code>
</td>
<td class="hdlist2">
<p>Default, if only <code>--shared</code> is specified.
Assigns write permissions to all group members.
Especially directories are also set to <code>g+sx</code> mode, allowing all group members to create new files (i.e. upload commits).
Note that if the <code>umask</code> sets read permission for all users (<code>a+r</code>), this permission will still be granted.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>all</code>
</td>
<td class="hdlist2">
<p>Same as <code>group</code>, except that read permissions are explicitly granted for all, regardless of the <code>umask</code>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>0<nnn></code>
</td>
<td class="hdlist2">
<p>Set the <code>umask</code> explicitly to <code><nnn></code>.</p>
</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>When you initialize a repository with <code>--shared</code>, the <code>receive.denyNonFastForwards</code> option is automatically set.
It prevents uploading commits that cannot be integrated via Fast-Forwards (even if the user explicitly wants to via <code>git push -f</code>).</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.git-shell"><a class="anchor" href="Git-Book_8.html#sec.git-shell"></a>7.1.5. Access via SSH: The Git Shell</h4>
<div class="paragraph">
<p>Usually, write access to Git repositories located on another computer can only be granted via SSH.
However, it is generally undesirable to grant a user who will have access to a repository the same user rights to the whole system.</p>
</div>
<div class="paragraph">
<p>Git works around this problem with the included <code>git-shell</code> program.
It works like a shell, but only allows you to run four Git commands that are responsible for uploading and downloading pack files.
Interactive use or execution of other commands is denied by the shell unless you explicitly enable the “Interactive Mode” of the shell — see the <code>git-shell(1)</code> man page for details.</p>
</div>
<div class="paragraph">
<p>If you create a new user and assign the git shell to him, e.g., using <code>chsh <user></code>, he cannot log in via SSH, but he can upload commits to all git repositories to which he has write permission.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.ssh-pubkey"><a class="anchor" href="Git-Book_8.html#sec.ssh-pubkey"></a>7.1.6. Access via SSH: Public Keys</h4>
<div class="paragraph">
<p>It’s a major advantage that Git uses SSH as an encrypted and authenticated transport channel, because most users already have a key pair (public/private) with which they log in on other computers.</p>
</div>
<div class="paragraph">
<p>So instead of tediously assigning (and then sending out) passwords to accounts, a system administrator can limit access to Git repositories to users who authenticate against SSH public keys.
This saves time for the user (by eliminating the need to re-enter a password), but also saves the administrator from having to worry about password changes (which would not be easily possible using the Git shell).</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.two-users"><a class="anchor" href="Git-Book_8.html#sec.two-users"></a>7.1.7. Example: Two Users Want to Collaborate</h4>
<div class="paragraph">
<p>In the following we will show you how to set up two users on your system, <code>max</code> and <code>moritz</code>, and let them work on the same repository.</p>
</div>
<div class="paragraph">
<p>First, we have to set up a repository that the two users will want to access later.
Assuming that other repositories might follow later, we will create a Unix group <code>git</code> (generally for Git users) and a directory <code>/var/repositories</code> with read permission for members of the <code>git</code> group, as well as a <code>git-example</code> group and its corresponding directory, writeable only for members of <code>git-example</code>, in which the repository will later be located:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>groupadd git</strong>
$ <strong>groupadd git-beispiel</strong>
$ <strong>mkdir -m 0750 /var/repositories</strong>
$ <strong>mkdir -m 0770 /var/repositories/git-beispiel</strong>
$ <strong>chown root:git /var/repositories</strong>
$ <strong>chown root:git-beispiel /var/repositories/git-beispiel</strong></pre>
</div>
</div>
<div class="paragraph">
<p>We also create a repository in the last created directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>git init --bare --shared /var/repositories/git-beispiel</strong>
$ <strong>chown -R nobody:git /var/repositories/git-beispiel</strong></pre>
</div>
</div>
<div class="paragraph">
<p>Next we create the two users.
Note that this call will <em>not</em> create a home directory for the users under <code>/home/</code>.
Also, both are added to the <code>git</code> and <code>git-example</code> groups:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>adduser --no-create-home --shell /usr/bin/git-shell max</strong>
$ <strong>adduser --no-create-home --shell /usr/bin/git-shell moritz</strong>
$ <strong>adduser max git</strong>
$ <strong>adduser max git-beispiel</strong>
$ <strong>adduser moritz git</strong>
$ <strong>adduser moritz git-beispiel</strong></pre>
</div>
</div>
<div class="paragraph">
<p>Next, we have to assign a password to each user via <code>passwd</code> so that they can log in via SSH.
Afterwards, the new users can now work together on a project.
You add the remote as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>git remote add origin max@server:/var/repositories/git-example</strong></pre>
</div>
</div>
<div class="paragraph">
<p>All other users who want to contribute to this project must belong to the <code>git-example</code> group.
So this approach is essentially based on the use of Unix groups and Unix users.
However, a server admin usually wants to offer not only Git, but various services.
And to control the user administration entirely via Unix groups is rather inflexible.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sec.gitolite"><a class="anchor" href="Git-Book_8.html#sec.gitolite"></a>7.2. Gitolite: Simple Git Hosting</h3>
<div class="paragraph">
<p>The aforementioned described way of managing users has some major disadvantages.
Namely:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A full Unix account must be created for each user.
This means a lot of additional work for the administrator and possibly also opens security holes.</p>
</li>
<li>
<p>For each project a separate Unix group must be created.</p>
</li>
<li>
<p>For each user created, the access permissions must be adjusted manually (or via a script).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The program <em>Gitolite</em> provides a remedy.<sup class="footnote">[<a id="_footnoteref_93" class="footnote" href="#_footnotedef_93" title="View footnote.">93</a>]</sup></p>
</div>
<div class="paragraph">
<p>Gitolite originated from the <em>Gitosis</em> project, which is now considered obsolete.
The idea: Only only Unix user (e.g. <code>git</code>) is created on the server.
Internally, Gitolite then manages a list of users with associated SSH keys.
But these users do not have a “real” user account on the system.</p>
</div>
<div class="paragraph">
<p>Users log <em>just</em> into the <code>git</code> account with their public SSH keys.
This has three major advantages:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>No password needs to be assigned or changed.</p>
</li>
<li>
<p>Users can store multiple SSH keys (for different computers they work on).</p>
</li>
<li>
<p>Using the SSH key a user logs in with, Gitolite can <em>uniquely</em><sup class="footnote">[<a id="_footnoteref_94" class="footnote" href="#_footnotedef_94" title="View footnote.">94</a>]</sup> derive the internal username and thus the permissions on the repositories managed by Gitolite.</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="sec.installing-gitolite"><a class="anchor" href="Git-Book_8.html#sec.installing-gitolite"></a>7.2.1. Installing Gitolite</h4>
<div class="paragraph">
<p>The installation of Gitolite is simple.
All you need to do is have your public key ready to register as an administrator.
You don’t need root privileges unless you need to create the <code>git</code> user first,<sup class="footnote">[<a id="_footnoteref_95" class="footnote" href="#_footnotedef_95" title="View footnote.">95</a>]</sup> so skip the next step if you have already created such a user.</p>
</div>
<div class="paragraph">
<p>First, create a user on the computer that will act as the git server (henceforth <code><server></code>).
Usually, this user is called <code>git</code>, but you may also call it something else (e.g. <code>gitolite</code>).
You can specify <code>/home/git</code> as your home directory or, as in this example, something like <code>/var/git</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>server# <strong>adduser --home /var/git git</strong></pre>
</div>
</div>
<div class="paragraph">
<p>Now switch to the <code>git</code> user.
Gitolite needs the <code>.ssh/</code> and <code>bin/</code> directories, so we need to create them:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>server$ <strong>mkdir -m 0700 ~/.ssh ~/bin</strong></pre>
</div>
</div>
<div class="paragraph">
<p>Now clone the Gitolite repository and install a symlink to <code>bin</code> (this is already the whole installation):</p>
</div>
<div class="listingblock">
<div class="content">
<pre>server$ <strong>git clone git://github.com/sitaramc/gitolite</strong>
server$ <strong>gitolite/install -ln</strong></pre>
</div>
</div>
<div class="paragraph">
<p>You can now configure Gitolite and enter your public key with which you want to manage the Gitolite configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>server$ <strong>bin/gitolite setup -pk <ihr-key>.pub</strong></pre>
</div>
</div>
<div class="paragraph">
<p>Check that Gitolite works on the computer where you normally work (and where you have stored the corresponding private key):</p>
</div>
<div class="listingblock">
<div class="content">
<pre>client$ <strong>ssh -T git@<server></strong>
...
R W gitolite-admin</pre>
</div>
</div>
<div class="paragraph">
<p>You should verify that your key gives you read and write permission to the gitolite-admin repository.
Now clone it onto your computer:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>client$ <strong>git clone git@<server>:gitolite-admin</strong></pre>
</div>
</div>
<div class="paragraph">
<p>The repository contains the entire configuration for Gitolite.
You check in your changes there and upload them via <code>git push</code>: the server automatically updates the settings.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.gitolite-config"><a class="anchor" href="Git-Book_8.html#sec.gitolite-config"></a>7.2.2. Configuring Gitolite</h4>
<div class="paragraph">
<p>The Gitolite admin directory contains two subdirectories, <code>conf</code> and <code>keydir</code>.
To introduce a new user to Gitolite, you need to put their SSH key under <code>keydir/<user>.pub</code>.
If the user has multiple keys, you can store them in separate files of the format <code><user>@<description>.pub</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>client$ <strong>cat > keydir/[email protected]</strong>
ssh-dss AAAAB3NzaC1kc3M ... dTw== feh@mali
^D
client$ <strong>cat > keydir/[email protected]</strong>
ssh-dss AAAAB3NzaC1kc3M ... 5LA== feh@deepthought
^D</pre>
</div>
</div>
<div class="paragraph">
<p>Don’t forget to check in the new keys with <code>git add keydir</code> followed by <code>git commit</code>.
To make them known to the gitolite installation, you also need to upload the commits using <code>git push</code>.</p>
</div>
<div class="paragraph">
<p>Then you can assign permissions to this username in the <code>conf/gitolite.conf</code> configuration file.</p>
</div>
<div class="paragraph">
<p>You can save yourself a lot of administrative work and typing by using <em>macros</em>.
You can combine groups (of users or repositories), e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@test_entwickler = max markus felix
@test_repos = test1 test2 test3</pre>
</div>
</div>
<div class="paragraph">
<p>These macros are also evaluated recursively.
When defining them, it does not have to be clear whether they are users or repositories; the macros are only evaluated at runtime.
This allows you to create groups from other groups:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@proj = @developer @tester @admins</pre>
</div>
</div>
<div class="paragraph">
<p>There is a special group <code>@all</code> which, depending on the context, contains all users or all repositories.</p>
</div>
<div class="paragraph">
<p>You can configure one (or more) repositories as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo @test_repos
RW+ = @test_entwickler</pre>
</div>
</div>
<div class="paragraph">
<p><code>R</code> and <code>W</code> stand for read or write access.
The plus means that forced uploading is also allowed (<em>non-fast-forward</em>, i.e. also deleting commits).</p>
</div>
<div class="paragraph">
<p>For a repository, of course, several such lines can be entered.
In a small project there could be maintainers, other developers and testers.
Then the access rights could be regulated as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@maintainers = ... # Hauptentwickler/Chefs
@developers = ... # Weitere Entwickler
@testers = ...
repo Projekt
RW+ = @maintainers
RW = @developers
R = @testers</pre>
</div>
</div>
<div class="paragraph">
<p>Thus, the testers have read-only access, while the developers are allowed to upload new commits, but only if they can be integrated via <em>fast-forward</em>.
The main maintainers are allowed “everything”.</p>
</div>
<div class="paragraph">
<p>These lines are processed sequentially.
If the line applies to a user, Gitolite authorizes the user and grants him the appropriate rights.
If no line matches the user, the user is rejected and is not allowed to change anything in the repository.</p>
</div>
<div class="paragraph">
<p>A user can view all his permissions by simply logging into the Git server via SSH.
Immediately after installation, this is how it looks like to the administrator:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>ssh -q git@<server></strong>
hello feh, this is git@mjanja running gitolite3 v3.6.1-6-gdc8b590 on git 2.1.0
R W gitolite-admin
R W testing</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="sec.gitweb-name"><a class="anchor" href="Git-Book_8.html#sec.gitweb-name"></a>7.2.3. Ownership and Description</h4>
<div class="paragraph">
<p>If you want to install a web-based tool to browse the Git repositories later, you should also name a person in charge and describe the project:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo <repo-name>
# Zugriffsrechte
config gitweb.owner = "Julius Plenz"
config gitweb.description = "Ein Test-Repository"</pre>
</div>
</div>
<div class="paragraph">
<p>For this to work, you must first enable Gitolite to set these config settings: This is done on the server where Gitolite is installed, in the file <code>.gitolite.rc</code>: Enter the value <code>gitweb\..*</code> under the <code>GIT_CONFIG_KEYS</code> key.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.file-access"><a class="anchor" href="Git-Book_8.html#sec.file-access"></a>7.2.4. Access Rights on File or Branch Level</h4>
<div class="paragraph">
<p>Especially in corporate environments, access rights often have to be differentiated even more finely than a mere “has access” and “must not access”.
For this purpose, Gitolite offers access restriction on directory- and file- as well as tag- and branch-level.</p>
</div>
<div class="paragraph">
<p>We will first look at a case that occurs frequently: developers should be able to develop on development branches at will, but only a small group of maintainers should be able to edit “important” branches such as <code>master</code>.</p>
</div>
<div class="paragraph">
<p>This could be implemented in a similar way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@maintainers = ...
@developers = ...
repo Projekt
RW+ dev/ = @developers
RW+ = @maintainers
R = @developers</pre>
</div>
</div>
<div class="paragraph">
<p>Here a “development namespace” is created: The group of developers can work with branches below <code>dev/</code>, e.g. create <code>dev/feature</code> or delete it.
However, the developers can only read the <code>master</code> branch, not change it — this is reserved for the maintainers.</p>
</div>
<div class="paragraph">
<p>The part between the <em>flags</em> (<code>RW+</code>) and the equal sign is a so-called <em>Perl-Compatible Regular Expression</em> (PCRE).
If it does not start with <code>refs/</code>, the expression refers to all references below <code>refs/heads/</code>, i.e. branches.
In the above example, any references below <code>refs/heads/dev/</code> can be modified — but not the <code>dev</code> branch itself, nor <code>anything-dev</code>!</p>
</div>
<div class="paragraph">
<p>But if such an expression starts explicitly with <code>refs/</code>, you can manage any references.
In the following way you can set up that all maintainers are allowed to create <em>Release Candidate</em> tags,<sup class="footnote">[<a id="_footnoteref_96" class="footnote" href="#_footnotedef_96" title="View footnote.">96</a>]</sup> but only <em>one</em> maintainer is really allowed to create the versioning tag (or any other):</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo Projekt
RW+ refs/tags/v.*-rc[0-9]+$ = @maintainers
RW+ refs/tags/ = <projektleiter></pre>
</div>
</div>
<div class="paragraph">
<p>If one of the maintainers still wants to upload a tag like <code>v1.0</code>, the following happens:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>remote: W refs/tags/v1.0 <repository> <user> DENIED by fallthru
remote: error: hook declined to update refs/tags/v1.0
To <user>:<repository>
! [remote rejected] v1.0 -> v1.0 (hook declined)</pre>
</div>
</div>
<div class="paragraph">
<p>As mentioned above, here the rules are applied one after the other.
Since the tag <code>v1.0</code> does not match the regular expression above, only the bottom line comes into question, but the username does not match.
No line is left (<code>fallthru</code>), so the action is not allowed.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.personal-namespaces"><a class="anchor" href="Git-Book_8.html#sec.personal-namespaces"></a>7.2.5. Personal Namespaces</h4>
<div class="paragraph">
<p>The concept of personal namespaces is somewhat more flexible.
This gives each developer his own hierarchy of branches that he can manage.</p>
</div>
<div class="paragraph">
<p>There is a special keyword for this, <code>USER</code>, which is replaced by the user name currently accessing the branch.
This makes the following possible:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo Projekt
RW+ p/USER/ = @developers
R = @developers @maintainers</pre>
</div>
</div>
<div class="paragraph">
<p>Now all developers under <code>p/<user>/</code> can manage their branches as they like.
The lower directive makes sure that all developers can read these branches.
Now <code>max</code> can e.g. create <code>p/max/bugfixes</code>, but <code>moritz</code> can only read them.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.file-level-acl"><a class="anchor" href="Git-Book_8.html#sec.file-level-acl"></a>7.2.6. File-Level Access Control</h4>
<div class="paragraph">
<p>Gitolite also allows file- and directory-level access restrictions.
The virtual reference <code>VREF/NAME</code> is responsible for this.
For example, you can allow the documentation team only (writing<sup class="footnote">[<a id="_footnoteref_97" class="footnote" href="#_footnotedef_97" title="View footnote.">97</a>]</sup>) access to <code>doc/</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@doc = ... # Dokumentations-Team
repo Projekt
RW VREF/NAME/doc/ = @doc
- VREF/NAME/ = @doc</pre>
</div>
</div>
<div class="paragraph">
<p>However, the following pitfalls must be taken into account: Once the keyword <code>VREF/NAME</code> appears once, the file-based rules are applied to <em>all</em> users.
If none of them apply, access is allowed — so the second rule is important, which prohibits access for <code>@doc</code> unless the commit only modifies files under <code>doc/</code> (see also <a href="Git-Book_8.html#sec.gl-deny">Sec. 7.2.7, “Explicitly Prohibiting Actions”</a> below).</p>
</div>
<div class="paragraph">
<p>Access control checks at the commit level which files are modified; if a commit contains changes to a file that the user is not allowed to edit, the entire <code>push</code> process is aborted.
In particular, no actions can be performed that involve commits from other developers that modify files outside the allowed range.</p>
</div>
<div class="paragraph">
<p>Specifically, in relation to the above example, this means that <code>@doc</code> members generally <em>cannot create new branches</em>.
Creating a new branch would mean creating a new reference to an initial commit and then <em>fast-forwarding</em> all commits from top to root, i.e., the entire project history.
However, there are certainly commits in it that modify files outside of <code>doc/</code>, and so the action is prohibited.</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.gl-deny"><a class="anchor" href="Git-Book_8.html#sec.gl-deny"></a>7.2.7. Explicitly Prohibiting Actions</h4>
<div class="paragraph">
<p>Previously, a user was only rejected if he failed all rules (<code>fallthru</code>), i.e. if no rights were assigned to him.
But the <code>-</code> flag (instead of <code>RW</code>) can be used to explicitly restrict access.
Again, the rules are passed through from top to bottom.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo Projekt
- VREF/NAME/Makefile = @developers</pre>
</div>
</div>
<div class="paragraph">
<p>This directive prohibits members of <code>@developers</code> from making commits that modify the <code>Makefile</code>.<sup class="footnote">[<a id="_footnoteref_98" class="footnote" href="#_footnotedef_98" title="View footnote.">98</a>]</sup></p>
</div>
<div class="paragraph">
<p>By convention, you should never upload forced updates to the <code>master</code> or <code>maint</code> branches (see also <a href="Git-Book_4.html#sec.branches">Sec. 3.1, “References: Branches and Tags”</a>).
You can now force this policy with Gitolite:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo Projekt
RW master maint = @developers
- master maint = @developers
RW+ = @developers</pre>
</div>
</div>
<div class="paragraph">
<p>If a branch that is <em>not</em> called <code>master</code> or <code>maint</code> is uploaded, only the third rule is applied and arbitrary access (including non <em>fast-forward</em> updates) is allowed.
Commits that can be integrated to <code>master</code> or <code>maint</code> via <em>fast-forward</em> are allowed by the first rule.
Note the missing plus sign, though: A forced update is not covered by the first rule, but by the second one, which explicitly prohibits everything (that has not been allowed before).</p>
</div>
</div>
<div class="sect3">
<h4 id="sec.enforcing-policies"><a class="anchor" href="Git-Book_8.html#sec.enforcing-policies"></a>7.2.8. Should Policies Be Enforced?</h4>
<div class="paragraph">
<p>With the means presented here and others, which you can take from the documentation, <sup class="footnote">[<a id="_footnoteref_99" class="footnote" href="#_footnotedef_99" title="View footnote.">99</a>]</sup> you are able to force policies very flexibly.
However, it may not be useful to control everything down to the smallest detail.
As mentioned above, especially a control on file name level is problematic.
Then, if hours of work go into a commit, but it can’t be uploaded because one of those restrictions prohibits it, the frustration is great (and fixing that commit is not trivial, either; see <em>rebase</em>, <a href="Git-Book_5.html#sec.rebase">Sec. 4.1, “Moving commits — Rebase”</a>).</p>
</div>
<div class="paragraph">
<p>At the branch level, it makes sense to give only a limited group of developers access to “important” branches (such as <code>master</code>).
Of course, strict control over who can do what comes at the expense of flexibility, and it’s this flexibility that makes branching in Git so practical.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sec.git-daemon"><a class="anchor" href="Git-Book_8.html#sec.git-daemon"></a>7.3. Git Daemon: Anonymous Read-Only Access</h3>
<div class="paragraph">
<p>The Git daemon allows unencrypted, anonymous, read-only access to Git repositories via the Git protocol.
It comes with Git and usually runs on TCP port 9418 (and can thus be started without root privileges).</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The transmission is not encrypted.
However, the cryptographic integrity that Git constantly checks excludes the possibility of attackers manipulating the data stream and smuggling in malicious code.<sup class="footnote">[<a id="_footnoteref_100" class="footnote" href="#_footnotedef_100" title="View footnote.">100</a>]</sup></p>
</li>
<li>
<p>This way is ideal for making source code available to a large number of people quickly and easily.
Only the minimum of necessary information is downloaded (only the required commits are negotiated and then transferred packed).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In order to export one or more repositories, simply execute <code>git daemon <path></code>, where <code><path></code> is the path where your repositories are located.
You can also specify multiple paths.
If you have already set up Gitolite as above, <code>/var/git/repositories</code> is a useful path.</p>
</div>
<div class="paragraph">
<p>For testing, you can run a Git daemon on a single repository:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>touch .git/git-daemon-export-ok</strong>
$ <strong>git daemon --verbose /home/feh/testrepo</strong></pre>
</div>
</div>
<div class="paragraph">
<p>Then clone (preferably into a temporary directory) this very repository:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>git clone git://localhost/home/feh/testrepo</strong>
Initialized empty Git repository in /tmp/tmp.kXtkwxKgkc/testrepo/.git/
remote: Counting objects: 130, done.
remote: Compressing objects: 100% (102/102), done.
Receiving objects: 100% (130/130), 239.71 KiB, done.
Resolving deltas: 100% (54/54), done.
remote: Total 130 (delta 54), reused 0 (delta 0)</pre>
</div>
</div>
<div class="paragraph">
<p>However, the Git daemon will only export a repository if a <code>git-daemon-export-ok</code> file is created in the <code>.git</code> directory (as done above; in the case of <em>bare repositories</em>, of course, this must be done in the directory itself).
This is done for security reasons: For example, <code>/var/git/repositories</code> may contain many (even private) repositories, but only those that really need to be exported without access control will receive this file.</p>
</div>
<div class="paragraph">
<p>However, the daemon accepts the <code>--export-all</code> option, which removes this restriction and exports all repositories in all subdirectories.</p>
</div>
<div class="paragraph">
<p>Another important setting is the <em>Base Path</em>, which is the path where the actual Git repositories are located.
Start the Git daemon as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ <strong>git daemon --base-path=/var/git/repositories /var/git/repositories</strong></pre>
</div>
</div>
<div class="paragraph">
<p>every request for a git repository is preceded by the <em>base path</em>.
Now users can clone a repository with the address <code>git://<server>/<project>.git</code> instead of using the cumbersome <code>git://<server>/var/git/repositories/<project>.git</code>.</p>
</div>
<div class="sect3">
<h4 id="sec.git-daemon-inetd"><a class="anchor" href="Git-Book_8.html#sec.git-daemon-inetd"></a>7.3.1. Git-Daemon and Inetd</h4>
<div class="paragraph">
<p>As a rule, the Git daemon is supposed to constantly deliver a large number of repositories.
To do this, it runs constantly in the background or is restarted for each request.
The latter task is typically performed by <em>Inetd</em> from OpenBSD.
To make this work, you just need to add the following (one!) line to <code>/etc/inetd.conf</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>git stream tcp nowait <user> /usr/bin/git git daemon
--inetd --base-path=/var/git/repositories /var/git/repositories</pre>
</div>
</div>
<div class="paragraph">
<p><code><user></code> must be a user who has read access to the repositories.
This can be <code>root</code>, because the Inetd normally runs with root privileges, but should be <code>git</code> or a similarly unprivileged account.</p>
</div>
<div class="paragraph">
<p>The configuration for the <code>xinetd</code> is similar, but more self-explanatory.
It is stored e.g. under <code>/etc/xinet.d/git-daemon</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>service git
{
disable = no
type = UNLISTED
port = 9418
socket_type = stream
wait = no
user = <user>
server = /usr/bin/git
server_args = daemon --inetd --base-path=... ...
log_on_failure += USERID
}</pre>
</div>
</div>
<div class="paragraph">
<p>Do not forget to restart the respective daemon via <code>/etc/init.d/[x]inetd restart</code>.<sup class="footnote">[<a id="_footnoteref_101" class="footnote" href="#_footnotedef_101" title="View footnote.">101</a>]</sup></p>
</div>
</div>
<div class="sect3">
<h4 id="sec.git-daemon-sv"><a class="anchor" href="Git-Book_8.html#sec.git-daemon-sv"></a>7.3.2. The Debian Way: Git Daemon SV</h4>
<div class="paragraph">
<p>Debian offers the <code>git-daemon-run</code> package which contains configuration files for <code>sv</code>.<sup class="footnote">[<a id="_footnoteref_102" class="footnote" href="#_footnotedef_102" title="View footnote.">102</a>]</sup>
The package essentially creates a <code>gitlog</code> user and two executable shell scripts, <code>/etc/sv/git-daemon/run</code> and <code>/etc/sv/git-daemon/log/run</code>.
Modify the former to run the Git daemon in the directory where your repositories are located:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="shell"><span class="c">#!/bin/sh</span>
<span class="nb">exec </span>2>&1
<span class="nb">echo </span>_git-daemon starting._
<span class="nb">exec </span>git-daemon <span class="nt">--verbose</span> <span class="nt">--listen</span><span class="o">=</span>203.0.113.1 <span class="nt">--user</span><span class="o">=</span>git <span class="nt">--group</span><span class="o">=</span>git <span class="se">\</span>
<span class="nt">--reuseaddr</span> <span class="nt">--base-path</span><span class="o">=</span>/var/git/repositories /var/git/repositories</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you start the Git daemon from a shell script this way (or similarly via SysV-Init), the script will be executed with root privileges.
The following options are therefore useful:</p>
</div>
<div class="hdlist">
<table>
<tbody><tr>
<td class="hdlist1">
<code>--user=<user></code>
</td>
<td class="hdlist2">
<p>The user which the daemon runs as (e.g. <code>git</code>).
Must have read access to the repositories.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>--group=<group></code>
</td>
<td class="hdlist2">
<p>The group which the daemon runs as.
It makes sense to use the user group (<code>git</code>) or <code>nobody</code>.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<code>--reuseaddr</code>
</td>
<td class="hdlist2">
<p>Prevents the daemon restart from going wrong because there are still open connections waiting for a timeout.
This option uses the bind address even if there are still connections.
You should always specify this option if an instance is running continuously.</p>
</td>
</tr>
</tbody></table>
</div>
<div class="paragraph">
<p>If you are using SysV-Init, which means that services are usually started via symlinks in <code>/etc/rc2.d/</code> to scripts in <code>/etc/init.d/</code>, you will also need to create the following symlinks to automatically start the git daemon when the system boots</p>
</div>
<div class="listingblock">
<div class="content">
<pre># <strong>ln -s /usr/bin/sv /etc/init.d/git-daemon</strong>
# <strong>ln -s ../init.d/git-daemon /etc/rc2.d/S92git-daemon</strong>
# <strong>ln -s ../init.d/git-daemon /etc/rc0.d/K10git-daemon</strong>
# <strong>ln -s ../init.d/git-daemon /etc/rc6.d/K10git-daemon</strong></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="sec.git-daemon-production"><a class="anchor" href="Git-Book_8.html#sec.git-daemon-production"></a>7.3.3. The Git Daemon on Production Systems</h4>
<div class="paragraph">
<p>On a production system that is more than just a Git server, you may encounter the following situations:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>There are several network cards or virtual interfaces.</p>
</li>
<li>
<p>The service should run on a different port.</p>
</li>
<li>
<p>Different IPs should deliver different repositories.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The Git daemon provides options to respond to such situations.
They are summarized below.
For more detailed explanations, please consult the <code>git-daemon</code> man page.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>--max-connections=<n></code> </dt>
<dd>
<p>By default, the Git daemon only allows 32 simultaneous connections.
With this option you can increase the number.
A value of 0 allows any number of connections.<sup class="footnote">[<a id="_footnoteref_103" class="footnote" href="#_footnotedef_103" title="View footnote.">103</a>]</sup></p>
</dd>
<dt class="hdlist1"><code>--syslog</code> </dt>
<dd>
<p>Uses the syslog mechanism instead of standard error to log error messages.</p>
</dd>
<dt class="hdlist1"><code>--port=<n></code> </dt>
<dd>
<p>Uses a port other than 9418.</p>
</dd>
<dt class="hdlist1"><code>--listen=<host/ip></code> </dt>
<dd>
<p>Determines which interface the Git daemon should bind to.
By default the daemon is accessible on all interfaces, so it binds to <code>0.0.0.0</code>.
A setting of <code>127.0.0.1</code>, for example, only allows connections from the local machine.</p>
</dd>
<dt class="hdlist1"><code>--interpolated-path=<template></code> </dt>
<dd>
<p>If a Git daemon shall offer different repositories depending on the interface-address, this is controlled by the <code><template></code>: <code>%IP</code> is replaced by the IP address of the interface, where the connection comes in, and <code>%D</code> by the given path.
With a template of <code>/repos/%IP%D</code>, a <code>git clone git://localhost/testrepo</code> will display the following message in the log files: <code>interpolated dir '/repos/127.0.0.1/testrepo'</code> (because the connection is established via the loopback interface).
For each interface on which the Git daemon runs, there must be a subdirectory in <code>/repos/</code> with the interface’s corresponding IP address in which exportable repositories are located.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="sec.gitolite-export"><a class="anchor" href="Git-Book_8.html#sec.gitolite-export"></a>7.3.4. Specifying Exportable Repositories on Gitolite</h4>
<div class="paragraph">
<p>Gitolite knows a special username, <code>daemon</code>.
For all repositories where this user has read permission, the file <code>git-daemon-export-ok</code> is automatically created.
So you can use Gitolite to directly specify which repositories to export:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>repo Projekt
R = daemon</pre>
</div>
</div>
<div class="paragraph">
<p>Note that this setting has no effect if you start the Git daemon with the <code>--export-all</code> option.
Also, you cannot give this permission to all repositories via <code>repo @all</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sec.gitweb"><a class="anchor" href="Git-Book_8.html#sec.gitweb"></a>7.4. Gitweb: The Integrated Web Frontend</h3>
<div class="paragraph">