From f7998d05c40c24ae66d1972abfcb070552b1d7b5 Mon Sep 17 00:00:00 2001 From: Tor Norbye Date: Fri, 27 Sep 2013 10:19:19 -0700 Subject: Snapshot cd724ea5e27634f1c84f893f10b646937a677d56 from idea/132.425 of git://git.jetbrains.org/idea/community.git MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cd724ea: Code cleanup - Idea's warnings fixed - message moved to .properties file c84855b: for performance use processNames api for java symbol contributor 334c509: IDEA-114064 Create "From Maven" library dialog doesn't handle full coords correctly (as advertised) 4e10a17: IDEA-109943 Download Library from Maven Repository: artifacts from repository with provider != maven2 are suggested, but repository is filtered off d4bc48d: IDEA-114037 Code completion should prefer variable names to unimported class names b7e5e6c: refix RUBY-11716: do not play with fire, always save and load in UTF-8 ! bb7ed8a: cleanup 15bd24e: cleanup e56b270: ProjectId, don't add project level provider if project is not mapped a0fb6a5: let IsNullCheck mean null->true, the former !null->false meaning was useless 26402542: test data fixed f800733: new inference: input/output inference variables 56d872d: NPE: find usage for db element 3ffd6a0: IDEA-114003 XDebuger breakpoint properties: strage selection jumps in breakpoint tree bbdef54: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken f6ff871: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken 8f3d962: IDEABKL-6897 Enter inserts closing brace in wrong place 6a78643: IDEABKL-6897 Enter inserts closing brace in wrong place 06b899c: IDEA-114001 XDebuger Breakpoint Properties: enable in tree is not saved IDEA-114002 XDebuger breakpoint properties: don't close the dialog by double click IDEA-114004 XDebugger breakpoint properties: checkboxes synchronization is broken aeda985: don't give focus to ant messages view f525708: new inference: overload resolution for SAM return type for implicit lambda should be ignored 6692602: cleanup current file from highlighting markup 27c6645: compilation fix 1936bb2: IDEA-107453 Compilation error if overriding methods have different access modifiers 0ddcc36: api a7f05e1: card layout fixed b007608: IDEA-110203 IDEA ignores space after comma setting for methods declaration/call [CR-IC-2022] ae02c17: hiding artifacts 90e6ed2: back to AddModuleWizard 4a029e9: Groovy: Pull-up members 6f9e810: NPE fc48bab: pull-up cbf7531: prepare pull-up refactoring for Groovy 6762d5f: cleanup b26ffb2: spaces around inner classes 41e8e70: IDEA-113333 Java formatter breaks source code: Merges statements into line comments [CR-IC-2245] ea91b55: IDEA-113815 keep "simple methods in one line" does not keep long methods [CR-IC-2486] ecd65ad: Import Eclipse code style settings from XML profile (a part of IDEA-104068) [CR-IC-2219] aacf1e4: IDEA-113844 (handling of core component initialization failures when spoiled by plugins) 8dc3ede: IDEA-112387 Reformat code with rearrange entires on = fail on enum [CR-IC-2205] 72ddb9e: Merge remote-tracking branch 'origin/master' 209340b: Add the description for MavenDuplicatePluginInspection. de367e1: Merge branch 'svn1_8_new' 1a70497: IdeaTestAssistant: fix test data d6a2510: svn: Fixed "Import" when path/url contains '@' symbol 94c4223: svn: Implemented "Export" action for command line 8913712: parameter popup: escape for annotation methods (IDEA-113971) fdf7312: svn: Made event handler for checkout/export utilize passed progress indicator (instead of just current thread progress indicator) f653713: IDEA-105758: Contradiction between error and fix actions (Java EE artifact) eac456f: Platform: ability to provide native icons for PsiElements (PsiFile/Directory) AppCode: blue icons for folders 4d5c47a: IDEA-77519: Project fails to open when workspace.xml is empty c40e732: two classes temporary restored to fix backward compatibility b6b3bc6: added optional dependencies for framework support providers a9dae78: IDEA-90661: recognize IBM JDK jars 6b44958: cleanup & javadoc 0c0a6a6: IDEA-108785 Allow applying the same context to many selected live templates 247661b: don't search for unknown path macros in the middle of xml unless asked so by PathMacroFilter (IDEA-102674) 90222d5: hopefully fix control flow building stack inconsistency assertions in case when a PCE is thrown 241e44b: EA-50288 - CCE: RefJavaUtilImpl.getTopLevelClass 22d5c2f: ensure to filter already inserted annotations (IDEA-113785) 27b76b4: inplace introducer: another case to restore expression (IDEA-113352) 603e138: add mnemonics (IDEA-113889) a8c374c: XSuspendPolicyPanel "Make default" (requires for new JavaBreakpointType) remove unused methods 4f19472: CR-IC-2485 (deprecation policy specified; deprecated API usage upgraded) 7231807: JavaBreakpointType isSuspendThreadSupported true 8637e89: register JavaBreakpointType, but hide under system property java.debugger.xBreakpoint 0b2d5f0: cleanup 5cc1f5e: EA-50289 (CCE: TooBroadScopeInspection$TooBroadScopeInspectionFix.getCommentText) 505b86e: new inference: pertinent to applicability 8ac21fd: cleanup 2c5f39e: cleanup f6efaa9: simplify DebuggerInvocationUtil bf8865f: overrides 0d49e5b: JavaBreakpointType canPutAt 33ebea3: extract XLineBreakpointTypeBase de7d963: extract XDebuggerEditorsProviderBase, init JavaBreakpointType (is not registered, so, not in action now) ed777e6: remove deprecated canPutAt 9163435: overrides 44af67f8: extract XDebuggerUtil.getInstance().getGroupingByFileRuleAsList() b93b27c: add missing Overrides 0857036: cleanup ae791a7: new inference: test preparations 48120ab: IdeaTestAssistant: add resolving and completion inside TestDataPath annotation 971544b: remove empty unused class c5642d9: hippie completion: split complex tokens by spaces e1383b1: refix and add test for IDEA-90294 Don't use substring match in word completion fbae94c: EA-49809 Made client factories final in SvnVcs 2b4b70f: Fix OC-8127: Appcode hangs on reformatting (endless right shift) +review CR-OC @Anton.Makeev, @Rustam.Vishnyakov b7314cf: fix pycharm detection 5f0bb3c: revert error checking 5f99590: svn: Implemented "Import" action for command line ad04905: svn: Changed import logic to use common commit event handler (instead of checkout event handler) 1a45be0: custom options 8d278a3: MavenArchetypesPanel extracted 32eeb4c: aggregation panel invisible 9388cc4: new project wizard: project type sorting 2c02a07: svn: Add "Skipped" event processing in commit/import output for command line d365580: svn: Refactored commit output parsing for command line b1cc312: immutable dfa offset stack 5c494fb: toolbarIcon is nullable 4304880: dfa: traverse only flushable variables, not all ed08eab: immutable EqClass 03de519: overrides f8661d9: return empty collection if list of storage files is empty 81a998c: IDEA-111030: Add Framework Support: Ok is disabled for the only selected Web Application 4ce1cc8: unused class removed 84f7401: svn: Added final status bar message for Import ("Committed revision xxx") aa1d479: library editor: 'attach javadoc' extracted to separate button so the main '+' button won't show popup 1612198: cleanup e180456: cleanup 546fffe: Merge remote-tracking branch 'origin/master' c3caf6c: Merge remote-tracking branch 'origin/master' 5cd2b37: assertion for EA-45385 - NPE: XmlTagImpl.getDescriptor 99563ea: EA-49418 - NPE: InjectLanguageAction.invokeImpl dc82859: cleanup f70ef96: EA-50139 - assert: TextRange. 990e410: svn: Removed unused code (from "Ignore" functionality) 6604613: svn: Implemented "Ignore" functionality on subversion level d544d03: cleanup after notnullification 5330d9e: plugin suggester: suggest plugins from repository by unknown facet 1ccf92a: error which should never happen replaced by assertion 889d3ce: improved dialog for choosing root types of added roots 0eb34fa: hide "use out of process build" option from UI d79e13e: plugin suggester: suggest plugins from repository by unknown facet 00a127b: Use shell options only if applicable. b4f21b9: Don't fail to create SSH terminal session if we failed to create local terminal session. 8e5cb57: test for "Unnecessary unicode escape sequence" inspection dc8acce: temp revert c7c4431: fix SliceBackwardTest 3e16a04: svn: Implemented "Edit Revision Comment" action for command line c54948a: 'async' added e4f7950: svn: Correctly create externals that have '@' in url - add '@' at url end 9b66e1c: svn: Fix line separators duplication for "Create External" action for SVNKit a98dc14: svn: Implemented "Create External" action for command line 32e30d1: EA-50206 - assert: FileManagerImpl.findFile 4a4c0cc: svn: Unify line separator for multiline properties 4b9422b: Reverted: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435] ad970ef: lambda: propagate wildcards elimination e78ab51: lambda: check formal params for equality, eliminate wildcards during inference according to 15.27.3 fc9a196: new inference: ignore proper types in mutual eq constraints generation 7bc0048: new inference: void compatible according to return values 939fc45: prepare for test new inference eef6eb2: new inference: exact method reference 172daec: new inference: eliminate delayed constrains according to 0.6.3 ec93384: postpone type evaluation e689d68: new inference: make use of ex constraint 7838f8e: Merge branch 'safe-sudo-escaping' 1c22df9: Add grails-app/resources as resources folder, not a source folder. a7f094d: fix NPE e1fe819: Added ExecUtil.sudoAndGetOutput() with safe escaping and quoting for Mac and Linux 6bf3a02: fixed EA-48905 - SIOOBE: ParameterInfoComponent$OneLineComponent.buildLabelText c853c69: system dependent paths in groovy shell db7d97f: Merge remote-tracking branch 'origin/master' 65426f9: mark as DumbAware 0d1a074: Support active links in GotIt panel c7297a0: debugging blinking test 755c6b2: IDEA-113938 "Submit feedback" should pre-fill project and affected version ff45141: dfa: don't go into the same instruction twice with the same state 3361944: a bit more parsimonous DfaMemoryStateImpl.createCopy 028d28b: dfa states should not change while in queue => no need to copy them 1709382: dfa: use UnorderedPair instead of two-element set e8dbc21: immutable DfaVariableState, for faster copying and less memory usage 666ed52: IDEA-70241 (Replace with '{@code}' inspection doesn't replace all occurrences in file.) 71bd9cf: Merge remote-tracking branch 'origin/master' c923098: EA-47881 - IOE: GroovyPsiElementFactoryImpl.createGroovyFileChecked 8b97940: cleanup logging 6e4b81e: EA-50137 - assert: TestObject.addClassesListToJavaParameters 5381d51: cleanup dc2d1b2: notnull f419fab: "todo" moved out of lang-impl 97cd633: attributes cleanup 75b3eaa: notnull c7fa9af: cleanup f5b5bf4: cleanup 776b16b: cleanup bf3cea4: made fields final 87913f7: cleanup 798e94e: cleanup, get rid of buggy duplicate node renderer 50f13e4: removed deprecated methods from ExternalAnnotator 6d9c887: avoid deprecated methods 4852116: minor 9cd549c: now Searchable. fixes test. 302302a: typo 26d8885: - handle strings with more than one quote used for start / end delimiters - proper retrieving syntax highlighter in case of non languge based syntaxhighlighter (quite often it is bound to file type) - Find: String literals only: Throwable at StringSearcher.scan() on XML with a string (IDEA-113885) - fix for backward search not ending when whole word option used 4dfd0c7: Encapsulate field dialog: explicit value for "Use accessors when field is accessible" when "as is" visibility is selected e1aff45: typo :((( 6237b9b: test fixed 6c0d31b: test fixed 493cfae: update test data 711bca1: update test data f1bc615: update test data 8dd18de: update test data e61a901: update test data 0be96e9: update test data aac178b: dfa: remove queued state duplication 6a25f5d: dfa: don't reschedule already processed states, cleanup 7559dfc: Semantic highlighting level to avoid conflicts with "unused symbol" annotations [CR-IC-2435], for WI-19396, WI-20126 (cherry picked from commit 56d66dc) 7c27aef: extract collectUsedJars() function 12f59ff: update test data 03df890: update test data 1efd604: update test data 2c1726e: update test data 24bf1d1: Merge remote-tracking branch 'origin/master' 8f26a8b: improved duplicates search in python extract method 9bfcbbe: setup resource roots when project is imported from Maven (IDEA-57398) 64594cd: diagnostics for EA-49831 0d76c32: add support for frameworks step: sorting restored b510334: IDEA-113294 indentation of brace in a lambda expression corrected [CR-IC-2426] 9651be4: IDEA-113910 Gradle: code insight; dependencies DSL resolving 25595c8: new inference: checked exceptions compatibility constraint 6b8f295: dump highlighting test data without markup 636719b: now that we have dfa state hashing, use it instead of linear lookup 3813120: dfa: don't merge states when there's only one 3fd9ba8: IDEA-113910 Gradle: code insight; dependencies DSL resolving 57a6aeb: IDEA-113910 Gradle: code insight; dependencies resolving da23b6c: Merge remote-tracking branch 'origin/master' 7ca6ea3: Merge remote branch 'origin/master' cdc6d6a: show deprecated make implementation warning once on first compilation after project opening 090c4e3: dfa state merging: cache copies e6ee024: Allows getting Gradle home without having a Project. 0391639: Gradle VM Options are now saved in between sessions. f5412f0: resource root: show 'New Directory' action instead of 'New Package' under resource roots 1637f6b: notnullification 87f394f: IDEA-113904 (Add New Module from Project Structure dialog wants to create new project) a7c75f6: IDEA-113865 ('Equals should check class of parameter' shouldn't warn on identity equals) 2486e9e: dfa: merge several states to account for variables with several possible values 4d4f4b0: dfa: some minor things and caching c14961f: UnorderedPair in platform 5ad442d: Merge remote-tracking branch 'origin/master' 946a281: Scroll to bottom on typing in terminal (PY-10344). e5a0548: Close all connections on dispose. f61f6a2: changes from tech-writers b82b0bb: dfa: state merging interruptibility 3893373: VcsDirtyScopeManagerImpl: log who marks everything dirty 41e5381: Merge remote-tracking branch 'origin/master' da21efb: JediTerm updated. beb1d1a: Merge remote-tracking branch 'origin/master' ed3a2b5: skip the whole document if some component has disabled roaming type (details CR-IU-308) d66309b: Fix antialiasing. e55fae1: dfa: abstract out eq class into EqClass class 370d44d: dfa: remove trivial state facts that constant != another constant 4ccfcf7: UsagesStatistic must specify roaming disabled 75894ae: cleanup 784b4e3: DimensionService: cleanup, order of stored data should be stable 36443b6: overrides b70b1dc: overrides dfe38fb: simplify some constant conditions and greenify 9a08478: IDEA-85961 (Pattern BACKSLASH_PATTERN = Pattern.compile("\\", Pattern.LITERAL) is always marked red.) d0bdc3b: simplify load from providers – we don't need to filter again (our save do it, in any case it is absurd to store component with global roaming in the project level file, — should be refine later) bf85e1b: cleanup 9c30823: remove unused methods f671c09: overrides 3bd62bc: ComponentRoamingManager should not keep defaults (we use RoamingType.PER_USER by default) a8f1063: CR-IU-300 remove outdated EP ComponentRoamingType b182751: CR-IU-300 remove outdated RoamingTypePerPlatform 994389c: another java.util.regex.Pattern.compile() parameter annotation 301710d: IDEA-113866 (this. not suggested for fields of anonymous inner classes) f5d03c4: dfa: don't consider final getters same as immutable fields 272a6d0: Corresponding parents for console colors. 71298ce: Bright console colors for Monokai. f39c34b: Console colors for WarmNeon scheme. 7548e47: Black is invisible on dark background (in RegExps for example). ca6b784: Change bloody red to light pink for numbers (pink is specific to Neon color schemes while red is not, also eyes say thanks). 7f627d9: Console colors for Twilight scheme fixed. a5eb2fc: Console colors for Monokai scheme fixed. f7da145: DfaPsiType: add @NotNull b216102: rebomb test b349547: diagnostics for inconsistencies during control flow building 6823425: dfa: only perform costly state merging when it has chances - after jumps fea8871: dfa: fighting too complex methods; join complementary memory states after fork to avoid having too many states 0ac2084: DfaMemoryStateImpl: introduce unwrap; compare variable values with their non-initialized counterparts e919b8b: dfa: only goto catch on non-trivial method calls and throws e2ea04f: new inference: initial method reference constraint a9dde36: new inference: check substituted descriptor return type 3e5b164: new inference: expression inside condition should be poly, target type for conditional expression ff9f2e9: new inference: emulate fresh variable - do not override vars with captured ones f415702: new inference: default constructor as poly expression argument ee56497: new inference: symmetric variable bounds 4a46b24: new inference: init inter call inference 06829c5: Merge remote-tracking branch 'origin/master' e3f213f: Console colors for Darcula. f748505: IDEA-57940 Cyclic expand word should take into account all open files 460ef47: StreamProvider.isVersioningRequired 8029f47: Bright yellow made more visible on white background. 96006be: Default console colors as in xterm palette, gray and dark gray from standard vga palette for better readability. a378414: Bight console colors added to settings. 54e6582: builder-based project types b0b2cf8: template-based project types? e741484: CPU hogging fix again eb22a99: fix todo duplication when several pattern match -> prefer finding match with last pattern (in settings list), thus default TODO pattern is matched last a4d4371: fix compilation 2f823ba: Difference Groovy Shell & Groovy Console actions 3e876f4: IDEA-113590 annotations as annotation values 732cafd: dead code a712f87: pull up 'isQualified()' method 4edd102: extract base class from PullUpDialog 10d89d6: remove obsolete test a0750e4: delete envFile manually 114cbb2: IDEA-113861 Gradle: it could be possible to hide 'Gradle: download' progress to the background ca416b8: 'More' element for classes, files, action, and settings. Better renderer. b2a550c: test framework: drop temp directory on light project close 8aaf53b: greenify ActionsTreeUtil a bit 922d41a: layout 2cd7326: adding frameworks support 2bd8fb0: cleanup 4ea6442: ProjectSummaryStep 9fdcdcd: commit project name bd39918: new project wizard: first test 630fc14: External system: use URLs in compile output paths 85dbe5f: IDEA-65114 "Add Maven projects" cannot be undone 5041ae5: test framework: returning of the data provider 16e2072: @Nullable XBreakpoint.getProperties reverted +review CR-IC-2418 df4da38: dump shell environment to a temporary file to reduce probability of malformed lines occurrence 280d52a: let event log warning color be orange (IDEA-113802) a30b2ae: IDEA-113836 Console folding: add TestNG related patterns cbeb0f1: don't change mouse cursor during goto name population (IDEA-113800) fb5ad5b: IDEA-113638 ChooseByName restart on write action spawns a new thread 89b3767: disable autopopup in groovy shell if selection by chars is enabled (IDEA-112820) 9fa36be: CompletionConfidence: don't force API users to implement unused method 34cf7eb: Console Folding: proper capitalization 5e8aa44: IDEA-113855 Search Everywhere looks scrambled at first start 71723cb: svn: Refactored executable validation - use separate version client 1114cfe: javadoc 0738800: jps model: simplification, source roots always have default properties b1d5062: jps model: JpsElementType converted to interface to allow reusing common base class 229deb0: test framework: ok, put light project file into ephemeral directory, but keep it for a project's life 6e8b950: ensure "thread" suspend policy for logging breakpoints d67c04e: EA-49809 Move client factories creation to SvnVcs constructor (instead of active() method) 935cdba: new inference: initial tests 970a180: encapsulate read access to USE_COMPILE_SERVER option b9b3fc8: remote agents - extract to remote servers cfe8e2b: WEB-9335 Bad insert pair brace in CSS 2815c22: WEB-9334 Incremental selection works bad with negative CSS values d023471: new "Unnecessary unicode escape sequence" inspection 945b069: unicode escape needs at least one 'u' 8e7797b: chrome still crashed, revert to old, not-recursive speed search 1917d86: Merge remote-tracking branch 'origin/master' c18e6bd: Lense mode "internal" preview db88427: Merge branch 'svn1_8_new' 7c64e8b: test framework: do not put light project file into ephemeral directory af09e11: remove @Nullable from key.get as it's too generic d49df32: svn: Refactored prompting for working copy format - make return not null format d6086ae: dfa: types with wildcard parameters are not equal 3d28aa5: Optimization: check exiting of griffon-app first b016c04: correct ephemeral state copy (IDEA-113143 Calling method with contract shouldn't result in nullability suspicion) 189573f: svn: Refactored upgrade working copy format dialog - use list of available formats (instead of separate fields for each format) 60c471b: Rename test 1a42f59: Remove using of unnecessary StringBuilder a56db90: Use MultiMap 340cf22: Calling method with contract shouldn't result in nullability suspicion (IDEA-113763, IDEA-113699, almost IDEA-113143) f2a563b: dfa: unify nullability violation processing 709af86: dfa: expand contract test 1cddfb4: dfa cleanup: skipping reports on method calls is now done via unknown variable mechanism 2765dab: dfa: spare some minor cpu cycles 8bc7465: svn: Added "1.8" option to upgrade/checkout dialogs c266bd2: IDEA-66603 Maven3: provide inspection that checks duplicate declarations of plugins af32923: SpellChecker: "cyclomatic" 5f4f98f: svn: Refactored working copy format selection dialog to use WorkingCopyFormat instances instead of just strings e33b58b: MismatchedCollectionQueryUpdateInspection -- added "compute" prefix (from j.u.Map in JDK8) 7d54b2e: new inference: accept nonProper eq bounds 457d95b: new inference: distinguish different captures 5b5f52e: new inference: assertions caused by raw types 3848de4: new inference: open top level captured wildcards 35d59c0: new inference: extend usage of already inferred variables 4f7b572: new inference: inference of calls in arguments during outer call inference bfa7879: new inference: captured variables from outer calls to be included ed95269: new inference: eq bound for S<=T constraint reduction 12a0faf: better positioning 13029b7: different position layout algorithms 39e6e21: EA-49923 - Fixed working copy format detection for default project d521e9d: JDK combobox should show JDK home 17fe05e: Fix typo 7ab769b: IDEA-16077 Maven embedder runs in the 'wrong' JDK add "embedder JDK" option 418ddc0: Inline string constant 6a8f1e2: IDEA-16077 Maven embedder runs in the 'wrong' JDK extract MavenJdkCombobox 46078c4: svn: Refactored detection if command line implementation should be used (use utility method) 24106fc: XDebugger: @Nullable XBreakpoint.getProperties() 3dc6f07: extract util method 476dac4: Reinit checkbox state on create 39cf1fd: Structure viewer for simple editors support fixed a38a251: Show filters only for table editor + a few model and UI fixes cbd5630: Initial dynamic filters model + columns header improved 281c008: svn: Support nullable SVNStatusClient in status implementation for SVNKit 1840d42: simplification fbcba0f: svn: Make command line clients (info, status) use vcs instead of project instances ae8b41b: Merge remote-tracking branch 'origin/master' a97397c: Extract method. 3b9eca4: new project wizard: preparing test infrastructure 327ddb0: Lense mode "internal" preview 0ede5e1: new project wizard: AbstractProjectWizard extracted a94b556: IDEA-111335 Gradle: task tree is incorrectly displayed if tasks are added to sub-projects via 'subprojects' method bfd366f: Merge remote-tracking branch 'origin/master' 0ef2a82: calls to obsolete method removed from build scripts 2df016f: AntLoggerFactory inner class made static to fix NoSuchMethodException in Logger.setFactory fe876e2: svn: Clients for update command renamed and moved to corresponding package a38d90e: Terminal color settings. bd285b8: svn: Refactored update logic to common ClientFactory model 9cc13da: platform: ignore hidden Windows files d87664c: test framework: relic property dropped 5f6ef06: svn: Removed unused "common ancestor" behavior from command line update client 3667fe1: Find in strings with reg exp with start / end match markers doesn't work without string delimiters (IDEA-113788) 94a079f: svn: Refactored "update" command - explicitly create new SVNKit update client for each update/switch operation 0344e91: new project wizard: added option to use framework libraries from an app server 2882ac0: svn: Removed unused methods from "update" client 17ea275: svn: Removed unused SvnProxies class c926181: WEB-9342 External Tool fails on OSX if an executable file basename specified a3433f9: svn: Removed unused methods from "info" client ec3112d: Optimize SassExtensionFunctionsIndex 9f1abf7: nosplash shouldn't prevent from plugin update 4c7154d: dfa: use cached nullability b81e9c3: dfa: less frequent "too long" check 0b0eba9: DfaValueFactory: use List instead of TIntObjectHashMap for sequential keys 95d5433: introduce DfaPsiType without nullability, to quickly check assignability/convertibility in DfaVariableState b901d90: IDEA-96713 Incorrect options shown for 'implements' e02e2c4: IDEA-113780 "Annotate" from history fixed for renamed/moved files fe00f73: test framework: stability improvements 76d664d: platform: suspicious event logging b204bdf: Cleanup (de-duplication) 7ba9ff0: spelling ece939c: make public for Upsource 496db4d: xdebugger: rebuild standalone variables view on EDT eae27cb: xdebugger: supported rebuilding of standalone variables view 8bf5204: xdebugger api: added convenient method 43dbb6f: Terminal options. 3db1f5c: Blink period and antialiasing settings. 88264bd: IDEA-108147 Use "merge sources" wrapper object instead of just string representation as data model for "Merge Sources" column (to correctly get file revision object and show details panel) 111e6ba: IDEA-108147 While building history for element make check "if element parent or child was changed in given revision" only be performed for non-"merge source" revisions e07828d: svn: Implemented support for "merged revisions" parsing in history logic for command line 1586c4a: svn: history logic refactored for command line - get and parse history data in xml format 0ac1dd2: IDEA-94942 Refactored "Annotate" implementation for command line - use utility method for parsing ba1e5e0: IDEA-94942 Implemented merge history support for "Annotate" action 4c3b0a8: IDEA-94942 Implemented "Switch" logic (during update) Change-Id: I7092ae66ff47d353a5b9770d1d91f77369bb7734 --- .../org/jetbrains/idea/svn/SvnBundle.properties | 3 + .../org/jetbrains/idea/svn/SvnConfigurable.java | 6 +- .../org/jetbrains/idea/svn/SvnConfiguration.java | 9 +- .../org/jetbrains/idea/svn/SvnFormatSelector.java | 19 +- .../org/jetbrains/idea/svn/SvnPropertyKeys.java | 1 + .../src/org/jetbrains/idea/svn/SvnProxies.java | 113 -------- .../idea/svn/SvnRecursiveStatusWalker.java | 6 +- .../src/org/jetbrains/idea/svn/SvnUtil.java | 6 +- .../src/org/jetbrains/idea/svn/SvnVcs.java | 27 +- .../org/jetbrains/idea/svn/WorkingCopyFormat.java | 26 -- .../idea/svn/actions/CreateExternalAction.java | 25 +- .../idea/svn/annotate/CmdAnnotateClient.java | 63 ++++- .../org/jetbrains/idea/svn/api/ClientFactory.java | 24 +- .../jetbrains/idea/svn/api/CmdClientFactory.java | 17 +- .../jetbrains/idea/svn/api/CmdVersionClient.java | 80 ++++++ .../idea/svn/api/SvnKitClientFactory.java | 15 +- .../idea/svn/api/SvnKitVersionClient.java | 18 ++ .../org/jetbrains/idea/svn/api/VersionClient.java | 14 + .../idea/svn/checkin/CmdImportClient.java | 51 ++++ .../idea/svn/checkin/IdeaCommitHandler.java | 2 + .../jetbrains/idea/svn/checkin/ImportClient.java | 26 ++ .../idea/svn/checkin/SvnCheckinEnvironment.java | 6 +- .../idea/svn/checkin/SvnKitImportClient.java | 44 +++ .../idea/svn/checkout/CheckoutEventHandler.java | 40 ++- .../idea/svn/checkout/CmdExportClient.java | 53 ++++ .../jetbrains/idea/svn/checkout/ExportClient.java | 27 ++ .../idea/svn/checkout/SvnCheckoutProvider.java | 79 +++--- .../idea/svn/checkout/SvnKitExportClient.java | 48 ++++ .../idea/svn/commandLine/CommandUtil.java | 38 ++- .../idea/svn/commandLine/CommitEventType.java | 3 +- .../svn/commandLine/SvnCommandLineInfoClient.java | 14 +- .../commandLine/SvnCommandLineStatusClient.java | 13 +- .../commandLine/SvnCommandLineUpdateClient.java | 233 ---------------- .../idea/svn/commandLine/SvnCommandName.java | 5 +- .../idea/svn/commandLine/SvnCommitRunner.java | 66 ++++- .../idea/svn/commandLine/SvnExecutableChecker.java | 37 +-- .../svn/commandLine/UpdateOutputLineConverter.java | 16 +- .../jetbrains/idea/svn/dialogs/CopiesPanel.java | 7 +- .../idea/svn/dialogs/RepositoryBrowserDialog.java | 2 +- .../idea/svn/dialogs/UpgradeFormatDialog.java | 78 ++++-- .../idea/svn/history/CmdHistoryClient.java | 206 ++++++-------- .../svn/history/SvnEditCommitMessageAction.java | 12 +- .../idea/svn/history/SvnHistoryProvider.java | 105 ++++--- .../idea/svn/ignore/SvnPropertyService.java | 68 +---- .../idea/svn/portable/SvnSvnkitUpdateClient.java | 211 -------------- .../idea/svn/portable/SvnUpdateClientI.java | 76 ------ .../jetbrains/idea/svn/portable/SvnWcClientI.java | 69 +---- .../idea/svn/portable/SvnkitSvnStatusClient.java | 28 +- .../idea/svn/portable/SvnkitSvnWcClient.java | 304 --------------------- .../idea/svn/properties/CmdPropertyClient.java | 34 ++- .../idea/svn/properties/PropertyClient.java | 17 ++ .../idea/svn/properties/SvnKitPropertyClient.java | 37 ++- .../treeConflict/ApplyPatchSaveToFileExecutor.java | 9 +- .../jetbrains/idea/svn/update/CmdUpdateClient.java | 187 +++++++++++++ .../idea/svn/update/SvnKitUpdateClient.java | 93 +++++++ .../idea/svn/update/SvnUpdateEnvironment.java | 9 +- .../jetbrains/idea/svn/update/UpdateClient.java | 45 +++ 57 files changed, 1388 insertions(+), 1482 deletions(-) delete mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java delete mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java delete mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java delete mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java (limited to 'plugins/svn4idea/src/org/jetbrains/idea') diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties index b642114d1cc8..bbb8e54c6704 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties @@ -206,6 +206,7 @@ radio.configure.upgrade.auto=Upgrade &automatically (use Subversion 1.4) radio.configure.upgrade.auto.15format=Upgrade automatically (use Subversion 1.&5) radio.configure.upgrade.auto.16format=Upgrade automatically (use Subversion 1.&6) radio.configure.upgrade.auto.17format=Upgrade automatically (use Subversion 1.&7) +radio.configure.upgrade.auto.18format=Upgrade automatically (use Subversion 1.&8) label.configure.create.label={0} is about to create new Subversion working copy,\n\ please, select desired working copy format: @@ -215,10 +216,12 @@ radio.configure.create.auto=1.&4 format radio.configure.create.auto.15format=1.&5 format radio.configure.create.auto.16format=1.&6 format radio.configure.create.auto.17format=1.&7 format +radio.configure.create.auto.18format=1.&8 format label.configure.change.label=Change working copy ''{0}'' format to: radio.configure.change.auto.16format=1.&6 format radio.configure.change.auto.17format=1.&7 format +radio.configure.change.auto.18format=1.&8 format dialog.upgrade.wcopy.format.title=Subversion Working Copy Format diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java index ecd387b3cc89..ac239636ec61 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java @@ -282,10 +282,6 @@ public class SvnConfigurable implements Configurable { return SvnConfiguration.UseAcceleration.nothing; } - private void setAcceleration(SvnConfiguration.UseAcceleration acceleration) { - myWithCommandLineClient.setSelected(SvnConfiguration.UseAcceleration.commandLine.equals(acceleration)); - } - public void apply() throws ConfigurationException { SvnConfiguration configuration = SvnConfiguration.getInstance(myProject); configuration.setConfigurationDirParameters(myUseDefaultCheckBox.isSelected(), myConfigurationDirectoryText.getText()); @@ -351,7 +347,7 @@ public class SvnConfigurable implements Configurable { mySSHConnectionTimeout.setValue(Long.valueOf(configuration.mySSHConnectionTimeout / 1000)); mySSHReadTimeout.setValue(Long.valueOf(configuration.mySSHReadTimeout / 1000)); myHttpTimeout.setValue(Long.valueOf(configuration.getHttpTimeout() / 1000)); - setAcceleration(configuration.myUseAcceleration); + myWithCommandLineClient.setSelected(configuration.isCommandLine()); final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); myCommandLineClient.setText(applicationSettings17.getCommandLinePath()); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java index b4f799153824..1b2a8df0142f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java @@ -75,11 +75,6 @@ public class SvnConfiguration implements PersistentStateComponent { private final static String SERVERS_FILE_NAME = "servers"; - public static final String UPGRADE_AUTO = "auto"; - public static final String UPGRADE_AUTO_15 = "auto1.5"; - public static final String UPGRADE_AUTO_16 = "auto1.6"; - public static final String UPGRADE_AUTO_17 = "auto1.7"; - public static final String UPGRADE_NONE = "none"; public static final String CLEANUP_ON_START_RUN = "cleanupOnStartRun"; private final Project myProject; @@ -130,6 +125,10 @@ public class SvnConfiguration implements PersistentStateComponent { private SvnInteractiveAuthenticationProvider myInteractiveProvider; private IdeaSVNConfigFile myConfigFile; + public boolean isCommandLine() { + return UseAcceleration.commandLine.equals(myUseAcceleration); + } + @Override public Element getState() { Element element = new Element("state"); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java index 77783badc2f8..2595631bac4b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java @@ -136,17 +136,20 @@ public class SvnFormatSelector implements ISVNAdminAreaFactorySelector { return result; } - public static String showUpgradeDialog(final File path, final Project project, final boolean display13format, final String mode, - @NotNull final Ref wasOk) { + public static WorkingCopyFormat showUpgradeDialog(final File path, + final Project project, + final boolean display13format, + @NotNull final WorkingCopyFormat defaultSelection, + @NotNull final Ref wasOk) { assert ! ApplicationManager.getApplication().isUnitTestMode(); - final String[] newMode = new String[] {mode}; + final Ref format = new Ref(defaultSelection); WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(new Runnable() { public void run() { - wasOk.set(displayUpgradeDialog(project, path, display13format, newMode)); + wasOk.set(displayUpgradeDialog(project, path, display13format, format)); } }); ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run(); - return newMode[0]; + return format.get(); } public static WorkingCopyFormat findRootAndGetFormat(final File path) { @@ -187,12 +190,12 @@ public class SvnFormatSelector implements ISVNAdminAreaFactorySelector { return WorkingCopyFormat.getInstance(format); } - private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, String[] newMode) { + private static boolean displayUpgradeDialog(Project project, File path, final boolean dispay13format, Ref format) { UpgradeFormatDialog dialog = new UpgradeFormatDialog(project, path, false); - dialog.setData(newMode[0]); + dialog.setData(format.get()); dialog.show(); if (dialog.isOK()) { - newMode[0] = dialog.getUpgradeMode(); + format.set(dialog.getUpgradeMode()); } return dialog.isOK(); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java index 2de723244054..1b0792a51c22 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnPropertyKeys.java @@ -24,4 +24,5 @@ public interface SvnPropertyKeys { String SVN_EXECUTABLE = "svn:executable"; String SVN_IGNORE = "svn:ignore"; String SVN_EXTERNALS = "svn:externals"; + String LOG = "svn:log"; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java deleted file mode 100644 index fcac3966c2d6..000000000000 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.svn; - -import com.intellij.vcsUtil.LearningProxy; -import org.jetbrains.idea.svn.portable.SVNChangelistClientI; -import org.jetbrains.idea.svn.portable.SvnUpdateClientI; -import org.tmatesoft.svn.core.SVNException; - -import java.io.File; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/19/12 - * Time: 4:22 PM - */ -// TODO: Likely to be removed (together with SvnAbstractWriteOperationLocks). -public class SvnProxies { - private final SvnAbstractWriteOperationLocks myLocks; - private final AtomicReference> myChangelist; - private final AtomicReference> myUpdate; - - public SvnProxies(SvnAbstractWriteOperationLocks locks) { - myLocks = locks; - myChangelist = new AtomicReference>(); - myUpdate = new AtomicReference>(); - } - - public LearningProxy getChangelistsProfessor(final File file) { - if (myChangelist.get() == null) { - final MyLearningProxy proxy = new MyLearningProxy(myLocks, file); - final SVNChangelistClientI learn = proxy.learn(SVNChangelistClientI.class); - try { - learn.addToChangelist(null, null, null, null); - learn.doAddToChangelist(null, null, null, null); - learn.doRemoveFromChangelist(null, null, null); - learn.removeFromChangelist(null, null, null); - } catch (SVNException e) { - //can not occur since methods are not really called - throw new RuntimeException(e); - } - - myChangelist.set(proxy); - } - return myChangelist.get(); - } - - public LearningProxy getUpdateProfessor(final File file) { - if (myUpdate.get() == null) { - final MyLearningProxy proxy = new MyLearningProxy(myLocks, file); - final SvnUpdateClientI learn = proxy.learn(SvnUpdateClientI.class); - try { - learn.doUpdate(null, null, false); - learn.doUpdate(null, null, false, false); - learn.doUpdate((File[]) null, null, null, false, false); - learn.doUpdate((File[]) null, null, null, false, false, false); - learn.doUpdate((File) null, null, null, false, false); - - learn.doSwitch(null, null, null, false); - learn.doSwitch(null, null, null, null, false); - learn.doSwitch(null, null, null, null, false, false); - learn.doSwitch(null, null, null, null, null, false, false); - learn.doSwitch(null, null, null, null, null, false, false, false); - - learn.doCheckout(null, null, null, null, false); - // todo continue - //learn.doCheckout(); - //learn.doCheckout(); - } - catch (SVNException e) { - //can not occur since methods are not really called - throw new RuntimeException(e); - } - myUpdate.set(proxy); - } - return myUpdate.get(); - } - - private static class MyLearningProxy extends LearningProxy { - private final SvnAbstractWriteOperationLocks myLocks; - private final File myFile; - - private MyLearningProxy(SvnAbstractWriteOperationLocks locks, final File file) { - myLocks = locks; - myFile = file; - } - - @Override - protected void onBefore() throws SVNException { - myLocks.lockWrite(myFile); - } - - @Override - protected void onAfter() throws SVNException { - myLocks.unlockWrite(myFile); - } - } -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java index b246ea70e8a6..690ec0e1fb13 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java @@ -129,8 +129,8 @@ public class SvnRecursiveStatusWalker { myConfiguration17 = SvnConfiguration.getInstance(myProject); myPath = path; myDepth = depth; - mySvnClient = new SvnkitSvnStatusClient(client); - myCommandLineClient = new SvnCommandLineStatusClient(myProject); + mySvnClient = new SvnkitSvnStatusClient(myVcs, client); + myCommandLineClient = new SvnCommandLineStatusClient(myVcs); myIsInnerCopyRoot = isInnerCopyRoot; } @@ -159,7 +159,7 @@ public class SvnRecursiveStatusWalker { if (CheckJavaHL.isPresent() && SvnConfiguration.UseAcceleration.javaHL.equals(myConfiguration17.myUseAcceleration) && Svn17Detector.is17(myProject, file)) { return new JavaHLSvnStatusClient(myProject); - } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration)) { + } else if (myConfiguration17.isCommandLine()) { // apply command line disregarding working copy format return myCommandLineClient; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index 7594c2a56058..07301c0829f1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -91,7 +91,11 @@ public class SvnUtil { } public static boolean isSvnVersioned(final Project project, File parent) { - final SVNInfo info = SvnVcs.getInstance(project).getInfo(parent); + return isSvnVersioned(SvnVcs.getInstance(project), parent); + } + + public static boolean isSvnVersioned(final @NotNull SvnVcs vcs, File parent) { + final SVNInfo info = vcs.getInfo(parent); return info != null; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index 02b28a965b40..55b79b063614 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -83,6 +83,7 @@ import org.jetbrains.idea.svn.history.SvnHistoryProvider; import org.jetbrains.idea.svn.lowLevel.PrimitivePool; import org.jetbrains.idea.svn.networking.SSLProtocolExceptionParser; import org.jetbrains.idea.svn.portable.SvnWcClientI; +import org.jetbrains.idea.svn.properties.PropertyClient; import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment; import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment; import org.jetbrains.idea.svn.update.SvnUpdateEnvironment; @@ -202,8 +203,8 @@ public class SvnVcs extends AbstractVcs { }; private SvnCheckoutProvider myCheckoutProvider; - private ClientFactory cmdClientFactory; - private ClientFactory svnKitClientFactory; + private final ClientFactory cmdClientFactory; + private final ClientFactory svnKitClientFactory; private final boolean myLogExceptions; @@ -244,6 +245,9 @@ public class SvnVcs extends AbstractVcs { public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) { super(project, VCS_NAME); + cmdClientFactory = new CmdClientFactory(this); + svnKitClientFactory = new SvnKitClientFactory(this); + myLoadedBranchesStorage = storage; myRootsToWorkingCopies = new RootsToWorkingCopies(this); myConfiguration = svnConfiguration; @@ -362,7 +366,7 @@ public class SvnVcs extends AbstractVcs { public boolean checkCommandLineVersion() { boolean isValid = true; - if (!isProject16() && (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration) || isProject18())) { + if (!isProject16() && (myConfiguration.isCommandLine() || isProject18())) { isValid = myChecker.checkExecutableAndNotifyIfNeeded(); } @@ -501,9 +505,6 @@ public class SvnVcs extends AbstractVcs { checkCommandLineVersion(); } - cmdClientFactory = new CmdClientFactory(this); - svnKitClientFactory = new SvnKitClientFactory(this); - // do one time after project loaded StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() { @Override @@ -861,7 +862,7 @@ public class SvnVcs extends AbstractVcs { } @Nullable - public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws SVNException { + public SVNPropertyValue getPropertyWithCaching(final VirtualFile file, final String propName) throws VcsException { Map>> cachedMap = myPropertyCache.get(keyForVf(file)); final Pair> cachedValue = cachedMap == null ? null : cachedMap.get(propName); @@ -875,7 +876,8 @@ public class SvnVcs extends AbstractVcs { } } - final SVNPropertyData value = createWCClient().doGetProperty(ioFile, propName, SVNRevision.WORKING, SVNRevision.WORKING); + PropertyClient client = getFactory(ioFile).createPropertyClient(); + final SVNPropertyData value = client.getProperty(SvnTarget.fromFile(ioFile, SVNRevision.WORKING), propName, false, SVNRevision.WORKING); final SVNPropertyValue propValue = value == null ? null : value.getValue(); if (cachedMap == null) { @@ -1349,7 +1351,7 @@ public class SvnVcs extends AbstractVcs { } private WorkingCopyFormat getProjectRootFormat() { - return getWorkingCopyFormat(new File(getProject().getBaseDir().getPath())); + return !getProject().isDefault() ? getWorkingCopyFormat(new File(getProject().getBaseDir().getPath())) : WorkingCopyFormat.UNKNOWN; } /** @@ -1395,6 +1397,11 @@ public class SvnVcs extends AbstractVcs { @NotNull public ClientFactory getFactoryFromSettings() { - return myConfiguration.myUseAcceleration.equals(SvnConfiguration.UseAcceleration.commandLine) ? cmdClientFactory : svnKitClientFactory; + return myConfiguration.isCommandLine() ? cmdClientFactory : svnKitClientFactory; + } + + @NotNull + public ClientFactory getCommandLineFactory() { + return cmdClientFactory; } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java index 909d904ab0cf..041ee2811a63 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java @@ -97,33 +97,7 @@ public enum WorkingCopyFormat { return UNKNOWN; } - public static WorkingCopyFormat getInstance(final String updateOption) { - if (SvnConfiguration.UPGRADE_AUTO_17.equals(updateOption)) { - return ONE_DOT_SEVEN; - } else if (SvnConfiguration.UPGRADE_AUTO_16.equals(updateOption)) { - return ONE_DOT_SIX; - } else if (SvnConfiguration.UPGRADE_AUTO_15.equals(updateOption)) { - return ONE_DOT_FIVE; - } else if (SvnConfiguration.UPGRADE_AUTO.equals(updateOption)) { - return ONE_DOT_FOUR; - } - return ONE_DOT_THREE; - } - public int getFormat() { return myFormat; } - - public String getOption() { - if (ONE_DOT_SEVEN.equals(this)) { - return SvnConfiguration.UPGRADE_AUTO_17; - } else if (ONE_DOT_SIX.equals(this)) { - return SvnConfiguration.UPGRADE_AUTO_16; - } else if (ONE_DOT_FIVE.equals(this)) { - return SvnConfiguration.UPGRADE_AUTO_15; - } else if (ONE_DOT_FOUR.equals(this)) { - return SvnConfiguration.UPGRADE_AUTO; - } - return SvnConfiguration.UPGRADE_NONE; - } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java index 1af0550a9d0e..337a045caed1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/CreateExternalAction.java @@ -36,13 +36,17 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnPropertyKeys; import org.jetbrains.idea.svn.SvnVcs; +import org.jetbrains.idea.svn.api.ClientFactory; +import org.jetbrains.idea.svn.commandLine.CommandUtil; import org.jetbrains.idea.svn.dialogs.SelectCreateExternalTargetDialog; +import org.jetbrains.idea.svn.update.UpdateClient; import org.tmatesoft.svn.core.SVNCancelException; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNPropertyValue; import org.tmatesoft.svn.core.internal.wc.SVNExternal; import org.tmatesoft.svn.core.wc.*; +import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; @@ -94,7 +98,7 @@ public class CreateExternalAction extends DumbAwareAction { dirtyScopeManager.fileDirty(filePath); if (checkout) { // +- - final SVNUpdateClient client = vcs.createUpdateClient(); + final UpdateClient client = vcs.getFactory(ioFile).createUpdateClient(); client.setEventHandler(new ISVNEventHandler() { @Override public void handleEvent(SVNEvent event, double progress) throws SVNException { @@ -118,12 +122,16 @@ public class CreateExternalAction extends DumbAwareAction { catch (SVNException e1) { AbstractVcsHelper.getInstance(project).showError(new VcsException(e1), "Create External"); } + catch (VcsException e1) { + AbstractVcsHelper.getInstance(project).showError(e1, "Create External"); + } } - public static boolean addToExternalProperty(SvnVcs vcs, File ioFile, String target, String url) throws SVNException { - final SVNWCClient wcClient = vcs.createWCClient(); - final SVNPropertyData propertyData = - wcClient.doGetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED); + public static boolean addToExternalProperty(@NotNull SvnVcs vcs, @NotNull File ioFile, String target, String url) + throws SVNException, VcsException { + ClientFactory factory = vcs.getFactory(ioFile); + SVNPropertyData propertyData = factory.createPropertyClient().getProperty(SvnTarget.fromFile(ioFile), SvnPropertyKeys.SVN_EXTERNALS, + false, SVNRevision.UNDEFINED); String newValue; if (propertyData != null && propertyData.getValue() != null && ! StringUtil.isEmptyOrSpaces(propertyData.getValue().getString())) { final SVNExternal[] externals = SVNExternal.parseExternals("Create External", propertyData.getValue().getString()); @@ -135,16 +143,17 @@ public class CreateExternalAction extends DumbAwareAction { } } final String string = createExternalDefinitionString(url, target); - newValue = propertyData.getValue().getString() + "\n" + string; + newValue = propertyData.getValue().getString().trim() + "\n" + string; } else { newValue = createExternalDefinitionString(url, target); } - wcClient.doSetProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), false, SVNDepth.EMPTY, null, null); + factory.createPropertyClient().setProperty(ioFile, SvnPropertyKeys.SVN_EXTERNALS, SVNPropertyValue.create(newValue), SVNDepth.EMPTY, + false); return false; } public static String createExternalDefinitionString(String url, String target) { - return url + " " + target; + return CommandUtil.escape(url) + " " + target; } @Override diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java index c2fe2c3dd753..f7674b6e2fc4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java @@ -37,9 +37,6 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { boolean includeMergedRevisions, @Nullable SVNDiffOptions diffOptions, @Nullable final ISVNAnnotateHandler handler) throws VcsException { - // TODO: after merge remove setting includeMergedRevisions to false and update parsing - includeMergedRevisions = false; - List parameters = new ArrayList(); CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision); parameters.add("--revision"); @@ -55,9 +52,7 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { public void parseOutput(@NotNull String output, @Nullable ISVNAnnotateHandler handler) throws VcsException { try { - JAXBContext context = JAXBContext.newInstance(BlameInfo.class); - Unmarshaller unmarshaller = context.createUnmarshaller(); - BlameInfo info = (BlameInfo)unmarshaller.unmarshal(new StringReader(output)); + BlameInfo info = CommandUtil.parse(output, BlameInfo.class); if (handler != null && info != null && info.target != null && info.target.lineEntries != null) { for (LineEntry entry : info.target.lineEntries) { @@ -75,7 +70,10 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { private static void invokeHandler(ISVNAnnotateHandler handler, LineEntry entry) throws SVNException { // line numbers in our api start from 0 - not from 1 like in svn output - handler.handleLine(entry.date(), entry.revision(), entry.author(), null, null, 0, null, null, entry.lineNumber - 1); + // "line" value is not used in handlers - so null is passed + handler + .handleLine(entry.date(), entry.revision(), entry.author(), null, entry.mergedDate(), entry.mergedRevision(), entry.mergedAuthor(), + entry.mergedPath(), entry.lineNumber - 1); } @XmlRootElement(name = "blame") @@ -99,15 +97,53 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { @XmlElement(name = "commit") public CommitEntry commit; + @XmlElement(name = "merged") + public MergedEntry merged; + public long revision() { - return commit != null ? commit.revision : 0; + return revision(commit); } + @Nullable public String author() { - return commit != null ? commit.author : null; + return author(commit); } + @Nullable public Date date() { + return date(commit); + } + + @Nullable + public String mergedPath() { + return merged != null ? merged.path : null; + } + + public long mergedRevision() { + return merged != null ? revision(merged.commit) : 0; + } + + @Nullable + public String mergedAuthor() { + return merged != null ? author(merged.commit) : null; + } + + @Nullable + public Date mergedDate() { + return merged != null ? date(merged.commit) : null; + } + + private static long revision(@Nullable CommitEntry commit) { + return commit != null ? commit.revision : 0; + } + + @Nullable + private static String author(@Nullable CommitEntry commit) { + return commit != null ? commit.author : null; + } + + @Nullable + private static Date date(@Nullable CommitEntry commit) { return commit != null ? commit.date : null; } } @@ -123,4 +159,13 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { @XmlElement(name = "date") public Date date; } + + public static class MergedEntry { + + @XmlAttribute(name = "path") + public String path; + + @XmlElement(name = "commit") + public CommitEntry commit; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java index 739e2add101a..27c0d1e30885 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java @@ -5,7 +5,9 @@ import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.add.AddClient; import org.jetbrains.idea.svn.annotate.AnnotateClient; import org.jetbrains.idea.svn.change.ChangeListClient; +import org.jetbrains.idea.svn.checkin.ImportClient; import org.jetbrains.idea.svn.checkout.CheckoutClient; +import org.jetbrains.idea.svn.checkout.ExportClient; import org.jetbrains.idea.svn.cleanup.CleanupClient; import org.jetbrains.idea.svn.conflict.ConflictClient; import org.jetbrains.idea.svn.content.ContentClient; @@ -15,7 +17,7 @@ import org.jetbrains.idea.svn.history.HistoryClient; import org.jetbrains.idea.svn.integrate.MergeClient; import org.jetbrains.idea.svn.lock.LockClient; import org.jetbrains.idea.svn.portable.SvnStatusClientI; -import org.jetbrains.idea.svn.portable.SvnUpdateClientI; +import org.jetbrains.idea.svn.update.UpdateClient; import org.jetbrains.idea.svn.portable.SvnWcClientI; import org.jetbrains.idea.svn.properties.PropertyClient; import org.jetbrains.idea.svn.revert.RevertClient; @@ -46,6 +48,9 @@ public abstract class ClientFactory { protected LockClient myLockClient; protected CleanupClient myCleanupClient; protected RelocateClient myRelocateClient; + protected VersionClient myVersionClient; + protected ImportClient myImportClient; + protected ExportClient myExportClient; protected ClientFactory(@NotNull SvnVcs vcs) { myVcs = vcs; @@ -94,7 +99,7 @@ public abstract class ClientFactory { // TODO: Update this in same like other clients - move to corresponding package, rename clients // New instances should be always created by this method, as setXxx() methods are currently used in update logic @NotNull - public abstract SvnUpdateClientI createUpdateClient(); + public abstract UpdateClient createUpdateClient(); @NotNull public DeleteClient createDeleteClient() { @@ -146,6 +151,21 @@ public abstract class ClientFactory { return prepare(myRelocateClient); } + @NotNull + public VersionClient createVersionClient() { + return prepare(myVersionClient); + } + + @NotNull + public ImportClient createImportClient() { + return prepare(myImportClient); + } + + @NotNull + public ExportClient createExportClient() { + return prepare(myExportClient); + } + @NotNull protected T prepare(@NotNull T client) { client.setVcs(myVcs); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java index e0849d951576..8b73377b6f9f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java @@ -5,11 +5,13 @@ import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.add.CmdAddClient; import org.jetbrains.idea.svn.annotate.CmdAnnotateClient; import org.jetbrains.idea.svn.change.CmdChangeListClient; +import org.jetbrains.idea.svn.checkin.CmdImportClient; import org.jetbrains.idea.svn.checkout.CmdCheckoutClient; +import org.jetbrains.idea.svn.checkout.CmdExportClient; import org.jetbrains.idea.svn.cleanup.CmdCleanupClient; +import org.jetbrains.idea.svn.update.CmdUpdateClient; import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient; import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient; -import org.jetbrains.idea.svn.commandLine.SvnCommandLineUpdateClient; import org.jetbrains.idea.svn.conflict.CmdConflictClient; import org.jetbrains.idea.svn.content.CmdContentClient; import org.jetbrains.idea.svn.copy.CmdCopyMoveClient; @@ -17,7 +19,7 @@ import org.jetbrains.idea.svn.delete.CmdDeleteClient; import org.jetbrains.idea.svn.history.CmdHistoryClient; import org.jetbrains.idea.svn.integrate.CmdMergeClient; import org.jetbrains.idea.svn.lock.CmdLockClient; -import org.jetbrains.idea.svn.portable.SvnUpdateClientI; +import org.jetbrains.idea.svn.update.UpdateClient; import org.jetbrains.idea.svn.properties.CmdPropertyClient; import org.jetbrains.idea.svn.revert.CmdRevertClient; import org.jetbrains.idea.svn.update.CmdRelocateClient; @@ -48,13 +50,16 @@ public class CmdClientFactory extends ClientFactory { myLockClient = new CmdLockClient(); myCleanupClient = new CmdCleanupClient(); myRelocateClient = new CmdRelocateClient(); - statusClient = new SvnCommandLineStatusClient(myVcs.getProject()); - infoClient = new SvnCommandLineInfoClient(myVcs.getProject()); + myVersionClient = new CmdVersionClient(); + myImportClient = new CmdImportClient(); + myExportClient = new CmdExportClient(); + statusClient = new SvnCommandLineStatusClient(myVcs); + infoClient = new SvnCommandLineInfoClient(myVcs); } @NotNull @Override - public SvnUpdateClientI createUpdateClient() { - return new SvnCommandLineUpdateClient(myVcs, null); + public UpdateClient createUpdateClient() { + return prepare(new CmdUpdateClient()); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java new file mode 100644 index 000000000000..bc40a9f11421 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java @@ -0,0 +1,80 @@ +package org.jetbrains.idea.svn.api; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.CapturingProcessHandler; +import com.intellij.execution.process.ProcessOutput; +import com.intellij.openapi.util.Version; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.CharsetToolkit; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.svn.SvnApplicationSettings; +import org.jetbrains.idea.svn.commandLine.SvnCommandName; + +/** + * @author Konstantin Kolosovsky. + */ +public class CmdVersionClient extends BaseSvnClient implements VersionClient { + + @NotNull + @Override + public Version getVersion() throws VcsException { + // TODO: Do not use common command running mechanism for now - to preserve timeout behavior. + ProcessOutput output; + + try { + output = runCommand(); + } + catch (ExecutionException e) { + throw new VcsException(e); + } + + return parseVersion(output); + } + + private static ProcessOutput runCommand() throws ExecutionException { + GeneralCommandLine commandLine = new GeneralCommandLine(); + commandLine.setExePath(SvnApplicationSettings.getInstance().getCommandLinePath()); + commandLine.addParameter(SvnCommandName.version.getName()); + commandLine.addParameter("--quiet"); + + CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset()); + return handler.runProcess(30 * 1000); + } + + @NotNull + private static Version parseVersion(@NotNull ProcessOutput output) throws VcsException { + if (output.isTimeout() || (output.getExitCode() != 0) || !output.getStderr().isEmpty()) { + throw new VcsException( + String.format("Exit code: %d, Error: %s, Timeout: %b", output.getExitCode(), output.getStderr(), output.isTimeout())); + } + + return parseVersion(output.getStdout()); + } + + @NotNull + private static Version parseVersion(@NotNull String versionText) throws VcsException { + Version result = null; + Exception cause = null; + String[] parts = versionText.trim().split("\\."); + + if (parts.length == 3) { + try { + result = new Version(getInt(parts[0]), getInt(parts[1]), getInt(parts[2])); + } + catch (NumberFormatException e) { + cause = e; + } + } + + if (cause != null || result == null) { + throw new VcsException(String.format("Could not parse svn version: %s", versionText), cause); + } + + return result; + } + + private static int getInt(@NotNull String value) { + return Integer.parseInt(value); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java index c11226a6c356..002820d47f9a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java @@ -5,7 +5,9 @@ import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.add.SvnKitAddClient; import org.jetbrains.idea.svn.annotate.SvnKitAnnotateClient; import org.jetbrains.idea.svn.change.SvnKitChangeListClient; +import org.jetbrains.idea.svn.checkin.SvnKitImportClient; import org.jetbrains.idea.svn.checkout.SvnKitCheckoutClient; +import org.jetbrains.idea.svn.checkout.SvnKitExportClient; import org.jetbrains.idea.svn.cleanup.SvnKitCleanupClient; import org.jetbrains.idea.svn.conflict.SvnKitConflictClient; import org.jetbrains.idea.svn.content.SvnKitContentClient; @@ -14,8 +16,8 @@ import org.jetbrains.idea.svn.delete.SvnKitDeleteClient; import org.jetbrains.idea.svn.history.SvnKitHistoryClient; import org.jetbrains.idea.svn.integrate.SvnKitMergeClient; import org.jetbrains.idea.svn.lock.SvnKitLockClient; -import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient; -import org.jetbrains.idea.svn.portable.SvnUpdateClientI; +import org.jetbrains.idea.svn.update.SvnKitUpdateClient; +import org.jetbrains.idea.svn.update.UpdateClient; import org.jetbrains.idea.svn.portable.SvnkitSvnStatusClient; import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient; import org.jetbrains.idea.svn.properties.SvnKitPropertyClient; @@ -48,13 +50,16 @@ public class SvnKitClientFactory extends ClientFactory { myLockClient = new SvnKitLockClient(); myCleanupClient = new SvnKitCleanupClient(); myRelocateClient = new SvnKitRelocateClient(); - statusClient = new SvnkitSvnStatusClient(myVcs.createStatusClient()); + myVersionClient = new SvnKitVersionClient(); + myImportClient = new SvnKitImportClient(); + myExportClient = new SvnKitExportClient(); + statusClient = new SvnkitSvnStatusClient(myVcs, null); infoClient = new SvnkitSvnWcClient(myVcs); } @NotNull @Override - public SvnUpdateClientI createUpdateClient() { - return new SvnSvnkitUpdateClient(myVcs.createUpdateClient()); + public UpdateClient createUpdateClient() { + return prepare(new SvnKitUpdateClient()); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java new file mode 100644 index 000000000000..084f7f79d946 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitVersionClient.java @@ -0,0 +1,18 @@ +package org.jetbrains.idea.svn.api; + +import com.intellij.openapi.util.Version; +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.svn.WorkingCopyFormat; + +/** + * @author Konstantin Kolosovsky. + */ +public class SvnKitVersionClient extends BaseSvnClient implements VersionClient { + + @NotNull + @Override + public Version getVersion() throws VcsException { + return WorkingCopyFormat.ONE_DOT_SEVEN.getVersion(); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java new file mode 100644 index 000000000000..bbd70921d7a0 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/VersionClient.java @@ -0,0 +1,14 @@ +package org.jetbrains.idea.svn.api; + +import com.intellij.openapi.util.Version; +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; + +/** + * @author Konstantin Kolosovsky. + */ +public interface VersionClient extends SvnClient { + + @NotNull + Version getVersion() throws VcsException; +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java new file mode 100644 index 000000000000..d6cb8945932e --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdImportClient.java @@ -0,0 +1,51 @@ +package org.jetbrains.idea.svn.checkin; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.commandLine.CommandUtil; +import org.jetbrains.idea.svn.commandLine.CommitEventHandler; +import org.jetbrains.idea.svn.commandLine.SvnCommandName; +import org.jetbrains.idea.svn.commandLine.SvnCommitRunner; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNCommitHandler; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Kolosovsky. + */ +public class CmdImportClient extends BaseSvnClient implements ImportClient { + + @Override + public long doImport(@NotNull File path, + @NotNull SVNURL url, + @Nullable SVNDepth depth, + @NotNull String message, + boolean noIgnore, + @Nullable CommitEventHandler handler, + @Nullable ISVNCommitHandler commitHandler) throws VcsException { + // TODO: ISVNFileFilter from ISVNCommitHandler is not currently implemented + + List parameters = new ArrayList(); + + CommandUtil.put(parameters, path, false); + CommandUtil.put(parameters, SvnTarget.fromURL(url), false); + CommandUtil.put(parameters, depth); + CommandUtil.put(parameters, noIgnore, "--no-ignore"); + parameters.add("--message"); + parameters.add(message); + + SvnCommitRunner.CommandListener listener = new SvnCommitRunner.CommandListener(handler); + listener.setBaseDirectory(path); + + CommandUtil.execute(myVcs, SvnTarget.fromURL(url), SvnCommandName.importFolder, parameters, listener); + + return listener.getCommittedRevision(); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java index 7c68e86401ab..8a4b2031c8ce 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java @@ -94,6 +94,8 @@ public class IdeaCommitHandler implements CommitEventHandler, ISVNEventHandler { result = CommitEventType.replacing; } else if (SVNEventAction.COMMIT_DELTA_SENT.equals(action)) { result = CommitEventType.transmittingDeltas; + } else if (SVNEventAction.SKIP.equals(action)) { + result = CommitEventType.skipped; } if (result == null) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java new file mode 100644 index 000000000000..2a8a549ab283 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/ImportClient.java @@ -0,0 +1,26 @@ +package org.jetbrains.idea.svn.checkin; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.SvnClient; +import org.jetbrains.idea.svn.commandLine.CommitEventHandler; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNCommitHandler; + +import java.io.File; + +/** + * @author Konstantin Kolosovsky. + */ +public interface ImportClient extends SvnClient { + + long doImport(@NotNull File path, + @NotNull SVNURL url, + @Nullable SVNDepth depth, + @NotNull String message, + boolean noIgnore, + @Nullable CommitEventHandler handler, + @Nullable ISVNCommitHandler commitHandler) throws VcsException; +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java index 8e2e10d85775..c1f3edeafdc3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java @@ -178,7 +178,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { return; } if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) && - SvnConfiguration.UseAcceleration.commandLine.equals(SvnConfiguration.getInstance(mySvnVcs.getProject()).myUseAcceleration) && + SvnConfiguration.getInstance(mySvnVcs.getProject()).isCommandLine() && (SvnAuthenticationManager.HTTP.equals(url.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(url.getProtocol()))) { doWithCommandLine(committables, comment, exception, feedback); return; @@ -282,7 +282,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { if (! childrenOfSomebody.isEmpty()) { final HashSet result = new HashSet(committables); result.removeAll(childrenOfSomebody); - final SvnCommandLineStatusClient statusClient = new SvnCommandLineStatusClient(mySvnVcs.getProject()); + final SvnCommandLineStatusClient statusClient = new SvnCommandLineStatusClient(mySvnVcs); for (File file : childrenOfSomebody) { try { final SVNStatus status = statusClient.doStatus(file, false); @@ -385,7 +385,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment { } private SVNStatus getStatusCommandLine(File file) throws SVNException { - return new SvnCommandLineStatusClient(mySvnVcs.getProject()).doStatus(file, false); + return new SvnCommandLineStatusClient(mySvnVcs).doStatus(file, false); } private static List collectPaths(final List changes) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java new file mode 100644 index 000000000000..838e7646a310 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnKitImportClient.java @@ -0,0 +1,44 @@ +package org.jetbrains.idea.svn.checkin; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.commandLine.CommitEventHandler; +import org.jetbrains.idea.svn.commandLine.SvnBindException; +import org.tmatesoft.svn.core.SVNCommitInfo; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNCommitHandler; +import org.tmatesoft.svn.core.wc.SVNCommitClient; + +import java.io.File; + +/** + * @author Konstantin Kolosovsky. + */ +public class SvnKitImportClient extends BaseSvnClient implements ImportClient { + + @Override + public long doImport(@NotNull File path, + @NotNull SVNURL url, + @Nullable SVNDepth depth, + @NotNull String message, + boolean noIgnore, + @Nullable CommitEventHandler handler, + @Nullable ISVNCommitHandler commitHandler) throws VcsException { + SVNCommitClient client = myVcs.createCommitClient(); + + client.setEventHandler(handler); + client.setCommitHandler(commitHandler); + + try { + SVNCommitInfo info = client.doImport(path, url, message, null, !noIgnore, false, depth); + return info.getNewRevision(); + } + catch (SVNException e) { + throw new SvnBindException(e); + } + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java index 365069668244..88f2a6940c10 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CheckoutEventHandler.java @@ -19,6 +19,8 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.StatusBar; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.SvnVcs; @@ -30,13 +32,13 @@ import org.tmatesoft.svn.core.wc.SVNEvent; import org.tmatesoft.svn.core.wc.SVNEventAction; public class CheckoutEventHandler implements ISVNEventHandler { - private final ProgressIndicator myIndicator; + @Nullable private final ProgressIndicator myIndicator; private int myExternalsCount; - private final SvnVcs myVCS; + @NotNull private final SvnVcs myVCS; private final boolean myIsExport; private int myCnt; - public CheckoutEventHandler(SvnVcs vcs, boolean isExport, ProgressIndicator indicator) { + public CheckoutEventHandler(@NotNull SvnVcs vcs, boolean isExport, @Nullable ProgressIndicator indicator) { myIndicator = indicator; myVCS = vcs; myExternalsCount = 1; @@ -51,16 +53,17 @@ public class CheckoutEventHandler implements ISVNEventHandler { } if (event.getAction() == SVNEventAction.UPDATE_EXTERNAL) { myExternalsCount++; - ProgressManager.progress(SvnBundle.message("progress.text2.fetching.external.location", event.getFile().getAbsolutePath()), ""); + progress(SvnBundle.message("progress.text2.fetching.external.location", event.getFile().getAbsolutePath())); } else if (event.getAction() == SVNEventAction.UPDATE_ADD) { - ProgressManager.progress2(SvnBundle.message(myIsExport ? "progress.text2.exported" : "progress.text2.checked.out", event.getFile().getName(), myCnt)); + progress2(SvnBundle.message(myIsExport ? "progress.text2.exported" : "progress.text2.checked.out", event.getFile().getName(), myCnt)); ++ myCnt; } else if (event.getAction() == SVNEventAction.UPDATE_COMPLETED) { myExternalsCount--; - ProgressManager.progress2((SvnBundle.message(myIsExport ? "progress.text2.exported.revision" : "progress.text2.checked.out.revision", event.getRevision()))); - if (myExternalsCount == 0 && event.getRevision() >= 0 && myVCS != null) { + progress2( + (SvnBundle.message(myIsExport ? "progress.text2.exported.revision" : "progress.text2.checked.out.revision", event.getRevision()))); + if (myExternalsCount == 0 && event.getRevision() >= 0) { myExternalsCount = 1; Project project = myVCS.getProject(); if (project != null) { @@ -68,9 +71,9 @@ public class CheckoutEventHandler implements ISVNEventHandler { } } } else if (event.getAction() == SVNEventAction.COMMIT_ADDED) { - ProgressManager.progress2((SvnBundle.message("progress.text2.adding", path))); + progress2((SvnBundle.message("progress.text2.adding", path))); } else if (event.getAction() == SVNEventAction.COMMIT_DELTA_SENT) { - ProgressManager.progress2((SvnBundle.message("progress.text2.transmitting.delta", path))); + progress2((SvnBundle.message("progress.text2.transmitting.delta", path))); } } @@ -79,4 +82,23 @@ public class CheckoutEventHandler implements ISVNEventHandler { throw new SVNCancelException(SVNErrorMessage.create(SVNErrorCode.CANCELLED, "Operation cancelled")); } } + + private void progress(@NotNull String text) { + if (myIndicator != null) { + myIndicator.checkCanceled(); + myIndicator.setText(text); + myIndicator.setText2(""); + } else { + ProgressManager.progress(text); + } + } + + private void progress2(@NotNull String text) { + if (myIndicator != null) { + myIndicator.checkCanceled(); + myIndicator.setText2(text); + } else { + ProgressManager.progress2(text); + } + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java new file mode 100644 index 000000000000..6bff70f5236d --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/CmdExportClient.java @@ -0,0 +1,53 @@ +package org.jetbrains.idea.svn.checkout; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.commandLine.BaseUpdateCommandListener; +import org.jetbrains.idea.svn.commandLine.CommandUtil; +import org.jetbrains.idea.svn.commandLine.SvnCommandName; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Kolosovsky. + */ +public class CmdExportClient extends BaseSvnClient implements ExportClient { + + @Override + public void export(@NotNull SvnTarget from, + @NotNull File to, + @Nullable SVNRevision revision, + @Nullable SVNDepth depth, + @Nullable String nativeLineEnd, + boolean force, + boolean ignoreExternals, + @Nullable ISVNEventHandler handler) throws VcsException { + List parameters = new ArrayList(); + + CommandUtil.put(parameters, from); + CommandUtil.put(parameters, to); + CommandUtil.put(parameters, revision); + CommandUtil.put(parameters, depth); + CommandUtil.put(parameters, force, "--force"); + CommandUtil.put(parameters, ignoreExternals, "--ignore-externals"); + if (!StringUtil.isEmpty(nativeLineEnd)) { + parameters.add("--native-eol"); + parameters.add(nativeLineEnd); + } + + BaseUpdateCommandListener listener = new BaseUpdateCommandListener(to, handler); + + CommandUtil.execute(myVcs, from, to, SvnCommandName.export, parameters, listener); + + listener.throwWrappedIfException(); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java new file mode 100644 index 000000000000..6ddd6debe763 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/ExportClient.java @@ -0,0 +1,27 @@ +package org.jetbrains.idea.svn.checkout; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.SvnClient; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.io.File; + +/** + * @author Konstantin Kolosovsky. + */ +public interface ExportClient extends SvnClient { + + void export(@NotNull SvnTarget from, + @NotNull File to, + @Nullable SVNRevision revision, + @Nullable SVNDepth depth, + @Nullable String nativeLineEnd, + boolean force, + boolean ignoreExternals, + @Nullable ISVNEventHandler handler) throws VcsException; +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java index 7b0ed8c35c2c..ff415a0c116f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java @@ -33,11 +33,14 @@ import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; import com.intellij.openapi.vcs.update.RefreshVFsSynchronously; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.StatusBar; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; import org.jetbrains.idea.svn.actions.ExclusiveBackgroundVcsAction; import org.jetbrains.idea.svn.actions.SvnExcludingIgnoredOperation; +import org.jetbrains.idea.svn.checkin.IdeaCommitHandler; +import org.jetbrains.idea.svn.commandLine.CommitEventHandler; import org.jetbrains.idea.svn.dialogs.CheckoutDialog; import org.tmatesoft.svn.core.SVNCancelException; import org.tmatesoft.svn.core.SVNDepth; @@ -62,13 +65,11 @@ public class SvnCheckoutProvider implements CheckoutProvider { target.mkdirs(); } - final String selectedFormat = promptForWCopyFormat(target, project); - if (selectedFormat == null) { - // cancelled - return; + final WorkingCopyFormat selectedFormat = promptForWCopyFormat(target, project); + // UNKNOWN here means operation was cancelled + if (selectedFormat != WorkingCopyFormat.UNKNOWN) { + checkout(project, target, url, revision, depth, ignoreExternals, listener, selectedFormat); } - - checkout(project, target, url, revision, depth, ignoreExternals, listener, WorkingCopyFormat.getInstance(selectedFormat)); } public static void checkout(final Project project, @@ -168,52 +169,50 @@ public class SvnCheckoutProvider implements CheckoutProvider { } public static boolean promptForWCFormatAndSelect(final File target, final Project project) { - final String result = promptForWCopyFormat(target, project); - if (result != null) { - SvnWorkingCopyFormatHolder.setPresetFormat(WorkingCopyFormat.getInstance(result)); + final WorkingCopyFormat result = promptForWCopyFormat(target, project); + if (result != WorkingCopyFormat.UNKNOWN) { + SvnWorkingCopyFormatHolder.setPresetFormat(result); } - return result != null; + return result != WorkingCopyFormat.UNKNOWN; } - @Nullable - private static String promptForWCopyFormat(final File target, final Project project) { - String formatMode = null; + @NotNull + private static WorkingCopyFormat promptForWCopyFormat(final File target, final Project project) { + WorkingCopyFormat format = WorkingCopyFormat.UNKNOWN; final Ref wasOk = new Ref(); - while ((formatMode == null) && (! Boolean.FALSE.equals(wasOk.get()))) { - formatMode = SvnFormatSelector.showUpgradeDialog(target, project, true, SvnConfiguration.UPGRADE_AUTO_17, wasOk); + while ((format == WorkingCopyFormat.UNKNOWN) && (! Boolean.FALSE.equals(wasOk.get()))) { + format = SvnFormatSelector.showUpgradeDialog(target, project, true, WorkingCopyFormat.ONE_DOT_SEVEN, wasOk); } - return Boolean.TRUE.equals(wasOk.get()) ? formatMode : null; + return Boolean.TRUE.equals(wasOk.get()) ? format : WorkingCopyFormat.UNKNOWN; } - public static void doExport(final Project project, final File target, final String url, final SVNDepth depth, + public static void doExport(final Project project, final File target, final SVNURL url, final SVNDepth depth, final boolean ignoreExternals, final boolean force, final String eolStyle) { try { - final SVNException[] exception = new SVNException[1]; - final SVNUpdateClient client = SvnVcs.getInstance(project).createUpdateClient(); + final VcsException[] exception = new VcsException[1]; + final SvnVcs vcs = SvnVcs.getInstance(project); ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { public void run() { ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - client.setEventHandler(new CheckoutEventHandler(SvnVcs.getInstance(project), true, progressIndicator)); - client.setIgnoreExternals(ignoreExternals); + ISVNEventHandler handler = new CheckoutEventHandler(vcs, true, progressIndicator); try { progressIndicator.setText(SvnBundle.message("progress.text.export", target.getAbsolutePath())); - client.doExport(SVNURL.parseURIEncoded(url), target, SVNRevision.UNDEFINED, SVNRevision.HEAD, eolStyle, force, depth); + + SvnTarget from = SvnTarget.fromURL(url); + ExportClient client = vcs.getFactoryFromSettings().createExportClient(); + client.export(from, target, SVNRevision.HEAD, depth, eolStyle, force, ignoreExternals, handler); } - catch (SVNException e) { + catch (VcsException e) { exception[0] = e; } - finally { - client.setIgnoreExternals(false); - client.setEventHandler(null); - } } }, SvnBundle.message("message.title.export"), true, project); if (exception[0] != null) { throw exception[0]; } } - catch (SVNException e1) { + catch (VcsException e1) { Messages.showErrorDialog(SvnBundle.message("message.text.cannot.export", e1.getMessage()), SvnBundle.message("message.title.export")); } } @@ -221,7 +220,7 @@ public class SvnCheckoutProvider implements CheckoutProvider { public static void doImport(final Project project, final File target, final SVNURL url, final SVNDepth depth, final boolean includeIgnored, final String message) { final Ref errorMessage = new Ref(); - final SVNCommitClient client = SvnVcs.getInstance(project).createCommitClient(); + final SvnVcs vcs = SvnVcs.getInstance(project); final String targetPath = FileUtil.toSystemIndependentName(target.getAbsolutePath()); ExclusiveBackgroundVcsAction.run(project, new Runnable() { @@ -230,7 +229,6 @@ public class SvnCheckoutProvider implements CheckoutProvider { public void run() { final FileIndexFacade facade = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class); ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - client.setEventHandler(new CheckoutEventHandler(SvnVcs.getInstance(project), true, progressIndicator)); try { progressIndicator.setText(SvnBundle.message("progress.text.import", target.getAbsolutePath())); @@ -244,22 +242,21 @@ public class SvnCheckoutProvider implements CheckoutProvider { return facade.isInContent(targetVf); } }); - if (project.isDefault() || !isInContent) { - // do not pay attention to ignored/excluded settings - client.doImport(target, url, message, null, !includeIgnored, false, depth); - } else { - client.setCommitHandler(new MyFilter(LocalFileSystem.getInstance(), new SvnExcludingIgnoredOperation.Filter(project))); - client.doImport(target, url, message, null, !includeIgnored, false, depth); + CommitEventHandler handler = new IdeaCommitHandler(progressIndicator); + boolean useFileFilter = !project.isDefault() && isInContent; + ISVNCommitHandler commitHandler = + useFileFilter ? new MyFilter(LocalFileSystem.getInstance(), new SvnExcludingIgnoredOperation.Filter(project)) : null; + long revision = vcs.getFactoryFromSettings().createImportClient() + .doImport(target, url, depth, message, includeIgnored, handler, commitHandler); + + if (revision > 0) { + StatusBar.Info.set(SvnBundle.message("status.text.comitted.revision", revision), project); } } } - catch (SVNException e) { + catch (VcsException e) { errorMessage.set(e.getMessage()); } - finally { - client.setIgnoreExternals(false); - client.setEventHandler(null); - } } }, SvnBundle.message("message.title.import"), true, project); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java new file mode 100644 index 000000000000..f04c749fb4f3 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnKitExportClient.java @@ -0,0 +1,48 @@ +package org.jetbrains.idea.svn.checkout; + +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.commandLine.SvnBindException; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc.SVNUpdateClient; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.io.File; + +/** + * @author Konstantin Kolosovsky. + */ +public class SvnKitExportClient extends BaseSvnClient implements ExportClient { + + @Override + public void export(@NotNull SvnTarget from, + @NotNull File to, + @Nullable SVNRevision revision, + @Nullable SVNDepth depth, + @Nullable String nativeLineEnd, + boolean force, + boolean ignoreExternals, + @Nullable ISVNEventHandler handler) throws VcsException { + SVNUpdateClient client = myVcs.createUpdateClient(); + + client.setEventHandler(handler); + client.setIgnoreExternals(ignoreExternals); + + try { + if (from.isFile()) { + client.doExport(from.getFile(), to, from.getPegRevision(), revision, nativeLineEnd, force, depth); + } + else { + client.doExport(from.getURL(), to, from.getPegRevision(), revision, nativeLineEnd, force, depth); + } + } + catch (SVNException e) { + throw new SvnBindException(e); + } + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java index 393cccc016c7..0279ebaf3467 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java @@ -103,9 +103,18 @@ public class CommandUtil { } public static void put(@NotNull List parameters, @Nullable SVNDepth depth) { + put(parameters, depth, false); + } + + public static void put(@NotNull List parameters, @Nullable SVNDepth depth, boolean sticky) { if (depth != null && !SVNDepth.UNKNOWN.equals(depth)) { parameters.add("--depth"); parameters.add(depth.getName()); + + if (sticky) { + parameters.add("--set-depth"); + parameters.add(depth.getName()); + } } } @@ -148,6 +157,16 @@ public class CommandUtil { } } + public static String escape(@NotNull String path) { + String result = path; + + if (path.contains("@")) { + result += "@"; + } + + return result; + } + public static T parse(@NotNull String data, @NotNull Class type) throws JAXBException { JAXBContext context = JAXBContext.newInstance(type); Unmarshaller unmarshaller = context.createUnmarshaller(); @@ -171,8 +190,18 @@ public class CommandUtil { @NotNull SvnCommandName name, @NotNull List parameters, @Nullable LineCommandListener listener) throws VcsException { - SVNURL repositoryUrl = resolveRepositoryUrl(vcs, name, target); File workingDirectory = resolveWorkingDirectory(vcs, target); + + return execute(vcs, target, workingDirectory, name, parameters, listener); + } + + public static SvnCommand execute(@NotNull SvnVcs vcs, + @NotNull SvnTarget target, + @NotNull File workingDirectory, + @NotNull SvnCommandName name, + @NotNull List parameters, + @Nullable LineCommandListener listener) throws VcsException { + SVNURL repositoryUrl = resolveRepositoryUrl(vcs, name, target); IdeaSvnkitBasedAuthenticationCallback callback = new IdeaSvnkitBasedAuthenticationCallback(vcs); return SvnLineCommand.runWithAuthenticationAttempt(workingDirectory, repositoryUrl, name, @@ -180,6 +209,11 @@ public class CommandUtil { ArrayUtil.toStringArray(parameters)); } + @NotNull + public static File getHomeDirectory() { + return new File(PathManager.getHomePath()); + } + private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @NotNull SvnCommandName name, @NotNull SvnTarget target) { RootUrlInfo rootInfo = target.isFile() ? vcs.getSvnFileUrlMapping().getWcRootForFilePath(target.getFile()) @@ -204,7 +238,7 @@ public class CommandUtil { if (workingDirectory == null) { workingDirectory = - !vcs.getProject().isDefault() ? VfsUtilCore.virtualToIoFile(vcs.getProject().getBaseDir()) : new File(PathManager.getHomePath()); + !vcs.getProject().isDefault() ? VfsUtilCore.virtualToIoFile(vcs.getProject().getBaseDir()) : getHomeDirectory(); } return workingDirectory; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java index 87dc212d0341..f0c6df7c61ec 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java @@ -27,7 +27,8 @@ public enum CommitEventType { sending("Sending"), replacing("Replacing"), transmittingDeltas("Transmitting file data"), - committedRevision("Committed revision"); + committedRevision("Committed revision"), + skipped("Skipped"); private final String myText; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java index 766d95a8457e..0e93b54a2b93 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java @@ -56,12 +56,11 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient"); - @NotNull - private final Project myProject; + @NotNull private final SvnVcs myVcs; - public SvnCommandLineInfoClient(@NotNull final Project project) { - super(SvnVcs.getInstance(project)); - myProject = project; + public SvnCommandLineInfoClient(@NotNull final SvnVcs vcs) { + super(vcs); + myVcs = vcs; } @Override @@ -118,8 +117,7 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient { }; try { - SvnCommand command = - CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromFile(path), SvnCommandName.info, parameters, listener); + SvnCommand command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.info, parameters, listener); return command.getOutput(); } @@ -217,7 +215,7 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient { fillParameters(path, pegRevision, revision, depth, parameters); SvnCommand command; try { - command = CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromURL(url), SvnCommandName.info, parameters, null); + command = CommandUtil.execute(myVcs, SvnTarget.fromURL(url), SvnCommandName.info, parameters, null); } catch (VcsException e) { throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java index 1cdf15f59969..14c701b79976 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java @@ -16,7 +16,6 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Getter; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -53,12 +52,12 @@ import java.util.*; public class SvnCommandLineStatusClient implements SvnStatusClientI { private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient"); - private final Project myProject; private final SvnCommandLineInfoClient myInfoClient; + @NotNull private final SvnVcs myVcs; - public SvnCommandLineStatusClient(Project project) { - myProject = project; - myInfoClient = new SvnCommandLineInfoClient(project); + public SvnCommandLineStatusClient(@NotNull SvnVcs vcs) { + myVcs = vcs; + myInfoClient = new SvnCommandLineInfoClient(vcs); } @Override @@ -111,7 +110,7 @@ public class SvnCommandLineStatusClient implements SvnStatusClientI { SvnCommand command; try { - command = CommandUtil.execute(SvnVcs.getInstance(myProject), SvnTarget.fromFile(path), SvnCommandName.st, parameters, null); + command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.st, parameters, null); } catch (VcsException e) { throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e); @@ -139,7 +138,7 @@ public class SvnCommandLineStatusClient implements SvnStatusClientI { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), svnHandl[0]); if (!svnHandl[0].isAnythingReported()) { - if (!SvnUtil.isSvnVersioned(myProject, path)) { + if (!SvnUtil.isSvnVersioned(myVcs, path)) { throw new SVNException( SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY, "Command - " + command.getCommandText() + ". Result - " + result)); } else { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java deleted file mode 100644 index 06901eaf64d7..000000000000 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.svn.commandLine; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient; -import org.tmatesoft.svn.core.*; -import org.tmatesoft.svn.core.wc.*; -import org.tmatesoft.svn.core.wc2.SvnTarget; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 2/1/12 - * Time: 12:13 PM - */ -public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient { - private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+"); - private static final String ourAuthenticationRealm = "Authentication realm:"; - private final Project myProject; - private final VirtualFile myCommonAncestor; - private boolean myIgnoreExternals; - private SvnVcs myVcs; - - public SvnCommandLineUpdateClient(final SvnVcs vcs, VirtualFile commonAncestor) { - super(vcs.createUpdateClient()); - myVcs = vcs; - myProject = vcs.getProject(); - myCommonAncestor = commonAncestor; - } - - @Override - public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException { - final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), false, false, false); - return longs[0]; - } - - @Override - public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException { - final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), force, false, false); - return longs[0]; - } - - @Override - public long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) - throws SVNException { - return doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, false); - } - - @Override - public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions, - final boolean depthIsSticky, final boolean makeParents) throws SVNException { - // since one revision is passed -> I assume same repository here - final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myProject); - final SVNInfo info = infoClient.doInfo(paths[0], SVNRevision.UNDEFINED); - if (info == null || info.getURL() == null) { - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, paths[0].getPath())); - } - final AtomicReference updatedToRevision = new AtomicReference(); - updatedToRevision.set(new long[0]); - - File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath()); - base = base.isDirectory() ? base : base.getParentFile(); - - final List parameters = prepareParameters(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents); - final BaseUpdateCommandListener listener = createCommandListener(paths, updatedToRevision, base); - try { - CommandUtil.execute(myVcs, SvnTarget.fromFile(base), SvnCommandName.up, parameters, listener); - } - catch (VcsException e) { - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e)); - } - - listener.throwIfException(); - - return updatedToRevision.get(); - } - - private BaseUpdateCommandListener createCommandListener(final File[] paths, - final AtomicReference updatedToRevision, - final File base) { - return new BaseUpdateCommandListener(base, getEventHandler()) { - final long[] myRevisions = new long[paths.length]; - - @Override - protected void beforeHandler(@NotNull SVNEvent event) { - if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) { - final long eventRevision = event.getRevision(); - for (int i = 0; i < paths.length; i++) { - final File path = paths[i]; - if (FileUtil.filesEqual(path, event.getFile())) { - myRevisions[i] = eventRevision; - break; - } - } - } - } - - @Override - public void processTerminated(int exitCode) { - super.processTerminated(exitCode); - updatedToRevision.set(myRevisions); - } - }; - } - - private List prepareParameters(File[] paths, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, - boolean depthIsSticky, boolean makeParents) { - List parameters = new ArrayList(); - - CommandUtil.put(parameters, revision); - CommandUtil.put(parameters, depth); - CommandUtil.put(parameters, allowUnversionedObstructions, "--force"); - if (depthIsSticky && depth != null) {// !!! not sure, but not used - parameters.add("--set-depth"); - parameters.add(depth.toString()); - } - CommandUtil.put(parameters, makeParents, "--parents"); - CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals"); - parameters.add("--accept"); - parameters.add("postpone"); - CommandUtil.put(parameters, paths); - - return parameters; - } - - - private void checkForException(final StringBuffer sbError) throws SVNException { - if (sbError.length() == 0) return; - final String message = sbError.toString(); - final Matcher matcher = ourExceptionPattern.matcher(message); - if (matcher.matches()) { - final String group = matcher.group(1); - if (group != null) { - try { - final int code = Integer.parseInt(group); - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message)); - } catch (NumberFormatException e) { - // - } - } - } - if (message.contains(ourAuthenticationRealm)) { - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message)); - } - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message)); - } - - @Override - public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) - throws SVNException { - final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false); - return longs[0]; - } - - @Override - public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException { - throw new UnsupportedOperationException(); - //return super.doSwitch(file, url, revision, recursive); - } - - @Override - public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException { - throw new UnsupportedOperationException(); - //return super.doSwitch(file, url, pegRevision, revision, recursive); - } - - @Override - public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) - throws SVNException { - throw new UnsupportedOperationException(); - //return super.doSwitch(file, url, pegRevision, revision, recursive, force); - } - - @Override - public long doSwitch(File path, - SVNURL url, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, - boolean depthIsSticky) throws SVNException { - throw new UnsupportedOperationException(); - //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky); - } - - @Override - public long doSwitch(File path, - SVNURL url, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, - boolean depthIsSticky, - boolean ignoreAncestry) throws SVNException { - throw new UnsupportedOperationException(); - // todo MAIN - //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry); - } - - @Override - public void setIgnoreExternals(boolean ignoreExternals) { - myIgnoreExternals = ignoreExternals; - } -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java index 72fd4657ec4e..9182d9371c4e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java @@ -26,6 +26,7 @@ public enum SvnCommandName { info("info", false), st("st", false), up("up", true), + switchCopy("switch", true), relocate("relocate", true), ci("commit", true), checkout("checkout", true), @@ -46,7 +47,9 @@ public enum SvnCommandName { merge("merge", true), changelist("changelist", true), lock("lock", true), - unlock("unlock", true); + unlock("unlock", true), + importFolder("import", false), + export("export", false); private final String myName; private final boolean myWriteable; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java index 1f93976434af..cf13f1267c7c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java @@ -29,6 +29,8 @@ import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. @@ -94,6 +96,14 @@ public class SvnCommitRunner { } public static class CommandListener extends LineCommandListener { + + // Status could contain spaces, like "Adding copy of ". But at the end we are not interested in "copy of" part and want to have + // only "Adding" in match group. + private static final String STATUS = "\\s*(\\w+)(.*?)\\s\\s+"; + private static final String OPTIONAL_FILE_TYPE = "(\\(.*\\))?"; + private static final String PATH = "\\s*(.*?)\\s*"; + private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + OPTIONAL_FILE_TYPE + PATH); + @Nullable private final CommitEventHandler myHandler; private SvnBindException myException; private long myCommittedRevision = Revision.SVN_INVALID_REVNUM; @@ -138,6 +148,24 @@ public class SvnCommitRunner { } return; } + if (line.startsWith(CommitEventType.skipped.getText())) { + File target = null; + if (myHandler != null) { + int pathStart = line.indexOf('\''); + if (pathStart > -1) { + int pathEnd = line.indexOf('\'', pathStart + 1); + if (pathEnd > -1) { + target = toFile(line.substring(pathStart + 1, pathEnd)); + } + } + if (target != null) { + myHandler.commitEvent(CommitEventType.skipped, myBase); + } else { + LOG.info("Can not parse 'Skipped' path " + line); + } + } + return; + } if (line.startsWith(CommitEventType.committedRevision.getText())) { final String substring = line.substring(CommitEventType.committedRevision.getText().length()); int cnt = 0; @@ -167,26 +195,34 @@ public class SvnCommitRunner { } } else { if (myHandler == null) return; - // status and path are separated by several spaces - final int idxSpace = line.indexOf(" "); - if (idxSpace == -1) { - LOG.info("Can not parse event type: " + line); - return; - } - final CommitEventType type = CommitEventType.create(line.substring(0, idxSpace)); - if (type == null) { - LOG.info("Can not parse event type: " + line); - return; - } - File target = new File(new String(line.substring(idxSpace + 1).trim())); - if (!target.isAbsolute()) { - target = new File(myBase, target.getPath()); + + Matcher matcher = CHANGED_PATH.matcher(line); + if (matcher.matches()) { + final CommitEventType type = CommitEventType.create(matcher.group(1)); + if (type == null) { + LOG.info("Can not parse event type: " + line); + return; + } + myHandler.commitEvent(type, toFile(matcher.group(4))); + } else { + LOG.info("Can not parse output: " + line); } - myHandler.commitEvent(type, target); } } + + @NotNull + private File toFile(@NotNull String path) { + File result = new File(path); + + if (!result.isAbsolute()) { + result = new File(myBase, result.getPath()); + } + + return result; + } } + /*C:\TestProjects\sortedProjects\Subversion\local2\preRelease\mod2\src\com\test>sv n st D gggG diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java index 9294f0bbaf2c..34525c63b8a8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java @@ -16,14 +16,11 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.execution.ExecutableValidator; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.CapturingProcessHandler; -import com.intellij.execution.process.ProcessOutput; import com.intellij.notification.Notification; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Version; -import com.intellij.openapi.vfs.CharsetToolkit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnApplicationSettings; @@ -41,6 +38,8 @@ import java.io.File; */ public class SvnExecutableChecker extends ExecutableValidator { + private static final Logger LOG = Logger.getInstance(SvnExecutableChecker.class); + public SvnExecutableChecker(Project project) { super(project, getNotificationTitle(), getWrongPathMessage()); } @@ -74,12 +73,13 @@ public class SvnExecutableChecker extends ExecutableValidator { protected boolean isExecutableValid(@NotNull String executable) { setNotificationErrorDescription(getWrongPathMessage()); - final Version version = getVersion(executable); + // Necessary executable path will be taken from settings while command execution + final Version version = getConfiguredClientVersion(); try { return version != null && validateVersion(version); } catch (Throwable e) { - // do nothing + LOG.info(e); return false; } } @@ -101,38 +101,19 @@ public class SvnExecutableChecker extends ExecutableValidator { } @Nullable - public Version getVersion(@NotNull String executable) { + private Version getConfiguredClientVersion() { Version result = null; try { - GeneralCommandLine commandLine = new GeneralCommandLine(); - commandLine.setExePath(executable); - commandLine.addParameter("--version"); - commandLine.addParameter("--quiet"); - - CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset()); - ProcessOutput output = handler.runProcess(30 * 1000); - - if (!output.isTimeout() && (output.getExitCode() == 0) && output.getStderr().isEmpty()) { - String versionText = output.getStdout().trim(); - final String[] parts = versionText.split("\\."); - - if (parts.length >= 3) { - result = new Version(getInt(parts[0]), getInt(parts[1]), getInt(parts[2])); - } - } + result = getVcs().getCommandLineFactory().createVersionClient().getVersion(); } catch (Throwable e) { - // do nothing + LOG.info(e); } return result; } - private static int getInt(@NotNull String value) { - return Integer.parseInt(value); - } - private static String getWrongPathMessage() { return SvnBundle.message("subversion.executable.notification.description"); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java index cfd6db992a03..6520c6254f65 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java @@ -26,7 +26,9 @@ import org.tmatesoft.svn.core.wc.SVNEventAction; import org.tmatesoft.svn.core.wc.SVNStatusType; import java.io.File; -import java.util.*; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -55,12 +57,18 @@ public class UpdateOutputLineConverter { private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION); private final static Pattern ourCheckedOutRevision = Pattern.compile("Checked out revision (\\d+)\\."); + // export from repository + private final static Pattern ourExportedRevision = Pattern.compile("Exported revision (\\d+)\\."); + // export from working copy + private final static Pattern ourExportComplete = Pattern.compile("Export complete\\."); + private final static Pattern ourExternal = Pattern.compile(EXTERNAL); private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL); private final static Pattern ourCheckedOutExternal = Pattern.compile("Checked out external at revision (\\d+)\\."); private final static Pattern[] ourCompletePatterns = - new Pattern[]{ourAtRevision, ourUpdatedToRevision, ourCheckedOutRevision, ourExternal, ourUpdatedExternal, ourCheckedOutExternal}; + new Pattern[]{ourAtRevision, ourUpdatedToRevision, ourCheckedOutRevision, ourExportedRevision, ourExternal, ourUpdatedExternal, + ourCheckedOutExternal, ourExportComplete}; private final File myBase; private File myCurrentFile; @@ -168,6 +176,10 @@ public class UpdateOutputLineConverter { private long matchAndGetRevision(final Pattern pattern, final String line) { final Matcher matcher = pattern.matcher(line); if (matcher.matches()) { + if (pattern == ourExportComplete) { + return 0; + } + final String group = matcher.group(1); if (group == null) return -1; try { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java index 0cfe815a702b..f88c8ebf13eb 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopiesPanel.java @@ -340,14 +340,13 @@ public class CopiesPanel { private void changeFormat(final WCInfo wcInfo) { ChangeFormatDialog dialog = new ChangeFormatDialog(myProject, new File(wcInfo.getPath()), false, ! wcInfo.isIsWcRoot()); - dialog.setData(wcInfo.getFormat().getOption()); + dialog.setData(wcInfo.getFormat()); dialog.show(); if (! dialog.isOK()) { return; } - final String newMode = dialog.getUpgradeMode(); - if (! wcInfo.getFormat().getOption().equals(newMode)) { - final WorkingCopyFormat newFormat = WorkingCopyFormat.getInstance(newMode); + final WorkingCopyFormat newFormat = dialog.getUpgradeMode(); + if (!wcInfo.getFormat().equals(newFormat)) { ApplicationManager.getApplication().saveAll(); final Task.Backgroundable task = new SvnFormatWorker(myProject, newFormat, wcInfo) { @Override diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java index ca596e92fefc..a04f8172ef7d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java @@ -894,7 +894,7 @@ public class RepositoryBrowserDialog extends DialogWrapper { ExportOptionsDialog dialog = new ExportOptionsDialog(p, url, dir); dialog.show(); if (dialog.isOK()) { - SvnCheckoutProvider.doExport(myProject, dir, url.toString(), dialog.getDepth(), + SvnCheckoutProvider.doExport(myProject, dir, url, dialog.getDepth(), dialog.isIgnoreExternals(), dialog.isForce(), dialog.getEOLStyle()); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java index f9bf6bda943d..cb2fcdaba0f1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/UpgradeFormatDialog.java @@ -23,16 +23,19 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnBundle; -import org.jetbrains.idea.svn.SvnConfiguration; +import org.jetbrains.idea.svn.WorkingCopyFormat; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; import javax.swing.*; import java.awt.*; import java.io.File; +import java.util.ArrayList; +import java.util.List; public class UpgradeFormatDialog extends DialogWrapper { - private JRadioButton myUpgradeAuto16Button; - private JRadioButton myUpgradeAuto17Button; + + private ButtonGroup formatGroup = new ButtonGroup(); + private List formatButtons = new ArrayList(); protected File myPath; @@ -61,11 +64,12 @@ public class UpgradeFormatDialog extends DialogWrapper { return "svn.upgradeDialog"; } - public void setData(final String selectedFormat) { - if (SvnConfiguration.UPGRADE_AUTO_17.equals(selectedFormat)) { - myUpgradeAuto17Button.setSelected(true); - } else { - myUpgradeAuto16Button.setSelected(true); + public void setData(final WorkingCopyFormat selectedFormat) { + for (JRadioButton button : formatButtons) { + if (selectedFormat == getFormat(button)) { + button.setSelected(true); + break; + } } } @@ -101,17 +105,9 @@ public class UpgradeFormatDialog extends DialogWrapper { panel.add(topLabel, gb); gb.gridy += 1; - - myUpgradeAuto16Button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto.16format")); - myUpgradeAuto17Button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto.17format")); - - ButtonGroup group = new ButtonGroup(); - group.add(myUpgradeAuto16Button); - group.add(myUpgradeAuto17Button); - panel.add(myUpgradeAuto16Button, gb); - gb.gridy += 1; - panel.add(myUpgradeAuto17Button, gb); - gb.gridy += 1; + registerFormat(WorkingCopyFormat.ONE_DOT_SIX, label, panel, gb); + registerFormat(WorkingCopyFormat.ONE_DOT_SEVEN, label, panel, gb); + registerFormat(WorkingCopyFormat.ONE_DOT_EIGHT, label, panel, gb); final JPanel auxiliaryPanel = getBottomAuxiliaryPanel(); if (auxiliaryPanel != null) { @@ -122,6 +118,24 @@ public class UpgradeFormatDialog extends DialogWrapper { return panel; } + private void registerFormat(@NotNull WorkingCopyFormat format, + @NotNull String label, + @NotNull JPanel panel, + @NotNull GridBagConstraints gb) { + JRadioButton button = new JRadioButton(SvnBundle.message("radio.configure." + label + ".auto." + getKey(format) + "format")); + button.putClientProperty("format", format); + + panel.add(button, gb); + gb.gridy += 1; + + formatGroup.add(button); + formatButtons.add(button); + } + + private static String getKey(@NotNull WorkingCopyFormat format) { + return String.format("%d%d", format.getVersion().major, format.getVersion().minor); + } + @Nullable protected JPanel getBottomAuxiliaryPanel() { return null; @@ -135,14 +149,24 @@ public class UpgradeFormatDialog extends DialogWrapper { return true; } - @Nullable - public String getUpgradeMode() { - if (myUpgradeAuto17Button.isSelected()) { - return SvnConfiguration.UPGRADE_AUTO_17; - } else if (myUpgradeAuto16Button.isSelected()) { - return SvnConfiguration.UPGRADE_AUTO_16; - } - return null; + @NotNull + private static WorkingCopyFormat getFormat(@NotNull JRadioButton button) { + Object format = button.getClientProperty("format"); + + return format instanceof WorkingCopyFormat ? (WorkingCopyFormat)format : WorkingCopyFormat.UNKNOWN; } + @NotNull + public WorkingCopyFormat getUpgradeMode() { + WorkingCopyFormat result = WorkingCopyFormat.UNKNOWN; + + for (JRadioButton button : formatButtons) { + if (button.isSelected()) { + result = getFormat(button); + break; + } + } + + return result; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java index fa11d6ed4d78..4123a6f55800 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java @@ -1,10 +1,7 @@ package org.jetbrains.idea.svn.history; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; -import com.intellij.util.LineSeparator; -import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.BaseSvnClient; @@ -18,23 +15,22 @@ import org.tmatesoft.svn.core.SVNLogEntryPath; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; +import javax.xml.bind.JAXBException; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlValue; import java.io.File; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author Konstantin Kolosovsky. */ public class CmdHistoryClient extends BaseSvnClient implements HistoryClient { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.CmdHistoryClient"); - @Override public void doLog(@NotNull File path, @NotNull SVNRevision startRevision, @@ -47,10 +43,6 @@ public class CmdHistoryClient extends BaseSvnClient implements HistoryClient { @Nullable String[] revisionProperties, @Nullable ISVNLogEntryHandler handler) throws VcsException { // TODO: add revision properties parameter if necessary - // TODO: svn log command supports --xml option - could update parsing to use xml format - - // TODO: after merge remove setting includeMergedRevisions to false and update parsing - includeMergedRevisions = false; List parameters = prepareCommand(path, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions, limit); @@ -59,18 +51,39 @@ public class CmdHistoryClient extends BaseSvnClient implements HistoryClient { SvnCommand command = CommandUtil.execute(myVcs, SvnTarget.fromFile(path, pegRevision), SvnCommandName.log, parameters, null); // TODO: handler should be called in parallel with command execution, but this will be in other thread // TODO: check if that is ok for current handler implementation - parseOutput(handler, command); + parseOutput(command, handler); } catch (SVNException e) { throw new VcsException(e); } } - private static void parseOutput(@Nullable ISVNLogEntryHandler handler, @NotNull SvnCommand command) + private static void parseOutput(@NotNull SvnCommand command, @Nullable ISVNLogEntryHandler handler) throws VcsException, SVNException { - Parser parser = new Parser(handler); - for (String line : StringUtil.splitByLines(command.getOutput(), false)) { - parser.onLine(line); + try { + LogInfo log = CommandUtil.parse(command.getOutput(), LogInfo.class); + + if (handler != null && log != null) { + for (LogEntry entry : log.entries) { + iterateRecursively(entry, handler); + } + } + } + catch (JAXBException e) { + throw new VcsException(e); + } + } + + private static void iterateRecursively(@NotNull LogEntry entry, @NotNull ISVNLogEntryHandler handler) throws SVNException { + handler.handleLogEntry(entry.toLogEntry()); + + for (LogEntry childEntry : entry.childEntries) { + iterateRecursively(childEntry, handler); + } + + if (entry.hasChildren()) { + // empty log entry passed to handler to fully correspond to SVNKit behavior. + handler.handleLogEntry(SVNLogEntry.EMPTY_ENTRY); } } @@ -92,133 +105,90 @@ public class CmdHistoryClient extends BaseSvnClient implements HistoryClient { parameters.add("--limit"); parameters.add(String.valueOf(limit)); } + parameters.add("--xml"); return parameters; } - private static class Parser { - private static final String REVISION = "\\s*r(\\d+)\\s*"; - private static final String AUTHOR = "\\s*([^|]*)\\s*"; - private static final String DATE = "\\s*([^|]*)\\s*"; - private static final String MESSAGE_LINES = "\\s*(\\d+).*"; + @XmlRootElement(name = "log") + public static class LogInfo { - private static final Pattern ENTRY_START = Pattern.compile("-+"); - private static final Pattern DETAILS = Pattern.compile(REVISION + "\\|" + AUTHOR + "\\|" + DATE + "\\|" + MESSAGE_LINES); + @XmlElement(name = "logentry") + public List entries = new ArrayList(); + } - private static final String STATUS = "\\s*(\\w)"; - private static final String PATH = "\\s*(.*?)\\s*"; - private static final String COPY_FROM_PATH = "(/[^:]*)"; - private static final String COPY_FROM_REVISION = "(\\d+)\\))\\s*"; - private static final String COPY_FROM_INFO = "((\\(from " + COPY_FROM_PATH + ":" + COPY_FROM_REVISION + ")?"; - private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + COPY_FROM_INFO); + public static class LogEntry { - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); + @XmlAttribute(name = "revision") + public long revision; - ISVNLogEntryHandler handler; + @XmlElement(name = "author") + public String author; - Entry entry; - boolean waitDetails; - boolean waitChangedPath; - boolean waitMessage; + @XmlElement(name = "date") + public Date date; - public Parser(@Nullable ISVNLogEntryHandler handler) { - this.handler = handler; - } + @XmlElement(name = "msg") + public String message; - public void onLine(@NotNull String line) throws VcsException, SVNException { - if (ENTRY_START.matcher(line).matches()) { - processEntryStart(); - } - else if (waitDetails) { - processDetails(line); - } - else if (waitMessage) { - processMessage(line); - } - else if (StringUtil.isEmpty(line.trim())) { - processChangedPathsFinished(); - } - else if (line.startsWith("Changed paths:")) { - processChangedPathsStarted(); - } - else if (waitChangedPath) { - processChangedPath(line); - } - else { - throw new VcsException("unknown state on line " + line); - } + @XmlElement(name = "paths") + public ChangedPaths changedPaths; + + @XmlElement(name = "logentry") + public List childEntries = new ArrayList(); + + public boolean hasChildren() { + return !childEntries.isEmpty(); } - private void processChangedPath(@NotNull String line) throws VcsException { - Matcher matcher = CHANGED_PATH.matcher(line); - if (!matcher.matches()) { - throw new VcsException("changed path not found in " + line); - } + public SVNLogEntry toLogEntry() { + SVNLogEntry entry = new SVNLogEntry(toChangedPathsMap(), revision, author, date, message); - String path = matcher.group(2); - char type = CommandUtil.getStatusChar(matcher.group(1)); - String copyPath = matcher.group(5); - long copyRevision = !StringUtil.isEmpty(matcher.group(6)) ? Long.valueOf(matcher.group(6)) : 0; + entry.setHasChildren(hasChildren()); - entry.changedPaths.put(path, new SVNLogEntryPath(path, type, copyPath, copyRevision)); + return entry; } - private void processChangedPathsStarted() { - waitChangedPath = true; + public Map toChangedPathsMap() { + return changedPaths != null ? changedPaths.toMap() : ContainerUtil.newHashMap(); } + } - private void processChangedPathsFinished() { - waitChangedPath = false; - waitMessage = true; - } + public static class ChangedPaths { - private void processMessage(@NotNull String line) { - entry.message.append(line); - entry.message.append(LineSeparator.LF.getSeparatorString()); - } + @XmlElement(name = "path") + public List changedPaths = new ArrayList(); - private void processDetails(@NotNull String line) throws VcsException { - Matcher matcher = DETAILS.matcher(line); - if (!matcher.matches()) { - throw new VcsException("details not found in " + line); + public Map toMap() { + Map changes = ContainerUtil.newHashMap(); + + for (ChangedPath path : changedPaths) { + changes.put(path.path, path.toLogEntryPath()); } - entry.revision = Long.valueOf(matcher.group(1)); - entry.author = matcher.group(2).trim(); - entry.date = tryGetDate(matcher.group(3)); - waitDetails = false; + return changes; } + } - private void processEntryStart() throws SVNException { - if (entry != null) { - handler.handleLogEntry(entry.toLogEntry()); - } - entry = new Entry(); - waitDetails = true; - waitMessage = false; - } + public static class ChangedPath { - private static Date tryGetDate(@NotNull String value) { - Date result = null; - try { - result = DATE_FORMAT.parse(value); - } - catch (ParseException e) { - LOG.debug(e); - } - return result; - } + @XmlAttribute(name = "kind") + public String kind; - private static class Entry { - Map changedPaths = new HashMap(); - long revision; - String author; - Date date; - StringBuilder message = new StringBuilder(); + @XmlAttribute(name = "action") + public String action; - private SVNLogEntry toLogEntry() { - return new SVNLogEntry(changedPaths, revision, author, date, message.toString()); - } + @XmlAttribute(name = "copyfrom-path") + public String copyFromPath; + + @XmlAttribute(name = "copyfrom-rev") + public long copyFromRevision; + + @XmlValue + public String path; + + public SVNLogEntryPath toLogEntryPath() { + return new SVNLogEntryPath(path, CommandUtil.getStatusChar(action), copyFromPath, copyFromRevision); } } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java index d67e29b598a0..f45a2942b269 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java @@ -36,13 +36,14 @@ import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.SvnPropertyKeys; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.SvnVcs; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNPropertyValue; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.SVNRevision; -import org.tmatesoft.svn.core.wc.SVNWCClient; +import org.tmatesoft.svn.core.wc2.SvnTarget; /** * Created with IntelliJ IDEA. @@ -133,7 +134,6 @@ public class SvnEditCommitMessageAction extends AnAction { @Override public void run(@NotNull ProgressIndicator indicator) { - final SVNWCClient client = myVcs.createWCClient(); final String url = myLocation.getURL(); final SVNURL root; try { @@ -142,12 +142,16 @@ public class SvnEditCommitMessageAction extends AnAction { myException = new VcsException("Can not determine repository root for URL: " + url); return; } - client.doSetRevisionProperty(root, SVNRevision.create(myNumber), "svn:log", - SVNPropertyValue.create(myNewMessage), false, null); + SvnTarget target = SvnTarget.fromURL(root); + myVcs.getFactory(target).createPropertyClient() + .setRevisionProperty(target, SvnPropertyKeys.LOG, SVNRevision.create(myNumber), SVNPropertyValue.create(myNewMessage), false); } catch (SVNException e) { myException = new VcsException(e); } + catch (VcsException e) { + myException = e; + } } @Override diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java index 44870c11f6a6..a4299991af6c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java @@ -20,6 +20,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.openapi.vcs.VcsException; @@ -42,7 +43,9 @@ import org.jetbrains.idea.svn.*; import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.internal.util.SVNPathUtil; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; -import org.tmatesoft.svn.core.wc.*; +import org.tmatesoft.svn.core.wc.SVNInfo; +import org.tmatesoft.svn.core.wc.SVNLogClient; +import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.util.SVNLogType; import javax.swing.*; @@ -502,6 +505,8 @@ public class SvnHistoryProvider } SVNLogEntryPath entryPath = null; String copyPath = null; + final int mergeLevel = svnLogEntryIntegerPair.getSecond(); + if (! myLastPathCorrector.isRoot()) { myLastPathCorrector.handleLogEntry(logEntry); entryPath = myLastPathCorrector.getDirectlyMentioned(); @@ -511,11 +516,16 @@ public class SvnHistoryProvider } else { // if there are no path with exact match, check whether parent or child paths had changed // "entry path" is allowed to be null now; if it is null, last path would be taken for revision construction - if (! checkForChildChanges(logEntry) && ! checkForParentChanges(logEntry)) return; + + // Separate SVNLogEntry is issued for each "merge source" revision. These "merge source" revisions are treated as child + // revisions of some other revision - this way we construct merge hierarchy. + // mergeLevel >= 0 indicates that we are currently processing some "merge source" revision. This "merge source" revision + // contains changes from some other branch - so checkForChildChanges() and checkForParentChanges() return "false". + // Because of this case we apply these methods only for non-"merge source" revisions - this means mergeLevel < 0. + if (mergeLevel < 0 && !checkForChildChanges(logEntry) && !checkForParentChanges(logEntry)) return; } } - final int mergeLevel = svnLogEntryIntegerPair.getSecond(); final SvnFileRevision revision = createRevision(logEntry, copyPath, entryPath); if (mergeLevel >= 0) { addToListByLevel((SvnFileRevision)myPrevious, revision, mergeLevel); @@ -608,7 +618,47 @@ public class SvnHistoryProvider } } - private class MergeSourceColumnInfo extends ColumnInfo { + private static class RevisionMergeSourceInfo { + + @NotNull private final VcsFileRevision revision; + + private RevisionMergeSourceInfo(@NotNull VcsFileRevision revision) { + this.revision = revision; + } + + @NotNull + public SvnFileRevision getRevision() { + return (SvnFileRevision)revision; + } + + // will be used, for instance, while copying (to clipboard) data from table + @Override + public String toString() { + return toString(revision); + } + + private static String toString(@Nullable VcsFileRevision value) { + if (!(value instanceof SvnFileRevision)) return ""; + final SvnFileRevision revision = (SvnFileRevision)value; + final List mergeSources = revision.getMergeSources(); + if (mergeSources.isEmpty()) { + return ""; + } + final StringBuilder sb = new StringBuilder(); + for (SvnFileRevision source : mergeSources) { + if (sb.length() != 0) { + sb.append(", "); + } + sb.append(source.getRevisionNumber().asString()); + if (!source.getMergeSources().isEmpty()) { + sb.append("*"); + } + } + return sb.toString(); + } + } + + private class MergeSourceColumnInfo extends ColumnInfo { private final MergeSourceRenderer myRenderer; private MergeSourceColumnInfo(final SvnHistorySession session) { @@ -621,8 +671,8 @@ public class SvnHistoryProvider return myRenderer; } - public String valueOf(final VcsFileRevision vcsFileRevision) { - return vcsFileRevision == null ? "" : getText(vcsFileRevision); + public RevisionMergeSourceInfo valueOf(final VcsFileRevision vcsFileRevision) { + return vcsFileRevision != null ? new RevisionMergeSourceInfo(vcsFileRevision) : null; } public String getText(final VcsFileRevision vcsFileRevision) { @@ -673,8 +723,8 @@ public class SvnHistoryProvider int column = table.columnAtPoint(e.getPoint()); final Object value = table.getModel().getValueAt(row, column); - if (value instanceof SvnFileRevision) { - return (SvnFileRevision)value; + if (value instanceof RevisionMergeSourceInfo) { + return ((RevisionMergeSourceInfo)value).getRevision(); } return null; } @@ -700,23 +750,7 @@ public class SvnHistoryProvider } public String getText(final VcsFileRevision value) { - if (!(value instanceof SvnFileRevision)) return ""; - final SvnFileRevision revision = (SvnFileRevision)value; - final List mergeSources = revision.getMergeSources(); - if (mergeSources.isEmpty()) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - for (SvnFileRevision source : mergeSources) { - if (sb.length() != 0) { - sb.append(", "); - } - sb.append(source.getRevisionNumber().asString()); - if (!source.getMergeSources().isEmpty()) { - sb.append("*"); - } - } - return sb.toString(); + return RevisionMergeSourceInfo.toString(value); } protected void customizeCellRenderer(final JTable table, @@ -729,22 +763,17 @@ public class SvnHistoryProvider myListener = new MergeSourceDetailsLinkListener(MERGE_SOURCE_DETAILS_TAG, myFile); myListener.installOn(table); } - if (value instanceof String) { - append((String)value, SimpleTextAttributes.REGULAR_ATTRIBUTES); - return; - } - if (!(value instanceof SvnFileRevision)) { + appendMergeSourceText(table, row, column, value instanceof RevisionMergeSourceInfo ? value.toString() : null); + } + + private void appendMergeSourceText(JTable table, int row, int column, @Nullable String text) { + if (StringUtil.isEmpty(text)) { append("", SimpleTextAttributes.REGULAR_ATTRIBUTES); - return; } - final SvnFileRevision revision = (SvnFileRevision)value; - final String text = getText(revision); - if (text.length() == 0) { - append("", SimpleTextAttributes.REGULAR_ATTRIBUTES); - return; + else { + append(cutString(text, table.getCellRect(row, column, false).getWidth()), SimpleTextAttributes.REGULAR_ATTRIBUTES, + MERGE_SOURCE_DETAILS_TAG); } - - append(cutString(text, table.getCellRect(row, column, false).getWidth()), SimpleTextAttributes.REGULAR_ATTRIBUTES); } private String cutString(final String text, final double value) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java index 5b76f6af01c6..2bd8627de196 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/ignore/SvnPropertyService.java @@ -15,28 +15,24 @@ */ package org.jetbrains.idea.svn.ignore; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnPropertyKeys; import org.jetbrains.idea.svn.SvnVcs; import org.tmatesoft.svn.core.SVNDepth; -import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNPropertyValue; import org.tmatesoft.svn.core.wc.SVNPropertyData; import org.tmatesoft.svn.core.wc.SVNRevision; -import org.tmatesoft.svn.core.wc.SVNWCClient; +import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; import java.util.*; public class SvnPropertyService { - private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.ignore.SvnPropertyService"); private SvnPropertyService() { } @@ -67,22 +63,23 @@ public class SvnPropertyService { private static abstract class IgnorePropertyWorkTemplate { protected final SvnVcs myVcs; - protected final SVNWCClient myClient; protected final Project myProject; protected final boolean myUseCommonExtension; protected final boolean myCanUseCachedProperty; protected abstract void processFolder(final VirtualFile folder, final File folderDir, final Set data, - final SVNPropertyValue propertyValue) throws SVNException; + final SVNPropertyValue propertyValue) throws VcsException; + protected abstract void onAfterProcessing(final VirtualFile[] file) throws VcsException; - protected abstract void onSVNException(SVNException e); + + protected abstract void onSVNException(Exception e); + protected abstract boolean stopIteration(); private IgnorePropertyWorkTemplate(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension, final boolean canUseCachedProperty) { myVcs = activeVcs; myCanUseCachedProperty = canUseCachedProperty; - myClient = activeVcs.createWCClient(); myProject = project; myUseCommonExtension = useCommonExtension; } @@ -100,12 +97,13 @@ public class SvnPropertyService { value = myVcs.getPropertyWithCaching(entry.getKey(), SvnPropertyKeys.SVN_IGNORE); } else { final SVNPropertyData data = - myVcs.createWCClient().doGetProperty(dir, SvnPropertyKeys.SVN_IGNORE, SVNRevision.UNDEFINED, SVNRevision.WORKING); + myVcs.getFactory(dir).createPropertyClient() + .getProperty(SvnTarget.fromFile(dir), SvnPropertyKeys.SVN_IGNORE, false, SVNRevision.WORKING); value = data == null ? null : data.getValue(); } processFolder(entry.getKey(), dir, entry.getValue(), value); } - catch (SVNException e) { + catch (VcsException e) { onSVNException(e); } } @@ -113,28 +111,6 @@ public class SvnPropertyService { } } - @Nullable - public static Set getIgnoreStringsUnder(final SvnVcs vcs, final VirtualFile dir) { - try { - final SVNPropertyData data = vcs.createWCClient().doGetProperty(new File(dir.getPath()), SvnPropertyKeys.SVN_IGNORE, SVNRevision.WORKING, SVNRevision.WORKING); - final SVNPropertyValue value = (data == null) ? null : data.getValue(); - if (value != null) { - final Set ignorePatterns = new HashSet(); - final String propAsString = SVNPropertyValue.getPropertyAsString(value); - final StringTokenizer st = new StringTokenizer(propAsString, "\r\n "); - while (st.hasMoreElements()) { - final String ignorePattern = (String) st.nextElement(); - ignorePatterns.add(ignorePattern); - } - return ignorePatterns; - } - } - catch (SVNException e) { - LOG.info(e); - } - return null; - } - private static class IgnorePropertyChecker extends IgnorePropertyWorkTemplate { private final String myExtensionPattern; private boolean myFilesOk; @@ -152,7 +128,7 @@ public class SvnPropertyService { } protected void processFolder(final VirtualFile folder, final File folderDir, final Set data, final SVNPropertyValue propertyValue) - throws SVNException { + throws VcsException { if (propertyValue == null) { myFilesOk = false; myExtensionOk = false; @@ -176,7 +152,7 @@ public class SvnPropertyService { protected void onAfterProcessing(final VirtualFile[] file) throws VcsException { } - protected void onSVNException(final SVNException e) { + protected void onSVNException(final Exception e) { myFilesOk = false; myExtensionOk = false; } @@ -207,10 +183,11 @@ public class SvnPropertyService { protected abstract String getNewPropertyValue(final Set data, final SVNPropertyValue propertyValue); protected void processFolder(final VirtualFile folder, final File folderDir, final Set data, final SVNPropertyValue propertyValue) - throws SVNException { + throws VcsException { String newValue = getNewPropertyValue(data, propertyValue); newValue = (newValue.trim().isEmpty()) ? null : newValue; - myClient.doSetProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), false, false, null); + myVcs.getFactory(folderDir).createPropertyClient() + .setProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(newValue), SVNDepth.EMPTY, false); if (myUseCommonExtension) { dirtyScopeManager.dirDirtyRecursively(folder); @@ -229,7 +206,7 @@ public class SvnPropertyService { } } - protected void onSVNException(final SVNException e) { + protected void onSVNException(final Exception e) { exceptions.add(e.getMessage()); } } @@ -247,21 +224,6 @@ public class SvnPropertyService { } } - public static void setIgnores(final SvnVcs vcs, final Collection patterns, final File file) - throws SVNException { - final SVNWCClient client = vcs.createWCClient(); - final StringBuilder sb = new StringBuilder(); - for (String pattern : patterns) { - sb.append(pattern).append('\n'); - } - if (! patterns.isEmpty()) { - final String value = sb.toString(); - client.doSetProperty(file, SvnPropertyKeys.SVN_IGNORE, SVNPropertyValue.create(value), false, SVNDepth.EMPTY, null, null); - } else { - client.doSetProperty(file, SvnPropertyKeys.SVN_IGNORE, null, false, SVNDepth.EMPTY, null, null); - } - } - private static String getNewPropertyValueForRemove(final Collection data, @NotNull final String propertyValue) { final StringBuilder sb = new StringBuilder(); final StringTokenizer st = new StringTokenizer(propertyValue, "\r\n "); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java deleted file mode 100644 index d69a47b2ec70..000000000000 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.svn.portable; - -import org.tmatesoft.svn.core.SVNDepth; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNURL; -import org.tmatesoft.svn.core.wc.ISVNEventHandler; -import org.tmatesoft.svn.core.wc.SVNRevision; -import org.tmatesoft.svn.core.wc.SVNUpdateClient; - -import java.io.File; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 2/1/12 - * Time: 12:11 PM - */ -public class SvnSvnkitUpdateClient implements SvnUpdateClientI { - private final SVNUpdateClient myClient; - private ISVNEventHandler myDispatcher; - - public SvnSvnkitUpdateClient(SVNUpdateClient client) { - myClient = client; - } - - @Override - public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException { - return myClient.doUpdate(file, revision, recursive); - } - - @Override - public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException { - return myClient.doUpdate(file, revision, recursive, force); - } - - @Override - public long[] doUpdate(File[] paths, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, - boolean depthIsSticky) throws SVNException { - return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky); - } - - @Override - public long[] doUpdate(File[] paths, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, - boolean depthIsSticky, - boolean makeParents) throws SVNException { - return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents); - } - - @Override - public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) - throws SVNException { - return myClient.doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky); - } - - @Override - public void setUpdateLocksOnDemand(boolean locksOnDemand) { - myClient.setUpdateLocksOnDemand(locksOnDemand); - } - - @Override - public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException { - return myClient.doSwitch(file, url, revision, recursive); - } - - @Override - public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException { - return myClient.doSwitch(file, url, pegRevision, revision, recursive); - } - - @Override - public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) - throws SVNException { - return myClient.doSwitch(file, url, pegRevision, revision, recursive, force); - } - - @Override - public long doSwitch(File path, - SVNURL url, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException { - return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky); - } - - @Override - public long doSwitch(File path, - SVNURL url, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException { - return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry); - } - - @Override - public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException { - return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive); - } - - @Override - public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) - throws SVNException { - return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive, force); - } - - @Override - public long doCheckout(SVNURL url, - File dstPath, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - boolean allowUnversionedObstructions) throws SVNException { - return myClient.doCheckout(url, dstPath, pegRevision, revision, depth, allowUnversionedObstructions); - } - - @Override - public long doExport(SVNURL url, - File dstPath, - SVNRevision pegRevision, - SVNRevision revision, - String eolStyle, - boolean force, - boolean recursive) throws SVNException { - return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive); - } - - @Override - public long doExport(SVNURL url, - File dstPath, - SVNRevision pegRevision, - SVNRevision revision, - String eolStyle, - boolean overwrite, - SVNDepth depth) throws SVNException { - return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, overwrite, depth); - } - - @Override - public long doExport(File srcPath, - File dstPath, - SVNRevision pegRevision, - SVNRevision revision, - String eolStyle, - boolean force, - boolean recursive) throws SVNException { - return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, force, recursive); - } - - @Override - public long doExport(File srcPath, - File dstPath, - SVNRevision pegRevision, - SVNRevision revision, - String eolStyle, - boolean overwrite, - SVNDepth depth) throws SVNException { - return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, overwrite, depth); - } - - @Override - public void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException { - myClient.doRelocate(dst, oldURL, newURL, recursive); - } - - @Override - public void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException { - myClient.doCanonicalizeURLs(dst, omitDefaultPort, recursive); - } - - @Override - public void setExportExpandsKeywords(boolean expand) { - myClient.setExportExpandsKeywords(expand); - } - - @Override - public void setEventHandler(ISVNEventHandler dispatcher) { - myDispatcher = dispatcher; - myClient.setEventHandler(dispatcher); - } - - @Override - public void setIgnoreExternals(boolean ignoreExternals) { - myClient.setIgnoreExternals(ignoreExternals); - } - - public ISVNEventHandler getEventHandler() { - return myDispatcher; - } -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java deleted file mode 100644 index 8eaafa4c8034..000000000000 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.idea.svn.portable; - -import org.tmatesoft.svn.core.SVNDepth; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNURL; -import org.tmatesoft.svn.core.wc.ISVNEventHandler; -import org.tmatesoft.svn.core.wc.SVNRevision; - -import java.io.File; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 2/1/12 - * Time: 11:59 AM - */ -public interface SvnUpdateClientI extends SvnMarkerInterface { - long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException; - - long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException; - - long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; - - long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException; - - long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; - - void setUpdateLocksOnDemand(boolean locksOnDemand); - - long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException; - - long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException; - - long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException; - - long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; - - long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException; - - long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException; - - long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException; - - long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions) throws SVNException; - - long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException; - - long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException; - - long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException; - - long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException; - - void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException; - - void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException; - - void setExportExpandsKeywords(boolean expand); - void setEventHandler(ISVNEventHandler dispatcher); - void setIgnoreExternals(boolean ignoreExternals); -} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java index 973058fe3f1b..036de6b785be 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnWcClientI.java @@ -19,7 +19,6 @@ import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.wc.*; import java.io.File; -import java.io.OutputStream; import java.util.Collection; /** @@ -29,67 +28,7 @@ import java.util.Collection; * Time: 6:54 PM */ public interface SvnWcClientI extends SvnMarkerInterface { - void setAddParameters(ISVNAddParameters addParameters); - ISVNCommitHandler getCommitHandler(); - void setCommitHandler(ISVNCommitHandler handler); - void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision, - boolean expandKeywords, OutputStream dst) throws SVNException; - void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision, - boolean expandKeywords, OutputStream dst) throws SVNException; - void doCleanup(File path) throws SVNException; - void doCleanup(File path, boolean deleteWCProperties) throws SVNException; - void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean skipChecks, - SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException; - void doSetProperty(File path, ISVNPropertyValueProvider propertyValueProvider, boolean skipChecks, - SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException; - SVNCommitInfo doSetProperty(SVNURL url, String propName, SVNPropertyValue propValue, - SVNRevision baseRevision, String commitMessage, SVNProperties revisionProperties, - boolean skipChecks, ISVNPropertyHandler handler) throws SVNException; - void doSetRevisionProperty(File path, SVNRevision revision, String propName, - SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException; - void doSetRevisionProperty(SVNURL url, SVNRevision revision, String propName, - SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException; - SVNPropertyData doGetProperty( File path, String propName, SVNRevision pegRevision, - SVNRevision revision) throws SVNException; - SVNPropertyData doGetProperty( SVNURL url, String propName, SVNRevision pegRevision, - SVNRevision revision) throws SVNException; - void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision, - boolean recursive, ISVNPropertyHandler handler) throws SVNException; - void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision, - SVNDepth depth, ISVNPropertyHandler handler, Collection changeLists) throws SVNException; - void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision, - boolean recursive, ISVNPropertyHandler handler) throws SVNException; - void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision, - SVNDepth depth, ISVNPropertyHandler handler) throws SVNException; - void doGetRevisionProperty(File path, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException; - long doGetRevisionProperty(SVNURL url, String propName, SVNRevision revision, - ISVNPropertyHandler handler) throws SVNException; - void doDelete(File path, boolean force, boolean dryRun) throws SVNException; - void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException; - void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, - boolean recursive) throws SVNException; - void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, - boolean recursive, boolean includeIgnored) throws SVNException; - void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, - SVNDepth depth, boolean includeIgnored, boolean makeParents) throws SVNException; - void doAdd(File[] paths, boolean force, boolean mkdir, boolean climbUnversionedParents, - SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException; - void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, - SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException; - void doMarkReplaced(File path) throws SVNException; - void doRevert(File path, boolean recursive) throws SVNException; - void doRevert(File[] paths, boolean recursive) throws SVNException; - void doRevert(File[] paths, SVNDepth depth, Collection changeLists) throws SVNException; - void doResolve(File path, boolean recursive) throws SVNException; - void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException; - void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties, - SVNConflictChoice conflictChoice) throws SVNException; - void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties, - boolean resolveTree, SVNConflictChoice conflictChoice) throws SVNException; - void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException; - void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException; - void doUnlock(File[] paths, boolean breakLock) throws SVNException; - void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException; + void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException; void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException; void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, @@ -97,12 +36,6 @@ public interface SvnWcClientI extends SvnMarkerInterface { void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException; void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, ISVNInfoHandler handler) throws SVNException; - String doGetWorkingCopyID( File path, String trailURL) throws SVNException; - String doGetWorkingCopyID( File path, String trailURL, boolean committed) throws SVNException; SVNInfo doInfo(File path, SVNRevision revision) throws SVNException; SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException; - void doCleanupWCProperties(File directory) throws SVNException; - void doSetWCFormat(File directory, int format) throws SVNException; - void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean force, - boolean recursive, ISVNPropertyHandler handler) throws SVNException; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java index ddc77840bc84..07edfa25fa61 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnStatusClient.java @@ -15,6 +15,9 @@ */ package org.jetbrains.idea.svn.portable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.SvnVcs; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.ISVNStatusHandler; @@ -32,16 +35,19 @@ import java.util.Collection; * Time: 9:47 AM */ public class SvnkitSvnStatusClient implements SvnStatusClientI { - private final SVNStatusClient myStatusClient; - public SvnkitSvnStatusClient(SVNStatusClient statusClient) { + @Nullable private final SVNStatusClient myStatusClient; + @NotNull private final SvnVcs myVcs; + + public SvnkitSvnStatusClient(@NotNull SvnVcs vcs, @Nullable SVNStatusClient statusClient) { + myVcs = vcs; myStatusClient = statusClient; } @Override public long doStatus(File path, boolean recursive, boolean remote, boolean reportAll, boolean includeIgnored, ISVNStatusHandler handler) throws SVNException { - return myStatusClient.doStatus(path, recursive, remote, reportAll, includeIgnored, handler); + return getStatusClient().doStatus(path, recursive, remote, reportAll, includeIgnored, handler); } @Override @@ -52,7 +58,7 @@ public class SvnkitSvnStatusClient implements SvnStatusClientI { boolean includeIgnored, boolean collectParentExternals, ISVNStatusHandler handler) throws SVNException { - return myStatusClient.doStatus(path, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler); + return getStatusClient().doStatus(path, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler); } @Override @@ -64,7 +70,7 @@ public class SvnkitSvnStatusClient implements SvnStatusClientI { boolean includeIgnored, boolean collectParentExternals, ISVNStatusHandler handler) throws SVNException { - return myStatusClient.doStatus(path, revision, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler); + return getStatusClient().doStatus(path, revision, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler); } @Override @@ -77,16 +83,22 @@ public class SvnkitSvnStatusClient implements SvnStatusClientI { boolean collectParentExternals, ISVNStatusHandler handler, Collection changeLists) throws SVNException { - return myStatusClient.doStatus(path, revision, depth, remote, reportAll, includeIgnored, collectParentExternals, handler, changeLists); + return getStatusClient() + .doStatus(path, revision, depth, remote, reportAll, includeIgnored, collectParentExternals, handler, changeLists); } @Override public SVNStatus doStatus(File path, boolean remote) throws SVNException { - return myStatusClient.doStatus(path, remote); + return getStatusClient().doStatus(path, remote); } @Override public SVNStatus doStatus(File path, boolean remote, boolean collectParentExternals) throws SVNException { - return myStatusClient.doStatus(path, remote, collectParentExternals); + return getStatusClient().doStatus(path, remote, collectParentExternals); + } + + @NotNull + private SVNStatusClient getStatusClient() { + return myStatusClient != null ? myStatusClient : myVcs.createStatusClient(); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java index 4b0076d0952c..faee8ecc3cb2 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnkitSvnWcClient.java @@ -21,7 +21,6 @@ import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.wc.*; import java.io.File; -import java.io.OutputStream; import java.util.Collection; /** @@ -42,279 +41,6 @@ public class SvnkitSvnWcClient implements SvnWcClientI { return myVcs.createWCClient(); } - @Override - public void setAddParameters(ISVNAddParameters addParameters) { - getClient().setAddParameters(addParameters); - } - - @Override - public ISVNCommitHandler getCommitHandler() { - return getClient().getCommitHandler(); - } - - @Override - public void setCommitHandler(ISVNCommitHandler handler) { - getClient().setCommitHandler(handler); - } - - @Override - public void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst) - throws SVNException { - getClient().doGetFileContents(path, pegRevision, revision, expandKeywords, dst); - } - - @Override - public void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst) - throws SVNException { - getClient().doGetFileContents(url, pegRevision, revision, expandKeywords, dst); - } - - @Override - public void doCleanup(File path) throws SVNException { - getClient().doCleanup(path); - } - - @Override - public void doCleanup(File path, boolean deleteWCProperties) throws SVNException { - getClient().doCleanup(path, deleteWCProperties); - } - - @Override - public void doSetProperty(File path, - String propName, - SVNPropertyValue propValue, - boolean skipChecks, - SVNDepth depth, - ISVNPropertyHandler handler, - Collection changeLists) throws SVNException { - getClient().doSetProperty(path, propName, propValue, skipChecks, depth, handler, changeLists); - } - - @Override - public void doSetProperty(File path, - ISVNPropertyValueProvider propertyValueProvider, - boolean skipChecks, - SVNDepth depth, - ISVNPropertyHandler handler, - Collection changeLists) throws SVNException { - getClient().doSetProperty(path, propertyValueProvider, skipChecks, depth, handler, changeLists); - } - - @Override - public SVNCommitInfo doSetProperty(SVNURL url, - String propName, - SVNPropertyValue propValue, - SVNRevision baseRevision, - String commitMessage, - SVNProperties revisionProperties, - boolean skipChecks, - ISVNPropertyHandler handler) throws SVNException { - return getClient().doSetProperty(url, propName, propValue, baseRevision, commitMessage, revisionProperties, skipChecks, handler); - } - - @Override - public void doSetRevisionProperty(File path, - SVNRevision revision, - String propName, - SVNPropertyValue propValue, - boolean force, - ISVNPropertyHandler handler) throws SVNException { - getClient().doSetRevisionProperty(path, revision, propName, propValue, force, handler); - } - - @Override - public void doSetRevisionProperty(SVNURL url, - SVNRevision revision, - String propName, - SVNPropertyValue propValue, - boolean force, - ISVNPropertyHandler handler) throws SVNException { - getClient().doSetRevisionProperty(url, revision, propName, propValue, force, handler); - } - - @Override - public SVNPropertyData doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException { - return getClient().doGetProperty(path, propName, pegRevision, revision); - } - - @Override - public SVNPropertyData doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException { - return getClient().doGetProperty(url, propName, pegRevision, revision); - } - - @Override - public void doGetProperty(File path, - String propName, - SVNRevision pegRevision, - SVNRevision revision, - boolean recursive, - ISVNPropertyHandler handler) throws SVNException { - getClient().doGetProperty(path, propName, pegRevision, revision, recursive, handler); - } - - @Override - public void doGetProperty(File path, - String propName, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - ISVNPropertyHandler handler, - Collection changeLists) throws SVNException { - getClient().doGetProperty(path, propName, pegRevision, revision, depth, handler, changeLists); - } - - @Override - public void doGetProperty(SVNURL url, - String propName, - SVNRevision pegRevision, - SVNRevision revision, - boolean recursive, - ISVNPropertyHandler handler) throws SVNException { - getClient().doGetProperty(url, propName, pegRevision, revision, recursive, handler); - } - - @Override - public void doGetProperty(SVNURL url, - String propName, - SVNRevision pegRevision, - SVNRevision revision, - SVNDepth depth, - ISVNPropertyHandler handler) throws SVNException { - getClient().doGetProperty(url, propName, pegRevision, revision, depth, handler); - } - - @Override - public void doGetRevisionProperty(File path, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException { - getClient().doGetRevisionProperty(path, propName, revision, handler); - } - - @Override - public long doGetRevisionProperty(SVNURL url, String propName, SVNRevision revision, ISVNPropertyHandler handler) throws SVNException { - return getClient().doGetRevisionProperty(url, propName, revision, handler); - } - - @Override - public void doDelete(File path, boolean force, boolean dryRun) throws SVNException { - getClient().doDelete(path, force, dryRun); - } - - @Override - public void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException { - getClient().doDelete(path, force, deleteFiles, dryRun); - } - - @Override - public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive) throws SVNException { - getClient().doAdd(path, force, mkdir, climbUnversionedParents, recursive); - } - - @Override - public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive, boolean includeIgnored) - throws SVNException { - getClient().doAdd(path, force, mkdir, climbUnversionedParents, recursive, includeIgnored); - } - - @Override - public void doAdd(File path, - boolean force, - boolean mkdir, - boolean climbUnversionedParents, - SVNDepth depth, - boolean includeIgnored, - boolean makeParents) throws SVNException { - getClient().doAdd(path, force, mkdir, climbUnversionedParents, depth, includeIgnored, makeParents); - } - - @Override - public void doAdd(File[] paths, - boolean force, - boolean mkdir, - boolean climbUnversionedParents, - SVNDepth depth, - boolean depthIsSticky, - boolean includeIgnored, - boolean makeParents) throws SVNException { - getClient().doAdd(paths, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents); - } - - @Override - public void doAdd(File path, - boolean force, - boolean mkdir, - boolean climbUnversionedParents, - SVNDepth depth, - boolean depthIsSticky, - boolean includeIgnored, - boolean makeParents) throws SVNException { - getClient().doAdd(path, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents); - } - - @Override - public void doMarkReplaced(File path) throws SVNException { - getClient().doMarkReplaced(path); - } - - @Override - public void doRevert(File path, boolean recursive) throws SVNException { - getClient().doRevert(path, recursive); - } - - @Override - public void doRevert(File[] paths, boolean recursive) throws SVNException { - getClient().doRevert(paths, recursive); - } - - @Override - public void doRevert(File[] paths, SVNDepth depth, Collection changeLists) throws SVNException { - getClient().doRevert(paths, depth, changeLists); - } - - @Override - public void doResolve(File path, boolean recursive) throws SVNException { - getClient().doResolve(path, recursive); - } - - @Override - public void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException { - getClient().doResolve(path, depth, conflictChoice); - } - - @Override - public void doResolve(File path, SVNDepth depth, boolean resolveContents, boolean resolveProperties, SVNConflictChoice conflictChoice) - throws SVNException { - getClient().doResolve(path, depth, resolveContents, resolveProperties, conflictChoice); - } - - @Override - public void doResolve(File path, - SVNDepth depth, - boolean resolveContents, - boolean resolveProperties, - boolean resolveTree, - SVNConflictChoice conflictChoice) throws SVNException { - getClient().doResolve(path, depth, resolveContents, resolveProperties, resolveTree, conflictChoice); - } - - @Override - public void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException { - getClient().doLock(paths, stealLock, lockMessage); - } - - @Override - public void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException { - getClient().doLock(urls, stealLock, lockMessage); - } - - @Override - public void doUnlock(File[] paths, boolean breakLock) throws SVNException { - getClient().doUnlock(paths, breakLock); - } - - @Override - public void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException { - getClient().doUnlock(urls, breakLock); - } - @Override public void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException { getClient().doInfo(path, revision, recursive, handler); @@ -348,16 +74,6 @@ public class SvnkitSvnWcClient implements SvnWcClientI { getClient().doInfo(url, pegRevision, revision, depth, handler); } - @Override - public String doGetWorkingCopyID(File path, String trailURL) throws SVNException { - return getClient().doGetWorkingCopyID(path, trailURL); - } - - @Override - public String doGetWorkingCopyID(File path, String trailURL, boolean committed) throws SVNException { - return getClient().doGetWorkingCopyID(path, trailURL, committed); - } - @Override public SVNInfo doInfo(File path, SVNRevision revision) throws SVNException { return getClient().doInfo(path, revision); @@ -367,24 +83,4 @@ public class SvnkitSvnWcClient implements SvnWcClientI { public SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException { return getClient().doInfo(url, pegRevision, revision); } - - @Override - public void doCleanupWCProperties(File directory) throws SVNException { - getClient().doCleanupWCProperties(directory); - } - - @Override - public void doSetWCFormat(File directory, int format) throws SVNException { - getClient().doSetWCFormat(directory, format); - } - - @Override - public void doSetProperty(File path, - String propName, - SVNPropertyValue propValue, - boolean force, - boolean recursive, - ISVNPropertyHandler handler) throws SVNException { - getClient().doSetProperty(path, propName, propValue, force, recursive, handler); - } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java index f6d2c56e7474..59ba154f4131 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java @@ -95,19 +95,47 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { @Nullable SVNPropertyValue value, @Nullable SVNDepth depth, boolean force) throws VcsException { + runSetProperty(SvnTarget.fromFile(file), property, null, depth, value, force); + } + + @Override + public void setRevisionProperty(@NotNull SvnTarget target, + @NotNull String property, + @NotNull SVNRevision revision, + @Nullable SVNPropertyValue value, + boolean force) throws VcsException { + runSetProperty(target, property, revision, null, value, force); + } + + private void runSetProperty(@NotNull SvnTarget target, + @NotNull String property, + @Nullable SVNRevision revision, + @Nullable SVNDepth depth, + @Nullable SVNPropertyValue value, + boolean force) throws VcsException { List parameters = new ArrayList(); boolean isDelete = value == null; parameters.add(property); + if (revision != null) { + parameters.add("--revprop"); + CommandUtil.put(parameters, revision); + } if (!isDelete) { parameters.add(SVNPropertyValue.getPropertyAsString(value)); // --force could only be used in "propset" command, but not in "propdel" command CommandUtil.put(parameters, force, "--force"); } - CommandUtil.put(parameters, file); + CommandUtil.put(parameters, target); CommandUtil.put(parameters, depth); - CommandUtil.execute(myVcs, SvnTarget.fromFile(file), isDelete ? SvnCommandName.propdel : SvnCommandName.propset, parameters, null); + // For some reason, command setting ignore property when working directory equals target directory (like + // "svn propset svn:ignore *.java . --depth empty") tries to set ignore also on child files and fails with error like + // "svn: E200009: Cannot set 'svn:ignore' on a file ('...File1.java')". So here we manually force home directory to be used. + // NOTE: that setting other properties (not svn:ignore) does not cause such error. + CommandUtil + .execute(myVcs, target, CommandUtil.getHomeDirectory(), isDelete ? SvnCommandName.propdel : SvnCommandName.propset, parameters, + null); } private void fillListParameters(@NotNull SvnTarget target, @@ -211,7 +239,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { // such behavior is required to compatibility with SVNKit as some logic in merge depends on // whether null property data or property data with empty string value is returned if (value != null) { - result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), null); + result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), LF_SEPARATOR_OPTIONS); } return result; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java index 2f1ba5ea7790..12bc0e9c885c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java @@ -1,11 +1,15 @@ package org.jetbrains.idea.svn.properties; import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.util.LineSeparator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.SvnClient; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNPropertyValue; +import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; +import org.tmatesoft.svn.core.wc.ISVNOptions; import org.tmatesoft.svn.core.wc.ISVNPropertyHandler; import org.tmatesoft.svn.core.wc.SVNPropertyData; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -18,6 +22,13 @@ import java.io.File; */ public interface PropertyClient extends SvnClient { + ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() { + @Override + public byte[] getNativeEOL() { + return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString()); + } + }; + @Nullable SVNPropertyData getProperty(@NotNull final SvnTarget target, @NotNull final String property, @@ -39,4 +50,10 @@ public interface PropertyClient extends SvnClient { @Nullable SVNPropertyValue value, @Nullable SVNDepth depth, boolean force) throws VcsException; + + void setRevisionProperty(@NotNull SvnTarget target, + @NotNull String property, + @NotNull SVNRevision revision, + @Nullable SVNPropertyValue value, + boolean force) throws VcsException; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java index ee72e59718ef..d55eb686371c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java @@ -31,9 +31,9 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien try { if (!revisionProperty) { if (target.isFile()) { - return myVcs.createWCClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision); + return createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision); } else { - return myVcs.createWCClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision); + return createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision); } } else { return getRevisionProperty(target, property, revision); @@ -44,6 +44,14 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien } } + @NotNull + private SVNWCClient createClient() { + SVNWCClient client = myVcs.createWCClient(); + client.setOptions(LF_SEPARATOR_OPTIONS); + + return client; + } + @Override public void getProperty(@NotNull SvnTarget target, @NotNull String property, @@ -68,7 +76,26 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien @Nullable SVNDepth depth, boolean force) throws VcsException { try { - myVcs.createWCClient().doSetProperty(file, property, value, force, depth, null, null); + createClient().doSetProperty(file, property, value, force, depth, null, null); + } + catch (SVNException e) { + throw new SvnBindException(e); + } + } + + @Override + public void setRevisionProperty(@NotNull SvnTarget target, + @NotNull String property, + @NotNull SVNRevision revision, + @Nullable SVNPropertyValue value, + boolean force) throws VcsException { + try { + if (target.isFile()) { + createClient().doSetRevisionProperty(target.getFile(), revision, property, value, force, null); + } + else { + createClient().doSetRevisionProperty(target.getURL(), revision, property, value, force, null); + } } catch (SVNException e) { throw new SvnBindException(e); @@ -80,7 +107,7 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien @Nullable SVNRevision revision, @Nullable SVNDepth depth, @Nullable ISVNPropertyHandler handler) throws VcsException { - SVNWCClient client = myVcs.createWCClient(); + SVNWCClient client = createClient(); try { if (target.isURL()) { @@ -94,7 +121,7 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien } private SVNPropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{ - final SVNWCClient client = myVcs.createWCClient(); + final SVNWCClient client = createClient(); final SVNPropertyData[] result = new SVNPropertyData[1]; ISVNPropertyHandler handler = new ISVNPropertyHandler() { @Override diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java index 72741cef4278..391077eb3e3b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java @@ -35,10 +35,7 @@ import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI; import com.intellij.openapi.vcs.changes.patch.ApplyPatchExecutor; import com.intellij.openapi.vcs.changes.patch.FilePatchInProgress; import com.intellij.openapi.vcs.changes.patch.PatchWriter; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileWrapper; +import com.intellij.openapi.vfs.*; import com.intellij.util.WaitForProgressToShow; import com.intellij.util.containers.MultiMap; @@ -79,7 +76,7 @@ public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor { new FileSaverDescriptor("Save patch to", ""), myProject); final VirtualFile baseDir = myProject.getBaseDir(); final VirtualFileWrapper save = dialog.save(baseDir, "TheirsChanges.patch"); - if (save != null && save.getFile() != null) { + if (save != null) { final CommitContext commitContext = new CommitContext(); final VirtualFile baseForPatch = myBaseForPatch == null ? baseDir : myBaseForPatch; @@ -107,7 +104,7 @@ public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor { for (Map.Entry> entry : patchGroups.entrySet()) { final VirtualFile vf = entry.getKey(); final String currBasePath = vf.getPath(); - final String relativePath = VfsUtil.getRelativePath(vf, baseDir, '/'); + final String relativePath = VfsUtilCore.getRelativePath(vf, baseDir, '/'); final boolean toConvert = !StringUtil.isEmptyOrSpaces(relativePath) && !".".equals(relativePath); for (FilePatchInProgress patchInProgress : entry.getValue()) { final TextFilePatch patch = patchInProgress.getPatch(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java new file mode 100644 index 000000000000..a6a4d0f2095f --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/CmdUpdateClient.java @@ -0,0 +1,187 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn.update; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.commandLine.BaseUpdateCommandListener; +import org.jetbrains.idea.svn.commandLine.CommandUtil; +import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient; +import org.jetbrains.idea.svn.commandLine.SvnCommandName; +import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.wc.SVNEvent; +import org.tmatesoft.svn.core.wc.SVNEventAction; +import org.tmatesoft.svn.core.wc.SVNInfo; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc2.SvnTarget; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 12:13 PM + */ +// TODO: Currently make inherit SVNKit update implementation not to duplicate setXxx() methods. +public class CmdUpdateClient extends SvnKitUpdateClient { + private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+"); + private static final String ourAuthenticationRealm = "Authentication realm:"; + + @Override + public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions, + final boolean depthIsSticky, final boolean makeParents) throws SVNException { + // since one revision is passed -> I assume same repository here + checkWorkingCopy(paths[0]); + + final List parameters = new ArrayList(); + + fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions); + CommandUtil.put(parameters, makeParents, "--parents"); + CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals"); + CommandUtil.put(parameters, paths); + + return run(paths, parameters, SvnCommandName.up); + } + + private void checkWorkingCopy(@NotNull File path) throws SVNException { + final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myVcs); + final SVNInfo info = infoClient.doInfo(path, SVNRevision.UNDEFINED); + + if (info == null || info.getURL() == null) { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, path.getPath())); + } + } + + private long[] run(@NotNull File[] paths, @NotNull List parameters, @NotNull SvnCommandName command) throws SVNException { + File base = paths[0]; + base = base.isDirectory() ? base : base.getParentFile(); + + final AtomicReference updatedToRevision = new AtomicReference(); + updatedToRevision.set(new long[0]); + + final BaseUpdateCommandListener listener = createCommandListener(paths, updatedToRevision, base); + try { + CommandUtil.execute(myVcs, SvnTarget.fromFile(base), command, parameters, listener); + } + catch (VcsException e) { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e)); + } + + listener.throwIfException(); + + return updatedToRevision.get(); + } + + private BaseUpdateCommandListener createCommandListener(final File[] paths, + final AtomicReference updatedToRevision, + final File base) { + return new BaseUpdateCommandListener(base, myDispatcher) { + final long[] myRevisions = new long[paths.length]; + + @Override + protected void beforeHandler(@NotNull SVNEvent event) { + if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) { + final long eventRevision = event.getRevision(); + for (int i = 0; i < paths.length; i++) { + final File path = paths[i]; + if (FileUtil.filesEqual(path, event.getFile())) { + myRevisions[i] = eventRevision; + break; + } + } + } + } + + @Override + public void processTerminated(int exitCode) { + super.processTerminated(exitCode); + updatedToRevision.set(myRevisions); + } + }; + } + + private static void fillParameters(@NotNull List parameters, + @Nullable SVNRevision revision, + @Nullable SVNDepth depth, + boolean depthIsSticky, + boolean allowUnversionedObstructions) { + + CommandUtil.put(parameters, revision); + CommandUtil.put(parameters, depth, depthIsSticky); + CommandUtil.put(parameters, allowUnversionedObstructions, "--force"); + parameters.add("--accept"); + parameters.add("postpone"); + } + + + private void checkForException(final StringBuffer sbError) throws SVNException { + if (sbError.length() == 0) return; + final String message = sbError.toString(); + final Matcher matcher = ourExceptionPattern.matcher(message); + if (matcher.matches()) { + final String group = matcher.group(1); + if (group != null) { + try { + final int code = Integer.parseInt(group); + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message)); + } catch (NumberFormatException e) { + // + } + } + } + if (message.contains(ourAuthenticationRealm)) { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message)); + } + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message)); + } + + @Override + public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) + throws SVNException { + final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false); + return longs[0]; + } + + @Override + public long doSwitch(File path, + SVNURL url, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, + boolean depthIsSticky) throws SVNException { + checkWorkingCopy(path); + + List parameters = new ArrayList(); + + CommandUtil.put(parameters, SvnTarget.fromURL(url, pegRevision)); + CommandUtil.put(parameters, path, false); + fillParameters(parameters, revision, depth, depthIsSticky, allowUnversionedObstructions); + parameters.add("--ignore-ancestry"); + + long[] revisions = run(new File[]{path}, parameters, SvnCommandName.switchCopy); + + return revisions != null && revisions.length > 0 ? revisions[0] : -1; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java new file mode 100644 index 000000000000..a847975b7f9f --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnKitUpdateClient.java @@ -0,0 +1,93 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn.update; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc.SVNUpdateClient; + +import java.io.File; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 12:11 PM + */ +public class SvnKitUpdateClient extends BaseSvnClient implements UpdateClient { + + @Nullable protected ISVNEventHandler myDispatcher; + protected boolean myIgnoreExternals; + protected boolean myLocksOnDemand; + + @Override + public long[] doUpdate(File[] paths, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, + boolean depthIsSticky, + boolean makeParents) throws SVNException { + return getClient().doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents); + } + + @Override + public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) + throws SVNException { + return getClient().doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky); + } + + @Override + public long doSwitch(File path, + SVNURL url, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException { + return getClient().doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky); + } + + @Override + public void setUpdateLocksOnDemand(boolean locksOnDemand) { + myLocksOnDemand = locksOnDemand; + } + + @Override + public void setEventHandler(ISVNEventHandler dispatcher) { + myDispatcher = dispatcher; + } + + @Override + public void setIgnoreExternals(boolean ignoreExternals) { + myIgnoreExternals = ignoreExternals; + } + + @NotNull + private SVNUpdateClient getClient() { + SVNUpdateClient client = myVcs.createUpdateClient(); + + client.setEventHandler(myDispatcher); + client.setIgnoreExternals(myIgnoreExternals); + client.setUpdateLocksOnDemand(myLocksOnDemand); + + return client; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java index 148d71703f96..af9ef2eccd64 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java @@ -25,7 +25,6 @@ import com.intellij.openapi.vcs.update.UpdatedFiles; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; import org.jetbrains.idea.svn.api.ClientFactory; -import org.jetbrains.idea.svn.portable.SvnUpdateClientI; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.io.SVNRepository; @@ -83,11 +82,11 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment final boolean isSwitch = rootInfo != null && rootInfo.getUrl() != null && ! rootInfo.getUrl().equals(sourceUrl); final SVNRevision updateTo = rootInfo != null && rootInfo.isUpdateToRevision() ? rootInfo.getRevision() : SVNRevision.HEAD; if (isSwitch) { - final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, true, sourceUrl); + final UpdateClient updateClient = createUpdateClient(configuration, root, true, sourceUrl); myHandler.addToSwitch(root, sourceUrl); rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); } else { - final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, false, sourceUrl); + final UpdateClient updateClient = createUpdateClient(configuration, root, false, sourceUrl); rev = updateClient.doUpdate(root, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); } @@ -96,14 +95,14 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment return rev; } - private SvnUpdateClientI createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) { + private UpdateClient createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) { boolean is17 = WorkingCopyFormat.ONE_DOT_SEVEN.equals(myVcs.getWorkingCopyFormat(root)); boolean isSupportedProtocol = SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(sourceUrl.getProtocol()); // TODO: Update this with just myVcs.getFactory(root) when switch and authentication protocols are implemented for command line ClientFactory factory = is17 && (isSwitch || !isSupportedProtocol) ? myVcs.getSvnKitFactory() : myVcs.getFactory(root); - final SvnUpdateClientI updateClient = factory.createUpdateClient(); + final UpdateClient updateClient = factory.createUpdateClient(); if (! isSwitch) { updateClient.setIgnoreExternals(configuration.IGNORE_EXTERNALS); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java new file mode 100644 index 000000000000..b68829e28940 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateClient.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn.update; + +import org.jetbrains.idea.svn.api.SvnClient; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; + +import java.io.File; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 11:59 AM + */ +public interface UpdateClient extends SvnClient { + + long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException; + + long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; + + void setUpdateLocksOnDemand(boolean locksOnDemand); + + long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; + + void setEventHandler(ISVNEventHandler dispatcher); + void setIgnoreExternals(boolean ignoreExternals); +} -- cgit v1.2.3