comparison src/org/tmatesoft/hg/core/HgCheckoutCommand.java @ 526:2f9ed6bcefa2

Initial support for Revert command with accompanying minor refactoring
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 15 Jan 2013 17:07:19 +0100
parents 0be5be8d57e9
children 47b7bedf0569
comparison
equal deleted inserted replaced
525:0be5be8d57e9 526:2f9ed6bcefa2
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.core; 17 package org.tmatesoft.hg.core;
18 18
19 import static org.tmatesoft.hg.repo.HgRepositoryFiles.Dirstate;
20
19 import java.io.File; 21 import java.io.File;
20 import java.io.FileOutputStream; 22 import java.io.FileOutputStream;
21 import java.io.IOException; 23 import java.io.IOException;
22 import java.nio.channels.FileChannel; 24 import java.nio.channels.FileChannel;
23 25
25 import org.tmatesoft.hg.internal.Experimental; 27 import org.tmatesoft.hg.internal.Experimental;
26 import org.tmatesoft.hg.internal.Internals; 28 import org.tmatesoft.hg.internal.Internals;
27 import org.tmatesoft.hg.internal.WorkingDirFileWriter; 29 import org.tmatesoft.hg.internal.WorkingDirFileWriter;
28 import org.tmatesoft.hg.repo.HgDataFile; 30 import org.tmatesoft.hg.repo.HgDataFile;
29 import org.tmatesoft.hg.repo.HgInvalidRevisionException; 31 import org.tmatesoft.hg.repo.HgInvalidRevisionException;
30 import org.tmatesoft.hg.repo.HgInvalidStateException;
31 import org.tmatesoft.hg.repo.HgManifest; 32 import org.tmatesoft.hg.repo.HgManifest;
33 import org.tmatesoft.hg.repo.HgManifest.Flags;
32 import org.tmatesoft.hg.repo.HgRepository; 34 import org.tmatesoft.hg.repo.HgRepository;
33 import org.tmatesoft.hg.repo.HgRuntimeException; 35 import org.tmatesoft.hg.repo.HgRuntimeException;
34 import org.tmatesoft.hg.repo.HgManifest.Flags;
35 import org.tmatesoft.hg.util.CancelledException; 36 import org.tmatesoft.hg.util.CancelledException;
36 import org.tmatesoft.hg.util.Path; 37 import org.tmatesoft.hg.util.Path;
37 38
38 /** 39 /**
39 * WORK IN PROGRESS. 40 * WORK IN PROGRESS.
91 * @throws HgIOException to indicate troubles updating files in working copy 92 * @throws HgIOException to indicate troubles updating files in working copy
92 * @throws HgException 93 * @throws HgException
93 * @throws CancelledException 94 * @throws CancelledException
94 */ 95 */
95 public void execute() throws HgException, CancelledException { 96 public void execute() throws HgException, CancelledException {
96 Internals internalRepo = Internals.getInstance(repo); 97 try {
97 // remove tracked files from wd (perhaps, just forget 'Added'?) 98 Internals internalRepo = Internals.getInstance(repo);
98 // TODO 99 // FIXME remove tracked files from wd (perhaps, just forget 'Added'?)
99 final DirstateBuilder dirstateBuilder = new DirstateBuilder(internalRepo.buildFileNameEncodingHelper()); 100 // TODO
100 final Exception[] failure = new Exception[1]; 101 final DirstateBuilder dirstateBuilder = new DirstateBuilder(internalRepo);
101 HgManifest.Inspector worker = new HgManifest.Inspector() { 102 final CheckoutWorker worker = new CheckoutWorker(internalRepo);
102 103 HgManifest.Inspector insp = new HgManifest.Inspector() {
103 public boolean next(Nodeid nid, Path fname, Flags flags) { 104
104 try { 105 public boolean next(Nodeid nid, Path fname, Flags flags) {
105 HgDataFile df = repo.getFileNode(fname); 106 if (worker.next(nid, fname, flags)) {
106 int fileRevIndex = df.getRevisionIndex(nid); 107 // new dirstate based on manifest
107 // check out files based on manifest 108 dirstateBuilder.recordNormal(fname, flags, worker.getLastWrittenFileSize());
108 // FIXME links! 109 return true;
109 WorkingDirFileWriter workingDirWriter = new WorkingDirFileWriter(repo); 110 }
110 workingDirWriter.processFile(df, fileRevIndex); 111 return false;
111 // new dirstate based on manifest 112 }
112 dirstateBuilder.recordNormal(fname, flags, workingDirWriter.bytesWritten()); 113
114 public boolean end(int manifestRevision) {
115 return false;
116 }
117
118 public boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision) {
113 return true; 119 return true;
114 } catch (IOException ex) {
115 failure[0] = ex;
116 } catch (HgRuntimeException ex) {
117 failure[0] = ex;
118 } 120 }
119 return false; 121 };
122 dirstateBuilder.parents(repo.getChangelog().getRevision(revisionToCheckout), null);
123 repo.getManifest().walk(revisionToCheckout, revisionToCheckout, insp);
124 worker.checkFailed();
125 File dirstateFile = internalRepo.getRepositoryFile(Dirstate);
126 try {
127 FileChannel dirstate = new FileOutputStream(dirstateFile).getChannel();
128 dirstateBuilder.serialize(dirstate);
129 dirstate.close();
130 } catch (IOException ex) {
131 throw new HgIOException("Can't write down new directory state", ex, dirstateFile);
120 } 132 }
121 133 // FIXME write down branch file
122 public boolean end(int manifestRevision) { 134 } catch (HgRuntimeException ex) {
123 return false; 135 throw new HgLibraryFailureException(ex);
136 }
137 }
138
139 static class CheckoutWorker {
140 private final Internals hgRepo;
141 private HgException failure;
142 private int lastWrittenFileSize;
143
144 CheckoutWorker(Internals implRepo) {
145 hgRepo = implRepo;
146 }
147
148 public boolean next(Nodeid nid, Path fname, Flags flags) {
149 try {
150 HgDataFile df = hgRepo.getRepo().getFileNode(fname);
151 int fileRevIndex = df.getRevisionIndex(nid);
152 // check out files based on manifest
153 // FIXME links!
154 WorkingDirFileWriter workingDirWriter = new WorkingDirFileWriter(hgRepo);
155 workingDirWriter.processFile(df, fileRevIndex);
156 lastWrittenFileSize = workingDirWriter.bytesWritten();
157 return true;
158 } catch (IOException ex) {
159 failure = new HgIOException("Failed to write down file revision", ex, /*FIXME file*/null);
160 } catch (HgRuntimeException ex) {
161 failure = new HgLibraryFailureException(ex);
124 } 162 }
125 163 return false;
126 public boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision) { 164 }
127 return true; 165
166 public int getLastWrittenFileSize() {
167 return lastWrittenFileSize;
168 }
169
170 public void checkFailed() throws HgException {
171 if (failure != null) {
172 throw failure;
128 } 173 }
129 };
130 dirstateBuilder.parents(repo.getChangelog().getRevision(revisionToCheckout), null);
131 repo.getManifest().walk(revisionToCheckout, revisionToCheckout, worker);
132 if (failure[0] != null) {
133 if (failure[0] instanceof IOException) {
134 throw new HgIOException("Failed to write down file revision", failure[0], /*FIXME file*/null);
135 }
136 if (failure[0] instanceof HgRuntimeException) {
137 throw new HgLibraryFailureException((HgRuntimeException) failure[0]);
138 }
139 HgInvalidStateException e = new HgInvalidStateException("Unexpected exception");
140 e.initCause(failure[0]);
141 throw e;
142 } 174 }
143 File dirstateFile = internalRepo.getFileFromRepoDir("dirstate"); 175 };
144 try {
145 FileChannel dirstate = new FileOutputStream(dirstateFile).getChannel();
146 dirstateBuilder.serialize(dirstate);
147 dirstate.close();
148 } catch (IOException ex) {
149 throw new HgIOException("Can't write down new directory state", ex, dirstateFile);
150 }
151 // FIXME write down branch file
152 }
153 } 176 }