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
.rebase
;
18 import com
.intellij
.openapi
.project
.Project
;
19 import com
.intellij
.openapi
.ui
.DialogWrapper
;
20 import com
.intellij
.openapi
.vcs
.VcsException
;
21 import com
.intellij
.openapi
.vfs
.VirtualFile
;
22 import com
.intellij
.ui
.DocumentAdapter
;
23 import git4idea
.GitBranch
;
24 import git4idea
.GitTag
;
25 import git4idea
.commands
.GitHandler
;
26 import git4idea
.commands
.GitLineHandler
;
27 import git4idea
.config
.GitConfigUtil
;
28 import git4idea
.i18n
.GitBundle
;
29 import git4idea
.merge
.GitMergeUtil
;
30 import git4idea
.ui
.GitReferenceValidator
;
31 import git4idea
.ui
.GitUIUtil
;
34 import javax
.swing
.event
.DocumentEvent
;
35 import java
.awt
.event
.ActionEvent
;
36 import java
.awt
.event
.ActionListener
;
37 import java
.util
.ArrayList
;
38 import java
.util
.List
;
41 * The dialog that allows initiating git rebase activity
43 public class GitRebaseDialog
extends DialogWrapper
{
47 private JComboBox myGitRootComboBox
;
49 * The selector for branch to rebase
51 private JComboBox myBranchComboBox
;
53 * The from branch combo box. This is used as base branch if different from onto branch
55 private JComboBox myFromComboBox
;
57 * The validation button for from branch
59 private JButton myFromValidateButton
;
61 * The onto branch combobox.
63 private JComboBox myOntoComboBox
;
65 * The validate button for onto branch
67 private JButton myOntoValidateButton
;
69 * Show tags in drop down
71 private JCheckBox myShowTagsCheckBox
;
73 * Merge strategy drop down
75 private JComboBox myMergeStrategyComboBox
;
77 * If selected, rebase is interactive
79 private JCheckBox myInteractiveCheckBox
;
81 * No merges are performed if selected.
83 private JCheckBox myDoNotUseMergeCheckBox
;
85 * The root panel of the dialog
87 private JPanel myPanel
;
89 * If selected, remote branches are shown as well
91 private JCheckBox myShowRemoteBranchesCheckBox
;
93 * Preserve merges checkbox
95 private JCheckBox myPreserveMergesCheckBox
;
99 private final Project myProject
;
101 * The list of local branches
103 private final List
<GitBranch
> myLocalBranches
= new ArrayList
<GitBranch
>();
105 * The list of remote branches
107 private final List
<GitBranch
> myRemoteBranches
= new ArrayList
<GitBranch
>();
111 private GitBranch myCurrentBranch
;
115 private final List
<GitTag
> myTags
= new ArrayList
<GitTag
>();
117 * The validator for onto field
119 private final GitReferenceValidator myOntoValidator
;
121 * The validator for from field
123 private final GitReferenceValidator myFromValidator
;
128 * @param project a project to select
129 * @param roots a git repository roots for the project
130 * @param defaultRoot a guessed default root
132 public GitRebaseDialog(Project project
, List
<VirtualFile
> roots
, VirtualFile defaultRoot
) {
133 super(project
, true);
134 setTitle(GitBundle
.getString("rebase.title"));
135 setOKButtonText(GitBundle
.getString("rebase.button"));
138 final Runnable validateRunnable
= new Runnable() {
143 myOntoValidator
= new GitReferenceValidator(myProject
, myGitRootComboBox
, GitUIUtil
.getTextField(myOntoComboBox
), myOntoValidateButton
,
145 myFromValidator
= new GitReferenceValidator(myProject
, myGitRootComboBox
, GitUIUtil
.getTextField(myFromComboBox
), myFromValidateButton
,
147 GitUIUtil
.setupRootChooser(myProject
, roots
, defaultRoot
, myGitRootComboBox
, null);
148 myGitRootComboBox
.addActionListener(new ActionListener() {
149 public void actionPerformed(ActionEvent e
) {
158 public GitLineHandler
handler() {
159 GitLineHandler h
= new GitLineHandler(myProject
, gitRoot(), GitHandler
.REBASE
);
161 if (myInteractiveCheckBox
.isSelected() && myInteractiveCheckBox
.isEnabled()) {
162 h
.addParameters("-i");
164 h
.addParameters("-v");
165 if (!myDoNotUseMergeCheckBox
.isSelected()) {
166 if (myMergeStrategyComboBox
.getSelectedItem().equals(GitMergeUtil
.DEFAULT_STRATEGY
)) {
167 h
.addParameters("-m");
170 h
.addParameters("-s", myMergeStrategyComboBox
.getSelectedItem().toString());
173 if (myPreserveMergesCheckBox
.isSelected()) {
174 h
.addParameters("-p");
176 String from
= GitUIUtil
.getTextField(myFromComboBox
).getText();
177 String onto
= GitUIUtil
.getTextField(myOntoComboBox
).getText();
178 if (from
.length() == 0) {
179 h
.addParameters(onto
);
182 h
.addParameters("--onto", onto
, from
);
184 final String selectedBranch
= (String
)myBranchComboBox
.getSelectedItem();
185 if (myCurrentBranch
!= null && !myCurrentBranch
.getName().equals(selectedBranch
)) {
186 h
.addParameters(selectedBranch
);
194 private void setupStrategy() {
195 for (String s
: GitMergeUtil
.getMergeStrategies(1)) {
196 myMergeStrategyComboBox
.addItem(s
);
198 myMergeStrategyComboBox
.setSelectedItem(GitMergeUtil
.DEFAULT_STRATEGY
);
199 myDoNotUseMergeCheckBox
.addActionListener(new ActionListener() {
200 public void actionPerformed(final ActionEvent e
) {
201 myMergeStrategyComboBox
.setEnabled(!myDoNotUseMergeCheckBox
.isSelected());
210 private void validateFields() {
211 if (GitUIUtil
.getTextField(myOntoComboBox
).getText().length() == 0) {
213 setOKActionEnabled(false);
216 else if (myOntoValidator
.isInvalid()) {
217 setErrorText(GitBundle
.getString("rebase.invalid.onto"));
218 setOKActionEnabled(false);
221 if (GitUIUtil
.getTextField(myFromComboBox
).getText().length() != 0 && myFromValidator
.isInvalid()) {
222 setErrorText(GitBundle
.getString("rebase.invalid.from"));
223 setOKActionEnabled(false);
226 if (GitRebaseUtils
.isRebaseInTheProgress(gitRoot())) {
227 setErrorText(GitBundle
.getString("rebase.in.progress"));
228 setOKActionEnabled(false);
232 setOKActionEnabled(true);
236 * Setup branch drop down.
238 private void setupBranches() {
239 GitUIUtil
.getTextField(myOntoComboBox
).getDocument().addDocumentListener(new DocumentAdapter() {
240 protected void textChanged(final DocumentEvent e
) {
244 final ActionListener rootListener
= new ActionListener() {
245 public void actionPerformed(final ActionEvent e
) {
250 final ActionListener showListener
= new ActionListener() {
251 public void actionPerformed(final ActionEvent e
) {
255 myShowRemoteBranchesCheckBox
.addActionListener(showListener
);
256 myShowTagsCheckBox
.addActionListener(showListener
);
257 rootListener
.actionPerformed(null);
258 myGitRootComboBox
.addActionListener(rootListener
);
259 myBranchComboBox
.addActionListener(new ActionListener() {
260 public void actionPerformed(final ActionEvent e
) {
261 updateTrackedBranch();
267 * Update branches when git root changed
269 private void updateBranches() {
270 myBranchComboBox
.removeAllItems();
271 for (GitBranch b
: myLocalBranches
) {
272 myBranchComboBox
.addItem(b
.getName());
274 if (myCurrentBranch
!= null) {
275 myBranchComboBox
.setSelectedItem(myCurrentBranch
.getName());
278 myBranchComboBox
.setSelectedItem(0);
281 updateTrackedBranch();
285 * Update onto and from comboboxes.
287 private void updateOntoFrom() {
288 String onto
= GitUIUtil
.getTextField(myOntoComboBox
).getText();
289 String from
= GitUIUtil
.getTextField(myFromComboBox
).getText();
290 myFromComboBox
.removeAllItems();
291 myOntoComboBox
.removeAllItems();
292 for (GitBranch b
: myLocalBranches
) {
293 myFromComboBox
.addItem(b
);
294 myOntoComboBox
.addItem(b
);
296 if (myShowRemoteBranchesCheckBox
.isSelected()) {
297 for (GitBranch b
: myRemoteBranches
) {
298 myFromComboBox
.addItem(b
);
299 myOntoComboBox
.addItem(b
);
302 if (myShowTagsCheckBox
.isSelected()) {
303 for (GitTag t
: myTags
) {
304 myFromComboBox
.addItem(t
);
305 myOntoComboBox
.addItem(t
);
308 GitUIUtil
.getTextField(myOntoComboBox
).setText(onto
);
309 GitUIUtil
.getTextField(myFromComboBox
).setText(from
);
313 * Load tags and branches
315 private void loadRefs() {
317 myLocalBranches
.clear();
318 myRemoteBranches
.clear();
320 final VirtualFile root
= gitRoot();
321 GitBranch
.list(myProject
, root
, true, false, myLocalBranches
);
322 GitBranch
.list(myProject
, root
, false, true, myRemoteBranches
);
323 GitTag
.list(myProject
, root
, myTags
);
324 myCurrentBranch
= GitBranch
.current(myProject
, root
);
326 catch (VcsException e
) {
327 GitUIUtil
.showOperationError(myProject
, e
, "git branch -a");
332 * Update tracked branch basing on the currently selected branch
334 private void updateTrackedBranch() {
336 final VirtualFile root
= gitRoot();
337 String currentBranch
= (String
)myBranchComboBox
.getSelectedItem();
338 final GitBranch trackedBranch
;
339 if (currentBranch
!= null) {
340 String remote
= GitConfigUtil
.getValue(myProject
, root
, "branch." + currentBranch
+ ".remote");
341 String merge
= GitConfigUtil
.getValue(myProject
, root
, "branch." + currentBranch
+ ".merge");
343 (merge
!= null && merge
.startsWith(GitBranch
.REFS_HEADS_PREFIX
)) ? merge
.substring(GitBranch
.REFS_HEADS_PREFIX
.length()) : null;
344 if (remote
== null || merge
== null || name
== null) {
345 trackedBranch
= null;
348 if (remote
.equals(".")) {
349 trackedBranch
= new GitBranch(name
, false, false);
352 trackedBranch
= new GitBranch(remote
+ "/" + name
, false, true);
357 trackedBranch
= null;
359 if (trackedBranch
!= null) {
360 myOntoComboBox
.setSelectedItem(trackedBranch
);
363 GitUIUtil
.getTextField(myOntoComboBox
).setText("");
365 GitUIUtil
.getTextField(myFromComboBox
).setText("");
367 catch (VcsException e
) {
368 GitUIUtil
.showOperationError(myProject
, e
, "git config");
373 * @return the currently selected git root
375 public VirtualFile
gitRoot() {
376 return (VirtualFile
)myGitRootComboBox
.getSelectedItem();
384 protected String
getDimensionServiceKey() {
385 return getClass().getName();
391 protected JComponent
createCenterPanel() {
399 protected String
getHelpId() {
400 return "reference.VersionControl.Git.Rebase";