001: /*
002: * ====================================================================
003: * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
004: *
005: * This software is licensed as described in the file COPYING, which
006: * you should have received as part of this distribution. The terms
007: * are also available at http://svnkit.com/license.html
008: * If newer versions of this license are posted there, you may use a
009: * newer version instead, at your option.
010: * ====================================================================
011: */
012:
013: package org.tmatesoft.svn.cli.command;
014:
015: import java.io.File;
016: import java.io.InputStream;
017: import java.io.PrintStream;
018:
019: import org.tmatesoft.svn.cli.SVNArgument;
020: import org.tmatesoft.svn.cli.SVNCommand;
021: import org.tmatesoft.svn.core.SVNException;
022: import org.tmatesoft.svn.core.SVNURL;
023: import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
024: import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
025: import org.tmatesoft.svn.core.wc.SVNDiffClient;
026: import org.tmatesoft.svn.core.wc.SVNDiffOptions;
027: import org.tmatesoft.svn.core.wc.SVNRevision;
028:
029: /**
030: * @version 1.1.1
031: * @author TMate Software Ltd.
032: */
033: public class SVNMergeCommand extends SVNCommand {
034:
035: public void run(InputStream in, PrintStream out, PrintStream err)
036: throws SVNException {
037: run(out, err);
038: }
039:
040: public void run(final PrintStream out, PrintStream err)
041: throws SVNException {
042: boolean useAncestry = !getCommandLine().hasArgument(
043: SVNArgument.IGNORE_ANCESTRY);
044: boolean recursive = !getCommandLine().hasArgument(
045: SVNArgument.NON_RECURSIVE);
046: boolean force = getCommandLine().hasArgument(SVNArgument.FORCE);
047: boolean dryRun = getCommandLine().hasArgument(
048: SVNArgument.DRY_RUN);
049:
050: getClientManager().setEventHandler(
051: new SVNCommandEventProcessor(out, err, false, false));
052: SVNDiffClient differ = getClientManager().getDiffClient();
053:
054: if (getCommandLine().hasArgument(SVNArgument.EXTENSIONS)) {
055: SVNDiffOptions diffOptions = new SVNDiffOptions(
056: getCommandLine().hasArgument(
057: SVNArgument.IGNORE_ALL_WS),
058: getCommandLine().hasArgument(
059: SVNArgument.IGNORE_WS_CHANGE),
060: getCommandLine().hasArgument(
061: SVNArgument.IGNORE_EOL_STYLE));
062: differ.setMergeOptions(diffOptions);
063: }
064:
065: if (getCommandLine().hasArgument(SVNArgument.REVISION)
066: || getCommandLine().hasArgument(SVNArgument.CHANGE)) {
067: // merge -rN:M urlOrPath@r wcPath
068: SVNRevision rN = SVNRevision.UNDEFINED;
069: SVNRevision rM = SVNRevision.UNDEFINED;
070: String revStr = (String) getCommandLine().getArgumentValue(
071: SVNArgument.REVISION);
072: if (revStr == null
073: && getCommandLine().hasArgument(SVNArgument.CHANGE)) {
074: long changeRev = Long
075: .parseLong((String) getCommandLine()
076: .getArgumentValue(SVNArgument.CHANGE));
077: if (changeRev >= 0) {
078: rM = SVNRevision.create(changeRev);
079: rN = SVNRevision.create(changeRev - 1);
080: } else {
081: rN = SVNRevision.create(-changeRev);
082: rM = SVNRevision.create((-changeRev) - 1);
083: }
084: } else if (revStr.indexOf(':') <= 0
085: || (revStr.indexOf('{') != -1
086: && revStr.indexOf("}:") == -1 && revStr
087: .indexOf(":{") == -1)) {
088: println(err,
089: "svn: merge needs both source and target revisions to be specified");
090: return;
091: } else {
092: SVNRevision[] revRange = getStartEndRevisions();
093: rN = revRange[0];
094: rM = revRange[1];
095: }
096: if (!rN.isValid() || !rM.isValid()
097: || rN == SVNRevision.WORKING
098: || rM == SVNRevision.WORKING) {
099: println(err,
100: "svn: merge needs both source and target revisions to be specified");
101: return;
102: }
103: if (getCommandLine().hasURLs()) {
104: String url = getCommandLine().getURL(0);
105: SVNRevision pegRev = getCommandLine().getPegRevision(0);
106: File dstPath = null; // try to get path from urls.
107: if (getCommandLine().getPathCount() > 0) {
108: dstPath = new File(getCommandLine().getPathAt(0));
109: }
110: if (dstPath == null) {
111: dstPath = new File(SVNEncodingUtil
112: .uriDecode(SVNPathUtil.tail(url)));
113: if (!dstPath.isFile()) {
114: dstPath = new File(".");
115: }
116: }
117: if (pegRev == SVNRevision.UNDEFINED) {
118: pegRev = SVNRevision.HEAD;
119: }
120: SVNURL svnURL = SVNURL.parseURIEncoded(url);
121: differ.doMerge(svnURL, pegRev, rN, rM, dstPath,
122: recursive, useAncestry, force, dryRun);
123: } else if (getCommandLine().hasPaths()) {
124: File srcPath = new File(getCommandLine().getPathAt(0));
125: SVNRevision pegRevision = getCommandLine()
126: .getPathPegRevision(0);
127: if (pegRevision == SVNRevision.UNDEFINED) {
128: pegRevision = SVNRevision.HEAD;
129: }
130: File dstPath = srcPath;
131: if (getCommandLine().getPathCount() > 1) {
132: dstPath = new File(getCommandLine().getPathAt(1));
133: }
134: differ.doMerge(srcPath, pegRevision, rN, rM, dstPath,
135: recursive, useAncestry, force, dryRun);
136: }
137: } else if (getCommandLine().getURLCount() == 2) {
138: // merge url1@r url2@r wcPath
139: String url1 = getCommandLine().getURL(0);
140: SVNRevision rN = getCommandLine().getPegRevision(0);
141: if (!rN.isValid()) {
142: rN = SVNRevision.HEAD;
143: }
144: String url2 = getCommandLine().getURL(1);
145: SVNRevision rM = getCommandLine().getPegRevision(1);
146: if (!rM.isValid()) {
147: rM = SVNRevision.HEAD;
148: }
149: File dstPath = null;
150: if (getCommandLine().getPathCount() > 0) {
151: dstPath = new File(getCommandLine().getPathAt(0));
152: }
153: if (dstPath == null) {
154: String c1 = SVNPathUtil.tail(url1);
155: String c2 = SVNPathUtil.tail(url2);
156: if (c1.equals(c2)) {
157: dstPath = new File(SVNEncodingUtil.uriDecode(c1));
158: if (!dstPath.isFile()) {
159: dstPath = new File(".");
160: }
161: }
162: }
163: SVNURL svnURL1 = SVNURL.parseURIEncoded(url1);
164: SVNURL svnURL2 = SVNURL.parseURIEncoded(url2);
165:
166: differ.doMerge(svnURL1, rN, svnURL2, rM, dstPath,
167: recursive, useAncestry, force, dryRun);
168: } else if (getCommandLine().getPathCount() >= 2) {
169: // merge wcPath1@r wcPath2@r wcPath
170: File path1 = new File(getCommandLine().getPathAt(0));
171: SVNRevision rN = getCommandLine().getPathPegRevision(0);
172: if (!rN.isValid()) {
173: rN = SVNRevision.HEAD;
174: }
175: File path2 = new File(getCommandLine().getPathAt(1));
176: SVNRevision rM = getCommandLine().getPathPegRevision(1);
177: if (!rM.isValid()) {
178: rM = SVNRevision.HEAD;
179: }
180: File dstPath = new File(".");
181: if (getCommandLine().getPathCount() > 2) {
182: dstPath = new File(getCommandLine().getPathAt(2));
183: }
184: differ.doMerge(path1, rN, path2, rM, dstPath, recursive,
185: useAncestry, force, dryRun);
186: } else {
187: println(err, "svn: unsupported merge call format");
188: }
189: }
190: }
|