Mercurial > jhg
comparison src/com/tmate/hgkit/console/Log.java @ 65:e21df6259f83
Log commandline sample updated to use LogCommand
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Fri, 21 Jan 2011 06:17:56 +0100 | 
| parents | 613c936d74e4 | 
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 64:19e9e220bf68 | 65:e21df6259f83 | 
|---|---|
| 2 * Copyright (c) 2010, 2011 Artem Tikhomirov | 2 * Copyright (c) 2010, 2011 Artem Tikhomirov | 
| 3 */ | 3 */ | 
| 4 package com.tmate.hgkit.console; | 4 package com.tmate.hgkit.console; | 
| 5 | 5 | 
| 6 import java.util.Formatter; | 6 import java.util.Formatter; | 
| 7 import java.util.LinkedHashSet; | |
| 8 import java.util.LinkedList; | 7 import java.util.LinkedList; | 
| 9 import java.util.List; | 8 import java.util.List; | 
| 10 import java.util.Map; | 9 | 
| 11 import java.util.Set; | 10 import org.tmatesoft.hg.core.Cset; | 
| 11 import org.tmatesoft.hg.core.LogCommand; | |
| 12 import org.tmatesoft.hg.core.LogCommand.FileRevision; | |
| 13 import org.tmatesoft.hg.core.Path; | |
| 12 | 14 | 
| 13 import com.tmate.hgkit.fs.RepositoryLookup; | 15 import com.tmate.hgkit.fs.RepositoryLookup; | 
| 14 import com.tmate.hgkit.ll.Changeset; | |
| 15 import com.tmate.hgkit.ll.HgDataFile; | 16 import com.tmate.hgkit.ll.HgDataFile; | 
| 16 import com.tmate.hgkit.ll.HgRepository; | 17 import com.tmate.hgkit.ll.HgRepository; | 
| 17 import com.tmate.hgkit.ll.Nodeid; | 18 import com.tmate.hgkit.ll.Nodeid; | 
| 18 import com.tmate.hgkit.ll.Revlog; | 19 import com.tmate.hgkit.ll.Revlog; | 
| 19 import com.tmate.hgkit.ll.StatusCollector; | |
| 20 | 20 | 
| 21 /** | 21 /** | 
| 22 * @author artem | 22 * @author artem | 
| 23 */ | 23 */ | 
| 24 public class Log { | 24 public class Log { | 
| 34 System.out.println(hgRepo.getLocation()); | 34 System.out.println(hgRepo.getLocation()); | 
| 35 final Dump dump = new Dump(hgRepo); | 35 final Dump dump = new Dump(hgRepo); | 
| 36 dump.complete = true; //cmdLineOpts; | 36 dump.complete = true; //cmdLineOpts; | 
| 37 dump.verbose = false; //cmdLineOpts; | 37 dump.verbose = false; //cmdLineOpts; | 
| 38 dump.reverseOrder = true; | 38 dump.reverseOrder = true; | 
| 39 dump.branches = cmdLineOpts.branches; | 39 LogCommand cmd = new LogCommand(hgRepo); | 
| 40 if (cmdLineOpts.users != null) { | 40 if (cmdLineOpts.users != null) { | 
| 41 dump.users = new LinkedHashSet<String>(); | |
| 42 for (String u : cmdLineOpts.users) { | 41 for (String u : cmdLineOpts.users) { | 
| 43 dump.users.add(u.toLowerCase()); | 42 cmd.user(u); | 
| 44 } | 43 } | 
| 44 } | |
| 45 if (cmdLineOpts.branches != null) { | |
| 46 for (String b : cmdLineOpts.branches) { | |
| 47 cmd.branch(b); | |
| 48 } | |
| 49 } | |
| 50 if (cmdLineOpts.limit != -1) { | |
| 51 cmd.limit(cmdLineOpts.limit); | |
| 52 | |
| 45 } | 53 } | 
| 46 if (cmdLineOpts.files.isEmpty()) { | 54 if (cmdLineOpts.files.isEmpty()) { | 
| 47 if (cmdLineOpts.limit == -1) { | 55 if (cmdLineOpts.limit == -1) { | 
| 48 // no revisions and no limit | 56 // no revisions and no limit | 
| 49 hgRepo.getChangelog().all(dump); | 57 cmd.execute(dump); | 
| 50 } else { | 58 } else { | 
| 51 // in fact, external (to dump inspector) --limit processing yelds incorrect results when other args | 59 // in fact, external (to dump inspector) --limit processing yelds incorrect results when other args | 
| 52 // e.g. -u or -b are used (i.e. with -u shall give <limit> csets with user, not check last <limit> csets for user | 60 // e.g. -u or -b are used (i.e. with -u shall give <limit> csets with user, not check last <limit> csets for user | 
| 53 int[] r = new int[] { 0, hgRepo.getChangelog().getRevisionCount() }; | 61 int[] r = new int[] { 0, hgRepo.getChangelog().getRevisionCount() }; | 
| 54 if (fixRange(r, dump.reverseOrder, cmdLineOpts.limit) == 0) { | 62 if (fixRange(r, dump.reverseOrder, cmdLineOpts.limit) == 0) { | 
| 55 System.out.println("No changes"); | 63 System.out.println("No changes"); | 
| 56 return; | 64 return; | 
| 57 } | 65 } | 
| 58 hgRepo.getChangelog().range(r[0], r[1], dump); | 66 cmd.range(r[0], r[1]).execute(dump); | 
| 59 } | 67 } | 
| 60 dump.complete(); | 68 dump.complete(); | 
| 61 } else { | 69 } else { | 
| 62 for (String fname : cmdLineOpts.files) { | 70 for (String fname : cmdLineOpts.files) { | 
| 63 HgDataFile f1 = hgRepo.getFileNode(fname); | 71 HgDataFile f1 = hgRepo.getFileNode(fname); | 
| 64 System.out.println("History of the file: " + f1.getPath()); | 72 System.out.println("History of the file: " + f1.getPath()); | 
| 65 if (cmdLineOpts.limit == -1) { | 73 if (cmdLineOpts.limit == -1) { | 
| 66 f1.history(dump); | 74 cmd.file(Path.create(fname)).execute(dump); | 
| 67 } else { | 75 } else { | 
| 68 int[] r = new int[] { 0, f1.getRevisionCount() }; | 76 int[] r = new int[] { 0, f1.getRevisionCount() }; | 
| 69 if (fixRange(r, dump.reverseOrder, cmdLineOpts.limit) == 0) { | 77 if (fixRange(r, dump.reverseOrder, cmdLineOpts.limit) == 0) { | 
| 70 System.out.println("No changes"); | 78 System.out.println("No changes"); | 
| 71 continue; | 79 continue; | 
| 72 } | 80 } | 
| 73 f1.history(r[0], r[1], dump); | 81 cmd.range(r[0], r[1]).file(Path.create(fname)).execute(dump); | 
| 74 } | 82 } | 
| 75 dump.complete(); | 83 dump.complete(); | 
| 76 } | 84 } | 
| 77 } | 85 } | 
| 78 // | 86 // | 
| 92 int rv = start_end[1] - start_end[0]; | 100 int rv = start_end[1] - start_end[0]; | 
| 93 start_end[1]--; // range needs index, not length | 101 start_end[1]--; // range needs index, not length | 
| 94 return rv; | 102 return rv; | 
| 95 } | 103 } | 
| 96 | 104 | 
| 97 // Differences with standard hg log output | 105 private static final class Dump implements LogCommand.Handler { | 
| 98 // - complete == true (--debug) files are not broke down to modified,+ and - | |
| 99 private static final class Dump implements Changeset.Inspector { | |
| 100 // params | 106 // params | 
| 101 boolean complete = false; // roughly --debug | 107 boolean complete = false; // roughly --debug | 
| 102 boolean reverseOrder = false; | 108 boolean reverseOrder = false; | 
| 103 Set<String> branches; | |
| 104 Set<String> users; // shall be lowercased | |
| 105 boolean verbose = true; // roughly -v | 109 boolean verbose = true; // roughly -v | 
| 106 // own | 110 // own | 
| 107 private LinkedList<String> l = new LinkedList<String>(); | 111 private LinkedList<String> l = new LinkedList<String>(); | 
| 108 private final HgRepository repo; | 112 private final HgRepository repo; | 
| 109 private Revlog.ParentWalker changelogWalker; | 113 private Revlog.ParentWalker changelogWalker; | 
| 110 private final int tip ; | 114 private final int tip ; | 
| 111 private StatusCollector statusHelper; | |
| 112 | 115 | 
| 113 public Dump(HgRepository hgRepo) { | 116 public Dump(HgRepository hgRepo) { | 
| 114 repo = hgRepo; | 117 repo = hgRepo; | 
| 115 tip = hgRepo.getChangelog().getRevisionCount() - 1; | 118 tip = hgRepo.getChangelog().getRevisionCount() - 1; | 
| 116 } | 119 } | 
| 117 | 120 | 
| 118 public void next(int revisionNumber, Nodeid nodeid, Changeset cset) { | 121 public void next(Cset changeset) { | 
| 119 if (branches != null && !branches.contains(cset.branch())) { | 122 final String s = print(changeset); | 
| 120 return; | |
| 121 } | |
| 122 if (users != null) { | |
| 123 String csetUser = cset.user().toLowerCase(); | |
| 124 boolean found = false; | |
| 125 for (String u : users) { | |
| 126 if (csetUser.indexOf(u) != -1) { | |
| 127 found = true; | |
| 128 break; | |
| 129 } | |
| 130 } | |
| 131 if (!found) { | |
| 132 return; | |
| 133 } | |
| 134 } | |
| 135 final String s = print(revisionNumber, nodeid, cset); | |
| 136 if (reverseOrder) { | 123 if (reverseOrder) { | 
| 137 l.addFirst(s); | 124 l.addFirst(s); | 
| 138 } else { | 125 } else { | 
| 139 System.out.print(s); | 126 System.out.print(s); | 
| 140 } | 127 } | 
| 149 } | 136 } | 
| 150 l.clear(); | 137 l.clear(); | 
| 151 changelogWalker = null; | 138 changelogWalker = null; | 
| 152 } | 139 } | 
| 153 | 140 | 
| 154 private String print(int revNumber, Nodeid csetNodeid, Changeset cset) { | 141 private String print(Cset cset) { | 
| 155 StringBuilder sb = new StringBuilder(); | 142 StringBuilder sb = new StringBuilder(); | 
| 156 Formatter f = new Formatter(sb); | 143 Formatter f = new Formatter(sb); | 
| 157 f.format("changeset: %d:%s\n", revNumber, complete ? csetNodeid : csetNodeid.shortNotation()); | 144 final Nodeid csetNodeid = cset.getNodeid(); | 
| 158 if (revNumber == tip || repo.getTags().isTagged(csetNodeid)) { | 145 f.format("changeset: %d:%s\n", cset.getRevision(), complete ? csetNodeid : csetNodeid.shortNotation()); | 
| 146 if (cset.getRevision() == tip || repo.getTags().isTagged(csetNodeid)) { | |
| 159 | 147 | 
| 160 sb.append("tag: "); | 148 sb.append("tag: "); | 
| 161 for (String t : repo.getTags().tags(csetNodeid)) { | 149 for (String t : repo.getTags().tags(csetNodeid)) { | 
| 162 sb.append(t); | 150 sb.append(t); | 
| 163 sb.append(' '); | 151 sb.append(' '); | 
| 164 } | 152 } | 
| 165 if (revNumber == tip) { | 153 if (cset.getRevision() == tip) { | 
| 166 sb.append("tip"); | 154 sb.append("tip"); | 
| 167 } | 155 } | 
| 168 sb.append('\n'); | 156 sb.append('\n'); | 
| 169 } | 157 } | 
| 170 if (complete) { | 158 if (complete) { | 
| 174 } | 162 } | 
| 175 Nodeid p1 = changelogWalker.safeFirstParent(csetNodeid); | 163 Nodeid p1 = changelogWalker.safeFirstParent(csetNodeid); | 
| 176 Nodeid p2 = changelogWalker.safeSecondParent(csetNodeid); | 164 Nodeid p2 = changelogWalker.safeSecondParent(csetNodeid); | 
| 177 int p1x = p1 == Nodeid.NULL ? -1 : repo.getChangelog().getLocalRevisionNumber(p1); | 165 int p1x = p1 == Nodeid.NULL ? -1 : repo.getChangelog().getLocalRevisionNumber(p1); | 
| 178 int p2x = p2 == Nodeid.NULL ? -1 : repo.getChangelog().getLocalRevisionNumber(p2); | 166 int p2x = p2 == Nodeid.NULL ? -1 : repo.getChangelog().getLocalRevisionNumber(p2); | 
| 179 int mx = repo.getManifest().getLocalRevisionNumber(cset.manifest()); | 167 int mx = repo.getManifest().getLocalRevisionNumber(cset.getManifestRevision()); | 
| 180 f.format("parent: %d:%s\nparent: %d:%s\nmanifest: %d:%s\n", p1x, p1, p2x, p2, mx, cset.manifest()); | 168 f.format("parent: %d:%s\nparent: %d:%s\nmanifest: %d:%s\n", p1x, p1, p2x, p2, mx, cset.getManifestRevision()); | 
| 181 } | 169 } | 
| 182 f.format("user: %s\ndate: %s\n", cset.user(), cset.dateString()); | 170 f.format("user: %s\ndate: %s\n", cset.getUser(), cset.getDate()); | 
| 183 if (!complete && verbose) { | 171 if (!complete && verbose) { | 
| 184 final List<String> files = cset.files(); | 172 final List<Path> files = cset.getAffectedFiles(); | 
| 185 sb.append("files: "); | 173 sb.append("files: "); | 
| 186 for (String s : files) { | 174 for (Path s : files) { | 
| 187 sb.append(' '); | 175 sb.append(' '); | 
| 188 sb.append(s); | 176 sb.append(s); | 
| 189 } | 177 } | 
| 190 sb.append('\n'); | 178 sb.append('\n'); | 
| 191 } | 179 } | 
| 192 if (complete) { | 180 if (complete) { | 
| 193 if (statusHelper == null) { | 181 if (!cset.getModifiedFiles().isEmpty()) { | 
| 194 statusHelper = new StatusCollector(repo); | |
| 195 } | |
| 196 StatusCollector.Record r = new StatusCollector.Record(); | |
| 197 statusHelper.change(revNumber, r); | |
| 198 if (!r.getModified().isEmpty()) { | |
| 199 sb.append("files: "); | 182 sb.append("files: "); | 
| 200 for (String s : r.getModified()) { | 183 for (FileRevision s : cset.getModifiedFiles()) { | 
| 184 sb.append(' '); | |
| 185 sb.append(s.getPath()); | |
| 186 } | |
| 187 sb.append('\n'); | |
| 188 } | |
| 189 if (!cset.getAddedFiles().isEmpty()) { | |
| 190 sb.append("files+: "); | |
| 191 for (FileRevision s : cset.getAddedFiles()) { | |
| 192 sb.append(' '); | |
| 193 sb.append(s.getPath()); | |
| 194 } | |
| 195 sb.append('\n'); | |
| 196 } | |
| 197 if (!cset.getRemovedFiles().isEmpty()) { | |
| 198 sb.append("files-: "); | |
| 199 for (Path s : cset.getRemovedFiles()) { | |
| 201 sb.append(' '); | 200 sb.append(' '); | 
| 202 sb.append(s); | 201 sb.append(s); | 
| 203 } | 202 } | 
| 204 sb.append('\n'); | 203 sb.append('\n'); | 
| 205 } | 204 } | 
| 206 if (!r.getAdded().isEmpty()) { | 205 // if (cset.extras() != null) { | 
| 207 sb.append("files+: "); | 206 // sb.append("extra: "); | 
| 208 for (String s : r.getAdded()) { | 207 // for (Map.Entry<String, String> e : cset.extras().entrySet()) { | 
| 209 sb.append(' '); | 208 // sb.append(' '); | 
| 210 sb.append(s); | 209 // sb.append(e.getKey()); | 
| 211 } | 210 // sb.append('='); | 
| 212 sb.append('\n'); | 211 // sb.append(e.getValue()); | 
| 213 } | 212 // } | 
| 214 if (!r.getRemoved().isEmpty()) { | 213 // sb.append('\n'); | 
| 215 sb.append("files-: "); | 214 // } | 
| 216 for (String s : r.getRemoved()) { | |
| 217 sb.append(' '); | |
| 218 sb.append(s); | |
| 219 } | |
| 220 sb.append('\n'); | |
| 221 } | |
| 222 if (cset.extras() != null) { | |
| 223 sb.append("extra: "); | |
| 224 for (Map.Entry<String, String> e : cset.extras().entrySet()) { | |
| 225 sb.append(' '); | |
| 226 sb.append(e.getKey()); | |
| 227 sb.append('='); | |
| 228 sb.append(e.getValue()); | |
| 229 } | |
| 230 sb.append('\n'); | |
| 231 } | |
| 232 } | 215 } | 
| 233 if (complete || verbose) { | 216 if (complete || verbose) { | 
| 234 f.format("description:\n%s\n\n", cset.comment()); | 217 f.format("description:\n%s\n\n", cset.getComment()); | 
| 235 } else { | 218 } else { | 
| 236 f.format("summary: %s\n\n", cset.comment()); | 219 f.format("summary: %s\n\n", cset.getComment()); | 
| 237 } | 220 } | 
| 238 return sb.toString(); | 221 return sb.toString(); | 
| 239 } | 222 } | 
| 240 } | 223 } | 
| 241 } | 224 } | 
