Daniel Rall wrote:
> On Thu, 12 Oct 2006, Kamesh Jayachandran wrote:
>
>
>> Patch looks fine to me.
>> Let me leverage on it with the suggested change to fs_skel.
>>
>
> Sounds good, Kamesh. I'll commit the patch after you've made those
> changes.
>
> - Dan
>
Attaching the patch/log having the 'svn:txn-mergeinfo' as an atomic blob.
Focus on subversion/libsvn_fs_base/revs-txn.c alone as that alone
changed majorly in this new patch.
With regards
Kamesh Jayachandran
On the merge-tracking branch: Implement 'txn-mergeinfo' change,
storage and retrieval for 'bdb' repositories.
Store the transaction merge info as a temporary transaction property
(svn:txn-mergeinfo) with a value as 'serialized form of apr_hash_t'.
* subversion/libsvn_fs_base/dag.h
(svn_fs_base__dag_commit_txn): Change the signature to accept
"svn_fs_txn_t *" (needed by svn_fs_merge_info__update_index()).
From "svn_fs_txn_t *", derive "svn_fs_t *" and "const char
*txn_id" rather than passing them explicitly.
* subversion/libsvn_fs_base/tree.c
Include "svn_mergeinfo.h".
(struct change_merge_info_args): New structure used as the baton for
txn_body_change_merge_info().
(txn_body_change_merge_info): New helper function for
base_change_merge_info()'s usage of the svn_fs_base__retry_txn()
callback parameter.
(base_change_merge_info): New hook function implementing root_vtable_t's
"change_merge_info" hook.
(change_txn_merge_info): New function to update the transaction
merge info upon modification of the "svn:mergeinfo" property.
(txn_body_change_node_prop): Call change_txn_merge_info() if the
property getting modified is "svn:mergeinfo".
(txn_body_commit): Update for API change to svn_fs_base__dag_commit_txn().
(root_vtable): Set the "change_merge_info" hook to "base_change_merge_info".
* subversion/libsvn_fs_base/tree.h
Include "svn_props.h"
(SVN_FS_PROP_TXN_MERGEINFO): New macro.
* subversion/libsvn_fs_base/revs-txns.c
Include "svn_hash.h" "svn_io.h" for serializing the mergeinfo.
(svn_fs_base__set_txn_merge_info): New function to record the
transaction merge info.
(base_txn_merge_info): New function that retrieves the stored
transaction mergeinfo implementing txn_vtable_t->get_mergeinfo hook.
(txn_vtable): Set 'get_mergeinfo' hook to 'base_txn_merge_info'.
* subversion/libsvn_fs_base/revs-txns.h
(svn_fs_base__set_txn_merge_info): Add prototype.
* subversion/libsvn_fs_base/dag.c
Include "tree.h" and "private/svn_fs_merge_info.h".
(svn_fs_base__dag_commit_txn): Changed function signature. Record
merge info by calling svn_fs_merge_info__update_index().
Patch by: Kamesh Jayachandran <kamesh@collab.net>
(Tweaked by me.)
Index: subversion/libsvn_fs_base/tree.c
===================================================================
--- subversion/libsvn_fs_base/tree.c (revision 21898)
+++ subversion/libsvn_fs_base/tree.c (working copy)
@@ -38,6 +38,7 @@
#include "svn_error.h"
#include "svn_path.h"
#include "svn_md5.h"
+#include "svn_mergeinfo.h"
#include "svn_fs.h"
#include "svn_sorts.h"
#include "fs.h"
@@ -1281,7 +1282,48 @@
return SVN_NO_ERROR;
}
+/* The input for txn_body_change_merge_info(). */
+struct change_merge_info_args
+{
+ svn_fs_root_t *root;
+ const char *path;
+ const svn_string_t *value;
+};
+/* Set the merge info on the transaction in BATON (expected to be of
+ type "struct change_merge_info_args"). Conforms to the callback
+ API used by svn_fs_base__retry_txn(). */
+static svn_error_t *
+txn_body_change_merge_info(void *baton,
+ trail_t *trail)
+{
+ struct change_merge_info_args *args = baton;
+ SVN_ERR(svn_fs_base__set_txn_merge_info(args->root->fs, args->root->txn,
+ args->path, args->value,
+ trail, trail->pool));
+ return SVN_NO_ERROR;
+}
+
+/* Change the merge info for the specified PATH to MERGE_INFO. */
+static svn_error_t *
+base_change_merge_info(svn_fs_root_t *root,
+ const char *path,
+ apr_hash_t *merge_info,
+ apr_pool_t *pool)
+{
+ svn_stringbuf_t *minfostr;
+ struct change_merge_info_args args;
+
+ if (! root->is_txn_root)
+ return NOT_TXN(root);
+ SVN_ERR(svn_mergeinfo_to_string(&minfostr, merge_info, pool));
+ args.root = root;
+ args.path = path;
+ args.value = svn_string_create_from_buf(minfostr, pool);
+ return svn_fs_base__retry_txn(root->fs, txn_body_change_merge_info, &args,
+ pool);
+}
+
struct change_node_prop_args {
svn_fs_root_t *root;
const char *path;
@@ -1291,6 +1333,24 @@
static svn_error_t *
+change_txn_merge_info(struct change_node_prop_args *args, trail_t *trail)
+{
+ const char *txn_id = args->root->txn;
+
+ /* At least for single file merges, nodes which are direct
+ children of the root are received without a leading slash
+ (e.g. "/file.txt" is received as "file.txt"), so must be made
+ absolute. */
+ const char *canon_path = svn_fs_base__canonicalize_abspath(args->path,
+ trail->pool);
+ SVN_ERR(svn_fs_base__set_txn_merge_info(args->root->fs, txn_id, canon_path,
+ args->value, trail, trail->pool));
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
txn_body_change_node_prop(void *baton,
trail_t *trail)
{
@@ -1321,6 +1381,9 @@
if (! proplist)
proplist = apr_hash_make(trail->pool);
+ if (strcmp(args->name, SVN_PROP_MERGE_INFO) == 0)
+ SVN_ERR(change_txn_merge_info(args, trail));
+
/* Set the property. */
apr_hash_set(proplist, args->name, APR_HASH_KEY_STRING, args->value);
@@ -2382,8 +2445,8 @@
SVN_ERR(verify_locks(txn_name, trail, trail->pool));
/* Else, commit the txn. */
- SVN_ERR(svn_fs_base__dag_commit_txn(&(args->new_rev), fs, txn_name,
- trail, trail->pool));
+ SVN_ERR(svn_fs_base__dag_commit_txn(&(args->new_rev), txn, trail,
+ trail->pool));
return SVN_NO_ERROR;
}
@@ -4374,7 +4437,7 @@
base_contents_changed,
base_get_file_delta_stream,
base_merge,
- NULL,
+ base_change_merge_info,
svn_fs_merge_info__get_merge_info
};
Index: subversion/libsvn_fs_base/dag.h
===================================================================
--- subversion/libsvn_fs_base/dag.h (revision 21898)
+++ subversion/libsvn_fs_base/dag.h (working copy)
@@ -1,7 +1,7 @@
/* dag.h : DAG-like interface filesystem, private to libsvn_fs
*
* ====================================================================
- * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ * Copyright (c) 2000-2006 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
@@ -199,23 +199,22 @@
apr_pool_t *pool);
-/* Commit the transaction TXN_ID in FS, as part of TRAIL. Store the
+/* Commit the transaction TXN->id in TXN->FS, as part of TRAIL. Store the
new revision number in *NEW_REV. This entails:
- - marking the tree of mutable nodes at TXN_ID's root as immutable,
+ - marking the tree of mutable nodes at TXN->id's root as immutable,
and marking all their contents as stable
- - creating a new revision, with TXN_ID's root as its root directory
- - promoting TXN_ID to a "committed" transaction.
+ - creating a new revision, with TXN->id's root as its root directory
+ - promoting TXN->id to a "committed" transaction.
- Beware! This does not make sure that TXN_ID is based on the very
- latest revision in FS. If the caller doesn't take care of this,
+ Beware! This does not make sure that TXN->id is based on the very
+ latest revision in TXN->FS. If the caller doesn't take care of this,
you may lose people's work!
Do any necessary temporary allocation in a subpool of POOL.
Consume temporary space at most proportional to the maximum depth
of SVN_TXN's tree of mutable nodes. */
svn_error_t *svn_fs_base__dag_commit_txn(svn_revnum_t *new_rev,
- svn_fs_t *fs,
- const char *txn_id,
+ svn_fs_txn_t *txn,
trail_t *trail,
apr_pool_t *pool);
Index: subversion/libsvn_fs_base/tree.h
===================================================================
--- subversion/libsvn_fs_base/tree.h (revision 21898)
+++ subversion/libsvn_fs_base/tree.h (working copy)
@@ -1,7 +1,7 @@
/* tree.h : internal interface to tree node functions
*
* ====================================================================
- * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ * Copyright (c) 2000-2006 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
@@ -22,6 +22,12 @@
extern "C" {
#endif /* __cplusplus */
+#include "svn_props.h"
+
+/* A transaction property which maps to a skel form of apr_hash_t
+ (target wc path char * -> actual merge info). */
+#define SVN_FS_PROP_TXN_MERGEINFO SVN_PROP_PREFIX "txn-mergeinfo"
+
/* These functions implement some of the calls in the FS loader
Index: subversion/libsvn_fs_base/revs-txns.c
===================================================================
--- subversion/libsvn_fs_base/revs-txns.c (revision 21898)
+++ subversion/libsvn_fs_base/revs-txns.c (working copy)
@@ -1,7 +1,7 @@
/* revs-txns.c : operations on revision and transactions
*
* ====================================================================
- * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ * Copyright (c) 2000-2006 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
@@ -25,6 +25,8 @@
#include "svn_time.h"
#include "svn_fs.h"
#include "svn_props.h"
+#include "svn_hash.h"
+#include "svn_io.h"
#include "fs.h"
#include "dag.h"
@@ -558,7 +560,65 @@
return put_txn(fs, txn, txn_name, trail, pool);
}
+svn_error_t *
+svn_fs_base__set_txn_merge_info(svn_fs_t *fs,
+ const char *txn_name,
+ const char *path,
+ const svn_string_t *value,
+ trail_t *trail,
+ apr_pool_t *pool)
+{
+ transaction_t *txn;
+ apr_hash_t *target_mergeinfo;
+ svn_stringbuf_t* serialized_stringbuf;
+ const svn_string_t* serialized_string;
+ svn_stream_t *stream;
+ SVN_ERR(get_txn(&txn, fs, txn_name, FALSE, trail, pool));
+ if (txn->kind != transaction_kind_normal)
+ return svn_fs_base__err_txn_not_mutable(fs, txn_name);
+
+ if (txn->proplist == NULL)
+ {
+ /* If we're deleting a property, exit now. Otherwise, create a
+ proplist. */
+ if (value == NULL)
+ return SVN_NO_ERROR;
+
+ txn->proplist = apr_hash_make(pool);
+ }
+
+ target_mergeinfo = apr_hash_make(pool);
+ serialized_string = apr_hash_get(txn->proplist, SVN_FS_PROP_TXN_MERGEINFO,
+ APR_HASH_KEY_STRING);
+ if (serialized_string)
+ {
+ serialized_stringbuf = svn_stringbuf_create_from_string(serialized_string,
+ pool);
+ stream = svn_stream_from_stringbuf(serialized_stringbuf, pool);
+ SVN_ERR(svn_hash_read2(target_mergeinfo, stream, NULL, pool));
+ }
+ else
+ {
+ serialized_stringbuf = svn_stringbuf_create("", pool);
+ stream = svn_stream_from_stringbuf(serialized_stringbuf, pool);
+ }
+
+ /* Set the mergeinfo for the path. */
+ apr_hash_set(target_mergeinfo, path, APR_HASH_KEY_STRING, value);
+
+ /* Serialize the hash for storage. */
+ SVN_ERR(svn_hash_write2(target_mergeinfo, stream, NULL, pool));
+ serialized_string = svn_string_create_from_buf(serialized_stringbuf, pool);
+
+ /* Set the property. */
+ apr_hash_set(txn->proplist, SVN_FS_PROP_TXN_MERGEINFO,
+ APR_HASH_KEY_STRING, serialized_string);
+
+ /* Now overwrite the transaction. */
+ return put_txn(fs, txn, txn_name, trail, pool);
+}
+
static svn_error_t *
txn_body_change_txn_prop(void *baton, trail_t *trail)
{
@@ -587,7 +647,46 @@
return SVN_NO_ERROR;
}
+/* txn_vtable's get_mergeinfo hook. Set TABLE_P to a merge info hash
+ (possibly empty), or NULL if there are no transaction
+ properties. */
+static svn_error_t *
+base_txn_merge_info(apr_hash_t **table_p,
+ svn_fs_txn_t *txn,
+ apr_pool_t *pool)
+{
+ apr_hash_t *txnprops = NULL;
+ apr_hash_t *target_mergeinfo = NULL;
+ struct txn_proplist_args args;
+ svn_fs_t *fs = txn->fs;
+ SVN_ERR(svn_fs_base__check_fs(fs));
+
+ args.table_p = &txnprops;
+ args.id = txn->id;
+ SVN_ERR(svn_fs_base__retry(fs, txn_body_txn_proplist, &args, pool));
+
+ if (txnprops)
+ {
+ const svn_string_t *serialized_string = apr_hash_get(txnprops,
+ SVN_FS_PROP_TXN_MERGEINFO,
+ APR_HASH_KEY_STRING);
+ if (serialized_string)
+ {
+ target_mergeinfo = apr_hash_make(pool);
+ svn_stringbuf_t* serialized_stringbuf =
+ svn_stringbuf_create_from_string(serialized_string, pool);
+ svn_stream_t *stream = svn_stream_from_stringbuf(serialized_stringbuf,
+ pool);
+ SVN_ERR(svn_hash_read2(target_mergeinfo, stream, NULL, pool));
+ }
+ }
+ *table_p = target_mergeinfo;
+
+ return SVN_NO_ERROR;
+}
+
+
/* Creating a transaction */
@@ -598,7 +697,7 @@
svn_fs_base__txn_proplist,
svn_fs_base__change_txn_prop,
svn_fs_base__txn_root,
- NULL
+ base_txn_merge_info
};
Index: subversion/libsvn_fs_base/revs-txns.h
===================================================================
--- subversion/libsvn_fs_base/revs-txns.h (revision 21898)
+++ subversion/libsvn_fs_base/revs-txns.h (working copy)
@@ -1,7 +1,7 @@
/* revs-txns.h : internal interface to revision and transactions operations
*
* ====================================================================
- * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ * Copyright (c) 2000-2006 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
@@ -144,6 +144,20 @@
apr_pool_t *pool);
+/* Set a PATH to VALUE for the SVN_FS_PROP_TXN_MERGEINFO property (a
+ hash table) on transaction TXN_NAME's proplist in FS as part of
+ TRAIL. Use POOL for any necessary allocations.
+
+ Return SVN_ERR_FS_TRANSACTION_NOT_MUTABLE if TXN_NAME refers to a
+ transaction that has already been committed. */
+svn_error_t *
+svn_fs_base__set_txn_merge_info(svn_fs_t *fs,
+ const char *txn_name,
+ const char *path,
+ const svn_string_t *value,
+ trail_t *trail,
+ apr_pool_t *pool);
+
/* Set a property NAME to VALUE on transaction TXN_NAME in FS as part
of TRAIL. Use POOL for any necessary allocations.
Index: subversion/libsvn_fs_base/dag.c
===================================================================
--- subversion/libsvn_fs_base/dag.c (revision 21898)
+++ subversion/libsvn_fs_base/dag.c (working copy)
@@ -1,7 +1,7 @@
/* dag.c : DAG-like interface filesystem, private to libsvn_fs
*
* ====================================================================
- * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ * Copyright (c) 2000-2006 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
@@ -34,6 +34,7 @@
#include "reps-strings.h"
#include "revs-txns.h"
#include "id.h"
+#include "tree.h" /* needed for SVN_FS_PROP_TXN_MERGEINFO */
#include "util/fs_skels.h"
@@ -44,6 +45,7 @@
#include "bdb/reps-table.h"
#include "bdb/strings-table.h"
+#include "private/svn_fs_merge_info.h"
#include "../libsvn_fs/fs-loader.h"
#include "svn_private_config.h"
@@ -1416,18 +1418,35 @@
svn_error_t *
svn_fs_base__dag_commit_txn(svn_revnum_t *new_rev,
- svn_fs_t *fs,
- const char *txn_id,
+ svn_fs_txn_t *txn,
trail_t *trail,
apr_pool_t *pool)
{
revision_t revision;
svn_string_t date;
apr_hash_t *txnprops;
+ svn_fs_t *fs = txn->fs;
+ const char *txn_id = txn->id;
+ const svn_string_t *target_mergeinfo;
/* Remove any temporary transaction properties initially created by
begin_txn(). */
SVN_ERR(svn_fs_base__txn_proplist_in_trail(&txnprops, txn_id, trail));
+
+ /* Add new revision entry to `revisions' table. */
+ revision.txn_id = txn_id;
+ *new_rev = SVN_INVALID_REVNUM;
+ SVN_ERR(svn_fs_bdb__put_rev(new_rev, fs, &revision, trail, pool));
+
+ target_mergeinfo = apr_hash_get(txnprops, SVN_FS_PROP_TXN_MERGEINFO,
+ APR_HASH_KEY_STRING);
+ if (target_mergeinfo)
+ {
+ SVN_ERR(svn_fs_merge_info__update_index(txn, *new_rev, TRUE, pool));
+ SVN_ERR(svn_fs_base__set_txn_prop
+ (fs, txn_id, SVN_FS_PROP_TXN_MERGEINFO, NULL, trail, pool));
+ }
+
if (txnprops)
{
if (apr_hash_get(txnprops, SVN_FS_PROP_TXN_CHECK_OOD,
@@ -1440,12 +1459,6 @@
SVN_ERR(svn_fs_base__set_txn_prop
(fs, txn_id, SVN_FS_PROP_TXN_CHECK_LOCKS, NULL, trail, pool));
}
-
- /* Add new revision entry to `revisions' table. */
- revision.txn_id = txn_id;
- *new_rev = SVN_INVALID_REVNUM;
- SVN_ERR(svn_fs_bdb__put_rev(new_rev, fs, &revision, trail, pool));
-
/* Promote the unfinished transaction to a committed one. */
SVN_ERR(svn_fs_base__txn_make_committed(fs, txn_id, *new_rev,
trail, pool));
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Oct 13 18:02:47 2006