comparison src/org/tmatesoft/hg/core/HgChangeset.java @ 129:645829962785

core.Cset renamed to HgChangeset; repo.Changeset moved into HgChangelog
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 16 Feb 2011 20:32:29 +0100
parents src/org/tmatesoft/hg/core/Cset.java@26ad21b250e4
children aa1629f36482
comparison
equal deleted inserted replaced
128:44b97930570c 129:645829962785
1 /*
2 * Copyright (c) 2011 TMate Software Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * For information on how to redistribute this software under
14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com
16 */
17 package org.tmatesoft.hg.core;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.tmatesoft.hg.core.LogCommand.FileRevision;
24 import org.tmatesoft.hg.repo.HgChangelog.Changeset;
25 import org.tmatesoft.hg.repo.HgRepository;
26 import org.tmatesoft.hg.repo.HgStatusCollector;
27 import org.tmatesoft.hg.util.PathPool;
28
29
30 /**
31 * TODO rename to Changeset along with original Changeset moved to .repo and renamed to HgChangeset?
32 * Not thread-safe, don't try to read from different threads
33 *
34 * @author Artem Tikhomirov
35 * @author TMate Software Ltd.
36 */
37 public class HgChangeset implements Cloneable {
38 private final HgStatusCollector statusHelper;
39 private final PathPool pathHelper;
40
41 //
42 private Changeset changeset;
43 private Nodeid nodeid;
44
45 //
46 private List<FileRevision> modifiedFiles, addedFiles;
47 private List<Path> deletedFiles;
48 private int revNumber;
49
50 // XXX consider CommandContext with StatusCollector, PathPool etc. Commands optionally get CC through a cons or create new
51 // and pass it around
52 /*package-local*/HgChangeset(HgStatusCollector statusCollector, PathPool pathPool) {
53 statusHelper = statusCollector;
54 pathHelper = pathPool;
55 }
56
57 /*package-local*/
58 void init(int localRevNumber, Nodeid nid, Changeset rawChangeset) {
59 revNumber = localRevNumber;
60 nodeid = nid;
61 changeset = rawChangeset;
62 modifiedFiles = addedFiles = null;
63 deletedFiles = null;
64 }
65 public int getRevision() {
66 return revNumber;
67 }
68 public Nodeid getNodeid() {
69 return nodeid;
70 }
71 public String getUser() {
72 return changeset.user();
73 }
74 public String getComment() {
75 return changeset.comment();
76 }
77 public String getBranch() {
78 return changeset.branch();
79 }
80 public String getDate() {
81 return changeset.dateString();
82 }
83 public Nodeid getManifestRevision() {
84 return changeset.manifest();
85 }
86
87 public List<Path> getAffectedFiles() {
88 // reports files as recorded in changelog. Note, merge revisions may have no
89 // files listed, and thus this method would return empty list, while
90 // #getModifiedFiles() would return list with merged file(s) (because it uses status to get 'em, not
91 // what #files() gives).
92 ArrayList<Path> rv = new ArrayList<Path>(changeset.files().size());
93 for (String name : changeset.files()) {
94 rv.add(pathHelper.path(name));
95 }
96 return rv;
97 }
98
99 public List<FileRevision> getModifiedFiles() {
100 if (modifiedFiles == null) {
101 initFileChanges();
102 }
103 return modifiedFiles;
104 }
105
106 public List<FileRevision> getAddedFiles() {
107 if (addedFiles == null) {
108 initFileChanges();
109 }
110 return addedFiles;
111 }
112
113 public List<Path> getRemovedFiles() {
114 if (deletedFiles == null) {
115 initFileChanges();
116 }
117 return deletedFiles;
118 }
119
120 public boolean isMerge() {
121 return !Nodeid.NULL.equals(getSecondParentRevision());
122 }
123
124 public Nodeid getFirstParentRevision() {
125 // XXX may read once for both p1 and p2
126 // or use ParentWalker to minimize reads even more.
127 byte[] p1 = new byte[20];
128 statusHelper.getRepo().getChangelog().parents(revNumber, new int[2], p1, null);
129 return Nodeid.fromBinary(p1, 0);
130 }
131
132 public Nodeid getSecondParentRevision() {
133 byte[] p2 = new byte[20];
134 statusHelper.getRepo().getChangelog().parents(revNumber, new int[2], null, p2);
135 return Nodeid.fromBinary(p2, 0);
136 }
137
138 @Override
139 public HgChangeset clone() {
140 try {
141 HgChangeset copy = (HgChangeset) super.clone();
142 copy.changeset = changeset.clone();
143 return copy;
144 } catch (CloneNotSupportedException ex) {
145 throw new InternalError(ex.toString());
146 }
147 }
148
149 private /*synchronized*/ void initFileChanges() {
150 ArrayList<Path> deleted = new ArrayList<Path>();
151 ArrayList<FileRevision> modified = new ArrayList<FileRevision>();
152 ArrayList<FileRevision> added = new ArrayList<FileRevision>();
153 HgStatusCollector.Record r = new HgStatusCollector.Record();
154 statusHelper.change(revNumber, r);
155 final HgRepository repo = statusHelper.getRepo();
156 for (Path s : r.getModified()) {
157 Nodeid nid = r.nodeidAfterChange(s);
158 if (nid == null) {
159 throw new IllegalArgumentException();
160 }
161 modified.add(new FileRevision(repo, nid, s));
162 }
163 for (Path s : r.getAdded()) {
164 Nodeid nid = r.nodeidAfterChange(s);
165 if (nid == null) {
166 throw new IllegalArgumentException();
167 }
168 added.add(new FileRevision(repo, nid, s));
169 }
170 for (Path s : r.getRemoved()) {
171 // with Path from getRemoved, may just copy
172 deleted.add(s);
173 }
174 modified.trimToSize();
175 added.trimToSize();
176 deleted.trimToSize();
177 modifiedFiles = Collections.unmodifiableList(modified);
178 addedFiles = Collections.unmodifiableList(added);
179 deletedFiles = Collections.unmodifiableList(deleted);
180 }
181 }