comparison src/com/tmate/hgkit/ll/Changeset.java @ 47:b01500fe2604

Log command output to match 'hg log'
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 14 Jan 2011 20:03:14 +0100
parents 21e26da142fa
children 26e3eeaa3962
comparison
equal deleted inserted replaced
46:4022c34a4804 47:b01500fe2604
3 */ 3 */
4 package com.tmate.hgkit.ll; 4 package com.tmate.hgkit.ll;
5 5
6 import java.io.UnsupportedEncodingException; 6 import java.io.UnsupportedEncodingException;
7 import java.util.ArrayList; 7 import java.util.ArrayList;
8 import java.util.Collections;
8 import java.util.Date; 9 import java.util.Date;
10 import java.util.Formatter;
11 import java.util.List;
9 import java.util.Locale; 12 import java.util.Locale;
13 import java.util.Map;
10 14
11 /** 15 /**
12 * @see mercurial/changelog.py:read() 16 * @see mercurial/changelog.py:read()
13 * <pre> 17 * <pre>
14 format used: 18 format used:
22 26
23 changelog v0 doesn't use extra 27 changelog v0 doesn't use extra
24 * </pre> 28 * </pre>
25 * @author artem 29 * @author artem
26 */ 30 */
27 public class Changeset { 31 public class Changeset implements Cloneable /*for those that would like to keep a copy*/ {
28 // TODO immutable 32 // TODO immutable
29 private /*final*/ Nodeid manifest; 33 private /*final*/ Nodeid manifest;
30 private String user; 34 private String user;
31 private String comment; 35 private String comment;
32 private ArrayList<String> files; 36 private List<String> files; // unmodifiable collection (otherwise #files() and implicit #clone() shall be revised)
33 private Date time; 37 private Date time;
38 private int timezone; // not sure it's of any use
34 private String extras; // TODO branch, etc. 39 private String extras; // TODO branch, etc.
35 40
36 public void dump() { 41 private Changeset() {
37 System.out.println("User: " + user); 42 }
38 System.out.println("Comment: " + comment); 43
39 System.out.println("Manifest: " + manifest); 44 public Nodeid manifest() {
40 System.out.printf(Locale.US, "Date: %ta %<tb %<td %<tH:%<tM:%<tS %<tY %<tz\n", time); 45 return manifest;
41 System.out.println("Files: " + files.size()); 46 }
47
48 public String user() {
49 return user;
50 }
51
52 public String comment() {
53 return comment;
54 }
55
56 public List<String> files() {
57 return files;
58 }
59
60 public Date date() {
61 return time;
62 }
63
64 public String dateString() {
65 StringBuilder sb = new StringBuilder(30);
66 Formatter f = new Formatter(sb, Locale.US);
67 f.format("%ta %<tb %<td %<tH:%<tM:%<tS %<tY %<tz", time);
68 return sb.toString();
69 }
70
71 public Map<String, String> extras() {
72 return null; // TODO
73 }
74
75 @Override
76 public String toString() {
77 StringBuilder sb = new StringBuilder();
78 sb.append("Changeset {");
79 sb.append("User: ").append(user).append(", ");
80 sb.append("Comment: ").append(comment).append(", ");
81 sb.append("Manifest: ").append(manifest).append(", ");
82 sb.append("Date: ").append(time).append(", ");
83 sb.append("Files: ").append(files.size());
84 for (String s : files) {
85 sb.append(", ").append(s);
86 }
42 if (extras != null) { 87 if (extras != null) {
43 System.out.println("Extra: " + extras); 88 sb.append(", Extra: ").append(extras);
44 } 89 }
45 for (String s : files) { 90 sb.append("}");
46 System.out.print('\t'); 91 return sb.toString();
47 System.out.println(s);
48 }
49 } 92 }
50 93
51 public static Changeset parse(byte[] data, int offset, int length) { 94 public static Changeset parse(byte[] data, int offset, int length) {
52 Changeset rv = new Changeset(); 95 Changeset rv = new Changeset();
53 rv.init(data, offset, length); 96 rv.init(data, offset, length);
79 int space2 = _timeString.indexOf(' ', space1+1); 122 int space2 = _timeString.indexOf(' ', space1+1);
80 if (space2 == -1) { 123 if (space2 == -1) {
81 space2 = _timeString.length(); 124 space2 = _timeString.length();
82 } 125 }
83 long unixTime = Long.parseLong(_timeString.substring(0, space1)); // XXX Float, perhaps 126 long unixTime = Long.parseLong(_timeString.substring(0, space1)); // XXX Float, perhaps
84 int timezone = Integer.parseInt(_timeString.substring(space1+1, space2)); 127 int _timezone = Integer.parseInt(_timeString.substring(space1+1, space2));
85 // XXX not sure need to add timezone here - I can't figure out whether Hg keeps GMT time, and records timezone just for info, or unixTime is taken local 128 // XXX not sure need to add timezone here - I can't figure out whether Hg keeps GMT time, and records timezone just for info, or unixTime is taken local
86 // on commit and timezone is recorded to adjust it to UTC. 129 // on commit and timezone is recorded to adjust it to UTC.
87 Date _time = new Date((unixTime + timezone) * 1000); 130 Date _time = new Date(unixTime * 1000);
88 String _extras = space2 < _timeString.length() ? _timeString.substring(space2+1) : null; 131 String _extras = space2 < _timeString.length() ? _timeString.substring(space2+1) : null;
89 132
90 // 133 //
91 int lastStart = breakIndex3 + 1; 134 int lastStart = breakIndex3 + 1;
92 int breakIndex4 = indexOf(data, lineBreak, lastStart, bufferEndIndex); 135 int breakIndex4 = indexOf(data, lineBreak, lastStart, bufferEndIndex);
113 } 156 }
114 // change this instance at once, don't leave it partially changes in case of error 157 // change this instance at once, don't leave it partially changes in case of error
115 this.manifest = _nodeid; 158 this.manifest = _nodeid;
116 this.user = _user; 159 this.user = _user;
117 this.time = _time; 160 this.time = _time;
118 this.files = _files; 161 this.timezone = _timezone;
162 this.files = Collections.unmodifiableList(_files);
119 this.comment = _comment; 163 this.comment = _comment;
120 this.extras = _extras; 164 this.extras = _extras;
121 } 165 }
122 166
123 private static int indexOf(byte[] src, byte what, int startOffset, int endIndex) { 167 private static int indexOf(byte[] src, byte what, int startOffset, int endIndex) {
130 } 174 }
131 175
132 public interface Inspector { 176 public interface Inspector {
133 // first(), last(), single(). 177 // first(), last(), single().
134 // <T> 178 // <T>
135 void next(Changeset cset); 179 // TODO describe whether cset is new instance each time
180 void next(int revisionNumber, Nodeid nodeid, Changeset cset);
136 } 181 }
137 } 182 }