⇤ ← Revision 1 as of 2008-09-04 15:54:46
Size: 250
Comment:
|
Size: 9013
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
= Performing 'svn merge URL_TO_TRUNK BRANCH_WC' and handling conflicts with SVNKit = | |
Line 2: | Line 3: |
you can handle conflicts programmatically using [[ISVNConflictHandler]]. | |
Line 3: | Line 5: |
you can handle conflicts programmatically using [[ISVNConflictHandler]]. | {{{#!java /* * ==================================================================== * Copyright (c) 2004-2008 TMate Software Ltd. 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 * are also available at http://svnkit.com/license.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.examples.wc; import java.io.File; import java.io.IOException; import java.util.Collections; import org.tmatesoft.svn.core.SVNCommitInfo; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNPropertyValue; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; import org.tmatesoft.svn.core.wc.ISVNConflictHandler; import org.tmatesoft.svn.core.wc.SVNClientManager; import org.tmatesoft.svn.core.wc.SVNCommitClient; import org.tmatesoft.svn.core.wc.SVNConflictChoice; import org.tmatesoft.svn.core.wc.SVNConflictDescription; import org.tmatesoft.svn.core.wc.SVNConflictReason; import org.tmatesoft.svn.core.wc.SVNConflictResult; import org.tmatesoft.svn.core.wc.SVNCopyClient; import org.tmatesoft.svn.core.wc.SVNCopySource; import org.tmatesoft.svn.core.wc.SVNDiffClient; import org.tmatesoft.svn.core.wc.SVNMergeFileSet; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc.SVNRevisionRange; import org.tmatesoft.svn.core.wc.SVNWCClient; /** * @version 1.2.0 * @author TMate Software Ltd. */ public class ConflictedMerge { /** * Pass the absolute path of the base directory where all example data will be created in * arg[0]. The sample will create: * * - arg[0]/exampleRepository - repository with some test data * - arg[0]/exampleWC - working copy checked out from exampleRepository */ public static void main (String[] args) { //initialize SVNKit to work through file:/// protocol SamplesUtility.initializeFSFSprotocol(); File baseDirectory = new File(args[0]); File reposRoot = new File(baseDirectory, "exampleRepository"); File wcRoot = new File(baseDirectory, "exampleWC"); try { //first create a repository and fill it with data SamplesUtility.createRepository(reposRoot); SVNCommitInfo info = SamplesUtility.createRepositoryTree(reposRoot); //print out new revision info System.out.println(info); SVNClientManager clientManager = SVNClientManager.newInstance(); SVNURL reposURL = SVNURL.fromFile(reposRoot); //copy A to A_copy in repository (url-to-url copy) SVNCopyClient copyClient = clientManager.getCopyClient(); SVNURL A_URL = reposURL.appendPath("A", true); SVNURL copyTargetURL = reposURL.appendPath("A_copy", true); SVNCopySource copySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.HEAD, A_URL); info = copyClient.doCopy(new SVNCopySource[] { copySource }, copyTargetURL, false, false, true, "copy A to A_copy", null); //print out new revision info System.out.println(info); //checkout the entire repository tree SamplesUtility.checkOutWorkingCopy(reposURL, wcRoot); //now make some changes to the A tree SamplesUtility.writeToFile(new File(wcRoot, "A/B/lambda"), "New text appended to 'lambda'", true); SamplesUtility.writeToFile(new File(wcRoot, "A/mu"), "New text in 'mu'", false); SVNWCClient wcClient = SVNClientManager.newInstance().getWCClient(); wcClient.doSetProperty(new File(wcRoot, "A/B"), "spam", SVNPropertyValue.create("egg"), false, SVNDepth.EMPTY, null, null); //commit local changes SVNCommitClient commitClient = clientManager.getCommitClient(); commitClient.doCommit(new File[] { wcRoot }, false, "committing changes", null, null, false, false, SVNDepth.INFINITY); //now diff the base revision of the working copy against the repository SVNDiffClient diffClient = clientManager.getDiffClient(); SVNRevisionRange rangeToMerge = new SVNRevisionRange(SVNRevision.create(1), SVNRevision.HEAD); diffClient.doMerge(A_URL, SVNRevision.HEAD, Collections.singleton(rangeToMerge), new File(wcRoot, "A_copy"), SVNDepth.UNKNOWN, true, false, false, false); //now make some changes to the A tree again //change file contents of iota and A/D/gamma SamplesUtility.writeToFile(new File(wcRoot, "A/B/lambda"), "New text2 appended to 'lambda'", true); SamplesUtility.writeToFile(new File(wcRoot, "A/D/gamma"), "New text in 'gamma'", false); //commit local changes commitClient.doCommit(new File[] { wcRoot }, false, "committing changes again", null, null, false, false, SVNDepth.INFINITY); //now make some local changes to the A_copy tree //change file contents of iota and A/D/gamma SamplesUtility.writeToFile(new File(wcRoot, "A_copy/B/lambda"), "New text in copied 'lambda'", true); SamplesUtility.writeToFile(new File(wcRoot, "A_copy/D/gamma"), "New text in copied 'gamma'", false); /* * Since we provided no custom ISVNOptions implementation to SVNClientManager, our * manager uses DefaultSVNOptions, which is set to all SVN*Client classes which the * manager produces. So, we can cast ISVNOptions to DefaultSVNOptions. */ DefaultSVNOptions options = (DefaultSVNOptions) diffClient.getOptions(); //This way we set a conflict handler which will automatically resolve conflicts for those //cases that we would like options.setConflictHandler(new ConflictResolverHandler()); /* do the same merge call, merge-tracking feature will merge only those revisions * which were not still merged. */ diffClient.doMerge(A_URL, SVNRevision.HEAD, Collections.singleton(rangeToMerge), new File(wcRoot, "A_copy"), SVNDepth.UNKNOWN, true, false, false, false); } catch (SVNException svne) { System.out.println(svne.getErrorMessage()); System.exit(1); } catch (IOException ioe) { ioe.printStackTrace(); System.exit(1); } } /** * Conflict resolver which always selects the local version of a file. * * @version 1.2.0 * @author TMate Software Ltd. */ private static class ConflictResolverHandler implements ISVNConflictHandler { public SVNConflictResult handleConflict(SVNConflictDescription conflictDescription) throws SVNException { SVNConflictReason reason = conflictDescription.getConflictReason(); SVNMergeFileSet mergeFiles = conflictDescription.getMergeFiles(); SVNConflictChoice choice = SVNConflictChoice.THEIRS_FULL; if (reason == SVNConflictReason.EDITED) { //If the reason why conflict occurred is local edits, chose local version of the file //Otherwise the repository version of the file will be chosen. choice = SVNConflictChoice.MINE_FULL; } System.out.println("Automatically resolving conflict for " + mergeFiles.getWCFile() + ", choosing " + (choice == SVNConflictChoice.MINE_FULL ? "local file" : "repository file")); return new SVNConflictResult(choice, mergeFiles.getResultFile()); } } } }}} When you run the program you will see an output similar to this one: {{{ r1 by 'alex' at Thu Sep 04 17:44:53 CEST 2008 r2 by 'alex' at Thu Sep 04 17:44:53 CEST 2008 Automatically resolving conflict for /home/alex/workspace/tmp/exampleWC/A_copy/B/lambda, choosing local file Automatically resolving conflict for /home/alex/workspace/tmp/exampleWC/A_copy/D/gamma, choosing local file }}} |
Performing 'svn merge URL_TO_TRUNK BRANCH_WC' and handling conflicts with SVNKit
This example is similar to Merging from trunk to a branch except for the second merge to the branch working copy produces a conflict. In this example we demonstrate how you can handle conflicts programmatically using ISVNConflictHandler.
1 /*
2 * ====================================================================
3 * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
4 *
5 * This software is licensed as described in the file COPYING, which
6 * you should have received as part of this distribution. The terms
7 * are also available at http://svnkit.com/license.html.
8 * If newer versions of this license are posted there, you may use a
9 * newer version instead, at your option.
10 * ====================================================================
11 */
12 package org.tmatesoft.svn.examples.wc;
13
14 import java.io.File;
15 import java.io.IOException;
16 import java.util.Collections;
17
18 import org.tmatesoft.svn.core.SVNCommitInfo;
19 import org.tmatesoft.svn.core.SVNDepth;
20 import org.tmatesoft.svn.core.SVNException;
21 import org.tmatesoft.svn.core.SVNPropertyValue;
22 import org.tmatesoft.svn.core.SVNURL;
23 import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
24 import org.tmatesoft.svn.core.wc.ISVNConflictHandler;
25 import org.tmatesoft.svn.core.wc.SVNClientManager;
26 import org.tmatesoft.svn.core.wc.SVNCommitClient;
27 import org.tmatesoft.svn.core.wc.SVNConflictChoice;
28 import org.tmatesoft.svn.core.wc.SVNConflictDescription;
29 import org.tmatesoft.svn.core.wc.SVNConflictReason;
30 import org.tmatesoft.svn.core.wc.SVNConflictResult;
31 import org.tmatesoft.svn.core.wc.SVNCopyClient;
32 import org.tmatesoft.svn.core.wc.SVNCopySource;
33 import org.tmatesoft.svn.core.wc.SVNDiffClient;
34 import org.tmatesoft.svn.core.wc.SVNMergeFileSet;
35 import org.tmatesoft.svn.core.wc.SVNRevision;
36 import org.tmatesoft.svn.core.wc.SVNRevisionRange;
37 import org.tmatesoft.svn.core.wc.SVNWCClient;
38
39
40 /**
41 * @version 1.2.0
42 * @author TMate Software Ltd.
43 */
44 public class ConflictedMerge {
45 /**
46 * Pass the absolute path of the base directory where all example data will be created in
47 * arg[0]. The sample will create:
48 *
49 * - arg[0]/exampleRepository - repository with some test data
50 * - arg[0]/exampleWC - working copy checked out from exampleRepository
51 */
52 public static void main (String[] args) {
53 //initialize SVNKit to work through file:/// protocol
54 SamplesUtility.initializeFSFSprotocol();
55
56 File baseDirectory = new File(args[0]);
57 File reposRoot = new File(baseDirectory, "exampleRepository");
58 File wcRoot = new File(baseDirectory, "exampleWC");
59
60 try {
61 //first create a repository and fill it with data
62 SamplesUtility.createRepository(reposRoot);
63 SVNCommitInfo info = SamplesUtility.createRepositoryTree(reposRoot);
64 //print out new revision info
65 System.out.println(info);
66
67 SVNClientManager clientManager = SVNClientManager.newInstance();
68
69 SVNURL reposURL = SVNURL.fromFile(reposRoot);
70
71 //copy A to A_copy in repository (url-to-url copy)
72 SVNCopyClient copyClient = clientManager.getCopyClient();
73 SVNURL A_URL = reposURL.appendPath("A", true);
74 SVNURL copyTargetURL = reposURL.appendPath("A_copy", true);
75 SVNCopySource copySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.HEAD, A_URL);
76 info = copyClient.doCopy(new SVNCopySource[] { copySource }, copyTargetURL, false, false, true,
77 "copy A to A_copy", null);
78 //print out new revision info
79 System.out.println(info);
80
81 //checkout the entire repository tree
82 SamplesUtility.checkOutWorkingCopy(reposURL, wcRoot);
83
84
85 //now make some changes to the A tree
86 SamplesUtility.writeToFile(new File(wcRoot, "A/B/lambda"), "New text appended to 'lambda'", true);
87 SamplesUtility.writeToFile(new File(wcRoot, "A/mu"), "New text in 'mu'", false);
88
89 SVNWCClient wcClient = SVNClientManager.newInstance().getWCClient();
90 wcClient.doSetProperty(new File(wcRoot, "A/B"), "spam", SVNPropertyValue.create("egg"), false,
91 SVNDepth.EMPTY, null, null);
92
93 //commit local changes
94 SVNCommitClient commitClient = clientManager.getCommitClient();
95 commitClient.doCommit(new File[] { wcRoot }, false, "committing changes", null, null, false, false, SVNDepth.INFINITY);
96
97 //now diff the base revision of the working copy against the repository
98 SVNDiffClient diffClient = clientManager.getDiffClient();
99 SVNRevisionRange rangeToMerge = new SVNRevisionRange(SVNRevision.create(1), SVNRevision.HEAD);
100
101 diffClient.doMerge(A_URL, SVNRevision.HEAD, Collections.singleton(rangeToMerge),
102 new File(wcRoot, "A_copy"), SVNDepth.UNKNOWN, true, false, false, false);
103
104 //now make some changes to the A tree again
105 //change file contents of iota and A/D/gamma
106 SamplesUtility.writeToFile(new File(wcRoot, "A/B/lambda"), "New text2 appended to 'lambda'", true);
107 SamplesUtility.writeToFile(new File(wcRoot, "A/D/gamma"), "New text in 'gamma'", false);
108
109 //commit local changes
110 commitClient.doCommit(new File[] { wcRoot }, false, "committing changes again", null, null, false, false, SVNDepth.INFINITY);
111
112 //now make some local changes to the A_copy tree
113 //change file contents of iota and A/D/gamma
114 SamplesUtility.writeToFile(new File(wcRoot, "A_copy/B/lambda"), "New text in copied 'lambda'", true);
115 SamplesUtility.writeToFile(new File(wcRoot, "A_copy/D/gamma"), "New text in copied 'gamma'", false);
116
117 /*
118 * Since we provided no custom ISVNOptions implementation to SVNClientManager, our
119 * manager uses DefaultSVNOptions, which is set to all SVN*Client classes which the
120 * manager produces. So, we can cast ISVNOptions to DefaultSVNOptions.
121 */
122 DefaultSVNOptions options = (DefaultSVNOptions) diffClient.getOptions();
123 //This way we set a conflict handler which will automatically resolve conflicts for those
124 //cases that we would like
125 options.setConflictHandler(new ConflictResolverHandler());
126
127 /* do the same merge call, merge-tracking feature will merge only those revisions
128 * which were not still merged.
129 */
130 diffClient.doMerge(A_URL, SVNRevision.HEAD, Collections.singleton(rangeToMerge),
131 new File(wcRoot, "A_copy"), SVNDepth.UNKNOWN, true, false, false, false);
132
133 } catch (SVNException svne) {
134 System.out.println(svne.getErrorMessage());
135 System.exit(1);
136 } catch (IOException ioe) {
137 ioe.printStackTrace();
138 System.exit(1);
139 }
140 }
141
142 /**
143 * Conflict resolver which always selects the local version of a file.
144 *
145 * @version 1.2.0
146 * @author TMate Software Ltd.
147 */
148 private static class ConflictResolverHandler implements ISVNConflictHandler {
149
150 public SVNConflictResult handleConflict(SVNConflictDescription conflictDescription) throws SVNException {
151 SVNConflictReason reason = conflictDescription.getConflictReason();
152 SVNMergeFileSet mergeFiles = conflictDescription.getMergeFiles();
153
154 SVNConflictChoice choice = SVNConflictChoice.THEIRS_FULL;
155 if (reason == SVNConflictReason.EDITED) {
156 //If the reason why conflict occurred is local edits, chose local version of the file
157 //Otherwise the repository version of the file will be chosen.
158 choice = SVNConflictChoice.MINE_FULL;
159 }
160 System.out.println("Automatically resolving conflict for " + mergeFiles.getWCFile() +
161 ", choosing " + (choice == SVNConflictChoice.MINE_FULL ? "local file" : "repository file"));
162 return new SVNConflictResult(choice, mergeFiles.getResultFile());
163 }
164
165 }
166 }
When you run the program you will see an output similar to this one:
r1 by 'alex' at Thu Sep 04 17:44:53 CEST 2008 r2 by 'alex' at Thu Sep 04 17:44:53 CEST 2008 Automatically resolving conflict for /home/alex/workspace/tmp/exampleWC/A_copy/B/lambda, choosing local file Automatically resolving conflict for /home/alex/workspace/tmp/exampleWC/A_copy/D/gamma, choosing local file