2 * Copyright 2000-2008 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 git4idea
.GitRemote
;
25 import git4idea
.GitVcs
;
26 import git4idea
.commands
.GitHandler
;
27 import git4idea
.commands
.GitHandlerUtil
;
28 import git4idea
.commands
.GitLineHandler
;
29 import git4idea
.commands
.GitSimpleHandler
;
30 import git4idea
.i18n
.GitBundle
;
31 import git4idea
.ui
.GitUIUtil
;
32 import org
.jetbrains
.annotations
.Nullable
;
35 import javax
.swing
.event
.DocumentEvent
;
36 import java
.awt
.event
.ActionEvent
;
37 import java
.awt
.event
.ActionListener
;
38 import java
.util
.Collections
;
39 import java
.util
.List
;
44 public class GitPullDialog
extends DialogWrapper
{
48 private JPanel myPanel
;
50 * The selected git root
52 private JComboBox myGitRoot
;
54 * Current branch label
56 private JLabel myCurrentBranch
;
60 private JComboBox myStrategy
;
64 private JCheckBox myNoCommitCheckBox
;
66 * Squash commit option
68 private JCheckBox mySquashCommitCheckBox
;
70 * No fast forward option
72 private JCheckBox myNoFastForwardCheckBox
;
74 * Add log info to commit option
76 private JCheckBox myAddLogInformationCheckBox
;
78 * Selected remote option
80 private JComboBox myRemote
;
84 private JButton myGetBranchesButton
;
88 private ElementsChooser
<String
> myBranchChooser
;
92 private final Project myProject
;
97 * @param project a project to select
98 * @param roots a git repository roots for the project
99 * @param defaultRoot a guessed default root
101 public GitPullDialog(Project project
, List
<VirtualFile
> roots
, VirtualFile defaultRoot
) {
102 super(project
, true);
103 setTitle(GitBundle
.getString("pull.title"));
105 GitUIUtil
.setupRootChooser(myProject
, roots
, defaultRoot
, myGitRoot
, myCurrentBranch
);
106 myGitRoot
.addActionListener(new ActionListener() {
107 public void actionPerformed(final ActionEvent e
) {
111 setOKButtonText(GitBundle
.getString("pull.button"));
115 final ElementsChooser
.ElementsMarkListener
<String
> listener
= new ElementsChooser
.ElementsMarkListener
<String
>() {
116 public void elementMarkChanged(final String element
, final boolean isMarked
) {
120 myBranchChooser
.addElementsMarkListener(listener
);
121 listener
.elementMarkChanged(null, true);
122 GitUIUtil
.imply(mySquashCommitCheckBox
, true, myNoCommitCheckBox
, true);
123 GitUIUtil
.imply(mySquashCommitCheckBox
, true, myAddLogInformationCheckBox
, false);
124 GitUIUtil
.exclusive(mySquashCommitCheckBox
, true, myNoFastForwardCheckBox
, true);
125 GitMergeUtil
.setupStrategies(myBranchChooser
, myStrategy
);
130 * Setup branch updating
132 private void setupBranches() {
133 ((JTextField
)myRemote
.getEditor().getEditorComponent()).getDocument().addDocumentListener(new DocumentAdapter() {
134 protected void textChanged(final DocumentEvent e
) {
142 * Validate dialog and enable buttons
144 private void validateDialog() {
145 if (getRemote().trim().length() == 0) {
146 setOKActionEnabled(false);
149 setOKActionEnabled(myBranchChooser
.getMarkedElements().size() != 0);
153 * Setup get branches button
155 private void setupGetBranches() {
156 final JTextField textField
= (JTextField
)myRemote
.getEditor().getEditorComponent();
157 final DocumentAdapter listener
= new DocumentAdapter() {
158 protected void textChanged(final DocumentEvent e
) {
160 myGetBranchesButton
.setEnabled(textField
.getText().trim().length() != 0);
163 textField
.getDocument().addDocumentListener(listener
);
164 listener
.changedUpdate(null);
165 myGetBranchesButton
.addActionListener(new ActionListener() {
166 public void actionPerformed(final ActionEvent e
) {
167 GitSimpleHandler h
= new GitSimpleHandler(myProject
, gitRoot(), GitHandler
.LS_REMOTE
);
168 h
.addParameters("--heads", myRemote
.getSelectedItem().toString());
169 String output
= GitHandlerUtil
.doSynchronously(h
, GitBundle
.getString("pull.getting.remote.branches"), h
.printableCommandLine());
170 if (output
== null) {
173 myBranchChooser
.removeAllElements();
174 for (String line
: output
.split("\n")) {
175 if (line
.length() == 0) {
178 int pos
= line
.lastIndexOf('/');
180 pos
= line
.lastIndexOf('\t');
182 myBranchChooser
.addElement(line
.substring(pos
+ 1), false);
189 * @return a pull handler configured according to dialog options
191 public GitLineHandler
pullHandler() {
192 GitLineHandler h
= new GitLineHandler(myProject
, gitRoot(), GitHandler
.PULL
);
193 // ignore merge failure for the pull
194 h
.ignoreErrorCode(1);
195 h
.addParameters("--no-stat");
196 if (myNoCommitCheckBox
.isSelected()) {
197 h
.addParameters("--no-commit");
200 if (myAddLogInformationCheckBox
.isSelected()) {
201 h
.addParameters("--log");
204 if (mySquashCommitCheckBox
.isSelected()) {
205 h
.addParameters("--squash");
207 if (myNoFastForwardCheckBox
.isSelected()) {
208 h
.addParameters("--no-ff");
210 String strategy
= (String
)myStrategy
.getSelectedItem();
211 if (!GitMergeUtil
.DEFAULT_STRATEGY
.equals(strategy
)) {
212 h
.addParameters("--strategy", strategy
);
214 h
.addParameters("-v");
215 h
.addParameters(getRemote());
216 final List
<String
> markedBranches
= myBranchChooser
.getMarkedElements();
217 h
.addParameters(markedBranches
.toArray(new String
[markedBranches
.size()]));
224 private void updateBranches() {
226 String item
= getRemote();
227 myBranchChooser
.removeAllElements();
229 final int count
= myRemote
.getItemCount();
230 for (int i
= 0; i
< count
; i
++) {
231 GitRemote candidate
= (GitRemote
)myRemote
.getItemAt(i
);
232 if (candidate
.name().equals(item
)) {
240 GitRemote
.Info ri
= r
.localInfo(myProject
, gitRoot());
241 String toSelect
= ri
.getRemoteForLocal(currentBranch());
242 for (String trackedBranch
: ri
.trackedBranches()) {
243 myBranchChooser
.addElement(trackedBranch
, trackedBranch
.equals(toSelect
));
246 catch (VcsException e
) {
247 GitVcs
.getInstance(myProject
).showErrors(Collections
.singletonList(e
), GitBundle
.getString("pull.retrieving.remotes"));
255 * @return current local branch for the git or null
258 private String
currentBranch() {
259 String text
= myCurrentBranch
.getText();
260 return text
.equals(GitUIUtil
.NO_CURRENT_BRANCH
) ?
null : text
;
264 * Update remotes for the git root
266 private void updateRemotes() {
267 GitUIUtil
.setupRemotes(myProject
, gitRoot(), currentBranch(), myRemote
, true);
271 * @return a currently selected git root
273 public VirtualFile
gitRoot() {
274 return (VirtualFile
)myGitRoot
.getSelectedItem();
279 * Create branch chooser
281 private void createUIComponents() {
282 myBranchChooser
= new ElementsChooser
<String
>(true);
288 protected JComponent
createCenterPanel() {
296 protected String
getDimensionServiceKey() {
297 return getClass().getName();
304 protected String
getHelpId() {
305 return "reference.VersionControl.Git.Pull";
311 public String
getRemote() {
312 return ((JTextField
)myRemote
.getEditor().getEditorComponent()).getText();