2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package git4idea
.update
;
18 import com
.intellij
.openapi
.application
.ApplicationNamesInfo
;
19 import com
.intellij
.openapi
.project
.Project
;
20 import com
.intellij
.openapi
.ui
.DialogWrapper
;
21 import com
.intellij
.openapi
.vcs
.VcsException
;
22 import com
.intellij
.openapi
.vfs
.VirtualFile
;
23 import com
.intellij
.util
.ui
.UIUtil
;
24 import com
.intellij
.vcsUtil
.VcsUtil
;
25 import git4idea
.GitUtil
;
26 import git4idea
.commands
.GitCommand
;
27 import git4idea
.commands
.GitSimpleHandler
;
28 import git4idea
.commands
.StringScanner
;
29 import git4idea
.i18n
.GitBundle
;
30 import git4idea
.ui
.GitUIUtil
;
33 import java
.awt
.event
.ActionEvent
;
34 import java
.awt
.event
.ActionListener
;
35 import java
.util
.ArrayList
;
36 import java
.util
.List
;
37 import java
.util
.concurrent
.atomic
.AtomicBoolean
;
40 * The dialog that displays locally modified files during update process
42 public class GitUpdateLocallyModifiedDialog
extends DialogWrapper
{
46 private JButton myRescanButton
;
48 * The list of files to revert
50 private JList myFilesList
;
52 private JLabel myDescriptionLabel
;
56 private JLabel myGitRoot
;
60 private JPanel myRootPanel
;
62 * The collection with locally modified files
64 private List
<String
> myLocallyModifiedFiles
;
69 * @param project the current project
70 * @param root the vcs root
71 * @param locallyModifiedFiles the collection of locally modified files to use
73 protected GitUpdateLocallyModifiedDialog(final Project project
, final VirtualFile root
, List
<String
> locallyModifiedFiles
) {
75 myLocallyModifiedFiles
= locallyModifiedFiles
;
76 setTitle(GitBundle
.getString("update.locally.modified.title"));
77 myGitRoot
.setText(root
.getPresentableUrl());
78 myFilesList
.setModel(new DefaultListModel());
79 setOKButtonText(GitBundle
.getString("update.locally.modified.revert"));
81 myRescanButton
.addActionListener(new ActionListener() {
82 public void actionPerformed(ActionEvent e
) {
83 myLocallyModifiedFiles
.clear();
85 scanFiles(project
, root
, myLocallyModifiedFiles
);
87 catch (VcsException ex
) {
88 GitUIUtil
.showOperationError(project
, ex
, "Checking for locally modified files");
93 .setText(GitBundle
.message("update.locally.modified.message", ApplicationNamesInfo
.getInstance().getFullProductName()));
98 * Refresh list model according to the current content of the collection
100 private void syncListModel() {
101 DefaultListModel listModel
= (DefaultListModel
)myFilesList
.getModel();
102 listModel
.removeAllElements();
103 for (String p
: myLocallyModifiedFiles
) {
104 listModel
.addElement(p
);
112 protected JComponent
createCenterPanel() {
120 protected String
getDimensionServiceKey() {
121 return getClass().getName();
125 * Scan working tree and detect locally modified files
127 * @param project the project to scan
128 * @param root the root to scan
129 * @param files the collection with files
130 * @throws VcsException if there problem with running git or working tree is dirty in unsupported way
132 private static void scanFiles(Project project
, VirtualFile root
, List
<String
> files
) throws VcsException
{
133 String rootPath
= root
.getPath();
134 GitSimpleHandler h
= new GitSimpleHandler(project
, root
, GitCommand
.DIFF
);
135 h
.addParameters("--name-status");
137 h
.setStdoutSuppressed(true);
138 StringScanner s
= new StringScanner(h
.run());
139 while (s
.hasMoreData()) {
144 if (s
.tryConsume("M\t")) {
145 String path
= rootPath
+ "/" + GitUtil
.unescapePath(s
.line());
149 throw new VcsException("Working tree is dirty in unsupported way: " + s
.line());
156 * Show the dialog if needed
158 * @param project the project
159 * @param root the vcs root
160 * @return true if showing is not needed or operation completed successfully
162 public static boolean showIfNeeded(final Project project
, final VirtualFile root
) {
163 final ArrayList
<String
> files
= new ArrayList
<String
>();
165 scanFiles(project
, root
, files
);
166 final AtomicBoolean rc
= new AtomicBoolean(true);
167 if (!files
.isEmpty()) {
168 UIUtil
.invokeAndWaitIfNeeded(new Runnable() {
170 GitUpdateLocallyModifiedDialog d
= new GitUpdateLocallyModifiedDialog(project
, root
, files
);
176 if (!files
.isEmpty()) {
177 revertFiles(project
, root
, files
);
183 catch (final VcsException e
) {
184 UIUtil
.invokeAndWaitIfNeeded(new Runnable() {
186 GitUIUtil
.showOperationError(project
, e
, "Checking for locally modified files");
194 * Revert files from the list
196 * @param project the project
197 * @param root the vcs root
198 * @param files the files to revert
200 private static void revertFiles(Project project
, VirtualFile root
, ArrayList
<String
> files
) throws VcsException
{
201 GitSimpleHandler h
= new GitSimpleHandler(project
, root
, GitCommand
.CHECKOUT
);
204 for (String p
: files
) {
205 h
.addRelativePaths(VcsUtil
.getFilePath(p
));