Git Repositories View: fix Branch Creation page
[egit/spearce.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / repository / CreateBranchPage.java
blob6c0975b040881acf9af27c1c0d8763bd8497df03
1 /*******************************************************************************
2 * Copyright (c) 2010 SAP AG.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
8 * Contributors:
9 * Mathias Kinzler (SAP AG) - initial implementation
10 *******************************************************************************/
11 package org.eclipse.egit.ui.internal.repository;
13 import java.io.IOException;
14 import java.util.Map.Entry;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.egit.core.op.BranchOperation;
19 import org.eclipse.egit.ui.UIText;
20 import org.eclipse.jface.layout.GridDataFactory;
21 import org.eclipse.jface.wizard.WizardPage;
22 import org.eclipse.jgit.lib.Constants;
23 import org.eclipse.jgit.lib.ObjectId;
24 import org.eclipse.jgit.lib.Ref;
25 import org.eclipse.jgit.lib.RefUpdate;
26 import org.eclipse.jgit.lib.Repository;
27 import org.eclipse.osgi.util.NLS;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.events.ModifyEvent;
30 import org.eclipse.swt.events.ModifyListener;
31 import org.eclipse.swt.events.SelectionAdapter;
32 import org.eclipse.swt.events.SelectionEvent;
33 import org.eclipse.swt.layout.GridLayout;
34 import org.eclipse.swt.widgets.Button;
35 import org.eclipse.swt.widgets.Combo;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Label;
38 import org.eclipse.swt.widgets.Text;
40 /**
41 * Allows to create a new local branch based on another branch. The source
42 * branch can be selected using a drop down.
44 public class CreateBranchPage extends WizardPage {
46 private final Repository myRepository;
48 private final Ref myBaseBranch;
50 private Text nameText;
52 private Button checkout;
54 private Combo branchCombo;
56 /**
57 * Constructs this page.
58 * <p>
59 * If a base branch is provided, the drop down will be selected accordingly
61 * @param repo
62 * the repository
63 * @param baseBranch
64 * the branch to base the new branch on, may be null
66 public CreateBranchPage(Repository repo, Ref baseBranch) {
67 super(CreateBranchPage.class.getName());
68 this.myRepository = repo;
69 this.myBaseBranch = baseBranch;
70 setTitle(UIText.CreateBranchPage_Title);
73 public void createControl(Composite parent) {
74 Composite main = new Composite(parent, SWT.NONE);
75 main.setLayout(new GridLayout(3, false));
77 Label sourceLabel = new Label(main, SWT.NONE);
78 sourceLabel.setText(UIText.CreateBranchPage_SourceBranchLabel);
79 sourceLabel.setToolTipText(UIText.CreateBranchPage_SourceBranchTooltip);
80 this.branchCombo = new Combo(main, SWT.READ_ONLY | SWT.DROP_DOWN);
82 GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(
83 this.branchCombo);
85 try {
86 for (Entry<String, Ref> ref : myRepository.getRefDatabase()
87 .getRefs(Constants.R_HEADS).entrySet()) {
88 if (!ref.getValue().isSymbolic())
89 this.branchCombo.add(ref.getValue().getName());
91 for (Entry<String, Ref> ref : myRepository.getRefDatabase()
92 .getRefs(Constants.R_REMOTES).entrySet()) {
93 if (!ref.getValue().isSymbolic())
94 this.branchCombo.add(ref.getValue().getName());
97 } catch (IOException e1) {
98 // ignore here
101 this.branchCombo.addSelectionListener(new SelectionAdapter() {
102 @Override
103 public void widgetSelected(SelectionEvent e) {
104 checkPage();
107 // select the current branch in the drop down
108 if (myBaseBranch != null) {
109 this.branchCombo.setText(myBaseBranch.getName());
110 } else {
111 // TODO this only works for local branches; once we have a solution
112 // for accessing the correct information (we need this for the
113 // project label decoration, too), we should figure out if a remote
114 // branch is checked-out and set the text accordingly
115 String fullBranch;
116 try {
117 fullBranch = myRepository.getFullBranch();
118 this.branchCombo.setText(fullBranch);
119 } catch (IOException e1) {
120 // ignore
124 Label nameLabel = new Label(main, SWT.NONE);
125 nameLabel.setText(UIText.CreateBranchPage_BranchNameLabel);
127 // we visualize the prefix here
128 Text prefix = new Text(main, SWT.NONE);
129 prefix.setText(Constants.R_HEADS);
130 prefix.setEnabled(false);
132 nameText = new Text(main, SWT.BORDER);
133 GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText);
135 nameText.addModifyListener(new ModifyListener() {
136 public void modifyText(ModifyEvent e) {
137 checkPage();
141 boolean isBare = myRepository.getConfig().getBoolean(
142 "core", "bare", false); //$NON-NLS-1$ //$NON-NLS-2$
143 checkout = new Button(main, SWT.CHECK);
144 checkout.setText(UIText.CreateBranchPage_CheckoutButton);
145 // most of the time, we probably will check this out
146 // unless we have a bare repository which doesn't allow
147 // check out at all
148 checkout.setSelection(!isBare);
149 checkout.setEnabled(!isBare);
150 checkout.setVisible(!isBare);
151 GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(
152 checkout);
153 checkout.addSelectionListener(new SelectionAdapter() {
155 @Override
156 public void widgetSelected(SelectionEvent e) {
157 checkPage();
162 setControl(main);
163 nameText.setFocus();
165 // in any case, we will have to enter the name
166 setPageComplete(false);
167 if (this.myBaseBranch != null)
168 setMessage(UIText.CreateBranchPage_ChosseNameMessage);
169 else
170 setMessage(UIText.CreateBranchPage_ChooseBranchAndNameMessage);
173 private void checkPage() {
174 setErrorMessage(null);
176 try {
178 if (branchCombo.getText().length() == 0) {
179 setErrorMessage(UIText.CreateBranchPage_MissingSourceMessage);
180 return;
182 if (nameText.getText().length() == 0) {
183 setErrorMessage(UIText.CreateBranchPage_MissingNameMessage);
184 return;
187 String fullName = getBranchName();
188 try {
189 if (myRepository.getRef(fullName) != null)
190 setErrorMessage(NLS.bind(
191 UIText.CreateBranchPage_BranchAlreadyExistsMessage,
192 fullName));
193 return;
194 } catch (IOException e) {
195 // ignore here
197 } finally {
198 setPageComplete(getErrorMessage() == null);
202 private String getBranchName() {
203 return Constants.R_HEADS + nameText.getText();
206 private String getSourceBranchName() {
207 if (myBaseBranch != null)
208 return myBaseBranch.getName();
209 else if (this.branchCombo != null)
210 return this.branchCombo.getText();
211 else
212 return null;
216 * @param monitor
217 * @throws CoreException
218 * @throws IOException
220 public void createBranch(IProgressMonitor monitor) throws CoreException,
221 IOException {
222 String newRefName = getBranchName();
223 RefUpdate updateRef;
225 monitor.beginTask(UIText.CreateBranchPage_CreatingBranchMessage,
226 IProgressMonitor.UNKNOWN);
227 updateRef = myRepository.updateRef(newRefName);
229 Ref sourceBranch;
230 if (myBaseBranch != null) {
231 sourceBranch = myBaseBranch;
232 } else {
233 sourceBranch = myRepository.getRef(getSourceBranchName());
235 ObjectId startAt = sourceBranch.getObjectId();
236 String startBranch = myRepository
237 .shortenRefName(sourceBranch.getName());
238 updateRef.setNewObjectId(startAt);
239 updateRef
240 .setRefLogMessage("branch: Created from " + startBranch, false); //$NON-NLS-1$
241 updateRef.update();
242 if (checkout.getSelection()) {
243 if (monitor.isCanceled())
244 return;
245 monitor.beginTask(UIText.CreateBranchPage_CheckingOutMessage,
246 IProgressMonitor.UNKNOWN);
247 new BranchOperation(myRepository, getBranchName()).execute(monitor);