hg.rst
author Oleksandr Gavenko <gavenkoa@gmail.com>
Thu, 16 Jun 2011 14:37:38 +0300
changeset 885 49e12da19c2d
parent 861 a0a4d3b85923
child 886 9b179c44f835
permissions -rw-r--r--
Merge or rebase uncommitted changes.

-*- mode: outline; coding: utf-8 -*-

* About.

    http://mercurial.selenic.com/wiki/ProjectsUsingMercurial
                Some Projects that Use Mercurial

* User config.

Put to your ~/.hgrc:

  [ui]
  ; Editor for editing commit message.
  editor = gvim
  ; Who commit.
  username = Oleksandr Gavenko <gavenkoa@gmail.com>
  ; Use internal merge algorithm, which mark conflict like <<<<<< ====== >>>>>>.
  ; Save previous file version in '*.orig' file, after merge must be marked as
  ; resolved by running 'hg resolve -m <file>'.
  merge = internal:merge
  [web]
  ; Default encoding for file hosted by 'hg serv'.
  encoding = utf-8

** Useful extension.

Put to your ~/.hgrc:

  [extensions]
  ; To allow 'fetch' command.
  hgext.fetch =
  ; To allow Mercurial Queues.
  hgext.mq =
  ; To import revisions from foreign VCS repositories into Mercurial.
  hgext.convert =
  ; Usage:  hg glog <dir>
  hgext.graphlog =
  ; Enable '.hgeol' tracking (fix for CR/LF).
  hgext.eol =

** Multiline log message for log command.

By default 'hg log' show only first line of log message. To see all message run:

  $ hg log -v

or put into ~/.hgrc:

  [defaults]
  log = -v

** Follow history ever when file copied.

By default 'hg log' show only history after last file copy. To see log message
before copying run:

  $ hg log -f

or put into ~/.hgrc:

  [defaults]
  log = -f

* Clone specific branches.

  $ hg clone http://your/repo -r $branch

* Closing branches.

  $ hg branches
$branch (inactive)
...
  $ hg branches -a
...                     # no $branch
  $ hg up -r $branch
  $ hg ci --close-branch -m "Bla-bla-bla"
  $ hg up -r default
  $ hg branches
...                     # no $branch
  $ hg branches -c
$branch (inactive)
...

To reopen closed branch just update to it and commit anything!

* Remove/rename files history from repo.

  $ cat >filemap.txt <<EOF
exclude path/to/file-or-dir
rename path/to/source path/to/destination
...
EOF
  $ hg convert --filemap filemap.txt $repo_orig $repo_new
  $ hg -R $repo_new up

* Join history of two repos.

  $ cat >filemap1.txt <<EOF
rename . dir1
EOF
  $ cat >filemap2.txt <<EOF
rename . dir2
EOF
  $ hg convert --filemap filemap1.txt $repo1 $repo_new
  $ hg convert --filemap filemap2.txt $repo2 $repo_new
  $ hg -R $repo_new merge
  $ hg -R $repo_new ci -m "Join $repo1 and $repo2."

* Publishing repo.

With static HTTP hosting you can copy via rsync, ftp, scp, etc., so long as all the files beneath
.hg are copied. Also since 1.1 pull protocol can detect static HTTP hosting:

  $ hg clone http://example.com/project

  http://mercurial.selenic.com/wiki/hgserve
  http://mercurial.selenic.com/wiki/HgWebDirStepByStep
  http://mercurial.selenic.com/wiki/StaticHTTP

** hgweb.config.

Set allowed project by specifying paths to they (keys are URL, values are fs paths):

  [paths]
  myproject = /home/user/hg/myproject
  otherproject = /home/user/hg/otherproject

You can use single wildcard '*' to search current subdirs or double wildcard '**' to search subdirs
recursively:

  [paths]
  myproject = /home/user/hg/my/*
  otherproject = /home/user/hg/other/**

Alternatively you can set a collection of repos (keys and values are both filesystem paths, keys
should be prefixes of the values and are "subtracted" from the values in order to generate the URL
paths to each repository):

  [collections]
  /home/user/hg = /home/user/hg
  /home/another/hg = /home/another/hg

Allow archive downloads:

  [web]
  allow_archive = gz, zip, bz2

Make web page look nice:

  [web]
  # Use 'cd /lib/python2.x/site-packages/mercurial/templates; find . -type d' to see available
  # styles. Some interesting: gitweb, coal, monoblue.
  style = gitweb

Set another settings:

  [web]
  encoding = UTF-8

  maxchanges = 100
  maxfiles = 100

In each $proj/.hg/hgrc put:

  [web]
  contact = ADMIN <admin@example.com>
  description = <p style="color: red;">$proj</b> allow make a <a href="http://example.com">BIG Thing.</a>
  # Do not use name, in this case you see dir name where project lcated.
  # name = $proj

To allow push in 'hg serv':

  [web]
  allow_push = *
  push_ssl = false

  http://mercurial.selenic.com/wiki/PublishingRepositories
                Publishing Mercurial Repositories

** init.d script.

  #!/bin/sh
  CMD=/usr/bin/hg

  PORT=7878
  SRC=/srv/hg
  CONGIG=/srv/hg/hgweb.config
  PIDFILE=/var/run/hg.pid

  case "$1" in
  start)
    echo "Mecurial Server service starting."
    (cd "$SRC"; $CMD serve -d -p $PORT --pid-file "$PIDFILE")
    ;;
  stop)
    if [ -f "$PIDFILE" ]; then
      PID=`cat "$PIDFILE"`
      if [ "$PID" -gt 1 ]; then
        kill -TERM $PID
        echo "Stopping the Mercurial service PID=$PID."
      else
        echo Bad PID for Mercurial -- \"$PID\".
        echo You may remove \"$PIDFILE\" manually.
      fi
    else
      echo No PID file recorded for mercurial.
    fi
    ;;
  *)
    echo "$0 {start|stop}"
    exit 1
    ;;
  esac

  http://mercurial.selenic.com/wiki/hgserve

* Manage patches with MQ.

First enable MQ, add following to your ~/.hgrc:

  [extensions]
  hgext.mq =

Second get unpatched sources and put it to hg repository:

  $ tar zxf proj-x.y.z.tar.gz
  $ mv proj-x.y.z proj
  $ cd proj
  $ hg init
  $ hg ci -m "Added x.y.z version of proj."

Init MQ and take name for first patch:

  $ hg qinit
  $ hg qnew first.patch

Next make changes by editing source and save it to patch:

  $ $EDITOR file.c
  ...
  $ hg diff
  ...
  $ hg qrefresh
  $ hg diff      # <-- have zero diff

You can make second patch by applying existing one:

  $ hg qnew second.patch
  $ patch -p1 <bugfix.patch
  $ hg qrefresh

You can take list of patches (from old to new) and revert or apply patches by
qpop/qpush command:

  $ hg qseries   # <-- what patches have
  first.patch
  second.patch
  $ hg qapplied  # <-- what patches applied
  first.patch
  second.patch
  $ hg qpop
  $ hg qseries
  first.patch
  second.patch
  $ hg qapplied
  first.patch

You can revert or apply all patches by single command:

  $ hg qpop -a
  $ hg qpush -a

You can delete patch from patch list (before that you need de-apply patch):

  $ hg qpop -a
  $ hg qdelete first.patch

To add new version of source and fix patches for it first de apply patches,
then pull new changes and try apply patches on top of new sources:

  $ hg qpop -a
  $ rm *       # .hg dir not deleted because its name start with dot
  $ cd ..
  $ tar zxf proj-a.b.c.tar.gz
  $ cp -R proj-a.b.c/* proj
  $ cd proj
  $ hg addremove -s 70
  $ hg ci -m "Added a.b.c version of proj."
  $ hg qpush -a

To apply series of already done patches use:

  $ ls /path/to/bugfixes/*.patch | xargs hg qimport

You can fix patch description message from command line:

  $ hg qser -s
makefile-doc.patch:
  $ hg qpush
applying makefile-doc.patch
now at: makefile-doc.patch
  $ hg qref -m 'Add description about Makefile usage.'
  $ hg qser -s
makefile-doc.patch: Add description about Makefile usage.

or from editor by:

  $ hg qref -e

* Remove all patches from MQ.

  $ hg qpop -a
  $ for patch in `hg qser`; do hg qrm $patch; done

* Show supported/loaded plugin.

  $ hg help extensions
  $ hg showconfig extensions

* Proxy.

  $ hg clone --config http_proxy.host=$host:$port \
    --config http_proxy.user=$user --config http_proxy.passwd=$password  $addr

* Free Mercurial hosting.

  http://mercurial.selenic.com/wiki/MercurialHosting
                Free Hosting of Mercurial Repositories

* Merge or rebase uncommitted changes.

  $ hg diff > .diff   # save local changes
  $ hg revert -a
  $ hg fetch
  $ patch -p1 <.diff

  http://mercurial.selenic.com/wiki/TipsAndTricks#Merge_or_rebase_with_uncommitted_changes