1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
\r
2 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
\r
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
\r
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
\r
6 <meta name="generator" content="AsciiDoc 7.1.2" />
\r
7 <style type="text/css">
\r
9 p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
\r
11 border: 1px solid red;
\r
16 margin: 1em 5% 1em 5%;
\r
21 text-decoration: underline;
\r
39 h1, h2, h3, h4, h5, h6 {
\r
41 font-family: sans-serif;
\r
43 margin-bottom: 0.5em;
\r
48 border-bottom: 2px solid silver;
\r
51 border-bottom: 2px solid silver;
\r
61 border: 1px solid silver;
\r
66 margin-bottom: 0.5em;
\r
76 font-family: sans-serif;
\r
83 font-family: sans-serif;
\r
87 font-family: sans-serif;
\r
89 border-top: 2px solid silver;
\r
95 padding-bottom: 0.5em;
\r
99 padding-bottom: 0.5em;
\r
103 div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
\r
104 div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
\r
105 div.admonitionblock {
\r
108 margin-bottom: 1.5em;
\r
110 div.admonitionblock {
\r
112 margin-bottom: 2.5em;
\r
115 div.content { /* Block element content. */
\r
119 /* Block element titles. */
\r
120 div.title, caption.title {
\r
121 font-family: sans-serif;
\r
125 margin-bottom: 0.5em;
\r
131 td div.title:first-child {
\r
134 div.content div.title:first-child {
\r
137 div.content + div.title {
\r
141 div.sidebarblock > div.content {
\r
142 background: #ffffee;
\r
143 border: 1px solid silver;
\r
147 div.listingblock > div.content {
\r
148 border: 1px solid silver;
\r
149 background: #f4f4f4;
\r
153 div.quoteblock > div.content {
\r
154 padding-left: 2.0em;
\r
160 div.verseblock + div.attribution {
\r
164 div.admonitionblock .icon {
\r
165 vertical-align: top;
\r
168 text-decoration: underline;
\r
170 padding-right: 0.5em;
\r
172 div.admonitionblock td.content {
\r
173 padding-left: 0.5em;
\r
174 border-left: 2px solid silver;
\r
177 div.exampleblock > div.content {
\r
178 border-left: 2px solid silver;
\r
182 div.verseblock div.content {
\r
186 div.imageblock div.content { padding-left: 0; }
\r
187 div.imageblock img { border: 1px solid silver; }
\r
188 span.image img { border-style: none; }
\r
192 margin-bottom: 0.8em;
\r
197 font-style: italic;
\r
199 dd > *:first-child {
\r
204 list-style-position: outside;
\r
207 list-style-type: lower-alpha;
\r
210 div.tableblock > table {
\r
211 border: 3px solid #527bbd;
\r
214 font-family: sans-serif;
\r
223 margin-bottom: 0.8em;
\r
226 vertical-align: top;
\r
227 font-style: italic;
\r
228 padding-right: 0.8em;
\r
231 vertical-align: top;
\r
235 div#footer-badges { display: none; }
\r
237 /* Workarounds for IE6's broken and incomplete CSS2. */
\r
239 div.sidebar-content {
\r
240 background: #ffffee;
\r
241 border: 1px solid silver;
\r
244 div.sidebar-title, div.image-title {
\r
245 font-family: sans-serif;
\r
248 margin-bottom: 0.5em;
\r
251 div.listingblock div.content {
\r
252 border: 1px solid silver;
\r
253 background: #f4f4f4;
\r
257 div.quoteblock-content {
\r
258 padding-left: 2.0em;
\r
261 div.exampleblock-content {
\r
262 border-left: 2px solid silver;
\r
263 padding-left: 0.5em;
\r
266 <title>Documentation of mercurial setup of grml</title>
\r
270 <h1>Documentation of mercurial setup of grml</h1>
\r
272 <h2>1. Preface</h2>
\r
273 <div class="sectionbody">
\r
274 <p><a href="http://www.selenic.com/mercurial/wiki/index.cgi">Mercurial</a> is a
\r
275 fast, lightweight and distributed Source Control Management system
\r
276 designed for efficient handling of very large distributed projects.</p>
\r
277 <p>For grml we use a mixture between a
\r
278 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/WorkingPractices">subversion-like</a>
\r
279 working practise and the
\r
280 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/KernelPractice">kernel-like</a>
\r
281 working practise.</p>
\r
282 <p>We use /data/repos on the vserver as the directory containing the
\r
283 mercurial repositories. The mercurial setup/server is running inside a
\r
284 dedicated vserver. /data is a xfs partition made available through LVM
\r
285 and mounted into the vserver so we can use ACL features which vserver's
\r
286 ufs does not provide.</p>
\r
287 <p>If you are interested in the "<a href="#server">Server setup</a>" of grml read on, if you are
\r
288 not interested in the server setup skip the following section and start
\r
289 at section "<a href="#user">Working with mercurial</a>".</p>
\r
291 <h2><a id="server"></a>2. Server setup</h2>
\r
292 <div class="sectionbody">
\r
293 <h3>2.1. Setup of hgweb</h3>
\r
294 <div class="literalblock">
\r
295 <div class="content">
\r
296 <pre><tt>% cp /usr/share/doc/mercurial/examples/hgwebdir.cgi /data/repos/</tt></pre>
\r
298 <div class="literalblock">
\r
299 <div class="content">
\r
300 <pre><tt>% cat > /data/repos/hgweb.config << EOF
\r
302 grml-etc-core/ = /data/repos/grml-etc-core/
\r
303 udev/ = /data/repos/udev/
\r
304 hg-doc/ = /data/repos/hg-doc/</tt></pre>
\r
306 <div class="literalblock">
\r
307 <div class="content">
\r
312 allowzip = yes</tt></pre>
\r
314 <div class="literalblock">
\r
315 <div class="content">
\r
316 <pre><tt>motd = (c) grml-team 2003++<br />
\r
317 Repositories maintained by <a href="http://grml.org/team/#mika">Michael Prokop</a>.<br />
\r
318 <a href="http://grml.org/mercurial/">Documentation about the setup is available online.</a>
\r
321 <h3>2.2. Apache2 setup for hgweb</h3>
\r
322 <div class="literalblock">
\r
323 <div class="content">
\r
324 <pre><tt># cat /etc/apache2/sites-available/default
\r
325 NameVirtualHost *:80</tt></pre>
\r
327 <div class="literalblock">
\r
328 <div class="content">
\r
329 <pre><tt><VirtualHost *:80>
\r
330 ServerAdmin repos@grml.org.invalid
\r
331 ServerName repos.grml.org</tt></pre>
\r
333 <div class="literalblock">
\r
334 <div class="content">
\r
335 <pre><tt>DocumentRoot /data/deb</tt></pre>
\r
337 <div class="literalblock">
\r
338 <div class="content">
\r
339 <pre><tt><Directory />
\r
340 Options FollowSymLinks
\r
342 </Directory></tt></pre>
\r
344 <div class="literalblock">
\r
345 <div class="content">
\r
346 <pre><tt><Directory "/data">
\r
348 Options Indexes FollowSymLinks MultiViews
\r
351 # RedirectMatch ^/$ /deb/
\r
352 </Directory></tt></pre>
\r
354 <div class="literalblock">
\r
355 <div class="content">
\r
356 <pre><tt><Directory "/data/repos">
\r
358 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
\r
359 AddHandler cgi-script .cgi
\r
362 </Directory></tt></pre>
\r
364 <div class="literalblock">
\r
365 <div class="content">
\r
366 <pre><tt>RedirectMatch ^/web/$ /hgwebdir.cgi
\r
367 ScriptAlias /hgwebdir.cgi /data/repos/hgwebdir.cgi</tt></pre>
\r
369 <div class="literalblock">
\r
370 <div class="content">
\r
371 <pre><tt>ErrorLog /var/log/apache2/error.log</tt></pre>
\r
373 <div class="literalblock">
\r
374 <div class="content">
\r
375 <pre><tt>LogLevel warn</tt></pre>
\r
377 <div class="literalblock">
\r
378 <div class="content">
\r
379 <pre><tt> CustomLog /var/log/apache2/access.log combined
\r
381 </VirtualHost></tt></pre>
\r
383 <div class="literalblock">
\r
384 <div class="content">
\r
385 <pre><tt><VirtualHost *:80>
\r
386 ServerName hg.grml.org
\r
387 ServerAdmin repos@grml.org.invalid</tt></pre>
\r
389 <div class="literalblock">
\r
390 <div class="content">
\r
391 <pre><tt><Directory "/">
\r
393 AddHandler cgi-script .cgi
\r
394 </Directory></tt></pre>
\r
396 <div class="literalblock">
\r
397 <div class="content">
\r
398 <pre><tt>RewriteEngine on
\r
399 RewriteRule (.*) /data/repos/hgwebdir.cgi$1</tt></pre>
\r
401 <div class="literalblock">
\r
402 <div class="content">
\r
403 <pre><tt>LogLevel warn</tt></pre>
\r
405 <div class="literalblock">
\r
406 <div class="content">
\r
407 <pre><tt> ErrorLog /var/log/apache2/error.log
\r
408 CustomLog /var/log/apache2/access.log combined
\r
410 </VirtualHost></tt></pre>
\r
412 <p>Now repositories can be accessed via
\r
413 <a href="http://hg.grml.org/">http://hg.grml.org/</a> - for example
\r
414 <a href="http://hg.grml.org/hg-doc">http://hg.grml.org/hg-doc</a>
\r
415 to access the repository named hg-doc.</p>
\r
416 <h3>2.3. Activate FastCGI with Apache2 setup for hgwebdir</h3>
\r
417 <p>If you have hg.grml.org allready running it's a one minute job:</p>
\r
421 Install libapache2-mod-fastcgi and python-flup
\r
426 Copy hgwebdir.cgi to hgwebdir.fcgi
\r
431 Change the line in hgwebdir.fcgi from
\r
433 <div class="literalblock">
\r
434 <div class="content">
\r
435 <pre><tt>wsgicgi.launch(wsgiapplication(make_web_app))</tt></pre>
\r
437 <div class="literalblock">
\r
438 <div class="content">
\r
439 <pre><tt>to</tt></pre>
\r
441 <div class="literalblock">
\r
442 <div class="content">
\r
443 <pre><tt>from flup.server.fcgi import WSGIServer
\r
444 WSGIServer(wsgiapplication(make_web_app)).run()</tt></pre>
\r
449 This 2 lines uses the threaded fcgi version. You could also use the
\r
450 fork fcgi version with
\r
452 <div class="literalblock">
\r
453 <div class="content">
\r
454 <pre><tt>flup.server.fcgi_fork import WSGIServer</tt></pre>
\r
459 To make hg.grml.org using the fcgi version you should change your apache
\r
460 config form something like this
\r
462 <div class="literalblock">
\r
463 <div class="content">
\r
464 <pre><tt>RewriteRule (.*) /data/repos/hgwebdir.cgi$1</tt></pre>
\r
466 <div class="literalblock">
\r
467 <div class="content">
\r
468 <pre><tt>to</tt></pre>
\r
470 <div class="literalblock">
\r
471 <div class="content">
\r
472 <pre><tt>RewriteRule (.*) /data/repos/hgwebdir.fcgi$1</tt></pre>
\r
481 <h3>2.4. User setup</h3>
\r
482 <h4>2.4.1. Accounts for core developers</h4>
\r
483 <p>grml core developers have a ssh account without any restrictions.</p>
\r
484 <h4>2.4.2. Accounts for contributors</h4>
\r
485 <p>Contributors are allowed to work on some selected packages (having write
\r
486 access therefore of course) but not on all repositories.</p>
\r
487 <div class="literalblock">
\r
488 <div class="content">
\r
489 <pre><tt># grep $USER /etc/passwd
\r
490 $USER:*:1002:1002:$DEMOUSER,,,:/home/$USER:/bin/zsh
\r
492 Important: disable password so user can run hg-ssh but does not get a shell!</tt></pre>
\r
494 <p>hg-ssh is a wrapper for ssh access to a limited set of mercurial repos, to
\r
495 be used in ~/.ssh/authorized_keys and can be found at
\r
496 /usr/share/doc/mercurial/examples/hg-ssh (so install hg-ssh in $PATH):</p>
\r
497 <div class="literalblock">
\r
498 <div class="content">
\r
499 <pre><tt># cat /home/$USER/.ssh/authorized_keys
\r
500 command="cd /data/repos/ && hg-ssh hg-doc",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa [key...]</tt></pre>
\r
502 <h4><a id="acl"></a>2.4.3. Permission handling</h4>
\r
503 <p>Set up a dummy user, we don't really use UNIX permissions but POSIX ACLs
\r
505 <div class="literalblock">
\r
506 <div class="content">
\r
507 <pre><tt># cd /data/repos
\r
508 # adduser dummy --system
\r
509 # addgroup dummy --system
\r
510 # addgroup dummy dummy
\r
511 # chown -R dummy:dummy .</tt></pre>
\r
513 <p>Make sure people from group repos have access anytime:</p>
\r
514 <div class="literalblock">
\r
515 <div class="content">
\r
516 <pre><tt># cat /data/repos/default_acl_schema
\r
528 default:user:www-data:r-x
\r
530 default:group:www-data:r-x
\r
531 default:group:repos:rwx
\r
534 # setfacl -R --set-file /data/repos/default_acl_schema /data/repos</tt></pre>
\r
536 <p>Team setup - user(s) of group repos-udev should have access to their
\r
538 <div class="literalblock">
\r
539 <div class="content">
\r
540 <pre><tt># addgroup repos-udev
\r
541 # addgroup tklauser repos-udev
\r
542 # setfacl -R -m d:g:repos-udev:rwx,g:repos-udev:rwx udev</tt></pre>
\r
544 <p>Example for setting up a private repository where other users should not
\r
545 have access to:</p>
\r
546 <div class="literalblock">
\r
547 <div class="content">
\r
548 <pre><tt># cd /data/repos
\r
550 # chmod 750 private
\r
551 # chown -R mika.mika private
\r
552 # setfacl -R --remove-all private</tt></pre>
\r
554 <div class="sidebarblock">
\r
555 <div class="sidebar-content">
\r
556 <p>Important: to avoid conflicts with permissions do not work on the server
\r
557 via ssh in the repositories in /data/repos/ themselve but clone them to
\r
558 your $HOME directory instead or download them to your own box! (This seems
\r
559 to be a bug in the permission handling of mercurial. We are investigating
\r
560 on this issue…)</p>
\r
563 <h2><a id="user"></a>3. Working with mercurial</h2>
\r
564 <div class="sectionbody">
\r
565 <div class="admonitionblock">
\r
568 <div class="title">Tip</div>
\r
570 <td class="content">Keep your changesets small, sync and push often!</td>
\r
573 <p>First of all read
\r
574 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart">the quick start howto</a>.</p>
\r
575 <h3>3.1. Mercurial and Debian packages</h3>
\r
576 <h4>3.1.1. Working with your own packages</h4>
\r
577 <p>In this case the <a href="http://hg.grml.org/">mercurial repository on grml.org</a>
\r
578 itself is interesting for you. You push all your changes immediatly to the
\r
580 <h4>3.1.2. For changes in other packages</h4>
\r
581 <p>You create a local repository (hg clone …), make your changes and
\r
582 inform the (grml) maintainer who is responsible for this package about
\r
583 your changes. Preferred is the mercurial nativ way to communicate
\r
584 changesets (push/pull/clone). Look at the different ways to communicate
\r
585 changes (see "<a href="#patch">How to create a patch</a>" for more details).</p>
\r
586 <h4>3.1.3. Building the debian package</h4>
\r
587 <p>We assume you know
\r
588 <em><a href="http://packages.debian.org/unstable/utils/dpkg-dev">dpkg-buildpackage</a>
\r
589 -rfakeroot</em> already.</p>
\r
590 <p>If you use mercurial you have a single directory named .hg in the root
\r
591 directory of your repository (unlike svn, which has .svn directories in
\r
592 every single directory of your repository). To avoid shipping the .hg
\r
593 directory we wrote hg-buildpackage. hg-buildpackage is a simple wrapper
\r
594 around dpkg-buildpackage. To use it make sure you have grml-mercurial-utils
\r
595 installed (it's available from <a href="http://deb.grml.org/">grml-repos</a>, if
\r
596 you are using grml you have it on your box already but please make sure you
\r
597 are using a recent version).</p>
\r
598 <h4>3.1.4. Working with non-native Debian package</h4>
\r
599 <p>Variante 1) only directory debian/ is under revision control</p>
\r
600 <div class="literalblock">
\r
601 <div class="content">
\r
602 <pre><tt>% mv package package-old
\r
603 % unp newupstream-package.tar.gz
\r
604 % cp -a package-old/.hg package/
\r
605 % cp -a package-old/debian package/
\r
607 <adjust debian packaging..>
\r
608 % hg ci -m "notice about changes"
\r
610 % hg-buildpackage -rfakeroot ...</tt></pre>
\r
612 <p>Variante 2) directory debian/ <strong>including</strong> upstream sources are under revision control:</p>
\r
613 <div class="literalblock">
\r
614 <div class="content">
\r
615 <pre><tt>% mv package package-old
\r
616 % unp newupstream-package.tar.gz
\r
617 % cp -a package-old/.hg package/
\r
618 % cp -a package-old/debian package/
\r
621 % hg ci -m 'new upstream version'
\r
622 % hg tag <upstream version'
\r
623 <adjust debian packaging..>
\r
624 % hg ci -m "notice about changes"
\r
625 % hg tag <debian version>
\r
627 % hg-buildpackage -rfakeroot ...</tt></pre>
\r
629 <p>Variante 3) upstream tracking repository + versioned mercurial patch queue</p>
\r
630 <div class="literalblock">
\r
631 <div class="content">
\r
632 <pre><tt>% mv package package-old
\r
633 % unp newupstream-package.tar.gz
\r
634 % cp -a package-old/.hg package/
\r
637 % hg ci -m 'new upstream version'
\r
638 % hg tag <upstream version>
\r
640 % hg qpush debian.patch
\r
641 <adjust debian packaging..>
\r
642 % hg qci -m 'new upstream version'
\r
643 % hg-buildpackage -mqd -rfakeroot
\r
645 % hg tag <debian version>
\r
646 % hg push</tt></pre>
\r
648 <h4>3.1.5. Get notifications when pushing</h4>
\r
649 <p>If you want to be notified as soon as changesets are pushed to the
\r
650 repository activate the incoming hook in .hg/hgrc of the repository:</p>
\r
651 <div class="literalblock">
\r
652 <div class="content">
\r
654 incoming.notify = commithook</tt></pre>
\r
656 <p>whereas commithook is a script inside $PATH:</p>
\r
657 <div class="literalblock">
\r
658 <div class="content">
\r
659 <pre><tt>% cat /usr/bin/commithook
\r
661 if ! [ -x /usr/bin/mail ] ; then
\r
665 <div class="literalblock">
\r
666 <div class="content">
\r
667 <pre><tt>SUBJECT=`hg log -r $HG_NODE | grep "^summary:" | cut -b 14-`
\r
668 SUBJECT="$SUBJECT - http://hg.grml.org/$(basename `hg root`)/rev/$HG_NODE"
\r
669 RECIPIENT="$(hg debugconfig | grep web.author | sed 's/web.author=//'), repos@grml.org.invalid"</tt></pre>
\r
671 <div class="literalblock">
\r
672 <div class="content">
\r
673 <pre><tt>if [ -n "$RECIPIENT" ] ; then
\r
674 hg log -vr $HG_NODE | mail -s "commit: $SUBJECT" "$RECIPIENT"
\r
677 <div class="admonitionblock">
\r
680 <div class="title">Tip</div>
\r
682 <td class="content">Also take a look at
\r
683 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/CommitHook">CommitHook
\r
684 in mercurial-wiki</a>.</td>
\r
687 <h4>3.1.6. Get notification when commiting</h4>
\r
688 <p>If you want to be notified as soon as a commit happens use the commit hook
\r
689 via .hg/hgrc of the repository:</p>
\r
690 <div class="literalblock">
\r
691 <div class="content">
\r
693 commit = commithook</tt></pre>
\r
695 <p>whereas commithook is a script inside $PATH:</p>
\r
696 <div class="literalblock">
\r
697 <div class="content">
\r
699 SUBJECT=`hg log -r $HG_NODE | grep "^summary:" | cut -b 14-`
\r
700 hg log -vpr $HG_NODE | mail -s "commit: $SUBJECT" commit-list@grml.org.invalid</tt></pre>
\r
702 <div class="admonitionblock">
\r
705 <div class="title">Tip</div>
\r
707 <td class="content">Also take a look at
\r
708 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/CommitHook">CommitHook
\r
709 in mercurial-wiki</a>.</td>
\r
712 <h3>3.2. Configuration of mercurial</h3>
\r
713 <p>Configure the global setup of mercurial via /etc/mercurial/hgrc, see
\r
714 <a href="http://www.selenic.com/mercurial/hgrc.5.html">man 5 hgrc</a> for details.</p>
\r
715 <p>Important: please adjust the default name for commits (could be any config
\r
716 file: ~/.hgrc or repository .hg/hgrc):</p>
\r
717 <div class="literalblock">
\r
718 <div class="content">
\r
720 username = Michael Prokop <mika@grml.org></tt></pre>
\r
722 <p>Put all your personal configuration stuff into the file $HOME/.hgrc.
\r
723 Example configuration file from grml:</p>
\r
724 <div class="literalblock">
\r
725 <div class="content">
\r
726 <pre><tt># Filename: $HOME/.hgrc
\r
727 # Purpose: configuration file for mercurial
\r
728 # Authors: grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
\r
729 # Bug-Reports: see http://grml.org/bugs/
\r
730 # License: This file is licensed under the GPL v2.
\r
731 # Latest change: Mon Okt 23 00:06:34 CEST 2006 [mika]
\r
732 ################################################################################</tt></pre>
\r
734 <div class="literalblock">
\r
735 <div class="content">
\r
736 <pre><tt># See 'man 5 hgrc' and http://www.selenic.com/mercurial/hgrc.5.html
\r
737 # for more details about possibilities for configuration of mercurial.</tt></pre>
\r
739 <div class="literalblock">
\r
740 <div class="content">
\r
742 username = Michael Prokop <mika@grml.org>
\r
745 # merge = hgmergevim</tt></pre>
\r
747 <div class="literalblock">
\r
748 <div class="content">
\r
749 <pre><tt># useful for patchbomb extension (e.g.: 'hg email -t grml@localhost tip')
\r
751 from = grml User <grml@localhost>
\r
752 method = /usr/sbin/sendmail</tt></pre>
\r
754 <div class="literalblock">
\r
755 <div class="content">
\r
756 <pre><tt># Extension stuff, see /etc/mercurial/hgrc.d/hgext.rc
\r
757 # and http://www.selenic.com/mercurial/wiki/index.cgi/ExtensionHowto</tt></pre>
\r
759 <div class="literalblock">
\r
760 <div class="content">
\r
761 <pre><tt>[extensions]</tt></pre>
\r
763 <div class="literalblock">
\r
764 <div class="content">
\r
765 <pre><tt># Hooks to control commit access to parts of a tree.
\r
766 # acl=/usr/share/python-support/mercurial/hgext/acl.py</tt></pre>
\r
768 <div class="literalblock">
\r
769 <div class="content">
\r
770 <pre><tt># Update Bugzilla bugs when changesets mention them (> 0.9-1).
\r
771 # bugzilla = /home/grml/mercurial-snapshot/hgext/bugzilla.py</tt></pre>
\r
773 <div class="literalblock">
\r
774 <div class="content">
\r
775 <pre><tt># Graph amount of code changed per author over time (> 0.9-1).
\r
776 # churn = /home/grml/mercurial-snapshot/contrib/churn.py
\r
777 # churn =</tt></pre>
\r
779 <div class="literalblock">
\r
780 <div class="content">
\r
781 <pre><tt># Extension for using an external program to diff repository (or
\r
782 # selected files). Available in 0.9.1.
\r
783 # extdiff=/usr/share/python-support/mercurial/hgext/extdiff.py
\r
784 hgext.extdiff=</tt></pre>
\r
786 <div class="literalblock">
\r
787 <div class="content">
\r
788 <pre><tt># Convenience wrapper for pulling and merging.
\r
789 # fetch =</tt></pre>
\r
791 <div class="literalblock">
\r
792 <div class="content">
\r
793 <pre><tt># Extension that provides commands to help working with trees
\r
794 # composed of many Mercurial repositories. See
\r
795 # http://www.terminus.org/hg/hgforest
\r
796 # forest =</tt></pre>
\r
798 <div class="literalblock">
\r
799 <div class="content">
\r
800 <pre><tt># Extension for signing and checking signatures.
\r
801 # gpg=/usr/share/python-support/mercurial/hgext/gpg.py
\r
804 <div class="literalblock">
\r
805 <div class="content">
\r
806 <pre><tt># Extension for binary searching in O(log2(n)) for the changeset
\r
807 # introducing a (mis)feature, see
\r
808 # http://www.selenic.com/mercurial/wiki/index.cgi/UsingBisect
\r
809 # hbisect=/usr/share/python-support/mercurial/hgext/hbisect.py</tt></pre>
\r
811 <div class="literalblock">
\r
812 <div class="content">
\r
813 <pre><tt># Graphical gitk-like repository browser, invoked with hg view.
\r
814 # hgk=/usr/share/python-support/mercurial/hgext/hgk.py</tt></pre>
\r
816 <div class="literalblock">
\r
817 <div class="content">
\r
818 <pre><tt># Mercurial Queue management extension - see
\r
819 # http://www.selenic.com/mercurial/wiki/index.cgi/MqExtension
\r
820 # mq=/usr/share/python-support/mercurial/hgext/mq.py</tt></pre>
\r
822 <div class="literalblock">
\r
823 <div class="content">
\r
824 <pre><tt># Template-driven email notifications, see
\r
825 # http://www.selenic.com/mercurial/wiki/index.cgi/NotifyExtension
\r
826 # notify=/usr/share/python-support/mercurial/hgext/notify.py
\r
827 # hgext.notify =</tt></pre>
\r
829 <div class="literalblock">
\r
830 <div class="content">
\r
831 <pre><tt># Extension providing the hg email command for sending a collection of
\r
832 # Mercurial changesets as a series of patch emails.
\r
833 # patchbomb=/usr/share/python-support/mercurial/hgext/patchbomb.py</tt></pre>
\r
835 <div class="literalblock">
\r
836 <div class="content">
\r
837 <pre><tt># Cherry-picking, rebasing and changeset rewriting - see
\r
838 # http://www.selenic.com/mercurial/wiki/index.cgi/TransplantExtension
\r
839 # transplant =</tt></pre>
\r
841 <div class="literalblock">
\r
842 <div class="content">
\r
843 <pre><tt># Extension for line ending conversion filters for the Windows platform.
\r
844 # win32text=/usr/share/python-support/mercurial/hgext/win32text.py</tt></pre>
\r
846 <div class="literalblock">
\r
847 <div class="content">
\r
849 # DirDiff script for Vim: http://www.vim.org/scripts/script.php?script_id=102
\r
850 # wget http://www.vim.org/scripts/download_script.php?src_id=5306 -O ~/.vim/plugin/DirDiff.vim
\r
851 # Notice: opts.* works only in Mercurial >0.9.1, use hgvimdiff as wrapper therefore
\r
852 cmd.vimdiff=/usr/bin/hgvimdiff
\r
853 # cmd.vimdiff=/usr/bin/vim.basic
\r
854 # opts.vimdiff=-f '+next' '+execute "DirDiff" argv(0) argv(1)'</tt></pre>
\r
856 <div class="literalblock">
\r
857 <div class="content">
\r
858 <pre><tt># vim: ft=config</tt></pre>
\r
860 <h3>3.3. Set up a new repository</h3>
\r
861 <div class="literalblock">
\r
862 <div class="content">
\r
863 <pre><tt>% cd /data/repos/hg-doc
\r
865 % cat > .hg/hgrc << EOF
\r
867 default = ssh://mika@repos.grml.org//data/repos/hg-doc</tt></pre>
\r
869 <div class="literalblock">
\r
870 <div class="content">
\r
872 from = repos@grml.org.invalid</tt></pre>
\r
874 <div class="literalblock">
\r
875 <div class="content">
\r
878 description = documentation of hg
\r
879 author = Michael Prokop
\r
882 <div class="literalblock">
\r
883 <div class="content">
\r
885 % hg ci -m "* initial checkin"</tt></pre>
\r
887 <h3>3.4. Checkout of a repository</h3>
\r
888 <p>For developers with account:</p>
\r
889 <div class="literalblock">
\r
890 <div class="content">
\r
891 <pre><tt>% hg clone ssh://repos.grml.org//data/repos/hg-doc</tt></pre>
\r
893 <p>Anonymous (without account, password,…):</p>
\r
894 <div class="literalblock">
\r
895 <div class="content">
\r
896 <pre><tt>% hg clone http://hg.grml.org/hg-doc</tt></pre>
\r
898 <h3><a id="patch"></a>3.5. How to create a patch</h3>
\r
899 <p>If you do not have the repository yet download it via:</p>
\r
900 <div class="literalblock">
\r
901 <div class="content">
\r
902 <pre><tt>% hg clone http://hg.grml.org/$PACKAGENAME</tt></pre>
\r
904 <p>If you already have the repository please make sure you are using the
\r
905 current version:</p>
\r
906 <div class="literalblock">
\r
907 <div class="content">
\r
909 % hg update</tt></pre>
\r
911 <p>Now apply your changes (with the editor of you choice).
\r
912 Then commit your changes local via running:</p>
\r
913 <div class="literalblock">
\r
914 <div class="content">
\r
915 <pre><tt>% hg commit -m "short information regarding your changes"</tt></pre>
\r
917 <p>Finally export the patch:</p>
\r
918 <div class="literalblock">
\r
919 <div class="content">
\r
920 <pre><tt>% hg export tip > hg-doc_newfeature.patch</tt></pre>
\r
922 <p>and send the hg-doc_newfeature.patch via mail to the maintainer of
\r
923 $PACKAGENAME and make sure you send a copy (CC:) to <repos@grml.org.invalid>.</p>
\r
924 <p>Notice: using the patchbomb extension you can send the patch via mail even faster:</p>
\r
925 <div class="literalblock">
\r
926 <div class="content">
\r
927 <pre><tt>% hg email -t repos@grml.org.invalid tip</tt></pre>
\r
929 <h3><a id="mq"></a>3.6. Working with mq</h3>
\r
930 <p>Example session:</p>
\r
931 <div class="literalblock">
\r
932 <div class="content">
\r
933 <pre><tt>% hg qinit -c
\r
934 % hq qimport /raid/Grml/kernel/patches.2.6.18/[1-5]*
\r
936 % hg qcommit -m "initial version for 2.6.18-grml"
\r
937 % hg qpop 4310_reiser4-for-2.6.18.patch
\r
938 % hg qdel 4310_reiser4-for-2.6.18.patch
\r
940 % hg qcommit -m "removed 4310_reiser4-for-2.6.18.patch"
\r
941 % hg qcommit -m "qrefresh for 5002_linux-2.6.17-commandline.patch"
\r
942 % hg qpop 5002_linux-2.6.17-commandline.patch
\r
944 % hg rename 5002_linux-2.6.17-commandline.patch 5002_linux-2.6.18-commandline.patch
\r
946 % hg qdel 5002_linux-2.6.17-commandline.patch
\r
947 % echo 5002_linux-2.6.18-commandline.patch >> .hg/patches/series
\r
948 % hg qpush 5002_linux-2.6.18-commandline.patch
\r
950 % hg qcommit -m "renamed 5002_linux-2.6.17-commandline.patch into 5002_linux-2.6.18-commandline.patch"
\r
951 % hg qapp</tt></pre>
\r
953 <p>Create an all-in-one patch:</p>
\r
954 <div class="literalblock">
\r
955 <div class="content">
\r
956 <pre><tt>% hg -v qapp
\r
957 35b24375c791bd4a6ab3f6266ed4c86e7db1c116:1000_2.6.18.1.patch
\r
958 dbfdc94b23e11a79557e2380113783ab40e2ea58:2500_via-irq-quirk-revert.patch
\r
959 a73fe2a1ba6744119d7c46689fbd647d29284068:4005_sky2-v1.9.patch
\r
960 55ebc8d22f4bc98c5030f0630b3009fcbd4daaeb:4010_r8169-8168.patch
\r
961 d1dfcd3b8952db725b5ac920e1ef0741ba0a9873:4105_dm-bbr.patch
\r
962 771f8dfaca97ac92349e7949a438e5221a435afd:4110_promise-pdc2037x.patch
\r
963 152b0976f9d18424139612df4f996b6b34ab89ac:4150_iteraid.patch
\r
964 e0646b22c4e6accbf11e7e69f43826b101b73f0f:4300_squashfs-3.1.patch
\r
965 16d9f8a538ccbdbff23353cf88bf24a6e3329b85:4400_speakup-20060814.patch
\r
966 d7c39ee5a2b1b4367f5d9b2b88f1de2260202be9:5000_grml-version.patch
\r
967 a900842d6ffee405cad60f94c6b5e291f513e452:5001_grml_logo.patch
\r
968 6d96a8f6a4e73e9a0a1b41cc53c6708801ab882d:5002_linux-2.6.18-commandline.patch
\r
969 % hg -v qapp | head -1
\r
970 35b24375c791bd4a6ab3f6266ed4c86e7db1c116:1000_2.6.18.1.patch
\r
971 % hg diff -r 35b24375c791bd4a6ab3f6266ed4c86e7db1c116 > all-in-one
\r
972 hg diff -r 35b24375c791bd4a6ab3f6266ed4c86e7db1c116 > all-in-one 5,31s user 0,30s system 99% cpu 5,638 total</tt></pre>
\r
975 <h2>4. Tips and tricks for working</h2>
\r
976 <div class="sectionbody">
\r
977 <h3>4.1. Merging</h3>
\r
978 <p>If you want to use vimdiff for merging make sure you have
\r
979 grml-mercurial-utils installed (it's available from
\r
980 <a href="http://deb.grml.org/">grml-repos</a>, if you are using grml you have it
\r
981 on your box already) and put the following line into your ~/.hgrc:</p>
\r
982 <div class="literalblock">
\r
983 <div class="content">
\r
985 merge = hgmergevim</tt></pre>
\r
987 <p>You can also define your own command for merging. Very useful is
\r
988 <a href="http://www.vim.org/scripts/script.php?script_id=102">the DirDiff script
\r
989 for Vim</a>. Add the following lines to your ~/.hgrc:</p>
\r
990 <div class="literalblock">
\r
991 <div class="content">
\r
993 # wget http://www.vim.org/scripts/download_script.php?src_id=5306 -O ~/.vim/plugin/DirDiff.vim
\r
994 # Notice: opts.* works only in Mercurial >0.9.1, use hgvimdiff as wrapper therefore
\r
995 cmd.vimdiff=/usr/bin/hgvimdiff
\r
996 # cmd.vimdiff=/usr/bin/vim.basic
\r
997 # opts.vimdiff=-f '+next' '+execute "DirDiff" argv(0) argv(1)'</tt></pre>
\r
999 <p>Now you can run for example <em>hg vimdiff -r2 -r4</em> for running Vim in DirDiff
\r
1000 mode for displaying the changes between revision 2 and 4.</p>
\r
1001 <h3>4.2. Repository stuff</h3>
\r
1002 <p>If you do not want to type the target everytime you push to the central
\r
1003 adjust the repository config (.hg/hgrc):</p>
\r
1004 <div class="literalblock">
\r
1005 <div class="content">
\r
1007 default-push = ssh://repos.grml.org//data/repos/package</tt></pre>
\r
1009 <p>If you dont want to write the source everytime you make a pull adjust
\r
1010 the repository config (.hg/hgrc):</p>
\r
1011 <div class="literalblock">
\r
1012 <div class="content">
\r
1014 default = /home/grml/work/projects/package</tt></pre>
\r
1016 <p>If you want to be able to use <em>hg clone ssh://repos.grml.org/hg/hg-doc</em>
\r
1017 for cloning the repository instead of <em>ssh://repos.grml.org//data/repos/hg-doc</em>
\r
1018 just create a symlink on your box:</p>
\r
1019 <div class="literalblock">
\r
1020 <div class="content">
\r
1021 <pre><tt>% ln -s /data/repos ~/hg</tt></pre>
\r
1023 <h3>4.3. Recursive mercurial commands</h3>
\r
1024 <p>If you have multiple repositories inside a single directory you should be
\r
1025 aware of hgr for running mercurial commands recursive.</p>
\r
1026 <p>For example run:</p>
\r
1027 <div class="literalblock">
\r
1028 <div class="content">
\r
1029 <pre><tt>% cd ~/grml/hg && hgr status</tt></pre>
\r
1031 <p>to get the status of all the repositories inside ~/grml/hg.</p>
\r
1033 <div class="literalblock">
\r
1034 <div class="content">
\r
1035 <pre><tt>% cd ~/grml/hg && hgr in</tt></pre>
\r
1037 <p>to show all new changesets found in source directories of all the
\r
1039 <div class="sidebarblock">
\r
1040 <div class="sidebar-content">
\r
1041 <p>Notice: hgr is part of the Debian package grml-mercurial-utils. Mare sure
\r
1042 you have it installed (it's available from
\r
1043 <a href="http://deb.grml.org/">grml-repos</a>, if you are using grml you have it
\r
1044 on your box already but please make sure you are using a recent version).</p>
\r
1046 <h3>4.4. Set up zsh completion for mercurial</h3>
\r
1047 <p>grml 0.9 will provide zsh completion for mercurial out-of-the-box. Read on to know
\r
1048 what has been done to provide this feature.</p>
\r
1049 <p>Create a directory /etc/zsh/site-functions, adjust $FPATH via
\r
1050 /etc/zsh/zshrc and copy file to appropriate location:</p>
\r
1051 <div class="literalblock">
\r
1052 <div class="content">
\r
1053 <pre><tt># mkdir /etc/zsh/site-functions
\r
1054 # [ -d /etc/zsh/site-functions ] && export FPATH=/etc/zsh/site-functions:$FPATH
\r
1055 # zcat /usr/share/doc/mercurial/examples/zsh_completion.gz > /etc/zsh/site-functions/_hg</tt></pre>
\r
1057 <h3>4.5. Install current mercurial snapshot in $HOME</h3>
\r
1058 <p>Make sure you have python2.4-dev, gcc and libc6-dev on your system, then run:</p>
\r
1059 <div class="literalblock">
\r
1060 <div class="content">
\r
1061 <pre><tt>% wget http://www.selenic.com/mercurial/mercurial-snapshot.tar.gz
\r
1062 % unp mercurial-snapshot.tar.gz
\r
1063 % cd mercurial-snapshot
\r
1064 % make install-home-bin</tt></pre>
\r
1066 <p>and finally make sure you have the following PATH set:</p>
\r
1067 <div class="literalblock">
\r
1068 <div class="content">
\r
1069 <pre><tt>% export PYTHONPATH=${HOME}/lib/python
\r
1070 % export PATH=${HOME}/bin:$PATH</tt></pre>
\r
1072 <div class="admonitionblock">
\r
1075 <div class="title">Tip</div>
\r
1077 <td class="content">Take a look at the zsh functions gethgclone (get latest hg version via
\r
1078 hg itself) and gethgsnap (get latest mercurial-snapshot.tar.gz) in
\r
1079 /etc/skel/.zshrc (becoming $HOME/.zshrc) on grml.</td>
\r
1082 <h3>4.6. Install current mercurial version</h3>
\r
1083 <p>Upgrading mercurial might be interesting for you if you are runing hgweb so
\r
1084 you can use some brand new features. It is very simple and easy to keep it up2date.</p>
\r
1085 <p>Make sure you have python2.4-dev, gcc and libc6-dev on your system, then run:</p>
\r
1086 <div class="literalblock">
\r
1087 <div class="content">
\r
1088 <pre><tt>% cd /data
\r
1089 % hg clone http://selenic.com/repo/hg mercurial
\r
1091 % make local</tt></pre>
\r
1093 <p>Then insert/adjust <em>sys.path.insert(0, "/data/mercurial")</em> in hgwebdir.cgi.
\r
1095 <h3>4.7. Import patches from mails</h3>
\r
1096 <p>Just run <em>hg import -</em>. If you are using mutt[-ng] the following snippet
\r
1097 might be interesting for your ~/.mutt[ng]rc:</p>
\r
1098 <div class="literalblock">
\r
1099 <div class="content">
\r
1100 <pre><tt>macro pager ,i "|hg import --cwd hg/repos/hg-doc -" "hg import hg/repos/hg-doc"</tt></pre>
\r
1102 <h3>4.8. Static URLs for files via hgweb</h3>
\r
1103 <p>Using mercurial version >0.9.1 provides very handy, static URLs. Examples:</p>
\r
1107 <a href="http://hg.grml.org/grml-autoconfig/file/tip/autoconfig">http://hg.grml.org/grml-autoconfig/file/tip/autoconfig</a>
\r
1112 <a href="http://hg.grml.org/grml-autoconfig/raw-file/tip/autoconfig">http://hg.grml.org/grml-autoconfig/raw-file/tip/autoconfig</a>
\r
1117 <a href="http://hg.grml.org/grml-autoconfig/rss-log/tip/autoconfig">http://hg.grml.org/grml-autoconfig/rss-log/tip/autoconfig</a>
\r
1121 <h3>4.9. Serve your own repositories for LAN access</h3>
\r
1122 <p>You want to share you local repositories temporary so other people (for
\r
1123 example in your LAN) can access it as well?</p>
\r
1124 <div class="literalblock">
\r
1125 <div class="content">
\r
1126 <pre><tt>% hg serve</tt></pre>
\r
1128 <p>That's it. You can even serve your repositories via hgweb, just run:</p>
\r
1129 <div class="literalblock">
\r
1130 <div class="content">
\r
1131 <pre><tt>% cat > hgwebconfig << EOF
\r
1133 demorepos = /tmp/demorepos</tt></pre>
\r
1135 <div class="literalblock">
\r
1136 <div class="content">
\r
1139 % hg serve -d --webdir-conf hgwebconfig</tt></pre>
\r
1141 <h3>4.10. Speed up ssh access to repository</h3>
\r
1142 <p>Since OpenSSH 4.0 a feature called ControlMaster is available.
\r
1143 Activate ControlMaster through your ssh config:</p>
\r
1144 <div class="literalblock">
\r
1145 <div class="content">
\r
1146 <pre><tt>% cat >> ~/.ssh/config << EOF
\r
1148 ControlMaster auto
\r
1149 ControlPath ~/.ssh/master-%r@%h:%p
\r
1152 <p>Make sure you have an open connection to the server, then commands like <em>hg
\r
1153 push</em> will happen much faster.</p>
\r
1154 <h3>4.11. Avoid typing of ssh key passphrase</h3>
\r
1155 <p>You can either use ssh-agent:</p>
\r
1156 <div class="literalblock">
\r
1157 <div class="content">
\r
1158 <pre><tt>% eval $(ssh-agent) && ssh-add</tt></pre>
\r
1160 <p>or use keychain instead:</p>
\r
1161 <div class="literalblock">
\r
1162 <div class="content">
\r
1163 <pre><tt>% cat ~/.zlogin
\r
1164 if [[ -x =keychain ]] ; then
\r
1165 eval $(keychain --nocolor --quiet --agents ssh --eval ~/.ssh/id_rsa)
\r
1168 <h3>4.12. Tips for debugging mercurial</h3>
\r
1169 <p>Problems with mercurial you can't explain at all, even though you read the
\r
1171 <p>Take a look at mercurial's global options:</p>
\r
1172 <div class="literalblock">
\r
1173 <div class="content">
\r
1174 <pre><tt>-v --verbose enable additional output
\r
1175 --debug enable debugging output
\r
1176 --debugger start debugger</tt></pre>
\r
1178 <p>Using strace might help as well, run something like:</p>
\r
1179 <div class="literalblock">
\r
1180 <div class="content">
\r
1181 <pre><tt>% strace -f -eopen hg status</tt></pre>
\r
1183 <p>A hardcore variant is using pydb, an enhanced Python command-line
\r
1185 <div class="literalblock">
\r
1186 <div class="content">
\r
1187 <pre><tt>% pydb -X =hg status</tt></pre>
\r
1190 <h2>5. Todo - Checkout</h2>
\r
1191 <div class="sectionbody">
\r
1195 find a way for <em>hg log —style=changelog</em> to provide release based verbose, full changelogs [based on tags?]
\r
1200 extend hg-buildpackage
\r
1205 /usr/share/python-support/mercurial/hgext/hbisect.py
\r
1210 /usr/share/doc/mercurial/examples/vim/patchreview.vim.gz
\r
1215 <h2>6. Ressources</h2>
\r
1216 <div class="sectionbody">
\r
1217 <h3>6.1. English</h3>
\r
1221 <a href="http://www.selenic.com/mercurial/wiki/index.cgi">Mercurial Homepage</a>
\r
1226 <a href="http://www.red-bean.com/~bos/hgbook.pdf">Distributed revision control with Mercurial</a>
\r
1231 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/SharedSSH">SharedSSH</a>
\r
1236 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/MultipleCommitters">How To Handle Multiple Committers</a>
\r
1241 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/HgWebDirStepByStep">HgWebDirStepByStep</a>
\r
1246 <a href="http://www.selenic.com/mercurial/wiki/index.cgi/PublishingRepositories">Publishing Repositories</a>
\r
1251 <a href="http://www.ivy.fr/mercurial/ref/v1.0/">Mercurial Reference Card</a>
\r
1255 <h3>6.2. German</h3>
\r
1259 <a href="http://intevation.de/~thomas/mercurial-lt2006/">Mercurial Distributed SCM - Die verteilte Alternative zu CVS</a>
\r
1264 <h2>7. About this document</h2>
\r
1265 <div class="sectionbody">
\r
1266 <p>(c) Michael Prokop <mika@grml.org>; HTML version powered by <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a>.</p>
\r
1269 <div id="footer-text">
\r
1270 Last updated 25-Nov-2007 20:10:21 CEST
\r