[PATCH 1 of 3 V2] chg: fallback to original hg for some unsupported commands or flags

Yuya Nishihara yuya at tcha.org
Sat Feb 27 02:37:50 EST 2016


On Fri, 26 Feb 2016 14:20:25 +0000, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <quark at fb.com>
> # Date 1456496279 0
> #      Fri Feb 26 14:17:59 2016 +0000
> # Node ID ecefdf920cc8b8b983e06da8e82b8db0f67b85de
> # Parent  824ccfaf08a238b50f179b39ceebf303c798031a
> chg: fallback to original hg for some unsupported commands or flags

Queued modified version to the clowncopter, thanks.

> The current detection is not 100% accurate since we do not have an equivalent
> command line parser in C. But it tries not to cause false positives that
> prevents people from using chg for legit cases. In the future we may want to
> implement a more accurate "unsupported" check server-side.

I want to make them just work instead.

> +/*
> + * Test whether the command is unsupported or not. This is not designed to
> + * cover all cases. But it's fast, does not depend on the server and does
> + * not return false positives.
> + */
> +static int isunsupported(int argc, const char *argv[])
> +{
> +	enum {
> +		SERVE = 1,
> +		DAEMON = 2,
> +		SERVEDAEMON = SERVE | DAEMON,
> +		TIME = 4,
> +	};
> +	unsigned int state = 0;
> +	int i;
> +	for (i = 0; i < argc; ++i) {
> +		if (!strcmp(argv[i], "--"))
> +			break;
> +		if (i == 0 && strcmp("serve", argv[i]) == 0)
> +			state |= SERVE;

This can't catch "hg --xxx serve -d", but that's okay bacause this function
tries to avoid false positive.

> +static void execoriginalhg(const char *argv[])
> +{
> +	debugmsg("execute original hg");
> +	if (execvp(gethgcmd(), (char **)argv) < 0)
> +		abortmsg("failed to exec original hg (errno = %d)", errno);
> +}

Confirmed that the C standard says argv is NULL-terminated.

I'm not sure if we should set argv[0] to hgcmd. And it can exec chg infinitely
as it isn't guarded by CHGINTERNALMARK.

>  int main(int argc, const char *argv[], const char *envp[])
>  {
>  	if (getenv("CHGDEBUG"))
>  		enabledebugmsg();
>  
> +	if (isunsupported(argc, argv))
> +		execoriginalhg(argv);

Fixed as isunsupported(argc - 1, argv + 1).


More information about the Mercurial-devel mailing list