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.
44 import java
.beans
.PropertyChangeListener
;
45 import java
.beans
.PropertyChangeSupport
;
47 import java
.io
.FileInputStream
;
48 import java
.io
.FileOutputStream
;
49 import java
.io
.IOException
;
50 import java
.util
.HashMap
;
52 import java
.util
.logging
.Level
;
53 import java
.util
.logging
.Logger
;
54 import org
.nbgit
.util
.GitUtils
;
55 import org
.netbeans
.modules
.versioning
.spi
.VCSContext
;
56 import org
.netbeans
.modules
.versioning
.spi
.VersioningSupport
;
57 import org
.openide
.filesystems
.FileObject
;
58 import org
.openide
.filesystems
.FileUtil
;
59 import org
.openide
.util
.RequestProcessor
;
60 import org
.spearce
.jgit
.lib
.Repository
;
63 * Main entry point for Git functionality, use getInstance() to get the Git object.
66 * @author Maros Sandor
70 public static final String GIT_OUTPUT_TAB_TITLE
= org
.openide
.util
.NbBundle
.getMessage(Git
.class, "CTL_Git_DisplayName"); // NOI18N
72 public static final String PROP_ANNOTATIONS_CHANGED
= "annotationsChanged"; // NOI18N
73 public static final String PROP_VERSIONED_FILES_CHANGED
= "versionedFilesChanged"; // NOI18N
74 public static final String PROP_CHANGESET_CHANGED
= "changesetChanged"; // NOI18N
75 public static final Logger LOG
= Logger
.getLogger("org.nbgit"); // NOI18N
76 private static final int STATUS_DIFFABLE
=
77 StatusInfo
.STATUS_VERSIONED_UPTODATE
|
78 StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
|
79 StatusInfo
.STATUS_VERSIONED_MODIFIEDINREPOSITORY
|
80 StatusInfo
.STATUS_VERSIONED_CONFLICT
|
81 StatusInfo
.STATUS_VERSIONED_MERGE
|
82 StatusInfo
.STATUS_VERSIONED_REMOVEDINREPOSITORY
|
83 StatusInfo
.STATUS_VERSIONED_MODIFIEDINREPOSITORY
|
84 StatusInfo
.STATUS_VERSIONED_MODIFIEDINREPOSITORY
;
85 private final PropertyChangeSupport support
= new PropertyChangeSupport(this);
86 private final StatusCache statusCache
= new StatusCache(this);
87 private HashMap
<String
, RequestProcessor
> processorsToUrl
;
88 private final Map
<File
, Repository
> repos
= new HashMap
<File
, Repository
>();
89 private static Git instance
;
95 public static synchronized Git
getInstance()
102 public Repository
getRepository(File root
)
104 Repository repo
= repos
.get(root
);
107 final File gitDir
= new File(root
, GitRepository
.GIT_DIR
);
109 repo
= new Repository(gitDir
);
110 repos
.put(root
, repo
);
111 } catch (IOException ex
) {
119 * Gets the Status Cache for the Git repository.
121 * @return StatusCache for the repository
123 public StatusCache
getStatusCache()
129 * Tests the <tt>.git</tt> directory itself.
134 public boolean isAdministrative(File file
)
136 String name
= file
.getName();
137 return isAdministrative(name
) && file
.isDirectory();
140 public boolean isAdministrative(String fileName
)
142 return fileName
.equals(".git"); // NOI18N
146 * Tests whether a file or directory should receive the STATUS_NOTVERSIONED_NOTMANAGED status.
147 * All files and folders that have a parent with CVS/Repository file are considered versioned.
149 * @param file a file or directory
150 * @return false if the file should receive the STATUS_NOTVERSIONED_NOTMANAGED status, true otherwise
152 public boolean isManaged(File file
)
154 return VersioningSupport
.getOwner(file
) instanceof GitVCS
&& !GitUtils
.isPartOfGitMetadata(file
);
157 public File
getTopmostManagedParent(File file
)
159 if (GitUtils
.isPartOfGitMetadata(file
))
160 for (; file
!= null; file
= file
.getParentFile()) {
161 if (isAdministrative(file
)) {
162 file
= file
.getParentFile();
167 for (; file
!= null; file
= file
.getParentFile()) {
168 if (org
.netbeans
.modules
.versioning
.util
.Utils
.isScanForbidden(file
))
170 if (new File(file
, ".git").canWrite()) { // NOI18N
179 * Uses content analysis to return the mime type for files.
181 * @param file file to examine
182 * @return String mime type of the file (or best guess)
184 public String
getMimeType(File file
)
186 FileObject fo
= FileUtil
.toFileObject(file
);
189 foMime
= "content/unknown";
191 foMime
= fo
.getMIMEType();
192 if ("content/unknown".equals(foMime
)) // NOI18N
193 foMime
= "text/plain";
195 if ((statusCache
.getStatus(file
).getStatus() & StatusInfo
.STATUS_VERSIONED
) == 0)
196 return GitUtils
.isFileContentBinary(file
) ?
"application/octet-stream" : foMime
;
201 public void versionedFilesChanged()
203 support
.firePropertyChange(PROP_VERSIONED_FILES_CHANGED
, null, null);
206 public void refreshAllAnnotations()
208 support
.firePropertyChange(PROP_ANNOTATIONS_CHANGED
, null, null);
211 public void changesetChanged(File repository
)
213 support
.firePropertyChange(PROP_CHANGESET_CHANGED
, repository
, null);
216 public void addPropertyChangeListener(PropertyChangeListener listener
)
218 support
.addPropertyChangeListener(listener
);
221 public void removePropertyChangeListener(PropertyChangeListener listener
)
223 support
.removePropertyChangeListener(listener
);
226 public void getOriginalFile(File workingCopy
, File originalFile
)
228 StatusInfo info
= statusCache
.getStatus(workingCopy
);
229 LOG
.log(Level
.FINE
, "getOriginalFile: {0} {1}", new Object
[]{workingCopy
, info
}); // NOI18N
230 if ((info
.getStatus() & STATUS_DIFFABLE
) == 0)
233 // We can get status returned as UptoDate instead of LocallyNew
234 // because refreshing of status after creation has been scheduled
235 // but may not have happened yet.
237 File original
= GitUtils
.getFileRevision(workingCopy
, GitRepository
.REVISION_BASE
);
238 if (original
== null)
240 org
.netbeans
.modules
.versioning
.util
.Utils
.copyStreamsCloseAll(new FileOutputStream(originalFile
), new FileInputStream(original
));
242 } catch (IOException e
) {
243 Logger
.getLogger(Git
.class.getName()).log(Level
.INFO
, "Unable to get original file", e
); // NOI18N
249 * Serializes all Git requests (moves them out of AWT).
251 public RequestProcessor
getRequestProcessor()
253 return getRequestProcessor((String
) null);
257 * Serializes all Git requests (moves them out of AWT).
259 public RequestProcessor
getRequestProcessor(File file
)
261 return getRequestProcessor(file
.getAbsolutePath());
264 public RequestProcessor
getRequestProcessor(String url
)
266 if (processorsToUrl
== null)
267 processorsToUrl
= new HashMap
<String
, RequestProcessor
>();
275 RequestProcessor rp
= processorsToUrl
.get(key
);
277 rp
= new RequestProcessor("Git - " + key
, 1, true); // NOI18N
278 processorsToUrl
.put(key
, rp
);
283 public void clearRequestProcessor(String url
)
285 if (processorsToUrl
!= null & url
!= null)
286 processorsToUrl
.remove(url
);
291 * @param repositoryRoot String of Git repository so that logger writes to correct output tab. Can be null
292 * in which case the logger will not print anything
293 * @return OutputLogger logger to write to
295 public OutputLogger
getLogger(String repositoryRoot
)
297 return OutputLogger
.getLogger(repositoryRoot
);