You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/12/10 12:20:26 UTC
svn commit: r1719065 - in /subversion/branches/ra-git/subversion:
libsvn_ra_git/commit.c libsvn_ra_git/fetch.c libsvn_ra_git/ra_git.h
libsvn_ra_git/session.c tests/libsvn_client/git-client-test.c
Author: rhuijben
Date: Thu Dec 10 11:20:26 2015
New Revision: 1719065
URL: http://svn.apache.org/viewvc?rev=1719065&view=rev
Log:
On the ra-git branch: Following up on r1719060, commit the actual changes.
* subversion/libsvn_ra_git/commit.c
New file.
* subversion/libsvn_ra_git/fetch.c
(includes): Add ../libsvn_fs_git/svn_git.h.
(cleanup_git_repos): Remove function.
(svn_ra_git__push_commit): New function.
(open_git_repos): Update caller.
* subversion/libsvn_ra_git/ra_git.h
(svn_ra_git__wrap_git_error,
GIT2_ERR,
GIT2_ERR_NOTFOUND): Remove here.
(svn_ra_git__push_commit,
svn_ra_git__get_commit_editor): New function.
* subversion/libsvn_ra_git/session.c
(ra_git_get_commit_editor): Add implementation.
* subversion/tests/libsvn_client/git-client-test.c
New file.
Added:
subversion/branches/ra-git/subversion/libsvn_ra_git/commit.c (with props)
subversion/branches/ra-git/subversion/tests/libsvn_client/git-client-test.c (with props)
Modified:
subversion/branches/ra-git/subversion/libsvn_ra_git/fetch.c
subversion/branches/ra-git/subversion/libsvn_ra_git/ra_git.h
subversion/branches/ra-git/subversion/libsvn_ra_git/session.c
Added: subversion/branches/ra-git/subversion/libsvn_ra_git/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_git/commit.c?rev=1719065&view=auto
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_git/commit.c (added)
+++ subversion/branches/ra-git/subversion/libsvn_ra_git/commit.c Thu Dec 10 11:20:26 2015
@@ -0,0 +1,551 @@
+/*
+ * commit.c : Handles some commit scenarios to a libsvn_fs_git backend.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include "../libsvn_fs_git/svn_git.h"
+
+#include "svn_hash.h"
+#include "svn_dirent_uri.h"
+#include "svn_ra.h"
+#include "svn_repos.h"
+#include "svn_fs.h"
+#include "svn_pools.h"
+#include "svn_props.h"
+#include "svn_delta.h"
+
+#include "svn_private_config.h"
+#include "../libsvn_ra/ra_loader.h"
+#include "private/svn_atomic.h"
+#include "private/svn_fspath.h"
+
+#include "ra_git.h"
+
+typedef struct git_commit_edit_baton_t
+{
+ apr_pool_t *pool;
+ svn_ra_session_t *session;
+ svn_ra_git__session_t *sess;
+
+ svn_repos_t *repos;
+ svn_fs_root_t *root;
+ svn_revnum_t created_rev;
+
+ git_repository *repository;
+ const git_commit *commit;
+
+ svn_boolean_t aborted, done;
+
+ svn_commit_callback2_t commit_cb;
+ void *commit_baton;
+
+ apr_hash_t *revprops;
+
+ svn_boolean_t tag_mode;
+ svn_boolean_t change_mode;
+
+ const char *root_path;
+
+ svn_boolean_t tree_written;
+ git_oid tree_oid;
+
+} git_commit_edit_baton_t;
+
+typedef struct git_commit_node_baton_t
+{
+ struct git_commit_node_baton_t *pb;
+ git_commit_edit_baton_t *eb;
+
+ apr_pool_t *pool;
+
+ svn_fs_root_t *root;
+ const char *node_path;
+
+ git_treebuilder *dir_builder;
+ svn_boolean_t added;
+
+} git_commit_node_baton_t;
+
+static svn_error_t *
+setup_change_trees(git_commit_node_baton_t *db,
+ apr_pool_t *scratch_pool)
+{
+ if (db->dir_builder)
+ return SVN_NO_ERROR;
+
+ if (db->pb && !db->pb->dir_builder)
+ SVN_ERR(setup_change_trees(db->pb, scratch_pool));
+
+ if (db->pb && db->pb->dir_builder)
+ {
+ const git_tree_entry *entry;
+ const git_tree *tree = NULL;
+ entry = git_treebuilder_get(db->dir_builder,
+ svn_relpath_basename(db->node_path, NULL));
+
+ if (entry)
+ {
+ const git_object *obj;
+
+ SVN_ERR(svn_git__tree_entry_to_object(&obj, db->eb->repository,
+ entry, db->pool));
+
+ tree = (const git_tree*)obj;
+ }
+
+ SVN_ERR(svn_git__treebuilder_new(&db->dir_builder, db->eb->repository, tree,
+ db->pool));
+ return SVN_NO_ERROR;
+ }
+
+ if (!db->node_path[0])
+ return SVN_NO_ERROR; /* Creating 'trunk' */
+
+ if (strcmp(db->eb->root_path, db->node_path))
+ {
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+ensure_mutable(git_commit_node_baton_t *nb,
+ const char *path,
+ svn_revnum_t base_rev,
+ apr_pool_t *scratch_pool)
+{
+ git_commit_edit_baton_t *eb = nb->eb;
+
+ if (!path)
+ path = nb->node_path;
+ else
+ path = svn_relpath_join(nb->node_path,
+ svn_relpath_basename(path, NULL),
+ scratch_pool);
+
+ if (!(eb->tag_mode || eb->change_mode))
+ {
+ if (svn_relpath_skip_ancestor("trunk", path))
+ {
+ eb->change_mode = TRUE;
+ eb->root_path = "trunk";
+ }
+ else if (svn_relpath_skip_ancestor("branches", path))
+ {
+ if (strlen(path) > 8)
+ {
+ eb->change_mode = TRUE;
+ eb->root_path = svn_relpath_prefix(path, 2, eb->pool);
+ }
+ else
+ {
+ eb->tag_mode = TRUE;
+ eb->root_path = "branches";
+ }
+ }
+ else if (!strcmp("tags", path))
+ {
+ eb->tag_mode = TRUE;
+ eb->root_path = "tags";
+ }
+ else
+ return svn_error_createf(SVN_ERR_RA_NOT_IMPLEMENTED, NULL,
+ _("Can't commit directly to '%s' "
+ "in a git repository"),
+ path);
+
+ if (eb->change_mode)
+ {
+ svn_revnum_t youngest;
+ svn_fs_t *fs;
+ const git_tree *tree = NULL;
+
+ SVN_ERR(svn_repos_open3(&eb->repos, eb->sess->local_repos_abspath, NULL,
+ eb->pool, scratch_pool));
+
+ fs = svn_repos_fs(eb->repos);
+ SVN_ERR(svn_fs_youngest_rev(&youngest, fs, scratch_pool));
+
+ SVN_ERR(svn_fs_revision_root(&eb->root, fs, youngest, scratch_pool));
+
+ SVN_ERR(svn_fs_node_created_rev(&eb->created_rev, eb->root,
+ eb->root_path, scratch_pool));
+
+ SVN_ERR(svn_git__repository_open(&eb->repository,
+ svn_dirent_join(
+ eb->sess->local_repos_abspath,
+ "db/git", scratch_pool),
+ eb->pool));
+
+ if (eb->created_rev > 0)
+ {
+ svn_string_t *oid_value;
+
+ SVN_ERR(svn_fs_revision_prop2(&oid_value, fs, eb->created_rev,
+ "svn:git-commit-id", FALSE,
+ scratch_pool, scratch_pool));
+
+ if (oid_value)
+ {
+ git_oid oid;
+
+ GIT2_ERR(git_oid_fromstr(&oid, oid_value->data));
+
+ SVN_ERR(svn_git__commit_lookup(&eb->commit, eb->repository,
+ &oid, eb->pool));
+
+ if (eb->commit)
+ SVN_ERR(svn_git__commit_tree(&tree, eb->commit, eb->pool));
+ }
+ }
+ else
+ tree = NULL;
+
+ SVN_ERR(setup_change_trees(nb, scratch_pool));
+ }
+ }
+
+ if (eb->change_mode)
+ {
+ if (!svn_relpath_skip_ancestor(eb->root_path, path))
+ return svn_error_createf(SVN_ERR_RA_NOT_IMPLEMENTED, NULL,
+ _("Can't commit to '%s' and '%s' in one commit"),
+ eb->root_path, path);
+ }
+ else
+ {
+ const char *rp = svn_relpath_skip_ancestor(eb->root_path, path);
+
+ if (!rp || !*rp || strchr(rp, '/'))
+ return svn_error_createf(SVN_ERR_RA_NOT_IMPLEMENTED, NULL,
+ _("Can't tag to '%s'"), path);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+git_commit__open_root(void *edit_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *result_pool,
+ void **root_baton)
+{
+ git_commit_node_baton_t *nb = apr_pcalloc(result_pool, sizeof(*nb));
+ nb->eb = edit_baton;
+ nb->pool = result_pool;
+
+ nb->node_path = svn_uri_skip_ancestor(nb->eb->sess->repos_root_url,
+ nb->eb->sess->session_url_buf->data,
+ result_pool);
+
+ *root_baton = nb;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+git_commit__delete_entry(const char *path,
+ svn_revnum_t revision,
+ void *parent_baton,
+ apr_pool_t *scratch_pool)
+{
+ git_commit_node_baton_t *pb = parent_baton;
+
+ SVN_ERR(ensure_mutable(pb, path, revision, scratch_pool));
+
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__add_directory(const char *path,
+ void *parent_baton,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_revision,
+ apr_pool_t *result_pool,
+ void **child_baton)
+{
+ git_commit_node_baton_t *pb = parent_baton;
+ git_commit_edit_baton_t *eb = pb->eb;
+ git_commit_node_baton_t *db;
+ const char *relpath;
+
+ SVN_ERR(ensure_mutable(pb, path, SVN_INVALID_REVNUM,
+ result_pool));
+
+ if (!pb->eb->change_mode)
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+
+ db = apr_pcalloc(result_pool, sizeof(*db));
+ db->pb = pb;
+ db->eb = eb;
+ db->pool = result_pool;
+ db->node_path = svn_relpath_join(pb->node_path,
+ svn_relpath_basename(path, NULL),
+ result_pool);
+
+ relpath = svn_relpath_skip_ancestor(eb->root_path, db->node_path);
+
+ *child_baton = db;
+
+ SVN_ERR(svn_git__treebuilder_new(&db->dir_builder, db->eb->repository, NULL,
+ result_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+git_commit__open_directory(const char *path,
+ void *parent_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *result_pool,
+ void **child_baton)
+{
+ git_commit_node_baton_t *pb = parent_baton;
+
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__change_dir_prop(void *dir_baton,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *scratch_pool)
+{
+ git_commit_node_baton_t *db = dir_baton;
+
+ SVN_ERR(ensure_mutable(db, NULL, SVN_INVALID_REVNUM,
+ scratch_pool));
+
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__close_directory(void *dir_baton,
+ apr_pool_t *scratch_pool)
+{
+ git_commit_node_baton_t *db = dir_baton;
+
+ if (db->dir_builder)
+ {
+ git_oid oid;
+
+ GIT2_ERR(git_treebuilder_write(&oid, db->dir_builder));
+
+ if (db->pb && db->pb->dir_builder)
+ GIT2_ERR(git_treebuilder_insert(NULL, db->pb->dir_builder,
+ svn_relpath_basename(db->node_path,
+ NULL),
+ &oid, GIT_FILEMODE_TREE));
+ else if (!strcmp(db->node_path, db->eb->root_path))
+ {
+ db->eb->tree_oid = oid;
+ db->eb->tree_written = TRUE;
+ }
+ }
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+git_commit__add_file(const char *path,
+ void *parent_baton,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_revision,
+ apr_pool_t *result_pool,
+ void **file_baton)
+{
+ git_commit_node_baton_t *pb = parent_baton;
+
+ SVN_ERR(ensure_mutable(pb, path, SVN_INVALID_REVNUM,
+ result_pool));
+
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__open_file(const char *path,
+ void *parent_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *result_pool,
+ void **file_baton)
+{
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__apply_textdelta(void *file_baton,
+ const char *base_checksum,
+ apr_pool_t *result_pool,
+ svn_txdelta_window_handler_t *handler,
+ void **handler_baton)
+{
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__change_file_prop(void *file_baton,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__close_file(void *file_baton,
+ const char *text_checksum,
+ apr_pool_t *scratch_pool)
+{
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+git_commit__close_edit(void *edit_baton,
+ apr_pool_t *scratch_pool)
+{
+ git_commit_edit_baton_t *eb = edit_baton;
+
+ if (eb->done || eb->aborted)
+ return SVN_NO_ERROR;
+
+ if (eb->tree_written)
+ {
+ git_oid commit_oid;
+ git_signature *author;
+ int git_err;
+ svn_string_t *log_value;
+ svn_error_t *err;
+ const char *ref = svn_relpath_join("refs/tmp",
+ svn_uuid_generate(scratch_pool),
+ scratch_pool);
+ const git_tree *tree;
+
+ SVN_ERR(svn_git__tree_lookup(&tree, eb->repository, &eb->tree_oid,
+ scratch_pool));
+
+ git_err = git_signature_default(&author, eb->repository);
+ if (git_err != GIT_ENOTFOUND)
+ GIT2_ERR(git_err);
+ else
+ {
+ /* ### TODO: Fetch something better */
+ GIT2_ERR(git_signature_now(&author, "svn-dummy",
+ "svn-dummy@subversion.tigris.org"));
+ }
+
+ log_value = svn_hash_gets(eb->revprops, SVN_PROP_REVISION_LOG);
+
+ git_err = git_commit_create(&commit_oid, eb->repository, ref,
+ author, author,
+ "UTF-8",
+ log_value ? log_value->data : "",
+ tree,
+ eb->commit ? 1 : 0,
+ eb->commit ? &eb->commit : NULL);
+
+ git_signature_free(author);
+ GIT2_ERR(git_err);
+
+ /* Ok, we now have a commit... Let's push it to the actual server.
+
+ We can then fetch it back and return the revision of to the result */
+ err = svn_error_trace(
+ svn_ra_git__push_commit(eb->session,
+ ref, eb->root_path, &commit_oid,
+ eb->commit_cb, eb->commit_baton,
+ scratch_pool));
+
+ if (err)
+ {
+ git_reference_remove(eb->repository, ref);
+ giterr_clear();
+ }
+
+ eb->done = TRUE;
+ svn_pool_destroy(eb->pool);
+
+ return err;
+ }
+
+ //if (eb->treebuilder)
+ // {
+ // git_oid oid;
+ //
+ // GIT2_ERR(git_treebuilder_write(&oid, eb->treebuilder));
+ // }
+
+ return svn_error_create(APR_ENOTIMPL, NULL, NULL);
+}
+
+static svn_error_t *
+git_commit__abort_edit(void *edit_baton,
+ apr_pool_t *scratch_pool)
+{
+ git_commit_edit_baton_t *eb = edit_baton;
+ eb->aborted = TRUE;
+
+ if (!eb->done)
+ {
+ eb->done = TRUE;
+ svn_pool_destroy(eb->pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_git__get_commit_editor(const svn_delta_editor_t **editor_p,
+ void **edit_baton_p,
+ svn_ra_session_t *session,
+ apr_hash_t *revprop_table,
+ svn_commit_callback2_t callback,
+ void *callback_baton,
+ apr_pool_t *pool)
+{
+ svn_ra_git__session_t *sess = session->priv;
+ git_commit_edit_baton_t *eb = apr_pcalloc(pool, sizeof(*eb));
+ svn_delta_editor_t *editor = svn_delta_default_editor(pool);
+
+ eb->pool = svn_pool_create(pool);
+ eb->revprops = revprop_table;
+ eb->commit_cb = callback;
+ eb->commit_baton = callback_baton;
+ eb->session = session;
+ eb->sess = sess;
+
+ editor->open_root = git_commit__open_root;
+ editor->delete_entry = git_commit__delete_entry;
+ editor->add_directory = git_commit__add_directory;
+ editor->open_directory = git_commit__open_directory;
+ editor->change_dir_prop = git_commit__change_dir_prop;
+ editor->close_directory = git_commit__close_directory;
+ editor->add_file = git_commit__add_file;
+ editor->open_file = git_commit__open_file;
+ editor->change_file_prop = git_commit__change_file_prop;
+ editor->apply_textdelta = git_commit__apply_textdelta;
+ editor->close_file = git_commit__close_file;
+
+ editor->close_edit = git_commit__close_edit;
+ editor->abort_edit = git_commit__abort_edit;
+
+ *editor_p = editor;
+ *edit_baton_p = eb;
+ return SVN_NO_ERROR;
+}
Propchange: subversion/branches/ra-git/subversion/libsvn_ra_git/commit.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/ra-git/subversion/libsvn_ra_git/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_git/fetch.c?rev=1719065&r1=1719064&r2=1719065&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_git/fetch.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_git/fetch.c Thu Dec 10 11:20:26 2015
@@ -22,9 +22,7 @@
* ====================================================================
*/
-#include <apr.h>
-
-#include <git2.h>
+#include "../libsvn_fs_git/svn_git.h"
#include "svn_hash.h"
#include "svn_ra.h"
@@ -78,13 +76,6 @@ svn_ra_git__wrap_git_error(void)
}
static apr_status_t
-cleanup_git_repos(void *baton)
-{
- git_repository_free(baton);
- return APR_SUCCESS;
-}
-
-static apr_status_t
cleanup_git_remote(void *baton)
{
git_remote_free(baton);
@@ -287,6 +278,64 @@ svn_ra_git__git_fetch(svn_ra_session_t *
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_ra_git__push_commit(svn_ra_session_t *session,
+ const char *reference,
+ const char *edit_relpath,
+ const struct git_oid *commit_oid,
+ svn_commit_callback2_t callback,
+ void *callback_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_git__session_t *sess = session->priv;
+ git_repository *repos;
+ git_remote *remote;
+ git_remote_callbacks *callbacks;
+ apr_pool_t *subpool;
+
+ /* Create subpool, to allow closing handles early on */
+ subpool = svn_pool_create(scratch_pool);
+
+ SVN_ERR(open_git_repos(&repos, &remote, &callbacks, sess,
+ subpool, subpool));
+
+ SVN_DBG(("Pushing to %s\n", sess->git_remote_url));
+
+ {
+ git_push_options push_opts = GIT_PUSH_OPTIONS_INIT;
+ git_strarray refspecs;
+ char *refspec;
+ refspecs.count = 1;
+ refspecs.strings = &refspec;
+
+ push_opts.callbacks = *callbacks;
+ refspec = apr_pstrcat(scratch_pool, "+", reference, ":refs/heads/master",
+ SVN_VA_NULL);
+
+ GIT2_ERR(git_remote_push(remote, &refspecs, &push_opts));
+ }
+
+ svn_pool_clear(subpool);
+
+ SVN_ERR(svn_ra_git__git_fetch(session, TRUE, subpool));
+
+ if (callback)
+ {
+ svn_commit_info_t *info = svn_create_commit_info(subpool);
+
+ info->author = "Q";
+ info->date = svn_time_to_cstring(apr_time_now(), subpool);
+
+ SVN_ERR(sess->local_session->vtable->get_latest_revnum(
+ sess->local_session, &info->revision,
+ subpool));
+
+ SVN_ERR(callback(info, callback_baton, scratch_pool));
+ }
+
+ svn_pool_destroy(subpool);
+ return SVN_NO_ERROR;
+}
/* Fetch a username for use with SESS */
@@ -669,13 +718,10 @@ open_git_repos(git_repository **repos,
SVN_ERR(svn_atomic__init_once(&do_libgit2_init_called, do_libgit2_init,
NULL, scratch_pool));
- GIT2_ERR(git_repository_open(repos,
- svn_dirent_join(sess->local_repos_abspath,
- "db/git", scratch_pool)));
-
- if (*repos)
- apr_pool_cleanup_register(result_pool, *repos, cleanup_git_repos,
- apr_pool_cleanup_null);
+ SVN_ERR(svn_git__repository_open(repos,
+ svn_dirent_join(sess->local_repos_abspath,
+ "db/git", scratch_pool),
+ result_pool));
if (remote)
{
Modified: subversion/branches/ra-git/subversion/libsvn_ra_git/ra_git.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_git/ra_git.h?rev=1719065&r1=1719064&r2=1719065&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_git/ra_git.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_git/ra_git.h Thu Dec 10 11:20:26 2015
@@ -63,27 +63,6 @@ typedef struct svn_ra_git__session_t
apr_uint64_t progress_bytes;
} svn_ra_git__session_t;
-svn_error_t *
-svn_ra_git__wrap_git_error(void);
-
-#define GIT2_ERR(expr) \
- do { \
- int svn_err__git_temp = (expr); \
- if (svn_err__git_temp) \
- return svn_ra_git__wrap_git_error(); \
- } while (0)
-
-#define GIT2_ERR_NOTFOUND(x, expr) \
- do { \
- int svn_err__git_temp = (expr); \
- if (svn_err__git_temp == GIT_ENOTFOUND) \
- { \
- giterr_clear(); \
- *x = NULL; \
- } \
- else if (svn_err__git_temp) \
- return svn_ra_git__wrap_git_error(); \
- } while (0)
/* Git repositories don't have a UUID so a static UUID is as good as any. */
#define RA_GIT_UUID "a62d4ba0-b83e-11e3-8621-8f162a3365eb"
@@ -112,6 +91,26 @@ svn_ra_git__git_fetch(svn_ra_session_t *
svn_boolean_t refresh,
apr_pool_t *scratch_pool);
+struct git_oid;
+
+svn_error_t *
+svn_ra_git__push_commit(svn_ra_session_t *session,
+ const char *reference,
+ const char *edit_relpath,
+ const struct git_oid *commit_oid,
+ svn_commit_callback2_t callback,
+ void *callback_baton,
+ apr_pool_t *scratch_pool);
+
+svn_error_t *
+svn_ra_git__get_commit_editor(const svn_delta_editor_t **editor,
+ void **edit_baton,
+ svn_ra_session_t *session,
+ apr_hash_t *revprop_table,
+ svn_commit_callback2_t callback,
+ void *callback_baton,
+ apr_pool_t *pool);
+
void
svn_ra_git__libgit2_version(int *major,
int *minor,
Modified: subversion/branches/ra-git/subversion/libsvn_ra_git/session.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_git/session.c?rev=1719065&r1=1719064&r2=1719065&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_git/session.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_git/session.c Thu Dec 10 11:20:26 2015
@@ -570,7 +570,16 @@ ra_git_get_commit_editor(svn_ra_session_
svn_boolean_t keep_locks,
apr_pool_t *pool)
{
- return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, NULL, NULL);
+ svn_ra_git__session_t *sess = session->priv;
+
+ SVN_ERR(ensure_local_session(session, pool));
+ SVN_ERR(svn_ra_git__git_fetch(session, TRUE, sess->scratch_pool));
+
+ return svn_error_trace(
+ svn_ra_git__get_commit_editor(editor, edit_baton,
+ session, revprop_table,
+ callback, callback_baton,
+ pool));
}
Added: subversion/branches/ra-git/subversion/tests/libsvn_client/git-client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/tests/libsvn_client/git-client-test.c?rev=1719065&view=auto
==============================================================================
--- subversion/branches/ra-git/subversion/tests/libsvn_client/git-client-test.c (added)
+++ subversion/branches/ra-git/subversion/tests/libsvn_client/git-client-test.c Thu Dec 10 11:20:26 2015
@@ -0,0 +1,196 @@
+/*
+* Regression tests for logic in the libsvn_client library.
+*
+* ====================================================================
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+* ====================================================================
+*/
+
+#include "svn_pools.h"
+#include "svn_client.h"
+#include "private/svn_client_mtcc.h"
+
+#include "svn_repos.h"
+#include "svn_subst.h"
+#include "private/svn_sorts_private.h"
+#include "private/svn_wc_private.h"
+#include "svn_props.h"
+#include "svn_hash.h"
+
+#include "../svn_test.h"
+#include "../svn_test_fs.h"
+
+
+/* Create a GIT repository */
+static svn_error_t *
+create_git_repos(const char **repos_url,
+ const char *name,
+ apr_pool_t *pool)
+{
+ const char *fs_dir;
+ svn_fs_t *fs;
+
+ apr_pool_t *subpool = svn_pool_create(pool);
+
+ SVN_ERR(svn_dirent_get_absolute(&fs_dir, name, subpool));
+ SVN_ERR(svn_io_remove_dir2(fs_dir, TRUE, NULL, NULL, subpool));
+ svn_test_add_dir_cleanup(fs_dir);
+
+ {
+ apr_hash_t *fs_config = apr_hash_make(subpool);
+ svn_hash_sets(fs_config, SVN_FS_CONFIG_FS_TYPE, SVN_FS_TYPE_GIT);
+
+ SVN_ERR(svn_fs_create2(&fs, fs_dir, fs_config, subpool, subpool));
+ }
+
+ fs_dir = svn_dirent_join(fs_dir, "git", subpool);
+
+ SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, fs_dir, subpool));
+
+ *repos_url = apr_pstrcat(pool, "git+", *repos_url, SVN_VA_NULL);
+
+ svn_pool_destroy(subpool);
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_git_mkdir(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ const char *repos_url;
+ const char *wc_dir;
+ svn_client_ctx_t *ctx;
+ svn_client__mtcc_t *mtcc;
+ const char *trunk_url;
+ apr_pool_t *subpool = svn_pool_create(pool);
+
+ SVN_ERR(create_git_repos(&repos_url, "git-mkdir", subpool));
+
+ SVN_ERR(svn_dirent_get_absolute(&wc_dir, "git-mkdir-wc", subpool));
+ SVN_ERR(svn_io_remove_dir2(wc_dir, TRUE, NULL, NULL, subpool));
+ svn_test_add_dir_cleanup(wc_dir);
+
+ SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
+
+ trunk_url = svn_path_url_add_component2(repos_url, "trunk", pool);
+ //head_rev.kind = svn_opt_revision_head;
+ //SVN_ERR(svn_client_checkout3(&rev, trunk_url,
+ // wc_dir, &head_rev, &head_rev, svn_depth_infinity,
+ // FALSE, FALSE, ctx, pool));
+ //
+ //
+ //{
+ // apr_array_header_t *revs;
+ // apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char *));
+ // APR_ARRAY_PUSH(paths, const char *) = wc_dir;
+ //
+ // SVN_ERR(svn_client_update4(&revs, paths, &head_rev, svn_depth_infinity, FALSE,
+ // FALSE, FALSE, FALSE, FALSE, ctx, pool));
+ //}
+
+ SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool));
+
+ SVN_ERR(svn_client__mtcc_add_mkdir("trunk", mtcc, subpool));
+ SVN_ERR(svn_client__mtcc_add_mkdir("trunk/A", mtcc, subpool));
+ SVN_ERR(svn_client__mtcc_add_mkdir("trunk/A/E", mtcc, subpool));
+
+ //SVN_ERR(svn_client__mtcc_add_add_file(
+ // "trunk/iota",
+ // svn_stream_from_string(svn_string_create("This is the file 'iota'\n",
+ // subpool),
+ // subpool),
+ // NULL, mtcc, subpool));
+
+ SVN_ERR(svn_client__mtcc_commit(apr_hash_make(subpool),
+ NULL, NULL, mtcc, subpool));
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_git_checkout(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+ const char *repos_url;
+ const char *wc_dir;
+ svn_client_ctx_t *ctx;
+ svn_client__mtcc_t *mtcc;
+ const char *trunk_url;
+ apr_pool_t *subpool = svn_pool_create(pool);
+
+ SVN_ERR(create_git_repos(&repos_url, "git-checkout-repos", subpool));
+
+ SVN_ERR(svn_dirent_get_absolute(&wc_dir, "git-checkout-wc", subpool));
+ SVN_ERR(svn_io_remove_dir2(wc_dir, TRUE, NULL, NULL, subpool));
+ svn_test_add_dir_cleanup(wc_dir);
+
+ SVN_ERR(svn_client_create_context2(&ctx, NULL, pool));
+
+ trunk_url = svn_path_url_add_component2(repos_url, "trunk", pool);
+ //head_rev.kind = svn_opt_revision_head;
+ //SVN_ERR(svn_client_checkout3(&rev, trunk_url,
+ // wc_dir, &head_rev, &head_rev, svn_depth_infinity,
+ // FALSE, FALSE, ctx, pool));
+ //
+ //
+ //{
+ // apr_array_header_t *revs;
+ // apr_array_header_t *paths = apr_array_make(pool, 1, sizeof(const char *));
+ // APR_ARRAY_PUSH(paths, const char *) = wc_dir;
+ //
+ // SVN_ERR(svn_client_update4(&revs, paths, &head_rev, svn_depth_infinity, FALSE,
+ // FALSE, FALSE, FALSE, FALSE, ctx, pool));
+ //}
+
+ SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool));
+
+ SVN_ERR(svn_client__mtcc_add_mkdir("trunk", mtcc, subpool));
+
+ SVN_ERR(svn_client__mtcc_add_add_file(
+ "trunk/iota",
+ svn_stream_from_string(svn_string_create("This is the file 'iota'\n",
+ subpool),
+ subpool),
+ NULL, mtcc, subpool));
+
+ SVN_ERR(svn_client__mtcc_commit(apr_hash_make(subpool),
+ NULL, NULL, mtcc, subpool));
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
+/* ========================================================================== */
+
+
+static int max_threads = 3;
+
+static struct svn_test_descriptor_t test_funcs[] =
+{
+ SVN_TEST_NULL,
+ SVN_TEST_OPTS_PASS(test_git_mkdir,
+ "test git_mkdir"),
+ SVN_TEST_OPTS_XFAIL(test_git_checkout,
+ "test git_checkout"),
+
+ SVN_TEST_NULL
+};
+
+SVN_TEST_MAIN
+
Propchange: subversion/branches/ra-git/subversion/tests/libsvn_client/git-client-test.c
------------------------------------------------------------------------------
svn:eol-style = native