You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/11/03 18:02:44 UTC
svn commit: r1712352 - in
/subversion/branches/move-tracking-2/subversion/svnmover: merge3.c
svnmover.c svnmover.h
Author: julianfoad
Date: Tue Nov 3 17:02:43 2015
New Revision: 1712352
URL: http://svn.apache.org/viewvc?rev=1712352&view=rev
Log:
On the 'move-tracking-2' branch: Make 'svnmover' store conflicts in the WC,
and add subcommands 'conflicts' and 'resolved' to manipulate them.
* subversion/svnmover/merge3.c
(conflict_kind_t,
conflict_object_t,
conflict_object_create,
find_conflict,
svnmover_conflict_resolved,
svnmover_any_conflicts): New.
(svnmover_branch_merge): Use svnmover_any_conflicts().
* subversion/svnmover/svnmover.c
(action_code_t,
action_defn_t): Add new subcommands.
(do_switch): Store conflicts in the WC.
(commit): New, factored out of do_commit() and final_commit(). Raise an
error if there are unresolved conflicts.
(do_commit): Factor out some code as commit().
(final_commit): Delete.
(execute): Store conflicts in the WC. Reimplement final_commit() inline.
* subversion/svnmover/svnmover.h
(svnmover_wc_t): Add a 'conflicts' member.
(svnmover_conflict_resolved,
svnmover_any_conflicts): New.
Modified:
subversion/branches/move-tracking-2/subversion/svnmover/merge3.c
subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h
Modified: subversion/branches/move-tracking-2/subversion/svnmover/merge3.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/merge3.c?rev=1712352&r1=1712351&r2=1712352&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/merge3.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/merge3.c Tue Nov 3 17:02:43 2015
@@ -354,6 +354,122 @@ svnmover_display_conflicts(conflict_stor
return SVN_NO_ERROR;
}
+enum conflict_kind_t { conflict_kind_single_element,
+ conflict_kind_clash,
+ conflict_kind_cycle,
+ conflict_kind_orphan };
+
+/* */
+typedef struct conflict_object_t
+{
+ enum conflict_kind_t conflict_kind;
+ apr_hash_t *conflicts;
+ const void *key;
+} conflict_object_t;
+
+/* */
+static conflict_object_t *
+conflict_object_create(enum conflict_kind_t conflict_kind,
+ apr_hash_t *conflicts,
+ const void *key,
+ apr_pool_t *result_pool)
+{
+ conflict_object_t *c = apr_pcalloc(result_pool, sizeof(*c));
+
+ c->conflict_kind = conflict_kind;
+ c->conflicts = conflicts;
+ c->key = (conflict_kind == conflict_kind_clash)
+ ? apr_pstrdup(result_pool, key)
+ : apr_pmemdup(result_pool, key, sizeof(int));
+ return c;
+}
+
+static svn_error_t *
+find_conflict(conflict_object_t **conflict_p,
+ conflict_storage_t *conflicts,
+ const char *id_string,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ *conflict_p = NULL;
+
+ if (id_string[0] == 'e')
+ {
+ int which_eid = atoi(id_string + 1);
+
+ if (svn_int_hash_get(conflicts->single_element_conflicts, which_eid))
+ {
+ *conflict_p
+ = conflict_object_create(conflict_kind_single_element,
+ conflicts->single_element_conflicts,
+ &which_eid, result_pool);
+ }
+ if (svn_int_hash_get(conflicts->cycle_conflicts, which_eid))
+ {
+ *conflict_p
+ = conflict_object_create(conflict_kind_cycle,
+ conflicts->cycle_conflicts,
+ &which_eid, result_pool);
+ }
+ if (svn_int_hash_get(conflicts->orphan_conflicts, which_eid))
+ {
+ *conflict_p
+ = conflict_object_create(conflict_kind_orphan,
+ conflicts->orphan_conflicts,
+ &which_eid, result_pool);
+ }
+ }
+ else
+ {
+ if (svn_hash_gets(conflicts->name_clash_conflicts, id_string))
+ {
+ *conflict_p
+ = conflict_object_create(conflict_kind_clash,
+ conflicts->name_clash_conflicts,
+ id_string, result_pool);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svnmover_conflict_resolved(conflict_storage_t *conflicts,
+ const char *id_string,
+ apr_pool_t *scratch_pool)
+{
+ conflict_object_t *conflict;
+
+ SVN_ERR(find_conflict(&conflict, conflicts, id_string,
+ scratch_pool, scratch_pool));
+ if (! conflict)
+ {
+ return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+ _("Conflict '%s' not found"), id_string);
+ }
+
+ if (conflict->conflict_kind == conflict_kind_clash)
+ {
+ svn_hash_sets(conflict->conflicts, conflict->key, NULL);
+ }
+ else
+ {
+ apr_hash_set(conflict->conflicts, conflict->key, sizeof (int), NULL);
+ }
+ svnmover_notify("Marked conflict '%s' as resolved", id_string);
+ return SVN_NO_ERROR;
+}
+
+svn_boolean_t
+svnmover_any_conflicts(const conflict_storage_t *conflicts)
+{
+ return conflicts
+ && (apr_hash_count(conflicts->single_element_conflicts)
+ || apr_hash_count(conflicts->name_clash_conflicts)
+ || apr_hash_count(conflicts->cycle_conflicts)
+ || apr_hash_count(conflicts->orphan_conflicts));
+}
+
/* Merge the payload for one element.
*
* If there is no conflict, set *CONFLICT_P to FALSE and *RESULT_P to the
@@ -982,10 +1098,7 @@ svnmover_branch_merge(svn_branch_txn_t *
if (conflict_storage_p)
{
- if (apr_hash_count(conflicts->single_element_conflicts)
- || apr_hash_count(conflicts->name_clash_conflicts)
- || apr_hash_count(conflicts->cycle_conflicts)
- || apr_hash_count(conflicts->orphan_conflicts))
+ if (svnmover_any_conflicts(conflicts))
{
*conflict_storage_p = conflicts;
}
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1712352&r1=1712351&r2=1712352&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Tue Nov 3 17:02:43 2015
@@ -772,6 +772,8 @@ wc_commit(svn_revnum_t *new_rev_p,
typedef enum action_code_t {
ACTION_INFO_WC,
+ ACTION_LIST_CONFLICTS,
+ ACTION_RESOLVED_CONFLICT,
ACTION_DIFF,
ACTION_LOG,
ACTION_LIST_BRANCHES,
@@ -812,6 +814,10 @@ static const action_defn_t action_defn[]
{
{ACTION_INFO_WC, "info-wc", 0, "",
"print information about the WC"},
+ {ACTION_LIST_CONFLICTS, "conflicts", 0, "",
+ "list unresolved conflicts"},
+ {ACTION_RESOLVED_CONFLICT,"resolved", 1, "CONFLICT_ID",
+ "mark conflict as resolved"},
{ACTION_LIST_BRANCHES, "branches", 1, "PATH",
"list all branches rooted at the same element as PATH"},
{ACTION_LIST_BRANCHES_R, "ls-br-r", 0, "",
@@ -1318,7 +1324,6 @@ do_switch(svnmover_wc_t *wc,
if (has_local_changes)
{
svn_branch_el_rev_id_t *yca, *src, *tgt;
- conflict_storage_t *conflicts;
/* Merge changes from the old into the new WC */
yca = svn_branch_el_rev_id_create(previous_base_br,
@@ -1331,12 +1336,12 @@ do_switch(svnmover_wc_t *wc,
tgt = svn_branch_el_rev_id_create(wc->working->branch,
svn_branch_root_eid(wc->working->branch),
SVN_INVALID_REVNUM, scratch_pool);
- SVN_ERR(svnmover_branch_merge(wc->edit_txn, &conflicts,
+ SVN_ERR(svnmover_branch_merge(wc->edit_txn, &wc->conflicts,
src, tgt, yca, scratch_pool, scratch_pool));
- if (conflicts)
+ if (svnmover_any_conflicts(wc->conflicts))
{
- SVN_ERR(svnmover_display_conflicts(conflicts, scratch_pool));
+ SVN_ERR(svnmover_display_conflicts(wc->conflicts, scratch_pool));
return svn_error_createf(
SVN_ERR_BRANCHING, NULL,
_("Switch failed because of conflicts"));
@@ -2347,6 +2352,28 @@ display_diff_of_commit(const commit_call
return SVN_NO_ERROR;
}
+static svn_error_t *
+commit(svn_revnum_t *new_rev_p,
+ svnmover_wc_t *wc,
+ apr_hash_t *revprops,
+ apr_pool_t *scratch_pool)
+{
+ if (svnmover_any_conflicts(wc->conflicts))
+ {
+ return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+ _("Cannot commit because there are "
+ "unresolved conflicts"));
+ }
+
+ /* Complete the old edit drive (into the 'WC') */
+ SVN_ERR(svn_branch_txn_sequence_point(wc->edit_txn, scratch_pool));
+
+ /* Commit */
+ SVN_ERR(wc_commit(new_rev_p, wc, revprops, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
/* Commit and update WC.
*
* Set *NEW_REV_P to the committed revision number, and update the WC to
@@ -2365,11 +2392,7 @@ do_commit(svn_revnum_t *new_rev_p,
{
svn_revnum_t new_rev;
- /* Complete the old edit drive (into the 'WC') */
- SVN_ERR(svn_branch_txn_sequence_point(wc->edit_txn, scratch_pool));
-
- /* Commit */
- SVN_ERR(wc_commit(&new_rev, wc, revprops, scratch_pool));
+ SVN_ERR(commit(&new_rev, wc, revprops, scratch_pool));
/* Check out a new WC.
(Instead, we could perhaps just get a new WC editor.) */
@@ -2690,6 +2713,26 @@ execute(svnmover_wc_t *wc,
}
break;
+ case ACTION_LIST_CONFLICTS:
+ {
+ if (svnmover_any_conflicts(wc->conflicts))
+ {
+ SVN_ERR(svnmover_display_conflicts(wc->conflicts, iterpool));
+ }
+ }
+ break;
+
+ case ACTION_RESOLVED_CONFLICT:
+ {
+ if (svnmover_any_conflicts(wc->conflicts))
+ {
+ SVN_ERR(svnmover_conflict_resolved(wc->conflicts,
+ action->relpath[0],
+ iterpool));
+ }
+ }
+ break;
+
case ACTION_DIFF:
VERIFY_EID_EXISTS("diff", 0);
VERIFY_EID_EXISTS("diff", 1);
@@ -2860,8 +2903,6 @@ execute(svnmover_wc_t *wc,
case ACTION_MERGE:
{
- conflict_storage_t *conflicts;
-
VERIFY_EID_EXISTS("merge", 0);
VERIFY_EID_EXISTS("merge", 1);
VERIFY_EID_EXISTS("merge", 2);
@@ -2874,15 +2915,15 @@ execute(svnmover_wc_t *wc,
arg[0]->el_rev->eid, arg[1]->el_rev->eid, arg[2]->el_rev->eid);
}
SVN_ERR(svnmover_branch_merge(wc->edit_txn,
- &conflicts,
+ &wc->conflicts,
arg[0]->el_rev /*from*/,
arg[1]->el_rev /*to*/,
arg[2]->el_rev /*yca*/,
iterpool, iterpool));
- if (conflicts)
+ if (svnmover_any_conflicts(wc->conflicts))
{
- SVN_ERR(svnmover_display_conflicts(conflicts, iterpool));
+ SVN_ERR(svnmover_display_conflicts(wc->conflicts, iterpool));
return svn_error_createf(
SVN_ERR_BRANCHING, NULL,
_("Merge failed because of conflicts"));
@@ -3098,25 +3139,6 @@ execute(svnmover_wc_t *wc,
return SVN_NO_ERROR;
}
-/* */
-static svn_error_t *
-final_commit(svnmover_wc_t *wc,
- apr_hash_t *revprops,
- apr_pool_t *scratch_pool)
-{
- svn_error_t *err;
-
- /* Complete the old edit drive (into the 'WC') */
- SVN_ERR(svn_branch_txn_sequence_point(wc->edit_txn, scratch_pool));
-
- /* Commit, if there are any changes */
- err = wc_commit(NULL, wc, revprops, scratch_pool);
-
- svn_pool_destroy(wc->pool);
-
- return svn_error_trace(err);
-}
-
/* Perform the typical suite of manipulations for user-provided URLs
on URL, returning the result (allocated from POOL): IRI-to-URI
conversion, auto-escaping, and canonicalization. */
@@ -3888,7 +3910,10 @@ sub_main(int *exit_code, int argc, const
}
while (interactive_actions && action_args);
- SVN_ERR(final_commit(wc, revprops, pool));
+ /* Final commit */
+ err = commit(NULL, wc, revprops, pool);
+ svn_pool_destroy(wc->pool);
+ SVN_ERR(err);
return SVN_NO_ERROR;
}
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h?rev=1712352&r1=1712351&r2=1712352&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h Tue Nov 3 17:02:43 2015
@@ -56,6 +56,9 @@ typedef struct svnmover_wc_version_t
svn_branch_state_t *branch;
} svnmover_wc_version_t;
+/* */
+typedef struct conflict_storage_t conflict_storage_t;
+
typedef struct svnmover_wc_t
{
apr_pool_t *pool;
@@ -65,6 +68,7 @@ typedef struct svnmover_wc_t
svn_ra_session_t *ra_session;
svn_branch_txn_t *edit_txn;
+ conflict_storage_t *conflicts;
/* Base and working versions. */
svnmover_wc_version_t *base, *working;
@@ -77,8 +81,7 @@ typedef struct svnmover_wc_t
} svnmover_wc_t;
-/* */
-typedef struct conflict_storage_t
+struct conflict_storage_t
{
/* Single-element conflicts */
/* (eid -> element_merge3_conflict_t) */
@@ -95,7 +98,7 @@ typedef struct conflict_storage_t
/* Orphan conflicts */
/* (eid -> orphan_conflict_t) */
apr_hash_t *orphan_conflicts;
-} conflict_storage_t;
+};
/* Merge SRC into TGT, using the common ancestor YCA.
*
@@ -125,6 +128,15 @@ svn_error_t *
svnmover_display_conflicts(conflict_storage_t *conflict_storage,
apr_pool_t *scratch_pool);
+svn_error_t *
+svnmover_conflict_resolved(conflict_storage_t *conflicts,
+ const char *id_string,
+ apr_pool_t *scratch_pool);
+
+/* */
+svn_boolean_t
+svnmover_any_conflicts(const conflict_storage_t *conflicts);
+
#ifdef __cplusplus
}