You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by "Ph. Marek" <ph...@bmlv.gv.at> on 2005/02/01 07:05:56 UTC

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

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

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

Posted by "Ph. Marek" <ph...@bmlv.gv.at>.
Hello, Ben!

On Tuesday 01 February 2005 16:01, Ben Collins-Sussman wrote:
> On Feb 1, 2005, at 1:05 AM, Ph. Marek wrote:
> > 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.
>
> Wow, I know you've got a patch in that issue for preserving file
> timestamps in a property... but where did this extended idea come from?
>   I don't remember having discussed this.
Well, it's part of the (every now and then upcoming) idea of using svn as a 
backup-mechanism ... eg. for /etc, and similar things.

eg. take asvn, which exists at least since 2003.


Maybe you'd like to take over for Julian, who wanted to take a look at the 
patches in november? In that case, thanks a lot in advance !-)


Regards,

Phil

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by Ben Collins-Sussman <su...@collab.net>.
On Feb 1, 2005, at 1:05 AM, Ph. Marek wrote:

> 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.
>
>

Wow, I know you've got a patch in that issue for preserving file 
timestamps in a property... but where did this extended idea come from? 
  I don't remember having discussed this.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by John Peacock <jp...@rowman.com>.
Ph. Marek wrote:

>>We need a patch against trunk, not 1.1.3.
> 
> There you have me. It's not that simple for me to do that, as I'm behind a 
> firewall.

That shouldn't be much of a problem.  If your firewall includes an HTTP 
proxy that munges the WEBDav commands, you should be able to use HTTPS 
instead:

	https://svn.collab.net/repos/svn/

since an HTTPS connection can't be proxied.

HTH

John

-- 
John Peacock
Director of Information Research and Technology
Rowman & Littlefield Publishing Group
4501 Forbes Boulevard
Suite H
Lanham, MD  20706
301-459-3366 x.5010
fax 301-429-5748

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by Branko Čibej <br...@xbc.nu>.
Ph. Marek wrote:

>On Tuesday 08 February 2005 19:27, Philip Martin wrote:
>  
>
>On Tuesday 08 February 2005 19:50, C. Michael Pilato wrote:
>  
>
>>Is it considered in poor taste to register such a vague opinion such
>>as:
>>
>>   I think this "feature" is a horrendous idea.
>>
>>?
>>    
>>
>As I said, this patch ain't complete yet. And I'd like to get some discussion 
>going about the "how to do this" (for the people who need this) instead of 
>discussing if I really want this :-) Ok? Please??
>
>
>Please, try to see subversion in a bigger context than just software 
>development. It was a big leap to get use-commit-times; what I'm doing now is 
>just going further down that road.
>  
>

We've discussed this feature to death several times in the past. The 
decision was always that this is not the sort of thisn we want in the 
mainline code, with the suggestion to people who want this to work on a 
wrapper instead.

-- Brane


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by "Ph. Marek" <ph...@bmlv.gv.at>.
On Tuesday 08 February 2005 19:27, Philip Martin wrote:
> > The whole thing is currently triggered by auto-props and the config
> > option
>
> Auto-props are just a way of avoiding the need to run "svn propset".
Yes, you are right. The substitution of the property values is really 
triggered by the existence of the properties themselves, ie. if svn:group 
exists as a property, the file's group is set as value on commit.


> > "use-commit-times". If eg. a property "svn:owner" is set on a file, it
> > will be sent to the repository as the current value.
> > So you'd have in your ~/.subversion/config something like this:
> >  [auto-props]
> >  * = svn:text-time=yes;svn:owner=yes;svn:group=yes;svn:unix-mode=yes
> > or whatever values you'd like, and they'd be set on commit (and import).
>
> So the presence of svn:group say is not enough, I also need to have
> use-commit-times set?  That makes it different to svn:executable.  I
> don't like the overload of use-commit-times either.
use-commit-times is used _only_ to determine if the stored properties should 
be used on checkout/update.
The reason is that 
- for software development with make-invocations it is undesirable to use
  a stored modification time (because of the interactions with make) or the
  file's mode, and normally impossible to change the owner (nobody develops 
  software as uid 0).
  Here it possibly won't even make sense to *store* these properties.
- for some other purposes (archiving /etc, versioning /home, etc.) it is 
  *necessary* to store these informations - as they are needed for
  restauration.

Imagine restoring /etc or /home and having to manually restore the owners, 
groups and modes of the files ... 
Especially /etc with it's variety of owners and groups needs this.

Of course, it's possibly to save the other informations somewhere else ... 
say, "ls -laR /etc > /etc/.file_modes" and versioning that too. 
But that's not a clean way, IMO.


> How does svn:unix-mode interact with svn:executable?
>
> How does svn:unix-mode interact with umask?
The saved mode is applied after svn:executable, ie. it overwrites it, and 
ignores umask.

That's per design.
If I choose to save the mode of a file, it should be restored *as-is* and not 
modified by something else I might forget in the haste.


> >> - If I change the owner/group/mode of the working copy does this get
> >>   committed, or do I have to do an explicit propset?
> >
> > On every commit because of text-changes the properties are set to the
> > current values. Currently this happens *only* on text-changes, but read
> > below.
>
> I don't understand the your answer.
A file is choosen for commit because of text-changes.
*If* a file is going to be committed *and* the properties are set (to an 
arbitrary value), the value get's set to the file's state.

I grant you that this isn't strictly correct; if I just change the permission 
of a file it should be automatically found as a property change, and be 
committed as " U     file.txt".

This could be done by changing svn_wc__load_prop_file to check for this 
special properties and substitute the current values.


> If I have the unix-mode stuff enabled is a "chmod" sufficient to cause
> commit to store the new permissions or do I need to do an explicit
> "svn propset"?
A "chmod" is sufficient *if* (currently, see above) the file has been changed.


> What happens if I "svn propset" one value and chmod a different value,
> does one of the values get committed or is a conflict detected?
The value in the working copy is mostly ignored, it's just necessary that it 
exists.


> >> - I assume the owner/group/mode of the working copy files get set
> >>   during checkout, does it apply to directories as well?
> >
> > As I work with auto-properties, and these (currently) work only with
> > files. But I thought about implementing auto-dir-props too.
>
> Auto-props are just a way of avoiding "svn propset".  What happens if
> I "svn propset" one of your new properties on a directory?
It is left as-is and ignored. The patch currently just does files.
But you're right, directories have to have these versioned properties too.


> >> - If an update changes the owner/group/mode does it generate conflicts
> >>   with local changes, or do conflicts only occur if the wc properties
> >>   are modified?
> >
> > The conflict handling is currently unspecified.
> > But if these properties are handled like "svn:eol-style" (and cause a
> > re-translation of the file), the new values would be in effect
> > immediately.
> So if I do a chmod to have local modifications is "svn update" simply
> going to overwrite my changes?
That's a good question.
For my use-case I'd say yes, since the archived values have to have a higher 
preference.
(After all, /etc will be archived per-machine; an update of /etc is done 
mostly for recovery purposes, where the local state should be ignored.
Just the saved values are known to be valid).


On Tuesday 08 February 2005 19:50, C. Michael Pilato wrote:
> Is it considered in poor taste to register such a vague opinion such
> as:
>
>    I think this "feature" is a horrendous idea.
>
> ?
As I said, this patch ain't complete yet. And I'd like to get some discussion 
going about the "how to do this" (for the people who need this) instead of 
discussing if I really want this :-) Ok? Please??


Please, try to see subversion in a bigger context than just software 
development. It was a big leap to get use-commit-times; what I'm doing now is 
just going further down that road.


In the past 2 years we had on dev@ and users@ several questions and requests 
for this kind of automatic meta-data versioning. I believe there is demand 
for it. (Apart from that, I need it too :-)


Regards,

Phil

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by "C. Michael Pilato" <cm...@collab.net>.
Is it considered in poor taste to register such a vague opinion such
as:

   I think this "feature" is a horrendous idea.

?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by Philip Martin <ph...@codematters.co.uk>.
"Ph. Marek" <ph...@bmlv.gv.at> writes:

>> Please provide a short description of the behaviour you intend to
>> implement.  Some questions:
>>
>> - Is there a way to enable/disable the behaviour?
> The whole thing is currently triggered by auto-props and the config option 

Auto-props are just a way of avoiding the need to run "svn propset".

> "use-commit-times". If eg. a property "svn:owner" is set on a file, it will 
> be sent to the repository as the current value.
> So you'd have in your ~/.subversion/config something like this:
>  [auto-props]
>  * = svn:text-time=yes;svn:owner=yes;svn:group=yes;svn:unix-mode=yes
> or whatever values you'd like, and they'd be set on commit (and import).

So the presence of svn:group say is not enough, I also need to have
use-commit-times set?  That makes it different to svn:executable.  I
don't like the overload of use-commit-times either.

How does svn:unix-mode interact with svn:executable?

How does svn:unix-mode interact with umask?

>> - If I change the owner/group/mode of the working copy does this get
>>   committed, or do I have to do an explicit propset?
> On every commit because of text-changes the properties are set to the current 
> values. Currently this happens *only* on text-changes, but read below.

I don't understand the your answer.

If I have the unix-mode stuff enabled is a "chmod" sufficient to cause
commit to store the new permissions or do I need to do an explicit
"svn propset"?

What happens if I "svn propset" one value and chmod a different value,
does one of the values get committed or is a conflict detected?

>> - I assume the owner/group/mode of the working copy files get set
>>   during checkout, does it apply to directories as well?
> As I work with auto-properties, and these (currently) work only with files.
> But I thought about implementing auto-dir-props too.

Auto-props are just a way of avoiding "svn propset".  What happens if
I "svn propset" one of your new properties on a directory?

>> - Non-root Unix users cannot usually change ownership, does this cause
>>   lots of warnings or errors?
> No, this is silently ignored.
>
>> - Do updates modify the working copy owner/group/mode?
> I believe it does; but I'm not sure. I can't test at the moment.
>
>> - If an update changes the owner/group/mode does it generate conflicts
>>   with local changes, or do conflicts only occur if the wc properties
>>   are modified?
> The conflict handling is currently unspecified.
> But if these properties are handled like "svn:eol-style" (and cause a 
> re-translation of the file), the new values would be in effect immediately.

So if I do a chmod to have local modifications is "svn update" simply
going to overwrite my changes?

-- 
Philip Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by "Ph. Marek" <ph...@bmlv.gv.at>.
Hello Philip, 

I'm sorry for the delay.
I'll try to answer the questions you've sent; but I'll rearrange them a bit.

> Please provide a short description of the behaviour you intend to
> implement.  Some questions:
>
> - Is there a way to enable/disable the behaviour?
The whole thing is currently triggered by auto-props and the config option 
"use-commit-times". If eg. a property "svn:owner" is set on a file, it will 
be sent to the repository as the current value.
So you'd have in your ~/.subversion/config something like this:
 [auto-props]
 * = svn:text-time=yes;svn:owner=yes;svn:group=yes;svn:unix-mode=yes
or whatever values you'd like, and they'd be set on commit (and import).

> - If I change the owner/group/mode of the working copy does this get
>   committed, or do I have to do an explicit propset?
On every commit because of text-changes the properties are set to the current 
values. Currently this happens *only* on text-changes, but read below.

> - I assume the owner/group/mode of the working copy files get set
>   during checkout, does it apply to directories as well?
As I work with auto-properties, and these (currently) work only with files.
But I thought about implementing auto-dir-props too.

> - Non-root Unix users cannot usually change ownership, does this cause
>   lots of warnings or errors?
No, this is silently ignored.

> - Do updates modify the working copy owner/group/mode?
I believe it does; but I'm not sure. I can't test at the moment.

> - If an update changes the owner/group/mode does it generate conflicts
>   with local changes, or do conflicts only occur if the wc properties
>   are modified?
The conflict handling is currently unspecified.
But if these properties are handled like "svn:eol-style" (and cause a 
re-translation of the file), the new values would be in effect immediately.

> > 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)
>
> A rewrite has been mentioned, but that doesn't mean it is planned.
>
> > * subversion-1.1.3.tstamp/subversion/include/svn_io.h
>
> We need a patch against trunk, not 1.1.3.
There you have me. It's not that simple for me to do that, as I'm behind a 
firewall.


I know that these patches are not complete right now; saving 
directory-metadata needs some more work, and there'll be some other missing 
things too.


Regards,

Phil


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

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

Posted by Philip Martin <ph...@codematters.co.uk>.
"Ph. Marek" <ph...@bmlv.gv.at> writes:

> 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.

Please provide a short description of the behaviour you intend to
implement.  Some questions:

- I assume the owner/group/mode of the working copy files get set
  during checkout, does it apply to directories as well?

- Non-root Unix users cannot usually change ownership, does this cause
  lots of warnings or errors?

- Do updates modify the working copy owner/group/mode?

- If I change the owner/group/mode of the working copy does this get
  committed, or do I have to do an explicit propset?

- If an update changes the owner/group/mode does it generate conflicts
  with local changes, or do conflicts only occur if the wc properties
  are modified?

- Is there a way to enable/disable the behaviour?

> 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) 

A rewrite has been mentioned, but that doesn't mean it is planned.

> * subversion-1.1.3.tstamp/subversion/include/svn_io.h

We need a patch against trunk, not 1.1.3.

-- 
Philip Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org