Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/CommitFacility.java @ 559:6ca3d0c5b4bc
Commit: tests and fixes for defects discovered
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 25 Feb 2013 19:48:20 +0100 |
parents | 67d4b0f73984 |
children | ca56a36c2eea |
comparison
equal
deleted
inserted
replaced
558:154718ae23ed | 559:6ca3d0c5b4bc |
---|---|
22 import java.nio.ByteBuffer; | 22 import java.nio.ByteBuffer; |
23 import java.util.ArrayList; | 23 import java.util.ArrayList; |
24 import java.util.HashMap; | 24 import java.util.HashMap; |
25 import java.util.LinkedHashMap; | 25 import java.util.LinkedHashMap; |
26 import java.util.Map; | 26 import java.util.Map; |
27 import java.util.Set; | |
27 import java.util.TreeMap; | 28 import java.util.TreeMap; |
29 import java.util.TreeSet; | |
28 | 30 |
29 import org.tmatesoft.hg.core.HgRepositoryLockException; | 31 import org.tmatesoft.hg.core.HgRepositoryLockException; |
30 import org.tmatesoft.hg.core.Nodeid; | 32 import org.tmatesoft.hg.core.Nodeid; |
31 import org.tmatesoft.hg.internal.ByteArrayChannel; | 33 import org.tmatesoft.hg.internal.ByteArrayChannel; |
32 import org.tmatesoft.hg.internal.ChangelogEntryBuilder; | 34 import org.tmatesoft.hg.internal.ChangelogEntryBuilder; |
46 * | 48 * |
47 * @author Artem Tikhomirov | 49 * @author Artem Tikhomirov |
48 * @author TMate Software Ltd. | 50 * @author TMate Software Ltd. |
49 */ | 51 */ |
50 @Experimental(reason="Work in progress") | 52 @Experimental(reason="Work in progress") |
51 public class CommitFacility { | 53 public final class CommitFacility { |
52 private final HgRepository repo; | 54 private final HgRepository repo; |
53 private final int p1Commit, p2Commit; | 55 private final int p1Commit, p2Commit; |
54 private Map<Path, Pair<HgDataFile, ByteDataSupplier>> files = new LinkedHashMap<Path, Pair<HgDataFile, ByteDataSupplier>>(); | 56 private Map<Path, Pair<HgDataFile, ByteDataSupplier>> files = new LinkedHashMap<Path, Pair<HgDataFile, ByteDataSupplier>>(); |
55 | 57 private Set<Path> removals = new TreeSet<Path>(); |
58 private String branch; | |
56 | 59 |
57 public CommitFacility(HgRepository hgRepo, int parentCommit) { | 60 public CommitFacility(HgRepository hgRepo, int parentCommit) { |
58 this(hgRepo, parentCommit, NO_REVISION); | 61 this(hgRepo, parentCommit, NO_REVISION); |
59 } | 62 } |
60 | 63 |
70 public boolean isMerge() { | 73 public boolean isMerge() { |
71 return p1Commit != NO_REVISION && p2Commit != NO_REVISION; | 74 return p1Commit != NO_REVISION && p2Commit != NO_REVISION; |
72 } | 75 } |
73 | 76 |
74 public void add(HgDataFile dataFile, ByteDataSupplier content) { | 77 public void add(HgDataFile dataFile, ByteDataSupplier content) { |
78 if (content == null) { | |
79 throw new IllegalArgumentException(); | |
80 } | |
81 removals.remove(dataFile.getPath()); | |
75 files.put(dataFile.getPath(), new Pair<HgDataFile, ByteDataSupplier>(dataFile, content)); | 82 files.put(dataFile.getPath(), new Pair<HgDataFile, ByteDataSupplier>(dataFile, content)); |
83 } | |
84 | |
85 public void forget(HgDataFile dataFile) { | |
86 files.remove(dataFile.getPath()); | |
87 removals.add(dataFile.getPath()); | |
88 } | |
89 | |
90 public void branch(String branchName) { | |
91 branch = branchName; | |
76 } | 92 } |
77 | 93 |
78 public Nodeid commit(String message) throws HgRepositoryLockException { | 94 public Nodeid commit(String message) throws HgRepositoryLockException { |
79 | 95 |
80 final HgChangelog clog = repo.getChangelog(); | 96 final HgChangelog clog = repo.getChangelog(); |
85 repo.getManifest().walk(p1Commit, p1Commit, c1Manifest); | 101 repo.getManifest().walk(p1Commit, p1Commit, c1Manifest); |
86 } | 102 } |
87 if (p2Commit != NO_REVISION) { | 103 if (p2Commit != NO_REVISION) { |
88 repo.getManifest().walk(p2Commit, p2Commit, c2Manifest); | 104 repo.getManifest().walk(p2Commit, p2Commit, c2Manifest); |
89 } | 105 } |
90 FNCacheFile fncache = null; | |
91 if ((repo.getImplHelper().getRequiresFlags() & RequiresFile.FNCACHE) != 0) { | |
92 fncache = new FNCacheFile(repo.getImplHelper()); | |
93 try { | |
94 fncache.read(new Path.SimpleSource()); | |
95 } catch (IOException ex) { | |
96 // fncache may be restored using native client, so do not treat failure to read it as severe enough to stop | |
97 repo.getSessionContext().getLog().dump(getClass(), Severity.Error, ex, "Failed to read fncache, attempt commit nevertheless"); | |
98 } | |
99 } | |
100 // Pair<Integer, Integer> manifestParents = getManifestParents(); | 106 // Pair<Integer, Integer> manifestParents = getManifestParents(); |
101 Pair<Integer, Integer> manifestParents = new Pair<Integer, Integer>(c1Manifest.revisionIndex(), c2Manifest.revisionIndex()); | 107 Pair<Integer, Integer> manifestParents = new Pair<Integer, Integer>(c1Manifest.revisionIndex(), c2Manifest.revisionIndex()); |
102 TreeMap<Path, Nodeid> newManifestRevision = new TreeMap<Path, Nodeid>(); | 108 TreeMap<Path, Nodeid> newManifestRevision = new TreeMap<Path, Nodeid>(); |
103 HashMap<Path, Pair<Integer, Integer>> fileParents = new HashMap<Path, Pair<Integer,Integer>>(); | 109 HashMap<Path, Pair<Integer, Integer>> fileParents = new HashMap<Path, Pair<Integer,Integer>>(); |
104 for (Path f : c1Manifest.files()) { | 110 for (Path f : c1Manifest.files()) { |
105 HgDataFile df = repo.getFileNode(f); | 111 HgDataFile df = repo.getFileNode(f); |
106 Nodeid fileKnownRev = c1Manifest.nodeid(f); | 112 Nodeid fileKnownRev1 = c1Manifest.nodeid(f), fileKnownRev2; |
107 final int fileRevIndex1 = df.getRevisionIndex(fileKnownRev); | 113 final int fileRevIndex1 = df.getRevisionIndex(fileKnownRev1); |
108 final int fileRevIndex2; | 114 final int fileRevIndex2; |
109 if ((fileKnownRev = c2Manifest.nodeid(f)) != null) { | 115 if ((fileKnownRev2 = c2Manifest.nodeid(f)) != null) { |
110 // merged files | 116 // merged files |
111 fileRevIndex2 = df.getRevisionIndex(fileKnownRev); | 117 fileRevIndex2 = df.getRevisionIndex(fileKnownRev2); |
112 } else { | 118 } else { |
113 fileRevIndex2 = NO_REVISION; | 119 fileRevIndex2 = NO_REVISION; |
114 } | 120 } |
115 | 121 |
116 fileParents.put(f, new Pair<Integer, Integer>(fileRevIndex1, fileRevIndex2)); | 122 fileParents.put(f, new Pair<Integer, Integer>(fileRevIndex1, fileRevIndex2)); |
117 newManifestRevision.put(f, fileKnownRev); | 123 newManifestRevision.put(f, fileKnownRev1); |
118 } | 124 } |
119 // | 125 // |
120 // Files | 126 // Forget removed |
127 for (Path p : removals) { | |
128 newManifestRevision.remove(p); | |
129 } | |
130 // | |
131 // Register new/changed | |
121 ArrayList<Path> newlyAddedFiles = new ArrayList<Path>(); | 132 ArrayList<Path> newlyAddedFiles = new ArrayList<Path>(); |
122 for (Pair<HgDataFile, ByteDataSupplier> e : files.values()) { | 133 for (Pair<HgDataFile, ByteDataSupplier> e : files.values()) { |
123 HgDataFile df = e.first(); | 134 HgDataFile df = e.first(); |
124 Pair<Integer, Integer> fp = fileParents.get(df.getPath()); | 135 Pair<Integer, Integer> fp = fileParents.get(df.getPath()); |
125 if (fp == null) { | 136 if (fp == null) { |
159 Nodeid manifestRev = manifestWriter.addRevision(manifestBuilder.build(), clogRevisionIndex, manifestParents.first(), manifestParents.second()); | 170 Nodeid manifestRev = manifestWriter.addRevision(manifestBuilder.build(), clogRevisionIndex, manifestParents.first(), manifestParents.second()); |
160 // | 171 // |
161 // Changelog | 172 // Changelog |
162 final ChangelogEntryBuilder changelogBuilder = new ChangelogEntryBuilder(); | 173 final ChangelogEntryBuilder changelogBuilder = new ChangelogEntryBuilder(); |
163 changelogBuilder.setModified(files.keySet()); | 174 changelogBuilder.setModified(files.keySet()); |
175 changelogBuilder.branch(branch == null ? HgRepository.DEFAULT_BRANCH_NAME : branch); | |
164 byte[] clogContent = changelogBuilder.build(manifestRev, message); | 176 byte[] clogContent = changelogBuilder.build(manifestRev, message); |
165 RevlogStreamWriter changelogWriter = new RevlogStreamWriter(repo.getSessionContext(), clog.content); | 177 RevlogStreamWriter changelogWriter = new RevlogStreamWriter(repo.getSessionContext(), clog.content); |
166 Nodeid changesetRev = changelogWriter.addRevision(clogContent, clogRevisionIndex, p1Commit, p2Commit); | 178 Nodeid changesetRev = changelogWriter.addRevision(clogContent, clogRevisionIndex, p1Commit, p2Commit); |
167 if (!newlyAddedFiles.isEmpty() && fncache != null) { | 179 // FIXME move fncache update to an external facility, along with dirstate update |
180 if (!newlyAddedFiles.isEmpty() && repo.getImplHelper().fncacheInUse()) { | |
181 FNCacheFile fncache = new FNCacheFile(repo.getImplHelper()); | |
168 for (Path p : newlyAddedFiles) { | 182 for (Path p : newlyAddedFiles) { |
169 fncache.add(p); | 183 fncache.add(p); |
170 } | 184 } |
171 try { | 185 try { |
172 fncache.write(); | 186 fncache.write(); |
196 */ | 210 */ |
197 | 211 |
198 // unlike DataAccess (which provides structured access), this one | 212 // unlike DataAccess (which provides structured access), this one |
199 // deals with a sequence of bytes, when there's no need in structure of the data | 213 // deals with a sequence of bytes, when there's no need in structure of the data |
200 public interface ByteDataSupplier { // TODO look if can resolve DataAccess in HgCloneCommand visibility issue | 214 public interface ByteDataSupplier { // TODO look if can resolve DataAccess in HgCloneCommand visibility issue |
215 // FIXME needs lifecycle, e.g. for supplier that reads from WC | |
201 int read(ByteBuffer buf); | 216 int read(ByteBuffer buf); |
202 } | 217 } |
203 | 218 |
204 public interface ByteDataConsumer { | 219 public interface ByteDataConsumer { |
205 void write(ByteBuffer buf); | 220 void write(ByteBuffer buf); |