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
.merge
;
18 import com
.intellij
.ide
.util
.ElementsChooser
;
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
.ui
.DocumentAdapter
;
24 import com
.intellij
.util
.ArrayUtil
;
25 import git4idea
.GitRemote
;
26 import git4idea
.GitVcs
;
27 import git4idea
.commands
.GitCommand
;
28 import git4idea
.commands
.GitHandlerUtil
;
29 import git4idea
.commands
.GitLineHandler
;
30 import git4idea
.commands
.GitSimpleHandler
;
31 import git4idea
.i18n
.GitBundle
;
32 import git4idea
.ui
.GitUIUtil
;
33 import org
.jetbrains
.annotations
.Nullable
;
36 import javax
.swing
.event
.DocumentEvent
;
37 import java
.awt
.event
.ActionEvent
;
38 import java
.awt
.event
.ActionListener
;
39 import java
.util
.Collections
;
40 import java
.util
.List
;
45 public class GitPullDialog
extends DialogWrapper
{
49 private JPanel myPanel
;
51 * The selected git root
53 private JComboBox myGitRoot
;
55 * Current branch label
57 private JLabel myCurrentBranch
;
61 private JComboBox myStrategy
;
65 private JCheckBox myNoCommitCheckBox
;
67 * Squash commit option
69 private JCheckBox mySquashCommitCheckBox
;
71 * No fast forward option
73 private JCheckBox myNoFastForwardCheckBox
;
75 * Add log info to commit option
77 private JCheckBox myAddLogInformationCheckBox
;
79 * Selected remote option
81 private JComboBox myRemote
;
85 private JButton myGetBranchesButton
;
89 private ElementsChooser
<String
> myBranchChooser
;
93 private final Project myProject
;
98 * @param project a project to select
99 * @param roots a git repository roots for the project
100 * @param defaultRoot a guessed default root
102 public GitPullDialog(Project project
, List
<VirtualFile
> roots
, VirtualFile defaultRoot
) {
103 super(project
, true);
104 setTitle(GitBundle
.getString("pull.title"));
106 GitUIUtil
.setupRootChooser(myProject
, roots
, defaultRoot
, myGitRoot
, myCurrentBranch
);
107 myGitRoot
.addActionListener(new ActionListener() {
108 public void actionPerformed(final ActionEvent e
) {
112 setOKButtonText(GitBundle
.getString("pull.button"));
116 final ElementsChooser
.ElementsMarkListener
<String
> listener
= new ElementsChooser
.ElementsMarkListener
<String
>() {
117 public void elementMarkChanged(final String element
, final boolean isMarked
) {
121 myBranchChooser
.addElementsMarkListener(listener
);
122 listener
.elementMarkChanged(null, true);
123 GitUIUtil
.imply(mySquashCommitCheckBox
, true, myNoCommitCheckBox
, true);
124 GitUIUtil
.imply(mySquashCommitCheckBox
, true, myAddLogInformationCheckBox
, false);
125 GitUIUtil
.exclusive(mySquashCommitCheckBox
, true, myNoFastForwardCheckBox
, true);
126 GitMergeUtil
.setupStrategies(myBranchChooser
, myStrategy
);
131 * Setup branch updating
133 private void setupBranches() {
134 ((JTextField
)myRemote
.getEditor().getEditorComponent()).getDocument().addDocumentListener(new DocumentAdapter() {
135 protected void textChanged(final DocumentEvent e
) {
143 * Validate dialog and enable buttons
145 private void validateDialog() {
146 if (getRemote().trim().length() == 0) {
147 setOKActionEnabled(false);
150 setOKActionEnabled(myBranchChooser
.getMarkedElements().size() != 0);
154 * Setup get branches button
156 private void setupGetBranches() {
157 final JTextField textField
= (JTextField
)myRemote
.getEditor().getEditorComponent();
158 final DocumentAdapter listener
= new DocumentAdapter() {
159 protected void textChanged(final DocumentEvent e
) {
161 myGetBranchesButton
.setEnabled(textField
.getText().trim().length() != 0);
164 textField
.getDocument().addDocumentListener(listener
);
165 listener
.changedUpdate(null);
166 myGetBranchesButton
.addActionListener(new ActionListener() {
167 public void actionPerformed(final ActionEvent e
) {
168 GitSimpleHandler h
= new GitSimpleHandler(myProject
, gitRoot(), GitCommand
.LS_REMOTE
);
169 h
.addParameters("--heads", myRemote
.getSelectedItem().toString());
170 String output
= GitHandlerUtil
.doSynchronously(h
, GitBundle
.getString("pull.getting.remote.branches"), h
.printableCommandLine());
171 if (output
== null) {
174 myBranchChooser
.removeAllElements();
175 for (String line
: output
.split("\n")) {
176 if (line
.length() == 0) {
179 int pos
= line
.lastIndexOf('/');
181 pos
= line
.lastIndexOf('\t');
183 myBranchChooser
.addElement(line
.substring(pos
+ 1), false);
190 * @return a pull handler configured according to dialog options
192 public GitLineHandler
pullHandler() {
193 GitLineHandler h
= new GitLineHandler(myProject
, gitRoot(), GitCommand
.PULL
);
194 // ignore merge failure for the pull
195 h
.ignoreErrorCode(1);
196 h
.addParameters("--no-stat");
197 if (myNoCommitCheckBox
.isSelected()) {
198 h
.addParameters("--no-commit");
201 if (myAddLogInformationCheckBox
.isSelected()) {
202 h
.addParameters("--log");
205 if (mySquashCommitCheckBox
.isSelected()) {
206 h
.addParameters("--squash");
208 if (myNoFastForwardCheckBox
.isSelected()) {
209 h
.addParameters("--no-ff");
211 String strategy
= (String
)myStrategy
.getSelectedItem();
212 if (!GitMergeUtil
.DEFAULT_STRATEGY
.equals(strategy
)) {
213 h
.addParameters("--strategy", strategy
);
215 h
.addParameters("-v");
216 h
.addParameters(getRemote());
217 final List
<String
> markedBranches
= myBranchChooser
.getMarkedElements();
218 h
.addParameters(ArrayUtil
.toStringArray(markedBranches
));
225 private void updateBranches() {
227 String item
= getRemote();
228 myBranchChooser
.removeAllElements();
230 final int count
= myRemote
.getItemCount();
231 for (int i
= 0; i
< count
; i
++) {
232 GitRemote candidate
= (GitRemote
)myRemote
.getItemAt(i
);
233 if (candidate
.name().equals(item
)) {
241 GitRemote
.Info ri
= r
.localInfo(myProject
, gitRoot());
242 String toSelect
= ri
.getRemoteForLocal(currentBranch());
243 for (String trackedBranch
: ri
.trackedBranches()) {
244 myBranchChooser
.addElement(trackedBranch
, trackedBranch
.equals(toSelect
));
247 catch (VcsException e
) {
248 GitVcs
.getInstance(myProject
).showErrors(Collections
.singletonList(e
), GitBundle
.getString("pull.retrieving.remotes"));
256 * @return current local branch for the git or null
259 private String
currentBranch() {
260 String text
= myCurrentBranch
.getText();
261 return text
.equals(GitUIUtil
.NO_CURRENT_BRANCH
) ?
null : text
;
265 * Update remotes for the git root
267 private void updateRemotes() {
268 GitUIUtil
.setupRemotes(myProject
, gitRoot(), currentBranch(), myRemote
, true);
272 * @return a currently selected git root
274 public VirtualFile
gitRoot() {
275 return (VirtualFile
)myGitRoot
.getSelectedItem();
280 * Create branch chooser
282 private void createUIComponents() {
283 myBranchChooser
= new ElementsChooser
<String
>(true);
289 protected JComponent
createCenterPanel() {
297 protected String
getDimensionServiceKey() {
298 return getClass().getName();
305 protected String
getHelpId() {
306 return "reference.VersionControl.Git.Pull";
312 public String
getRemote() {
313 return ((JTextField
)myRemote
.getEditor().getEditorComponent()).getText();