comparison src/org/tmatesoft/hg/repo/CommitFacility.java @ 539:9edfd5a223b8

Commit: handle empty repository case
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 13 Feb 2013 18:44:58 +0100
parents dd4f6311af52
children 67d4b0f73984
comparison
equal deleted inserted replaced
538:dd4f6311af52 539:9edfd5a223b8
16 */ 16 */
17 package org.tmatesoft.hg.repo; 17 package org.tmatesoft.hg.repo;
18 18
19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; 19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION;
20 20
21 import java.io.IOException;
21 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
23 import java.util.ArrayList;
22 import java.util.HashMap; 24 import java.util.HashMap;
23 import java.util.LinkedHashMap; 25 import java.util.LinkedHashMap;
24 import java.util.Map; 26 import java.util.Map;
25 import java.util.TreeMap; 27 import java.util.TreeMap;
26 28
27 import org.tmatesoft.hg.core.HgRepositoryLockException; 29 import org.tmatesoft.hg.core.HgRepositoryLockException;
28 import org.tmatesoft.hg.core.Nodeid; 30 import org.tmatesoft.hg.core.Nodeid;
29 import org.tmatesoft.hg.internal.ByteArrayChannel; 31 import org.tmatesoft.hg.internal.ByteArrayChannel;
30 import org.tmatesoft.hg.internal.ChangelogEntryBuilder; 32 import org.tmatesoft.hg.internal.ChangelogEntryBuilder;
31 import org.tmatesoft.hg.internal.Experimental; 33 import org.tmatesoft.hg.internal.Experimental;
34 import org.tmatesoft.hg.internal.FNCacheFile;
32 import org.tmatesoft.hg.internal.ManifestEntryBuilder; 35 import org.tmatesoft.hg.internal.ManifestEntryBuilder;
33 import org.tmatesoft.hg.internal.ManifestRevision; 36 import org.tmatesoft.hg.internal.ManifestRevision;
37 import org.tmatesoft.hg.internal.RequiresFile;
38 import org.tmatesoft.hg.internal.RevlogStream;
34 import org.tmatesoft.hg.internal.RevlogStreamWriter; 39 import org.tmatesoft.hg.internal.RevlogStreamWriter;
35 import org.tmatesoft.hg.util.Pair; 40 import org.tmatesoft.hg.util.Pair;
36 import org.tmatesoft.hg.util.Path; 41 import org.tmatesoft.hg.util.Path;
42 import org.tmatesoft.hg.util.LogFacility.Severity;
37 43
38 /** 44 /**
39 * WORK IN PROGRESS 45 * WORK IN PROGRESS
40 * 46 *
41 * @author Artem Tikhomirov 47 * @author Artem Tikhomirov
79 repo.getManifest().walk(p1Commit, p1Commit, c1Manifest); 85 repo.getManifest().walk(p1Commit, p1Commit, c1Manifest);
80 } 86 }
81 if (p2Commit != NO_REVISION) { 87 if (p2Commit != NO_REVISION) {
82 repo.getManifest().walk(p2Commit, p2Commit, c2Manifest); 88 repo.getManifest().walk(p2Commit, p2Commit, c2Manifest);
83 } 89 }
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 }
84 // Pair<Integer, Integer> manifestParents = getManifestParents(); 100 // Pair<Integer, Integer> manifestParents = getManifestParents();
85 Pair<Integer, Integer> manifestParents = new Pair<Integer, Integer>(c1Manifest.revisionIndex(), c2Manifest.revisionIndex()); 101 Pair<Integer, Integer> manifestParents = new Pair<Integer, Integer>(c1Manifest.revisionIndex(), c2Manifest.revisionIndex());
86 TreeMap<Path, Nodeid> newManifestRevision = new TreeMap<Path, Nodeid>(); 102 TreeMap<Path, Nodeid> newManifestRevision = new TreeMap<Path, Nodeid>();
87 HashMap<Path, Pair<Integer, Integer>> fileParents = new HashMap<Path, Pair<Integer,Integer>>(); 103 HashMap<Path, Pair<Integer, Integer>> fileParents = new HashMap<Path, Pair<Integer,Integer>>();
88 for (Path f : c1Manifest.files()) { 104 for (Path f : c1Manifest.files()) {
89 HgDataFile df = repo.getFileNode(f); 105 HgDataFile df = repo.getFileNode(f);
90 Nodeid fileKnownRev = c1Manifest.nodeid(f); 106 Nodeid fileKnownRev = c1Manifest.nodeid(f);
91 int fileRevIndex = df.getRevisionIndex(fileKnownRev); 107 final int fileRevIndex1 = df.getRevisionIndex(fileKnownRev);
92 // FIXME merged files?! 108 final int fileRevIndex2;
93 fileParents.put(f, new Pair<Integer, Integer>(fileRevIndex, NO_REVISION)); 109 if ((fileKnownRev = c2Manifest.nodeid(f)) != null) {
110 // merged files
111 fileRevIndex2 = df.getRevisionIndex(fileKnownRev);
112 } else {
113 fileRevIndex2 = NO_REVISION;
114 }
115
116 fileParents.put(f, new Pair<Integer, Integer>(fileRevIndex1, fileRevIndex2));
94 newManifestRevision.put(f, fileKnownRev); 117 newManifestRevision.put(f, fileKnownRev);
95 } 118 }
96 // 119 //
97 // Files 120 // Files
121 ArrayList<Path> newlyAddedFiles = new ArrayList<Path>();
98 for (Pair<HgDataFile, ByteDataSupplier> e : files.values()) { 122 for (Pair<HgDataFile, ByteDataSupplier> e : files.values()) {
99 HgDataFile df = e.first(); 123 HgDataFile df = e.first();
100 Pair<Integer, Integer> fp = fileParents.get(df.getPath()); 124 Pair<Integer, Integer> fp = fileParents.get(df.getPath());
101 if (fp == null) { 125 if (fp == null) {
102 // NEW FILE 126 // NEW FILE
109 while (bds.read(bb) != -1) { 133 while (bds.read(bb) != -1) {
110 bb.flip(); 134 bb.flip();
111 bac.write(bb); 135 bac.write(bb);
112 bb.clear(); 136 bb.clear();
113 } 137 }
114 RevlogStreamWriter fileWriter = new RevlogStreamWriter(repo.getSessionContext(), df.content); 138 RevlogStream contentStream;
139 if (df.exists()) {
140 contentStream = df.content;
141 } else {
142 contentStream = repo.createStoreFile(df.getPath());
143 newlyAddedFiles.add(df.getPath());
144 }
145 RevlogStreamWriter fileWriter = new RevlogStreamWriter(repo.getSessionContext(), contentStream);
115 Nodeid fileRev = fileWriter.addRevision(bac.toArray(), clogRevisionIndex, fp.first(), fp.second()); 146 Nodeid fileRev = fileWriter.addRevision(bac.toArray(), clogRevisionIndex, fp.first(), fp.second());
116 newManifestRevision.put(df.getPath(), fileRev); 147 newManifestRevision.put(df.getPath(), fileRev);
117 } 148 }
118 // 149 //
119 // Manifest 150 // Manifest
128 final ChangelogEntryBuilder changelogBuilder = new ChangelogEntryBuilder(); 159 final ChangelogEntryBuilder changelogBuilder = new ChangelogEntryBuilder();
129 changelogBuilder.setModified(files.keySet()); 160 changelogBuilder.setModified(files.keySet());
130 byte[] clogContent = changelogBuilder.build(manifestRev, message); 161 byte[] clogContent = changelogBuilder.build(manifestRev, message);
131 RevlogStreamWriter changelogWriter = new RevlogStreamWriter(repo.getSessionContext(), clog.content); 162 RevlogStreamWriter changelogWriter = new RevlogStreamWriter(repo.getSessionContext(), clog.content);
132 Nodeid changesetRev = changelogWriter.addRevision(clogContent, clogRevisionIndex, p1Commit, p2Commit); 163 Nodeid changesetRev = changelogWriter.addRevision(clogContent, clogRevisionIndex, p1Commit, p2Commit);
164 if (!newlyAddedFiles.isEmpty() && fncache != null) {
165 for (Path p : newlyAddedFiles) {
166 fncache.add(p);
167 }
168 try {
169 fncache.write();
170 } catch (IOException ex) {
171 // see comment above for fnchache.read()
172 repo.getSessionContext().getLog().dump(getClass(), Severity.Error, ex, "Failed to write fncache, error ignored");
173 }
174 }
133 return changesetRev; 175 return changesetRev;
134 } 176 }
135 /* 177 /*
136 private Pair<Integer, Integer> getManifestParents() { 178 private Pair<Integer, Integer> getManifestParents() {
137 return new Pair<Integer, Integer>(extractManifestRevisionIndex(p1Commit), extractManifestRevisionIndex(p2Commit)); 179 return new Pair<Integer, Integer>(extractManifestRevisionIndex(p1Commit), extractManifestRevisionIndex(p2Commit));