comparison src/org/tmatesoft/hg/core/HgCheckoutCommand.java @ 563:ca56a36c2eea

HgCheckoutCommand: clean parameter, discard changes in WD, test for clean checkout
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 28 Feb 2013 16:34:33 +0100
parents 47b7bedf0569
children 78a9e26e670d
comparison
equal deleted inserted replaced
562:6fbca6506bb5 563:ca56a36c2eea
29 import org.tmatesoft.hg.internal.EncodingHelper; 29 import org.tmatesoft.hg.internal.EncodingHelper;
30 import org.tmatesoft.hg.internal.Experimental; 30 import org.tmatesoft.hg.internal.Experimental;
31 import org.tmatesoft.hg.internal.Internals; 31 import org.tmatesoft.hg.internal.Internals;
32 import org.tmatesoft.hg.internal.WorkingDirFileWriter; 32 import org.tmatesoft.hg.internal.WorkingDirFileWriter;
33 import org.tmatesoft.hg.repo.HgDataFile; 33 import org.tmatesoft.hg.repo.HgDataFile;
34 import org.tmatesoft.hg.repo.HgDirstate;
35 import org.tmatesoft.hg.repo.HgInternals;
34 import org.tmatesoft.hg.repo.HgInvalidRevisionException; 36 import org.tmatesoft.hg.repo.HgInvalidRevisionException;
35 import org.tmatesoft.hg.repo.HgManifest; 37 import org.tmatesoft.hg.repo.HgManifest;
38 import org.tmatesoft.hg.repo.HgDirstate.EntryKind;
39 import org.tmatesoft.hg.repo.HgDirstate.Record;
36 import org.tmatesoft.hg.repo.HgManifest.Flags; 40 import org.tmatesoft.hg.repo.HgManifest.Flags;
37 import org.tmatesoft.hg.repo.HgRepository; 41 import org.tmatesoft.hg.repo.HgRepository;
38 import org.tmatesoft.hg.repo.HgRuntimeException; 42 import org.tmatesoft.hg.repo.HgRuntimeException;
39 import org.tmatesoft.hg.util.CancelledException; 43 import org.tmatesoft.hg.util.CancelledException;
40 import org.tmatesoft.hg.util.Path; 44 import org.tmatesoft.hg.util.Path;
52 @Experimental(reason="Work in progress") 56 @Experimental(reason="Work in progress")
53 public class HgCheckoutCommand extends HgAbstractCommand<HgCheckoutCommand>{ 57 public class HgCheckoutCommand extends HgAbstractCommand<HgCheckoutCommand>{
54 58
55 private final HgRepository repo; 59 private final HgRepository repo;
56 private int revisionToCheckout = HgRepository.BAD_REVISION; 60 private int revisionToCheckout = HgRepository.BAD_REVISION;
61 private boolean cleanCheckout;
57 62
58 public HgCheckoutCommand(HgRepository hgRepo) { 63 public HgCheckoutCommand(HgRepository hgRepo) {
59 repo = hgRepo; 64 repo = hgRepo;
65 }
66
67 /**
68 * Whether to discard all uncommited changes prior to check-out.
69 *
70 * NOTE, at the moment, only clean checkout is supported!
71 *
72 * @param clean <code>true</code> to discard any change
73 * @return <code>this</code> for convenience
74 */
75 public HgCheckoutCommand clean(boolean clean) {
76 cleanCheckout = clean;
77 return this;
60 } 78 }
61 79
62 /** 80 /**
63 * Select revision to check out 81 * Select revision to check out
64 * 82 *
75 } 93 }
76 94
77 /** 95 /**
78 * Select revision to check out using local revision index 96 * Select revision to check out using local revision index
79 * 97 *
80 * @param changesetIndex local revision index 98 * @param changesetIndex local revision index, or {@link HgRepository#TIP}
81 * @return <code>this</code> for convenience 99 * @return <code>this</code> for convenience
82 * @throws HgBadArgumentException if failed to find supplied changeset 100 * @throws HgBadArgumentException if failed to find supplied changeset
83 */ 101 */
84 public HgCheckoutCommand changeset(int changesetIndex) throws HgBadArgumentException { 102 public HgCheckoutCommand changeset(int changesetIndex) throws HgBadArgumentException {
85 int lastCsetIndex = repo.getChangelog().getLastRevision(); 103 int lastCsetIndex = repo.getChangelog().getLastRevision();
104 if (changesetIndex == HgRepository.TIP) {
105 changesetIndex = lastCsetIndex;
106 }
86 if (changesetIndex < 0 || changesetIndex > lastCsetIndex) { 107 if (changesetIndex < 0 || changesetIndex > lastCsetIndex) {
87 throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetIndex, lastCsetIndex), null).setRevisionIndex(changesetIndex); 108 throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetIndex, lastCsetIndex), null).setRevisionIndex(changesetIndex);
88 } 109 }
89 revisionToCheckout = changesetIndex; 110 revisionToCheckout = changesetIndex;
90 return this; 111 return this;
97 * @throws CancelledException 118 * @throws CancelledException
98 */ 119 */
99 public void execute() throws HgException, CancelledException { 120 public void execute() throws HgException, CancelledException {
100 try { 121 try {
101 Internals internalRepo = Internals.getInstance(repo); 122 Internals internalRepo = Internals.getInstance(repo);
102 // FIXME remove tracked files from wd (perhaps, just forget 'Added'?) 123 if (cleanCheckout) {
103 // TODO 124 // remove tracked files from wd (perhaps, just forget 'Added'?)
125 // for now, just delete each and every tracked file
126 // TODO WorkingCopy container with getFile(HgDataFile/Path) to access files in WD
127 HgDirstate dirstate = new HgInternals(repo).getDirstate();
128 dirstate.walk(new HgDirstate.Inspector() {
129
130 public boolean next(EntryKind kind, Record entry) {
131 File f = new File(repo.getWorkingDir(), entry.name().toString());
132 if (f.exists()) {
133 f.delete();
134 }
135 return true;
136 }
137 });
138 } else {
139 throw new HgBadArgumentException("Sorry, only clean checkout is supported now, use #clean(true)", null);
140 }
104 final DirstateBuilder dirstateBuilder = new DirstateBuilder(internalRepo); 141 final DirstateBuilder dirstateBuilder = new DirstateBuilder(internalRepo);
105 final CheckoutWorker worker = new CheckoutWorker(internalRepo); 142 final CheckoutWorker worker = new CheckoutWorker(internalRepo);
106 HgManifest.Inspector insp = new HgManifest.Inspector() { 143 HgManifest.Inspector insp = new HgManifest.Inspector() {
107 144
108 public boolean next(Nodeid nid, Path fname, Flags flags) { 145 public boolean next(Nodeid nid, Path fname, Flags flags) {
125 dirstateBuilder.parents(repo.getChangelog().getRevision(revisionToCheckout), null); 162 dirstateBuilder.parents(repo.getChangelog().getRevision(revisionToCheckout), null);
126 repo.getManifest().walk(revisionToCheckout, revisionToCheckout, insp); 163 repo.getManifest().walk(revisionToCheckout, revisionToCheckout, insp);
127 worker.checkFailed(); 164 worker.checkFailed();
128 File dirstateFile = internalRepo.getRepositoryFile(Dirstate); 165 File dirstateFile = internalRepo.getRepositoryFile(Dirstate);
129 try { 166 try {
130 FileChannel dirstate = new FileOutputStream(dirstateFile).getChannel(); 167 FileChannel dirstateFileChannel = new FileOutputStream(dirstateFile).getChannel();
131 dirstateBuilder.serialize(dirstate); 168 dirstateBuilder.serialize(dirstateFileChannel);
132 dirstate.close(); 169 dirstateFileChannel.close();
133 } catch (IOException ex) { 170 } catch (IOException ex) {
134 throw new HgIOException("Can't write down new directory state", ex, dirstateFile); 171 throw new HgIOException("Can't write down new directory state", ex, dirstateFile);
135 } 172 }
136 String branchName = repo.getChangelog().range(revisionToCheckout, revisionToCheckout).get(0).branch(); 173 String branchName = repo.getChangelog().range(revisionToCheckout, revisionToCheckout).get(0).branch();
137 assert branchName != null; 174 assert branchName != null;