Branching in RepositoriesView
[egit/spearce.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / repository / CreateBranchPage.java
blob70a7bfb1c8aa3589f2c56adc625ef3725bd58300
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 branch based on another branch or with a selection of
42 * another branch
44 public class CreateBranchPage extends WizardPage {
46 private final Repository myRepository;
48 private final Ref myBaseBranch;
50 private final boolean remoteMode;
52 private Text nameText;
54 private Button checkout;
56 private Combo branchCombo;
58 /**
59 * Create a branch
61 * @param repo
62 * the repository
63 * @param baseBranch
64 * the branch to base the new branch on, may be null
65 * @param remote
66 * true if remote branch is to be created
68 public CreateBranchPage(Repository repo, Ref baseBranch, boolean remote) {
69 super(CreateBranchPage.class.getName());
70 this.myRepository = repo;
71 this.myBaseBranch = baseBranch;
72 this.remoteMode = remote;
73 if (this.remoteMode)
74 if (baseBranch != null)
75 setTitle(NLS.bind(
76 UIText.CreateBranchPage_CreateRemoteBaseOnTitle,
77 myBaseBranch.getName()));
78 else
79 setTitle(UIText.CreateBranchPage_CreateRemoteTitle);
80 else if (baseBranch != null)
81 setTitle(NLS.bind(UIText.CreateBranchPage_CreateLocalBasedTitle,
82 myBaseBranch.getName()));
83 else
84 setTitle(UIText.CreateBranchPage_CreateLocalTitle);
87 public void createControl(Composite parent) {
89 Composite main = new Composite(parent, SWT.NONE);
90 main.setLayout(new GridLayout(2, false));
92 Label sourceLabel = new Label(main, SWT.NONE);
93 sourceLabel.setText(UIText.CreateBranchPage_SourceBranchLabel);
94 sourceLabel.setToolTipText(UIText.CreateBranchPage_SourceBranchTooltip);
95 this.branchCombo = new Combo(main, SWT.READ_ONLY | SWT.DROP_DOWN);
97 GridDataFactory.fillDefaults().grab(true, false).applyTo(
98 this.branchCombo);
100 try {
101 for (Entry<String, Ref> ref : myRepository.getRefDatabase()
102 .getRefs(Constants.R_HEADS).entrySet()) {
103 if (!ref.getValue().isSymbolic())
104 this.branchCombo.add(ref.getValue().getName());
106 for (Entry<String, Ref> ref : myRepository.getRefDatabase()
107 .getRefs(Constants.R_REMOTES).entrySet()) {
108 if (!ref.getValue().isSymbolic())
109 this.branchCombo.add(ref.getValue().getName());
112 } catch (IOException e1) {
113 // ignore here
116 this.branchCombo.addSelectionListener(new SelectionAdapter() {
118 @Override
119 public void widgetSelected(SelectionEvent e) {
120 checkPage();
124 if (myBaseBranch != null) {
125 this.branchCombo.setText(myBaseBranch.getName());
126 this.branchCombo.setEnabled(false);
127 } else {
128 String fullBranch;
129 try {
130 fullBranch = myRepository.getFullBranch();
131 this.branchCombo.setText(fullBranch);
132 } catch (IOException e1) {
133 // ignore
137 Label nameLabel = new Label(main, SWT.NONE);
138 nameLabel.setText(UIText.CreateBranchPage_BranchNameLabel);
139 if (remoteMode)
140 nameLabel.setToolTipText(NLS.bind(
141 UIText.CreateBranchPage_BranchNameTooltip,
142 Constants.R_REMOTES));
143 else
144 nameLabel.setToolTipText(NLS.bind(
145 UIText.CreateBranchPage_BranchNameTooltip,
146 Constants.R_HEADS));
148 nameText = new Text(main, SWT.BORDER);
149 GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText);
150 nameText.addModifyListener(new ModifyListener() {
152 public void modifyText(ModifyEvent e) {
153 checkPage();
156 checkout = new Button(main, SWT.CHECK);
157 checkout.setText(UIText.CreateBranchPage_CheckoutButton);
158 // most of the time, we probably will check this out
159 checkout.setSelection(true);
160 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(
161 checkout);
162 checkout.addSelectionListener(new SelectionAdapter() {
164 @Override
165 public void widgetSelected(SelectionEvent e) {
166 checkPage();
171 setControl(main);
172 nameText.setFocus();
174 // in any case, we will have to enter the name
175 setPageComplete(false);
176 if (this.myBaseBranch != null)
177 setMessage(UIText.CreateBranchPage_ChosseNameMessage);
178 else
179 setMessage(UIText.CreateBranchPage_ChooseBranchAndNameMessage);
182 private void checkPage() {
183 setErrorMessage(null);
185 try {
187 if (branchCombo.getText().length() == 0) {
188 setErrorMessage(UIText.CreateBranchPage_MissingSourceMessage);
189 return;
191 if (nameText.getText().length() == 0) {
192 setErrorMessage(UIText.CreateBranchPage_MissingNameMessage);
193 return;
196 String fullName = getBranchName();
197 try {
198 if (myRepository.getRef(fullName) != null)
199 setErrorMessage(NLS.bind(
200 UIText.CreateBranchPage_BranchAlreadyExistsMessage,
201 fullName));
202 return;
203 } catch (IOException e) {
204 // ignore here
206 } finally {
207 setPageComplete(getErrorMessage() == null);
211 private String getBranchName() {
212 if (remoteMode)
213 return Constants.R_REMOTES + nameText.getText();
214 else
215 return Constants.R_HEADS + nameText.getText();
218 private String getSourceBranchName() {
219 if (myBaseBranch != null)
220 return myBaseBranch.getName();
221 else if (this.branchCombo != null)
222 return this.branchCombo.getText();
223 else
224 return null;
228 * @param monitor
229 * @throws CoreException
230 * @throws IOException
232 public void createBranch(IProgressMonitor monitor) throws CoreException,
233 IOException {
235 String newRefName = getBranchName();
236 RefUpdate updateRef;
238 monitor.beginTask(UIText.CreateBranchPage_CreatingBranchMessage,
239 IProgressMonitor.UNKNOWN);
240 updateRef = myRepository.updateRef(newRefName);
242 Ref sourceBranch;
243 if (myBaseBranch != null) {
244 sourceBranch = myBaseBranch;
245 } else {
246 sourceBranch = myRepository.getRef(getSourceBranchName());
248 ObjectId startAt = sourceBranch.getObjectId();
249 String startBranch = myRepository
250 .shortenRefName(sourceBranch.getName());
251 updateRef.setNewObjectId(startAt);
252 updateRef
253 .setRefLogMessage("branch: Created from " + startBranch, false); //$NON-NLS-1$
254 updateRef.update();
255 if (checkout.getSelection()) {
256 if (monitor.isCanceled())
257 return;
258 monitor.beginTask(UIText.CreateBranchPage_CheckingOutMessage,
259 IProgressMonitor.UNKNOWN);
260 new BranchOperation(myRepository, getBranchName()).execute(monitor);