Overview

c-hglib
""""""""

c-hglib is a high-level C library for interacting with Mercurial.
The project homepage is http://mercurial.selenic.com/wiki/C-Hglib.


Features
""""""""

c-hglib gives you:

    Fast: Normally, you would start a Mercurial process and then
          parse the output. C-hglib uses the Mercurial command server instead.
          This means that c-hglib starts a single Mercurial server process and
          interacts with that for the following operations.

    Convenient: We have done the hard work of parsing the output and
          turning it into a useful C API. Parsing a command like hg log is
          easy enough, but c-hglib also has code to talk with
          the interactive commands such as hg merge.

    Documented: c-hglib comes with extensive doxygen documentation
          that describes how each command works and a complete suite of
          examples.

    Tested: We have unit tests for all commands.


Purpose
"""""""""

c-hglib exists to provide a stable programmatic interface with Mercurial.
Mercurial internal python API is deliberatedly unstable and undocumented;
it can change from a Mercurial release without further notice.
On the other hand, c-hglib focuses on stability of the interface for use
in external projects: this is possible since it uses the Mercurial Command
Server to communicate with Mercurial.

Unlike Mercurial itself, which requires derived works be licensed with the
GPLv2+, c-hglib is available under the less restrictive MIT license.

This is possible since c-hglib is not derived work from Mercurial:
*) it uses an interface explictly declared to be unencumbered
*) was explicitly created to be unencumbered
*) exactly mirrors the other unencumbered interface (the command line).
You can't do anything with it that you can't already do from the command line...
except go a bit faster.


Deployment
""""""""""

c-hglib is build with autotools, i.e. configure/make/make install
should be all what is needed to install it.


Implementation description
""""""""""""""""""""""""""

The implementation is splitted in several levels (raw level, command level).

The raw level, also called level 0, contains the basic API functions. The
purpose of those functions is to wrap the lowest units that will be used
later to build the mercurial commands.
In the end using those functions you will be able to pass a raw command string
to  the Command Server and you will get some unparsed results.

The command level, also called level 1, has the purpose of creating a function
for each mercurial command. As applicable some functions will return the exit
code and other will process the output and will return results in native C
datatypes.


Example
"""""""

In the example folder you will find examples on how you can use c-hglib API.
To compile the binary files you can use the Makefile from the root directory.

* Export-Import example:

The export-import example will use the level 0 implementation and will export
the first revision from the first given repository and will import it to the
second given repository.
To compile the binary file you can use the make tool with "examples" target.
  > make example

This action will create an executable file named export_import_level0.

To run this executable, the first argument must be a path to the repository
where you want to import the patch, second argument.
  e.g: ./export_import_level0 export_repoy_path import_repo_path

To run this example, you can use two existing mercurial repository,
or create some throw-away ones just for the example. Here is how
you can create an ad-hoc repository
  e.g:
  > hg init export
  > cd export
  > touch foo ; echo boloo > foo; hg add foo ; hg commit -m foo
  > hg export -r 0 -o rev0.diff
  > cd ..
  > hg init import

* Import example:

The import example will use the level 0 implementation and will import to the
given repository the given patch.
To compile the binary file you can use the make tool with "examples" target.
  > make example

This action will create an executable file named import_level0.

To run this executable, the first argument must be a path to the repository
where you want to import the patch, second argument.
  e.g: ./import_level0 repository_path import_patch

To run this example, you can use an existing mercurial repository,
or create a throw-away one just for the example. Here is how
you can create an ad-hoc repository
  e.g:
  > hg init export
  > cd export
  > touch foo ; echo boloo > foo; hg add foo ; hg commit -m foo
  > hg export -r 0 -o rev0.diff
  > cd ..
  > hg init import

* Init example:

The init example will use the level 0 implementation and will create a new
repository with the given name.
To compile the binary file you can use the make tool with "examples" target.
  > make example

This action will create an executable file named init_level0.

To run this executable, the first argument must be a path to the repository
where you want to import the patch, second argument.
  e.g: ./import_level0 repository_name

* Log example:

The log example will use the level 0 implementation and will provide the history
data, for a specific repository, in an unparsed way.
To compile the binary file you can use the make tool with "examples" target.
 > make example

This action will create an executable file named log_level0.

To run this executable, the first argument must be a path to the repository
where you want to get the history.
  e.g: ./log_level0 repository_path

To run this example, you can use an existing mercurial repository,
or create a throw-away one just for the example. Here is how
you can create an ad-hoc repository
  e.g:
  > hg init tmp
  > touch foo ; hg add foo ; hg commit -m foo
  > echo baloo > foo ; hg commit -m 'baloo text'
  > touch voodoo ; hg add voodoo ; hg commit -m voodoo
  > echo voodoo > voodoo ; hg commit -m 'voodoo text'

* Merge example:

The merge example will use the level 0 implementation and will merge the heads
for a given repository.
To compile the binary file you can use the make tool with "examples" target.
  > make example

This action will create an executable file named merge_level0.

To run this executable, the first argument must be a path to the repository
where you want to import the patch, second argument.
  e.g: ./merge_level0 repository_path

To run this example, you can use an existing mercurial repository,
or create a throw-away one just for the example. Here is how
you can create an ad-hoc repository
  e.g:
  `Repository that creates two heads without conflicts` 
  > hg init tmp
  > cd tmp
  > touch foo ; hg add foo ; hg commit -m foo
  > echo baloo > foo ; hg commit -m 'baloo text'
  > hg up 0
  > touch boo ; hg add boo ; hg commit -m boo
  > echo voodoo > boo ; hg commit -m 'voodoo text'

  `Repository that creates two heads with conflicts`
  > hg init tmp
  > cd tmp
  > touch foo ; hg add foo ; hg commit -m foo
  > echo baloo > foo ; hg commit -m 'baloo text'
  > hg up 0
  > echo voodoo > foo ; hg commit -m 'voodoo text'

* Verify example:

The verify example will use the level 0 implementation and will verify the 
given repository.
To compile the binary file you can use the make tool with "examples" target.
  > make example

This action will create an executable file named verify_level0.

To run this executable, the first argument must be a path to the repository
where you want to import the patch, second argument.
  e.g: ./verify_level0 repository_path

To run this example, you can use an existing mercurial repository,
or create a throw-away one just for the example. Here is how
you can create an ad-hoc repository
  e.g:
  `Repository that it's not corrupt`
  > hg init tmp
  > cd tmp
  > touch foo ; hg add foo ; hg commit -m foo
  > echo baloo > foo ; hg commit -m 'baloo text'

  `Repository that it's corrupt`
  > hg init tmp
  > cd tmp
  > touch foo ; hg add foo ; hg commit -m foo
  > echo baloo > foo ; hg commit -m 'baloo text'
  > rm .hg/store/data/foo.i


Contact
""""""""

If you want to contact us, then please use one of these channels:

    Mercurial-Devel mailing list:
        http://mercurial.selenic.com/wiki/MailingLists#The_Mercurial-Devel_list
        This is the place for discussion about the development of c-hglib.
        You're also very welcome to send us a mail if you're using c-hglib in
        a project.
        Subscribe here: http://www.selenic.com/mailman/listinfo/mercurial/

    Bitbucket Issue Tracker: This is where you should report bugs in c-hglib.
       That would be problems of the form
       "When I do ..., c-hglib doesn't behave as expected".

Please remember to tell us which c-hglib version you're using.


License
""""""""

c-hglib is distributed under the MIT license.


Authors
""""""""

c-hglib was started by Iulian Stana as a Google Summer of Code 2013 project.
See the commit log for the full list of authors.