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

[PATCH] svn now stores unix-owner, -group, and -mode too

From: Ph. Marek <philipp.marek_at_bmlv.gv.at>
Date: 2005-02-01 08:05:56 CET

Hello everybody,

here's a patch which sits atop of my previous patch for issue 1256
(http://subversion.tigris.org/issues/show_bug.cgi?id=1256; patch at
http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=82866)
which saves the owner, group, and unix-mode of files in properties.

I did some amount of testing, but remarks are always appreciated.

(I know that a rewrite of libsvn_wc is planned which possibly does all that,
but as it may take some time I did a patch for the current code)

Regards,

Phil

[[[

* subversion-1.1.3.tstamp/subversion/include/svn_io.h
  Declarations of helper functions
 svn_io_file_owner_string
 svn_io_file_group_string
 svn_io_file_mode_string
 svn_io_file_set_file_owner_group_mode

* subversion-1.1.3.tstamp/subversion/include/svn_props.h
  Definitions of new property names

* subversion-1.1.3.tstamp/subversion/libsvn_client/commit.c
  (import_file): Change auto-props to the correct value

* subversion-1.1.3.tstamp/subversion/libsvn_client/commit_util.c
  (harvest_committables): Do the stat() on the file once and
     use the values for the properties text-time, owner, group
     and mode, if these are set.

* subversion-1.1.3.tstamp/subversion/libsvn_client/export.c
  (copy_versioned_files): Fetch and save the svn:text-time property
  (change_file_prop): and use it to override the commit-timestamp
  (close_file):

* subversion-1.1.3.tstamp/subversion/libsvn_client/repos_diff.c
  Define a static helper function populate_finfo()
  (change_file_prop): Uses populate_finfo to record property changes

* subversion-1.1.3.tstamp/subversion/libsvn_subr/io.c
  (svn_io_files_contents_same_p):
  Definitions of helper functions
 svn_io_file_owner_string: convert a userid to a string
 svn_io_file_group_string: convert a groupid to a string
 svn_io_file_mode_string: convert a unix-mode to a string
 svn_io_file_set_file_owner_group_mode: use the property values
   to set the file's meta-data

* subversion-1.1.3.tstamp/subversion/libsvn_wc/adm_crawler.c
  (restore_file):
* subversion-1.1.3.tstamp/subversion/libsvn_wc/adm_ops.c
  (revert_admin_things):
  Use the svn:text-time to override the commit-time

* subversion-1.1.3.tstamp/subversion/libsvn_wc/update_editor.c
  (change_file_prop): Save the properties owner, group, mode
  (close_file): and use them to restore the meta-dat

]]]

diff -urp subversion-1.1.3.tstamp/subversion/include/svn_io.h
subversion-1.1.3/subversion/include/svn_io.h
--- subversion-1.1.3.tstamp/subversion/include/svn_io.h 2004-09-06
08:17:49.000000000 +0200
+++ subversion-1.1.3/subversion/include/svn_io.h 2005-01-28 12:02:00.000000000
+0100
@@ -28,6 +28,7 @@
 #include <apr.h>
 #include <apr_pools.h>
 #include <apr_file_io.h>
+#include <apr_user.h>
 #include <apr_thread_proc.h>
 
 #include "svn_types.h"
@@ -874,6 +875,36 @@ svn_io_read_version_file (int *version,
 svn_error_t *
 svn_io_write_version_file (const char *path, int version, apr_pool_t *pool);
 
+/** Return a string for the userid in @a owner in the format "uid name".
+ * Use @a pool for all allocations.
+ */
+svn_string_t *
+svn_io_file_owner_string (apr_uid_t owner,
+ apr_pool_t *pool);
+
+/** Return a string for the @a group in the format "uid name".
+ * Use @a pool for all allocations.
+ */
+svn_string_t *
+svn_io_file_group_string (apr_gid_t group,
+ apr_pool_t *pool);
+
+/** Return a string for the @a mode in octal, ie. unix-like.
+ * Use @a pool for all allocations.
+ */
+svn_string_t *
+svn_io_file_mode_string(apr_fileperms_t mode,
+ apr_pool_t *pool);
+
+/** Set the file's owner, group, and mode, if specified.
+ */
+svn_error_t *
+svn_io_file_set_file_owner_group_mode (const char *path,
+ const svn_string_t *owner,
+ const svn_string_t *group,
+ const svn_string_t *mode,
+ apr_pool_t *pool);
+
 /** @} */
 
 #ifdef __cplusplus
diff -urp subversion-1.1.3.tstamp/subversion/include/svn_props.h
subversion-1.1.3/subversion/include/svn_props.h
--- subversion-1.1.3.tstamp/subversion/include/svn_props.h 2005-01-28
06:39:43.000000000 +0100
+++ subversion-1.1.3/subversion/include/svn_props.h 2005-01-27
07:22:42.000000000 +0100
@@ -191,6 +191,16 @@ svn_error_t *svn_prop_diffs (apr_array_h
 /** The files' last modification time */
 #define SVN_PROP_TEXT_TIME SVN_PROP_PREFIX "text-time"
 
+/** The files' owner */
+#define SVN_PROP_OWNER SVN_PROP_PREFIX "owner"
+
+/** The files' group */
+#define SVN_PROP_GROUP SVN_PROP_PREFIX "group"
+
+/** The files' unix-mode */
+#define SVN_PROP_UNIX_MODE SVN_PROP_PREFIX "unix-mode"
+
+
 /** Describes external items to check out into this directory.
  *
  * The format is a series of lines, such as:
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_client/commit.c
subversion-1.1.3/subversion/libsvn_client/commit.c
--- subversion-1.1.3.tstamp/subversion/libsvn_client/commit.c 2005-01-28
06:39:43.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_client/commit.c 2005-01-31
06:33:38.000000000 +0100
@@ -197,20 +197,28 @@ import_file (const svn_delta_editor_t *e
         {
           const void *pname;
           void *pval;
+ apr_finfo_t finfo;
+
+ SVN_ERR( svn_io_stat(&finfo, path, APR_FINFO_NORM, pool) );
 
           apr_hash_this (hi, &pname, NULL, &pval);
 
           /* if the svn:text-time property is set, use the current file
            * date instead of the value */
           if (strcmp (pname, SVN_PROP_TEXT_TIME) == 0)
- {
- apr_time_t mtime;
+ pval=svn_string_create(
+ svn_time_to_cstring (finfo.mtime, pool),
+ pool );
+
+ /* do the same for owner, group, and unix-mode */
+ if (strcmp (pname, SVN_PROP_OWNER) == 0)
+ pval=svn_io_file_owner_string(finfo.user, pool);
 
- SVN_ERR (svn_io_file_affected_time (&mtime, path, pool) );
- pval=svn_string_create(
- svn_time_to_cstring (mtime, pool),
- pool );
- }
+ if (strcmp (pname, SVN_PROP_GROUP) == 0)
+ pval=svn_io_file_group_string(finfo.group, pool);
+
+ if (strcmp (pname, SVN_PROP_UNIX_MODE) == 0)
+ pval=svn_io_file_mode_string(finfo.protection, pool);
 
 
           SVN_ERR (editor->change_file_prop (file_baton, pname, pval, pool));
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_client/commit_util.c
subversion-1.1.3/subversion/libsvn_client/commit_util.c
--- subversion-1.1.3.tstamp/subversion/libsvn_client/commit_util.c 2005-01-28
06:39:43.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_client/commit_util.c 2005-01-31
06:54:54.000000000 +0100
@@ -27,9 +27,11 @@
 #include "client.h"
 #include "svn_path.h"
 #include "svn_types.h"
+#include "svn_string.h"
 #include "svn_pools.h"
 #include "svn_wc.h"
 #include "svn_sorts.h"
+#include "svn_time.h"
 
 #include <assert.h>
 #include <stdlib.h> /* for qsort() */
@@ -414,7 +416,12 @@ harvest_committables (apr_hash_t *commit
   /* Set text/prop modification flags accordingly. */
   if (text_mod)
     {
- state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;
+ apr_finfo_t finfo;
+
+
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;
+
+ SVN_ERR( svn_io_stat(&finfo, path, APR_FINFO_NORM, pool) );
 
       SVN_ERR (svn_wc_prop_get (&propval, SVN_PROP_TEXT_TIME, path,
adm_access,
                                 pool));
@@ -422,17 +429,45 @@ harvest_committables (apr_hash_t *commit
        * should be recorded, there's an property modification too. */
       if (propval)
         {
- apr_time_t mtime;
-
- SVN_ERR (svn_io_file_affected_time (&mtime, path, pool) );
           propval=svn_string_create(
- svn_time_to_cstring (mtime, pool),
+ svn_time_to_cstring (finfo.mtime, pool),
                                     pool );
           SVN_ERR (svn_wc_prop_set (SVN_PROP_TEXT_TIME,
                                     propval, path, adm_access, pool) );
           state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
+
         }
 
+ /* Check for svn:owner, svn:group, and svn:unix-mode */
+ SVN_ERR (svn_wc_prop_get (&propval, SVN_PROP_OWNER, path, adm_access,
+ pool));
+ if (propval)
+ {
+ propval=svn_io_file_owner_string(finfo.user, pool);
+ SVN_ERR (svn_wc_prop_set (SVN_PROP_OWNER,
+ propval, path, adm_access, pool) );
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
+ }
+
+ SVN_ERR (svn_wc_prop_get (&propval, SVN_PROP_GROUP, path, adm_access,
+ pool));
+ if (propval)
+ {
+ propval=svn_io_file_group_string(finfo.group, pool);
+ SVN_ERR (svn_wc_prop_set (SVN_PROP_GROUP,
+ propval, path, adm_access, pool) );
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
+ }
+
+ SVN_ERR (svn_wc_prop_get (&propval, SVN_PROP_UNIX_MODE, path,
adm_access,
+ pool));
+ if (propval)
+ {
+ propval=svn_io_file_mode_string(finfo.protection, pool);
+ SVN_ERR (svn_wc_prop_set (SVN_PROP_UNIX_MODE,
+ propval, path, adm_access, pool) );
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
+ }
     }
 
   if (prop_mod)
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_client/export.c
subversion-1.1.3/subversion/libsvn_client/export.c
--- subversion-1.1.3.tstamp/subversion/libsvn_client/export.c 2005-01-28
06:39:44.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_client/export.c 2005-01-31
16:18:29.000000000 +0100
@@ -194,7 +194,8 @@ copy_versioned_files (const char *from,
           svn_subst_eol_style_t style;
           apr_hash_t *props;
           const char *base;
- svn_string_t *eol_style, *keywords, *executable, *externals,
*special, *text_time;
+ svn_string_t *eol_style, *keywords, *executable, *externals,
+ *special, *text_time, *owner, *group, *mode;
           const char *eol = NULL;
           svn_boolean_t local_mod = FALSE;
           apr_time_t tm;
@@ -246,6 +247,12 @@ copy_versioned_files (const char *from,
                                   APR_HASH_KEY_STRING);
           text_time = apr_hash_get (props, SVN_PROP_TEXT_TIME,
                                     APR_HASH_KEY_STRING);
+ owner = apr_hash_get (props, SVN_PROP_OWNER,
+ APR_HASH_KEY_STRING);
+ group = apr_hash_get (props, SVN_PROP_GROUP,
+ APR_HASH_KEY_STRING);
+ mode = apr_hash_get (props, SVN_PROP_UNIX_MODE,
+ APR_HASH_KEY_STRING);
           
           if (eol_style)
             SVN_ERR (get_eol_style (&style, &eol, eol_style->data,
native_eol));
@@ -299,7 +306,15 @@ copy_versioned_files (const char *from,
                                                  FALSE, iterpool));
 
           if (! special)
+ {
             SVN_ERR (svn_io_set_file_affected_time (tm, copy_to, iterpool));
+
+ SVN_ERR (svn_io_file_set_file_owner_group_mode (copy_to,
+ owner,
+ group,
+ mode,
+ iterpool) );
+ }
         }
     }
   svn_pool_destroy (iterpool);
@@ -400,6 +415,9 @@ struct file_baton
   const svn_string_t *executable_val;
   svn_boolean_t special;
 
+ /* unix owner, group, and mode will be restaured */
+ svn_string_t *owner, *group, *mode;
+
   /* Any keyword vals to be substituted */
   const char *revision;
   const char *url;
@@ -603,6 +621,14 @@ change_file_prop (void *file_baton,
       SVN_ERR (svn_time_from_cstring (&fb->date, value->data, fb->pool));
     }
 
+ /* save owner, group and unix-mode */
+ else if (strcmp (name, SVN_PROP_OWNER) == 0)
+ fb->owner = svn_string_dup (value, fb->pool);
+ else if (strcmp (name, SVN_PROP_GROUP) == 0)
+ fb->group = svn_string_dup (value, fb->pool);
+ else if (strcmp (name, SVN_PROP_UNIX_MODE) == 0)
+ fb->mode = svn_string_dup (value, fb->pool);
+
   /* Try to fill out the baton's keywords-structure too. */
   else if (strcmp (name, SVN_PROP_ENTRY_COMMITTED_REV) == 0)
     fb->revision = apr_pstrdup (fb->pool, value->data);
@@ -704,6 +730,13 @@ close_file (void *file_baton,
   if (fb->date && (! fb->special))
     SVN_ERR (svn_io_set_file_affected_time (fb->date, fb->path, pool));
 
+ if (!fb->special)
+ SVN_ERR (svn_io_file_set_file_owner_group_mode (fb->path,
+ fb->owner,
+ fb->group,
+ fb->mode,
+ pool) );
+
   if (fb->edit_baton->notify_func)
     (*fb->edit_baton->notify_func) (fb->edit_baton->notify_baton,
                                     fb->path,
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_client/repos_diff.c
subversion-1.1.3/subversion/libsvn_client/repos_diff.c
--- subversion-1.1.3.tstamp/subversion/libsvn_client/repos_diff.c 2005-01-28
06:39:44.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_client/repos_diff.c 2005-01-28
12:13:26.000000000 +0100
@@ -33,6 +33,7 @@
 #include "svn_path.h"
 #include "svn_io.h"
 #include "svn_utf.h"
+#include "svn_time.h"
 
 #include "client.h"
 
@@ -145,6 +146,9 @@ struct file_baton {
   /* A cache of any property changes (svn_prop_t) received for this file. */
   apr_array_header_t *propchanges;
 
+ /* a cache for the file's meta-information */
+ apr_finfo_t *file_info;
+
   /* The pool passed in by add_file or open_file.
      Also, the pool this file_baton is allocated in. */
   apr_pool_t *pool;
@@ -901,6 +905,21 @@ close_directory (void *dir_baton,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+populate_finfo (struct file_baton *fb,
+ const char *name,
+ apr_pool_t *pool)
+{
+ apr_finfo_t finfo;
+
+ if (!fb->file_info)
+ {
+ fb->file_info=apr_palloc(pool, sizeof(*fb->file_info));
+ SVN_ERR (svn_io_stat (fb->file_info, name, APR_FINFO_NORM, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
 
 /* An editor function. */
 static svn_error_t *
@@ -921,16 +940,33 @@ change_file_prop (void *file_baton,
     {
       apr_time_t mtime;
 
- SVN_ERR (svn_io_file_affected_time (&mtime, b->path, b->pool) );
+ SVN_ERR (populate_finfo(b, name, pool));
       propchange->value=svn_string_create(
- svn_time_to_cstring (mtime,
b->pool),
+ svn_time_to_cstring
(b->file_info->mtime, b->pool),
                                           b->pool );
     }
+ /* do likewise for owner, group, mode */
+ else if (strcmp (name, SVN_PROP_OWNER) == 0)
+ {
+ SVN_ERR (populate_finfo(b, name, pool));
+ propchange->value=svn_io_file_owner_string( b->file_info->user,
b->pool);
+ }
+ else if (strcmp (name, SVN_PROP_GROUP) == 0)
+ {
+ SVN_ERR (populate_finfo(b, name, pool));
+ propchange->value=svn_io_file_group_string( b->file_info->group,
b->pool);
+ }
+ else if (strcmp (name, SVN_PROP_UNIX_MODE) == 0)
+ {
+ SVN_ERR (populate_finfo(b, name, pool));
+ propchange->value=svn_io_file_mode_string( b->file_info->protection,
pool);
+ }
   else
     {
- propchange->value = value ? svn_string_dup (value, b->pool) : NULL;
+ propchange->value = value ? svn_string_dup (value, b->pool) : NULL;
     }
-
+
+
   return SVN_NO_ERROR;
 }
 
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_subr/io.c
subversion-1.1.3/subversion/libsvn_subr/io.c
--- subversion-1.1.3.tstamp/subversion/libsvn_subr/io.c 2004-11-08
21:39:56.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_subr/io.c 2005-01-28 13:13:20.000000000
+0100
@@ -43,6 +43,7 @@
 #include <apr_pools.h>
 #include <apr_file_io.h>
 #include <apr_file_info.h>
+#include <apr_user.h>
 #include <apr_general.h>
 #include <apr_strings.h>
 #include <apr_portable.h>
@@ -2637,7 +2638,183 @@ svn_io_files_contents_same_p (svn_boolea
   if (q)
     *same = 1;
   else
- *same = 0;
+ *same = 0;
 
   return SVN_NO_ERROR;
 }
+
+
+svn_string_t *
+svn_io_file_owner_string (apr_uid_t owner,
+ apr_pool_t *pool)
+{
+ svn_string_t *out;
+ char *username;
+
+ if (apr_uid_name_get (&username, owner, pool) != APR_SUCCESS)
+ username="";
+ out=svn_string_createf(pool, "%d %s", owner, username);
+
+ return out;
+}
+
+
+
+svn_string_t *
+svn_io_file_group_string (apr_gid_t group,
+ apr_pool_t *pool)
+{
+ svn_string_t *out;
+ char *groupname;
+
+ if (apr_gid_name_get (&groupname, group, pool) != APR_SUCCESS )
+ groupname="";
+ out=svn_string_createf(pool, "%d %s", group, groupname);
+
+ return out;
+}
+
+svn_string_t *
+svn_io_file_mode_string(apr_fileperms_t perms,
+ apr_pool_t *pool)
+{
+ return svn_string_createf(pool, "0%o", apr_unix_perms2mode(perms));
+}
+
+
+svn_error_t *
+svn_io_file_owner_id (apr_uid_t *uid,
+ svn_string_t *owner,
+ apr_pool_t *pool)
+{
+ apr_gid_t gid;
+ apr_array_header_t *list;
+
+ if (!owner || !owner->data) goto invalid;
+
+ list=svn_cstring_split (owner->data, " \t\r\n\f", TRUE, pool);
+ if (list->nelts>=2)
+ {
+ /* Use the name, if available. Else use the numeric id. */
+ if (apr_uid_get(uid, &gid, APR_ARRAY_IDX(list, 1, char*), pool)
+ != APR_SUCCESS)
+ {
+ /* should use strtol or some such for error detection */
+ if ( apr_isdigit(* APR_ARRAY_IDX(list, 0, char*) ) )
+ *uid=svn__atoui64( APR_ARRAY_IDX(list, 0, char*) );
+ else
+ goto invalid;
+ }
+ }
+
+ return SVN_NO_ERROR;
+
+invalid:
+ return svn_error_create (SVN_ERR_ENTRY_ATTRIBUTE_INVALID, NULL,
+ "value of " SVN_PROP_OWNER " is invalid");
+}
+
+
+svn_error_t *
+svn_io_file_group_id (apr_gid_t *gid,
+ svn_string_t *group,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *list;
+
+ if (!group || !group->data)
+ goto invalid;
+
+ list=svn_cstring_split (group->data, " \t\r\n\f", TRUE, pool);
+ if (list->nelts>=2)
+ {
+ /* Use the name, if available. Else use the numeric id. */
+ if (apr_gid_get(gid, APR_ARRAY_IDX(list, 1, char*), pool) !=
+ APR_SUCCESS)
+ {
+ /* should use strtol or some such for error detection */
+ if ( apr_isdigit(* APR_ARRAY_IDX(list, 0, char*) ) )
+ *gid=svn__atoui64( APR_ARRAY_IDX(list, 0, char*) );
+ else
+ goto invalid;
+ }
+ }
+
+ return SVN_NO_ERROR;
+
+invalid:
+ return svn_error_create (SVN_ERR_ENTRY_ATTRIBUTE_INVALID, NULL,
+ "value of " SVN_PROP_GROUP " is invalid");
+}
+
+
+
+svn_error_t *
+svn_io_file_set_file_owner_group_mode (const char *path,
+ const svn_string_t *owner,
+ const svn_string_t *group,
+ const svn_string_t *mode,
+ apr_pool_t *pool)
+{
+ apr_gid_t gid;
+ apr_uid_t uid;
+ apr_finfo_t finfo;
+ apr_fileperms_t perms;
+ char *errorptr;
+
+ /* this function should move to apr */
+#ifdef _WIN32
+#else
+
+ if (owner || group)
+ {
+ if (owner && owner->data)
+ if (svn_io_file_owner_id(&uid, owner, pool) != SVN_NO_ERROR)
+ uid=-1;
+
+ if (group && group)
+ if (svn_io_file_group_id(&gid, group, pool) != SVN_NO_ERROR)
+ gid=-1;
+
+ if (uid != -1 && gid != -1)
+ {
+ /* only if at least one value defined */
+ if (uid == -1 || gid == -1)
+ {
+ /* chown changes owner and group.
+ * if there's only one set, we have to query the original
value.
+ * */
+ SVN_ERR( svn_io_stat(&finfo, path, APR_FINFO_NORM, pool) );
+ if (gid == -1) uid=finfo.group;
+ if (uid == -1) uid=finfo.user;
+ }
+
+ /* can only be done be uid 0, or by user with special priviledges.
+ * easiest thing is to try, and ignore an error
+ * */
+ chown(path, uid, gid);
+ }
+ }
+
+ if (mode && mode->data && apr_isdigit(mode->data[0]))
+ {
+ apr_status_t status;
+ /* use strtoul, which auto-detects the mode (octal, decimal, etc.)
+ * Normally the value is written in octal
+ *
+ * For now don't allow sticky bits.
+ * That should probably be configured with some option. */
+ perms=apr_unix_mode2perms(
+ strtoul(mode->data, NULL, 0) & 0777
+ );
+ status= apr_file_perms_set(path, perms);
+ if (status != APR_SUCCESS)
+ return svn_error_wrap_apr (status,
+ "Can't set file permissions on file '%s'",
+ path);
+ }
+#endif
+
+ return SVN_NO_ERROR;
+}
+
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_wc/adm_crawler.c
subversion-1.1.3/subversion/libsvn_wc/adm_crawler.c
--- subversion-1.1.3.tstamp/subversion/libsvn_wc/adm_crawler.c 2005-01-28
06:39:44.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_wc/adm_crawler.c 2005-01-28
12:31:53.000000000 +0100
@@ -37,6 +37,7 @@
 #include "svn_sorts.h"
 #include "svn_delta.h"
 #include "svn_path.h"
+#include "svn_time.h"
 
 #include "wc.h"
 #include "adm_files.h"
@@ -70,6 +71,7 @@ restore_file (const char *file_path,
   const char *bname;
   apr_uint32_t modify_flags = 0;
   svn_boolean_t special;
+ const svn_string_t *owner, *group, *mode;
 
   text_base_path = svn_wc__text_base_path (file_path, FALSE, pool);
   tmp_text_base_path = svn_wc__text_base_path (file_path, TRUE, pool);
@@ -130,7 +132,19 @@ restore_file (const char *file_path,
     {
       SVN_ERR (svn_io_file_affected_time (&tstamp, file_path, pool));
     }
-
+
+ SVN_ERR (svn_wc_prop_get(&owner, SVN_PROP_OWNER,
+ file_path, adm_access, pool));
+ SVN_ERR (svn_wc_prop_get(&group, SVN_PROP_GROUP,
+ file_path, adm_access, pool));
+ SVN_ERR (svn_wc_prop_get(&mode, SVN_PROP_UNIX_MODE,
+ file_path, adm_access, pool));
+ SVN_ERR (svn_io_file_set_file_owner_group_mode (file_path,
+ owner,
+ group,
+ mode,
+ pool) );
+
   /* Modify our entry's text-timestamp to match the working file. */
   modify_flags |= SVN_WC__ENTRY_MODIFY_TEXT_TIME;
   newentry.text_time = tstamp;
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_wc/adm_ops.c
subversion-1.1.3/subversion/libsvn_wc/adm_ops.c
--- subversion-1.1.3.tstamp/subversion/libsvn_wc/adm_ops.c 2005-01-28
06:39:44.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_wc/adm_ops.c 2005-01-28
12:32:09.000000000 +0100
@@ -1303,6 +1303,7 @@ revert_admin_things (svn_wc_adm_access_t
           if (use_commit_times && (! special))
             {
               const svn_string_t *mtime;
+ const svn_string_t *owner, *group, *mode;
 
               SVN_ERR (svn_wc_prop_get (&mtime, SVN_PROP_TEXT_TIME,
                                         fullpath, adm_access, pool));
@@ -1314,6 +1315,22 @@ revert_admin_things (svn_wc_adm_access_t
               SVN_ERR (svn_io_set_file_affected_time (tstamp,
                                                       fullpath, pool));
               tstamp = entry->cmt_date;
+
+
+ /* if any of owner, group, or unix-mode are set,
+ * use this information
+ * */
+ SVN_ERR (svn_wc_prop_get (&owner, SVN_PROP_OWNER,
+ fullpath, adm_access, pool));
+ SVN_ERR (svn_wc_prop_get (&group, SVN_PROP_GROUP,
+ fullpath, adm_access, pool));
+ SVN_ERR (svn_wc_prop_get (&mode, SVN_PROP_UNIX_MODE,
+ fullpath, adm_access, pool));
+ SVN_ERR (svn_io_file_set_file_owner_group_mode (fullpath,
+ owner,
+ group,
+ mode,
+ pool) );
             }
           else
             {
diff -urp subversion-1.1.3.tstamp/subversion/libsvn_wc/update_editor.c
subversion-1.1.3/subversion/libsvn_wc/update_editor.c
--- subversion-1.1.3.tstamp/subversion/libsvn_wc/update_editor.c 2005-01-28
06:39:44.000000000 +0100
+++ subversion-1.1.3/subversion/libsvn_wc/update_editor.c 2005-01-28
12:27:13.000000000 +0100
@@ -526,6 +526,9 @@ struct file_baton
   const char *last_changed_date;
   svn_boolean_t last_changed_is_for_entry;
 
+ /* The fields for owner, group, and mode of this file */
+ svn_string_t *owner, *group, *mode;
+
   /* Bump information for the directory this file lives in */
   struct bump_dir_info *bump_info;
 
@@ -1694,7 +1698,19 @@ change_file_prop (void *file_baton,
         }
       if ( (strcmp (name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0) &&
            !fb->last_changed_is_for_entry)
         fb->last_changed_date = apr_pstrdup (fb->pool, value->data);
- }
+ if ( (strcmp (name, SVN_PROP_OWNER) == 0) )
+ {
+ fb->owner = svn_string_dup (value, fb->pool);
+ }
+ if ( (strcmp (name, SVN_PROP_GROUP) == 0) )
+ {
+ fb->group = svn_string_dup (value, fb->pool);
+ }
+ if ( (strcmp (name, SVN_PROP_UNIX_MODE) == 0) )
+ {
+ fb->mode = svn_string_dup (value, fb->pool);
+ }
+ }
 
   return SVN_NO_ERROR;
 }
@@ -2367,6 +2382,13 @@ close_file (void *file_baton,
                          fb->last_changed_date,
                          pool));
 
+ /* set owner, group, mode */
+ SVN_ERR (svn_io_file_set_file_owner_group_mode (fb->path,
+ fb->owner,
+ fb->group,
+ fb->mode,
+ pool) );
+
   /* We have one less referrer to the directory's bump information. */
   SVN_ERR (maybe_bump_dir_info (eb, fb->bump_info, pool));
 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Feb 1 08:07:10 2005

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.