Source Code Cross Referenced for HgCommand.java in  » IDE-Netbeans » mercurial » org » netbeans » modules » mercurial » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » mercurial » org.netbeans.modules.mercurial.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.modules.mercurial.util;
0043:
0044:        import java.awt.EventQueue;
0045:        import java.io.BufferedReader;
0046:        import java.io.BufferedWriter;
0047:        import java.io.FileWriter;
0048:        import java.io.File;
0049:        import java.io.IOException;
0050:        import java.io.InterruptedIOException;
0051:        import java.io.InputStreamReader;
0052:        import java.io.PrintWriter;
0053:        import java.text.ParseException;
0054:        import java.text.SimpleDateFormat;
0055:        import java.util.ArrayList;
0056:        import java.util.Date;
0057:        import java.util.HashMap;
0058:        import java.util.Iterator;
0059:        import java.util.LinkedList;
0060:        import java.util.List;
0061:        import java.util.Map;
0062:        import java.util.Set;
0063:        import java.util.logging.Level;
0064:        import org.netbeans.api.options.OptionsDisplayer;
0065:        import org.openide.util.NbBundle;
0066:        import org.netbeans.modules.mercurial.FileInformation;
0067:        import org.netbeans.modules.mercurial.FileStatus;
0068:        import org.netbeans.modules.mercurial.HgException;
0069:        import org.netbeans.modules.mercurial.Mercurial;
0070:        import org.netbeans.modules.mercurial.OutputLogger;
0071:        import org.netbeans.api.queries.SharabilityQuery;
0072:        import org.netbeans.modules.mercurial.HgModuleConfig;
0073:        import org.netbeans.modules.mercurial.config.HgConfigFiles;
0074:        import org.netbeans.modules.mercurial.ui.log.HgLogMessage;
0075:        import org.openide.DialogDisplayer;
0076:        import org.openide.NotifyDescriptor;
0077:        import org.openide.util.Utilities;
0078:
0079:        /**
0080:         *
0081:         * @author jrice
0082:         */
0083:        public class HgCommand {
0084:            public static final String HG_COMMAND = "hg"; // NOI18N
0085:            public static final String HG_WINDOWS_EXE = ".exe"; // NOI18N
0086:            public static final String HG_WINDOWS_CMD = ".cmd"; // NOI18N
0087:            public static final String HGK_COMMAND = "hgk"; // NOI18N
0088:
0089:            private static final String HG_STATUS_CMD = "status"; // NOI18N // need -A to see ignored files, specified in .hgignore, see man hgignore for details
0090:            private static final String HG_OPT_REPOSITORY = "--repository"; // NOI18N
0091:            private static final String HG_OPT_BUNDLE = "--bundle"; // NOI18N
0092:            private static final String HG_OPT_CWD_CMD = "--cwd"; // NOI18N
0093:            private static final String HG_OPT_USERNAME = "--user"; // NOI18N
0094:
0095:            private static final String HG_OPT_FOLLOW = "--follow"; // NOI18N
0096:            private static final String HG_STATUS_FLAG_ALL_CMD = "-marduicC"; // NOI18N
0097:            private static final String HG_FLAG_REV_CMD = "--rev"; // NOI18N
0098:            private static final String HG_STATUS_FLAG_TIP_CMD = "tip"; // NOI18N
0099:            private static final String HG_STATUS_FLAG_REM_DEL_CMD = "-rd"; // NOI18N
0100:            private static final String HG_STATUS_FLAG_INCLUDE_CMD = "-I"; // NOI18N
0101:            private static final String HG_STATUS_FLAG_INCLUDE_GLOB_CMD = "glob:"; // NOI18N
0102:            private static final String HG_STATUS_FLAG_INCLUDE_END_CMD = "*"; // NOI18N
0103:            private static final String HG_STATUS_FLAG_INTERESTING_CMD = "-marduC"; // NOI18N
0104:            private static final String HG_STATUS_FLAG_UNKNOWN_CMD = "-u"; // NOI18N
0105:            private static final String HG_HEAD_STR = "HEAD"; // NOI18N
0106:            private static final String HG_FLAG_DATE_CMD = "--date"; // NOI18N
0107:
0108:            private static final String HG_COMMIT_CMD = "commit"; // NOI18N
0109:            private static final String HG_COMMIT_OPT_LOGFILE_CMD = "--logfile"; // NOI18N
0110:            private static final String HG_COMMIT_TEMPNAME = "hgcommit"; // NOI18N
0111:            private static final String HG_COMMIT_TEMPNAME_SUFFIX = ".hgm"; // NOI18N
0112:            private static final String HG_COMMIT_DEFAULT_MESSAGE = "[no commit message]"; // NOI18N
0113:
0114:            private static final String HG_REVERT_CMD = "revert"; // NOI18N
0115:            private static final String HG_REVERT_NOBACKUP_CMD = "--no-backup"; // NOI18N
0116:            private static final String HG_ADD_CMD = "add"; // NOI18N
0117:
0118:            private static final String HG_BRANCH_CMD = "branch"; // NOI18N
0119:            private static final String HG_BRANCH_REV_CMD = "tip"; // NOI18N
0120:            private static final String HG_BRANCH_REV_TEMPLATE_CMD = "--template={rev}\\n"; // NOI18N
0121:            private static final String HG_BRANCH_SHORT_CS_TEMPLATE_CMD = "--template={node|short}\\n"; // NOI18N
0122:            private static final String HG_BRANCH_INFO_TEMPLATE_CMD = "--template={branches}:{rev}:{node|short}\\n"; // NOI18N
0123:            private static final String HG_GET_PREVIOUS_TEMPLATE_CMD = "--template={files}\\n"; // NOI18N
0124:
0125:            private static final String HG_CREATE_CMD = "init"; // NOI18N
0126:            private static final String HG_CLONE_CMD = "clone"; // NOI18N
0127:
0128:            private static final String HG_UPDATE_ALL_CMD = "update"; // NOI18N
0129:            private static final String HG_UPDATE_FORCE_ALL_CMD = "-C"; // NOI18N
0130:
0131:            private static final String HG_REMOVE_CMD = "remove"; // NOI18N
0132:            private static final String HG_REMOVE_FLAG_FORCE_CMD = "--force"; // NOI18N
0133:
0134:            private static final String HG_LOG_CMD = "log"; // NOI18N
0135:            private static final String HG_OUT_CMD = "out"; // NOI18N
0136:            private static final String HG_LOG_LIMIT_ONE_CMD = "-l 1"; // NOI18N
0137:            private static final String HG_LOG_LIMIT_CMD = "-l"; // NOI18N
0138:            private static final String HG_LOG_TEMPLATE_SHORT_CMD = "--template={rev}\\n{desc|firstline}\\n{date|hgdate}\\n{node|short}\\n"; // NOI18N
0139:            private static final String HG_LOG_TEMPLATE_LONG_CMD = "--template={rev}\\n{desc}\\n{date|hgdate}\\n{node|short}\\n"; // NOI18N
0140:
0141:            private static final String HG_LOG_NO_MERGES_CMD = "-M";
0142:            private static final String HG_LOG_DEBUG_CMD = "--debug";
0143:            private static final String HG_LOG_TEMPLATE_HISTORY_CMD = "--template=rev:{rev}\\nauth:{author}\\ndesc:{desc}\\ndate:{date|hgdate}\\nid:{node|short}\\n"
0144:                    + // NOI18N
0145:                    "file_mods:{files}\\nfile_adds:{file_adds}\\nfile_dels:{file_dels}\\nfile_copies:\\nendCS:\\n"; // NOI18N
0146:            private static final String HG_LOG_REVISION_OUT = "rev:"; // NOI18N
0147:            private static final String HG_LOG_AUTHOR_OUT = "auth:"; // NOI18N
0148:            private static final String HG_LOG_DESCRIPTION_OUT = "desc:"; // NOI18N
0149:            private static final String HG_LOG_DATE_OUT = "date:"; // NOI18N
0150:            private static final String HG_LOG_ID_OUT = "id:"; // NOI18N
0151:            private static final String HG_LOG_FILEMODS_OUT = "file_mods:"; // NOI18N
0152:            private static final String HG_LOG_FILEADDS_OUT = "file_adds:"; // NOI18N
0153:            private static final String HG_LOG_FILEDELS_OUT = "file_dels:"; // NOI18N
0154:            private static final String HG_LOG_FILECOPIESS_OUT = "file_copies:"; // NOI18N
0155:            private static final String HG_LOG_ENDCS_OUT = "endCS:"; // NOI18N
0156:
0157:            private static final String HG_LOG_PATCH_CMD = "-p";
0158:            private static final String HG_LOG_TEMPLATE_EXPORT_FILE_CMD = "--template=# Mercurial Export File Diff\\n# changeset: \\t{rev}:{node|short}\\n# user:\\t\\t{author}\\n# date:\\t\\t{date|isodate}\\n# summary:\\t{desc}\\n\\n";
0159:
0160:            private static final String HG_CSET_TEMPLATE_CMD = "--template={rev}:{node|short}\\n"; // NOI18N
0161:            private static final String HG_REV_TEMPLATE_CMD = "--template={rev}\\n"; // NOI18N
0162:            private static final String HG_CSET_TARGET_TEMPLATE_CMD = "--template={rev} ({node|short})\\n"; // NOI18N
0163:
0164:            private static final String HG_CAT_CMD = "cat"; // NOI18N
0165:            private static final String HG_FLAG_OUTPUT_CMD = "--output"; // NOI18N
0166:
0167:            private static final String HG_ANNOTATE_CMD = "annotate"; // NOI18N
0168:            private static final String HG_ANNOTATE_FLAGN_CMD = "--number"; // NOI18N
0169:            private static final String HG_ANNOTATE_FLAGU_CMD = "--user"; // NOI18N
0170:
0171:            private static final String HG_EXPORT_CMD = "export"; // NOI18N
0172:            private static final String HG_IMPORT_CMD = "import"; // NOI18N
0173:
0174:            private static final String HG_RENAME_CMD = "rename"; // NOI18N
0175:            private static final String HG_RENAME_AFTER_CMD = "-A"; // NOI18N
0176:            private static final String HG_PATH_DEFAULT_CMD = "paths"; // NOI18N
0177:            private static final String HG_PATH_DEFAULT_OPT = "default"; // NOI18N
0178:            private static final String HG_PATH_DEFAULT_PUSH_OPT = "default-push"; // NOI18N
0179:
0180:            // TODO: replace this hack 
0181:            // Causes /usr/bin/hgmerge script to return when a merge
0182:            // has conflicts with exit 0, instead of throwing up EDITOR. 
0183:            // Problem is after this Hg thinks the merge succeded and no longer
0184:            // marks repository with a merge needed flag. So Plugin needs to 
0185:            // track this merge required status by changing merge conflict file
0186:            // status. If the cache is removed this information would be lost.
0187:            //
0188:            // Really need Hg to give us back merge status information, 
0189:            // which it currently does not
0190:            private static final String HG_MERGE_CMD = "merge"; // NOI18N
0191:            private static final String HG_MERGE_FORCE_CMD = "-f"; // NOI18N
0192:            private static final String HG_MERGE_ENV = "EDITOR=success || $TEST -s"; // NOI18N
0193:
0194:            public static final String HG_HGK_PATH_SOLARIS10 = "/usr/demo/mercurial"; // NOI18N
0195:            private static final String HG_HGK_PATH_SOLARIS10_ENV = "PATH=/usr/bin/:/usr/sbin:/bin:"
0196:                    + HG_HGK_PATH_SOLARIS10; // NOI18N
0197:
0198:            private static final String HG_PULL_CMD = "pull"; // NOI18N
0199:            private static final String HG_UPDATE_CMD = "-u"; // NOI18N
0200:            private static final String HG_PUSH_CMD = "push"; // NOI18N
0201:            private static final String HG_UNBUNDLE_CMD = "unbundle"; // NOI18N
0202:            private static final String HG_ROLLBACK_CMD = "rollback"; // NOI18N
0203:            private static final String HG_BACKOUT_CMD = "backout"; // NOI18N
0204:            private static final String HG_BACKOUT_MERGE_CMD = "--merge"; // NOI18N
0205:            private static final String HG_BACKOUT_COMMIT_MSG_CMD = "-m"; // NOI18N
0206:            private static final String HG_REV_CMD = "-r"; // NOI18N
0207:
0208:            private static final String HG_STRIP_CMD = "strip"; // NOI18N
0209:            private static final String HG_STRIP_EXT_CMD = "extensions.mq="; // NOI18N
0210:            private static final String HG_STRIP_NOBACKUP_CMD = "-n"; // NOI18N
0211:            private static final String HG_STRIP_FORCE_MULTIHEAD_CMD = "-f"; // NOI18N
0212:
0213:            private static final String HG_VERSION_CMD = "version"; // NOI18N
0214:            private static final String HG_INCOMING_CMD = "incoming"; // NOI18N
0215:            private static final String HG_OUTGOING_CMD = "outgoing"; // NOI18N
0216:            private static final String HG_VIEW_CMD = "view"; // NOI18N
0217:            private static final String HG_VERBOSE_CMD = "-v"; // NOI18N
0218:            private static final String HG_CONFIG_OPTION_CMD = "--config"; // NOI18N
0219:            private static final String HG_FETCH_EXT_CMD = "extensions.fetch="; // NOI18N
0220:            private static final String HG_FETCH_CMD = "fetch"; // NOI18N
0221:            public static final String HG_PROXY_ENV = "http_proxy="; // NOI18N
0222:
0223:            private static final String HG_MERGE_NEEDED_ERR = "(run 'hg heads' to see heads, 'hg merge' to merge)"; // NOI18N
0224:            public static final String HG_MERGE_CONFLICT_ERR = "conflicts detected in "; // NOI18N
0225:            public static final String HG_MERGE_CONFLICT_WIN1_ERR = "merging"; // NOI18N
0226:            public static final String HG_MERGE_CONFLICT_WIN2_ERR = "failed!"; // NOI18N
0227:            private static final String HG_MERGE_MULTIPLE_HEADS_ERR = "abort: repo has "; // NOI18N
0228:            private static final String HG_MERGE_UNCOMMITTED_ERR = "abort: outstanding uncommitted merges"; // NOI18N
0229:
0230:            private static final String HG_MERGE_UNAVAILABLE_ERR = "is not recognized as an internal or external command";
0231:
0232:            private static final String HG_NO_CHANGES_ERR = "no changes found"; // NOI18N
0233:            private final static String HG_CREATE_NEW_BRANCH_ERR = "abort: push creates new remote branches!"; // NOI18N
0234:            private final static String HG_HEADS_CREATED_ERR = "(+1 heads)"; // NOI18N
0235:            private final static String HG_NO_HG_CMD_FOUND_ERR = "hg: not found";
0236:            private final static String HG_ARG_LIST_TOO_LONG_ERR = "Arg list too long";
0237:
0238:            private final static String HG_HEADS_CMD = "heads"; // NOI18N
0239:
0240:            private static final String HG_NO_REPOSITORY_ERR = "There is no Mercurial repository here"; // NOI18N
0241:            private static final String HG_NO_RESPONSE_ERR = "no suitable response from remote hg!"; // NOI18N
0242:            private static final String HG_NOT_REPOSITORY_ERR = "does not appear to be an hg repository"; // NOI18N
0243:            private static final String HG_REPOSITORY = "repository"; // NOI18N
0244:            private static final String HG_NOT_FOUND_ERR = "not found!"; // NOI18N
0245:            private static final String HG_UPDATE_SPAN_BRANCHES_ERR = "abort: update spans branches"; // NOI18N
0246:            private static final String HG_ALREADY_TRACKED_ERR = " already tracked!"; // NOI18N
0247:            private static final String HG_NOT_TRACKED_ERR = " no tracked!"; // NOI18N
0248:            private static final String HG_CANNOT_READ_COMMIT_MESSAGE_ERR = "abort: can't read commit message"; // NOI18N
0249:            private static final String HG_CANNOT_RUN_ERR = "Cannot run program"; // NOI18N
0250:            private static final String HG_ABORT_ERR = "abort: "; // NOI18N
0251:            private static final String HG_ABORT_PUSH_ERR = "abort: push creates new remote branches!"; // NOI18N
0252:            private static final String HG_ABORT_NO_FILES_TO_COPY_ERR = "abort: no files to copy"; // NOI18N
0253:            private static final String HG_ABORT_NO_DEFAULT_PUSH_ERR = "abort: repository default-push not found!"; // NOI18N
0254:            private static final String HG_ABORT_NO_DEFAULT_ERR = "abort: repository default not found!"; // NOI18N
0255:            private static final String HG_ABORT_POSSIBLE_PROXY_ERR = "abort: error: node name or service name not known"; // NOI18N
0256:            private static final String HG_ABORT_UNCOMMITTED_CHANGES_ERR = "abort: outstanding uncommitted changes"; // NOI18N
0257:            private static final String HG_BACKOUT_MERGE_NEEDED_ERR = "(use \"backout --merge\" if you want to auto-merge)";
0258:            private static final String HG_ABORT_BACKOUT_MERGE_CSET_ERR = "abort: cannot back out a merge changeset without --parent"; // NOI18N"
0259:
0260:            private static final String HG_NO_CHANGE_NEEDED_ERR = "no change needed"; // NOI18N
0261:            private static final String HG_NO_ROLLBACK_ERR = "no rollback information available"; // NOI18N
0262:            private static final String HG_NO_UPDATES_ERR = "0 files updated, 0 files merged, 0 files removed, 0 files unresolved"; // NOI18N
0263:            private static final String HG_NO_VIEW_ERR = "hg: unknown command 'view'"; // NOI18N
0264:            private static final String HG_HGK_NOT_FOUND_ERR = "sh: hgk: not found"; // NOI18N
0265:            private static final String HG_NO_SUCH_FILE_ERR = "No such file"; // NOI18N
0266:
0267:            private static final String HG_NO_REV_STRIP_ERR = "abort: unknown revision"; // NOI18N
0268:            private static final String HG_LOCAL_CHANGES_STRIP_ERR = "abort: local changes found"; // NOI18N
0269:            private static final String HG_MULTIPLE_HEADS_STRIP_ERR = "no rollback information available"; // NOI18N
0270:
0271:            private static final char HG_STATUS_CODE_MODIFIED = 'M' + ' '; // NOI18N // STATUS_VERSIONED_MODIFIEDLOCALLY
0272:            private static final char HG_STATUS_CODE_ADDED = 'A' + ' '; // NOI18N // STATUS_VERSIONED_ADDEDLOCALLY
0273:            private static final char HG_STATUS_CODE_REMOVED = 'R' + ' '; // NOI18N  // STATUS_VERSIONED_REMOVEDLOCALLY - still tracked, hg update will recover, hg commit
0274:            private static final char HG_STATUS_CODE_CLEAN = 'C' + ' '; // NOI18N  // STATUS_VERSIONED_UPTODATE
0275:            private static final char HG_STATUS_CODE_DELETED = '!' + ' '; // NOI18N // STATUS_VERSIONED_DELETEDLOCALLY - still tracked, hg update will recover, hg commit no effect
0276:            private static final char HG_STATUS_CODE_NOTTRACKED = '?' + ' '; // NOI18N // STATUS_NOTVERSIONED_NEWLOCALLY - not tracked
0277:            private static final char HG_STATUS_CODE_IGNORED = 'I' + ' '; // NOI18N // STATUS_NOTVERSIONED_EXCLUDE - not shown by default
0278:            private static final char HG_STATUS_CODE_CONFLICT = 'X' + ' '; // NOI18N // STATUS_VERSIONED_CONFLICT - TODO when Hg status supports conflict markers
0279:
0280:            private static final char HG_STATUS_CODE_ABORT = 'a' + 'b'; // NOI18N
0281:            public static final String HG_STR_CONFLICT_EXT = ".conflict~"; // NOI18N
0282:
0283:            private static final String HG_EPOCH_PLUS_ONE_YEAR = "1971-01-01"; // NOI18N    
0284:
0285:            /**
0286:             * Merge working directory with the head revision
0287:             * Merge the contents of the current working directory and the
0288:             * requested revision. Files that changed between either parent are
0289:             * marked as changed for the next commit and a commit must be
0290:             * performed before any further updates are allowed.
0291:             *
0292:             * @param File repository of the mercurial repository's root directory
0293:             * @param Revision to merge with, if null will merge with default tip rev
0294:             * @return hg merge output
0295:             * @throws HgException
0296:             */
0297:            public static List<String> doMerge(File repository, String revStr)
0298:                    throws HgException {
0299:                if (repository == null)
0300:                    return null;
0301:                List<String> command = new ArrayList<String>();
0302:                List<String> env = new ArrayList<String>();
0303:
0304:                command.add(getHgCommand());
0305:                command.add(HG_MERGE_CMD);
0306:                command.add(HG_MERGE_FORCE_CMD);
0307:                command.add(HG_OPT_REPOSITORY);
0308:                command.add(repository.getAbsolutePath());
0309:                if (revStr != null)
0310:                    command.add(revStr);
0311:                env.add(HG_MERGE_ENV);
0312:
0313:                List<String> list = execEnv(command, env);
0314:                return list;
0315:            }
0316:
0317:            /**
0318:             * Update the working directory to the tip revision.
0319:             * By default, update will refuse to run if doing so would require
0320:             * merging or discarding local changes.
0321:             *
0322:             * @param File repository of the mercurial repository's root directory
0323:             * @param Boolean force an Update and overwrite any modified files in the  working directory
0324:             * @param String revision to be updated to
0325:             * @param Boolean throw exception on error
0326:             * @return hg update output
0327:             * @throws org.netbeans.modules.mercurial.HgException
0328:             */
0329:            public static List<String> doUpdateAll(File repository,
0330:                    boolean bForce, String revision, boolean bThrowException)
0331:                    throws HgException {
0332:                if (repository == null)
0333:                    return null;
0334:                List<String> command = new ArrayList<String>();
0335:
0336:                command.add(getHgCommand());
0337:                command.add(HG_UPDATE_ALL_CMD);
0338:                if (bForce)
0339:                    command.add(HG_UPDATE_FORCE_ALL_CMD);
0340:                command.add(HG_OPT_REPOSITORY);
0341:                command.add(repository.getAbsolutePath());
0342:                if (revision != null) {
0343:                    command.add(revision);
0344:                }
0345:
0346:                List<String> list = exec(command);
0347:                if (bThrowException) {
0348:                    if (!list.isEmpty()) {
0349:                        if (isErrorUpdateSpansBranches(list.get(0))) {
0350:                            throw new HgException(NbBundle.getMessage(
0351:                                    HgCommand.class,
0352:                                    "MSG_WARN_UPDATE_MERGE_TEXT"));
0353:                        } else if (isMergeAbortUncommittedMsg(list.get(0))) {
0354:                            throw new HgException(NbBundle.getMessage(
0355:                                    HgCommand.class,
0356:                                    "MSG_WARN_UPDATE_COMMIT_TEXT"));
0357:                        }
0358:                    }
0359:                }
0360:                return list;
0361:            }
0362:
0363:            public static List<String> doUpdateAll(File repository,
0364:                    boolean bForce, String revision) throws HgException {
0365:                return doUpdateAll(repository, bForce, revision, true);
0366:            }
0367:
0368:            /**
0369:             * Roll back the last transaction in this repository
0370:             * Transactions are used to encapsulate the effects of all commands
0371:             * that create new changesets or propagate existing changesets into a
0372:             * repository. For example, the following commands are transactional,
0373:             * and their effects can be rolled back:
0374:             * commit, import, pull, push (with this repository as destination)
0375:             * unbundle
0376:             * There is only one level of rollback, and there is no way to undo a rollback.
0377:             *
0378:             * @param File repository of the mercurial repository's root directory
0379:             * @return hg update output
0380:             * @throws org.netbeans.modules.mercurial.HgException
0381:             */
0382:            public static List<String> doRollback(File repository,
0383:                    OutputLogger logger) throws HgException {
0384:                if (repository == null)
0385:                    return null;
0386:                List<String> command = new ArrayList<String>();
0387:
0388:                command.add(getHgCommand());
0389:                command.add(HG_ROLLBACK_CMD);
0390:                command.add(HG_OPT_REPOSITORY);
0391:                command.add(repository.getAbsolutePath());
0392:
0393:                List<String> list = exec(command);
0394:                if (list.isEmpty())
0395:                    handleError(command, list, NbBundle.getMessage(
0396:                            HgCommand.class, "MSG_ROLLBACK_FAILED"), logger);
0397:
0398:                return list;
0399:            }
0400:
0401:            public static List<String> doBackout(File repository,
0402:                    String revision, boolean doMerge, String commitMsg,
0403:                    OutputLogger logger) throws HgException {
0404:                if (repository == null)
0405:                    return null;
0406:                List<String> env = new ArrayList<String>();
0407:                List<String> command = new ArrayList<String>();
0408:
0409:                command.add(getHgCommand());
0410:                command.add(HG_BACKOUT_CMD);
0411:                if (doMerge) {
0412:                    command.add(HG_BACKOUT_MERGE_CMD);
0413:                    env.add(HG_MERGE_ENV);
0414:                }
0415:
0416:                if (commitMsg != null && !commitMsg.equals("")) { // NOI18N
0417:                    command.add(HG_BACKOUT_COMMIT_MSG_CMD);
0418:                    command.add(commitMsg);
0419:                } else {
0420:                    command.add(HG_BACKOUT_COMMIT_MSG_CMD);
0421:                    command.add(NbBundle.getMessage(HgCommand.class,
0422:                            "MSG_BACKOUT_MERGE_COMMIT_MSG", revision)); // NOI18N          
0423:                }
0424:
0425:                command.add(HG_OPT_REPOSITORY);
0426:                command.add(repository.getAbsolutePath());
0427:                if (revision != null) {
0428:                    command.add(HG_REV_CMD);
0429:                    command.add(revision);
0430:                }
0431:
0432:                List<String> list;
0433:                if (doMerge) {
0434:                    list = execEnv(command, env);
0435:                } else {
0436:                    list = exec(command);
0437:                }
0438:                if (list.isEmpty())
0439:                    handleError(command, list, NbBundle.getMessage(
0440:                            HgCommand.class, "MSG_BACKOUT_FAILED"), logger);
0441:
0442:                return list;
0443:            }
0444:
0445:            public static List<String> doStrip(File repository,
0446:                    String revision, boolean doForceMultiHead,
0447:                    boolean doBackup, OutputLogger logger) throws HgException {
0448:                if (repository == null)
0449:                    return null;
0450:                List<String> command = new ArrayList<String>();
0451:
0452:                command.add(getHgCommand());
0453:                command.add(HG_CONFIG_OPTION_CMD);
0454:                command.add(HG_STRIP_EXT_CMD);
0455:                command.add(HG_STRIP_CMD);
0456:                if (doForceMultiHead) {
0457:                    command.add(HG_STRIP_FORCE_MULTIHEAD_CMD);
0458:                }
0459:                if (!doBackup) {
0460:                    command.add(HG_STRIP_NOBACKUP_CMD);
0461:                }
0462:                command.add(HG_OPT_REPOSITORY);
0463:                command.add(repository.getAbsolutePath());
0464:                if (revision != null) {
0465:                    command.add(revision);
0466:                }
0467:
0468:                List<String> list = exec(command);
0469:                if (list.isEmpty())
0470:                    handleError(command, list, NbBundle.getMessage(
0471:                            HgCommand.class, "MSG_STRIP_FAILED"), logger);
0472:
0473:                return list;
0474:            }
0475:
0476:            /**
0477:             * Return the version of hg, e.g. "0.9.3". // NOI18N
0478:             *
0479:             * @return String
0480:             */
0481:            public static String getHgVersion() {
0482:                List<String> list = new LinkedList<String>();
0483:                try {
0484:                    list = execForVersionCheck();
0485:                } catch (HgException ex) {
0486:                    // Ignore Exception
0487:                    return null;
0488:                }
0489:                if (!list.isEmpty()) {
0490:                    int start = list.get(0).indexOf('(');
0491:                    int end = list.get(0).indexOf(')');
0492:                    if (start != -1 && end != -1) {
0493:                        return list.get(0).substring(start + 9, end);
0494:                    }
0495:                }
0496:                return null;
0497:            }
0498:
0499:            /**
0500:             * Pull changes from the default pull locarion and update working directory.
0501:             * By default, update will refuse to run if doing so would require
0502:             * merging or discarding local changes.
0503:             *
0504:             * @param File repository of the mercurial repository's root directory
0505:             * @return hg pull output
0506:             * @throws org.netbeans.modules.mercurial.HgException
0507:             */
0508:            public static List<String> doPull(File repository,
0509:                    OutputLogger logger) throws HgException {
0510:                return doPull(repository, null, logger);
0511:            }
0512:
0513:            /**
0514:             * Pull changes from the specified repository and
0515:             * update working directory.
0516:             * By default, update will refuse to run if doing so would require
0517:             * merging or discarding local changes.
0518:             *
0519:             * @param File repository of the mercurial repository's root directory
0520:             * @param String source repository to pull from
0521:             * @return hg pull output
0522:             * @throws org.netbeans.modules.mercurial.HgException
0523:             */
0524:            public static List<String> doPull(File repository, String from,
0525:                    OutputLogger logger) throws HgException {
0526:                if (repository == null)
0527:                    return null;
0528:                List<String> command = new ArrayList<String>();
0529:
0530:                command.add(getHgCommand());
0531:                command.add(HG_PULL_CMD);
0532:                command.add(HG_UPDATE_CMD);
0533:                command.add(HG_OPT_REPOSITORY);
0534:                command.add(repository.getAbsolutePath());
0535:                if (from != null) {
0536:                    command.add(from);
0537:                }
0538:
0539:                List<String> list;
0540:                String defaultPull = new HgConfigFiles(repository)
0541:                        .getDefaultPull(false);
0542:                String proxy = getGlobalProxyIfNeeded(defaultPull, true, logger);
0543:                if (proxy != null) {
0544:                    List<String> env = new ArrayList<String>();
0545:                    env.add(HG_PROXY_ENV + proxy);
0546:                    list = execEnv(command, env);
0547:                } else {
0548:                    list = exec(command);
0549:                }
0550:
0551:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
0552:                    handleError(command, list, NbBundle.getMessage(
0553:                            HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0554:                }
0555:                return list;
0556:            }
0557:
0558:            /**
0559:             * Unbundle changes from the specified local source repository and
0560:             * update working directory.
0561:             * By default, update will refuse to run if doing so would require
0562:             * merging or discarding local changes.
0563:             *
0564:             * @param File repository of the mercurial repository's root directory
0565:             * @param File bundle identfies the compressed changegroup file to be applied
0566:             * @return hg unbundle output
0567:             * @throws org.netbeans.modules.mercurial.HgException
0568:             */
0569:            public static List<String> doUnbundle(File repository, File bundle,
0570:                    OutputLogger logger) throws HgException {
0571:                if (repository == null)
0572:                    return null;
0573:                List<String> command = new ArrayList<String>();
0574:
0575:                command.add(getHgCommand());
0576:                command.add(HG_UNBUNDLE_CMD);
0577:                command.add(HG_UPDATE_CMD);
0578:                command.add(HG_OPT_REPOSITORY);
0579:                command.add(repository.getAbsolutePath());
0580:                if (bundle != null) {
0581:                    command.add(bundle.getAbsolutePath());
0582:                }
0583:
0584:                List<String> list = exec(command);
0585:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
0586:                    handleError(command, list, NbBundle.getMessage(
0587:                            HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0588:                }
0589:                return list;
0590:            }
0591:
0592:            /**
0593:             * Show the changesets that would be pulled if a pull
0594:             * was requested from the default pull location
0595:             *
0596:             * @param File repository of the mercurial repository's root directory
0597:             * @return hg incoming output
0598:             * @throws org.netbeans.modules.mercurial.HgException
0599:             */
0600:            public static List<String> doIncoming(File repository,
0601:                    OutputLogger logger) throws HgException {
0602:                return doIncoming(repository, null, null, logger);
0603:            }
0604:
0605:            /**
0606:             * Show the changesets that would be pulled if a pull
0607:             * was requested from the specified repository
0608:             *
0609:             * @param File repository of the mercurial repository's root directory
0610:             * @param String source repository to query
0611:             * @param File bundle to store downloaded changesets.
0612:             * @return hg incoming output
0613:             * @throws org.netbeans.modules.mercurial.HgException
0614:             */
0615:            public static List<String> doIncoming(File repository, String from,
0616:                    File bundle, OutputLogger logger) throws HgException {
0617:                if (repository == null)
0618:                    return null;
0619:                List<String> command = new ArrayList<String>();
0620:
0621:                command.add(getHgCommand());
0622:                command.add(HG_INCOMING_CMD);
0623:                command.add(HG_VERBOSE_CMD);
0624:                command.add(HG_OPT_REPOSITORY);
0625:                command.add(repository.getAbsolutePath());
0626:                if (bundle != null) {
0627:                    command.add(HG_OPT_BUNDLE);
0628:                    command.add(bundle.getAbsolutePath());
0629:                }
0630:                if (from != null) {
0631:                    command.add(from);
0632:                }
0633:
0634:                List<String> list;
0635:                String defaultPull = new HgConfigFiles(repository)
0636:                        .getDefaultPull(false);
0637:                String proxy = getGlobalProxyIfNeeded(defaultPull, false, null);
0638:                if (proxy != null) {
0639:                    List<String> env = new ArrayList<String>();
0640:                    env.add(HG_PROXY_ENV + proxy);
0641:                    list = execEnv(command, env);
0642:                } else {
0643:                    list = exec(command);
0644:                }
0645:
0646:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
0647:                    handleError(command, list, NbBundle.getMessage(
0648:                            HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0649:                }
0650:                return list;
0651:            }
0652:
0653:            /**
0654:             * Show the changesets that would be pushed if a push
0655:             * was requested to the specified local source repository
0656:             *
0657:             * @param File repository of the mercurial repository's root directory
0658:             * @param String source repository to query
0659:             * @return hg outgoing output
0660:             * @throws org.netbeans.modules.mercurial.HgException
0661:             */
0662:            public static List<String> doOutgoing(File repository, String to,
0663:                    OutputLogger logger) throws HgException {
0664:                if (repository == null)
0665:                    return null;
0666:                List<String> command = new ArrayList<String>();
0667:
0668:                command.add(getHgCommand());
0669:                command.add(HG_OUTGOING_CMD);
0670:                command.add(HG_VERBOSE_CMD);
0671:                command.add(HG_OPT_REPOSITORY);
0672:                command.add(repository.getAbsolutePath());
0673:                command.add(to);
0674:
0675:                List<String> list;
0676:                String defaultPush = new HgConfigFiles(repository)
0677:                        .getDefaultPush(false);
0678:                String proxy = getGlobalProxyIfNeeded(defaultPush, false, null);
0679:                if (proxy != null) {
0680:                    List<String> env = new ArrayList<String>();
0681:                    env.add(HG_PROXY_ENV + proxy);
0682:                    list = execEnv(command, env);
0683:                } else {
0684:                    list = exec(command);
0685:                }
0686:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
0687:                    handleError(command, list, NbBundle.getMessage(
0688:                            HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0689:                }
0690:                return list;
0691:            }
0692:
0693:            /**
0694:             * Push changes to the specified repository
0695:             * By default, push will refuse to run if doing so would create multiple heads
0696:             *
0697:             * @param File repository of the mercurial repository's root directory
0698:             * @param String source repository to push to
0699:             * @return hg push output
0700:             * @throws org.netbeans.modules.mercurial.HgException
0701:             */
0702:            public static List<String> doPush(File repository, String to,
0703:                    OutputLogger logger) throws HgException {
0704:                if (repository == null || to == null)
0705:                    return null;
0706:                List<String> command = new ArrayList<String>();
0707:
0708:                command.add(getHgCommand());
0709:                command.add(HG_PUSH_CMD);
0710:                command.add(HG_OPT_REPOSITORY);
0711:                command.add(repository.getAbsolutePath());
0712:                command.add(to);
0713:
0714:                List<String> list;
0715:                String defaultPush = new HgConfigFiles(repository)
0716:                        .getDefaultPush(false);
0717:                String proxy = getGlobalProxyIfNeeded(defaultPush, true, logger);
0718:                if (proxy != null) {
0719:                    List<String> env = new ArrayList<String>();
0720:                    env.add(HG_PROXY_ENV + proxy);
0721:                    list = execEnv(command, env);
0722:                } else {
0723:                    list = exec(command);
0724:                }
0725:
0726:                if (!list.isEmpty()
0727:                        && !isErrorAbortPush(list.get(list.size() - 1))
0728:                        && isErrorAbort(list.get(list.size() - 1))) {
0729:                    handleError(command, list, NbBundle.getMessage(
0730:                            HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0731:                }
0732:                return list;
0733:            }
0734:
0735:            /**
0736:             * Run the command hg view for the specified repository
0737:             *
0738:             * @param File repository of the mercurial repository's root directory
0739:             * @throws org.netbeans.modules.mercurial.HgException
0740:             */
0741:            public static List<String> doView(File repository,
0742:                    OutputLogger logger) throws HgException {
0743:                if (repository == null)
0744:                    return null;
0745:                List<String> command = new ArrayList<String>();
0746:                List<String> env = new ArrayList<String>();
0747:
0748:                command.add(getHgCommand());
0749:                command.add(HG_VIEW_CMD);
0750:                command.add(HG_OPT_REPOSITORY);
0751:                command.add(repository.getAbsolutePath());
0752:
0753:                List<String> list;
0754:
0755:                if (HgUtils.isSolaris()) {
0756:                    env.add(HG_HGK_PATH_SOLARIS10_ENV);
0757:                    list = execEnv(command, env);
0758:                } else {
0759:                    list = exec(command);
0760:                }
0761:
0762:                if (!list.isEmpty()) {
0763:                    if (isErrorNoView(list.get(list.size() - 1))) {
0764:                        throw new HgException(NbBundle.getMessage(
0765:                                HgCommand.class, "MSG_WARN_NO_VIEW_TEXT"));
0766:                    } else if (isErrorHgkNotFound(list.get(0))) {
0767:                        throw new HgException(NbBundle.getMessage(
0768:                                HgCommand.class, "MSG_WARN_HGK_NOT_FOUND_TEXT"));
0769:                    } else if (isErrorAbort(list.get(list.size() - 1))) {
0770:                        handleError(command, list, NbBundle.getMessage(
0771:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0772:                    }
0773:                }
0774:                return list;
0775:            }
0776:
0777:            private static String getGlobalProxyIfNeeded(String defaultPath,
0778:                    boolean bOutputDetails, OutputLogger logger) {
0779:                String proxy = null;
0780:                if (defaultPath != null
0781:                        && (defaultPath.startsWith("http:") || defaultPath
0782:                                .startsWith("https:"))) { // NOI18N
0783:                    HgProxySettings ps = new HgProxySettings();
0784:                    if (ps.isManualSetProxy()) {
0785:                        if ((defaultPath.startsWith("http:") && !ps
0786:                                .getHttpHost().equals(""))
0787:                                || (defaultPath.startsWith("https:")
0788:                                        && !ps.getHttpHost().equals("") && ps
0789:                                        .getHttpsHost().equals(""))) { // NOI18N
0790:                            proxy = ps.getHttpHost();
0791:                            if (proxy != null && !proxy.equals("")) {
0792:                                proxy += ps.getHttpPort() > -1 ? ":"
0793:                                        + Integer.toString(ps.getHttpPort())
0794:                                        : ""; // NOI18N
0795:                            } else {
0796:                                proxy = null;
0797:                            }
0798:                        } else if (defaultPath.startsWith("https:")
0799:                                && !ps.getHttpsHost().equals("")) { // NOI18N
0800:                            proxy = ps.getHttpsHost();
0801:                            if (proxy != null && !proxy.equals("")) {
0802:                                proxy += ps.getHttpsPort() > -1 ? ":"
0803:                                        + Integer.toString(ps.getHttpsPort())
0804:                                        : ""; // NOI18N
0805:                            } else {
0806:                                proxy = null;
0807:                            }
0808:                        }
0809:                    }
0810:                }
0811:                if (proxy != null && bOutputDetails) {
0812:                    logger.output(NbBundle.getMessage(HgCommand.class,
0813:                            "MSG_USING_PROXY_INFO", proxy)); // NOI18N
0814:                }
0815:                return proxy;
0816:            }
0817:
0818:            /**
0819:             * Run the fetch extension for the specified repository
0820:             *
0821:             * @param File repository of the mercurial repository's root directory
0822:             * @throws org.netbeans.modules.mercurial.HgException
0823:             */
0824:            public static List<String> doFetch(File repository,
0825:                    OutputLogger logger) throws HgException {
0826:                if (repository == null)
0827:                    return null;
0828:                List<String> command = new ArrayList<String>();
0829:
0830:                command.add(getHgCommand());
0831:                command.add(HG_CONFIG_OPTION_CMD);
0832:                command.add(HG_FETCH_EXT_CMD);
0833:                command.add(HG_FETCH_CMD);
0834:                command.add(HG_OPT_REPOSITORY);
0835:                command.add(repository.getAbsolutePath());
0836:
0837:                List<String> list;
0838:                String defaultPull = new HgConfigFiles(repository)
0839:                        .getDefaultPull(false);
0840:                String proxy = getGlobalProxyIfNeeded(defaultPull, true, logger);
0841:                if (proxy != null) {
0842:                    List<String> env = new ArrayList<String>();
0843:                    env.add(HG_PROXY_ENV + proxy);
0844:                    list = execEnv(command, env);
0845:                } else {
0846:                    list = exec(command);
0847:                }
0848:
0849:                if (!list.isEmpty()) {
0850:                    if (isErrorAbort(list.get(list.size() - 1))) {
0851:                        handleError(command, list, NbBundle.getMessage(
0852:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
0853:                    }
0854:                }
0855:                return list;
0856:            }
0857:
0858:            private static List<HgLogMessage> processLogMessages(
0859:                    List<String> list, final List<HgLogMessage> messages) {
0860:                String rev, author, desc, date, id, fm, fa, fd, fc;
0861:                if (list != null && !list.isEmpty()) {
0862:                    rev = author = desc = date = id = fm = fa = fd = fc = null;
0863:                    boolean bEnd = false;
0864:                    for (String s : list) {
0865:                        if (s.indexOf(HG_LOG_REVISION_OUT) == 0) {
0866:                            rev = s.substring(HG_LOG_REVISION_OUT.length())
0867:                                    .trim();
0868:                        } else if (s.indexOf(HG_LOG_AUTHOR_OUT) == 0) {
0869:                            author = s.substring(HG_LOG_AUTHOR_OUT.length())
0870:                                    .trim();
0871:                        } else if (s.indexOf(HG_LOG_DESCRIPTION_OUT) == 0) {
0872:                            desc = s.substring(HG_LOG_DESCRIPTION_OUT.length())
0873:                                    .trim();
0874:                        } else if (s.indexOf(HG_LOG_DATE_OUT) == 0) {
0875:                            date = s.substring(HG_LOG_DATE_OUT.length()).trim();
0876:                        } else if (s.indexOf(HG_LOG_ID_OUT) == 0) {
0877:                            id = s.substring(HG_LOG_ID_OUT.length()).trim();
0878:                        } else if (s.indexOf(HG_LOG_FILEMODS_OUT) == 0) {
0879:                            fm = s.substring(HG_LOG_FILEMODS_OUT.length())
0880:                                    .trim();
0881:                        } else if (s.indexOf(HG_LOG_FILEADDS_OUT) == 0) {
0882:                            fa = s.substring(HG_LOG_FILEADDS_OUT.length())
0883:                                    .trim();
0884:                        } else if (s.indexOf(HG_LOG_FILEDELS_OUT) == 0) {
0885:                            fd = s.substring(HG_LOG_FILEDELS_OUT.length())
0886:                                    .trim();
0887:                        } else if (s.indexOf(HG_LOG_FILECOPIESS_OUT) == 0) {
0888:                            fc = s.substring(HG_LOG_FILECOPIESS_OUT.length())
0889:                                    .trim();
0890:                        } else if (s.indexOf(HG_LOG_ENDCS_OUT) == 0) {
0891:                            bEnd = true;
0892:                        } else {
0893:                            // Ignore all other lines
0894:                        }
0895:
0896:                        if (rev != null & bEnd) {
0897:                            messages.add(new HgLogMessage(rev, author, desc,
0898:                                    date, id, fm, fa, fd, fc));
0899:                            rev = author = desc = date = id = fm = fa = fd = fc = null;
0900:                            bEnd = false;
0901:                        }
0902:                    }
0903:                }
0904:                return messages;
0905:            }
0906:
0907:            public static HgLogMessage[] getIncomingMessages(
0908:                    final String rootUrl, String toRevision,
0909:                    boolean bShowMerges, OutputLogger logger) {
0910:                final List<HgLogMessage> messages = new ArrayList<HgLogMessage>(
0911:                        0);
0912:                final File root = new File(rootUrl);
0913:
0914:                try {
0915:
0916:                    List<String> list = new LinkedList<String>();
0917:                    list = HgCommand.doIncomingForSearch(root, toRevision,
0918:                            bShowMerges, logger);
0919:                    processLogMessages(list, messages);
0920:
0921:                } catch (HgException ex) {
0922:                    NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(
0923:                            ex);
0924:                    DialogDisplayer.getDefault().notifyLater(e);
0925:                } finally {
0926:                    logger.closeLog();
0927:                }
0928:
0929:                return messages.toArray(new HgLogMessage[0]);
0930:            }
0931:
0932:            public static HgLogMessage[] getOutMessages(final String rootUrl,
0933:                    String toRevision, boolean bShowMerges, OutputLogger logger) {
0934:                final List<HgLogMessage> messages = new ArrayList<HgLogMessage>(
0935:                        0);
0936:                final File root = new File(rootUrl);
0937:
0938:                try {
0939:
0940:                    List<String> list = new LinkedList<String>();
0941:                    list = HgCommand.doOutForSearch(root, toRevision,
0942:                            bShowMerges, logger);
0943:                    processLogMessages(list, messages);
0944:
0945:                } catch (HgException ex) {
0946:                    NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(
0947:                            ex);
0948:                    DialogDisplayer.getDefault().notifyLater(e);
0949:                } finally {
0950:                    logger.closeLog();
0951:                }
0952:
0953:                return messages.toArray(new HgLogMessage[0]);
0954:            }
0955:
0956:            public static HgLogMessage[] getLogMessages(final String rootUrl,
0957:                    final Set<File> files, String fromRevision,
0958:                    String toRevision, boolean bShowMerges, OutputLogger logger) {
0959:                final List<HgLogMessage> messages = new ArrayList<HgLogMessage>(
0960:                        0);
0961:                final File root = new File(rootUrl);
0962:
0963:                try {
0964:                    String headRev = HgCommand.getLastRevision(root, null);
0965:                    if (headRev == null) {
0966:                        return messages.toArray(new HgLogMessage[0]);
0967:                    }
0968:
0969:                    List<String> list = new LinkedList<String>();
0970:                    list = HgCommand.doLogForHistory(root,
0971:                            files != null ? new ArrayList<File>(files) : null,
0972:                            fromRevision, toRevision, headRev, bShowMerges,
0973:                            logger);
0974:                    processLogMessages(list, messages);
0975:
0976:                } catch (HgException ex) {
0977:                    NotifyDescriptor.Exception e = new NotifyDescriptor.Exception(
0978:                            ex);
0979:                    DialogDisplayer.getDefault().notifyLater(e);
0980:                } finally {
0981:                    logger.closeLog();
0982:                }
0983:
0984:                return messages.toArray(new HgLogMessage[0]);
0985:            }
0986:
0987:            /**
0988:             * Determines whether repository requires a merge - has more than 1 heads
0989:             *
0990:             * @param File repository of the mercurial repository's root directory
0991:             * @return Boolean which is true if the repository needs a merge
0992:             */
0993:            public static Boolean isMergeRequired(File repository) {
0994:                if (repository == null)
0995:                    return false;
0996:
0997:                try {
0998:                    List<String> list = getHeadRevisions(repository);
0999:
1000:                    if (!list.isEmpty() && list.size() > 1) {
1001:                        Mercurial.LOG.log(Level.FINE,
1002:                                "isMergeRequired(): TRUE " + list); // NOI18N
1003:                        return true;
1004:                    } else {
1005:                        Mercurial.LOG.log(Level.FINE,
1006:                                "isMergeRequired(): FALSE " + list); // NOI18N
1007:                        return false;
1008:                    }
1009:                } catch (HgException e) {
1010:                    return false;
1011:                }
1012:            }
1013:
1014:            /**
1015:             * Determines whether anything has been committed to the repository
1016:             *
1017:             * @param File repository of the mercurial repository's root directory
1018:             * @return Boolean which is true if the repository has revision history.
1019:             */
1020:            public static Boolean hasHistory(File repository) {
1021:                if (repository == null)
1022:                    return false;
1023:
1024:                List<String> command = new ArrayList<String>();
1025:
1026:                command.add(getHgCommand());
1027:                command.add(HG_LOG_CMD);
1028:                command.add(HG_LOG_LIMIT_ONE_CMD);
1029:                command.add(HG_OPT_REPOSITORY);
1030:                command.add(repository.getAbsolutePath());
1031:
1032:                try {
1033:                    List<String> list = exec(command);
1034:                    if (!list.isEmpty() && isErrorAbort(list.get(0)))
1035:                        return false;
1036:                    else
1037:                        return !list.isEmpty();
1038:                } catch (HgException e) {
1039:                    return false;
1040:                }
1041:            }
1042:
1043:            /**
1044:             * Determines the previous name of the specified file 
1045:             * We make the assumption that the previous file name is in the
1046:             * list of files returned by hg log command immediately befor
1047:             * the file we started with.
1048:             *
1049:             * @param File repository of the mercurial repository's root directory
1050:             * @param File file of the file whose previous name is required
1051:             * @param String revision which the revision to start from.
1052:             * @return File for the previous name of the file
1053:             */
1054:            private static File getPreviousName(File repository, File file,
1055:                    String revision) throws HgException {
1056:                if (repository == null)
1057:                    return null;
1058:                if (revision == null)
1059:                    return null;
1060:
1061:                List<String> command = new ArrayList<String>();
1062:
1063:                command.add(getHgCommand());
1064:                command.add(HG_LOG_CMD);
1065:                command.add(HG_OPT_FOLLOW);
1066:                command.add(HG_OPT_REPOSITORY);
1067:                command.add(repository.getAbsolutePath());
1068:                command.add(HG_FLAG_REV_CMD);
1069:                command.add(revision);
1070:                command.add(HG_GET_PREVIOUS_TEMPLATE_CMD);
1071:
1072:                command.add(file.getAbsolutePath());
1073:
1074:                List<String> list = exec(command);
1075:                try {
1076:                    list = exec(command);
1077:                    if (!list.isEmpty() && isErrorAbort(list.get(0)))
1078:                        return null;
1079:                } catch (HgException e) {
1080:                    return null;
1081:                }
1082:                String[] fileNames = list.get(0).split(" ");
1083:                for (int j = fileNames.length - 1; j > 0; j--) {
1084:                    File name = new File(repository, fileNames[j]);
1085:                    if (name.equals(file)) {
1086:                        return new File(repository, fileNames[j - 1]);
1087:                    }
1088:                }
1089:                return null;
1090:            }
1091:
1092:            /**
1093:             * Retrives the log information with just first line of commit message for the specified file.
1094:             *
1095:             * @param File repository of the mercurial repository's root directory
1096:             * @param File of file which revision history is to be retrieved.
1097:             * @return List<String> list of the log entries for the specified file.
1098:             * @throws org.netbeans.modules.mercurial.HgException
1099:             */
1100:            public static List<String> doLogShort(File repository, File file,
1101:                    OutputLogger logger) throws HgException {
1102:                return doLog(repository, file, HG_LOG_TEMPLATE_SHORT_CMD,
1103:                        false, logger);
1104:            }
1105:
1106:            /**
1107:             * Retrives the log information with the full commit message for the specified file.
1108:             *
1109:             * @param File repository of the mercurial repository's root directory
1110:             * @param File of file which revision history is to be retrieved.
1111:             * @return List<String> list of the log entries for the specified file.
1112:             * @throws org.netbeans.modules.mercurial.HgException
1113:             */
1114:            public static List<String> doLogLong(File repository, File file,
1115:                    OutputLogger logger) throws HgException {
1116:                return doLog(repository, file, HG_LOG_TEMPLATE_LONG_CMD, false,
1117:                        logger);
1118:            }
1119:
1120:            /**
1121:             * Retrives the log information for the specified file, as defined by the LOG_TEMPLATE.
1122:             *
1123:             * @param File repository of the mercurial repository's root directory
1124:             * @param File of file which revision history is to be retrieved.
1125:             * @param String Template specifying how output should be returned
1126:             * @param boolean flag indicating if debug param should be used - required to get all file mod, add, del info
1127:             * @return List<String> list of the log entries for the specified file.
1128:             * @throws org.netbeans.modules.mercurial.HgException
1129:             */
1130:            public static List<String> doLog(File repository, File file,
1131:                    String LOG_TEMPLATE, boolean bDebug, OutputLogger logger)
1132:                    throws HgException {
1133:                if (repository == null)
1134:                    return null;
1135:
1136:                List<String> command = new ArrayList<String>();
1137:
1138:                command.add(getHgCommand());
1139:                command.add(HG_LOG_CMD);
1140:                if (!file.isDirectory()) {
1141:                    command.add(HG_OPT_FOLLOW);
1142:                }
1143:                command.add(HG_OPT_REPOSITORY);
1144:                command.add(repository.getAbsolutePath());
1145:                if (bDebug) {
1146:                    command.add(HG_LOG_DEBUG_CMD);
1147:                }
1148:                command.add(LOG_TEMPLATE);
1149:                command.add(file.getAbsolutePath());
1150:
1151:                List<String> list = exec(command);
1152:                if (!list.isEmpty()) {
1153:                    if (isErrorNoRepository(list.get(0))) {
1154:                        handleError(command, list, NbBundle.getMessage(
1155:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1156:                                logger);
1157:                    } else if (isErrorAbort(list.get(0))) {
1158:                        handleError(command, list, NbBundle.getMessage(
1159:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1160:                    }
1161:                }
1162:                return list;
1163:            }
1164:
1165:            /**
1166:             * Retrives the log information for the specified files.
1167:             *
1168:             * @param File repository of the mercurial repository's root directory
1169:             * @param List<File> of files which revision history is to be retrieved.
1170:             * @param String Template specifying how output should be returned
1171:             * @param boolean flag indicating if debug param should be used - required to get all file mod, add, del info
1172:             * @return List<String> list of the log entries for the specified file.
1173:             * @throws org.netbeans.modules.mercurial.HgException
1174:             */
1175:            public static List<String> doLog(File repository, List<File> files,
1176:                    String LOG_TEMPLATE, boolean bDebug, OutputLogger logger)
1177:                    throws HgException {
1178:                if (repository == null)
1179:                    return null;
1180:                if (files != null && files.isEmpty())
1181:                    return null;
1182:
1183:                List<String> command = new ArrayList<String>();
1184:
1185:                command.add(getHgCommand());
1186:                command.add(HG_VERBOSE_CMD);
1187:                command.add(HG_LOG_CMD);
1188:                boolean doFollow = true;
1189:                if (files != null) {
1190:                    for (File f : files) {
1191:                        if (f.isDirectory()) {
1192:                            doFollow = false;
1193:                            break;
1194:                        }
1195:                    }
1196:                }
1197:                if (doFollow) {
1198:                    command.add(HG_OPT_FOLLOW);
1199:                }
1200:                command.add(HG_OPT_REPOSITORY);
1201:                command.add(repository.getAbsolutePath());
1202:                if (bDebug) {
1203:                    command.add(HG_LOG_DEBUG_CMD);
1204:                }
1205:                if (LOG_TEMPLATE != null) {
1206:                    command.add(LOG_TEMPLATE);
1207:                }
1208:                if (files != null) {
1209:                    for (File f : files) {
1210:                        command.add(f.getAbsolutePath());
1211:                    }
1212:                }
1213:
1214:                List<String> list = exec(command);
1215:                if (!list.isEmpty()) {
1216:                    if (isErrorNoRepository(list.get(0))) {
1217:                        handleError(command, list, NbBundle.getMessage(
1218:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1219:                                logger);
1220:                    } else if (isErrorAbort(list.get(0))) {
1221:                        handleError(command, list, NbBundle.getMessage(
1222:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1223:                    }
1224:                }
1225:                return list;
1226:            }
1227:
1228:            /**
1229:             * Retrives the log information for the specified files.
1230:             *
1231:             * @param File repository of the mercurial repository's root directory
1232:             * @param List<File> of files which revision history is to be retrieved.
1233:             * @param String Template specifying how output should be returned
1234:             * @param boolean flag indicating if debug param should be used - required to get all file mod, add, del info
1235:             * @return List<String> list of the log entries for the specified file.
1236:             * @throws org.netbeans.modules.mercurial.HgException
1237:             */
1238:            public static List<String> doLogForHistory(File repository,
1239:                    List<File> files, String from, String to, String headRev,
1240:                    boolean bShowMerges, OutputLogger logger)
1241:                    throws HgException {
1242:                if (repository == null)
1243:                    return null;
1244:                if (files != null && files.isEmpty())
1245:                    return null;
1246:
1247:                List<String> command = new ArrayList<String>();
1248:
1249:                command.add(getHgCommand());
1250:                command.add(HG_VERBOSE_CMD);
1251:                command.add(HG_LOG_CMD);
1252:                boolean doFollow = true;
1253:                if (files != null) {
1254:                    for (File f : files) {
1255:                        if (f.isDirectory()) {
1256:                            doFollow = false;
1257:                            break;
1258:                        }
1259:                    }
1260:                }
1261:                if (doFollow) {
1262:                    command.add(HG_OPT_FOLLOW);
1263:                }
1264:                if (!bShowMerges) {
1265:                    command.add(HG_LOG_NO_MERGES_CMD);
1266:                }
1267:                command.add(HG_OPT_REPOSITORY);
1268:                command.add(repository.getAbsolutePath());
1269:                command.add(HG_LOG_DEBUG_CMD);
1270:
1271:                String dateStr = handleRevDates(from, to);
1272:                if (dateStr != null) {
1273:                    command.add(HG_FLAG_DATE_CMD);
1274:                    command.add(dateStr);
1275:                }
1276:                String revStr = handleRevNumbers(from, to, headRev);
1277:                if (dateStr == null && revStr != null) {
1278:                    command.add(HG_FLAG_REV_CMD);
1279:                    command.add(revStr);
1280:                }
1281:                command.add(HG_LOG_TEMPLATE_HISTORY_CMD);
1282:
1283:                if (files != null) {
1284:                    for (File f : files) {
1285:                        command.add(f.getAbsolutePath());
1286:                    }
1287:                }
1288:                List<String> list = exec(command);
1289:                if (!list.isEmpty()) {
1290:                    if (isErrorNoRepository(list.get(0))) {
1291:                        handleError(command, list, NbBundle.getMessage(
1292:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1293:                                logger);
1294:                    } else if (isErrorAbort(list.get(0))) {
1295:                        handleError(command, list, NbBundle.getMessage(
1296:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1297:                    }
1298:                }
1299:                return list;
1300:            }
1301:
1302:            /**
1303:             * Retrives the Out information for the specified repository
1304:             *
1305:             * @param File repository of the mercurial repository's root directory
1306:             * @return List<String> list of the out entries for the specified repo.
1307:             * @throws org.netbeans.modules.mercurial.HgException
1308:             */
1309:            public static List<String> doOutForSearch(File repository,
1310:                    String to, boolean bShowMerges, OutputLogger logger)
1311:                    throws HgException {
1312:                if (repository == null)
1313:                    return null;
1314:
1315:                List<String> command = new ArrayList<String>();
1316:
1317:                command.add(getHgCommand());
1318:                command.add(HG_OUT_CMD);
1319:                command.add(HG_OPT_REPOSITORY);
1320:                command.add(repository.getAbsolutePath());
1321:                if (!bShowMerges) {
1322:                    command.add(HG_LOG_NO_MERGES_CMD);
1323:                }
1324:                command.add(HG_LOG_DEBUG_CMD);
1325:                String revStr = handleIncomingRevNumber(to);
1326:                if (revStr != null) {
1327:                    command.add(HG_FLAG_REV_CMD);
1328:                    command.add(revStr);
1329:                }
1330:                command.add(HG_LOG_TEMPLATE_HISTORY_CMD);
1331:
1332:                List<String> list;
1333:                String defaultPush = new HgConfigFiles(repository)
1334:                        .getDefaultPush(false);
1335:                String proxy = getGlobalProxyIfNeeded(defaultPush, false, null);
1336:                if (proxy != null) {
1337:                    List<String> env = new ArrayList<String>();
1338:                    env.add(HG_PROXY_ENV + proxy);
1339:                    list = execEnv(command, env);
1340:                } else {
1341:                    list = exec(command);
1342:                }
1343:                if (!list.isEmpty()) {
1344:                    if (isErrorNoDefaultPush(list.get(0))) {
1345:                        // Ignore
1346:                    } else if (isErrorNoRepository(list.get(0))) {
1347:                        handleError(command, list, NbBundle.getMessage(
1348:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1349:                                logger);
1350:                    } else if (isErrorAbort(list.get(0))) {
1351:                        handleError(command, list, NbBundle.getMessage(
1352:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1353:                    }
1354:                }
1355:                return list;
1356:            }
1357:
1358:            /**
1359:             * Retrives the Incoming changeset information for the specified repository
1360:             *
1361:             * @param File repository of the mercurial repository's root directory
1362:             * @return List<String> list of the out entries for the specified repo.
1363:             * @throws org.netbeans.modules.mercurial.HgException
1364:             */
1365:            public static List<String> doIncomingForSearch(File repository,
1366:                    String to, boolean bShowMerges, OutputLogger logger)
1367:                    throws HgException {
1368:                if (repository == null)
1369:                    return null;
1370:
1371:                List<String> command = new ArrayList<String>();
1372:
1373:                command.add(getHgCommand());
1374:                command.add(HG_INCOMING_CMD);
1375:                command.add(HG_OPT_REPOSITORY);
1376:                command.add(repository.getAbsolutePath());
1377:                if (!bShowMerges) {
1378:                    command.add(HG_LOG_NO_MERGES_CMD);
1379:                }
1380:                command.add(HG_LOG_DEBUG_CMD);
1381:                String revStr = handleIncomingRevNumber(to);
1382:                if (revStr != null) {
1383:                    command.add(HG_FLAG_REV_CMD);
1384:                    command.add(revStr);
1385:                }
1386:                command.add(HG_LOG_TEMPLATE_HISTORY_CMD);
1387:
1388:                List<String> list = exec(command);
1389:                String defaultPull = new HgConfigFiles(repository)
1390:                        .getDefaultPull(false);
1391:                String proxy = getGlobalProxyIfNeeded(defaultPull, false, null);
1392:                if (proxy != null) {
1393:                    List<String> env = new ArrayList<String>();
1394:                    env.add(HG_PROXY_ENV + proxy);
1395:                    list = execEnv(command, env);
1396:                } else {
1397:                    list = exec(command);
1398:                }
1399:
1400:                if (!list.isEmpty()) {
1401:                    if (isErrorNoDefaultPath(list.get(0))) {
1402:                        // Ignore
1403:                    } else if (isErrorNoRepository(list.get(0))) {
1404:                        handleError(command, list, NbBundle.getMessage(
1405:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1406:                                logger);
1407:                    } else if (isErrorAbort(list.get(0))
1408:                            || isErrorAbort(list.get(list.size() - 1))) {
1409:                        handleError(command, list, NbBundle.getMessage(
1410:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1411:                    }
1412:                }
1413:                return list;
1414:            }
1415:
1416:            private static String handleRevDates(String from, String to) {
1417:                // Check for Date range:
1418:                Date fromDate = null;
1419:                Date toDate = null;
1420:                Date currentDate = new Date(); // Current Date            
1421:                Date epochPlusOneDate = null;
1422:
1423:                try {
1424:                    epochPlusOneDate = new SimpleDateFormat("yyyy-MM-dd")
1425:                            .parse(HG_EPOCH_PLUS_ONE_YEAR); // NOI18N
1426:                } catch (ParseException ex) {
1427:                    // Ignore invalid dates
1428:                }
1429:
1430:                // Set From date
1431:                try {
1432:                    if (from != null)
1433:                        fromDate = new SimpleDateFormat("yyyy-MM-dd")
1434:                                .parse(from); // NOI18N
1435:                } catch (ParseException ex) {
1436:                    // Ignore invalid dates
1437:                }
1438:
1439:                // Set To date
1440:                try {
1441:                    if (to != null)
1442:                        toDate = new SimpleDateFormat("yyyy-MM-dd").parse(to); // NOI18N
1443:                } catch (ParseException ex) {
1444:                    // Ignore invalid dates
1445:                }
1446:
1447:                // If From date is set, but To date is not - default To date to current date
1448:                if (fromDate != null && toDate == null && to == null) {
1449:                    toDate = currentDate;
1450:                    to = new SimpleDateFormat("yyyy-MM-dd").format(toDate);
1451:                }
1452:                // If To date is set, but From date is not - default From date to 1971-01-01
1453:                if (fromDate == null && from == null && toDate != null) {
1454:                    fromDate = epochPlusOneDate;
1455:                    from = HG_EPOCH_PLUS_ONE_YEAR; // NOI18N
1456:                }
1457:
1458:                // If using dates make sure both From and To are set to dates
1459:                if ((fromDate != null && toDate == null && to != null)
1460:                        || (fromDate == null && from != null && toDate != null)) {
1461:                    HgUtils.warningDialog(HgCommand.class,
1462:                            "MSG_SEARCH_HISTORY_TITLE",// NOI18N
1463:                            "MSG_SEARCH_HISTORY_WARN_BOTHDATES_NEEDED_TEXT"); // NOI18N
1464:                    return null;
1465:                }
1466:
1467:                if (fromDate != null && toDate != null) {
1468:                    // Check From date - default to 1971-01-01 if From date is earlier than this
1469:                    if (epochPlusOneDate != null
1470:                            && fromDate.before(epochPlusOneDate)) {
1471:                        fromDate = epochPlusOneDate;
1472:                        from = HG_EPOCH_PLUS_ONE_YEAR; // NOI18N
1473:                    }
1474:                    // Set To date - default to current date if To date is later than this
1475:                    if (currentDate != null && toDate.after(currentDate)) {
1476:                        toDate = currentDate;
1477:                        to = new SimpleDateFormat("yyyy-MM-dd").format(toDate);
1478:                    }
1479:
1480:                    // Make sure the From date is before the To date
1481:                    if (fromDate.after(toDate)) {
1482:                        HgUtils
1483:                                .warningDialog(HgCommand.class,
1484:                                        "MSG_SEARCH_HISTORY_TITLE",// NOI18N
1485:                                        "MSG_SEARCH_HISTORY_WARN_FROM_BEFORE_TODATE_NEEDED_TEXT"); // NOI18N
1486:                        return null;
1487:                    }
1488:                    return from + " to " + to; // NOI18N
1489:                }
1490:                return null;
1491:            }
1492:
1493:            private static String handleIncomingRevNumber(String to) {
1494:                int toInt = -1;
1495:
1496:                // Handle users entering head or tip for revision, instead of a number
1497:                if (to != null
1498:                        && (to.equalsIgnoreCase(HG_STATUS_FLAG_TIP_CMD) || to
1499:                                .equalsIgnoreCase(HG_HEAD_STR))) {
1500:                    to = HG_STATUS_FLAG_TIP_CMD;
1501:                }
1502:                try {
1503:                    toInt = Integer.parseInt(to);
1504:                } catch (NumberFormatException e) {
1505:                    // ignore invalid numbers
1506:                }
1507:
1508:                return (toInt > -1) ? to : HG_STATUS_FLAG_TIP_CMD;
1509:            }
1510:
1511:            private static String handleRevNumbers(String from, String to,
1512:                    String headRev) {
1513:                int fromInt = -1;
1514:                int toInt = -1;
1515:                int headRevInt = -1;
1516:
1517:                // Handle users entering head or tip for revision, instead of a number
1518:                if (from != null
1519:                        && (from.equalsIgnoreCase(HG_STATUS_FLAG_TIP_CMD) || from
1520:                                .equalsIgnoreCase(HG_HEAD_STR)))
1521:                    from = headRev;
1522:                if (to != null
1523:                        && (to.equalsIgnoreCase(HG_STATUS_FLAG_TIP_CMD) || to
1524:                                .equalsIgnoreCase(HG_HEAD_STR)))
1525:                    to = headRev;
1526:
1527:                try {
1528:                    fromInt = Integer.parseInt(from);
1529:                } catch (NumberFormatException e) {
1530:                    // ignore invalid numbers
1531:                }
1532:                try {
1533:                    toInt = Integer.parseInt(to);
1534:                } catch (NumberFormatException e) {
1535:                    // ignore invalid numbers
1536:                }
1537:                try {
1538:                    headRevInt = Integer.parseInt(headRev);
1539:                } catch (NumberFormatException e) {
1540:                    // ignore invalid numbers
1541:                }
1542:
1543:                // Handle out of range revisions
1544:                if (headRevInt > -1 && toInt > headRevInt) {
1545:                    to = headRev;
1546:                    toInt = headRevInt;
1547:                }
1548:                if (headRevInt > -1 && fromInt > headRevInt) {
1549:                    from = headRev;
1550:                    fromInt = headRevInt;
1551:                }
1552:
1553:                // Handle revision ranges
1554:                String revStr = null;
1555:                if (fromInt > -1 && toInt > -1) {
1556:                    revStr = from + ":" + to;
1557:                } else if (fromInt > -1) {
1558:                    revStr = from + (headRevInt != -1 ? ":" + headRevInt : "");
1559:                } else if (toInt > -1) {
1560:                    revStr = "0:" + to;
1561:                }
1562:
1563:                return revStr;
1564:            }
1565:
1566:            /**
1567:             * Retrieves the base revision of the specified file to the
1568:             * specified output file.
1569:             *
1570:             * @param File repository of the mercurial repository's root directory
1571:             * @param File file in the mercurial repository
1572:             * @param File outFile to contain the contents of the file
1573:             * @throws org.netbeans.modules.mercurial.HgException
1574:             */
1575:            public static void doCat(File repository, File file, File outFile,
1576:                    OutputLogger logger) throws HgException {
1577:                doCat(repository, file, outFile, "tip", false, logger); //NOI18N
1578:            }
1579:
1580:            /**
1581:             * Retrieves the specified revision of the specified file to the
1582:             * specified output file.
1583:             *
1584:             * @param File repository of the mercurial repository's root directory
1585:             * @param File file in the mercurial repository
1586:             * @param File outFile to contain the contents of the file
1587:             * @param String of revision for the revision of the file to be
1588:             * printed to the output file.
1589:             * @return List<String> list of all the log entries
1590:             * @throws org.netbeans.modules.mercurial.HgException
1591:             */
1592:            public static void doCat(File repository, File file, File outFile,
1593:                    String revision, OutputLogger logger) throws HgException {
1594:                doCat(repository, file, outFile, revision, true, logger); //NOI18N
1595:            }
1596:
1597:            public static void doCat(File repository, File file, File outFile,
1598:                    String revision, boolean retry, OutputLogger logger)
1599:                    throws HgException {
1600:                if (repository == null)
1601:                    return;
1602:                if (file == null)
1603:                    return;
1604:
1605:                List<String> command = new ArrayList<String>();
1606:
1607:                command.add(getHgCommand());
1608:                command.add(HG_CAT_CMD);
1609:                command.add(HG_OPT_REPOSITORY);
1610:                command.add(repository.getAbsolutePath());
1611:                command.add(HG_FLAG_OUTPUT_CMD);
1612:                command.add(outFile.getAbsolutePath());
1613:
1614:                if (revision != null) {
1615:                    command.add(HG_FLAG_REV_CMD);
1616:                    command.add(revision);
1617:                }
1618:                command.add(file.getAbsolutePath());
1619:                List<String> list = exec(command);
1620:
1621:                if (!list.isEmpty()) {
1622:                    if (isErrorNoRepository(list.get(0))) {
1623:                        handleError(command, list, NbBundle.getMessage(
1624:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1625:                                logger);
1626:                    } else if (isErrorAbort(list.get(0))) {
1627:                        handleError(command, list, NbBundle.getMessage(
1628:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1629:                    }
1630:                }
1631:                if (outFile.length() == 0 && retry) {
1632:                    // Perhaps the file has changed its name
1633:                    String newRevision = Integer.toString(Integer
1634:                            .parseInt(revision) + 1);
1635:                    File prevFile = getPreviousName(repository, file,
1636:                            newRevision);
1637:                    if (prevFile != null) {
1638:                        doCat(repository, prevFile, outFile, revision, false,
1639:                                logger); //NOI18N
1640:                    }
1641:                }
1642:            }
1643:
1644:            /**
1645:             * Initialize a new repository in the given directory.  If the given
1646:             * directory does not exist, it is created. Will throw a HgException
1647:             * if the repository already exists.
1648:             *
1649:             * @param root for the mercurial repository
1650:             * @return void
1651:             * @throws org.netbeans.modules.mercurial.HgException
1652:             */
1653:            public static void doCreate(File root, OutputLogger logger)
1654:                    throws HgException {
1655:                if (root == null)
1656:                    return;
1657:                List<String> command = new ArrayList<String>();
1658:
1659:                command.add(getHgCommand());
1660:                command.add(HG_CREATE_CMD);
1661:                command.add(root.getAbsolutePath());
1662:
1663:                List<String> list = exec(command);
1664:                if (!list.isEmpty())
1665:                    handleError(command, list, NbBundle.getMessage(
1666:                            HgCommand.class, "MSG_CREATE_FAILED"), logger);
1667:            }
1668:
1669:            /**
1670:             * Clone an exisiting repository to the specified target directory
1671:             *
1672:             * @param File repository of the mercurial repository's root directory
1673:             * @param target directory to clone to
1674:             * @return clone output
1675:             * @throws org.netbeans.modules.mercurial.HgException
1676:             */
1677:            public static List<String> doClone(File repository, String target,
1678:                    OutputLogger logger) throws HgException {
1679:                if (repository == null)
1680:                    return null;
1681:                return doClone(repository.getAbsolutePath(), target, logger);
1682:            }
1683:
1684:            /**
1685:             * Clone a repository to the specified target directory
1686:             *
1687:             * @param String repository of the mercurial repository
1688:             * @param target directory to clone to
1689:             * @return clone output
1690:             * @throws org.netbeans.modules.mercurial.HgException
1691:             */
1692:            public static List<String> doClone(String repository,
1693:                    String target, OutputLogger logger) throws HgException {
1694:                if (repository == null || target == null)
1695:                    return null;
1696:
1697:                // Ensure that parent directory of target exists, creating if necessary
1698:                File fileTarget = new File(target);
1699:                File parentTarget = fileTarget.getParentFile();
1700:                try {
1701:                    if (!parentTarget.mkdir()) {
1702:                        if (!parentTarget.isDirectory()) {
1703:                            Mercurial.LOG.log(Level.WARNING,
1704:                                    "File.mkdir() failed for : "
1705:                                            + parentTarget.getAbsolutePath()); // NOI18N
1706:                            throw (new HgException(NbBundle.getMessage(
1707:                                    HgCommand.class,
1708:                                    "MSG_UNABLE_TO_CREATE_PARENT_DIR"))); // NOI18N
1709:                        }
1710:                    }
1711:                } catch (SecurityException e) {
1712:                    Mercurial.LOG.log(Level.WARNING, "File.mkdir() for : "
1713:                            + parentTarget.getAbsolutePath()
1714:                            + " threw SecurityException " + e.getMessage()); // NOI18N
1715:                    throw (new HgException(NbBundle.getMessage(HgCommand.class,
1716:                            "MSG_UNABLE_TO_CREATE_PARENT_DIR"))); // NOI18N
1717:                }
1718:                List<String> command = new ArrayList<String>();
1719:
1720:                command.add(getHgCommand());
1721:                command.add(HG_CLONE_CMD);
1722:                command.add(HG_VERBOSE_CMD);
1723:                // Workaround for http://www.selenic.com/mercurial/bts/issue776
1724:                // Strip off file:// from start of repository
1725:                if (repository.startsWith("file://")) {
1726:                    command.add(repository.substring(7));
1727:                } else {
1728:                    command.add(repository);
1729:                }
1730:                command.add(target);
1731:
1732:                List<String> list = exec(command);
1733:                if (!list.isEmpty()) {
1734:                    if (isErrorNoRepository(list.get(0))) {
1735:                        handleError(command, list, NbBundle.getMessage(
1736:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
1737:                                logger);
1738:                    } else if (isErrorNoResponse(list.get(list.size() - 1))) {
1739:                        handleError(command, list, NbBundle.getMessage(
1740:                                HgCommand.class, "MSG_NO_RESPONSE_ERR"), logger);
1741:                    } else if (isErrorAbort(list.get(list.size() - 1))) {
1742:                        handleError(command, list, NbBundle.getMessage(
1743:                                HgCommand.class, "MSG_COMMAND_ABORTED"), logger);
1744:                    }
1745:                }
1746:                return list;
1747:            }
1748:
1749:            /**
1750:             * Commits the list of Locally Changed files to the mercurial Repository
1751:             *
1752:             * @param File repository of the mercurial repository's root directory
1753:             * @param List<files> of files to be committed to hg
1754:             * @param String for commitMessage
1755:             * @return void
1756:             * @throws org.netbeans.modules.mercurial.HgException
1757:             */
1758:            public static void doCommit(File repository,
1759:                    List<File> commitFiles, String commitMessage,
1760:                    OutputLogger logger) throws HgException {
1761:                List<String> command = new ArrayList<String>();
1762:
1763:                command.add(getHgCommand());
1764:                command.add(HG_COMMIT_CMD);
1765:                command.add(HG_OPT_REPOSITORY);
1766:                command.add(repository.getAbsolutePath());
1767:
1768:                String projectUserName = new HgConfigFiles(repository)
1769:                        .getUserName(false);
1770:                String globalUsername = HgConfigFiles.getInstance()
1771:                        .getUserName();
1772:                String username = null;
1773:                if (projectUserName != null && projectUserName.length() > 0)
1774:                    username = projectUserName;
1775:                else if (globalUsername != null && globalUsername.length() > 0)
1776:                    username = globalUsername;
1777:
1778:                if (username != null) {
1779:                    command.add(HG_OPT_USERNAME);
1780:                    command.add(username);
1781:                }
1782:
1783:                File tempfile = null;
1784:
1785:                try {
1786:                    if (commitMessage == null || commitMessage.length() == 0) {
1787:                        commitMessage = HG_COMMIT_DEFAULT_MESSAGE;
1788:                    }
1789:                    // Create temporary file.
1790:                    tempfile = File.createTempFile(HG_COMMIT_TEMPNAME,
1791:                            HG_COMMIT_TEMPNAME_SUFFIX);
1792:
1793:                    // Write to temp file
1794:                    BufferedWriter out = new BufferedWriter(new FileWriter(
1795:                            tempfile));
1796:                    out.write(commitMessage);
1797:                    out.close();
1798:
1799:                    command.add(HG_COMMIT_OPT_LOGFILE_CMD);
1800:                    command.add(tempfile.getAbsolutePath());
1801:
1802:                    for (File f : commitFiles) {
1803:                        command.add(f.getAbsolutePath());
1804:                    }
1805:                    List<String> list = exec(command);
1806:
1807:                    if (!list.isEmpty()
1808:                            && (isErrorNotTracked(list.get(0)) || isErrorCannotReadCommitMsg(list
1809:                                    .get(0))))
1810:                        handleError(command, list, NbBundle.getMessage(
1811:                                HgCommand.class, "MSG_COMMIT_FAILED"), logger);
1812:
1813:                } catch (IOException ex) {
1814:                    throw new HgException(NbBundle.getMessage(HgCommand.class,
1815:                            "MSG_FAILED_TO_READ_COMMIT_MESSAGE"));
1816:                } finally {
1817:                    if (commitMessage != null && tempfile != null) {
1818:                        tempfile.delete();
1819:                    }
1820:                }
1821:            }
1822:
1823:            /**
1824:             * Rename a source file to a destination file.
1825:             * mercurial hg rename 
1826:             *
1827:             * @param File repository of the mercurial repository's root directory
1828:             * @param File of sourceFile which was renamed
1829:             * @param File of destFile to which sourceFile has been renaned
1830:             * @param boolean whether to do a rename --after
1831:             * @return void
1832:             * @throws org.netbeans.modules.mercurial.HgException
1833:             */
1834:            public static void doRename(File repository, File sourceFile,
1835:                    File destFile, OutputLogger logger) throws HgException {
1836:                doRename(repository, sourceFile, destFile, false, logger);
1837:            }
1838:
1839:            private static void doRename(File repository, File sourceFile,
1840:                    File destFile, boolean bAfter, OutputLogger logger)
1841:                    throws HgException {
1842:                if (repository == null)
1843:                    return;
1844:
1845:                List<String> command = new ArrayList<String>();
1846:
1847:                command.add(getHgCommand());
1848:                command.add(HG_RENAME_CMD);
1849:                if (bAfter)
1850:                    command.add(HG_RENAME_AFTER_CMD);
1851:                command.add(HG_OPT_REPOSITORY);
1852:                command.add(repository.getAbsolutePath());
1853:                command.add(HG_OPT_CWD_CMD);
1854:                command.add(repository.getAbsolutePath());
1855:
1856:                command.add(sourceFile.getAbsolutePath().substring(
1857:                        repository.getAbsolutePath().length() + 1));
1858:                command.add(destFile.getAbsolutePath().substring(
1859:                        repository.getAbsolutePath().length() + 1));
1860:
1861:                List<String> list = exec(command);
1862:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
1863:                    if (!bAfter
1864:                            || !isErrorAbortNoFilesToCopy(list
1865:                                    .get(list.size() - 1))) {
1866:                        handleError(command, list, NbBundle.getMessage(
1867:                                HgCommand.class, "MSG_RENAME_FAILED"), logger);
1868:                    }
1869:                }
1870:            }
1871:
1872:            /**
1873:             * Mark a source file as having been renamed to a destination file.
1874:             * mercurial hg rename -A.
1875:             *
1876:             * @param File repository of the mercurial repository's root directory
1877:             * @param File of sourceFile which was renamed
1878:             * @param File of destFile to which sourceFile has been renaned
1879:             * @return void
1880:             * @throws org.netbeans.modules.mercurial.HgException
1881:             */
1882:            public static void doRenameAfter(File repository, File sourceFile,
1883:                    File destFile, OutputLogger logger) throws HgException {
1884:                doRename(repository, sourceFile, destFile, true, logger);
1885:            }
1886:
1887:            /**
1888:             * Adds the list of Locally New files to the mercurial Repository
1889:             * Their status will change to added and they will be added on the next
1890:             * mercurial hg add.
1891:             *
1892:             * @param File repository of the mercurial repository's root directory
1893:             * @param List<Files> of files to be added to hg
1894:             * @return void
1895:             * @throws org.netbeans.modules.mercurial.HgException
1896:             */
1897:            public static void doAdd(File repository, List<File> addFiles,
1898:                    OutputLogger logger) throws HgException {
1899:                if (repository == null)
1900:                    return;
1901:                if (addFiles.size() == 0)
1902:                    return;
1903:                List<String> command = new ArrayList<String>();
1904:
1905:                command.add(getHgCommand());
1906:                command.add(HG_ADD_CMD);
1907:                command.add(HG_OPT_REPOSITORY);
1908:                command.add(repository.getAbsolutePath());
1909:
1910:                for (File f : addFiles) {
1911:                    if (f.isDirectory())
1912:                        continue;
1913:                    // We do not look for files to ignore as we should not here
1914:                    // with a file to be ignored.
1915:                    command.add(f.getAbsolutePath());
1916:                }
1917:                List<String> list = exec(command);
1918:                if (!list.isEmpty() && isErrorAlreadyTracked(list.get(0)))
1919:                    handleError(command, list, NbBundle.getMessage(
1920:                            HgCommand.class, "MSG_ALREADY_TRACKED"), logger);
1921:            }
1922:
1923:            /**
1924:             * Reverts the list of files in the mercurial Repository to the specified revision
1925:             *
1926:             * @param File repository of the mercurial repository's root directory
1927:             * @param List<Files> of files to be reverted
1928:             * @param String revision to be reverted to
1929:             * @return void
1930:             * @throws org.netbeans.modules.mercurial.HgException
1931:             */
1932:            public static void doRevert(File repository,
1933:                    List<File> revertFiles, String revision, boolean doBackup,
1934:                    OutputLogger logger) throws HgException {
1935:                if (repository == null)
1936:                    return;
1937:                if (revertFiles.size() == 0)
1938:                    return;
1939:
1940:                List<String> command = new ArrayList<String>();
1941:
1942:                command.add(getHgCommand());
1943:                command.add(HG_REVERT_CMD);
1944:                if (!doBackup) {
1945:                    command.add(HG_REVERT_NOBACKUP_CMD);
1946:                }
1947:                command.add(HG_OPT_REPOSITORY);
1948:                command.add(repository.getAbsolutePath());
1949:                if (revision != null) {
1950:                    command.add(HG_FLAG_REV_CMD);
1951:                    command.add(revision);
1952:                }
1953:
1954:                for (File f : revertFiles) {
1955:                    command.add(f.getAbsolutePath());
1956:                }
1957:                List<String> list = exec(command);
1958:                if (!list.isEmpty() && isErrorNoChangeNeeded(list.get(0)))
1959:                    handleError(command, list, NbBundle.getMessage(
1960:                            HgCommand.class, "MSG_REVERT_FAILED"), logger);
1961:            }
1962:
1963:            /**
1964:             * Adds a Locally New file to the mercurial Repository
1965:             * The status will change to added and they will be added on the next
1966:             * mercurial hg commit.
1967:             *
1968:             * @param File repository of the mercurial repository's root directory
1969:             * @param File of file to be added to hg
1970:             * @return void
1971:             * @throws org.netbeans.modules.mercurial.HgException
1972:             */
1973:            public static void doAdd(File repository, File file,
1974:                    OutputLogger logger) throws HgException {
1975:                if (repository == null)
1976:                    return;
1977:                if (file == null)
1978:                    return;
1979:                if (file.isDirectory())
1980:                    return;
1981:                // We do not look for file to ignore as we should not here
1982:                // with a file to be ignored.
1983:
1984:                List<String> command = new ArrayList<String>();
1985:
1986:                command.add(getHgCommand());
1987:                command.add(HG_ADD_CMD);
1988:                command.add(HG_OPT_REPOSITORY);
1989:                command.add(repository.getAbsolutePath());
1990:
1991:                command.add(file.getAbsolutePath());
1992:                List<String> list = exec(command);
1993:                if (!list.isEmpty() && isErrorAlreadyTracked(list.get(0)))
1994:                    handleError(command, list, NbBundle.getMessage(
1995:                            HgCommand.class, "MSG_ALREADY_TRACKED"), logger);
1996:            }
1997:
1998:            /**
1999:             * Get the annotations for the specified file
2000:             *
2001:             * @param File repository of the mercurial repository
2002:             * @param File file to be annotated
2003:             * @param String revision of the file to be annotated
2004:             * @return List<String> list of the annotated lines of the file
2005:             * @throws org.netbeans.modules.mercurial.HgException
2006:             */
2007:            public static List<String> doAnnotate(File repository, File file,
2008:                    String revision, OutputLogger logger) throws HgException {
2009:                if (repository == null)
2010:                    return null;
2011:                List<String> command = new ArrayList<String>();
2012:
2013:                command.add(getHgCommand());
2014:                command.add(HG_ANNOTATE_CMD);
2015:                command.add(HG_OPT_REPOSITORY);
2016:                command.add(repository.getAbsolutePath());
2017:
2018:                if (revision != null) {
2019:                    command.add(HG_FLAG_REV_CMD);
2020:                    command.add(revision);
2021:                }
2022:                command.add(HG_ANNOTATE_FLAGN_CMD);
2023:                command.add(HG_ANNOTATE_FLAGU_CMD);
2024:                command.add(HG_OPT_FOLLOW);
2025:                command.add(file.getAbsolutePath());
2026:                List<String> list = exec(command);
2027:                if (!list.isEmpty()) {
2028:                    if (isErrorNoRepository(list.get(0))) {
2029:                        handleError(command, list, NbBundle.getMessage(
2030:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
2031:                                logger);
2032:                    } else if (isErrorNoSuchFile(list.get(0))) {
2033:                        // This can happen if we have multiple heads and the wrong
2034:                        // one was picked by default hg annotation 
2035:                        if (revision == null) {
2036:                            String rev = getLastRevision(repository, file);
2037:                            if (rev != null) {
2038:                                list = doAnnotate(repository, file, rev, logger);
2039:                            } else {
2040:                                list = null;
2041:                            }
2042:                        } else {
2043:                            list = null;
2044:                        }
2045:                    }
2046:                }
2047:                return list;
2048:            }
2049:
2050:            public static List<String> doAnnotate(File repository, File file,
2051:                    OutputLogger logger) throws HgException {
2052:                return doAnnotate(repository, file, null, logger);
2053:            }
2054:
2055:            /**
2056:             * Get the revisions this file has been modified in.
2057:             *
2058:             * @param File repository of the mercurial repository's root directory
2059:             * @param files to query revisions for
2060:             * @param Int limit on nunmber of revisions (-1 for no limit)
2061:             * @return List<String> list of the revisions of the file - {<rev>:<short cset hash>}
2062:             *         or null if no commits made yet.
2063:             */
2064:            public static List<String> getRevisionsForFile(File repository,
2065:                    File[] files, int limit) {
2066:                if (repository == null)
2067:                    return null;
2068:                List<String> command = new ArrayList<String>();
2069:
2070:                command.add(getHgCommand());
2071:                command.add(HG_LOG_CMD);
2072:                if (limit >= 0) {
2073:                    command.add(HG_LOG_LIMIT_CMD);
2074:                    command.add(Integer.toString(limit));
2075:                }
2076:                command.add(HG_OPT_REPOSITORY);
2077:                command.add(repository.getAbsolutePath());
2078:                command.add(HG_CSET_TARGET_TEMPLATE_CMD);
2079:                if (files != null) {
2080:                    for (File file : files) {
2081:                        command.add(file.getAbsolutePath());
2082:                    }
2083:                }
2084:
2085:                List<String> list = new ArrayList<String>();
2086:                try {
2087:                    list = exec(command);
2088:                } catch (HgException ex) {
2089:                    // Ignore Exception
2090:                }
2091:                return list == null || list.isEmpty() ? null : list;
2092:            }
2093:
2094:            /**
2095:             * Get the revisions for a repository
2096:             *
2097:             * @param File repository of the mercurial repository's root directory
2098:             * @return List<String> list of the revisions of the repository - {<rev>:<short cset hash>}
2099:             *         or null if no commits made yet.
2100:             */
2101:            public static List<String> getRevisions(File repository, int limit) {
2102:                if (repository == null)
2103:                    return null;
2104:                return getRevisionsForFile(repository, null, limit);
2105:            }
2106:
2107:            /**
2108:             * Get the pull default for the specified repository, i.e. the default
2109:             * destination for hg pull commmands.
2110:             *
2111:             * @param File repository of the mercurial repository's root directory
2112:             * @return String for pull default
2113:             */
2114:            public static String getPullDefault(File repository) {
2115:                return getPathDefault(repository, HG_PATH_DEFAULT_OPT);
2116:            }
2117:
2118:            /**
2119:             * Get the push default for the specified repository, i.e. the default
2120:             * destination for hg push commmands.
2121:             *
2122:             * @param File repository of the mercurial repository's root directory
2123:             * @return String for push default
2124:             */
2125:            public static String getPushDefault(File repository) {
2126:                return getPathDefault(repository, HG_PATH_DEFAULT_PUSH_OPT);
2127:            }
2128:
2129:            private static String getPathDefault(File repository, String type) {
2130:                if (repository == null)
2131:                    return null;
2132:                List<String> command = new ArrayList<String>();
2133:
2134:                command.add(getHgCommand());
2135:                command.add(HG_PATH_DEFAULT_CMD);
2136:                command.add(HG_OPT_REPOSITORY);
2137:                command.add(repository.getAbsolutePath());
2138:                command.add(type);
2139:
2140:                String res = null;
2141:
2142:                List<String> list = new LinkedList<String>();
2143:                try {
2144:                    list = exec(command);
2145:                } catch (HgException ex) {
2146:                    // Ignore Exception
2147:                }
2148:                if (!list.isEmpty() && (!isErrorNotFound(list.get(0)))) {
2149:                    res = list.get(0);
2150:                }
2151:                return res;
2152:            }
2153:
2154:            /**
2155:             * Returns the mercurial branch name if any for a repository
2156:             *
2157:             * @param File repository of the mercurial repository's root directory
2158:             * @return String branch name or null if not named
2159:             * @throws org.netbeans.modules.mercurial.HgException
2160:             */
2161:            public static String getBranchName(File repository)
2162:                    throws HgException {
2163:                if (repository == null)
2164:                    return null;
2165:
2166:                List<String> command = new ArrayList<String>();
2167:
2168:                command.add(getHgCommand());
2169:                command.add(HG_BRANCH_CMD);
2170:                command.add(HG_OPT_REPOSITORY);
2171:                command.add(repository.getAbsolutePath());
2172:
2173:                List<String> list = exec(command);
2174:                if (!list.isEmpty()) {
2175:                    return list.get(0);
2176:                } else {
2177:                    return null;
2178:                }
2179:            }
2180:
2181:            /**
2182:             * Returns the mercurial branch revision for a repository
2183:             *
2184:             * @param File repository of the mercurial repository's root directory
2185:             * @return int value of revision for repository tip
2186:             * @throws org.netbeans.modules.mercurial.HgException
2187:             */
2188:            public static int getBranchRev(File repository) throws HgException {
2189:                if (repository == null)
2190:                    return -1;
2191:
2192:                List<String> command = new ArrayList<String>();
2193:
2194:                command.add(getHgCommand());
2195:                command.add(HG_BRANCH_REV_CMD);
2196:                command.add(HG_BRANCH_REV_TEMPLATE_CMD);
2197:                command.add(HG_OPT_REPOSITORY);
2198:                command.add(repository.getAbsolutePath());
2199:
2200:                List<String> list = exec(command);
2201:                if (!list.isEmpty()) {
2202:                    return Integer.parseInt(list.get(0));
2203:                } else {
2204:                    return -1;
2205:                }
2206:            }
2207:
2208:            /**
2209:             * Returns the mercurial branch name if any for a repository
2210:             *
2211:             * @param File repository of the mercurial repository's root directory
2212:             * @return String branch short change set hash
2213:             * @throws org.netbeans.modules.mercurial.HgException
2214:             */
2215:            public static String getBranchShortChangesetHash(File repository)
2216:                    throws HgException {
2217:                if (repository == null)
2218:                    return null;
2219:
2220:                List<String> command = new ArrayList<String>();
2221:
2222:                command.add(getHgCommand());
2223:                command.add(HG_BRANCH_REV_CMD);
2224:                command.add(HG_BRANCH_SHORT_CS_TEMPLATE_CMD);
2225:                command.add(HG_OPT_REPOSITORY);
2226:                command.add(repository.getAbsolutePath());
2227:
2228:                List<String> list = exec(command);
2229:                if (!list.isEmpty()) {
2230:                    return list.get(0);
2231:                } else {
2232:                    return null;
2233:                }
2234:            }
2235:
2236:            /**
2237:             * Returns the mercurial branch info for a repository
2238:             *
2239:             * @param File repository of the mercurial repository's root directory
2240:             * @return String of form :<branch>:<rev>:<shortchangeset>:
2241:             * @throws org.netbeans.modules.mercurial.HgException
2242:             */
2243:            public static String getBranchInfo(File repository)
2244:                    throws HgException {
2245:                if (repository == null)
2246:                    return null;
2247:
2248:                List<String> command = new ArrayList<String>();
2249:
2250:                command.add(getHgCommand());
2251:                command.add(HG_BRANCH_REV_CMD);
2252:                command.add(HG_BRANCH_INFO_TEMPLATE_CMD);
2253:                command.add(HG_OPT_REPOSITORY);
2254:                command.add(repository.getAbsolutePath());
2255:
2256:                List<String> list = exec(command);
2257:                if (!list.isEmpty()) {
2258:                    return list.get(0);
2259:                } else {
2260:                    return null;
2261:                }
2262:            }
2263:
2264:            /**
2265:             * Returns the revision number for the heads in a repository
2266:             *
2267:             * @param File repository of the mercurial repository's root directory
2268:             * @return List<String> of revision numbers.
2269:             * @throws org.netbeans.modules.mercurial.HgException
2270:             */
2271:            public static List<String> getHeadRevisions(File repository)
2272:                    throws HgException {
2273:                return getHeadInfo(repository, HG_REV_TEMPLATE_CMD);
2274:            }
2275:
2276:            /**
2277:             * Returns the revision number for the heads in a repository
2278:             *
2279:             * @param String repository of the mercurial repository
2280:             * @return List<String> of revision numbers.
2281:             * @throws org.netbeans.modules.mercurial.HgException
2282:             */
2283:            public static List<String> getHeadRevisions(String repository)
2284:                    throws HgException {
2285:                return getHeadInfo(repository, HG_REV_TEMPLATE_CMD);
2286:            }
2287:
2288:            /**
2289:             * Returns the changeset for the the heads in a repository
2290:             *
2291:             * @param File repository of the mercurial repository's root directory
2292:             * @param File file of the file whose last changeset is to be returned.
2293:             * @return List<String> of changeset ids.
2294:             * @throws org.netbeans.modules.mercurial.HgException
2295:             */
2296:            public static List<String> getHeadChangeSetIds(File repository)
2297:                    throws HgException {
2298:                return getHeadInfo(repository, HG_CSET_TARGET_TEMPLATE_CMD);
2299:            }
2300:
2301:            private static List<String> getHeadInfo(String repository,
2302:                    String template) throws HgException {
2303:                if (repository == null)
2304:                    return null;
2305:
2306:                List<String> command = new ArrayList<String>();
2307:
2308:                command.add(getHgCommand());
2309:                command.add(HG_HEADS_CMD);
2310:                command.add(HG_OPT_REPOSITORY);
2311:                command.add(repository);
2312:                command.add(template);
2313:
2314:                return exec(command);
2315:            }
2316:
2317:            private static List<String> getHeadInfo(File repository,
2318:                    String template) throws HgException {
2319:                if (repository == null)
2320:                    return null;
2321:                return getHeadInfo(repository.getAbsolutePath(), template);
2322:            }
2323:
2324:            /**
2325:             * Returns the revision number for the last change to a file
2326:             *
2327:             * @param File repository of the mercurial repository's root directory
2328:             * @param File file of the file whose last revision number is to be returned, if null test for repo
2329:             * @return String in the form of a revision number.
2330:             * @throws org.netbeans.modules.mercurial.HgException
2331:             */
2332:            public static String getLastRevision(File repository, File file)
2333:                    throws HgException {
2334:                return getLastChange(repository, file, HG_REV_TEMPLATE_CMD);
2335:            }
2336:
2337:            /**
2338:             * Returns the changeset for the last change to a file
2339:             *
2340:             * @param File repository of the mercurial repository's root directory
2341:             * @param File file of the file whose last changeset is to be returned.
2342:             * @return String in the form of a changeset id.
2343:             * @throws org.netbeans.modules.mercurial.HgException
2344:             */
2345:            public static String getLastChangeSetId(File repository, File file)
2346:                    throws HgException {
2347:                return getLastChange(repository, file, HG_CSET_TEMPLATE_CMD);
2348:            }
2349:
2350:            private static String getLastChange(File repository, File file,
2351:                    String template) throws HgException {
2352:
2353:                if (repository == null)
2354:                    return null;
2355:
2356:                List<String> command = new ArrayList<String>();
2357:
2358:                command.add(getHgCommand());
2359:                command.add(HG_LOG_CMD);
2360:                command.add(HG_LOG_LIMIT_ONE_CMD);
2361:                command.add(HG_OPT_REPOSITORY);
2362:                command.add(repository.getAbsolutePath());
2363:                command.add(template);
2364:                if (file != null)
2365:                    command.add(file.getAbsolutePath());
2366:
2367:                List<String> list = exec(command);
2368:                if (!list.isEmpty()) {
2369:                    return new StringBuffer(list.get(0)).toString();
2370:                } else {
2371:                    return null;
2372:                }
2373:            }
2374:
2375:            /**
2376:             * Returns the mercurial status for a given file
2377:             *
2378:             * @param File repository of the mercurial repository's root directory
2379:             * @param cwd current working directory containing file to be checked
2380:             * @param filename name of file whose status is to be checked
2381:             * @return FileInformation for the given filename
2382:             * @throws org.netbeans.modules.mercurial.HgException
2383:             */
2384:            public static FileInformation getSingleStatus(File repository,
2385:                    String cwd, String filename) throws HgException {
2386:                FileInformation info = null;
2387:                List<String> list = doSingleStatusCmd(repository, cwd, filename);
2388:                if (list == null || list.isEmpty())
2389:                    return new FileInformation(FileInformation.STATUS_UNKNOWN,
2390:                            null, false);
2391:
2392:                info = getFileInformationFromStatusLine(list.get(0));
2393:                // Handles Copy status
2394:                // Could save copy source in FileStatus but for now we don't need it.
2395:                // FileStatus used in Fileinformation.java:getStatusText() and getShortStatusText() to check if
2396:                // file is Locally Copied when it's status is Locally Added
2397:                if (list.size() == 2) {
2398:                    if (list.get(1).length() > 0) {
2399:                        if (list.get(1).charAt(0) == ' ') {
2400:
2401:                            info = new FileInformation(
2402:                                    FileInformation.STATUS_VERSIONED_ADDEDLOCALLY,
2403:                                    new FileStatus(new File(new File(cwd),
2404:                                            filename), true), false);
2405:                            Mercurial.LOG
2406:                                    .log(
2407:                                            Level.FINE,
2408:                                            "getSingleStatus() - Copied: Locally Added {0}, Copy Source {1}", // NOI18N
2409:                                            new Object[] { list.get(0),
2410:                                                    list.get(1) });
2411:                        }
2412:                    } else {
2413:                        Mercurial.LOG
2414:                                .log(
2415:                                        Level.FINE,
2416:                                        "getSingleStatus() - Second line empty: first line: {0}",
2417:                                        list.get(0)); // NOI18N
2418:                    }
2419:                }
2420:
2421:                // Handle Conflict Status
2422:                // TODO: remove this if Hg status supports Conflict marker
2423:                if (existsConflictFile(cwd + File.separator + filename)) {
2424:                    info = new FileInformation(
2425:                            FileInformation.STATUS_VERSIONED_CONFLICT, null,
2426:                            false);
2427:                    Mercurial.LOG
2428:                            .log(
2429:                                    Level.FINE,
2430:                                    "getSingleStatus(): CONFLICT StatusLine: {0} Status: {1}  {2} RepoPath:{3} cwd:{4} CONFLICT {5}", // NOI18N
2431:                                    new Object[] {
2432:                                            list.get(0),
2433:                                            info.getStatus(),
2434:                                            filename,
2435:                                            repository.getAbsolutePath(),
2436:                                            cwd,
2437:                                            cwd
2438:                                                    + File.separator
2439:                                                    + filename
2440:                                                    + HgCommand.HG_STR_CONFLICT_EXT });
2441:                }
2442:
2443:                Mercurial.LOG
2444:                        .log(
2445:                                Level.FINE,
2446:                                "getSingleStatus(): StatusLine: {0} Status: {1}  {2} RepoPath:{3} cwd:{4}", // NOI18N
2447:                                new Object[] { list.get(0), info.getStatus(),
2448:                                        filename, repository.getAbsolutePath(),
2449:                                        cwd });
2450:                return info;
2451:            }
2452:
2453:            /**
2454:             * Returns the mercurial status for all files in a given  subdirectory of
2455:             * a repository
2456:             *
2457:             * @param File repository of the mercurial repository's root directory
2458:             * @param File dir of the subdirectoy of interest. 
2459:             * @return Map of files and status for all files in the specified subdirectory
2460:             * @throws org.netbeans.modules.mercurial.HgException
2461:             */
2462:            public static Map<File, FileInformation> getAllStatus(
2463:                    File repository, File dir) throws HgException {
2464:                return getDirStatusWithFlags(repository, dir,
2465:                        HG_STATUS_FLAG_ALL_CMD, true);
2466:            }
2467:
2468:            /**
2469:             * Returns the mercurial status for all files in a given repository
2470:             *
2471:             * @param File repository of the mercurial repository's root directory
2472:             * @return Map of files and status for all files under the repository root
2473:             * @throws org.netbeans.modules.mercurial.HgException
2474:             */
2475:            public static Map<File, FileInformation> getAllStatus(
2476:                    File repository) throws HgException {
2477:                return getAllStatusWithFlags(repository,
2478:                        HG_STATUS_FLAG_ALL_CMD, true);
2479:            }
2480:
2481:            /**
2482:             * Returns the mercurial status for only files of interest to us in a given repository
2483:             * that is modified, locally added, locally removed, locally deleted, locally new and ignored.
2484:             *
2485:             * @param File repository of the mercurial repository's root directory
2486:             * @return Map of files and status for all files of interest under the repository root
2487:             * @throws org.netbeans.modules.mercurial.HgException
2488:             */
2489:            public static Map<File, FileInformation> getAllInterestingStatus(
2490:                    File repository) throws HgException {
2491:                return getAllStatusWithFlags(repository,
2492:                        HG_STATUS_FLAG_INTERESTING_CMD, true);
2493:            }
2494:
2495:            /**
2496:             * Returns the mercurial status for only files of interest to us in a given directory in a repository
2497:             * that is modified, locally added, locally removed, locally deleted, locally new and ignored.
2498:             *
2499:             * @param File repository of the mercurial repository's root directory
2500:             * @param File dir of the directory of interest
2501:             * @return Map of files and status for all files of interest in the directory of interest
2502:             * @throws org.netbeans.modules.mercurial.HgException
2503:             */
2504:            public static Map<File, FileInformation> getInterestingStatus(
2505:                    File repository, File dir) throws HgException {
2506:                return getDirStatusWithFlags(repository, dir,
2507:                        HG_STATUS_FLAG_INTERESTING_CMD, true);
2508:            }
2509:
2510:            /**
2511:             * Returns the mercurial status for only files of interest to us in a given repository
2512:             * that is modified, locally added, locally removed, locally deleted, locally new and ignored.
2513:             *
2514:             * @param File repository of the mercurial repository's root directory
2515:             * @return Map of files and status for all files of interest under the repository root
2516:             * @throws org.netbeans.modules.mercurial.HgException
2517:             */
2518:            public static Map<File, FileInformation> getAllRemovedDeletedStatus(
2519:                    File repository) throws HgException {
2520:                return getAllStatusWithFlags(repository,
2521:                        HG_STATUS_FLAG_REM_DEL_CMD, true);
2522:            }
2523:
2524:            /**
2525:             * Returns the mercurial status for only files of interest to us in a given directory in a repository
2526:             * that is modified, locally added, locally removed, locally deleted, locally new and ignored.
2527:             *
2528:             * @param File repository of the mercurial repository's root directory
2529:             * @param File dir of the directory of interest
2530:             * @return Map of files and status for all files of interest in the specified directory
2531:             * @throws org.netbeans.modules.mercurial.HgException
2532:             */
2533:            public static Map<File, FileInformation> getRemovedDeletedStatus(
2534:                    File repository, File dir) throws HgException {
2535:                return getDirStatusWithFlags(repository, dir,
2536:                        HG_STATUS_FLAG_REM_DEL_CMD, true);
2537:            }
2538:
2539:            /**
2540:             * Returns the unknown files in a specified directory under a mercurial repository root
2541:             *
2542:             * @param File of the mercurial repository's root directory
2543:             * @param File of the directory whose files are required
2544:             * @return Map of files and status for all files under the repository root
2545:             * @throws org.netbeans.modules.mercurial.HgException
2546:             */
2547:            public static Map<File, FileInformation> getUnknownStatus(
2548:                    File repository, File dir) throws HgException {
2549:                Map<File, FileInformation> files = getDirStatusWithFlags(
2550:                        repository, dir, HG_STATUS_FLAG_UNKNOWN_CMD, false);
2551:                int share = SharabilityQuery
2552:                        .getSharability(dir == null ? repository : dir);
2553:                for (Iterator i = files.keySet().iterator(); i.hasNext();) {
2554:                    File file = (File) i.next();
2555:                    if ((share == SharabilityQuery.MIXED && SharabilityQuery
2556:                            .getSharability(file) == SharabilityQuery.NOT_SHARABLE)
2557:                            || (share == SharabilityQuery.NOT_SHARABLE)) {
2558:                        i.remove();
2559:                    }
2560:                }
2561:                return files;
2562:            }
2563:
2564:            /**
2565:             * Returns the unknown files under a mercurial repository root
2566:             *
2567:             * @param File repository of the mercurial repository's root directory
2568:             * @return Map of files and status for all files under the repository root
2569:             * @throws org.netbeans.modules.mercurial.HgException
2570:             */
2571:            public static Map<File, FileInformation> getAllUnknownStatus(
2572:                    File repository) throws HgException {
2573:                return getUnknownStatus(repository, null);
2574:            }
2575:
2576:            /**
2577:             * Remove the specified file from the mercurial Repository
2578:             *
2579:             * @param File repository of the mercurial repository's root directory
2580:             * @param List<Files> of files to be added to hg
2581:             * @param f path to be removed from the repository
2582:             * @throws org.netbeans.modules.mercurial.HgException
2583:             */
2584:            public static void doRemove(File repository,
2585:                    List<File> removeFiles, OutputLogger logger)
2586:                    throws HgException {
2587:                List<String> command = new ArrayList<String>();
2588:
2589:                command.add(getHgCommand());
2590:                command.add(HG_REMOVE_CMD);
2591:                command.add(HG_OPT_REPOSITORY);
2592:                command.add(repository.getAbsolutePath());
2593:                command.add(HG_REMOVE_FLAG_FORCE_CMD);
2594:                for (File f : removeFiles) {
2595:                    command.add(f.getAbsolutePath());
2596:                }
2597:
2598:                List<String> list = exec(command);
2599:                if (!list.isEmpty() && isErrorAlreadyTracked(list.get(0)))
2600:                    handleError(command, list, NbBundle.getMessage(
2601:                            HgCommand.class, "MSG_ALREADY_TRACKED"), logger);
2602:            }
2603:
2604:            /**
2605:             * Remove the specified files from the mercurial Repository
2606:             *
2607:             * @param File repository of the mercurial repository's root directory
2608:             * @param f path to be removed from the repository
2609:             * @throws org.netbeans.modules.mercurial.HgException
2610:             */
2611:            public static void doRemove(File repository, File f,
2612:                    OutputLogger logger) throws HgException {
2613:                List<String> command = new ArrayList<String>();
2614:
2615:                command.add(getHgCommand());
2616:                command.add(HG_REMOVE_CMD);
2617:                command.add(HG_OPT_REPOSITORY);
2618:                command.add(repository.getAbsolutePath());
2619:                command.add(HG_REMOVE_FLAG_FORCE_CMD);
2620:                command.add(f.getAbsolutePath());
2621:
2622:                List<String> list = exec(command);
2623:                if (!list.isEmpty() && isErrorAlreadyTracked(list.get(0)))
2624:                    handleError(command, list, NbBundle.getMessage(
2625:                            HgCommand.class, "MSG_ALREADY_TRACKED"), logger);
2626:            }
2627:
2628:            /**
2629:             * Export the diffs for the specified revision to the specified output file
2630:            /**
2631:             * Export the diffs for the specified revision to the specified output file
2632:             *
2633:             * @param File repository of the mercurial repository's root directory
2634:             * @param revStr the revision whose diffs are to be exported
2635:             * @param outputFileName path of the output file
2636:             * @throws org.netbeans.modules.mercurial.HgException
2637:             */
2638:            public static List<String> doExport(File repository, String revStr,
2639:                    String outputFileName, OutputLogger logger)
2640:                    throws HgException {
2641:                // Ensure that parent directory of target exists, creating if necessary
2642:                File fileTarget = new File(outputFileName);
2643:                File parentTarget = fileTarget.getParentFile();
2644:                try {
2645:                    if (!parentTarget.mkdir()) {
2646:                        if (!parentTarget.isDirectory()) {
2647:                            Mercurial.LOG.log(Level.WARNING,
2648:                                    "File.mkdir() failed for : "
2649:                                            + parentTarget.getAbsolutePath()); // NOI18N
2650:                            throw (new HgException(NbBundle.getMessage(
2651:                                    HgCommand.class,
2652:                                    "MSG_UNABLE_TO_CREATE_PARENT_DIR"))); // NOI18N
2653:                        }
2654:                    }
2655:                } catch (SecurityException e) {
2656:                    Mercurial.LOG.log(Level.WARNING, "File.mkdir() for : "
2657:                            + parentTarget.getAbsolutePath()
2658:                            + " threw SecurityException " + e.getMessage()); // NOI18N
2659:                    throw (new HgException(NbBundle.getMessage(HgCommand.class,
2660:                            "MSG_UNABLE_TO_CREATE_PARENT_DIR"))); // NOI18N
2661:                }
2662:                List<String> command = new ArrayList<String>();
2663:
2664:                command.add(getHgCommand());
2665:                command.add(HG_EXPORT_CMD);
2666:                command.add(HG_VERBOSE_CMD);
2667:                command.add(HG_OPT_REPOSITORY);
2668:                command.add(repository.getAbsolutePath());
2669:                command.add(HG_FLAG_OUTPUT_CMD);
2670:                command.add(outputFileName);
2671:                command.add(revStr);
2672:
2673:                List<String> list = exec(command);
2674:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
2675:                    handleError(command, list, NbBundle.getMessage(
2676:                            HgCommand.class, "MSG_EXPORT_FAILED"), logger);
2677:                }
2678:                return list;
2679:            }
2680:
2681:            /**
2682:             * Export the diffs for the specified revision to the specified output file
2683:            /**
2684:             * Export the diffs for the specified revision to the specified output file
2685:             *
2686:             * @param File repository of the mercurial repository's root directory
2687:             * @param revStr the revision whose diffs are to be exported
2688:             * @param outputFileName path of the output file
2689:             * @throws org.netbeans.modules.mercurial.HgException
2690:             */
2691:            public static List<String> doExportFileDiff(File repository,
2692:                    File file, String revStr, String outputFileName,
2693:                    OutputLogger logger) throws HgException {
2694:                // Ensure that parent directory of target exists, creating if necessary
2695:                File fileTarget = new File(outputFileName);
2696:                File parentTarget = fileTarget.getParentFile();
2697:                try {
2698:                    if (!parentTarget.mkdir()) {
2699:                        if (!parentTarget.isDirectory()) {
2700:                            Mercurial.LOG.log(Level.WARNING,
2701:                                    "File.mkdir() failed for : "
2702:                                            + parentTarget.getAbsolutePath()); // NOI18N
2703:                            throw (new HgException(NbBundle.getMessage(
2704:                                    HgCommand.class,
2705:                                    "MSG_UNABLE_TO_CREATE_PARENT_DIR"))); // NOI18N
2706:                        }
2707:                    }
2708:                } catch (SecurityException e) {
2709:                    Mercurial.LOG.log(Level.WARNING, "File.mkdir() for : "
2710:                            + parentTarget.getAbsolutePath()
2711:                            + " threw SecurityException " + e.getMessage()); // NOI18N
2712:                    throw (new HgException(NbBundle.getMessage(HgCommand.class,
2713:                            "MSG_UNABLE_TO_CREATE_PARENT_DIR"))); // NOI18N
2714:                }
2715:                List<String> command = new ArrayList<String>();
2716:
2717:                command.add(getHgCommand());
2718:                command.add(HG_LOG_CMD);
2719:                command.add(HG_OPT_REPOSITORY);
2720:                command.add(repository.getAbsolutePath());
2721:                command.add(HG_REV_CMD);
2722:                command.add(revStr);
2723:                command.add(HG_LOG_TEMPLATE_EXPORT_FILE_CMD);
2724:                command.add(HG_LOG_PATCH_CMD);
2725:                command.add(file.getAbsolutePath());
2726:
2727:                List<String> list = exec(command);
2728:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
2729:                    handleError(command, list, NbBundle.getMessage(
2730:                            HgCommand.class, "MSG_EXPORT_FAILED"), logger);
2731:                } else {
2732:                    writeOutputFileDiff(list, outputFileName);
2733:                }
2734:                return list;
2735:            }
2736:
2737:            private static void writeOutputFileDiff(List<String> list,
2738:                    String outputFileName) {
2739:                PrintWriter pw = null;
2740:                try {
2741:                    pw = new PrintWriter(new FileWriter(outputFileName));
2742:                    for (String s : list) {
2743:                        pw.println(s);
2744:                        pw.flush();
2745:                    }
2746:                } catch (IOException ex) {
2747:                    // Ignore
2748:                } finally {
2749:                    if (pw != null)
2750:                        pw.close();
2751:                }
2752:            }
2753:
2754:            /**
2755:             * Imports the diffs from the specified file
2756:             *
2757:             * @param File repository of the mercurial repository's root directory
2758:             * @param File patchFile of the patch file
2759:             * @throws org.netbeans.modules.mercurial.HgException
2760:             */
2761:            public static List<String> doImport(File repository,
2762:                    File patchFile, OutputLogger logger) throws HgException {
2763:                List<String> command = new ArrayList<String>();
2764:
2765:                command.add(getHgCommand());
2766:                command.add(HG_IMPORT_CMD);
2767:                command.add(HG_VERBOSE_CMD);
2768:                command.add(HG_OPT_REPOSITORY);
2769:                command.add(repository.getAbsolutePath());
2770:                command.add(HG_OPT_CWD_CMD);
2771:                command.add(repository.getAbsolutePath());
2772:                command.add(patchFile.getAbsolutePath());
2773:
2774:                List<String> list = exec(command);
2775:                if (!list.isEmpty() && isErrorAbort(list.get(list.size() - 1))) {
2776:                    logger.output(list); // need the failure info from import
2777:                    handleError(command, list, NbBundle.getMessage(
2778:                            HgCommand.class, "MSG_IMPORT_FAILED"), logger);
2779:                }
2780:                return list;
2781:            }
2782:
2783:            /**
2784:             * Returns Map of mercurial file and status for files in a given repository as specified by the status flags
2785:             */
2786:            private static Map<File, FileInformation> getAllStatusWithFlags(
2787:                    File repository, String statusFlags,
2788:                    boolean bIgnoreUnversioned) throws HgException {
2789:                return getDirStatusWithFlags(repository, null, statusFlags,
2790:                        bIgnoreUnversioned);
2791:            }
2792:
2793:            private static Map<File, FileInformation> getDirStatusWithFlags(
2794:                    File repository, File dir, String statusFlags,
2795:                    boolean bIgnoreUnversioned) throws HgException {
2796:                if (repository == null)
2797:                    return null;
2798:
2799:                List<FileStatus> statusList = new ArrayList<FileStatus>();
2800:                FileInformation prev_info = null;
2801:                List<String> list = doRepositoryDirStatusCmd(repository, dir,
2802:                        statusFlags);
2803:
2804:                Map<File, FileInformation> repositoryFiles = new HashMap<File, FileInformation>(
2805:                        list.size());
2806:
2807:                StringBuffer filePath = null;
2808:                for (String statusLine : list) {
2809:                    FileInformation info = getFileInformationFromStatusLine(statusLine);
2810:                    Mercurial.LOG
2811:                            .log(
2812:                                    Level.FINE,
2813:                                    "getDirStatusWithFlags(): status line {0}  info {1}",
2814:                                    new Object[] { statusLine, info }); // NOI18N
2815:                    if (statusLine.length() > 0) {
2816:                        if (statusLine.charAt(0) == ' ') {
2817:                            // Locally Added but Copied
2818:                            if (filePath != null) {
2819:                                prev_info = new FileInformation(
2820:                                        FileInformation.STATUS_VERSIONED_ADDEDLOCALLY,
2821:                                        new FileStatus(new File(filePath
2822:                                                .toString()), true), false);
2823:                                Mercurial.LOG
2824:                                        .log(
2825:                                                Level.FINE,
2826:                                                "getDirStatusWithFlags(): prev_info {0}  filePath {1}",
2827:                                                new Object[] { prev_info,
2828:                                                        filePath.toString() }); // NOI18N
2829:                            } else {
2830:                                Mercurial.LOG
2831:                                        .log(
2832:                                                Level.FINE,
2833:                                                "getDirStatusWithFlags(): repository path: {0} status flags: {1} status line {2} filepath == nullfor prev_info ",
2834:                                                new Object[] {
2835:                                                        repository
2836:                                                                .getAbsolutePath(),
2837:                                                        statusFlags, statusLine }); // NOI18N
2838:                            }
2839:                            break;
2840:                        } else {
2841:                            if (filePath != null) {
2842:                                repositoryFiles.put(new File(filePath
2843:                                        .toString()), prev_info);
2844:                            }
2845:                        }
2846:                    }
2847:                    if (bIgnoreUnversioned) {
2848:                        if (info.getStatus() == FileInformation.STATUS_NOTVERSIONED_NOTMANAGED
2849:                                || info.getStatus() == FileInformation.STATUS_UNKNOWN)
2850:                            continue;
2851:                    } else {
2852:                        if (info.getStatus() == FileInformation.STATUS_UNKNOWN)
2853:                            continue;
2854:                    }
2855:                    filePath = new StringBuffer(repository.getAbsolutePath())
2856:                            .append(File.separatorChar);
2857:                    StringBuffer sb = new StringBuffer(statusLine);
2858:                    sb.delete(0, 2); // Strip status char and following 2 spaces: [MARC\?\!I][ ][ ]
2859:                    filePath.append(sb.toString());
2860:
2861:                    // Handle Conflict Status
2862:                    // TODO: remove this if Hg status supports Conflict marker
2863:                    if (existsConflictFile(filePath.toString())) {
2864:                        info = new FileInformation(
2865:                                FileInformation.STATUS_VERSIONED_CONFLICT,
2866:                                null, false);
2867:                        Mercurial.LOG
2868:                                .log(
2869:                                        Level.FINE,
2870:                                        "getDirStatusWithFlags(): CONFLICT repository path: {0} status flags: {1} status line {2} CONFLICT {3}",
2871:                                        new Object[] {
2872:                                                repository.getAbsolutePath(),
2873:                                                statusFlags,
2874:                                                statusLine,
2875:                                                filePath.toString()
2876:                                                        + HgCommand.HG_STR_CONFLICT_EXT }); // NOI18N
2877:                    }
2878:                    prev_info = info;
2879:                }
2880:                if (prev_info != null) {
2881:                    repositoryFiles.put(new File(filePath.toString()),
2882:                            prev_info);
2883:                }
2884:
2885:                if (list.size() < 10) {
2886:                    Mercurial.LOG
2887:                            .log(
2888:                                    Level.FINE,
2889:                                    "getDirStatusWithFlags(): repository path: {0} status flags: {1} status list {2}", // NOI18N
2890:                                    new Object[] {
2891:                                            repository.getAbsolutePath(),
2892:                                            statusFlags, list });
2893:                } else {
2894:                    Mercurial.LOG
2895:                            .log(
2896:                                    Level.FINE,
2897:                                    "getDirStatusWithFlags(): repository path: {0} status flags: {1} status list has {2} elements", // NOI18N
2898:                                    new Object[] {
2899:                                            repository.getAbsolutePath(),
2900:                                            statusFlags, list.size() });
2901:                }
2902:                return repositoryFiles;
2903:            }
2904:
2905:            /**
2906:             * Gets file information for a given hg status output status line
2907:             */
2908:            private static FileInformation getFileInformationFromStatusLine(
2909:                    String status) {
2910:                FileInformation info = null;
2911:                if (status == null || (status.length() == 0))
2912:                    return new FileInformation(
2913:                            FileInformation.STATUS_VERSIONED_UPTODATE, null,
2914:                            false);
2915:
2916:                char c0 = status.charAt(0);
2917:                char c1 = status.charAt(1);
2918:                switch (c0 + c1) {
2919:                case HG_STATUS_CODE_MODIFIED:
2920:                    info = new FileInformation(
2921:                            FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY,
2922:                            null, false);
2923:                    break;
2924:                case HG_STATUS_CODE_ADDED:
2925:                    info = new FileInformation(
2926:                            FileInformation.STATUS_VERSIONED_ADDEDLOCALLY,
2927:                            null, false);
2928:                    break;
2929:                case HG_STATUS_CODE_REMOVED:
2930:                    info = new FileInformation(
2931:                            FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY,
2932:                            null, false);
2933:                    break;
2934:                case HG_STATUS_CODE_CLEAN:
2935:                    info = new FileInformation(
2936:                            FileInformation.STATUS_VERSIONED_UPTODATE, null,
2937:                            false);
2938:                    break;
2939:                case HG_STATUS_CODE_DELETED:
2940:                    info = new FileInformation(
2941:                            FileInformation.STATUS_VERSIONED_DELETEDLOCALLY,
2942:                            null, false);
2943:                    break;
2944:                case HG_STATUS_CODE_IGNORED:
2945:                    info = new FileInformation(
2946:                            FileInformation.STATUS_NOTVERSIONED_EXCLUDED, null,
2947:                            false);
2948:                    break;
2949:                case HG_STATUS_CODE_NOTTRACKED:
2950:                    info = new FileInformation(
2951:                            FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY,
2952:                            null, false);
2953:                    break;
2954:                // Leave this here for whenever Hg status suports conflict markers
2955:                case HG_STATUS_CODE_CONFLICT:
2956:                    info = new FileInformation(
2957:                            FileInformation.STATUS_VERSIONED_CONFLICT, null,
2958:                            false);
2959:                    break;
2960:                case HG_STATUS_CODE_ABORT:
2961:                    info = new FileInformation(
2962:                            FileInformation.STATUS_NOTVERSIONED_NOTMANAGED,
2963:                            null, false);
2964:                    break;
2965:                default:
2966:                    info = new FileInformation(FileInformation.STATUS_UNKNOWN,
2967:                            null, false);
2968:                    break;
2969:                }
2970:
2971:                return info;
2972:            }
2973:
2974:            /**
2975:             * Gets hg status command output line for a given file
2976:             */
2977:            private static List<String> doSingleStatusCmd(File repository,
2978:                    String cwd, String filename) throws HgException {
2979:                String statusLine = null;
2980:
2981:                List<String> command = new ArrayList<String>();
2982:
2983:                command.add(getHgCommand());
2984:                command.add(HG_STATUS_CMD);
2985:                command.add(HG_STATUS_FLAG_ALL_CMD);
2986:                command.add(HG_OPT_REPOSITORY);
2987:                command.add(repository.getAbsolutePath());
2988:                command.add(HG_OPT_CWD_CMD);
2989:                command.add(repository.getAbsolutePath());
2990:
2991:                // In 0.9.3 hg status does not give back copy information unless we 
2992:                // use relative paths from repository. This is fixed in 0.9.4.
2993:                // See http://www.selenic.com/mercurial/bts/issue545.
2994:                command.add(new File(cwd, filename).getAbsolutePath()
2995:                        .substring(repository.getAbsolutePath().length() + 1));
2996:
2997:                return exec(command);
2998:            }
2999:
3000:            /**
3001:             * Gets hg status command output list for the specified status flags for a given repository and directory
3002:             */
3003:            private static List<String> doRepositoryDirStatusCmd(
3004:                    File repository, File dir, String statusFlags)
3005:                    throws HgException {
3006:                List<String> command = new ArrayList<String>();
3007:
3008:                command.add(getHgCommand());
3009:                command.add(HG_STATUS_CMD);
3010:
3011:                command.add(statusFlags);
3012:                command.add(HG_OPT_REPOSITORY);
3013:                command.add(repository.getAbsolutePath());
3014:                command.add(HG_OPT_CWD_CMD);
3015:                command.add(repository.getAbsolutePath());
3016:                if (dir != null) {
3017:                    command.add(dir.getAbsolutePath());
3018:                } else {
3019:                    command.add(repository.getAbsolutePath());
3020:                }
3021:
3022:                List<String> list = exec(command);
3023:                if (!list.isEmpty() && isErrorNoRepository(list.get(0))) {
3024:                    OutputLogger logger = OutputLogger.getLogger(repository
3025:                            .getAbsolutePath());
3026:                    try {
3027:                        handleError(command, list, NbBundle.getMessage(
3028:                                HgCommand.class, "MSG_NO_REPOSITORY_ERR"),
3029:                                logger);
3030:                    } finally {
3031:                        logger.closeLog();
3032:                    }
3033:                }
3034:                return list;
3035:            }
3036:
3037:            /**
3038:             * Returns the ouput from the given command
3039:             *
3040:             * @param command to execute
3041:             * @return List of the command's output or an exception if one occured
3042:             */
3043:
3044:            private static List<String> execEnv(List<String> command,
3045:                    List<String> env) throws HgException {
3046:                if (EventQueue.isDispatchThread()) {
3047:                    Mercurial.LOG
3048:                            .log(Level.FINE,
3049:                                    "WARNING execEnv():  calling Hg command in AWT Thread - could stall UI"); // NOI18N
3050:                }
3051:                assert (command != null && command.size() > 0);
3052:                List<String> list = new ArrayList<String>();
3053:                BufferedReader input = null;
3054:                Process proc = null;
3055:                try {
3056:                    if (command.size() > 10) {
3057:                        List<String> smallCommand = new ArrayList<String>();
3058:                        int count = 0;
3059:                        for (Iterator i = command.iterator(); i.hasNext();) {
3060:                            smallCommand.add((String) i.next());
3061:                            if (count++ > 10)
3062:                                break;
3063:                        }
3064:                        Mercurial.LOG.log(Level.FINE, "execEnv(): "
3065:                                + smallCommand); // NOI18N
3066:                    } else {
3067:                        Mercurial.LOG.log(Level.FINE, "execEnv(): " + command); // NOI18N
3068:                    }
3069:                    if (env != null && env.size() > 0) {
3070:                        ProcessBuilder pb = new ProcessBuilder(command);
3071:                        Map<String, String> envOrig = pb.environment();
3072:                        for (String s : env) {
3073:                            envOrig.put(s.substring(0, s.indexOf('=')), s
3074:                                    .substring(s.indexOf('=') + 1));
3075:                        }
3076:                        proc = pb.start();
3077:                    } else {
3078:                        proc = new ProcessBuilder(command).start();
3079:                    }
3080:
3081:                    input = new BufferedReader(new InputStreamReader(proc
3082:                            .getInputStream()));
3083:
3084:                    String line;
3085:                    while ((line = input.readLine()) != null) {
3086:                        list.add(line);
3087:                    }
3088:                    input.close();
3089:                    input = new BufferedReader(new InputStreamReader(proc
3090:                            .getErrorStream()));
3091:                    while ((line = input.readLine()) != null) {
3092:                        list.add(line);
3093:                    }
3094:                    input.close();
3095:                    input = null;
3096:                    try {
3097:                        proc.waitFor();
3098:                        // By convention we assume that 255 (or -1) is a serious error.
3099:                        // For instance, the command line could be too long.
3100:                        if (proc.exitValue() == 255) {
3101:                            Mercurial.LOG.log(Level.FINE,
3102:                                    "execEnv():  process returned 255"); // NOI18N
3103:                            if (list.isEmpty()) {
3104:                                Mercurial.LOG.log(Level.SEVERE, "command: "
3105:                                        + command); // NOI18N
3106:                                throw new HgException(NbBundle.getMessage(
3107:                                        HgCommand.class,
3108:                                        "MSG_UNABLE_EXECUTE_COMMAND"));
3109:                            }
3110:                        }
3111:                    } catch (InterruptedException e) {
3112:                        Mercurial.LOG.log(Level.FINE,
3113:                                "execEnv():  process interrupted " + e); // NOI18N
3114:                    }
3115:                } catch (InterruptedIOException e) {
3116:                    // We get here is we try to cancel so kill the process
3117:                    Mercurial.LOG.log(Level.FINE,
3118:                            "execEnv():  execEnv(): InterruptedIOException "
3119:                                    + e); // NOI18N
3120:                    if (proc != null) {
3121:                        try {
3122:                            proc.getInputStream().close();
3123:                            proc.getOutputStream().close();
3124:                            proc.getErrorStream().close();
3125:                        } catch (IOException ioex) {
3126:                            //Just ignore. Closing streams.
3127:                        }
3128:                        proc.destroy();
3129:                    }
3130:                    throw new HgException(NbBundle.getMessage(HgCommand.class,
3131:                            "MSG_COMMAND_CANCELLED"));
3132:                } catch (IOException e) {
3133:                    // Hg does not seem to be returning error status != 0
3134:                    // even when it fails when for instance adding an already tracked file to
3135:                    // the repository - we will have to examine the output in the context of the
3136:                    // calling func and raise exceptions there if needed
3137:                    Mercurial.LOG.log(Level.SEVERE,
3138:                            "execEnv():  execEnv(): IOException " + e); // NOI18N
3139:
3140:                    // Handle low level Mercurial failures
3141:                    if (isErrorArgsTooLong(e.getMessage())) {
3142:                        assert (command.size() > 2);
3143:                        throw new HgException(NbBundle.getMessage(
3144:                                HgCommand.class, "MSG_ARG_LIST_TOO_LONG_ERR",
3145:                                command.get(1), command.size() - 2));
3146:                    } else if (isErrorNoHg(e.getMessage())
3147:                            || isErrorCannotRun(e.getMessage())) {
3148:                        throw new HgException(NbBundle.getMessage(
3149:                                Mercurial.class, "MSG_VERSION_NONE_MSG"));
3150:                    } else {
3151:                        throw new HgException(NbBundle.getMessage(
3152:                                HgCommand.class, "MSG_UNABLE_EXECUTE_COMMAND"));
3153:                    }
3154:                } finally {
3155:                    if (input != null) {
3156:                        try {
3157:                            input.close();
3158:                        } catch (IOException ioex) {
3159:                            //Just ignore. Closing streams.
3160:                        }
3161:                        input = null;
3162:                    }
3163:                }
3164:                return list;
3165:            }
3166:
3167:            /**
3168:             * Returns the ouput from the given command
3169:             *
3170:             * @param command to execute
3171:             * @return List of the command's output or an exception if one occured
3172:             */
3173:            private static List<String> exec(List<String> command)
3174:                    throws HgException {
3175:                if (!Mercurial.getInstance().isGoodVersion()) {
3176:                    return new ArrayList<String>();
3177:                }
3178:                return execEnv(command, null);
3179:            }
3180:
3181:            private static List<String> execForVersionCheck()
3182:                    throws HgException {
3183:                List<String> command = new ArrayList<String>();
3184:                command.add(getHgCommand());
3185:                command.add(HG_VERSION_CMD);
3186:
3187:                return execEnv(command, null);
3188:            }
3189:
3190:            private static String getHgCommand() {
3191:                String defaultPath = HgModuleConfig.getDefault()
3192:                        .getExecutableBinaryPath();
3193:                if (defaultPath == null || defaultPath.length() == 0)
3194:                    return HG_COMMAND;
3195:                else
3196:                    return defaultPath + File.separatorChar + HG_COMMAND;
3197:            }
3198:
3199:            private static void handleError(List<String> command,
3200:                    List<String> list, String message, OutputLogger logger)
3201:                    throws HgException {
3202:                if (command != null && list != null && logger != null) {
3203:                    Mercurial.LOG.log(Level.WARNING, "command: "
3204:                            + HgUtils.replaceHttpPassword(command)); // NOI18N        
3205:                    Mercurial.LOG.log(Level.WARNING, "output: "
3206:                            + HgUtils.replaceHttpPassword(list)); // NOI18N
3207:                    logger.outputInRed(NbBundle.getMessage(HgCommand.class,
3208:                            "MSG_COMMAND_ERR")); // NOI18N
3209:                    logger.output(NbBundle.getMessage(HgCommand.class,
3210:                            "MSG_COMMAND_INFO_ERR", HgUtils
3211:                                    .replaceHttpPassword(command), HgUtils
3212:                                    .replaceHttpPassword(list))); // NOI18N
3213:                }
3214:
3215:                if (list != null
3216:                        && (isErrorPossibleProxyIssue(list.get(0)) || isErrorPossibleProxyIssue(list
3217:                                .get(list.size() - 1)))) {
3218:                    boolean bConfirmSetProxy;
3219:                    bConfirmSetProxy = HgUtils.confirmDialog(HgCommand.class,
3220:                            "MSG_POSSIBLE_PROXY_ISSUE_TITLE",
3221:                            "MSG_POSSIBLE_PROXY_ISSUE_QUERY"); // NOI18N
3222:                    if (bConfirmSetProxy) {
3223:                        OptionsDisplayer.getDefault().open("General"); // NOI18N
3224:                    }
3225:                } else {
3226:                    throw new HgException(message);
3227:                }
3228:            }
3229:
3230:            public static boolean isMergeNeededMsg(String msg) {
3231:                return msg.indexOf(HG_MERGE_NEEDED_ERR) > -1; // NOI18N
3232:            }
3233:
3234:            public static boolean isBackoutMergeNeededMsg(String msg) {
3235:                return msg.indexOf(HG_BACKOUT_MERGE_NEEDED_ERR) > -1; // NOI18N
3236:            }
3237:
3238:            public static boolean isMergeConflictMsg(String msg) {
3239:                if (Utilities.isWindows()) {
3240:                    return (msg.indexOf(HG_MERGE_CONFLICT_WIN1_ERR) > -1) && // NOI18N
3241:                            (msg.indexOf(HG_MERGE_CONFLICT_WIN2_ERR) > -1); // NOI18N
3242:                } else {
3243:                    return msg.indexOf(HG_MERGE_CONFLICT_ERR) > -1; // NOI18N
3244:                }
3245:            }
3246:
3247:            public static boolean isMergeUnavailableMsg(String msg) {
3248:                return msg.indexOf(HG_MERGE_UNAVAILABLE_ERR) > -1; // NOI18N
3249:            }
3250:
3251:            public static boolean isMergeAbortMultipleHeadsMsg(String msg) {
3252:                return msg.indexOf(HG_MERGE_MULTIPLE_HEADS_ERR) > -1; // NOI18N
3253:            }
3254:
3255:            public static boolean isMergeAbortUncommittedMsg(String msg) {
3256:                return msg.indexOf(HG_MERGE_UNCOMMITTED_ERR) > -1; // NOI18N
3257:            }
3258:
3259:            public static boolean isNoChanges(String msg) {
3260:                return msg.indexOf(HG_NO_CHANGES_ERR) > -1; // NOI18N
3261:            }
3262:
3263:            private static boolean isErrorNoDefaultPush(String msg) {
3264:                return msg.indexOf(HG_ABORT_NO_DEFAULT_PUSH_ERR) > -1; // NOI18N
3265:            }
3266:
3267:            private static boolean isErrorNoDefaultPath(String msg) {
3268:                return msg.indexOf(HG_ABORT_NO_DEFAULT_ERR) > -1; // NOI18N
3269:            }
3270:
3271:            private static boolean isErrorPossibleProxyIssue(String msg) {
3272:                return msg.indexOf(HG_ABORT_POSSIBLE_PROXY_ERR) > -1; // NOI18N
3273:            }
3274:
3275:            private static boolean isErrorNoRepository(String msg) {
3276:                return msg.indexOf(HG_NO_REPOSITORY_ERR) > -1
3277:                        || msg.indexOf(HG_NOT_REPOSITORY_ERR) > -1
3278:                        || (msg.indexOf(HG_REPOSITORY) > -1 && msg
3279:                                .indexOf(HG_NOT_FOUND_ERR) > -1); // NOI18N
3280:            }
3281:
3282:            private static boolean isErrorNoHg(String msg) {
3283:                return msg.indexOf(HG_NO_HG_CMD_FOUND_ERR) > -1; // NOI18N
3284:            }
3285:
3286:            private static boolean isErrorArgsTooLong(String msg) {
3287:                return msg.indexOf(HG_ARG_LIST_TOO_LONG_ERR) > -1; // NOI18N
3288:            }
3289:
3290:            private static boolean isErrorCannotRun(String msg) {
3291:                return msg.indexOf(HG_CANNOT_RUN_ERR) > -1; // NOI18N
3292:            }
3293:
3294:            private static boolean isErrorUpdateSpansBranches(String msg) {
3295:                return msg.indexOf(HG_UPDATE_SPAN_BRANCHES_ERR) > -1; // NOI18N
3296:            }
3297:
3298:            private static boolean isErrorAlreadyTracked(String msg) {
3299:                return msg.indexOf(HG_ALREADY_TRACKED_ERR) > -1; // NOI18N
3300:            }
3301:
3302:            private static boolean isErrorNotTracked(String msg) {
3303:                return msg.indexOf(HG_NOT_TRACKED_ERR) > -1; // NOI18N
3304:            }
3305:
3306:            private static boolean isErrorNotFound(String msg) {
3307:                return msg.indexOf(HG_NOT_FOUND_ERR) > -1; // NOI18N
3308:            }
3309:
3310:            private static boolean isErrorCannotReadCommitMsg(String msg) {
3311:                return msg.indexOf(HG_CANNOT_READ_COMMIT_MESSAGE_ERR) > -1; // NOI18N
3312:            }
3313:
3314:            private static boolean isErrorAbort(String msg) {
3315:                return msg.indexOf(HG_ABORT_ERR) > -1; // NOI18N
3316:            }
3317:
3318:            public static boolean isErrorAbortPush(String msg) {
3319:                return msg.indexOf(HG_ABORT_PUSH_ERR) > -1; // NOI18N
3320:            }
3321:
3322:            public static boolean isErrorAbortNoFilesToCopy(String msg) {
3323:                return msg.indexOf(HG_ABORT_NO_FILES_TO_COPY_ERR) > -1; // NOI18N
3324:            }
3325:
3326:            private static boolean isErrorNoChangeNeeded(String msg) {
3327:                return msg.indexOf(HG_NO_CHANGE_NEEDED_ERR) > -1; // NOI18N
3328:            }
3329:
3330:            public static boolean isCreateNewBranch(String msg) {
3331:                return msg.indexOf(HG_CREATE_NEW_BRANCH_ERR) > -1; // NOI18N
3332:            }
3333:
3334:            public static boolean isHeadsCreated(String msg) {
3335:                return msg.indexOf(HG_HEADS_CREATED_ERR) > -1; // NOI18N
3336:            }
3337:
3338:            public static boolean isNoRollbackPossible(String msg) {
3339:                return msg.indexOf(HG_NO_ROLLBACK_ERR) > -1; // NOI18N
3340:            }
3341:
3342:            public static boolean isNoRevStrip(String msg) {
3343:                return msg.indexOf(HG_NO_REV_STRIP_ERR) > -1; // NOI18N
3344:            }
3345:
3346:            public static boolean isLocalChangesStrip(String msg) {
3347:                return msg.indexOf(HG_LOCAL_CHANGES_STRIP_ERR) > -1; // NOI18N
3348:            }
3349:
3350:            public static boolean isMultipleHeadsStrip(String msg) {
3351:                return msg.indexOf(HG_MULTIPLE_HEADS_STRIP_ERR) > -1; // NOI18N
3352:            }
3353:
3354:            public static boolean isUncommittedChangesBackout(String msg) {
3355:                return msg.indexOf(HG_ABORT_UNCOMMITTED_CHANGES_ERR) > -1; // NOI18N
3356:            }
3357:
3358:            public static boolean isMergeChangesetBackout(String msg) {
3359:                return msg.indexOf(HG_ABORT_BACKOUT_MERGE_CSET_ERR) > -1; // NOI18N
3360:            }
3361:
3362:            public static boolean isNoUpdates(String msg) {
3363:                return msg.indexOf(HG_NO_UPDATES_ERR) > -1; // NOI18N
3364:            }
3365:
3366:            private static boolean isErrorNoView(String msg) {
3367:                return msg.indexOf(HG_NO_VIEW_ERR) > -1; // NOI18N
3368:            }
3369:
3370:            private static boolean isErrorHgkNotFound(String msg) {
3371:                return msg.indexOf(HG_HGK_NOT_FOUND_ERR) > -1; // NOI18N
3372:            }
3373:
3374:            private static boolean isErrorNoSuchFile(String msg) {
3375:                return msg.indexOf(HG_NO_SUCH_FILE_ERR) > -1; // NOI18N
3376:            }
3377:
3378:            private static boolean isErrorNoResponse(String msg) {
3379:                return msg.indexOf(HG_NO_RESPONSE_ERR) > -1; // NOI18N
3380:            }
3381:
3382:            public static void createConflictFile(String path) {
3383:                try {
3384:                    File file = new File(path + HG_STR_CONFLICT_EXT);
3385:
3386:                    boolean success = file.createNewFile();
3387:                    Mercurial.LOG.log(Level.FINE,
3388:                            "createConflictFile(): File: {0} {1}", // NOI18N
3389:                            new Object[] { path + HG_STR_CONFLICT_EXT,
3390:                                    success ? "Created" : "Not Created" }); // NOI18N
3391:                } catch (IOException e) {
3392:                }
3393:            }
3394:
3395:            public static void deleteConflictFile(String path) {
3396:                boolean success = (new File(path + HG_STR_CONFLICT_EXT))
3397:                        .delete();
3398:
3399:                Mercurial.LOG.log(Level.FINE,
3400:                        "deleteConflictFile(): File: {0} {1}", // NOI18N
3401:                        new Object[] { path + HG_STR_CONFLICT_EXT,
3402:                                success ? "Deleted" : "Not Deleted" }); // NOI18N
3403:            }
3404:
3405:            public static boolean existsConflictFile(String path) {
3406:                File file = new File(path + HG_STR_CONFLICT_EXT);
3407:                boolean bExists = file.canWrite();
3408:
3409:                if (bExists) {
3410:                    Mercurial.LOG
3411:                            .log(Level.FINE,
3412:                                    "existsConflictFile(): File: {0} {1}", // NOI18N
3413:                                    new Object[] { path + HG_STR_CONFLICT_EXT,
3414:                                            "Exists" }); // NOI18N
3415:                }
3416:                return bExists;
3417:            }
3418:
3419:            /**
3420:             * This utility class should not be instantiated anywhere.
3421:             */
3422:            private HgCommand() {
3423:            }
3424:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.