C-hglib - Level 0, API proposal.

Matt Mackall mpm at selenic.com
Mon Jul 8 15:36:26 CDT 2013


On Thu, 2013-07-04 at 18:57 +0300, Iulian Stana wrote:
> /* return the handle for a connection */
> hg_handle* hg_open(const char *path);

Do you see the * on the left? It does not go there, as I've already
explained at length. "foo *x", not "foo* x".

How do I set encoding for the connection?

> /* The function returns 0 if successful, -1 to indicate an error, with
> errno set appropriately. */
> int hg_close(hg_handle *handle);
> 
> /* The function returns 0 if successful, -1 to indicate an error, with
> errno set appropriately. */

What sorts of errors might we encounter?

> /* It's just sending the command to the cmdsrv.*/
> int hg_rawcommand(hg_handle *handle, const char *command);

Consider:

ret = hg_rawcommand(h, "add this filename has spaces in it");

Will this do the right thing? If so, how?

Please have a look at the manpages for execl/execv to see how this
problem has been solved in the past.

> a) hg init <- doesn't start with a repo
> In this case, I will create a new process were I will execute the init
> command, to create the new repo. After this, I will establish the
> connection through pipes, with the cmdserver.
> For the clone command, there I will execute the same steps.
> The return in those cases will be the handle for the connection.

How about clone? How about other commands that don't require an
extension like help, version, etc? How about commands we do not know
about yet because they are in extensions or future versions of
Mercurial?

> b) hg log <- can produce huge output
> I know that some repo could have a huge log, but I don't know if the user
> will use that huge output. My single thought right now is to set a limit
> for the huge mass of data.

I feel like I've spent hours explaining to you that this is not
acceptable already.

Here's how it ought to work:

- client opens a connection
- client sends a command
- client reads output until no more output is available
- client reads result code

This is not hard and I spelled this out already way back here:

http://mercurial.markmail.org/thread/tc6hsvl7fofdjqcl

Note how it never reads more than 4k at a time.

> c) hg import - <- wants a patch fed to it from client
> If patch is a list of files or a file-like, then the input for the command
> server will be from those files. In this case the data will be send line by
> line to the server.

A client will want to be able to do the equivalent of:

hg -R repo-a export | hg -R repo-b import -

..without buffering the entire patch either in memory or on disk.

> d) hg merge <- has prompts
> By default, if there will be any prompts the merge will abort.

Assume this is a question designed to make you search for a non-trivial
answer. Suppose I'm building a Mercurial GUI that uses c-hglib. Such a
GUI will most assuredly want to be able to do interactive merges. How do
I get the prompt questions displayed to the user and get the user
answers back?

> e) hg verify <- might give warnings intermixed with output
> Returns 0 on success, 1 if errors are encountered.
> In handle I will save the good output and warnings/errors.

Let's try this a different way: you may only call malloc once per
connection and you may not malloc more than 1k. Of course, you can still
expect commands to return gigabytes of output. Assume some commands
(like verify) can return more than 1k of error messages and that
dropping such messages may be unacceptable.

Hopefully, this will help you focus your thinking about the problem.

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list