2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common
8 * Development and Distribution License("CDDL") (collectively, the
9 * "License"). You may not use this file except in compliance with the
10 * License. You can obtain a copy of the License at
11 * http://www.netbeans.org/cddl-gplv2.html
12 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13 * specific language governing permissions and limitations under the
14 * License. When distributing the software, include this License Header
15 * Notice in each file and include the License file at
16 * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17 * particular file as subject to the "Classpath" exception as provided
18 * by Sun in the GPL Version 2 section of the License file that
19 * accompanied this code. If applicable, add the following below the
20 * License Header, with the fields enclosed by brackets [] replaced by
21 * your own identifying information:
22 * "Portions Copyrighted [year] [name of copyright owner]"
26 * The Original Software is NetBeans. The Initial Developer of the Original
27 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28 * Microsystems, Inc. All Rights Reserved.
29 * Portions Copyright 2008 Alexander Coles (Ikonoklastik Productions).
31 * If you wish your version of this file to be governed by only the CDDL
32 * or only the GPL Version 2, indicate your decision by adding
33 * "[Contributor] elects to include this software in this distribution
34 * under the [CDDL or GPL Version 2] license." If you do not indicate a
35 * single choice of license, a recipient has the option to distribute
36 * your version of this file under either the CDDL, the GPL Version 2 or
37 * to extend the choice of license to its licensees as provided above.
38 * However, if you add GPL Version 2 code and therefore, elected the GPL
39 * Version 2 license, then the option applies only if the new code is
40 * made subject to such option by the copyright holder.
42 package org
.netbeans
.modules
.git
.ui
.create
;
44 import java
.awt
.event
.ActionEvent
;
46 import java
.util
.Calendar
;
47 import java
.util
.HashMap
;
49 import java
.util
.logging
.Level
;
50 import javax
.swing
.Action
;
51 import javax
.swing
.JOptionPane
;
52 import org
.netbeans
.api
.project
.Project
;
53 import org
.netbeans
.modules
.git
.FileInformation
;
54 import org
.netbeans
.modules
.git
.FileStatusCache
;
55 import org
.netbeans
.modules
.git
.Git
;
56 import org
.netbeans
.modules
.git
.GitException
;
57 import org
.netbeans
.modules
.git
.GitProgressSupport
;
58 import org
.netbeans
.modules
.git
.OutputLogger
;
59 import org
.netbeans
.modules
.git
.ui
.actions
.ContextAction
;
60 import org
.netbeans
.modules
.git
.util
.GitCommand
;
61 import org
.netbeans
.modules
.git
.util
.GitProjectUtils
;
62 import org
.netbeans
.modules
.git
.util
.GitUtils
;
63 import org
.netbeans
.modules
.versioning
.spi
.VCSContext
;
64 import org
.openide
.DialogDisplayer
;
65 import org
.openide
.NotifyDescriptor
;
66 import org
.openide
.util
.NbBundle
;
67 import org
.openide
.util
.RequestProcessor
;
70 * Create action for Git:
71 * git init - create a new repository in the given directory
75 public class CreateAction
extends ContextAction
{
77 private final VCSContext context
;
78 Map
<File
, FileInformation
> repositoryFiles
= new HashMap
<File
, FileInformation
>();
80 public CreateAction(String name
, VCSContext context
) {
81 this.context
= context
;
82 putValue(Action
.NAME
, name
);
86 public boolean isEnabled() {
87 // If it is not a Git managed repository enable action
88 File root
= GitUtils
.getRootFile(context
);
89 File
[] files
= context
.getRootFiles().toArray(new File
[context
.getRootFiles().size()]);
90 if ( files
== null || files
.length
== 0)
99 private File
getCommonAncestor(File firstFile
, File secondFile
) {
100 if (firstFile
.equals(secondFile
)) return firstFile
;
102 File tempFirstFile
= firstFile
;
103 while (tempFirstFile
!= null) {
104 File tempSecondFile
= secondFile
;
105 while (tempSecondFile
!= null) {
106 if (tempFirstFile
.equals(tempSecondFile
))
107 return tempSecondFile
;
108 tempSecondFile
= tempSecondFile
.getParentFile();
110 tempFirstFile
= tempFirstFile
.getParentFile();
115 private File
getCommonAncestor(File
[] files
) {
118 for (int i
= 1; i
< files
.length
; i
++) {
119 f1
= getCommonAncestor(f1
, files
[i
]);
121 Git
.LOG
.log(Level
.SEVERE
, "Unable to get common parent of {0} and {1} ", // NOI18N
122 new Object
[] {f1
.getAbsolutePath(), files
[i
].getAbsolutePath()});
129 public void performAction(ActionEvent e
) {
130 final Git git
= Git
.getInstance();
132 File
[] files
= context
.getRootFiles().toArray(new File
[context
.getRootFiles().size()]);
133 if(files
== null || files
.length
== 0) return;
135 // If there is a .git directory in an ancestor of any of the files in
136 // the context we fail.
138 for (File file
: files
) {
139 if(!file
.isDirectory()) file
= file
.getParentFile();
140 if (git
.getTopmostManagedParent(file
) != null) {
141 Git
.LOG
.log(Level
.SEVERE
, "Found .git directory in ancestor of {0} ", // NOI18N
147 final Project proj
= GitUtils
.getProject(context
);
148 File projFile
= GitUtils
.getProjectFile(proj
);
150 if (projFile
== null) {
151 OutputLogger logger
= OutputLogger
.getLogger(Git
.GIT_OUTPUT_TAB_TITLE
);
152 logger
.outputInRed( NbBundle
.getMessage(CreateAction
.class,"MSG_CREATE_TITLE")); // NOI18N
153 logger
.outputInRed( NbBundle
.getMessage(CreateAction
.class,"MSG_CREATE_TITLE_SEP")); // NOI18N
155 NbBundle
.getMessage(CreateAction
.class, "MSG_CREATE_NOT_SUPPORTED_INVIEW_INFO")); // NOI18N
156 logger
.output(""); // NOI18N
157 JOptionPane
.showMessageDialog(null,
158 NbBundle
.getMessage(CreateAction
.class, "MSG_CREATE_NOT_SUPPORTED_INVIEW"),// NOI18N
159 NbBundle
.getMessage(CreateAction
.class, "MSG_CREATE_NOT_SUPPORTED_INVIEW_TITLE"),// NOI18N
160 JOptionPane
.INFORMATION_MESSAGE
);
164 String projName
= GitProjectUtils
.getProjectName(projFile
);
167 root
= getCommonAncestor(files
);
168 root
= getCommonAncestor(root
, projFile
);
169 if (root
== null) return;
171 final File rootToManage
= root
;
172 final String prjName
= projName
;
174 RequestProcessor rp
= git
.getRequestProcessor(rootToManage
.getAbsolutePath());
176 GitProgressSupport supportCreate
= new GitProgressSupport() {
177 public void perform() {
180 OutputLogger logger
= getLogger();
182 NbBundle
.getMessage(CreateAction
.class,
183 "MSG_CREATE_TITLE")); // NOI18N
185 NbBundle
.getMessage(CreateAction
.class,
186 "MSG_CREATE_TITLE_SEP")); // NOI18N
189 NbBundle
.getMessage(CreateAction
.class,
190 "MSG_CREATE_INIT", prjName
, rootToManage
)); // NOI18N
191 GitCommand
.doCreate(rootToManage
, logger
);
192 git
.versionedFilesChanged();
193 git
.refreshAllAnnotations();
194 } catch (GitException ex
) {
195 NotifyDescriptor
.Exception e
= new NotifyDescriptor
.Exception(ex
);
196 DialogDisplayer
.getDefault().notifyLater(e
);
200 supportCreate
.start(rp
, rootToManage
.getAbsolutePath(),
201 org
.openide
.util
.NbBundle
.getMessage(CreateAction
.class, "MSG_Create_Progress")); // NOI18N
204 GitProgressSupport supportAdd
= new GitProgressSupport() {
205 public void perform() {
206 OutputLogger logger
= getLogger();
208 File
[] files
= GitUtils
.getProjectRootFiles(proj
);
209 FileStatusCache cache
= git
.getFileStatusCache();
210 FileInformation fi
= new FileInformation(FileInformation
.STATUS_NOTVERSIONED_NEWLOCALLY
, null, false);
212 for (int j
= 0; j
< files
.length
; j
++) {
213 File rootFile
= files
[j
];
214 Calendar start
= Calendar
.getInstance();
215 repositoryFiles
= GitCommand
.getUnknownStatus(rootToManage
, rootFile
);
216 Calendar end
= Calendar
.getInstance();
217 Git
.LOG
.log(Level
.FINE
, "getUnknownStatus took {0} millisecs", end
.getTimeInMillis() - start
.getTimeInMillis()); // NOI18N
219 NbBundle
.getMessage(CreateAction
.class,
220 "MSG_CREATE_ADD", repositoryFiles
.keySet().size(), rootFile
.getAbsolutePath())); // NOI18N
221 start
= Calendar
.getInstance(); cache
.addToCache(repositoryFiles
.keySet());
222 end
= Calendar
.getInstance();
223 Git
.LOG
.log(Level
.FINE
, "addUnknownsToCache took {0} millisecs", end
.getTimeInMillis() - start
.getTimeInMillis()); // NOI18N
224 if (repositoryFiles
.keySet().size() < OutputLogger
.MAX_LINES_TO_PRINT
) {
225 for(File f
: repositoryFiles
.keySet()){
226 logger
.output("\t" + f
.getAbsolutePath()); // NOI18N
230 GitUtils
.createIgnored(rootToManage
);
231 logger
.output(""); // NOI18N
232 logger
.outputInRed(NbBundle
.getMessage(CreateAction
.class, "MSG_CREATE_DONE_WARNING")); // NOI18N
233 } catch (GitException ex
) {
234 NotifyDescriptor
.Exception e
= new NotifyDescriptor
.Exception(ex
);
235 DialogDisplayer
.getDefault().notifyLater(e
);
237 logger
.outputInRed(NbBundle
.getMessage(CreateAction
.class, "MSG_CREATE_DONE")); // NOI18N
238 logger
.output(""); // NOI18N
242 supportAdd
.start(rp
, rootToManage
.getAbsolutePath(),
243 org
.openide
.util
.NbBundle
.getMessage(CreateAction
.class, "MSG_Create_Add_Progress")); // NOI18N