[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: Mo DeJong <supermo_at_bayarea.net>
Date: 2001-09-17 04:03:00 CEST

Hi all.

Here is an initial implementation of the svn patch subcommand that was discussed
in my previous post. This is meant to be a placeholder for the final implementation
which will need to be discussed in more detail. I would like the final implementation
to support svn commands embedded in patch file. That way you could send someone
one patch file with embedded `svn add ...` commands and all they would need to
do is run something like this:

% svn patch from_bob.patch
% svn status
A one.sh
A two.sh
A three.sh
M four.sh
% svn commit -m "patch from Bob to add new shell scripts"

Of course, this is not implemented yet. Bob would still need to this by hand
with the current patch.

% svn patch from_bob.patch
% svn add one.sh two.sh three.sh
% snv commit -m "patch from Bob to add new shell scripts"

Even so, this is a good start.

cheers
Mo DeJong

2001-09-16 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 and patch-cmd.c.
        * subversion/clients/cmdline/patch.c (svn_cl__patch_wc):
        Add initial implementation that simply exec's GNU patch
        behind the scenes.
        * subversion/clients/cmdline/README: Add usage info.
        * 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 Sun Sep 16 18:36:22 2001
+++ ./subversion/clients/cmdline/patch-cmd.c Sun Sep 16 17:39:45 2001
@@ -0,0 +1,66 @@
+/*
+ * patch-cmd.c -- Patch a file
+ *
+ * ====================================================================
+ * 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 Wed Sep 12 23:02:28 2001
+++ ./subversion/clients/cmdline/cl.h Sun Sep 16 18:35:14 2001
@@ -127,6 +136,7 @@
   svn_cl__undelete,
   svn_cl__help,
   svn_cl__import,
+ svn_cl__patch,
   svn_cl__proplist,
   svn_cl__propget,
   svn_cl__propset,
@@ -204,6 +214,10 @@
 svn_error_t *svn_cl__print_dir_diff (svn_stringbuf_t *path,
                                      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. */
Index: ./subversion/clients/cmdline/patch.c
===================================================================
--- ./subversion/clients/cmdline/SVN/text-base/patch.c Sun Sep 16 18:36:22 2001
+++ ./subversion/clients/cmdline/patch.c Sun Sep 16 18:28:22 2001
@@ -0,0 +1,112 @@
+/*
+ * 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"
+
+/* todo: correctly handle entries which are being added or removed. */
+
+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;
+
+ /* 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,
+ patchfile_handle, stdout_handle, stderr_handle,
+ pool));
+
+ /* 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/README
===================================================================
--- ./subversion/clients/cmdline/SVN/text-base/README Mon Sep 10 09:51:14 2001
+++ ./subversion/clients/cmdline/README Sun Sep 16 17:20:49 2001
@@ -171,6 +171,7 @@
    keyword | kw | key
    log | lo
    merge | me
+ patch | pa
    propget | pg | pget
    propset | ps | pset
    rdiff | rd
@@ -338,6 +339,17 @@
   e.g. svn rdiff http://svn.tigris.org/1999-10-23-alpha \
                  http://svn.tigris.org/2000-05-19-beta
 
+ patch
+ ====
+
+ Usage: svn patch file
+
+ The patch subcommand will apply changes from a patch file to the WC.
+ A patch file is typically created by saving the output of the diff
+ subcommand to a file. A patch can modify existing files as well
+ as perform other svn operations like renaming or deleting a file.
+ Note that a patch file cannot perform a commit operation, it can
+ only modify the existing WC.
 
   annotate
   ========
Index: ./subversion/clients/cmdline/main.c
===================================================================
--- ./subversion/clients/cmdline/SVN/text-base/main.c Wed Sep 12 23:02:57 2001
+++ ./subversion/clients/cmdline/main.c Sun Sep 16 17:20:25 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
Received on Sat Oct 21 14:36:41 2006

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