Size: 5564
Comment:
|
Size: 8552
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
This example demonstrates how you can merge changes to a branch without specifying revisions. | This example demonstrates how you can merge changes from trunk to a branch several times without specifying revisions. What we are going to do here is the following: 0. Initialize SVNKit to work with file:/// protocol. 1. Create a repository. 2. Populate it with some tree. 3. Make a copy of that tree: /A to /A_copy. 4. Checkout the entire repository tree to a working copy. 5. Make some changes to trunk (A). Commit those changes to the repository. 6. Then merge the changes from trunk (A) to the branch (A_copy). 7. Then again make some changes to trunk and commit them to the repository. 8. Again, merge the changes from trunk (A) to the branch (A_copy). This steps are reflected in code comments: |
Line 42: | Line 54: |
/** * 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 */ |
|
Line 43: | Line 62: |
//initialize SVNKit to work through file:/// protocol | //0. initialize SVNKit to work through file:/// protocol |
Line 51: | Line 70: |
//first create a repository and fill it with data | //1. first create a repository |
Line 53: | Line 72: |
//2. fill it with data | |
Line 61: | Line 81: |
//copy A to A_copy in repository (url-to-url copy) | //3. copy A to A_copy in the repository (url-to-url copy) |
Line 71: | Line 91: |
//checkout the entire repository tree | //4. checkout the entire repository tree |
Line 75: | Line 95: |
//now make some changes to the A tree | //5. now make some changes to the A tree and commit them |
Line 85: | Line 105: |
commitClient.doCommit(new File[] { wcRoot }, false, "committing changes", null, null, false, false, SVNDepth.INFINITY); | commitClient.doCommit(new File[] { wcRoot }, false, "committing changes", null, null, false, false, SVNDepth.INFINITY); |
Line 87: | Line 108: |
//now diff the base revision of the working copy against the repository | //6. now merge changes from trunk to the branch. |
Line 92: | Line 113: |
new File(wcRoot, "A_copy"), SVNDepth.UNKNOWN, true, false, false, false); | new File(wcRoot, "A_copy"), SVNDepth.INFINITY, true, false, false, false); |
Line 95: | Line 116: |
//now make some changes to the A tree again | //7. now make some changes to the A tree again and commit them |
Line 103: | Line 124: |
commitClient.doCommit(new File[] { wcRoot }, false, "committing changes again", null, null, false, false, SVNDepth.INFINITY); | commitClient.doCommit(new File[] { wcRoot }, false, "committing changes again", null, null, false, false, SVNDepth.INFINITY); |
Line 105: | Line 127: |
/* do the same merge call, merge-tracking feature will merge only those revisions * which were not still merged. |
/* 8. do the same merge call, merge-tracking feature will merge only those revisions * which were not merged yet. |
Line 109: | Line 131: |
new File(wcRoot, "A_copy"), SVNDepth.UNKNOWN, true, false, false, false); | new File(wcRoot, "A_copy"), SVNDepth.INFINITY, true, false, false, false); |
Line 119: | Line 141: |
Line 122: | Line 143: |
Here are some comments on calling ''doMerge()'' in this example: * We use a pegged version of ''doMerge()'' which allows to merge differences between different revisions of the same file. * A_URL - URL of the merge source. * ''SVNRevision.HEAD'' - [[Peg revision|peg revision]] in which A_URL is valid for sure. * We use the entire revision range - from revisio 1 to HEAD not caring of how already merged revisions are skipped - merge-tracking feature will do that for us. * Then goes the merge target local path. * We use ''SVNDepth.INFINITY'' to recursively merge the whole target tree. * We want to merge only related (by history) objects, so the next parameter is ''true''. * We do not want our merge to delete any versioned files containing local edits or unversioned ones, so passing ''false''. * We do want a real merge to perform, not a just the final status of a potential merge, so passing ''false''. * We do wand a real merge to perform, not just to record mergeinfo without bringing real changes to A_copy. Each merge operation in this example is equivalent to the following command line client' command: {{{ svn merge file:///home/alex/workspace/tmp/exampleRepository/A /home/alex/workspace/exampleWC/A_copy }}} After the first merge, if you run 'svn status' in the working copy you should see this report: {{{ alex@UFO:~/workspace/tmp/exampleWC$ $JSVN_PATH stat M A_copy M A_copy/B M A_copy/mu }}} And 'svn pg svn:mergeinfo .' in A_copy gives: {{{ alex@UFO:~/workspace/tmp/exampleWC/A_copy$ $JSVN_PATH pg svn:mergeinfo . /A:2-3 }}} After the second merge the status report will look like this: {{{ alex@UFO:~/workspace/tmp/exampleWC$ $JSVN_PATH stat M A_copy D A_copy/C M A_copy/D/gamma }}} and propget report like this: {{{ alex@UFO:~/workspace/tmp/exampleWC/A_copy$ $JSVN_PATH pg svn:mergeinfo . /A:2-4 }}} |
This example demonstrates how you can merge changes from trunk to a branch several times without specifying revisions. What we are going to do here is the following:
Initialize SVNKit to work with file:/// protocol.
- Create a repository.
- Populate it with some tree.
- Make a copy of that tree: /A to /A_copy.
- Checkout the entire repository tree to a working copy.
- Make some changes to trunk (A). Commit those changes to the repository.
- Then merge the changes from trunk (A) to the branch (A_copy).
- Then again make some changes to trunk and commit them to the repository.
- Again, merge the changes from trunk (A) to the branch (A_copy).
This steps are reflected in code comments:
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.wc.SVNClientManager;
24 import org.tmatesoft.svn.core.wc.SVNCommitClient;
25 import org.tmatesoft.svn.core.wc.SVNCopyClient;
26 import org.tmatesoft.svn.core.wc.SVNCopySource;
27 import org.tmatesoft.svn.core.wc.SVNDiffClient;
28 import org.tmatesoft.svn.core.wc.SVNRevision;
29 import org.tmatesoft.svn.core.wc.SVNRevisionRange;
30 import org.tmatesoft.svn.core.wc.SVNWCClient;
31
32
33 /**
34 * @version 1.2.0
35 * @author TMate Software Ltd.
36 */
37 public class Merge {
38
39 /**
40 * Pass the absolute path of the base directory where all example data will be created in
41 * arg[0]. The sample will create:
42 *
43 * - arg[0]/exampleRepository - repository with some test data
44 * - arg[0]/exampleWC - working copy checked out from exampleRepository
45 */
46 public static void main (String[] args) {
47 //0. initialize SVNKit to work through file:/// protocol
48 SamplesUtility.initializeFSFSprotocol();
49
50 File baseDirectory = new File(args[0]);
51 File reposRoot = new File(baseDirectory, "exampleRepository");
52 File wcRoot = new File(baseDirectory, "exampleWC");
53
54 try {
55 //1. first create a repository
56 SamplesUtility.createRepository(reposRoot);
57 //2. fill it with data
58 SVNCommitInfo info = SamplesUtility.createRepositoryTree(reposRoot);
59 //print out new revision info
60 System.out.println(info);
61
62 SVNClientManager clientManager = SVNClientManager.newInstance();
63
64 SVNURL reposURL = SVNURL.fromFile(reposRoot);
65
66 //3. copy A to A_copy in the repository (url-to-url copy)
67 SVNCopyClient copyClient = clientManager.getCopyClient();
68 SVNURL A_URL = reposURL.appendPath("A", true);
69 SVNURL copyTargetURL = reposURL.appendPath("A_copy", true);
70 SVNCopySource copySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.HEAD, A_URL);
71 info = copyClient.doCopy(new SVNCopySource[] { copySource }, copyTargetURL, false, false, true,
72 "copy A to A_copy", null);
73 //print out new revision info
74 System.out.println(info);
75
76 //4. checkout the entire repository tree
77 SamplesUtility.checkOutWorkingCopy(reposURL, wcRoot);
78
79
80 //5. now make some changes to the A tree and commit them
81 SamplesUtility.writeToFile(new File(wcRoot, "iota"), "New text appended to 'iota'", true);
82 SamplesUtility.writeToFile(new File(wcRoot, "A/mu"), "New text in 'mu'", false);
83
84 SVNWCClient wcClient = SVNClientManager.newInstance().getWCClient();
85 wcClient.doSetProperty(new File(wcRoot, "A/B"), "spam", SVNPropertyValue.create("egg"), false,
86 SVNDepth.EMPTY, null, null);
87
88 //commit local changes
89 SVNCommitClient commitClient = clientManager.getCommitClient();
90 commitClient.doCommit(new File[] { wcRoot }, false, "committing changes", null, null, false,
91 false, SVNDepth.INFINITY);
92
93 //6. now merge changes from trunk to the branch.
94 SVNDiffClient diffClient = clientManager.getDiffClient();
95 SVNRevisionRange rangeToMerge = new SVNRevisionRange(SVNRevision.create(1), SVNRevision.HEAD);
96
97 diffClient.doMerge(A_URL, SVNRevision.HEAD, Collections.singleton(rangeToMerge),
98 new File(wcRoot, "A_copy"), SVNDepth.INFINITY, true, false, false, false);
99
100
101 //7. now make some changes to the A tree again and commit them
102 //change file contents of iota and A/D/gamma
103 SamplesUtility.writeToFile(new File(wcRoot, "iota"), "New text2 appended to 'iota'", true);
104 SamplesUtility.writeToFile(new File(wcRoot, "A/D/gamma"), "New text in 'gamma'", false);
105 //remove A/C from version control
106 wcClient.doDelete(new File(wcRoot, "A/C"), false, true, false);
107
108 //commit local changes
109 commitClient.doCommit(new File[] { wcRoot }, false, "committing changes again", null, null,
110 false, false, SVNDepth.INFINITY);
111
112 /* 8. do the same merge call, merge-tracking feature will merge only those revisions
113 * which were not merged yet.
114 */
115 diffClient.doMerge(A_URL, SVNRevision.HEAD, Collections.singleton(rangeToMerge),
116 new File(wcRoot, "A_copy"), SVNDepth.INFINITY, true, false, false, false);
117
118 } catch (SVNException svne) {
119 System.out.println(svne.getErrorMessage());
120 System.exit(1);
121 } catch (IOException ioe) {
122 ioe.printStackTrace();
123 System.exit(1);
124 }
125 }
126 }
Here are some comments on calling doMerge() in this example:
We use a pegged version of doMerge() which allows to merge differences between different revisions of the same file.
- A_URL - URL of the merge source.
SVNRevision.HEAD - peg revision in which A_URL is valid for sure.
- We use the entire revision range - from revisio 1 to HEAD not caring of how already merged revisions are skipped - merge-tracking feature will do that for us.
- Then goes the merge target local path.
We use SVNDepth.INFINITY to recursively merge the whole target tree.
We want to merge only related (by history) objects, so the next parameter is true.
We do not want our merge to delete any versioned files containing local edits or unversioned ones, so passing false.
We do want a real merge to perform, not a just the final status of a potential merge, so passing false.
- We do wand a real merge to perform, not just to record mergeinfo without bringing real changes to A_copy.
Each merge operation in this example is equivalent to the following command line client' command:
svn merge file:///home/alex/workspace/tmp/exampleRepository/A /home/alex/workspace/exampleWC/A_copy
After the first merge, if you run 'svn status' in the working copy you should see this report:
alex@UFO:~/workspace/tmp/exampleWC$ $JSVN_PATH stat M A_copy M A_copy/B M A_copy/mu
And 'svn pg svn:mergeinfo .' in A_copy gives:
alex@UFO:~/workspace/tmp/exampleWC/A_copy$ $JSVN_PATH pg svn:mergeinfo . /A:2-3
After the second merge the status report will look like this:
alex@UFO:~/workspace/tmp/exampleWC$ $JSVN_PATH stat M A_copy D A_copy/C M A_copy/D/gamma
and propget report like this:
alex@UFO:~/workspace/tmp/exampleWC/A_copy$ $JSVN_PATH pg svn:mergeinfo . /A:2-4