diff options
author | Tor Norbye <tnorbye@google.com> | 2014-07-25 12:24:15 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2014-07-25 12:24:21 -0700 |
commit | 2e5965e996aad62ab1338b09d54caaf99ff3dd6a (patch) | |
tree | 68aa5081765150003d05155215812e629de09ec8 /platform/vcs-impl | |
parent | 65f60eb9011bb2c549a6d83ae31257480368ddc5 (diff) | |
download | idea-2e5965e996aad62ab1338b09d54caaf99ff3dd6a.tar.gz |
Snapshot idea/138.1283 from git://git.jetbrains.org/idea/community.git
047cbb9: IDEA-127620 - Clouds: move frameworks to the top level in new module/project wizard - refactoring of import
1d1914f: IDEA-127620 - Clouds: move frameworks to the top level in new module/project wizard - remove from JavaEE group
3206e15: Merge remote-tracking branch 'origin/master'
a513e70: enable injected context for actions in action popups (IDEA-126995)
70c5d69: CommentInjector: improved detection and IDEA-114915 InjectorUtils performance
482cdc2: @MagicConstant added
997dc0b: do not show VM names in run configurations: junit, application (IDEA-126880)
9873768: merge commands to replace duplicates (IDEA-126776)
e9a17df: field can be local: when field is used in method for read it can't be converted to local if used in another methods (IDEA-127159)
f9e6f06: faster LexerEditorHighlighter.checkContentIsEqualTo
6051f49: generic debugger settings: step 3 — root settings (Debugger node content) — Java transformed
bcb94d7: cleanup
a12ac6c: treat Diagnostic.Kind.NOTE as information message, not a warning message (IDEA-105383)
f367dcb: IDEA-127666 Add tooltip to "Project Setting" icon
08d9677: add delegate method to TextFieldWithHistoryWitBrowseButton
ce0d23f: change messages for postfix templates configurable
d7d7e88: platform: syntax compatibility with antiquated Python versions for environment loader
2a10168: SwingHelper moved to platform-impl
0299b30: auto-import context variable declaration type when completing (IDEA-90157)
e353c2f: prefer some well-known java util classes in completion (IDEA-100669)
f81e96e: java chained completion: qualifier class items shouldn't be inserted as constructors
7cb41f8: Update image to visualize the project-based configurable in the Settings dialog.
e1d651b: Cleanup (formatting)
a7e55c6: time limit for constant search
9cce5c7: do not split annotations on multiple lines for params (IDEA-127017)
0aa3890: simplified, added filtering for subsequent parameter pairs: "key, value", "first, second"
d477f91: IDEA-59662: Provide ability to specify right margin (columns) for each file type separately (enabled for PHP)
9b820f7: IDEA-127679 ArrayIndexOutOfBoundsException if no default or focused button is specified
4c997e0: Prevent NPE in AbstractPopup and add corresponding logging
5a49a15: fix inset: VerticalFlowLayout incorrectly uses vertical gap as top inset
ece44da: cleanup
5a46a42: generic debugger settings: step 3 — root settings (Debugger node content)
04518cd: Inspections settings ui: tools not initialized if no necessity to apply inspections filter
da81c5d: ProjectFileIndex#isIgnored renamed to 'isExcluded'
0e67032: Return accidentally removed PyStringLiteralFixer
3089c9c: PY-12877 Complete statement doesn't insert colon for 'with' statement
1c70a28: IG inline fixes: use inline method processor; if simple getter is inlined in simple expr statement - it should be deleted (IDEA-127135)
8835827: logging for (IDEA-127288)
b585c95: inline method: check unique names for this variable in initial class scope (IDEA-127411)
ccc235e: tests: show warning when only ignored tests were detected (IDEA-127660)
ad42de6: vcs: reformat and cleanup
e9fe369: fixed starting jps-builders tests
9d121c2: fix disposeUIResources if merged
2e780d7: turn off contract inference for overrideable methods: fix logic
1bf7333: don't measure MinusculeMatcher performance
2eae3c8: contract inference: take explicit parameter notnull into account (IDEA-127667)
8851417: non-code gutter: get annotations for bytecode psi when highlighting library source
6608b52: generic debugger settings: step 2 — stepping — transform Groovy, all Stepping configurable on one page
e46729f: cleanup
dd0fd0f: ContainerUtil notNullize/nullize
3d30b27: extract EMPTY_SETTINGS_PANEL_PROVIDER
efe0d5a: Inspections settings ui: filter actions in toolbar added
006705c: DefaultVcsRootPolicy refactoring: 'isIgnored' check moved from 'matchesDefaultMapping' implementations to 'getMappingFor'
363b2cd: simplification
12a3d4f: platform: minor optimization (do not rename/delete directory recursively)
9a80d33: vfs: on create/delete notifications mark a child dirty as well
74d6cb2: diff: use separate action for 'roolback' for file (VCS action) and 'roolback' for local changes (LST action)
8b69a0f: diff: fix access to the invalid ranges
1f4de9d: diff: diff from LineStatusTracker
950a80a: IDEA-110611 diff: Ability to revert lines in selection
b6cd05a: diff: small fixes in LineStatusTracker
db873ee: Use Guava's immutable lists instead of static initializers in PySmartEnterProcessor
b1b8116: PY-9176 Converting % to format() doesn't handle multiline string literals
3d377d9: trigger automake for deleted files
1101b55: Merge remote-tracking branch 'origin/master'
3bf8f90: fix paint track
1e1a9c7: IDEA-61550 respect EditorFilter
831cecb: Merge remote-tracking branch 'origin/master'
28dd985: make editor vertical scrollbar bg the same as editor bg on Mac
c3a963a: fix preferred height for JComboBox too
da026c5: override ControlDoubleClick+Left/Right, make new bindings switchable
222d8ef: bind 'clone caret' actions to ControlDoubleClick+Up/Down
41034f6: DirectoryInfo: extracted sub-class
693b2a2: DirectoryIndexTest: renames
a06bd87: Inspections settings ui: added mask and fixed height of severity icon
73dfd94: parameter name folding reducing: - do not inline if parameter length is less than 3 - do not inline if two subsequent parameters has interval names (beginIndex, endIndex; startId, endId; from, to...)
90d58be: DirectoryIndex: removed unnecessary isProjectExcludeRoot method
359bc94: DirectoryInfo simplification: use booleans instead of bit flags because now we have no so many instance of this class (CR-IC-5807)
df51a0d: Inspections settings ui: severity colors in tree showed only for enabled inspections
931d600: Inspections ui: expand/collapse tree fixed
c0d2162: EA-58395 - NPE: PerlMatcher.matches
d203d8f: bytecode-inferred annotations are only available for compiled elements (IDEA-127608)
5c1256f: Merge remote-tracking branch 'origin/master'
bacc3c2: lambda -> method refs: collapse when acceptable method without supers found
3bed881: Merge remote-tracking branch 'origin/master'
dd4ddfb: method ref -> lambda: names based on resolved method (IDEA-126977)
4b7122b: shorten FQNs when insert casts (IDEA-127573)
91f505e: create static method from usage in interface (IDEA-127563)
124d774: generic debugger settings: step 2 — stepping
72a3ffa: Cleanup (formatting)
7016425: Cleanup (two utility classes merged)
ff16ce7: update about graphics
02939b8: add problems listener to update counter
22a3964: +getList() to access configurables list
79a933c: update problems counter for Darcula
b198c6a: add Problems counter
67cbc12: allow to override layouting algorithm
43ab48e: + getErrorsCount()
72925df: pointless expressions: do not simplify a - b - b to a - 0
824f432: workaround for <p/> inside <pre> in javadoc preview in JEditorPane (IDEA-127430)
ae4f3d9: unwrap: adjust caret before RParenth (IDEA-127580)
a46f4ce: anonym -> lambda: disable in case when inferred type differs from type of anonymous class and parameter of param type is used inside (IDEA-127603); BTW param.toString would be also rejected
89dc528: new inference: no substitution during most specific inference by means of new spec (IDEA-127584)
fb786d3: SSR: improve annotation name value pair matching
20cb223: SSR: renaming
6af6e5d: SSR: Nullable annotations
912772c: SSR: remove unnecessary field
1017a77: SSR: remove a bit of dead code
04d10f8: IDEA-127337 Popups in editor sometimes aren't shown on first invocation
f18c04d: jps plugins: added extension to allow plugins contribute to JPS model even if they don't contribute to external build
5c81146: generic debugger settings: step 1 — data views — merge settings (generic and custom) into one page
4a15d1b: add copyright
27fddc2: generic debugger settings: step 1 — data views
e6d092e: cleanup
343e145: cleanup
90cc9e3: cleanup
30c7264: cleanup
31d8039: cleanup
322e539: IDEA-127077 (highlighting test)
4d7f4ab: move PropertiesComponentImpl to core-impl
2495d31: runtime-opcodes support
f3ffe1a: java-analysis-impl doesn't depend on platform-api
68de28e: use JBColor
fd0bb1e: IDEA-127620 - Clouds: move frameworks to the top level in new module/project wizard
0cf69f8: bytecode analysis: resolve only wrt PsiClassOwner (IDEA-127608)
9ca2a55: reverted e442926 because there is no thread visibility problem right now (per discussion with Roman.Shevchenko)
8e74038: additional tracing code for difference of this session and previous session of particular content calculation
bcd970c: Nullable / NotNull
62a0104: revert: Ctrl-N doesn't show after delete; no input field for Ctrl-N etc
9b4912c: lambda: do not start inference from void type (IDEA-127596)
6de6ee1: delegate methods: do not suggest to delegate when delegate would override final (IDEA-127605)
9ff4e24: plugins update dialog layout (IDEA-127462)
f03ca65: create class: filter out generated roots (IDEA-127562)
455fc35: move destination: fix laziness
d93d0ab: Workaround for another JDK bug in cached popups.
a4cdd68: update grails project structure: remove proper instance of ContentEntry (IDEA-120622) using urls since ContentEntry uses default equals/hashcode implementation
14d57e4: Cleanup (formatting)
e35d9d8: IDEA-127077 (incorrect parsing of type annotations)
653ccf4: move to the right module
0e44e1c: Merge remote-tracking branch 'origin/master'
afc422e: fix errors foreground for Darcula
f38dd67: Merge remote-tracking branch 'origin/master'
bbb42a45d: IDEA-126982 (Add an inspection to flag a nonfinal class that only has private constructors)
c54ff24: fix typos
8ae3019: [git tests] assume git version is supported
1e79d7b: [log] Simplify & fix refs comparison API & implementation
dd0a29c: [git] fix refs comparator for the case when refs have equal names
db96ca3: [git] remove trivial test setup
7f6d1ce: [git] rename test class to match the production class name
d94a9bf: simplify:inline variale
a2d93f2: IDEA-126389 FromString ClosureParams Hint should use method.getTypeParametersList() as a context for creating type because method does not process its type parameters in processDeclarations(). Use method as a context if it does not contain type parameter list
a2221d5: IDEA-126334 Correct declaration scope for light parameters and getReturnTypeElementGroovy for light methods
5ccb872: IDEA-126389 FromString ClosureParams Hint should use method.getTypeParametersList() as a context for creating type because method does not process its type parameters in processDeclarations()
b43f06c: make another IG test light
09fafa8: IDEA-127263 ("Conditional Expression With Identical Branches" deleting non-identical branches.)
feeb54a: SSR: remove unused method
d5ce2c1: SSR: match name value pairs when value is not specified
d61fdb0: fix typo
55eb67a: fixing JspAutoImportTest: auto-import classes at statement start
455b352: cleanup. remove unused fields
42c3f0d: change links protocol
05a4407: add hyperlink listener
9906008: Merge remote-tracking branch 'origin/master'
25f1003: stub for ordered scopes problem
7e4a359: Merge branch 'master' of git.labs.intellij.net:idea/community
3559eb7: bundling ecj-4.4 java compiler
0d34ff1: PY-4186 Lettuce BDD tool support (initial commit of lettuce runner)
640c9a6: Merge remote-tracking branch 'origin/master'
e442926: IDEA-117507 NullPointerException on startup of IDEA 13
d2be1f3: disable hard consistency check
5cc3a16: fix mistype in html+ increase space between elements
2dc1b7c: Log popup window size before showing
1a20228: showing build attempt in logs and in title bar only
2df962a: scopes: include module in file pattern as matching would be calculated against it anyway (IDEA-127397)
d60644a: Resize a popup window according to the preferred size of the component instead of its size.
b237157: do not lock UI during plugin download (IDEA-127454)
067ef9e: method refs: check first parameter if it could be a receiver for varargs methods (IDEA-127506)
eff4567: compose error message (IDEA-127534)
3bc9fa3: IDEA-111466 Mac OS X keyboard shortcuts with alt don't work under Oracle Java 7
6bf1409: postfix template fix ternary operator + test
c6ff466: IDEA-111466 Mac OS X keyboard shortcuts with alt don't work under Oracle Java 7
55a8bd4: DebuggerSettings — use PersistentStateComponent instead of deprecated JDOMExternalizable
189f3f5: cleanup
402ccab: DBE-228: column margins
333636c: Replace comma with ampersand
68ec56f: Add groupId for top-level configurable for Junior IDEs.
2ff73e2: don't recreate code fragment psi (IDEA-127039)
5379b77: turn off contract inference for overrideable methods; hopefully, not forever (IDEA-127518)
49a119a: IDEA-121276 Constant conditions: work with arrays
ec7c9a3: JavaConstantExpressionEvaluator: add @Nullable
563ad9e: move DfaValue calculation for expressions to one place
392885a: @NotNull DfaVariableValue.psiVariable
ee1eb2c: store / use buildAttemptInfo taken from file
5de0503: insert delete with renaming logic for Windows into general delete method
0a6a374: Reverted: cast from Short to char is prohibited (1c5a03589e5155633de91051e59255d3ad84414f)
91b8291: IDEA-123863 'Save Project as Template' action leads to deadlock
3aed563: Platform: use presentable names when generate keymaps for help
34f2fb0: grayed call frame view if in library content (the same as in java)
f9982ec: update grails project structure: remove proper instance of ContentEntry (IDEA-120622)
ecbbac9: Merge remote-tracking branch 'origin/master'
9795ec8: extract from internal mode
3b00516: notnull
67b840e: notnull
e4308c8: cleanup
e75bfff: correctly calculate inspection short name in presence of upsource
52d5382: optimisation
1c5a035: cast from Short to char is prohibited
685fdb4: optimisation: getMaybeSuperClassSubstitutor() allows to avoid extra isInheritor() check
60d088f: notnull, cleanup
b5fb827: optimisation
edf6a02: Merge remote-tracking branch 'origin/master'
23586b9: Added coverage.py fixing wrongly optimized imports.
f291cc5: Fixed getting helper.
ecec042: Merge remote-tracking branch 'origin/master'
f997ddb: StringPattern: restore binary compatibility (broken by 64c812e)
145fbae: Merge remote-tracking branch 'origin/master'
642faba: as ignored file set can be quite large, use map without entries for smaller memory footprint (e.g. in snapshot for IDEA-126201 number of ignored files is 126K, size of entries's memory for this number of elements is 2.5M)
067aa19: skip non-java files with given word in literal even before retrieving text / searching the word / finding element at tree (IDEA-126201)
aea7066: allow to pull methods in super interface as default ones when super interface already contains a method with the same signature; remove @Override in such case (IDEA-126988)
7d19e0e: method refs: missed super class substitution (IDEA-126969)
f17f398: 'unmark root' action: allow user to cancel exclusion if excluded folder is selected (IDEA-23537)
d61da37: IDEA-122076, IDEA-122172 Multicaret actions in quick find mode
8b2824d: IDEA-121956 Multiple Carets: Add support for skipping next selection
1ce6009: - catch runtime problems (e.g. IndexOutOfBoundsException from ByteBuffer) when instantiating stub index and retry index creation (IDEA-117596, IDEA-125750), ep2
c455dd4: - catch runtime problems (e.g. IndexOutOfBoundsException from ByteBuffer) when instantiating stub index and retry index creation (IDEA-117596, IDEA-125750) - use deleteWithRenaming to update index version (IDEA-127160)
b0fe937: DirectoryIndex: fixed 'isIgnored' for ignored files
fb4de8d: DirectoryIndex: store info for excluded and ignored directories
df68af8: require that notnull fields be initialized (IDEA-114889)
5a22fdc: IDEA-126660 Incorrect 'condition is always true' for a final field if an overridden method is called from the constructor
a7ec8b7: IDEA-126173 Specify exception type thrown by @NotNull annotations
f4d3703: IDEA-126531 Completion inserts unwanted semicolon
2887069: dfa: take into account known variable values when handling number comparisons (IDEA-126446)
1aa6e7a: add cast to disambiguate method calls when replacing their argument with null (IDEA-126466)
65ccc19: HardcodedContracts: use a utility method
4853112: dfa: we don't replace nontrivial references with constants, so remove the corresponding code and tests
3eea5bc: hardcode Guava Preconditions.checkNotNull contract
6d9cf39: dfa: understand assertThat notnull (IDEA-125977, IDEA-65004)
2a3e157: Merge remote-tracking branch 'origin/master'
f5e85e7: IDEA-126122 (reFS volumes recognized)
be1c5b8: Refactoring: configurable from provider can be null
e568624: Cleanup (file watcher project converted to VS13; generated junk dropped; version info updated)
1e7a9e9: Cleanup (tabs/spaces; formatting)
0262088: cosmetics: add extra offset for project icon and label margins
1695e0c: fix AIOOB in history
2b3dd78: add css styles to Error Pane
ac796ba: wrap errors to html for new project structure dialog
59763f3: Focus logging
3d07af1: SingleInspectionProfilePanel NPE fixed
397e893: IDEA-127478 Tip Of The Day dialog could be shown on incorrect monitor
090b2e5: on case-insensitive file systems perform file name compatibility check using real file names, not the ones taken from dynamically built or stored paths
e77cd8a: imports optimized
444f98b: show tooltip when mouse on "multiscopes" icon in inspections settings ui
b0b0fef: external build: send empty text with statistics message to avoid producing unnecessary output by IDEA Project Runner in TeamCity
970fe60: use ProjectFileIndex (from API) instead of DirectoryIndex (from impl) where possible
d9c45be: libraries scope: use ProjectFileIndex (from API) instead of DirectoryIndex (from impl) where possible
417adc7: notnull
b58808c: js postfix templates -> fix examples and configurable UI
ba3b637: Settings dialog: the project-based configurables are marked with an icon.
6508417: IDEA-127438 Tool windows drag&drop failure under Java 7
ca76151: IDEA-127343 Github: pass ModalityState to PasswordSafe
da5b7e6: use Couple
e98cb25: use Couple
568b881: DBE-228: abbreviate long cell values
abd5dce: notnull
6d84ba6: Add image to visualize the project-based configurable in the Settings dialog.
c32d9db: [vcs] IDEA-107598 Affected paths: consider the whole path when highlighting
f4ee468: Inspections settings ui: new inspections tree (tree replaced by table tree, added icons represent severities)
47de3cf6: LiteralExpressionTokenizer cleanup
120fe08: get rid of group border
1a5cf59: IDEA-127343 Pass ModalityState to PasswordSafe.store/removePassword
0143935: remove trivial javadocs
f3eb2b2: [git] Remove obsolete password aware handler
c4a16ff: Get password called with modality state; unnecessary get password from memory removed for hg auth
bf1f916: restore API for idea-php-symfony2-plugin
c53dc62: check for null
62e5744: unused classes from 'old make' implementation deleted
b8ddfa4: groovy compiler: deleted classes related to old make implementation
42926e1: Fix possible NPE in JiraRepository (EA-58392)
3498760: Introduce live integration tests for Tasks plugin. Add initial version of such tests for Trello
6fd747b: Migrate TrelloRepository to new tasks API
3021914: Remove wrong GSON annotation of 'closed' field in TrelloCard
e2b581a: IDEA-115177 (watcher size check no longer needed)
c9d3e32: vfs: file watcher executable lookup fixed
431f9db: get rid of deprecated code
25c8ccd: EA-58277 (diagnostic)
6037400: don't highlight '*.restartRequired' properties in registry.properties as unused
dfb7e51: registry: use 'restartRequired' property to enforce automatic restart
3305c35: registry: description text corrected
0ffc7d0: CIDR: OC-10422 Current resolve configuration should be preselected in resolve context panel
5f31e2e: show excluded files in Project View, initial (IDEA-23537)
ace6fe4: artifacts: one more unused class from 'old make' implementation deleted
5897a01: deleted old unused deprecated 'build participant' classes
b75d5f2: artifacts: unused classes from 'old make' implementation deleted
3ed24eb: RUBY-15507: we should not wrap configurables in scroll pane
26b2743: ProjectViewPsiTreeChangeListener updates tree more deeply on property changed
77ee53a: Fix again the following changes that were reverted: Fix for nullable composite configurable.
d0cd301: IDEA-126984 Mac OS X: Double line above the editor
c2e6ab0: revert (e3e3224e853ad466cebf13c8b5c7f01d272d8e88 Fix for nullable composite configurable.)
d1ce059: highlight modules
8b6c40d: platform: splash misalignment on Windows fixed
8b35719: devkit: incorrect modification reverted
928feba: JavaHelp 2.0_05
bc13d12: Merge remote-tracking branch 'origin/master'
a9d7da6: added test for default property file in resource bundle editor
160fca0: project: windows update scripts unified
e3e3224: Fix for nullable composite configurable.
a69f781: cleanup
aa16ba2: IDEA-126984 Mac OS X: Double line above the editor
0994232: project: build/update scripts tuned to support home paths with spaces
b9eb20d: EA-57720 - PIEAE: LeafPsiElement.a
1396322: IDEA-127343 Pass ModalityState to PasswordSafe.getPassword
7eb4791: [git] remove obsolete javadoc
4d3abb7: cleanup: remove trivial comments
d8f6d4c: SeverityEditorDialog -- if "mixed" pseudo severity chosen then no default selection
e39d6a2: ScopesAndSeveritiesTable suppress unused declaration inspection
f356442: DBE-321: prevent data tooltip flicker
226e175: Inspection settings UI: multiselection in inspections tree support
68c651e: catch exception when writing content, marking vfs for rebuild (IDEA-125925)
f59b7b3: revert the change that breaks functionality
eac71fe: add tool window id to assertion
349f84a: fix several concurrency issues in Search Everywhere
65824bb: Some configurables requires the dynamic attribute to configure its wrapper properly.
73c7f62: go to action: move Analyze Stacktrace... to the top
5458ff1: IDEA-127232 Fatal Error on startup on Mac Os X
09230b2: IDEA-125671 "Install plugin from disk" action could have different description in Find Action list, because now there are two identical items in the list
35e6c4d: remove suppressions
e83f80f: implicit usage provider for *.description in registry.properties
ddae39a: file path completion fixed
6f1f6cf: Inspection settings UI: creation copy of tool wrapper if new scope inserted
981a3db: remove unused class ColumnInfo$StringColumn
864cd2d: Inspection settings UI: - "ALL" scope moved to last position in table - move scopes in single inspection disabled
4965683: Merge remote-tracking branch 'origin/master'
e488923: cleanup. remove unused methods
d13074e: fix incorrect target element calculation for text editors
e2c4550: typo
219b31c: show display name for certificate configurable
1b4a3c1: larger scope when searching in path / ssr (IDEA-127068)
17a5843: disable plugins if cycle was detected (IDEA-127177)
001a9cf: New inspections settings UI: - nodes for individual scopes deleted from settings tree - added table in right panel to configure scopes&severities - new scope button added to right panel (if only default scope currently available)
de377f8: extract variable missed events (IDEA-127166)
dcb45f2: extract field missed events (IDEA-127167;IDEA-127169)
1d8d358: extract parameter missed after event added (IDEA-127170)
30d945d: local rename events (IDEA-127172; IDEA-127172)
d0b86b6: popup position for injected fragments during inplace refactorings should be calculated over injected editor as caret range marker is against injected document (IDEA-126989)
53de53f: Refactoring of grouping configurables. Use the following registry key to switch on this functionality: ide.file.settings.order.new
088e9a2: Fix tests broken after changes for PY-4073
d5032e5: java: parser changes temporarily reverted
690797e: Using "Batch File Change" events in BuildManager to cancel already running automake session while VCS is updating working tree (IDEA-111673)
4e586b4: replace with foreach
b70bfe3: Platform: do not produce duplicating shortcuts in help keymaps
d65ce21: Merge remote-tracking branch 'origin/master'
6a141b3: [git] rename utility method to a more consistent name
c5129cf: fix layouts: exclude structural search from defaul platform implementations
a9396b6: unused property inspection: search in a narrow scope first
5002c70: contract inference: honor already known parameter values during data flow analysis
704198c: contract inference: exclude contracts not matching the return type
349f900: no ContractInference for compiled elements
f02a497: change foreground and separator color
2e6fb66: move Problems down and change separator
6404449: support "--" separator
aa98745: customize separator
2e376b2: [git] IDEA-126472 IDEA-126473 Notify about external changes modifying the working tree
1a37016: [git] better diagnostics output format
f9a615b: [git] remove unused method
8b2eae6: [git] Remove duplicated code
5dd8682: Merge remote-tracking branch 'origin/master'
91b1e1b: Fixed wrong cast.
44ec294: annotate getPattern / getOptimizedIndexingPattern with @Nullable return info
50d32b8: SSR fix replace test
6521af0: IDEA-127077 (incorrect parsing of type annotations)
5b72fac: Cleanup (warning)
4fd07a5: License dialog: License key: provide precise diagnostic for rejected key After-review
6cb2eab: Remove deprecated Remote Interpreters API.
7d1e1bd: do not propagate exceptions in case of broken bytecode
980b837: fix test
e099a14: gant-based builds: added one more jar required for Kotlin compiler
f36393b: go to action: use gray instead of italic for shortcuts rendering
1c43998: gant-based builds: removed incorrect classpath entry for Kotlin compiler
ffb8b5f: gant-based builds: added jars required for Kotlin compiler to classpath
47eec66: java inheritor cache: use weak map to avoid holding PSI for unnecessary long time
1a78fe7: goto action: restore enabled action preference
8343e8e: goto action: rewrite using a more suitable API, prefer exact matches, fix search everywhere
a24b862: IDEA-127189 Select next/all ocurrence fails with braces
304a69b: IDEA-103025, EA-53787 fix handling of special fonts in soft wrap model
dd4b761: trait field searching test fixed
7c04faa: Merge remote-tracking branch 'origin/master'
bad2fa8: Fixing env tests
dd23104: memory hogging on javaInjections.xml editing
1bbb89c: go to action: proper text attributes for shortcuts
0057fe3: go to action: don't show duplicate group for intention actions
482084c: go to action: missing bg for option descriptors
590ed4c: disable create instance field inside interface (IDEA-127211)
65d11dd: disable generate test method actions outside class (IDEA-127246)
f69f9fd: leave static modifiers in interface methods (IDEA-127255)
42f50f6: sort items in goto action by matching degree (IDEA-112613)
45915b2: show colored matched fragments in goto action (IDEA-112613)
34b51a1: show progress when status bar is switched off (registry: ide.show.progress.without.status.bar)
cdbb650: null check
d5dada4: disposed check
64c812e: StringPattern: cleanup, add StringPatternTest
7fa1b28: remove unnecessary field and getter from SSR ReplaceCommand
472bf3f: java: decompiler fixes (IDEA-127229 et al.)
7ada79c: AnnotationUtil.isInferredAnnotation
c0d76a2: parameter info: don't retrieve inferred annotations in dumb mode
4df5903: IDEA-127127 charset name completion: provide completion for more APIs
b6ea24b: don't duplicate annotations in parameter info
3f7935a: dfa: turn on contract inference from source
b6b76b7: IDEA-127212 Live templates "Use static import if possible" fails sometimes
f372b95: corrected 'isCommunity' check
08b3c7f: disable table speed search for empty tables
51292ab: Merge branch 'svn_18_3'
511f071: IDEA-126911 Do not call "VirtualFile.getFileType()" for directories (while checking if annotate action is enabled)
93e45b9: PY-4073 Add completion for special function attributes
0a5bfb0: Merge remote-tracking branch 'origin/master'
0fcfb36: Merge remote-tracking branch 'origin/master'
86b7bf5: Fix copying .egg files from remote host to libraries folder (PY-13044).
912c0d7: html editor as a error pane
55b4064: do not modify profile file to write default
102bcb2: structural search bundles fixed
bb0b50c: Merge remote-tracking branch 'origin/master'
5253ba2: type migration: make part of platform
3ab8864: Error pane initial
581cf80: structural search: groovy should work in community
76726e8: disposed check
be28458: css synchronizer — support of manual update
7b29836: structural search: make part of platform: enable in community
a5061f3: fix module locations
a3626d6: Merge remote-tracking branch 'origin/master'
695682b: structural search: make part of platform
50e27ec: enable inline redundant local vars in batch mode (IDEA-126957)
49b9f30: EA-58014 (diagnostic)
9d32e98: added incompatible plugin version org.intellij.clojure / 0.2.1.178
c27d829: - properly retrieve set of keys for unsaved documents for their first change - (in extra sanity checks mode) added PHM that stores previous content indexing info to facilitate discovery / fixing assertions about different indexing behavior
0896a25: avoid accessing invalid buffer
159f3c5: Merge remote-tracking branch 'origin/master'
4cc0d5e: IDEA-127183 Windows: Look for 1.8 JVM registry entry by default
f41f9c3: Debugger reader performance fixed, now uses BaseOutpuReader (PY-11393).
cb2159e: Switch on new Alt processing under Windows L&F.
ef8fbc4: notnull
e1445e6: Gradle: IDEA-127217 Tests with spaces aren't wrapped with " " when running specific test as Gradle test
cf1f8c8: fix tests: improved 'isInCommunity' check
bcb38e5: pep8.py updated to version 1.5.7
0970549: Coverage.py updated to version 3.7.1
90f034d: Merge remote-tracking branch 'origin/master'
6ec557a: Try even more to connect.
69a2a4c: path completion: rendering fixed for several matched context helpers
21efa65: cleanup
7494ef6: support for multiple groups in idea.test.group property
00847ed: No need to register MessageBusConnection disposal: it is done automatically
0fb6eab: Suppress "unused" constructor: initialized as a Service
2b6b549: Fix already disposed EA-58257
fc46e99: look for JVM 1.8 first
b7cea46: added caching + minor size opts
63453c3: fix NPE in SSR ReplaceOptions
941c20b: stop usage search on target invalidation (EA-54329)
d75a12f: invalid type diagnostics (EA-58069)
121084a: remove specific Lookup check in intentions pass, daemon is disabled during lookup anyway (EA-58246)
71fd543: WEB-9954 move and rename confusing "Live Edit menu item
5d745b1: check for null for content hashes flush
7073116: fix ConcurrentMapsTest (by Roman)
6d6d15a: IDEA-122254 ("Use static import if possible" checkbox for the Structural Replace dialog)
4febd80: intention should insert static import when replacing assertNull() with assertEquals()
4dd5b62: insert static import when replacing assertEquals() with intention
591d723: insert static import when flipping assert literal outside of test method
90f2ef5: use static import if it is already present for several intentions and inspections
dd2d141: Merge remote-tracking branch 'origin/master'
ae714aa: Win tests should be more stable now
3b3fee8: clear zip file caches on low memory
c81ebf5: Refactoring: create instances of IdeConfigurablesGroup and ProjectConfigurablesGroup in one place.
b83f901: Merge remote-tracking branch 'origin/master'
9c13559: Comment.
ec56a95: skip leading .* in reg exp used for todo pattern when building index: it makes sense for todo highlighting but increases matching due to backtracking enormously (IDEA-74104)
d83e334: IDEA-126836 Formatting adds extra blank line after class header if it ends with comment
6d68662: use 1px separators
e360f62: add utility method to configure 1px separator
23ba8f8: use encoding info when building hash for contents + rebuild content dependent indices upon encoding change
7b8cc6c: Fixed according to CR-IC-5706
93d37fa: don't auto-import classes where class references are prohibited syntactically (IDEA-127190)
f87e56d: bytecode analysis: a comment about lite control flow analysis
90addcd: bytecode analysis: lazy resultOrigins analysis
a7c1c1a: bytecode analysis: lite control flow analysis
8211223: bytecode analysis: no analysis at all if nothing is inferrable
60a6acf: moved method from moduleutils to modulerootmodificationutils
3173594: jetbrains.dic + "unmerged"
c95ca18: support prefix expressions in quick evaluate
8d71285: cleanup
e418bb2: use UIUtil.getSidePanelColor()
bef8a7f: remove border for content component
1835567: + side panel color
105b9a1: @Nullable
ef2875d: IDEA-126927 - CloudFoundry: if the same artifact is deployed to few clouds, one can view the state of the single one only
7c415ca: IDEA-127069 help button added to the Mercurial Update Project dialog
0e12675: Revert "StringUtil: Added wordWrapString() method"
5af9e9f: separator titles for Darcula
b044185: better IDE responsiveness during bytecode indexing
15ed602: svn: Fixed converting SVNStatusType to StatusType - explicitly check values that have non-unique status type names
43b6e08: BytecodeAnalysisIntegrationTest: a more profound test data refresh
525a896: Merge branch 'master' of git+ssh://git.labs.intellij.net/idea/community
fe15e86: bytecode analysis: index version increment
0d24afe: disabled batch evaluator by default, overhead is too high. Enable if needed using registry key debugger.batch.evaluation
0069112: added nontull
062254d: svn: Refactored SvnStatusHandler - moved status type parsing to StatusType class
a884c1b: ignore inferred annotations when checking overriding parameters nullability
b6b6ea1: bytecode analysis: lite persistent hashCode for Configuration
1f05788: bytecode analysis: skipping frames and debug instructions
aa3b189: svn: Refactored StatusType - removed deprecated STATUS_MERGED value
f2d0988: do not capitalize titles
5ba1390: extract CachingEnumerator from PersistentStringEnumerator
1cd8961: IDEA-126973 IDE does not see the use of string resources in libraries
bb0b856: @NotNull
b700084: nullable/notnull/contract intentions available on library sources in Groovy
18afce3: external/inferred annotation gutter markers in Groovy
18dcabb: [vcs] assert annotationProvider != null (otherwise the action shouldn't be enabled)
ff89749: [vcs] Handle all exceptions during annotation similarly. EA-58021
45cd16b: svn: Refactored SvnVcs.svnStatusIs() - method moved to Status class
37423bb: StringUtil: Added wordWrapString() method
228a7f0: IDEA-127144 (No word wrap or horizontal scrolling for ignore list in Proxy dialog)
a570ab1: SSR: remove unused code from replace options
e19e11f: SSR replace handler cleanup
ab42788: IDEA-125021 Improve multi-caret copy-paste logic
8662259: IDEA-127125 Throwable at com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter.reload
7c0fcae: fixed Breakpoints tests
be3789a: do not calculate source position twice
a22e159: Disable css emmet fuzzy search by default
687fa76: no need for findClass if we have object already
86d795a: ElementPatternCondition: less memory
7801b62: ObjectPattern.oneOf(T...): less memory for single value
394b9f4: GPUB: keyword completion on non-trivial offsets
d9d79ac: resource bundle editor property rename fixed: no property with old invalid name creation after rename
233bdf9: svn: Replaced SVNStatusType (from SVNKit) with custom StatusType enum
5803898: action popups are broken if new project settings dialog option is on
1b4fef2: svn: Replaced SVNEventAction (from SVNKit) with custom EventAction enum
cbcc65f: more robust lookup start offset invalidation tracking (EA-51961 etc)
4703c93: IDEA-75885 Fast invoking shortcut with Alt brings focus to main menu [Windows] IDEA-87408 Hold <ALT> button and select multiple lines vertically does not work as desired
19eb679: Add diagnostic info
40acdf7: License dialog: provide precise diagnostic for rejected key (IDEA-122894, IDEA-125916, IDEA-125917, IDEA-125921)
e28ee1b: display inferred annotations in italic
fe21a09: IDEA-81781 Unintuitive 'Project Files Changed' message box
78b8b2c: Fix emmet tests
b363ad7: notnull
ac8bf17: added comment
d61930f: revert 43b0575239264eef2d4a5299b48f3d2119d8d380
3674c5e: PY-13140 Fix several minor issues found during code review
99058ce: TableView: update only visible column sizes
4a8c1f7: fix BytecodeAnalysisTest?
6563b56: fix BytecodeAnalysisTest?
f6c970f: IDEA-126896 Gradle: Grails integration buildPlugins issues
1ee9d0e: ModuleWithDependentsScope, another minor post-review cleanup
1478698: Fast groovy tests: exclude external system integration tests from FastGroovyTestSuite (e.g. GrailsGradleImportingTest)
43b0575: IDEA-126836 Formatting adds extra blank line after class header if it ends with comment
abcc172: IDEA-127062 Bug when closing splitted editors
ee204e9: IDEA-127045 Unexpected 'step over' behaviour in debugger
a2fb7f6: DBE-60 Windows Authentication for SQL Server
79fc7d2: processing vcs changed text only if we are not processing selected one
0f34d80: Add diagnostic info
f506a15: PY-13140 Underscored names are completed inside import statement
e0ddef7: PY-13140 Top-level module names starting with underscore are not imported via wildcard import
b6eee00: fix PushedFilePropertiesUpdater registration
b9e4b83: BytecodeAnalysisIndex is only in idea
4dfa351: BytecodeAnalysisConverter is only in idea
cb79e2e: if editor has selection, reformat only selected lines, when reformat dialog is not shown. Do not take into account processChangedText flag
76ed9f7: Merge branch 'master' of git.labs.intellij.net:idea/community
c3c78c5: IDEA-93948 Code Style->XML->Other: no preview text for CDATA
d08111d: XML Colors settings: fix description text (missing line breaks)
34dcb63: SSR: remove unnecessary class
472994b: remove some dead code from SSR search dialog
fca4af3: more efficient shortening of class references in SSR
560fb1c: fix not-null assertion
e13715a: fix NPE
9665337: javascript-psi-impl shouldn't depend on lang-impl
2a91d19: fixed XBreakpointManager.testSerialize
f698722: ModuleWithDependentsScope minor post-review cleanup
9d399a3: WEB-12568 Dart autocomplete deletes closing bracket
95673d1: don't use getPackage to check if PSI directory is in source (SCL-7243)
fbbb221: bytecode analysis: copying to prevent indices/enumerators issues
831ab18: bytecode analysis: compound keys - maximizing shared stuff
0ddd915: enable inference bytecode indexing only in internal & test mode
ee888c2: fix AnnotateMethodTest
e0861b8: bytecode analysis: leaking parameters analysis
31d93dc: ProjectBytecodeAnalysis -> service
fbb2825: ignore inferred annotation in @NotNull propagation to overridden methods
1b75318: adapt testdata to inferred jdk annotations
f350b3d: hold inferred @NotNull annotation on a hold reference to avoid UsageViewTest failures
0e53e62: bytecode analysis: assume that errors are due to incorrect bytecode
affe6e0: log bytecode analysis related information with debug level
a11744c: adapt dfa testAlexBug to jdk notnull inference
f98006e: ProjectBytecodeAnalysis: use tree hierarchy to find parameter's declaring method
bfbc9e0: limiting number of elementary steps of bytecode analysis to 30000
8eee4f3: import fix
261018e: logging AnalyzerException
ce0e838: bytecode analysis: increase IDE responsiveness during large class file analysis (e.g. groovy's ArrayUtil)
3357716: bytecode analysis: use separate keys for each file to avoid O(n^2) index removeAssociatedValue
7fc5d9e: make BytecodeAnalysisTest more classloader-agnostic
bd2ebf1: cache enumerator data, remove unnecessary enumerator queries
14ed555: do postponed formatting in JavaChainLookupElement (EA-56040)
ce64501: no contract annotation if method is already @NotNull
1754869: findInferredAnnotations returns @NotNull array
3b75ca1: refresh annotations dir during setUp
6dd49cb: update annotations after mockJDK update
c5f3f23: hashCode via ordinal, copying equations into solver
90e6e0d: myAnnotations are volatile
08811b0: more logging
1e54e26: simple smoke test that inferred annotations are visible to codeInspection
0db25e9: arrays and primitive collections
658b710: aligned with faba
b993ee5: NPE fix (possible dead bytecode instructions)
8de3dfd: using TIntObjectHashMap in analysis (instead of wrappers)
0ea01ef: minimal structures for inferred annotations in memory
861fbc7: reload inferred annotations on root change
92e2f07: checking enumerators during converter initialization
338481d: Bytecode analysis tests
75eb3cb: straightforward solver
7056873: rigid infinum
6220d1a: porting faba features
ecce111: Contract clauses normalization (sorted)
cd2946b: Tuning null -> ... analysis
82e7fd8: Parameters: CNPE join CYCLE = CYCLE
ade7530: stable calls (ported from faba)
657b7af: starting integrations tests
70cc7af: qname may be null (anonymous classes)
f2e3270: smart propagation (resultOrigins analysis)
05486ff: separate indices
eb58968: a proper disposal of app component in the test
1901b35: this is NotNullValue
f8a153e: equals/hashCode for index values
6dcf377: comments + refactoring
383752b: compound indices in action
ff84337: initial implementation for compound keys
d905c85: towards compound keys
68ef299: Refactoring: moving class processing into DataIndexer
c8e0bef: towards compound ids
bacb5f5: extracting converter
655e0ba: poc implementation via indices
eac23b5: indexing
dabdf64: towards indexing
10fda95: emulating touch via special value
e1fce3d: No need for components (with touched flag) in raw equations
44ea307: testing contract annotations
a8717a4: testing hand-coded classes
fb6ce34: Start test for BytecodeAnalysis
8ec604c: using (naively yet) solutions of IntIdSolver in Idea
fc86f2b: full cycle of solving (not tested yet)
1d2c7d5: in progress: internalizing equations
c31fd4a: No need for signatures
41d2da1: poc usage of enumerators
073012d: inferred annotations in gutter
8c57905: Draft implementation of inferring Nullity and Contract annotations
dca785b: stub for inferred annotations
d83c897: @notnull
aeb0b27: allow / skip build attempt number e.g. IU-135.455.10 (IDEA-122579)
604ec3a: Add workaround for CertificateManager *service* to work with old task connectors
b96c582: Rename classes related to legacy JIRA interface to not cause confusion anymore
165465c: IDEA-123972 Display JIRA version under JQL editor field in settings
6708af2: Use simpler test API for performing actions
eb009fc: introduced expandNodesOnLoad in XDebuggerTree
1c3cefb: nice diagnostics for failed assertion about same indexing result from the same content
6b75304: IDEA-127042 Create tip of the day for quick evaluate
b8d6082: add to watches with control+enter from evaluate dialog
86d958c: for nonntrivial file systems (e.g. in tests): build todo data flag should have the same value as todoindex.isAcceptable (cherry picked from commit 5213e01)
962d04b: svn: Refactored SyntheticWorker - reused default DirectoryEntry comparison for sorting
99e9710: IDEA-107376 Goto next / previous splitter not working when show tabs are set to none (Carlos Ortiz)
0ce61f1: notnull
a0f6b0a: svn: Refactored "checking node kind" logic - use utility methods (instead of direct comparison with NodeKind enum values)
2b5e1c1: update breakpoints and execution line highlighters on color scheme change
69be4e2: svn: Refactored RepositoryBrowserDialog - removed duplication and simplified "set action enabled" logic
e438d20: Merge remote-tracking branch 'origin/master'
1cc9650: IDEA-122894 License dialog: License key: provide precise diagnostic for rejected key (cherry picked from commit ff0eada) (cherry picked from commit 29c98ba)
9241cae: Merge remote-tracking branch 'origin/master'
7d896bb: provide completion variants for Charset.forName() in Groovy (IDEA-126595)
e62b6df: IDEA-126973 IDE does not see the use of string resources in libraries
02e5ede: updated javadoc for exit and restart actions
e1d0804: WEB-12677 Emmet: do not expand too long abbreviations
6046586: Emmet: preview editor should have maximum width if softwraps are enabled
be20e87: DOC-3246 IDEA: Update master password dialog panels help
ca5260d: IDEA-79083 Popup lists are sometimes not clickable
8a05f8e: Merge remote-tracking branch 'origin/master'
be76dc1: highlight matches in plugins table
fcd53e5: save search query as a client property
fd6b2c9: add a client property key for search query
febbd75: fix inspection setting
e119956: svn: Simplified node kind values parsing - parse right to NodeKind enum (using jaxb annotations)
6979d52: do not let transient iterator escape as it references nonsharable thread locals
746de0c: diff: fix example in diff editor color settings
3eebc8b: show different icons for muted enabled/disabled breakpoints
1b1a23a: IDEA-120465 Code completion: no Autopopup code completion and inserting pair brackets if Column selection mode is on
9dde9e3: svn: Replaced SVNNodeKind (from SVNKit) with custom NodeKind enum
ed3bf70: split 'force' flag into two different ones: 'force' and 'exitConfirmed', so that now 'force==true' guarantees application shutdown; (fixes also IDEA-127009)
756bc03: performance optimization (following IDEA-CR-337)
7a94893: change storage format for smart backspace configuration (following review CR-IC-5570)
8feafdf: Updated tests due to changes in interface of CommentByLineCommentAction
5d8aeec: IDEA-127074 Executing gradle script fails with error '.../build.gradle' is not a directory
546e0ba: IDEA-88643 delete item from list of breakpoints by pressing delete key: selection should not return to position 1.
4de85a6: IDEA-122513 Can't expand single character property in Spring config
2595051: fix blinking test
51305d0: fix test (following IDEA-124928)
51c9f4a: IDEA-121060 Multiple carets: comment/uncomment works incorrectly
0ddcf6e: IDEA-121060 Multiple carets: comment/uncomment works incorrectly
d51dd50: IDEA-121060 Multiple carets: comment/uncomment works incorrectly
9307f63: svn: Save selected depth for update/integrate operations in configuration
0e44683: svn: Refactored DepthCombo - use custom renderer to display presentable depth labels (instead of separate DepthWithName class)
c20bfe7: svn: Replaced SVNDepth (from SVNKit) with custom Depth enum
0e8564a: Merge remote-tracking branch 'origin/master'
c3e78ad: Add read action.
54474d0: TestDataGuessByExistingFilesUtil: prevent thread starvation and use processor to avoid several huge String collections in the memory (IDEA-127038)
02c1b76: svn: Utilized CommitInfo when parsing "svn list" output and for DirectoryEntry implementation
ac00218: svn: Unified "lock" information parsing for info, status and browse clients (utilized Lock class for all cases)
3ea1e9e: Merge remote-tracking branch 'origin/master'
61c9bc4: highlight matches in selected search result
e3fd6eb: don't add a newline when completing with smart enter shortcut (IDEA-126726)
4029019: EA-57959 - ISE: DomInvocationHandler.getAttributeChild diagnostics
e3c7a70: don't require PerformanceWatcher unresponsiveness threshold to be divisible by unresponsiveness interval (IDEA-127038)
02b931c: diff: fix NPE
dc4f600: Merge remote-tracking branch 'origin/master'
bcc88e8: svn: Replaced SVNLock (from SVNKit) with custom Lock class
f21bc13: svn: Replaced SVNDirEntry (from SVNKit) with custom DirectoryEntry class
8434e55: svn: Fixed NPE in SvnKitBrowseClient (SVNLogClient.doList() logic) - use SVNRevision.UNDEFINED if null is passed
e6f257f: Added multi-associations in win (un)installer with the controls on the option page.
6eb7f53: svn: Replaced ISVNAnnotateHandler (from SVNKit) with custom AnnotationConsumer class
535cb8c: svn: Refactored SvnRemoteFileAnnotation - removed unused fields
56cd6a8: svn: Refactored BaseSvnFileAnnotation - utilized CommitInfo for implementation logic
6916bac: svn: Refactored BaseSvnFileAnnotation - code simplified, duplication and unused code removed, warnings fixed
79f167e: svn: Utilized CommitInfo when parsing "svn annotate" output
5585db2: svn: Replaced SVNCommitInfo (from SVNKit) with custom CommitInfo class
3b0971e: svn: Replaced SVNDiffOptions (from SVNKit) with custom DiffOptions class
58ab1b9: svn: Replaced SVNConflictVersion (from SVNKit) with custom ConflictVersion class
d287078: svn: Fixed "memory leak" error (on application close) after viewing merge source hierarchy details - correctly register dialogs for disposal
ef3bc87: svn: Refactored TreeStructureNode - made not to be generic, renamed
ff2698d: svn: Unified LogEntry and LogEntryPath with corresponding similar classes used for svn executable xml output parsing
00224be: svn: Replaced SVNLogEntryPath (from SVNKit) with custom LogEntryPath class
6a330b5: svn: Replaced SVNLogEntry (from SVNKit) with custom LogEntry class
615f0cb: svn: Refactored parsing of child xml elements collections - use @XmlElementWrapper (instead of intermediate classes)
5ac00c0: svn: Refactored SvnUtil - moved "getPathForProgress" to ProgressEvent
cef6176: svn: Refactored ProgressTracker - removed unused method parameters, make inherit ThrowableConsumer
17cbb94: svn: Replaced SVNEvent (from SVNKit) with custom ProgressEvent class
57e1c41: svn: Preserve several more used fields when converting from SVNStatus to Status
37798c0: svn: Allow @Nullable values when converting SVNKit types to corresponding svn4idea types
ea32a54: IDEA-125627 Added new conflict reason values available in svn 1.8
099870d: svn: Replaced SVNConflictAction, SVNConflictReason, SVNOperation (from SVNKit) with corresponding custom enums
6dc734f: svn: Replaced SVNTreeConflictDescription (from SVNKit) with custom TreeConflictDescription class
57db2a5: svn: Replaced SVNStatus (from SVNKit) with custom Status class
6730240: svn: Replaced SVNInfo (from SVNKit) with custom Info class
b527300: svn: Removed unnecessary IdeaSVNInfo - directly use SVNInfo instead
46fdb20: svn: Refactored UpdateClient - make methods throw SvnBindException (instead of SVNException from SVNKit)
9ccd315: svn: Refactored StatusClient - make methods throw SvnBindException (instead of SVNException from SVNKit)
bb3582d: svn: Refactored RepeatSvnActionThroughBusy - make methods throw VcsException (instead of SVNException from SVNKit)
33b3795: svn: Refactored InfoClient - make methods throw SvnBindException (instead of SVNException from SVNKit)
ab74ce3: svn: Refactored CmdInfoClient - removed duplication, methods extracted/inlined, @NotNull
29f24cf: svn: Refactored CmdInfoClient - inlined "doInfo" methods, removed duplication
17d79f7: svn: Refactored UpdateClient - removed unnecessary methods
19cc497: svn: Refactored StatusClient - removed unnecessary "doStatus" overload method (call replaced with more general overload)
faa09ef: svn: Refactored StatusClient - removed unnecessary methods
b45cfaa: svn: Refactored StatusClient - removed unnecessary "doStatus(File path, boolean remote, boolean collectParentExternals)" overload method (as always invoked with collectParentExternals = false)
ae24d84: svn: Refactored InfoClient - removed unnecessary methods
2e97768: svn: Added some todo items for working copies of 1.8 and greater formats (cleanup, nested working copies file status refresh)
7874cb3: svn: Refactored SvnCheckoutProvider - removed unused parameters, @NotNull
22b2900: svn: Refactored SvnCheckinHandlerFactory - code simplifications, warnings fixes
1ce0847: IDEA-118540 Refactored "committing changes to same repository but from working copies of different formats" detection logic, updated confirmation message
491ac7d: svn: Updated working copy format checks to be "weaker" - to correctly support working copies with greater than svn 1.8 formats
Change-Id: I25f808eb8c86e4bd21610b40ab6b6df310d8e636
Diffstat (limited to 'platform/vcs-impl')
20 files changed, 616 insertions, 216 deletions
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java index 3008138c60a2..291289854fa7 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java @@ -169,6 +169,7 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware, Ann if (vcs == null) return; final AnnotationProvider annotationProvider = vcs.getCachingAnnotationProvider(); + assert annotationProvider != null; final Ref<FileAnnotation> fileAnnotationRef = new Ref<FileAnnotation>(); final Ref<VcsException> exceptionRef = new Ref<VcsException>(); @@ -190,7 +191,7 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware, Ann exceptionRef.set(e); } catch (Throwable t) { - handler.completed(file.getPath()); + exceptionRef.set(new VcsException(t)); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/MapIgnoredFilesHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/MapIgnoredFilesHolder.java index 297e46482135..5ba7ce8cab0e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/MapIgnoredFilesHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/MapIgnoredFilesHolder.java @@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.hash.HashSet; +import gnu.trove.THashSet; import java.util.Collection; import java.util.Set; @@ -40,8 +40,8 @@ public class MapIgnoredFilesHolder extends AbstractIgnoredFilesHolder { public MapIgnoredFilesHolder(Project project) { super(project); myProject = project; - mySet = new HashSet<VirtualFile>(); - myVcsIgnoredSet = new HashSet<VirtualFile>(); //collect ignored files from VcsChangeProvider -> processIgnored + mySet = new THashSet<VirtualFile>(); + myVcsIgnoredSet = new THashSet<VirtualFile>(); //collect ignored files from VcsChangeProvider -> processIgnored } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java index 0ff134eb723a..7870b7ddbe02 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java @@ -16,13 +16,11 @@ package com.intellij.openapi.vcs.changes; import com.intellij.lifecycle.PeriodicalTasksCloser; -import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Couple; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Getter; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.*; @@ -57,12 +55,12 @@ public class RemoteRevisionsCache implements PlusMinus<Pair<String, AbstractVcs> private final Object myLock; private final Map<String, RemoteDifferenceStrategy> myKinds; private final ControlledCycle myControlledCycle; - private final MessageBusConnection myConnection; public static RemoteRevisionsCache getInstance(final Project project) { return PeriodicalTasksCloser.getInstance().safeGetService(project, RemoteRevisionsCache.class); } + @SuppressWarnings("UnusedDeclaration") // initialized as a Service private RemoteRevisionsCache(final Project project) { myProject = project; myLock = new Object(); @@ -73,15 +71,11 @@ public class RemoteRevisionsCache implements PlusMinus<Pair<String, AbstractVcs> myChangeDecorator = new RemoteStatusChangeNodeDecorator(this); myVcsManager = ProjectLevelVcsManager.getInstance(project); - myConnection = myProject.getMessageBus().connect(); - myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); - myConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED_IN_PLUGIN, this); + MessageBusConnection connection = myProject.getMessageBus().connect(); + connection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); + connection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED_IN_PLUGIN, this); myKinds = new HashMap<String, RemoteDifferenceStrategy>(); - Disposer.register(project, new Disposable() { - public void dispose() { - myConnection.disconnect(); - } - }); + final VcsConfiguration vcsConfiguration = VcsConfiguration.getInstance(myProject); myControlledCycle = new ControlledCycle(project, new Getter<Boolean>() { @Override @@ -92,7 +86,14 @@ public class RemoteRevisionsCache implements PlusMinus<Pair<String, AbstractVcs> boolean somethingChanged = myRemoteRevisionsNumbersCache.updateStep(); somethingChanged |= myRemoteRevisionsStateCache.updateStep(); if (somethingChanged) { - myProject.getMessageBus().syncPublisher(REMOTE_VERSION_CHANGED).run(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + if (!myProject.isDisposed()) { + myProject.getMessageBus().syncPublisher(REMOTE_VERSION_CHANGED).run(); + } + } + }); } } return shouldBeDone; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java index 93919fcb2bd0..fdc079641b68 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java @@ -66,14 +66,14 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { } public void processChange(final Change change, VcsKey vcsKey) { - processChangeInList( change, (ChangeList) null, vcsKey); + processChangeInList(change, (ChangeList)null, vcsKey); } public void processChangeInList(final Change change, @Nullable final ChangeList changeList, final VcsKey vcsKey) { checkIfDisposed(); LOG.debug("[processChangeInList-1] entering, cl name: " + ((changeList == null) ? null: changeList.getName()) + - " change: " + ChangesUtil.getFilePath(change).getPath()); + " change: " + ChangesUtil.getFilePath(change).getPath()); final String fileName = ChangesUtil.getFilePath(change).getName(); if (FileTypeManager.getInstance().isFileIgnored(fileName)) { LOG.debug("[processChangeInList-1] file type ignored"); @@ -86,11 +86,13 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { if (changeList != null) { LOG.debug("[processChangeInList-1] to add change to cl"); myChangeListWorker.addChangeToList(changeList.getName(), change, vcsKey); - } else { + } + else { LOG.debug("[processChangeInList-1] to add to corresponding list"); myChangeListWorker.addChangeToCorrespondingList(change, vcsKey); } - } else { + } + else { LOG.debug("[processChangeInList-1] not under scope"); } } @@ -203,7 +205,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { if (file == null) return; checkIfDisposed(); if (myScope.belongsTo(new FilePathImpl(file))) { - ((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).add(file, logicalLock); + ((LogicallyLockedHolder)myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).add(file, logicalLock); } } @@ -220,7 +222,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder { if (file == null) return; checkIfDisposed(); if (myScope.belongsTo(new FilePathImpl(file))) { - ((SwitchedFileHolder) myComposite.get(FileHolder.HolderType.ROOT_SWITCH)).addFile(file, branch, false); + ((SwitchedFileHolder)myComposite.get(FileHolder.HolderType.ROOT_SWITCH)).addFile(file, branch, false); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java index f5abcf039ece..00ca9f2ebf4f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java @@ -22,6 +22,7 @@ import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -34,7 +35,7 @@ public class VcsGuess { VcsGuess(final Project project) { myProject = project; - myVcsManager = (ProjectLevelVcsManagerImpl) ProjectLevelVcsManagerImpl.getInstance(myProject); + myVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(myProject); myExcludedFileIndex = PeriodicalTasksCloser.getInstance().safeGetService(myProject, FileIndexFacade.class); } @@ -72,14 +73,14 @@ public class VcsGuess { final boolean inContent = myVcsManager.isFileInContent(validParent); if (inContent) return true; if (filePath != null) { - return isFileInBaseDir(filePath, myProject.getBaseDir()) && ! myExcludedFileIndex.isExcludedFile(validParent); + return isFileInBaseDir(filePath, myProject.getBaseDir()) && !myExcludedFileIndex.isExcludedFile(validParent); } return false; } }); } - private boolean isFileInBaseDir(final FilePath filePath, final VirtualFile baseDir) { + private static boolean isFileInBaseDir(final FilePath filePath, final VirtualFile baseDir) { final VirtualFile parent = filePath.getVirtualFileParent(); return !filePath.isDirectory() && parent != null && parent.equals(baseDir); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java index 21ee42093193..2b4ea995448b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FilePath; @@ -445,7 +446,7 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP ContentRevision afterRevision = change.getAfterRevision(); if (afterRevision == null) return false; FilePath file = afterRevision.getFile(); - return file.getName().equals(toSelect.getName()); + return FileUtil.pathsEqual(file.getPath(), toSelect.getPath()); } protected abstract DefaultTreeModel buildTreeModel(final List<T> changes, final ChangeNodeDecorator changeNodeDecorator); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java index 83dc7ebd8b21..aaa512c4e674 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java @@ -35,7 +35,7 @@ public class CopyLineStatusRangeAction extends BaseLineStatusRangeAction { } public void actionPerformed(final AnActionEvent e) { - final String content = myLineStatusTracker.getUpToDateContent(myRange); + final String content = myLineStatusTracker.getUpToDateContent(myRange).toString(); CopyPasteManager.getInstance().setContents(new StringSelection(content)); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java index d6362ffe19c9..1674b55ff3b6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java @@ -38,21 +38,14 @@ public class DocumentWrapper { @NotNull public List<String> getLines() { - return getLines(0, myDocument.getLineCount() - 1); + return getLines(0, getLineCount(myDocument) - 1); } @NotNull public List<String> getLines(int from, int to) { ArrayList<String> result = new ArrayList<String>(); for (int i = from; i <= to; i++) { - if (i >= myDocument.getLineCount()) break; - final String line = getLine(i); - /* - if (line.length() > 0 || i < to) { - result.add(line); - } - */ - result.add(line); + result.add(getLine(i)); } return result; } @@ -65,5 +58,9 @@ public class DocumentWrapper { } return myDocument.getText(range); } + + private static int getLineCount(@NotNull Document document) { + return Math.max(document.getLineCount(), 1); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java index ac0bc8608368..44a56e7df517 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -175,10 +175,10 @@ public class LineStatusTracker { LOG.assertTrue(!myReleased, "Already released"); int first = - range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset1()); + range.getOffset1() >= getLineCount(myDocument) ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset1()); int second = - range.getOffset2() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset2()); + range.getOffset2() >= getLineCount(myDocument) ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset2()); final RangeHighlighter highlighter = DocumentMarkupModel.forDocument(myDocument, myProject, true) .addRangeHighlighter(first, second, HighlighterLayer.FIRST - 1, null, HighlighterTargetArea.LINES_IN_RANGE); @@ -259,6 +259,7 @@ public class LineStatusTracker { if (range.getHighlighter() != null) { range.getHighlighter().dispose(); } + range.invalidate(); } myRanges.clear(); } @@ -316,10 +317,10 @@ public class LineStatusTracker { if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return; try { myFirstChangedLine = myDocument.getLineNumber(e.getOffset()); - myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength()); - myChangedLines = myLastChangedLine - myFirstChangedLine; + myLastChangedLine = e.getOldLength() == 0 ? myFirstChangedLine : myDocument.getLineNumber(e.getOffset() + e.getOldLength() - 1); if (StringUtil.endsWithChar(e.getOldFragment(), '\n')) myLastChangedLine++; - myTotalLines = e.getDocument().getLineCount(); + myChangedLines = myLastChangedLine - myFirstChangedLine; + myTotalLines = getLineCount(e.getDocument()); } catch (ProcessCanceledException ignore) { } @@ -334,9 +335,14 @@ public class LineStatusTracker { if (myReleased) return; if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return; try { - int currentChangedLines = myDocument.getLineNumber(e.getOffset() + e.getNewLength()) - myDocument.getLineNumber(e.getOffset()); + int currentFirstChangedLine = myFirstChangedLine; + int currentLastChangedLine = + e.getNewLength() == 0 ? currentFirstChangedLine : myDocument.getLineNumber(e.getOffset() + e.getNewLength() - 1); + if (StringUtil.endsWithChar(e.getNewFragment(), '\n')) currentLastChangedLine++; + int currentChangedLines = currentLastChangedLine - currentFirstChangedLine; + int upToDateTotalLine = getLineCount(myUpToDateDocument); + int linesShift = currentChangedLines - myChangedLines; - int upToDateTotalLine = myUpToDateDocument.getLineCount(); List<Range> rangesBeforeChange = new ArrayList<Range>(); List<Range> rangesAfterChange = new ArrayList<Range>(); @@ -355,13 +361,14 @@ public class LineStatusTracker { myLastChangedLine = lastChangedRange.getOffset2() - 1; } - int currentFirstLine = myFirstChangedLine; - int currentLastLine = myLastChangedLine + linesShift; + currentFirstChangedLine = myFirstChangedLine; + currentLastChangedLine = myLastChangedLine + linesShift; int upToDateFirstLine = getUpToDateLine1(lastRangeBefore, myFirstChangedLine); int upToDateLastLine = getUpToDateLine2(firstRangeAfter, myLastChangedLine, myTotalLines, upToDateTotalLine); - List<Range> newChangedRanges = getNewChangedRanges(currentFirstLine, currentLastLine, upToDateFirstLine, upToDateLastLine); + List<Range> newChangedRanges = + getNewChangedRanges(currentFirstChangedLine, currentLastChangedLine, upToDateFirstLine, upToDateLastLine); shiftRanges(rangesAfterChange, linesShift); @@ -426,6 +433,7 @@ public class LineStatusTracker { range.getHighlighter().dispose(); } range.setHighlighter(null); + range.invalidate(); } for (Range range : newRangesInChange) { range.setHighlighter(createHighlighter(range)); @@ -531,98 +539,207 @@ public class LineStatusTracker { } } - public void rollbackChanges(final Range range) { + public void rollbackChanges(@NotNull Range range) { myApplication.assertWriteAccessAllowed(); synchronized (myLock) { - TextRange currentTextRange = getCurrentTextRangeWithMagic(range); + if (!range.isValid()) { + LOG.warn("Rollback of invalid range"); + return; + } + + if (range.getType() == Range.MODIFIED) { + TextRange currentTextRange = getCurrentTextRange(range); + int offset1 = currentTextRange.getStartOffset(); + int offset2 = currentTextRange.getEndOffset(); - int offset1 = currentTextRange.getStartOffset(); - int offset2 = Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()); - if (range.getType() == Range.INSERTED) { - myDocument.replaceString(offset1, offset2, ""); + CharSequence upToDateContent = getUpToDateContent(range); + myDocument.replaceString(offset1, offset2, upToDateContent); + } + else if (range.getType() == Range.INSERTED) { + TextRange currentTextRange = getCurrentTextRange(range); + int offset1 = currentTextRange.getStartOffset(); + int offset2 = currentTextRange.getEndOffset(); + + if (offset1 > 0) { + offset1--; + } + else if (offset2 < myDocument.getTextLength()) { + offset2++; + } + myDocument.deleteString(offset1, offset2); } else if (range.getType() == Range.DELETED) { - String upToDateContent = getUpToDateContentWithMagic(range); - myDocument.insertString(offset1, upToDateContent); + CharSequence content = getUpToDateContent(range); + if (range.getOffset2() == getLineCount(myDocument)) { + myDocument.insertString(myDocument.getTextLength(), "\n" + content); + } + else { + myDocument.insertString(myDocument.getLineStartOffset(range.getOffset2()), content + "\n"); + } } else { - String upToDateContent = getUpToDateContentWithMagic(range); - myDocument.replaceString(offset1, offset2, upToDateContent); + throw new IllegalArgumentException("Unknown range type: " + range.getType()); } } } - public String getUpToDateContentWithMagic(Range range) { - synchronized (myLock) { - TextRange textRange = getUpToDateRangeWithMagic(range); - final int startOffset = textRange.getStartOffset(); - final int endOffset = Math.min(textRange.getEndOffset() + 1, myUpToDateDocument.getTextLength()); - return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset).toString(); - } - } + public void rollbackChanges(@NotNull SegmentTree lines) { + myApplication.assertWriteAccessAllowed(); - public String getUpToDateContent(Range range) { synchronized (myLock) { - TextRange textRange = getUpToDateRange(range); - final int startOffset = textRange.getStartOffset(); - final int endOffset = Math.min(textRange.getEndOffset() + 1, myUpToDateDocument.getTextLength()); - return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset).toString(); + List<Range> affectedRanges = new ArrayList<Range>(); + + boolean wasEnd = false; + boolean simple = true; + for (Range range : myRanges) { + if (!range.isValid()) { + LOG.warn("Rollback of invalid range"); + return; + } + + boolean check; + if (range.getOffset1() == range.getOffset2()) { + check = lines.check(range.getOffset1()); + } + else { + check = lines.check(range.getOffset1(), range.getOffset2()); + } + if (check) { + if (wasEnd) simple = false; + affectedRanges.add(range); + } + else { + if (!affectedRanges.isEmpty()) wasEnd = true; + } + } + + if (simple) { + rollbackChangesSimple(affectedRanges); + } + else { + rollbackChangesComplex(affectedRanges); + } } } - Project getProject() { - return myProject; + private void rollbackChangesSimple(@NotNull List<Range> ranges) { + if (ranges.isEmpty()) return; + + Range first = ranges.get(0); + Range last = ranges.get(ranges.size() - 1); + + byte type = first == last ? first.getType() : Range.MODIFIED; + final Range merged = new Range(first.getOffset1(), last.getOffset2(), first.getUOffset1(), last.getUOffset2(), type); + + // We don't expect complex Insertion/Deletion operation - they shouldn't exist + assert type != Range.MODIFIED || (first.getOffset1() != last.getOffset2() && first.getUOffset1() != last.getUOffset2()); + + rollbackChanges(merged); } - @NotNull - TextRange getCurrentTextRangeWithMagic(@NotNull Range range) { - return getRangeWithMagic(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument); + private void rollbackChangesComplex(@NotNull List<Range> ranges) { + // We can't relay on assumption, that revert of a single change will not affect any other. + // This, among the others, is because of 'magic' ranges for revert, that will affect nearby lines implicitly. + // So it's dangerous to apply ranges ony-by-one and we have to create single atomic modification. + // Usage of Bulk mode will lead to full rebuild of tracker, and therefore will be slow.. + + if (ranges.isEmpty()) return; + if (ranges.size() == 1) { + rollbackChanges(ranges.get(0)); + return; + } + + Range first = ranges.get(0); + Range last = ranges.get(ranges.size() - 1); + + // We don't expect complex Insertion/Deletion operation - they shouldn't exist. + assert first != last && first.getOffset1() != last.getOffset2() && first.getUOffset1() != last.getUOffset2(); + + final int start = getCurrentTextRange(first).getStartOffset(); + final int end = getCurrentTextRange(last).getEndOffset(); + + StringBuilder builder = new StringBuilder(); + + int lastOffset = start; + for (Range range : ranges) { + TextRange textRange = getCurrentTextRange(range); + + builder.append(myDocument.getText(new TextRange(lastOffset, textRange.getStartOffset()))); + lastOffset = textRange.getEndOffset(); + + if (range.getType() == Range.MODIFIED) { + builder.append(getUpToDateContent(range)); + } + else if (range.getType() == Range.INSERTED) { + if (builder.length() > 0) { + builder.deleteCharAt(builder.length() - 1); + } + else { + lastOffset++; + } + } + else if (range.getType() == Range.DELETED) { + CharSequence content = getUpToDateContent(range); + if (range.getOffset2() == getLineCount(myDocument)) { + builder.append('\n').append(content); + } + else { + builder.append(content).append('\n'); + } + } + else { + throw new IllegalArgumentException("Unknown range type: " + range.getType()); + } + } + builder.append(myDocument.getText(new TextRange(lastOffset, end))); + + final String s = builder.toString(); + + myDocument.replaceString(start, end, s); } - @NotNull - TextRange getUpToDateRangeWithMagic(@NotNull Range range) { - return getRangeWithMagic(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument); + public CharSequence getUpToDateContent(@NotNull Range range) { + synchronized (myLock) { + TextRange textRange = getUpToDateRange(range); + final int startOffset = textRange.getStartOffset(); + final int endOffset = textRange.getEndOffset(); + return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset); + } } @NotNull TextRange getCurrentTextRange(@NotNull Range range) { - return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument); - } + synchronized (myLock) { + if (!range.isValid()) { + LOG.warn("Current TextRange of invalid range"); + } - @NotNull - TextRange getUpToDateRange(@NotNull Range range) { - return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument); + return getRange(range.getOffset1(), range.getOffset2(), myDocument); + } } @NotNull - private static TextRange getRangeWithMagic(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) { - if (rangeType == emptyRangeCondition) { - int lineStartOffset; - if (offset1 == 0) { - lineStartOffset = 0; - } - else { - lineStartOffset = document.getLineEndOffset(offset1 - 1); - } - //if (lineStartOffset > 0) lineStartOffset--; - return new TextRange(lineStartOffset, lineStartOffset); - } - else { - int startOffset = document.getLineStartOffset(offset1); - int endOffset = document.getLineEndOffset(offset2 - 1); - if (startOffset > 0) { - --startOffset; - --endOffset; + TextRange getUpToDateRange(@NotNull Range range) { + synchronized (myLock) { + if (!range.isValid()) { + LOG.warn("UpToDate TextRange of invalid range"); } - return new TextRange(startOffset, endOffset); + + return getRange(range.getUOffset1(), range.getUOffset2(), myUpToDateDocument); } } + /** + * Return affected range, without non-internal '\n' + * so if last line is not empty, the last symbol will be not '\n' + * <p/> + * So we consider '\n' not as a part of line, but a separator between lines + */ @NotNull - private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) { - if (rangeType == emptyRangeCondition) { - int lineStartOffset = offset1 < document.getLineCount() ? document.getLineStartOffset(offset1) : document.getTextLength(); + private static TextRange getRange(int offset1, int offset2, @NotNull Document document) { + if (offset1 == offset2) { + int lineStartOffset = offset1 < getLineCount(document) ? document.getLineStartOffset(offset1) : document.getTextLength(); return new TextRange(lineStartOffset, lineStartOffset); } else { @@ -643,7 +760,11 @@ public class LineStatusTracker { } } - public static enum BaseLoadState { + Project getProject() { + return myProject; + } + + public enum BaseLoadState { LOADING, FAILED, LOADED @@ -705,4 +826,8 @@ public class LineStatusTracker { myLabel.setText("Can not highlight changed lines. File is too big and there are too many changes."); } } + + private static int getLineCount(@NotNull Document document) { + return Math.max(document.getLineCount(), 1); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index 24884b4a101c..6f1cd15ef018 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -160,7 +160,7 @@ public class LineStatusTrackerDrawing { localShowPrevAction.copyFrom(globalShowPrevAction); final RollbackLineStatusRangeAction rollback = new RollbackLineStatusRangeAction(tracker, range, editor); - EmptyAction.setupAction(rollback, IdeActions.CHANGES_VIEW_ROLLBACK, editorComponent); + EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent); group.add(rollback); group.add(new ShowLineStatusRangeDiffAction(tracker, range, editor)); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java index 5727c62f4d14..e166acd30fec 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java @@ -42,6 +42,8 @@ public class Range { private final byte myType; @Nullable private RangeHighlighter myRangeHighlighter; + private boolean myValid = true; + public static Range createOn(@NotNull Diff.Change change, int shift, int upToDateShift) { byte type = getChangeTypeFrom(change); @@ -158,4 +160,12 @@ public class Range { public RangeHighlighter getHighlighter() { return myRangeHighlighter; } + + public boolean isValid() { + return myValid; + } + + public void invalidate() { + myValid = false; + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java new file mode 100644 index 000000000000..59697f1222dd --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java @@ -0,0 +1,136 @@ +/* + * Copyright 2000-2010 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 com.intellij.openapi.vcs.ex; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.VcsBundle; +import com.intellij.openapi.vcs.impl.LineStatusTrackerManager; +import com.intellij.openapi.vfs.ReadonlyStatusHandler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class RollbackLineStatusAction extends DumbAwareAction { + public RollbackLineStatusAction() { + super("Rollback", "Rollback selected changes", AllIcons.Actions.Reset); + } + + @Override + public void update(AnActionEvent e) { + Project project = e.getProject(); + if (project == null) { + e.getPresentation().setEnabled(false); + return; + } + Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + if (editor == null) { + e.getPresentation().setEnabled(false); + return; + } + LineStatusTracker tracker = LineStatusTrackerManager.getInstance(project).getLineStatusTracker(editor.getDocument()); + if (tracker == null) { + e.getPresentation().setEnabled(false); + return; + } + e.getPresentation().setEnabled(true); + } + + @Override + public void actionPerformed(AnActionEvent e) { + Project project = e.getProject(); + Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); + LineStatusTracker tracker = LineStatusTrackerManager.getInstance(project).getLineStatusTracker(editor.getDocument()); + if (tracker == null) return; + + rollback(tracker, editor, null); + } + + protected static void rollback(@NotNull LineStatusTracker tracker, @Nullable Editor editor, @Nullable Range range) { + if (range != null) { + doRollback(tracker, range); + return; + } + + if (editor == null) return; + Document document = editor.getDocument(); + int totalLines = getLineCount(document); + + SegmentTree lines = new SegmentTree(totalLines + 1); + + List<Caret> carets = editor.getCaretModel().getAllCarets(); + for (Caret caret : carets) { + if (caret.hasSelection()) { + int line1 = editor.offsetToLogicalPosition(caret.getSelectionStart()).line; + int line2 = editor.offsetToLogicalPosition(caret.getSelectionEnd()).line; + lines.mark(line1, line2 + 1); + if (caret.getSelectionEnd() == document.getTextLength()) lines.mark(totalLines); + } + else { + lines.mark(caret.getLogicalPosition().line); + if (caret.getOffset() == document.getTextLength()) lines.mark(totalLines); + } + } + + doRollback(tracker, lines); + } + + private static void doRollback(@NotNull final LineStatusTracker tracker, @NotNull final Range range) { + execute(tracker, new Runnable() { + @Override + public void run() { + tracker.rollbackChanges(range); + } + }); + } + + private static void doRollback(@NotNull final LineStatusTracker tracker, @NotNull final SegmentTree lines) { + execute(tracker, new Runnable() { + @Override + public void run() { + tracker.rollbackChanges(lines); + } + }); + } + + private static void execute(@NotNull final LineStatusTracker tracker, @NotNull final Runnable task) { + // TODO: is there possible data races? + CommandProcessor.getInstance().executeCommand(tracker.getProject(), new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + if (!tracker.getDocument().isWritable()) { + final ReadonlyStatusHandler.OperationStatus operationStatus = ReadonlyStatusHandler + .getInstance(tracker.getProject()).ensureFilesWritable(tracker.getVirtualFile()); + if (operationStatus.hasReadonlyFiles()) return; + } + task.run(); + } + }); + } + }, VcsBundle.message("command.name.rollback.change"), null); + } + + private static int getLineCount(@NotNull Document document) { + return Math.max(document.getLineCount(), 1); + } +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusRangeAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusRangeAction.java index ed5846d20ade..f1795b5efc3c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusRangeAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusRangeAction.java @@ -12,41 +12,28 @@ */ package com.intellij.openapi.vcs.ex; -import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.vcs.VcsBundle; -import com.intellij.openapi.vfs.ReadonlyStatusHandler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -/** -* @author irengrig -*/ -public class RollbackLineStatusRangeAction extends BaseLineStatusRangeAction { - public RollbackLineStatusRangeAction(final LineStatusTracker lineStatusTracker, final Range range, final Editor editor) { - super(VcsBundle.message("action.name.rollback"), AllIcons.Actions.Reset, lineStatusTracker, range); +public class RollbackLineStatusRangeAction extends RollbackLineStatusAction { + @NotNull private final LineStatusTracker myTracker; + @Nullable private final Editor myEditor; + @NotNull private final Range myRange; + + public RollbackLineStatusRangeAction(@NotNull LineStatusTracker tracker, @NotNull Range range, @Nullable Editor editor) { + myTracker = tracker; + myEditor = editor; + myRange = range; } - public boolean isEnabled() { - return true; + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(true); } public void actionPerformed(final AnActionEvent e) { - CommandProcessor.getInstance().executeCommand(myLineStatusTracker.getProject(), new Runnable() { - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - if (!myLineStatusTracker.getDocument().isWritable()) { - final ReadonlyStatusHandler.OperationStatus operationStatus = ReadonlyStatusHandler - .getInstance(myLineStatusTracker.getProject()).ensureFilesWritable(myLineStatusTracker.getVirtualFile()); - if (operationStatus.hasReadonlyFiles()) return; - } - myLineStatusTracker.rollbackChanges(myRange); - } - }); - } - }, VcsBundle.message("command.name.rollback.change"), null); - + rollback(myTracker, myEditor, myRange); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/SegmentTree.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/SegmentTree.java new file mode 100644 index 000000000000..68307129c13e --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/SegmentTree.java @@ -0,0 +1,116 @@ +package com.intellij.openapi.vcs.ex; + +import org.jetbrains.annotations.Nullable; + +public class SegmentTree { + private final int myActualLength; + private final int myLength; + + private final Node myRoot; + + public SegmentTree(int length) { + myActualLength = length; + myLength = toUpperSquare(length); + myRoot = new Node(); + } + + public void mark(int pos) { + mark(pos, pos + 1); + } + + public void mark(int start, int end) { + start = correct(0, myActualLength, start); + end = correct(0, myActualLength, end); + + myRoot.mark(0, myLength, start, end); + } + + public boolean check(int pos) { + return check(pos, pos + 1); + } + + public boolean check(int start, int end) { + start = correct(0, myActualLength, start); + end = correct(0, myActualLength, end); + + return myRoot.check(0, myLength, start, end); + } + + private static int toUpperSquare(int value) { + int high = Integer.highestOneBit(value); + return high == value ? value : high * 2; + } + + private static class Node { + @Nullable + public Node myLeft; + + @Nullable + public Node myRight; + + public boolean myMarked; + + public boolean mark(int thisStart, int thisEnd, int start, int end) { + if (myLeft == null && myMarked) return true; + + if (start == end) return false; + + myMarked = true; + + if (thisStart == start && thisEnd == end) { + myLeft = null; + myRight = null; + return true; + } + + if (myLeft == null) { + myLeft = new Node(); + myRight = new Node(); + } + + int mid = thisStart + (thisEnd - thisStart) / 2; + int start1 = correct(thisStart, mid, start); + int end1 = correct(thisStart, mid, end); + int start2 = correct(mid, thisEnd, start); + int end2 = correct(mid, thisEnd, end); + + boolean marked = true; + marked &= myLeft.mark(thisStart, mid, start1, end1); + marked &= myRight.mark(mid, thisEnd, start2, end2); + + if (marked) { + myLeft = null; + myRight = null; + } + + return marked; + } + + public boolean check(int thisStart, int thisEnd, int start, int end) { + if (start == end) return false; + + if (thisStart == start && thisEnd == end) { + return myMarked; + } + + if (myLeft == null) return myMarked; + + int mid = thisStart + (thisEnd - thisStart) / 2; + int start1 = correct(thisStart, mid, start); + int end1 = correct(thisStart, mid, end); + int start2 = correct(mid, thisEnd, start); + int end2 = correct(mid, thisEnd, end); + + if (myLeft.check(thisStart, mid, start1, end1)) return true; + if (myRight.check(mid, thisEnd, start2, end2)) return true; + + return false; + } + } + + private static int correct(int start, int end, int value) { + if (value < start) return start; + if (value > end) return end; + return value; + } +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java index c5dba0cab29c..38f65446a56f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java @@ -25,27 +25,22 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author irengrig */ public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction { - public ShowLineStatusRangeDiffAction(final LineStatusTracker lineStatusTracker, final Range range, final Editor editor) { + public ShowLineStatusRangeDiffAction(@NotNull LineStatusTracker lineStatusTracker, @NotNull Range range, @Nullable Editor editor) { super(VcsBundle.message("action.name.show.difference"), AllIcons.Actions.Diff, lineStatusTracker, range); } + @Override public boolean isEnabled() { - return isModifiedRange() || isDeletedRange(); - } - - private boolean isDeletedRange() { - return Range.DELETED == myRange.getType(); - } - - private boolean isModifiedRange() { - return Range.MODIFIED == myRange.getType(); + return true; } + @Override public void actionPerformed(final AnActionEvent e) { DiffManager.getInstance().getDiffTool().show(createDiffData()); } @@ -54,12 +49,13 @@ public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction { return new DiffRequest(myLineStatusTracker.getProject()) { @NotNull public DiffContent[] getContents() { + Range range = expand(myRange, myLineStatusTracker.getDocument(), myLineStatusTracker.getUpToDateDocument()); return new DiffContent[]{ createDiffContent(myLineStatusTracker.getUpToDateDocument(), - myLineStatusTracker.getUpToDateRange(myRange), + myLineStatusTracker.getUpToDateRange(range), null), createDiffContent(myLineStatusTracker.getDocument(), - myLineStatusTracker.getCurrentTextRange(myRange), + myLineStatusTracker.getCurrentTextRange(range), myLineStatusTracker.getVirtualFile())}; } @@ -74,9 +70,25 @@ public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction { }; } - private DiffContent createDiffContent(final Document uDocument, final TextRange textRange, final VirtualFile file) { + @NotNull + private DiffContent createDiffContent(@NotNull Document uDocument, @NotNull TextRange textRange, @Nullable VirtualFile file) { final Project project = myLineStatusTracker.getProject(); final DiffContent diffContent = new DocumentContent(project, uDocument); return new FragmentContent(diffContent, textRange, project, file); } + + @NotNull + private static Range expand(@NotNull Range range, @NotNull Document document, @NotNull Document uDocument) { + if (range.getType() == Range.MODIFIED) return range; + if (range.getType() == Range.INSERTED || range.getType() == Range.DELETED) { + boolean canExpandBefore = range.getOffset1() != 0 && range.getUOffset1() != 0; + boolean canExpandAfter = range.getOffset2() < document.getLineCount() && range.getUOffset2() < uDocument.getLineCount(); + int offset1 = range.getOffset1() - (canExpandBefore ? 1 : 0); + int uOffset1 = range.getUOffset1() - (canExpandBefore ? 1 : 0); + int offset2 = range.getOffset2() + (canExpandAfter ? 1 : 0); + int uOffset2 = range.getUOffset2() + (canExpandAfter ? 1 : 0); + return new Range(offset1, offset2, uOffset1, uOffset2, range.getType()); + } + throw new IllegalArgumentException("Unknown range type: " + range.getType()); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java index a1fa2baeb1d2..172edc75d02a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java @@ -56,6 +56,7 @@ import com.intellij.openapi.vcs.ui.ReplaceFileConfirmationDialog; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vcs.vfs.VcsFileSystem; import com.intellij.openapi.vcs.vfs.VcsVirtualFile; +import com.intellij.openapi.vcs.vfs.VcsVirtualFolder; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.*; @@ -1123,8 +1124,9 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { VcsFileRevision revision = e.getData( VcsDataKeys.VCS_FILE_REVISION ); final Boolean nonLocal = e.getData(VcsDataKeys.VCS_NON_LOCAL_HISTORY_SESSION); - FileType fileType = revVFile == null ? null : revVFile.getFileType(); - boolean enabled = revision != null && revVFile != null && !fileType.isBinary() && ! Boolean.TRUE.equals(nonLocal); + boolean isFile = revVFile != null && !revVFile.isDirectory(); + FileType fileType = isFile ? revVFile.getFileType() : null; + boolean enabled = revision != null && isFile && !fileType.isBinary() && !Boolean.TRUE.equals(nonLocal); if (enabled) { final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(myVcs.getProject()); @@ -1309,7 +1311,9 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { private VirtualFile createVirtualFileForRevision(VcsFileRevision revision) { if (!myRevisionToVirtualFile.containsKey(revision)) { FilePath filePath = (revision instanceof VcsFileRevisionEx ? ((VcsFileRevisionEx)revision).getPath() : myFilePath); - myRevisionToVirtualFile.put(revision, new VcsVirtualFile(filePath.getPath(), revision, VcsFileSystem.getInstance())); + myRevisionToVirtualFile.put(revision, filePath.isDirectory() + ? new VcsVirtualFolder(filePath.getPath(), null, VcsFileSystem.getInstance()) + : new VcsVirtualFile(filePath.getPath(), revision, VcsFileSystem.getInstance())); } return myRevisionToVirtualFile.get(revision); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java index 4f4efe5137a3..4b057f49b282 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ModuleDefaultVcsRootPolicy.java @@ -21,7 +21,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.StorageScheme; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectEx; @@ -35,7 +34,6 @@ import com.intellij.openapi.vcs.changes.FilePathUnderVcs; import com.intellij.openapi.vcs.changes.VcsGuess; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; import com.intellij.openapi.vcs.impl.projectlevelman.NewMappings; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -102,10 +100,7 @@ public class ModuleDefaultVcsRootPolicy extends DefaultVcsRootPolicy { if (matchContext != null) { return true; } - if (myBaseDir != null && VfsUtilCore.isAncestor(myBaseDir, file, false)) { - return !ProjectRootManager.getInstance(myProject).getFileIndex().isIgnored(file); - } - return false; + return myBaseDir != null && VfsUtilCore.isAncestor(myBaseDir, file, false); } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index cbf9d2b1889a..5cc3a8a9ca92 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -135,7 +135,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme myMappings = new NewMappings(myProject, myMessageBus, this, manager, excludedFileIndex); myMappingsToRoots = new MappingsToRoots(myMappings, myProject); - if (! myProject.isDefault()) { + if (!myProject.isDefault()) { myVcsEventListenerManager = new VcsEventsListenerManagerImpl(); } @@ -203,7 +203,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme } public boolean haveVcses() { - return ! AllVcses.getInstance(myProject).isEmpty(); + return !AllVcses.getInstance(myProject).isEmpty(); } @Override @@ -356,7 +356,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme } public void unregisterVcs(AbstractVcs vcs) { - if (! ApplicationManager.getApplication().isUnitTestMode() && myMappings.haveActiveVcs(vcs.getName())) { + if (!ApplicationManager.getApplication().isUnitTestMode() && myMappings.haveActiveVcs(vcs.getName())) { // unlikely LOG.warn("Active vcs '" + vcs.getName() + "' is being unregistered. Remove from mappings first."); } @@ -391,7 +391,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @Override public boolean hasAnyMappings() { - return ! myMappings.isEmpty(); + return !myMappings.isEmpty(); } @Override @@ -452,7 +452,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme private void releaseEditor() { if (myEditorAdapter != null) { final Editor editor = myEditorAdapter.getEditor(); - if (! editor.isDisposed()) { + if (!editor.isDisposed()) { EditorFactory.getInstance().releaseEditor(editor); } } @@ -472,7 +472,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @Override @NotNull public VcsShowSettingOption getStandardOption(@NotNull VcsConfiguration.StandardOption option, @NotNull AbstractVcs vcs) { - final VcsShowOptionsSettingImpl options = (VcsShowOptionsSettingImpl) getOptions(option); + final VcsShowOptionsSettingImpl options = (VcsShowOptionsSettingImpl)getOptions(option); options.addApplicableVcs(vcs); return options; } @@ -490,7 +490,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @Override public UpdateInfoTree showUpdateProjectInfo(UpdatedFiles updatedFiles, String displayActionName, ActionInfo actionInfo, boolean canceled) { - if (! myProject.isOpen() || myProject.isDisposed()) return null; + if (!myProject.isOpen() || myProject.isDisposed()) return null; ContentManager contentManager = getContentManager(); if (contentManager == null) { return null; // content manager is made null during dispose; flag is set later @@ -537,7 +537,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme public boolean hasExplicitMapping(final VirtualFile vFile) { final VcsDirectoryMapping mapping = myMappings.getMappingFor(vFile); - return mapping != null && ! mapping.isDefaultMapping(); + return mapping != null && !mapping.isDefaultMapping(); } @Override @@ -687,7 +687,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme final AbstractVcs[] vcses = myMappings.getActiveVcses(); for (AbstractVcs vcs : vcses) { final VirtualFile[] roots = getRootsUnderVcs(vcs); - for(VirtualFile root: roots) { + for (VirtualFile root : roots) { vcsRoots.add(new VcsRoot(vcs, root)); } } @@ -708,10 +708,8 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme myMappings.clear(); final List<VcsDirectoryMapping> mappingsList = new ArrayList<VcsDirectoryMapping>(); - final List list = element.getChildren(ELEMENT_MAPPING); boolean haveNonEmptyMappings = false; - for(Object childObj: list) { - Element child = (Element) childObj; + for (Element child : element.getChildren(ELEMENT_MAPPING)) { final String vcs = child.getAttributeValue(ATTRIBUTE_VCS); if (vcs != null && !vcs.isEmpty()) { haveNonEmptyMappings = true; @@ -729,8 +727,9 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme try { rootSettings.readExternal(rootSettingsElement); mapping.setRootSettings(rootSettings); - } catch (InvalidDataException e) { - LOG.error("Failed to load VCS root settings class "+ className + " for VCS " + vcsInstance.getClass().getName(), e); + } + catch (InvalidDataException e) { + LOG.error("Failed to load VCS root settings class " + className + " for VCS " + vcsInstance.getClass().getName(), e); } } } @@ -748,7 +747,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme if (myProject.isDefault()) { element.setAttribute(ATTRIBUTE_DEFAULT_PROJECT, Boolean.TRUE.toString()); } - for(VcsDirectoryMapping mapping: getDirectoryMappings()) { + for (VcsDirectoryMapping mapping : getDirectoryMappings()) { Element child = new Element(ELEMENT_MAPPING); child.setAttribute(ATTRIBUTE_DIRECTORY, mapping.getDirectory()); child.setAttribute(ATTRIBUTE_VCS, mapping.getVcs()); @@ -803,7 +802,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @Override public void fireDirectoryMappingsChanged() { - if (myProject.isOpen() && ! myProject.isDisposed()) { + if (myProject.isOpen() && !myProject.isDisposed()) { myMappings.mappingsChanged(); } } @@ -844,7 +843,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme @Override public Boolean compute() { return vf != null && (myExcludedIndex.isInContent(vf) || isFileInBaseDir(vf) || vf.equals(myProject.getBaseDir()) || - hasExplicitMapping(vf) || isInDirectoryBasedRoot(vf)) && ! myExcludedIndex.isExcludedFile(vf); + hasExplicitMapping(vf) || isInDirectoryBasedRoot(vf)) && !myExcludedIndex.isExcludedFile(vf); } }); } @@ -862,7 +861,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme private boolean isInDirectoryBasedRoot(final VirtualFile file) { if (file == null) return false; - final StorageScheme storageScheme = ((ProjectEx) myProject).getStateStore().getStorageScheme(); + final StorageScheme storageScheme = ((ProjectEx)myProject).getStateStore().getStorageScheme(); if (StorageScheme.DIRECTORY_BASED.equals(storageScheme)) { final VirtualFile baseDir = myProject.getBaseDir(); if (baseDir == null) return false; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java index 8caa6f2bc981..122988896cb2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java @@ -54,12 +54,10 @@ public class VcsRootIterator { public boolean acceptFolderUnderVcs(final VirtualFile vcsRoot, final VirtualFile file) { final String vcsUrl = vcsRoot.getUrl(); final MyRootFilter rootFilter = myOtherVcsFolders.get(vcsUrl); - if ((rootFilter != null) && (! rootFilter.accept(file))) { + if ((rootFilter != null) && (!rootFilter.accept(file))) { return false; } - final Boolean excluded = isExcluded(myExcludedFileIndex, file); - if (excluded) return false; - return true; + return !isExcluded(myExcludedFileIndex, file); } private static boolean isExcluded(final FileIndexFacade indexFacade, final VirtualFile file) { @@ -128,9 +126,9 @@ public class VcsRootIterator { } public static void iterateVcsRoot(final Project project, - final VirtualFile root, - final Processor<FilePath> processor, - @Nullable VirtualFileFilter directoryFilter) { + final VirtualFile root, + final Processor<FilePath> processor, + @Nullable VirtualFileFilter directoryFilter) { final MyRootIterator rootIterator = new MyRootIterator(project, root, processor, null, directoryFilter); rootIterator.iterate(); } @@ -177,9 +175,9 @@ public class VcsRootIterator { @Override public Result visitFileEx(@NotNull VirtualFile file) { if (isExcluded(myExcludedFileIndex, file)) return SKIP_CHILDREN; - if (myRootPresentFilter != null && ! myRootPresentFilter.accept(file)) return SKIP_CHILDREN; - if (myProject.isDisposed() || ! process(file)) return skipTo(myRoot); - if (myDirectoryFilter != null && file.isDirectory() && ! myDirectoryFilter.shouldGoIntoDirectory(file)) return SKIP_CHILDREN; + if (myRootPresentFilter != null && !myRootPresentFilter.accept(file)) return SKIP_CHILDREN; + if (myProject.isDisposed() || !process(file)) return skipTo(myRoot); + if (myDirectoryFilter != null && file.isDirectory() && !myDirectoryFilter.shouldGoIntoDirectory(file)) return SKIP_CHILDREN; return CONTINUE; } }); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java index de1a40d80f36..32fe920fc4db 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java @@ -53,30 +53,31 @@ public class NewMappings { private final DefaultVcsRootPolicy myDefaultVcsRootPolicy; private final MessageBus myMessageBus; private final FileStatusManager myFileStatusManager; - private final FileIndexFacade myExcludedFileIndex; + private final FileIndexFacade myFileIndexFacade; private final Project myProject; private boolean myActivated; public NewMappings(final Project project, final MessageBus messageBus, - final ProjectLevelVcsManagerImpl vcsManager, FileStatusManager fileStatusManager, FileIndexFacade excludedFileIndex) { + final ProjectLevelVcsManagerImpl vcsManager, FileStatusManager fileStatusManager, FileIndexFacade fileIndexFacade) { myProject = project; myMessageBus = messageBus; myFileStatusManager = fileStatusManager; - myExcludedFileIndex = excludedFileIndex; + myFileIndexFacade = fileIndexFacade; myLock = new Object(); myVcsToPaths = new HashMap<String, List<VcsDirectoryMapping>>(); myFileWatchRequestsManager = new FileWatchRequestsManager(myProject, this, LocalFileSystem.getInstance()); myDefaultVcsRootPolicy = DefaultVcsRootPolicy.getInstance(project); myActiveVcses = new AbstractVcs[0]; - if (! myProject.isDefault()) { + if (!myProject.isDefault()) { final ArrayList<VcsDirectoryMapping> listStr = new ArrayList<VcsDirectoryMapping>(); final VcsDirectoryMapping mapping = new VcsDirectoryMapping("", ""); listStr.add(mapping); myVcsToPaths.put("", listStr); - mySortedMappings = new VcsDirectoryMapping[] {mapping}; - } else { + mySortedMappings = new VcsDirectoryMapping[]{mapping}; + } + else { mySortedMappings = VcsDirectoryMapping.EMPTY_ARRAY; } myActivated = false; @@ -131,7 +132,6 @@ public class NewMappings { return; } } - } final Ref<Boolean> switched = new Ref<Boolean>(Boolean.FALSE); @@ -139,7 +139,7 @@ public class NewMappings { public void run() { // sorted -> map. sorted mappings are NOT changed; switched.set(trySwitchVcs(path, activeVcsName)); - if (! switched.get().booleanValue()) { + if (!switched.get().booleanValue()) { final List<VcsDirectoryMapping> newList = listForVcsFromMap(newMapping.getVcs()); newList.add(newMapping); sortedMappingsByMap(); @@ -153,7 +153,7 @@ public class NewMappings { private void keepActiveVcs(@NotNull Runnable runnable) { final MyVcsActivator activator; synchronized (myLock) { - if (! myActivated) { + if (!myActivated) { runnable.run(); return; } @@ -204,7 +204,8 @@ public class NewMappings { final List<VcsDirectoryMapping> itemsCopy; if (items.isEmpty()) { itemsCopy = Collections.singletonList(new VcsDirectoryMapping("", "")); - } else { + } + else { itemsCopy = items; } @@ -224,7 +225,7 @@ public class NewMappings { @Nullable public VcsDirectoryMapping getMappingFor(@Nullable VirtualFile file) { if (file == null) return null; - if (! file.isInLocalFileSystem()) { + if (!file.isInLocalFileSystem()) { return null; } @@ -232,17 +233,22 @@ public class NewMappings { } @Nullable - public VcsDirectoryMapping getMappingFor(final VirtualFile file, final Object matchContext) { + public VcsDirectoryMapping getMappingFor(final VirtualFile file, final Object parentModule) { + // if parentModule is not null it means that file belongs to the module so it isn't excluded + if (parentModule == null && myFileIndexFacade.isExcludedFile(file)) { + return null; + } + // performance: calculate file path just once, rather than once per mapping String path = file.getPath(); - final String systemIndependentPath = FileUtil.toSystemIndependentName((file.isDirectory() && (! path.endsWith("/"))) ? (path + "/") : path); + final String systemIndependentPath = FileUtil.toSystemIndependentName((file.isDirectory() && (!path.endsWith("/"))) ? (path + "/") : path); final VcsDirectoryMapping[] mappings; synchronized (myLock) { mappings = mySortedMappings; } - for (int i = mappings.length - 1; i >= 0; -- i) { + for (int i = mappings.length - 1; i >= 0; --i) { final VcsDirectoryMapping mapping = mappings[i]; - if (fileMatchesMapping(file, matchContext, systemIndependentPath, mapping)) { + if (fileMatchesMapping(file, parentModule, systemIndependentPath, mapping)) { return mapping; } } @@ -258,12 +264,14 @@ public class NewMappings { return mapping.getVcs(); } - private boolean fileMatchesMapping(final VirtualFile file, final Object matchContext, final String systemIndependentPath, final VcsDirectoryMapping mapping) { + private boolean fileMatchesMapping(final VirtualFile file, + final Object matchContext, + final String systemIndependentPath, + final VcsDirectoryMapping mapping) { if (mapping.getDirectory().length() == 0) { return myDefaultVcsRootPolicy.matchesDefaultMapping(file, matchContext); } - return FileUtil.startsWith(systemIndependentPath, mapping.systemIndependentPath()) && - ! myExcludedFileIndex.isExcludedFile(file); + return FileUtil.startsWith(systemIndependentPath, mapping.systemIndependentPath()); } public List<VirtualFile> getMappingsAsFilesUnderVcs(final AbstractVcs vcs) { @@ -281,7 +289,8 @@ public class NewMappings { if (mapping.isDefaultMapping()) { // todo callback here; don't like it myDefaultVcsRootPolicy.addDefaultVcsRoots(this, vcsName, result); - } else { + } + else { final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(mapping.getDirectory()); if (file != null) { result.add(file); @@ -307,7 +316,7 @@ public class NewMappings { private void clearImpl() { // if vcses were not mapped, there's nothing to clear - if ((myActiveVcses == null) || (myActiveVcses.length == 0)) return; + if ((myActiveVcses == null) || (myActiveVcses.length == 0)) return; keepActiveVcs(new Runnable() { public void run() { @@ -374,7 +383,7 @@ public class NewMappings { final LocalFileSystem lfs = LocalFileSystem.getInstance(); final AllVcsesI allVcses = AllVcses.getInstance(myProject); - for (Iterator<String> iterator = myVcsToPaths.keySet().iterator(); iterator.hasNext();) { + for (Iterator<String> iterator = myVcsToPaths.keySet().iterator(); iterator.hasNext(); ) { final String vcsName = iterator.next(); final List<VcsDirectoryMapping> mappings = myVcsToPaths.get(vcsName); @@ -399,8 +408,9 @@ public class NewMappings { }; if (StringUtil.isEmptyOrSpaces(vcsName)) { filteredFiles = AbstractVcs.filterUniqueRootsDefault(objects, fileConvertor); - } else { - final AbstractVcs vcs = allVcses.getByName(vcsName); + } + else { + final AbstractVcs<?> vcs = allVcses.getByName(vcsName); if (vcs == null) { VcsBalloonProblemNotifier.showOverChangesView(myProject, "VCS plugin not found for mapping to : '" + vcsName + "'", MessageType.ERROR); continue; @@ -420,7 +430,8 @@ public class NewMappings { if (filteredMappings.isEmpty()) { iterator.remove(); - } else { + } + else { mappings.clear(); mappings.addAll(filteredMappings); } @@ -434,7 +445,7 @@ public class NewMappings { for (VcsDirectoryMapping mapping : mySortedMappings) { if (mapping.systemIndependentPath().equals(fixedPath)) { final String oldVcs = mapping.getVcs(); - if (! oldVcs.equals(activeVcsName)) { + if (!oldVcs.equals(activeVcsName)) { migrateVcs(activeVcsName, mapping, oldVcs); } return true; @@ -489,7 +500,7 @@ public class NewMappings { return ourInstance; } - public int compare(VcsDirectoryMapping m1, VcsDirectoryMapping m2) { + public int compare(@NotNull VcsDirectoryMapping m1, @NotNull VcsDirectoryMapping m2) { return m1.getDirectory().compareTo(m2.getDirectory()); } } @@ -514,7 +525,8 @@ public class NewMappings { catch (VcsException e) { // actually is not thrown (AbstractVcs#actualActivate()) } - } else { + } + else { LOG.info("Error: activating non existing vcs: " + s); } } @@ -529,7 +541,8 @@ public class NewMappings { catch (VcsException e) { // actually is not thrown (AbstractVcs#actualDeactivate()) } - } else { + } + else { LOG.info("Error: removing non existing vcs: " + s); } } @@ -543,7 +556,7 @@ public class NewMappings { // omit empty vcs: not a vcs if (topItem.trim().length() == 0) continue; - if (! bottom.contains(topItem)) { + if (!bottom.contains(topItem)) { if (notInBottom == null) { notInBottom = new HashSet<String>(); } @@ -589,7 +602,8 @@ public class NewMappings { public void invoke() { if (myItems.isEmpty()) { myItemsCopy = Collections.singletonList(new VcsDirectoryMapping("", "")); - } else { + } + else { myItemsCopy = myItems; } } @@ -606,8 +620,9 @@ public class NewMappings { myDefaultVcsRootPolicy.addDefaultVcsRoots(this, defaultVcs, list); if (StringUtil.isEmptyOrSpaces(defaultVcs)) { return AbstractVcs.filterUniqueRootsDefault(list, Convertor.SELF); - } else { - final AbstractVcs vcs = AllVcses.getInstance(myProject).getByName(defaultVcs); + } + else { + final AbstractVcs<?> vcs = AllVcses.getInstance(myProject).getByName(defaultVcs); if (vcs == null) { return AbstractVcs.filterUniqueRootsDefault(list, Convertor.SELF); } |