Mercurial > jhg
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) { |