comparison src/org/tmatesoft/hg/core/HgCommitCommand.java @ 617:65c01508f002

Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 15 May 2013 20:10:09 +0200
parents e447384f3771
children 7c0d2ce340b8
comparison
equal deleted inserted replaced
616:5e0313485eef 617:65c01508f002
21 import java.io.IOException; 21 import java.io.IOException;
22 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
23 import java.util.ArrayList; 23 import java.util.ArrayList;
24 24
25 import org.tmatesoft.hg.internal.ByteArrayChannel; 25 import org.tmatesoft.hg.internal.ByteArrayChannel;
26 import org.tmatesoft.hg.internal.COWTransaction;
26 import org.tmatesoft.hg.internal.CommitFacility; 27 import org.tmatesoft.hg.internal.CommitFacility;
28 import org.tmatesoft.hg.internal.CompleteRepoLock;
27 import org.tmatesoft.hg.internal.Experimental; 29 import org.tmatesoft.hg.internal.Experimental;
28 import org.tmatesoft.hg.internal.FileContentSupplier; 30 import org.tmatesoft.hg.internal.FileContentSupplier;
29 import org.tmatesoft.hg.internal.Internals; 31 import org.tmatesoft.hg.internal.Internals;
32 import org.tmatesoft.hg.internal.Transaction;
30 import org.tmatesoft.hg.repo.HgChangelog; 33 import org.tmatesoft.hg.repo.HgChangelog;
31 import org.tmatesoft.hg.repo.HgDataFile; 34 import org.tmatesoft.hg.repo.HgDataFile;
32 import org.tmatesoft.hg.repo.HgInternals; 35 import org.tmatesoft.hg.repo.HgInternals;
33 import org.tmatesoft.hg.repo.HgRepository; 36 import org.tmatesoft.hg.repo.HgRepository;
34 import org.tmatesoft.hg.repo.HgRuntimeException; 37 import org.tmatesoft.hg.repo.HgRuntimeException;
84 return parents[0] != NO_REVISION && parents[1] != NO_REVISION; 87 return parents[0] != NO_REVISION && parents[1] != NO_REVISION;
85 } 88 }
86 89
87 /** 90 /**
88 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state 91 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state
92 * @throws HgRepositoryLockException if failed to lock the repo for modifications
89 * @throws IOException propagated IO errors from status walker over working directory 93 * @throws IOException propagated IO errors from status walker over working directory
90 * @throws CancelledException if execution of the command was cancelled 94 * @throws CancelledException if execution of the command was cancelled
91 */ 95 */
92 public Outcome execute() throws HgException, IOException, CancelledException { 96 public Outcome execute() throws HgException, IOException, CancelledException {
93 if (message == null) { 97 if (message == null) {
94 throw new HgBadArgumentException("Shall supply commit message", null); 98 throw new HgBadArgumentException("Shall supply commit message", null);
95 } 99 }
100 final CompleteRepoLock repoLock = new CompleteRepoLock(repo);
101 repoLock.acquire();
96 try { 102 try {
97 int[] parentRevs = new int[2]; 103 int[] parentRevs = new int[2];
98 detectParentFromDirstate(parentRevs); 104 detectParentFromDirstate(parentRevs);
99 if (parentRevs[0] != NO_REVISION && parentRevs[1] != NO_REVISION) { 105 if (parentRevs[0] != NO_REVISION && parentRevs[1] != NO_REVISION) {
100 throw new HgBadArgumentException("Sorry, I'm not yet smart enough to perform merge commits", null); 106 throw new HgBadArgumentException("Sorry, I'm not yet smart enough to perform merge commits", null);
125 HgDataFile df = repo.getFileNode(r); 131 HgDataFile df = repo.getFileNode(r);
126 cf.forget(df); 132 cf.forget(df);
127 } 133 }
128 cf.branch(detectBranch()); 134 cf.branch(detectBranch());
129 cf.user(detectUser()); 135 cf.user(detectUser());
130 newRevision = cf.commit(message); 136 Transaction.Factory trFactory = new COWTransaction.Factory();
137 Transaction tr = trFactory.create(repo);
138 try {
139 newRevision = cf.commit(message, tr);
140 tr.commit();
141 } catch (RuntimeException ex) {
142 tr.rollback();
143 throw ex;
144 } catch (HgException ex) {
145 tr.rollback();
146 throw ex;
147 }
131 // TODO toClear list is awful 148 // TODO toClear list is awful
132 for (FileContentSupplier fcs : toClear) { 149 for (FileContentSupplier fcs : toClear) {
133 fcs.done(); 150 fcs.done();
134 } 151 }
135 return new Outcome(Kind.Success, "Commit ok"); 152 return new Outcome(Kind.Success, "Commit ok");
136 } catch (HgRuntimeException ex) { 153 } catch (HgRuntimeException ex) {
137 throw new HgLibraryFailureException(ex); 154 throw new HgLibraryFailureException(ex);
155 } finally {
156 repoLock.release();
138 } 157 }
139 } 158 }
140 159
141 public Nodeid getCommittedRevision() { 160 public Nodeid getCommittedRevision() {
142 if (newRevision == null) { 161 if (newRevision == null) {