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

[PATCH] Issue #1295

From: Mark Grosberg <mark_at_nolab.conman.org>
Date: 2003-05-09 01:21:47 CEST

Hello all,

I saw issue #1295 get filed. This is one of the things that has bothered
me about CVS for the longest time. So, I got a bit of energey and
implemented this. It really isn't that invasive at all.

Personally, I would like this feature much more. It makes the command line
client much easier to use than even the suggested alternative. Please
consider this.

I compiled and tested the fix. Seems to work well. There are some things
people may wish to add. I noticed there are a few places where the get_log
callback of the context is called to only get the log message.

Well, the those cases we may want to print a warning if any of the
comitted items have the (new) SVN_CLIENT_COMMIT_ITEM_UNMARKED flag set
(currently, it is just ignored).

Other than that, I'm open to suggestions about the patch.

Subversion rocks!

---------------------------------------------------------------------------

Index: include/svn_client.h
===================================================================
--- include/svn_client.h (revision 5857)
+++ include/svn_client.h (working copy)
@@ -292,6 +292,7 @@
 #define SVN_CLIENT_COMMIT_ITEM_TEXT_MODS 0x04
 #define SVN_CLIENT_COMMIT_ITEM_PROP_MODS 0x08
 #define SVN_CLIENT_COMMIT_ITEM_IS_COPY 0x10
+#define SVN_CLIENT_COMMIT_ITEM_UNMARKED 0x20
 /** @} */

 /** The commit candidate structure. */
Index: libsvn_client/commit_util.c
===================================================================
--- libsvn_client/commit_util.c (revision 5857)
+++ libsvn_client/commit_util.c (working copy)
@@ -747,6 +747,19 @@

   assert (ci && ci->nelts);

+ /* Delete unrequested items. */
+ for (i = 0; i < ci->nelts; i++)
+ {
+ item = (((svn_client_commit_item_t **) ci->elts)[i]);
+ if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_UNMARKED)
+ {
+ /* I couldn't find an apr_array_delete -- MYG. */
+ if (ci->nelts > 1)
+ ci->elts[i] = ci->elts[ci->nelts - 1];
+ ci->nelts--;
+ }
+ }
+
   /* Sort our commit items by their URLs. */
   qsort (ci->elts, ci->nelts,
          ci->elt_size, svn_client__sort_commit_item_urls);
Index: clients/cmdline/util.c
===================================================================
--- clients/cmdline/util.c (revision 5857)
+++ clients/cmdline/util.c (working copy)
@@ -416,6 +416,150 @@

 #define EDITOR_EOF_PREFIX "--This line, and those below, will be ignored--"

+static const char *
+get_item_path (svn_client_commit_item_t *item,
+ struct log_msg_baton *lmb,
+ apr_pool_t *pool)
+{
+ const char *item_path = item->path;
+
+ if (! item_path)
+ item_path = item->url;
+ else if (! *item_path)
+ item_path = ".";
+
+ if (item_path && lmb->base_dir)
+ item_path = svn_path_is_child (lmb->base_dir, item_path, pool);
+
+ /* If still no path, then just use current directory. */
+ if (! item_path)
+ item_path = ".";
+
+ return item_path;
+}
+
+static void process_comitted_list(struct log_msg_baton *lmb,
+ svn_stringbuf_t *commited_list,
+ apr_array_header_t *commit_items,
+ apr_pool_t *pool)
+{
+ char *end_str, *prev_str = NULL;
+ int i;
+
+ /* Find the generated message. */
+ end_str = commited_list->data;
+ while (end_str != NULL)
+ {
+ end_str = strstr (end_str, EDITOR_EOF_PREFIX);
+ if (end_str == NULL)
+ break;
+
+ end_str = end_str + (sizeof(EDITOR_EOF_PREFIX) - 1);
+ prev_str = end_str;
+ }
+
+ if (prev_str == NULL)
+ return;
+ while (*prev_str != '\0')
+ {
+ if (!apr_isspace (*prev_str))
+ break;
+ prev_str++;
+ }
+
+ /* Flag all the commited items as unmarked. */
+ for (i = 0; i < commit_items->nelts; i++)
+ {
+ svn_client_commit_item_t *item
+ = ((svn_client_commit_item_t **) commit_items->elts)[i];
+
+ item->state_flags |= SVN_CLIENT_COMMIT_ITEM_UNMARKED;
+ }
+
+ /* Now, parse each line and make sure that the commited item is named. */
+ while (*prev_str != '\0')
+ {
+ char *end_of_path;
+
+ /* Skip leading whitespace. */
+ for (;;)
+ {
+ if (*prev_str == '\0')
+ return;
+
+ if (!apr_isspace (*prev_str))
+ break;
+ prev_str++;
+ }
+ if (*prev_str == '\0')
+ break;
+
+ /* The next byte had better be one of the text mod's below. */
+ switch (*prev_str++)
+ {
+ case '_':
+ case 'R':
+ case 'A':
+ case 'D':
+ case 'M':
+ break;
+
+ default:
+ return;
+ }
+
+ /* The next byte had better be one of the prop mod's below. */
+ switch (*prev_str++)
+ {
+ case ' ':
+ case 'M':
+ break;
+
+ default:
+ return;
+ }
+
+ /* Skip more whitespace. */
+ for (;;)
+ {
+ if (*prev_str == '\0')
+ return;
+ if (!apr_isspace(*prev_str))
+ break;
+ prev_str++;
+ }
+
+ /* Chop up the path. */
+ for (end_of_path = prev_str; *end_of_path != '\0';)
+ {
+ if (strcmp (end_of_path, APR_EOL_STR) == 0)
+ break;
+ else
+ end_of_path++;
+ }
+ if (*end_of_path == '\0')
+ return;
+
+ /* Truncate the string. The path is now in prev_str. */
+ *end_of_path++ = '\0';
+
+ /* Now, find it and enable it. */
+ for (i = 0; i < commit_items->nelts; i++)
+ {
+ svn_client_commit_item_t *item
+ = ((svn_client_commit_item_t **) commit_items->elts)[i];
+ const char *path = get_item_path(item, lmb, pool);
+
+ if (strcmp (path, prev_str) == 0)
+ item->state_flags &= ~SVN_CLIENT_COMMIT_ITEM_UNMARKED;
+ }
+
+ /* Advance the pointer. */
+ prev_str = end_of_path;
+ }
+}
+
+
 /* This function is of type svn_client_get_commit_log_t. */
 svn_error_t *
 svn_cl__get_log_message (const char **log_msg,
@@ -469,21 +613,9 @@
         {
           svn_client_commit_item_t *item
             = ((svn_client_commit_item_t **) commit_items->elts)[i];
- const char *path = item->path;
+ const char *path = get_item_path(item, lmb, pool);
           char text_mod = '_', prop_mod = ' ';

- if (! path)
- path = item->url;
- else if (! *path)
- path = ".";
-
- if (path && lmb->base_dir)
- path = svn_path_is_child (lmb->base_dir, path, pool);
-
- /* If still no path, then just use current directory. */
- if (! path)
- path = ".";
-
           if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
               && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
             text_mod = 'R';
@@ -542,8 +674,14 @@

       /* Strip the prefix from the buffer. */
       if (message)
+ {
+ svn_stringbuf_t *commited_list = svn_stringbuf_create (msg2, pool);
+ if (commited_list)
+ process_comitted_list (lmb, commited_list, commit_items, pool);
+
         truncate_buffer_at_prefix (&message->len, message->data,
                                    EDITOR_EOF_PREFIX);
+ }

       if (message)
         {

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri May 9 01:23:12 2003

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.