[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn needs a patch subcommand (Was svn ci/up --xml-file)

From: <kfogel_at_collab.net>
Date: 2001-10-03 00:43:25 CEST

Mo DeJong <supermo@bayarea.net> writes:
> It has been a number of weeks since I first posted this patch
> and the svn_io_run_cmd API has changed, so I figured this would
> be a good time to post an updated version. This patch adds
> a framework for the application of patches to a WC. Currently,
> it just runs `patch -p0 < file` behind the scenes, but the
> point is to provide a wrapper for application of patches to
> match the `svn diff` wrapper for generation of patches. As
> far a I can tell, the result of previous discussion on this
> topic was that a patch application subcommand was a good thing.

The benefit being that we'd eventually be able to apply `patch++' and
other formats, such that it would do the "svn add", "svn del", etc for
you, right? Sounds good.

A question though:

What's the benefit in having this in Subversion before it does more
than just run `patch', which the user could do anyway? If having this
subcommand in Subversion now would make it more likely that Subversion
will soon implement the extended functionality, then it makes sense to
apply this change right away. But I don't see why it would -- the
hard part of writing an "svn patch" command is not the framework nor
the exec'ing of patch, but choosing format[s] and interpreting them in
a way that is meaningful for Subversion. And it's of no use without
that extended functionality, since people can just run patch directly.

Subversion should have those extended features. But it should also
avoid a situation whereby it has, for some long period, just the
ability to invoke vanilla patch (which is by itself pointless) and no
more.

I guess what I'm really saying is, would you like to go the whole way
on this change -- research extended patch formats, document how
they'll be interpreted, and make Subversion do it? I'm not sure that
going only part of the way is terribly useful here.

-K

> 2001-10-02 Mo DeJong <supermo@bayarea.net>
>
> Implement `svn patch` subcommand.
>
> * subversion/clients/cmdline/patch-cmd.c (svn_cl__patch):
> * subversion/clients/cmdline/cl.h (svn_cl__patch, svn_cl__patch_wc):
> Declare patch functions for use in main.c.
> * subversion/clients/cmdline/patch.c (svn_cl__patch_wc):
> Add initial implementation that just exec's GNU patch
> behind the scenes.
> * subversion/clients/cmdline/main.c: Add patch to subcommand table.
>
> Index: subversion/clients/cmdline/patch-cmd.c
> ===================================================================
> --- subversion/clients/cmdline/SVN/text-base/patch-cmd.c Tue Oct 2 12:25:04 2001
> +++ subversion/clients/cmdline/patch-cmd.c Tue Oct 2 12:20:01 2001
> @@ -0,0 +1,66 @@
> +/*
> + * patch-cmd.c -- Patch the WC.
> + *
> + * ====================================================================
> + * Copyright (c) 2000-2001 CollabNet. All rights reserved.
> + *
> + * This software is licensed as described in the file COPYING, which
> + * you should have received as part of this distribution. The terms
> + * are also available at http://subversion.tigris.org/license-1.html.
> + * If newer versions of this license are posted there, you may use a
> + * newer version instead, at your option.
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals. For exact contribution history, see the revision
> + * history and logs, available at http://subversion.tigris.org/.
> + * ====================================================================
> + */
> +
> +/* ==================================================================== */
> +
> +
> +
> +/*** Includes. ***/
> +
> +#include "svn_wc.h"
> +#include "svn_client.h"
> +#include "svn_string.h"
> +#include "svn_path.h"
> +#include "svn_delta.h"
> +#include "svn_error.h"
> +#include "svn_types.h"
> +#include "cl.h"
> +
> +
> +/*** Code. ***/
> +
> +svn_error_t *
> +svn_cl__patch (apr_getopt_t *os,
> + svn_cl__opt_state_t *opt_state,
> + apr_pool_t *pool)
> +{
> + svn_error_t *err;
> + apr_array_header_t *targets;
> +
> + targets = svn_cl__args_to_target_array(os, pool);
> +
> + if (targets->nelts == 1)
> + {
> + svn_stringbuf_t *patchfile = ((svn_stringbuf_t **) (targets->elts))[0];
> + return svn_cl__patch_wc (patchfile, pool);
> + }
> + else
> + {
> + svn_cl__subcommand_help ("patch", pool);
> + return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, 0, 0, pool, "");
> + }
> +
> + return SVN_NO_ERROR;
> +}
> +
> +
> +/*
> + * local variables:
> + * eval: (load-file "../../svn-dev.el")
> + * end:
> + */
> Index: subversion/clients/cmdline/cl.h
> ===================================================================
> --- subversion/clients/cmdline/SVN/text-base/cl.h Thu Sep 27 13:13:36 2001
> +++ subversion/clients/cmdline/cl.h Tue Oct 2 12:22:03 2001
> @@ -130,6 +130,7 @@
> svn_cl__undelete,
> svn_cl__help,
> svn_cl__import,
> + svn_cl__patch,
> svn_cl__proplist,
> svn_cl__propget,
> svn_cl__propset,
> @@ -206,6 +207,10 @@
> apr_array_header_t *options,
> svn_boolean_t recurse,
> apr_pool_t *pool);
> +
> +/* Patch the working copy with the contents of patchfile. */
> +svn_error_t *svn_cl__patch_wc (svn_stringbuf_t *patchfile,
> + apr_pool_t *pool);
>
> /* Returns an editor that prints out events in an update or checkout. */
> svn_error_t *
> Index: subversion/clients/cmdline/patch.c
> ===================================================================
> --- subversion/clients/cmdline/SVN/text-base/patch.c Tue Oct 2 12:25:05 2001
> +++ subversion/clients/cmdline/patch.c Tue Oct 2 12:23:21 2001
> @@ -0,0 +1,113 @@
> +/*
> + * patch.c: the command-line's portion of the "svn patch" command
> + *
> + * ====================================================================
> + * Copyright (c) 2000-2001 CollabNet. All rights reserved.
> + *
> + * This software is licensed as described in the file COPYING, which
> + * you should have received as part of this distribution. The terms
> + * are also available at http://subversion.tigris.org/license-1.html.
> + * If newer versions of this license are posted there, you may use a
> + * newer version instead, at your option.
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals. For exact contribution history, see the revision
> + * history and logs, available at http://subversion.tigris.org/.
> + * ====================================================================
> + */
> +
> +/* ==================================================================== */
> +
> +
> +
> +/*** Includes. ***/
> +#define APR_WANT_STRFUNC /* for strcmp */
> +#include <apr_want.h>
> +
> +#include <apr_hash.h>
> +#include <apr_tables.h>
> +#include <apr_file_io.h>
> +
> +#include "svn_hash.h"
> +#include "svn_wc.h"
> +#include "svn_client.h"
> +#include "svn_string.h"
> +#include "svn_path.h"
> +#include "svn_private_config.h" /* for SVN_CLIENT_PATCH */
> +
> +#include "cl.h"
> +
> +svn_error_t *
> +svn_cl__patch_wc (svn_stringbuf_t *patchfile,
> + apr_pool_t *pool)
> +{
> + svn_boolean_t iswc;
> + const char **args;
> + int i = 0;
> + svn_stringbuf_t *cwd = svn_stringbuf_create (".", pool);
> + apr_file_t *patchfile_handle = NULL;
> + apr_file_t *stdout_handle = NULL, *stderr_handle = NULL;
> + apr_status_t apr_err;
> + apr_wait_t proc_status;
> +
> + /* Check that this is a real working copy. */
> + SVN_ERR (svn_wc_check_wc (cwd, &iswc, pool));
> +
> + if (!iswc)
> + return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, 0, NULL, pool,
> + "Current directory is not under version control.");
> +
> + /* Make sure the patch file exists and is readable */
> +
> + apr_err = apr_file_open (&patchfile_handle, patchfile->data, APR_READ,
> + APR_OS_DEFAULT, pool);
> +
> + if (apr_err)
> + return svn_error_createf (apr_err, 0, NULL, pool,
> + "error: can't open patch file %s", patchfile->data);
> +
> + /* Get an apr_file_t representing stdout */
> + apr_err = apr_file_open_stdout (&stdout_handle, pool);
> +
> + if (apr_err)
> + return svn_error_create (apr_err, 0, NULL, pool,
> + "error: can't open handle to stdout");
> +
> + /* Get an apr_file_t representing stderr */
> + apr_err = apr_file_open_stdout (&stderr_handle, pool);
> +
> + if (apr_err)
> + return svn_error_create (apr_err, 0, NULL, pool,
> + "error: can't open handle to stderr");
> +
> + /* Run the equiv of `patch -p 0 < patchfile` */
> +
> + args = apr_palloc(pool, 2*sizeof(char*));
> + args[i++] = "-p0";
> + args[i++] = NULL;
> +
> + SVN_ERR (svn_io_run_cmd (cwd->data, SVN_CLIENT_PATCH, args, &proc_status,
> + patchfile_handle, stdout_handle, stderr_handle,
> + pool));
> +
> + /* TODO: Handle proc_status != 0 here */
> +
> + /* TODO:
> +
> + 1. Don't depend on external patch program!
> +
> + 2. If a patch on any file fails all must be reverted. We must never
> + leave a tree in a half patched state.
> +
> + 3. We need to check for svn commands in the patch file.
> +
> + A line in the patch file like:
> +
> + svn rename foo bar
> +
> + Should call the rename command as if the user typed it in. Note
> + that the commit command must be disallowed in a patch file!
> + */
> +
> + return SVN_NO_ERROR;
> +}
> Index: subversion/clients/cmdline/main.c
> ===================================================================
> --- subversion/clients/cmdline/SVN/text-base/main.c Thu Sep 27 13:13:32 2001
> +++ subversion/clients/cmdline/main.c Tue Oct 2 12:23:50 2001
> @@ -106,6 +106,11 @@
> "Import a file or tree into the repository.\n"
> "usage: import REPOS_URL [PATH] [NEW_ENTRY_IN_REPOS] \n" },
>
> + { "patch", FALSE, svn_cl__patch,
> + "Apply patch to working copy.\n"
> + "usage: patch file\n" },
> + { "pa", TRUE, NULL, NULL },
> +
> { "proplist", FALSE, svn_cl__proplist,
> "List all properties for given files and directories.\n"
> "usage: proplist [TARGETS]\n" },
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:43 2006

This is an archived mail posted to the Subversion Dev mailing list.