vcs: Enabled unversioned files in commit dialog by default
[idea/community.git] / platform / vcs-api / src / com / intellij / openapi / vcs / VcsConfiguration.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.vcs;
17
18 import com.intellij.ide.todo.TodoPanelSettings;
19 import com.intellij.openapi.components.*;
20 import com.intellij.openapi.diff.impl.IgnoreSpaceEnum;
21 import com.intellij.openapi.progress.PerformInBackgroundOption;
22 import com.intellij.openapi.project.Project;
23 import com.intellij.openapi.util.io.FileUtilRt;
24 import com.intellij.openapi.util.text.StringUtil;
25 import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
26 import com.intellij.util.PlatformUtils;
27 import com.intellij.util.containers.ContainerUtil;
28 import com.intellij.util.xmlb.XmlSerializerUtil;
29 import com.intellij.util.xmlb.annotations.AbstractCollection;
30 import com.intellij.util.xmlb.annotations.OptionTag;
31 import com.intellij.util.xmlb.annotations.Property;
32 import com.intellij.util.xmlb.annotations.Tag;
33 import org.jetbrains.annotations.NonNls;
34 import org.jetbrains.annotations.NotNull;
35
36 import java.util.*;
37
38 @State(
39   name = "VcsManagerConfiguration",
40   storages = @Storage(StoragePathMacros.WORKSPACE_FILE)
41 )
42 public final class VcsConfiguration implements PersistentStateComponent<VcsConfiguration> {
43   public final static long ourMaximumFileForBaseRevisionSize = 500 * 1000;
44
45   @NonNls static final String VALUE_ATTR = "value";
46
47   @NonNls public static final String PATCH = "patch";
48   @NonNls public static final String DIFF = "diff";
49
50   public boolean OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT = true;
51   public boolean CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT = !PlatformUtils.isPyCharm() && !PlatformUtils.isRubyMine();
52   public boolean CHECK_CODE_CLEANUP_BEFORE_PROJECT_COMMIT = false;
53   public boolean CHECK_NEW_TODO = true;
54   public TodoPanelSettings myTodoPanelSettings = new TodoPanelSettings();
55   public boolean PERFORM_UPDATE_IN_BACKGROUND = true;
56   public boolean PERFORM_COMMIT_IN_BACKGROUND = true;
57   public boolean PERFORM_EDIT_IN_BACKGROUND = true;
58   public boolean PERFORM_CHECKOUT_IN_BACKGROUND = true;
59   public boolean PERFORM_ADD_REMOVE_IN_BACKGROUND = true;
60   public boolean PERFORM_ROLLBACK_IN_BACKGROUND = false;
61   public volatile boolean CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND = false;
62   @OptionTag(tag = "confirmMoveToFailedCommit", nameAttribute = "")
63   public VcsShowConfirmationOption.Value MOVE_TO_FAILED_COMMIT_CHANGELIST = VcsShowConfirmationOption.Value.SHOW_CONFIRMATION;
64   @OptionTag(tag = "confirmRemoveEmptyChangelist", nameAttribute = "")
65   public VcsShowConfirmationOption.Value REMOVE_EMPTY_INACTIVE_CHANGELISTS = VcsShowConfirmationOption.Value.SHOW_CONFIRMATION;
66   public int CHANGED_ON_SERVER_INTERVAL = 60;
67   public boolean SHOW_ONLY_CHANGED_IN_SELECTION_DIFF = true;
68   public boolean CHECK_COMMIT_MESSAGE_SPELLING = true;
69   public String DEFAULT_PATCH_EXTENSION = PATCH;
70   public boolean SHORT_DIFF_HORIZONTALLY = true;
71   public int SHORT_DIFF_EXTRA_LINES = 2;
72   public boolean SOFT_WRAPS_IN_SHORT_DIFF = true;
73   public IgnoreSpaceEnum SHORT_DIFF_IGNORE_SPACE = IgnoreSpaceEnum.NO;
74   // asked only for non-DVCS
75   public boolean INCLUDE_TEXT_INTO_PATCH = false;
76   public boolean INCLUDE_TEXT_INTO_SHELF = false;
77   public Boolean SHOW_PATCH_IN_EXPLORER = null;
78   public boolean SHOW_FILE_HISTORY_DETAILS = true;
79   public boolean SHOW_DIRTY_RECURSIVELY = false;
80   public boolean LIMIT_HISTORY = true;
81   public int MAXIMUM_HISTORY_ROWS = 1000;
82   public String UPDATE_FILTER_SCOPE_NAME = null;
83   public boolean USE_COMMIT_MESSAGE_MARGIN = false;
84   public int COMMIT_MESSAGE_MARGIN_SIZE = 72;
85   public boolean WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = false;
86   public boolean SHOW_UNVERSIONED_FILES_WHILE_COMMIT = true;
87   public boolean LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN = false;
88
89   @AbstractCollection(surroundWithTag = false, elementTag = "path")
90   @Tag("ignored-roots")
91   public List<String> IGNORED_UNREGISTERED_ROOTS = ContainerUtil.newArrayList();
92
93   public enum StandardOption {
94     ADD(VcsBundle.message("vcs.command.name.add")),
95     REMOVE(VcsBundle.message("vcs.command.name.remove")),
96     EDIT(VcsBundle.message("vcs.command.name.edit")),
97     CHECKOUT(VcsBundle.message("vcs.command.name.checkout")),
98     STATUS(VcsBundle.message("vcs.command.name.status")),
99     UPDATE(VcsBundle.message("vcs.command.name.update"));
100
101     StandardOption(final String id) {
102       myId = id;
103     }
104
105     private final String myId;
106
107     public String getId() {
108       return myId;
109     }
110   }
111
112   public enum StandardConfirmation {
113     ADD(VcsBundle.message("vcs.command.name.add")),
114     REMOVE(VcsBundle.message("vcs.command.name.remove"));
115
116     StandardConfirmation(final String id) {
117       myId = id;
118     }
119
120     private final String myId;
121
122     public String getId() {
123       return myId;
124     }
125   }
126
127   public boolean FORCE_NON_EMPTY_COMMENT = false;
128   public boolean CLEAR_INITIAL_COMMIT_MESSAGE = false;
129
130   @Property(surroundWithTag = false)
131   @AbstractCollection(elementTag = "MESSAGE", elementValueAttribute = "value", surroundWithTag = false)
132   public List<String> myLastCommitMessages = new ArrayList<String>();
133   public String LAST_COMMIT_MESSAGE = null;
134   public boolean MAKE_NEW_CHANGELIST_ACTIVE = false;
135   public boolean PRESELECT_EXISTING_CHANGELIST = true;
136
137   public boolean OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT = false;
138   public boolean CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT = false;
139
140   public boolean REFORMAT_BEFORE_PROJECT_COMMIT = false;
141   public boolean REFORMAT_BEFORE_FILE_COMMIT = false;
142
143   public boolean REARRANGE_BEFORE_PROJECT_COMMIT = false;
144
145   public Map<String, ChangeBrowserSettings> CHANGE_BROWSER_SETTINGS = new HashMap<String, ChangeBrowserSettings>();
146
147   public boolean UPDATE_GROUP_BY_PACKAGES = false;
148   public boolean UPDATE_GROUP_BY_CHANGELIST = false;
149   public boolean UPDATE_FILTER_BY_SCOPE = false;
150   public boolean SHOW_FILE_HISTORY_AS_TREE = false;
151   public float FILE_HISTORY_SPLITTER_PROPORTION = 0.6f;
152   private static final int MAX_STORED_MESSAGES = 25;
153   @NonNls static final String MESSAGE_ELEMENT_NAME = "MESSAGE";
154
155   private final PerformInBackgroundOption myUpdateOption = new UpdateInBackgroundOption();
156   private final PerformInBackgroundOption myCommitOption = new CommitInBackgroundOption();
157   private final PerformInBackgroundOption myEditOption = new EditInBackgroundOption();
158   private final PerformInBackgroundOption myCheckoutOption = new CheckoutInBackgroundOption();
159   private final PerformInBackgroundOption myAddRemoveOption = new AddRemoveInBackgroundOption();
160
161   @Override
162   public VcsConfiguration getState() {
163     return this;
164   }
165
166   @Override
167   public void loadState(VcsConfiguration state) {
168     XmlSerializerUtil.copyBean(state, this);
169   }
170
171   public static VcsConfiguration getInstance(@NotNull Project project) {
172     return ServiceManager.getService(project, VcsConfiguration.class);
173   }
174
175   public void saveCommitMessage(final String comment) {
176     LAST_COMMIT_MESSAGE = comment;
177     if (comment == null || comment.length() == 0) return;
178     myLastCommitMessages.remove(comment);
179     while (myLastCommitMessages.size() >= MAX_STORED_MESSAGES) {
180       myLastCommitMessages.remove(0);
181     }
182     myLastCommitMessages.add(comment);
183   }
184
185   public String getLastNonEmptyCommitMessage() {
186     if (myLastCommitMessages.isEmpty()) {
187       return null;
188     }
189     else {
190       return myLastCommitMessages.get(myLastCommitMessages.size() - 1);
191     }
192   }
193
194   @NotNull
195   public ArrayList<String> getRecentMessages() {
196     return new ArrayList<String>(myLastCommitMessages);
197   }
198
199   public void removeMessage(final String content) {
200     myLastCommitMessages.remove(content);
201   }
202
203
204   public PerformInBackgroundOption getUpdateOption() {
205     return myUpdateOption;
206   }
207
208   public PerformInBackgroundOption getCommitOption() {
209     return myCommitOption;
210   }
211
212   public PerformInBackgroundOption getEditOption() {
213     return myEditOption;
214   }
215
216   public PerformInBackgroundOption getCheckoutOption() {
217     return myCheckoutOption;
218   }
219
220   public PerformInBackgroundOption getAddRemoveOption() {
221     return myAddRemoveOption;
222   }
223
224   private class UpdateInBackgroundOption implements PerformInBackgroundOption {
225     @Override
226     public boolean shouldStartInBackground() {
227       return PERFORM_UPDATE_IN_BACKGROUND;
228     }
229
230     @Override
231     public void processSentToBackground() {}
232   }
233
234   private class CommitInBackgroundOption implements PerformInBackgroundOption {
235     @Override
236     public boolean shouldStartInBackground() {
237       return PERFORM_COMMIT_IN_BACKGROUND;
238     }
239
240     @Override
241     public void processSentToBackground() {}
242   }
243
244   private class EditInBackgroundOption implements PerformInBackgroundOption {
245     @Override
246     public boolean shouldStartInBackground() {
247       return PERFORM_EDIT_IN_BACKGROUND;
248     }
249
250     @Override
251     public void processSentToBackground() {
252       PERFORM_EDIT_IN_BACKGROUND = true;
253     }
254
255   }
256
257   private class CheckoutInBackgroundOption implements PerformInBackgroundOption {
258     @Override
259     public boolean shouldStartInBackground() {
260       return PERFORM_CHECKOUT_IN_BACKGROUND;
261     }
262
263     @Override
264     public void processSentToBackground() {
265       PERFORM_CHECKOUT_IN_BACKGROUND = true;
266     }
267
268   }
269
270   private class AddRemoveInBackgroundOption implements PerformInBackgroundOption {
271     @Override
272     public boolean shouldStartInBackground() {
273       return PERFORM_ADD_REMOVE_IN_BACKGROUND;
274     }
275
276     @Override
277     public void processSentToBackground() {
278       PERFORM_ADD_REMOVE_IN_BACKGROUND = true;
279     }
280
281   }
282
283   public String getPatchFileExtension() {
284     return DEFAULT_PATCH_EXTENSION;
285   }
286
287   public void acceptLastCreatedPatchName(final String string) {
288     if (StringUtil.isEmptyOrSpaces(string)) return;
289     if (FileUtilRt.extensionEquals(string, DIFF)) {
290       DEFAULT_PATCH_EXTENSION = DIFF;
291     }
292     else if (FileUtilRt.extensionEquals(string, PATCH)) {
293       DEFAULT_PATCH_EXTENSION = PATCH;
294     }
295   }
296
297   public boolean isChangedOnServerEnabled() {
298     return CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND;
299   }
300
301   public void addIgnoredUnregisteredRoots(@NotNull Collection<String> roots) {
302     List<String> unregisteredRoots = new ArrayList<String>(IGNORED_UNREGISTERED_ROOTS);
303     for (String root : roots) {
304       if (!unregisteredRoots.contains(root)) {
305         unregisteredRoots.add(root);
306       }
307     }
308     IGNORED_UNREGISTERED_ROOTS = unregisteredRoots;
309   }
310
311 }