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.
30 * If you wish your version of this file to be governed by only the CDDL
31 * or only the GPL Version 2, indicate your decision by adding
32 * "[Contributor] elects to include this software in this distribution
33 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34 * single choice of license, a recipient has the option to distribute
35 * your version of this file under either the CDDL, the GPL Version 2 or
36 * to extend the choice of license to its licensees as provided above.
37 * However, if you add GPL Version 2 code and therefore, elected the GPL
38 * Version 2 license, then the option applies only if the new code is
39 * made subject to such option by the copyright holder.
41 package org
.nbgit
.util
;
43 import org
.nbgit
.OutputLogger
;
44 import org
.nbgit
.StatusInfo
;
46 import java
.io
.IOException
;
47 import java
.util
.ArrayList
;
48 import java
.util
.HashMap
;
49 import java
.util
.List
;
53 import org
.nbgit
.ui
.log
.RepositoryRevision
;
54 import org
.netbeans
.api
.queries
.SharabilityQuery
;
55 import org
.openide
.util
.Exceptions
;
56 import org
.eclipse
.jgit
.dircache
.DirCache
;
57 import org
.eclipse
.jgit
.dircache
.DirCacheEntry
;
58 import org
.eclipse
.jgit
.lib
.Constants
;
59 import org
.eclipse
.jgit
.lib
.IndexDiff
;
60 import org
.eclipse
.jgit
.lib
.ObjectId
;
61 import org
.eclipse
.jgit
.lib
.Repository
;
62 import org
.eclipse
.jgit
.revwalk
.RevCommit
;
63 import org
.eclipse
.jgit
.revwalk
.RevWalk
;
64 import org
.eclipse
.jgit
.revwalk
.filter
.RevFilter
;
65 import org
.eclipse
.jgit
.treewalk
.FileTreeIterator
;
66 import org
.eclipse
.jgit
.treewalk
.TreeWalk
;
67 import org
.eclipse
.jgit
.treewalk
.filter
.PathFilter
;
68 import org
.eclipse
.jgit
.treewalk
.filter
.PathFilterGroup
;
73 public class GitCommand
{
75 public static RepositoryRevision
.Walk
getLogMessages(String rootPath
, Set
<File
> files
, String fromRevision
, String toRevision
, boolean showMerges
, OutputLogger logger
) {
76 File root
= new File(rootPath
);
77 Repository repo
= Git
.getInstance().getRepository(root
);
78 RepositoryRevision
.Walk walk
= new RepositoryRevision
.Walk(repo
);
81 if (fromRevision
== null) {
82 fromRevision
= Constants
.HEAD
;
84 ObjectId from
= repo
.resolve(fromRevision
);
88 walk
.markStart(walk
.parseCommit(from
));
89 ObjectId to
= toRevision
!= null ? repo
.resolve(toRevision
) : null;
91 walk
.markUninteresting(walk
.parseCommit(to
));
93 List
<PathFilter
> paths
= new ArrayList
<PathFilter
>();
94 for (File file
: files
) {
95 String path
= getRelative(root
, file
);
97 if (!(path
.length() == 0)) {
98 paths
.add(PathFilter
.create(path
));
102 if (!paths
.isEmpty()) {
103 walk
.setTreeFilter(PathFilterGroup
.create(paths
));
106 walk
.setRevFilter(RevFilter
.NO_MERGES
);
108 } catch (IOException ioe
) {
115 public static List
<String
[]> getRevisions(File root
, int limit
) {
116 return getRevisionsForFile(root
, null, limit
);
119 public static List
<String
[]> getRevisionsForFile(File root
, File
[] files
, int limit
) {
120 Repository repo
= Git
.getInstance().getRepository(root
);
121 RevWalk walk
= new RevWalk(repo
);
122 List
<String
[]> revs
= new ArrayList
<String
[]>();
125 ObjectId from
= repo
.resolve(Constants
.HEAD
);
129 walk
.markStart(walk
.parseCommit(from
));
132 List
<PathFilter
> paths
= new ArrayList
<PathFilter
>();
133 for (File file
: files
) {
134 String path
= getRelative(root
, file
);
136 if (!(path
.length() == 0)) {
137 paths
.add(PathFilter
.create(path
));
141 if (!paths
.isEmpty()) {
142 walk
.setTreeFilter(PathFilterGroup
.create(paths
));
146 for (RevCommit rev
: walk
) {
147 revs
.add(new String
[]{rev
.getShortMessage(), rev
.getId().name()});
153 } catch (IOException ioe
) {
159 private static String
getRelative(File root
, File dir
) {
160 return getRelative(root
.getAbsolutePath(), dir
.getAbsolutePath());
163 private static String
getRelative(String root
, String dir
) {
164 if (dir
.equals(root
)) {
167 return dir
.replace(root
+ File
.separator
, "");
170 private static void put(Set
<String
> set
, String relPath
,
171 Map
<File
, StatusInfo
> files
, File root
, int status
) {
172 for (String path
: set
) {
173 if (relPath
.length() > 0 && !path
.startsWith(relPath
)) {
176 File file
= new File(root
, path
);
177 files
.put(file
, new StatusInfo(status
, null, false));
193 public static Map
<File
, StatusInfo
> getAllStatus(File root
, File dir
) throws IOException
{
194 String relPath
= getRelative(root
, dir
);
196 Repository repo
= Git
.getInstance().getRepository(root
);
197 Map
<File
, StatusInfo
> files
= new HashMap
<File
, StatusInfo
>();
200 IndexDiff index
= new IndexDiff(repo
);
203 put(index
.getAdded(), relPath
, files
, root
,
204 StatusInfo
.STATUS_VERSIONED_ADDEDLOCALLY
);
205 put(index
.getRemoved(), relPath
, files
, root
,
206 StatusInfo
.STATUS_VERSIONED_REMOVEDLOCALLY
);
207 put(index
.getMissing(), relPath
, files
, root
,
208 StatusInfo
.STATUS_VERSIONED_DELETEDLOCALLY
);
209 put(index
.getChanged(), relPath
, files
, root
,
210 StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
);
211 put(index
.getModified(), relPath
, files
, root
,
212 StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
);
214 final FileTreeIterator workTree
= new FileTreeIterator(repo
.getWorkDir());
215 final TreeWalk walk
= new TreeWalk(repo
);
216 DirCache cache
= DirCache
.read(repo
);
218 walk
.reset(); // drop the first empty tree
219 walk
.setRecursive(true);
220 walk
.addTree(workTree
);
222 int share
= SharabilityQuery
.getSharability(dir
);
223 if (share
== SharabilityQuery
.NOT_SHARABLE
) {
226 while (walk
.next()) {
227 String path
= walk
.getPathString();
229 if (relPath
.length() > 0 && !path
.startsWith(relPath
)) {
232 if (index
.getAdded().contains(path
) ||
233 index
.getRemoved().contains(path
) ||
234 index
.getMissing().contains(path
) ||
235 index
.getChanged().contains(path
) ||
236 index
.getModified().contains(path
)) {
239 DirCacheEntry entry
= cache
.getEntry(path
);
240 File file
= new File(root
, path
);
244 status
= StatusInfo
.STATUS_VERSIONED_UPTODATE
;
246 if (share
== SharabilityQuery
.MIXED
&&
247 SharabilityQuery
.getSharability(file
) == SharabilityQuery
.NOT_SHARABLE
) {
250 status
= StatusInfo
.STATUS_NOTVERSIONED_NEWLOCALLY
;
253 files
.put(file
, new StatusInfo(status
, null, false));
256 } catch (IOException ex
) {
257 Exceptions
.printStackTrace(ex
);
271 public static Map
<File
, StatusInfo
> getInterestingStatus(File root
, File dir
) {
272 String relPath
= getRelative(root
, dir
);
274 Repository repo
= Git
.getInstance().getRepository(root
);
277 Map
<File
, StatusInfo
> files
= new HashMap
<File
, StatusInfo
>();
280 index
= new IndexDiff(repo
);
283 put(index
.getAdded(), relPath
, files
, root
,
284 StatusInfo
.STATUS_VERSIONED_ADDEDLOCALLY
);
285 put(index
.getRemoved(), relPath
, files
, root
,
286 StatusInfo
.STATUS_VERSIONED_REMOVEDLOCALLY
);
287 put(index
.getMissing(), relPath
, files
, root
,
288 StatusInfo
.STATUS_VERSIONED_DELETEDLOCALLY
);
289 put(index
.getChanged(), relPath
, files
, root
,
290 StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
);
291 put(index
.getModified(), relPath
, files
, root
,
292 StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
);
294 final FileTreeIterator workTree
= new FileTreeIterator(repo
.getWorkDir());
295 final TreeWalk walk
= new TreeWalk(repo
);
297 walk
.reset(); // drop the first empty tree
298 walk
.setRecursive(true);
299 walk
.addTree(workTree
);
301 DirCache cache
= DirCache
.read(repo
);
303 while (walk
.next()) {
304 String path
= walk
.getPathString();
306 if (relPath
.length() > 0 && !path
.startsWith(relPath
)) {
309 if (index
.getAdded().contains(path
) ||
310 index
.getRemoved().contains(path
) ||
311 index
.getMissing().contains(path
) ||
312 index
.getChanged().contains(path
) ||
313 index
.getModified().contains(path
)) {
316 DirCacheEntry entry
= cache
.getEntry(path
);
320 int status
= StatusInfo
.STATUS_NOTVERSIONED_NEWLOCALLY
;
321 File file
= new File(root
, path
);
322 files
.put(file
, new StatusInfo(status
, null, false));
325 } catch (IOException ex
) {
326 Exceptions
.printStackTrace(ex
);
332 public static StatusInfo
getSingleStatus(File root
, File file
) {
333 Repository repo
= Git
.getInstance().getRepository(root
);
336 int share
= SharabilityQuery
.getSharability(file
.getParentFile());
337 if (share
== SharabilityQuery
.NOT_SHARABLE
||
338 (share
== SharabilityQuery
.MIXED
&&
339 SharabilityQuery
.getSharability(file
) == SharabilityQuery
.NOT_SHARABLE
)) {
340 return new StatusInfo(StatusInfo
.STATUS_NOTVERSIONED_EXCLUDED
, null, false);
342 int status
= StatusInfo
.STATUS_UNKNOWN
;
343 String name
= getRelative(root
, file
);
346 index
= new IndexDiff(repo
);
348 } catch (IOException ex
) {
349 Exceptions
.printStackTrace(ex
);
350 return new StatusInfo(status
, null, false);
353 if (index
.getAdded().contains(name
)) {
354 status
= StatusInfo
.STATUS_VERSIONED_ADDEDLOCALLY
;
355 } else if (index
.getRemoved().contains(name
)) {
356 status
= StatusInfo
.STATUS_VERSIONED_REMOVEDLOCALLY
;
357 } else if (index
.getMissing().contains(name
)) {
358 status
= StatusInfo
.STATUS_VERSIONED_DELETEDLOCALLY
;
359 } else if (index
.getChanged().contains(name
)) {
360 status
= StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
;
361 } else if (index
.getModified().contains(name
)) {
362 status
= StatusInfo
.STATUS_VERSIONED_MODIFIEDLOCALLY
;
364 status
= StatusInfo
.STATUS_VERSIONED_UPTODATE
;
366 StatusInfo info
= new StatusInfo(status
, null, false);