public virtual void TestDirCacheMatchingId() { FilePath f = WriteTrashFile("file", "content"); Git git = new Git(db); WriteTrashFile("file", "content"); FsTick(f); git.Add().AddFilepattern("file").Call(); DirCacheEntry dce = db.ReadDirCache().GetEntry("file"); TreeWalk tw = new TreeWalk(db); FileTreeIterator fti = new FileTreeIterator(trash, db.FileSystem, ((FileBasedConfig )db.GetConfig()).Get(WorkingTreeOptions.KEY)); tw.AddTree(fti); DirCacheIterator dci = new DirCacheIterator(db.ReadDirCache()); tw.AddTree(dci); fti.SetDirCacheIterator(tw, 1); while (tw.Next() && !tw.PathString.Equals("file")) { } // NUnit.Framework.Assert.AreEqual(WorkingTreeIterator.MetadataDiff.EQUAL, fti.CompareMetadata (dce)); ObjectId fromRaw = ObjectId.FromRaw(fti.IdBuffer, fti.IdOffset); NUnit.Framework.Assert.AreEqual("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", fromRaw .GetName()); NUnit.Framework.Assert.IsFalse(fti.IsModified(dce, false)); }
/// <exception cref="System.IO.IOException"></exception> internal virtual int GetObjectType(WindowCursor curs, long pos) { byte[] ib = curs.tempId; for (; ;) { ReadFully(pos, ib, 0, 20, curs); int c = ib[0] & unchecked ((int)(0xff)); int type = (c >> 4) & 7; switch (type) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { return(type); } case Constants.OBJ_OFS_DELTA: { int p = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = ib[p++] & unchecked ((int)(0xff)); } c = ib[p++] & unchecked ((int)(0xff)); long ofs = c & 127; while ((c & 128) != 0) { ofs += 1; c = ib[p++] & unchecked ((int)(0xff)); ofs <<= 7; ofs += (c & 127); } pos = pos - ofs; continue; goto case Constants.OBJ_REF_DELTA; } case Constants.OBJ_REF_DELTA: { int p = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = ib[p++] & unchecked ((int)(0xff)); } ReadFully(pos + p, ib, 0, 20, curs); pos = FindDeltaBase(ObjectId.FromRaw(ib)); continue; goto default; } default: { throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf (type))); } } } }
public override ObjectId GetObjectId(long nthPosition) { int levelOne = System.Array.BinarySearch(idxHeader, nthPosition + 1); long @base; if (levelOne >= 0) { // If we hit the bucket exactly the item is in the bucket, or // any bucket before it which has the same object count. // @base = idxHeader[levelOne]; while (levelOne > 0 && @base == idxHeader[levelOne - 1]) { levelOne--; } } else { // The item is in the bucket we would insert it into. // levelOne = -(levelOne + 1); } @base = levelOne > 0 ? idxHeader[levelOne - 1] : 0; int p = (int)(nthPosition - @base); int dataIdx = IdOffset(p); return(ObjectId.FromRaw(idxdata[levelOne], dataIdx)); }
/// <exception cref="System.IO.IOException"></exception> private void OnOpenPack() { PackIndex idx = Idx(); byte[] buf = new byte[20]; fd.Seek(0); fd.ReadFully(buf, 0, 12); if (RawParseUtils.Match(buf, 0, Constants.PACK_SIGNATURE) != 4) { throw new IOException(JGitText.Get().notAPACKFile); } long vers = NB.DecodeUInt32(buf, 4); long packCnt = NB.DecodeUInt32(buf, 8); if (vers != 2 && vers != 3) { throw new IOException(MessageFormat.Format(JGitText.Get().unsupportedPackVersion, Sharpen.Extensions.ValueOf(vers))); } if (packCnt != idx.GetObjectCount()) { throw new PackMismatchException(MessageFormat.Format(JGitText.Get().packObjectCountMismatch , Sharpen.Extensions.ValueOf(packCnt), Sharpen.Extensions.ValueOf(idx.GetObjectCount ()), GetPackFile())); } fd.Seek(length - 20); fd.ReadFully(buf, 0, 20); if (!Arrays.Equals(buf, packChecksum)) { throw new PackMismatchException(MessageFormat.Format(JGitText.Get().packObjectCountMismatch , ObjectId.FromRaw(buf).Name, ObjectId.FromRaw(idx.packChecksum).Name, GetPackFile ())); } }
internal override ObjectId GetObjectId(long nthPosition) { int levelOne = System.Array.BinarySearch(fanoutTable, nthPosition + 1); long @base; if (levelOne >= 0) { // If we hit the bucket exactly the item is in the bucket, or // any bucket before it which has the same object count. // @base = fanoutTable[levelOne]; while (levelOne > 0 && @base == fanoutTable[levelOne - 1]) { levelOne--; } } else { // The item is in the bucket we would insert it into. // levelOne = -(levelOne + 1); } @base = levelOne > 0 ? fanoutTable[levelOne - 1] : 0; int p = (int)(nthPosition - @base); int p4 = p << 2; return(ObjectId.FromRaw(names[levelOne], p4 + p)); }
/// <exception cref="System.IO.IOException"></exception> public override ObjectId Insert(int type, long len, InputStream @is) { MessageDigest md = Digest(); FilePath tmp = ToTemp(md, type, len, @is); ObjectId id = ObjectId.FromRaw(md.Digest()); switch (db.InsertUnpackedObject(tmp, id, false)) { case FileObjectDatabase.InsertLooseObjectResult.INSERTED: case FileObjectDatabase.InsertLooseObjectResult.EXISTS_PACKED: case FileObjectDatabase.InsertLooseObjectResult.EXISTS_LOOSE: { return(id); } case FileObjectDatabase.InsertLooseObjectResult.FAILURE: default: { break; break; } } FilePath dst = db.FileFor(id); throw new ObjectWritingException("Unable to create new object: " + dst); }
/// <exception cref="System.IO.IOException"></exception> private RefDirectory.PackedRefList ReadPackedRefs() { FileSnapshot snapshot = FileSnapshot.Save(packedRefsFile); BufferedReader br; MessageDigest digest = Constants.NewMessageDigest(); try { br = new BufferedReader(new InputStreamReader(new DigestInputStream(new FileInputStream (packedRefsFile), digest), Constants.CHARSET)); } catch (FileNotFoundException) { // Ignore it and leave the new list empty. return(RefDirectory.PackedRefList.NO_PACKED_REFS); } try { return(new RefDirectory.PackedRefList(ParsePackedRefs(br), snapshot, ObjectId.FromRaw (digest.Digest()))); } finally { br.Close(); } }
internal DirCacheTree(byte[] @in, MutableInteger off, NGit.Dircache.DirCacheTree myParent) { parent = myParent; int ptr = RawParseUtils.Next(@in, off.value, '\0'); int nameLen = ptr - off.value - 1; if (nameLen > 0) { encodedName = new byte[nameLen]; System.Array.Copy(@in, off.value, encodedName, 0, nameLen); } else { encodedName = NO_NAME; } entrySpan = RawParseUtils.ParseBase10(@in, ptr, off); int subcnt = RawParseUtils.ParseBase10(@in, off.value, off); off.value = RawParseUtils.Next(@in, off.value, '\n'); if (entrySpan >= 0) { // Valid trees have a positive entry count and an id of a // tree object that should exist in the object database. // id = ObjectId.FromRaw(@in, off.value); off.value += Constants.OBJECT_ID_LENGTH; } if (subcnt > 0) { bool alreadySorted = true; children = new NGit.Dircache.DirCacheTree[subcnt]; for (int i = 0; i < subcnt; i++) { children[i] = new NGit.Dircache.DirCacheTree(@in, off, this); // C Git's ordering differs from our own; it prefers to // sort by length first. This sometimes produces a sort // we do not desire. On the other hand it may have been // created by us, and be sorted the way we want. // if (alreadySorted && i > 0 && TREE_CMP.Compare(children[i - 1], children[i]) > 0) { alreadySorted = false; } } if (!alreadySorted) { Arrays.Sort(children, 0, subcnt, TREE_CMP); } } else { // Leaf level trees have no children, only (file) entries. // children = NO_CHILDREN; } childCnt = subcnt; }
public virtual void TestEntryObjectId() { EmptyTreeIterator etp = new EmptyTreeIterator(); NUnit.Framework.Assert.AreSame(ObjectId.ZeroId, etp.EntryObjectId); NUnit.Framework.Assert.IsNotNull(etp.IdBuffer); NUnit.Framework.Assert.AreEqual(0, etp.IdOffset); NUnit.Framework.Assert.AreEqual(ObjectId.ZeroId, ObjectId.FromRaw(etp.IdBuffer)); }
public virtual void testEntryObjectId() { EmptyTreeIterator etp = new EmptyTreeIterator(); Assert.AreSame(ObjectId.ZeroId, etp.getEntryObjectId()); Assert.IsNotNull(etp.idBuffer()); Assert.AreEqual(0, etp.idOffset()); Assert.AreEqual(ObjectId.ZeroId, ObjectId.FromRaw(etp.idBuffer())); }
public virtual void TestNextDoesNothing() { EmptyTreeIterator etp = new EmptyTreeIterator(); etp.Next(1); NUnit.Framework.Assert.IsTrue(etp.First); NUnit.Framework.Assert.IsTrue(etp.Eof); NUnit.Framework.Assert.AreEqual(ObjectId.ZeroId, ObjectId.FromRaw(etp.IdBuffer)); etp.Next(1); NUnit.Framework.Assert.IsTrue(etp.First); NUnit.Framework.Assert.IsTrue(etp.Eof); NUnit.Framework.Assert.AreEqual(ObjectId.ZeroId, ObjectId.FromRaw(etp.IdBuffer)); }
public virtual void testBackDoesNothing() { EmptyTreeIterator etp = new EmptyTreeIterator(); etp.back(1); Assert.IsTrue(etp.first()); Assert.IsTrue(etp.eof()); Assert.AreEqual(ObjectId.ZeroId, ObjectId.FromRaw(etp.idBuffer())); etp.back(1); Assert.IsTrue(etp.first()); Assert.IsTrue(etp.eof()); Assert.AreEqual(ObjectId.ZeroId, ObjectId.FromRaw(etp.idBuffer())); }
/// <exception cref="System.IO.IOException"></exception> internal override void Resolve(ICollection <ObjectId> matches, AbbreviatedObjectId id, int matchLimit) { int[] data = names[id.FirstByte]; int max = (int)(((uint)offset32[id.FirstByte].Length) >> 2); int high = max; if (high == 0) { return; } int low = 0; do { int p = (int)(((uint)(low + high)) >> 1); int cmp = id.PrefixCompare(data, IdOffset(p)); if (cmp < 0) { high = p; } else { if (cmp == 0) { // We may have landed in the middle of the matches. Move // backwards to the start of matches, then walk forwards. // while (0 < p && id.PrefixCompare(data, IdOffset(p - 1)) == 0) { p--; } for (; p < max && id.PrefixCompare(data, IdOffset(p)) == 0; p++) { matches.AddItem(ObjectId.FromRaw(data, IdOffset(p))); if (matches.Count > matchLimit) { break; } } return; } else { low = p + 1; } } }while (low < high); }
/// <exception cref="System.IO.IOException"></exception> public override ObjectId Insert(int type, long len, InputStream @is) { if (len <= Buffer().Length) { byte[] buf = Buffer(); int actLen = IOUtil.ReadFully(@is, buf, 0); return(Insert(type, buf, 0, actLen)); } else { MessageDigest md = Digest(); FilePath tmp = ToTemp(md, type, len, @is); ObjectId id = ObjectId.FromRaw(md.Digest()); return(InsertOneObject(tmp, id)); } }
public void testComputeFileObjectId() { var top = new FileTreeIterator(trash); MessageDigest md = Constants.newMessageDigest(); md.Update(Constants.encodeASCII(Constants.TYPE_BLOB)); md.Update((byte)' '); md.Update(Constants.encodeASCII(Paths[0].Length)); md.Update(0); md.Update(Constants.encode(Paths[0])); ObjectId expect = ObjectId.FromRaw(md.Digest()); Assert.AreEqual(expect, top.getEntryObjectId()); // Verify it was cached by removing the File and getting it again. File.Delete(Path.Combine(trash.FullName, Paths[0])); Assert.AreEqual(expect, top.getEntryObjectId()); }
public virtual void TestComputeFileObjectId() { FileTreeIterator top = new FileTreeIterator(trash, db.FileSystem, ((FileBasedConfig )db.GetConfig()).Get(WorkingTreeOptions.KEY)); MessageDigest md = Constants.NewMessageDigest(); md.Update(Constants.EncodeASCII(Constants.TYPE_BLOB)); md.Update(unchecked ((byte)' ')); md.Update(Constants.EncodeASCII(paths[0].Length)); md.Update(unchecked ((byte)0)); md.Update(Constants.Encode(paths[0])); ObjectId expect = ObjectId.FromRaw(md.Digest()); NUnit.Framework.Assert.AreEqual(expect, top.EntryObjectId); // Verify it was cached by removing the file and getting it again. // FileUtils.Delete(new FilePath(trash, paths[0])); NUnit.Framework.Assert.AreEqual(expect, top.EntryObjectId); }
public void Write_Tree() { var t = new global::GitSharp.Core.Tree(db); FileTreeEntry f = t.AddFile("i-am-a-file"); writeTrashFile(f.Name, "and this is the data in me\r\n\r\n"); Assert.AreEqual(File.ReadAllText("Resources/single_file_commit/i-am-a-file"), File.ReadAllText(db.WorkingDirectory.FullName + "/i-am-a-file")); t.Accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY); var id = t.Id; int git_w1; int git_w2; int w1; int w2; using (var b1 = new BinaryReader(new Inspector(db).ContentStream(id))) using (var b2 = new BinaryReader(Inspector.ContentStream("Resources/single_file_commit", "917c130bd4fa5bf2df0c399dc1b03401860aa448"))) { b1.BaseStream.Position = b1.BaseStream.Length - 21; b2.BaseStream.Position = b2.BaseStream.Length - 21; Assert.AreEqual(b2.ReadByte(), b1.ReadByte()); git_w1 = b2.ReadInt32(); git_w2 = b2.ReadInt32(); var git_w3 = b2.ReadInt32(); var git_w4 = b2.ReadInt32(); var git_w5 = b2.ReadInt32(); b2.BaseStream.Position = b2.BaseStream.Length - 20; var git_id = ObjectId.FromRaw(b2.ReadBytes(20)); w1 = b1.ReadInt32(); w2 = b1.ReadInt32(); } Assert.AreEqual(git_w1, w1); Assert.AreEqual(git_w2, w2); Assert.AreEqual("917c130bd4fa5bf2df0c399dc1b03401860aa448", id.Name); var s_git = Inspector.Inspect("Resources/single_file_commit", "917c130bd4fa5bf2df0c399dc1b03401860aa448"); var s = new Inspector(db).Inspect(id); Assert.AreEqual(s_git, s); }
/// <summary> /// Rename the pack to it's final name and location and open it. /// <para/> /// If the call completes successfully the repository this IndexPack instance /// was created with will have the objects in the pack available for reading /// and use, without needing to scan for packs. /// </summary> /// <param name="lockMessage"> /// message to place in the pack-*.keep file. If null, no lock /// will be created, and this method returns null. /// </param> /// <returns>the pack lock object, if lockMessage is not null.</returns> public PackLock renameAndOpenPack(string lockMessage) { if (!_keepEmpty && _entryCount == 0) { CleanupTemporaryFiles(); return(null); } MessageDigest d = Constants.newMessageDigest(); var oeBytes = new byte[Constants.OBJECT_ID_LENGTH]; for (int i = 0; i < _entryCount; i++) { PackedObjectInfo oe = _entries[i]; oe.copyRawTo(oeBytes, 0); d.Update(oeBytes); } string name = ObjectId.FromRaw(d.Digest()).Name; var packDir = PathUtil.CombineDirectoryPath(_repo.ObjectsDirectory, "pack"); var finalPack = PathUtil.CombineFilePath(packDir, "pack-" + GetPackFileName(name)); var finalIdx = PathUtil.CombineFilePath(packDir, "pack-" + GetIndexFileName(name)); var keep = new PackLock(finalPack); if (!packDir.Exists && !packDir.Mkdirs() && !packDir.Exists) { // The objects/pack directory isn't present, and we are unable // to create it. There is no way to move this pack in. // CleanupTemporaryFiles(); throw new IOException("Cannot Create " + packDir); } if (finalPack.Exists) { // If the pack is already present we should never replace it. // CleanupTemporaryFiles(); return(null); } if (lockMessage != null) { // If we have a reason to create a keep file for this pack, do // so, or fail fast and don't put the pack in place. // try { if (!keep.Lock(lockMessage)) { throw new IOException("Cannot lock pack in " + finalPack); } } catch (IOException) { CleanupTemporaryFiles(); throw; } } if (!_dstPack.RenameTo(finalPack.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); throw new IOException("Cannot move pack to " + finalPack); } if (!_dstIdx.RenameTo(finalIdx.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); finalPack.DeleteFile(); //if (finalPack.Exists) // TODO: [caytchen] finalPack.deleteOnExit(); throw new IOException("Cannot move index to " + finalIdx); } try { _repo.OpenPack(finalPack, finalIdx); } catch (IOException) { keep.Unlock(); finalPack.DeleteFile(); finalIdx.DeleteFile(); throw; } return(lockMessage != null ? keep : null); }
/// <exception cref="System.IO.IOException"></exception> private PackLock RenameAndOpenPack(string lockMessage) { if (!keepEmpty && GetObjectCount() == 0) { CleanupTemporaryFiles(); return(null); } MessageDigest d = Constants.NewMessageDigest(); byte[] oeBytes = new byte[Constants.OBJECT_ID_LENGTH]; for (int i = 0; i < GetObjectCount(); i++) { PackedObjectInfo oe = GetObject(i); oe.CopyRawTo(oeBytes, 0); d.Update(oeBytes); } string name = ObjectId.FromRaw(d.Digest()).Name; FilePath packDir = new FilePath(db.GetDirectory(), "pack"); FilePath finalPack = new FilePath(packDir, "pack-" + name + ".pack"); FilePath finalIdx = new FilePath(packDir, "pack-" + name + ".idx"); PackLock keep = new PackLock(finalPack, db.GetFS()); if (!packDir.Exists() && !packDir.Mkdir() && !packDir.Exists()) { // The objects/pack directory isn't present, and we are unable // to create it. There is no way to move this pack in. // CleanupTemporaryFiles(); throw new IOException(MessageFormat.Format(JGitText.Get().cannotCreateDirectory, packDir.GetAbsolutePath())); } if (finalPack.Exists()) { // If the pack is already present we should never replace it. // CleanupTemporaryFiles(); return(null); } if (lockMessage != null) { // If we have a reason to create a keep file for this pack, do // so, or fail fast and don't put the pack in place. // try { if (!keep.Lock(lockMessage)) { throw new LockFailedException(finalPack, MessageFormat.Format(JGitText.Get().cannotLockPackIn , finalPack)); } } catch (IOException e) { CleanupTemporaryFiles(); throw; } } if (!tmpPack.RenameTo(finalPack)) { CleanupTemporaryFiles(); keep.Unlock(); throw new IOException(MessageFormat.Format(JGitText.Get().cannotMovePackTo, finalPack )); } if (!tmpIdx.RenameTo(finalIdx)) { CleanupTemporaryFiles(); keep.Unlock(); if (!finalPack.Delete()) { finalPack.DeleteOnExit(); } throw new IOException(MessageFormat.Format(JGitText.Get().cannotMoveIndexTo, finalIdx )); } try { newPack = db.OpenPack(finalPack, finalIdx); } catch (IOException err) { keep.Unlock(); if (finalPack.Exists()) { FileUtils.Delete(finalPack); } if (finalIdx.Exists()) { FileUtils.Delete(finalIdx); } throw; } return(lockMessage != null ? keep : null); }
/// <summary> /// Gets the <see cref="ObjectId"/> of the current entry. /// </summary> /// <returns>The <see cref="ObjectId"/> for the current entry.</returns> public virtual ObjectId getEntryObjectId() { return(ObjectId.FromRaw(idBuffer(), idOffset())); }
/// <exception cref="System.IO.IOException"></exception> internal virtual ObjectLoader Load(WindowCursor curs, long pos) { try { byte[] ib = curs.tempId; PackFile.Delta delta = null; byte[] data = null; int type = Constants.OBJ_BAD; bool cached = false; for (; ;) { ReadFully(pos, ib, 0, 20, curs); int c = ib[0] & unchecked ((int)(0xff)); int typeCode = (c >> 4) & 7; long sz = c & 15; int shift = 4; int p = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = ib[p++] & unchecked ((int)(0xff)); sz += ((long)(c & unchecked ((int)(0x7f)))) << shift; shift += 7; } switch (typeCode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { if (sz < curs.GetStreamFileThreshold()) { data = Decompress(pos + p, (int)sz, curs); } if (delta != null) { type = typeCode; goto SEARCH_break; } if (data != null) { return(new ObjectLoader.SmallObject(typeCode, data)); } else { return(new LargePackedWholeObject(typeCode, sz, pos, p, this, curs.db)); } goto case Constants.OBJ_OFS_DELTA; } case Constants.OBJ_OFS_DELTA: { c = ib[p++] & unchecked ((int)(0xff)); long @base = c & 127; while ((c & 128) != 0) { @base += 1; c = ib[p++] & unchecked ((int)(0xff)); @base <<= 7; @base += (c & 127); } @base = pos - @base; delta = new PackFile.Delta(delta, pos, (int)sz, p, @base); if (sz != delta.deltaSize) { goto SEARCH_break; } DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base); if (e != null) { type = e.type; data = e.data; cached = true; goto SEARCH_break; } pos = @base; goto SEARCH_continue; } case Constants.OBJ_REF_DELTA: { ReadFully(pos + p, ib, 0, 20, curs); long @base = FindDeltaBase(ObjectId.FromRaw(ib)); delta = new PackFile.Delta(delta, pos, (int)sz, p + 20, @base); if (sz != delta.deltaSize) { goto SEARCH_break; } DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base); if (e != null) { type = e.type; data = e.data; cached = true; goto SEARCH_break; } pos = @base; goto SEARCH_continue; } default: { throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf (typeCode))); } } SEARCH_continue :; } SEARCH_break :; // At this point there is at least one delta to apply to data. // (Whole objects with no deltas to apply return early above.) if (data == null) { return(delta.Large(this, curs)); } do { // Cache only the base immediately before desired object. if (cached) { cached = false; } else { if (delta.next == null) { curs.GetDeltaBaseCache().Store(this, delta.basePos, data, type); } } pos = delta.deltaPos; byte[] cmds = Decompress(pos + delta.hdrLen, delta.deltaSize, curs); if (cmds == null) { data = null; // Discard base in case of OutOfMemoryError return(delta.Large(this, curs)); } long sz = BinaryDelta.GetResultSize(cmds); if (int.MaxValue <= sz) { return(delta.Large(this, curs)); } byte[] result; try { result = new byte[(int)sz]; } catch (OutOfMemoryException) { data = null; // Discard base in case of OutOfMemoryError return(delta.Large(this, curs)); } BinaryDelta.Apply(data, cmds, result); data = result; delta = delta.next; }while (delta != null); return(new ObjectLoader.SmallObject(type, data)); } catch (SharpZipBaseException dfe) { CorruptObjectException coe = new CorruptObjectException(MessageFormat.Format(JGitText .Get().objectAtHasBadZlibStream, Sharpen.Extensions.ValueOf(pos), GetPackFile()) ); Sharpen.Extensions.InitCause(coe, dfe); throw coe; } }
public PackLock renameAndOpenPack(string lockMessage) { if (!_keepEmpty && _entryCount == 0) { CleanupTemporaryFiles(); return(null); } MessageDigest d = Constants.newMessageDigest(); var oeBytes = new byte[Constants.OBJECT_ID_LENGTH]; for (int i = 0; i < _entryCount; i++) { PackedObjectInfo oe = _entries[i]; oe.copyRawTo(oeBytes, 0); d.Update(oeBytes); } string name = ObjectId.FromRaw(d.Digest()).Name; var packDir = new DirectoryInfo(Path.Combine(_repo.ObjectsDirectory.ToString(), "pack")); var finalPack = new FileInfo(Path.Combine(packDir.ToString(), "pack-" + GetPackFileName(name))); var finalIdx = new FileInfo(Path.Combine(packDir.ToString(), "pack-" + GetIndexFileName(name))); var keep = new PackLock(finalPack); if (!packDir.Exists && !packDir.Mkdirs() && !packDir.Exists) { CleanupTemporaryFiles(); throw new IOException("Cannot Create " + packDir); } if (finalPack.Exists) { CleanupTemporaryFiles(); return(null); } if (lockMessage != null) { try { if (!keep.Lock(lockMessage)) { throw new IOException("Cannot lock pack in " + finalPack); } } catch (IOException) { CleanupTemporaryFiles(); throw; } } if (!_dstPack.RenameTo(finalPack.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); throw new IOException("Cannot move pack to " + finalPack); } if (!_dstIdx.RenameTo(finalIdx.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); finalPack.Delete(); //if (finalPack.Exists) // TODO: [caytchen] finalPack.deleteOnExit(); throw new IOException("Cannot move index to " + finalIdx); } try { _repo.OpenPack(finalPack, finalIdx); } catch (IOException) { keep.Unlock(); finalPack.Delete(); finalIdx.Delete(); throw; } return(lockMessage != null ? keep : null); }
/// <exception cref="System.IO.IOException"></exception> internal virtual LocalObjectRepresentation Representation(WindowCursor curs, AnyObjectId objectId) { long pos = Idx().FindOffset(objectId); if (pos < 0) { return(null); } byte[] ib = curs.tempId; ReadFully(pos, ib, 0, 20, curs); int c = ib[0] & unchecked ((int)(0xff)); int p = 1; int typeCode = (c >> 4) & 7; while ((c & unchecked ((int)(0x80))) != 0) { c = ib[p++] & unchecked ((int)(0xff)); } long len = (FindEndOffset(pos) - pos); switch (typeCode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { return(LocalObjectRepresentation.NewWhole(this, pos, len - p)); } case Constants.OBJ_OFS_DELTA: { c = ib[p++] & unchecked ((int)(0xff)); long ofs = c & 127; while ((c & 128) != 0) { ofs += 1; c = ib[p++] & unchecked ((int)(0xff)); ofs <<= 7; ofs += (c & 127); } ofs = pos - ofs; return(LocalObjectRepresentation.NewDelta(this, pos, len - p, ofs)); } case Constants.OBJ_REF_DELTA: { len -= p; len -= Constants.OBJECT_ID_LENGTH; ReadFully(pos + p, ib, 0, 20, curs); ObjectId id = ObjectId.FromRaw(ib); return(LocalObjectRepresentation.NewDelta(this, pos, len, id)); } default: { throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf (typeCode))); } } }
public DirCacheTree(byte[] @in, MutableInteger off, DirCacheTree myParent) { _parent = myParent; int ptr = RawParseUtils.next(@in, off.value, (byte)'\0'); int nameLen = ptr - off.value - 1; if (nameLen > 0) { _encodedName = new byte[nameLen]; Array.Copy(@in, off.value, _encodedName, 0, nameLen); } else { _encodedName = NoName; } _entrySpan = RawParseUtils.parseBase10(@in, ptr, off); int subcnt = RawParseUtils.parseBase10(@in, off.value, off); off.value = RawParseUtils.next(@in, off.value, (byte)'\n'); if (_entrySpan >= 0) { // Valid trees have a positive entry count and an id of a // tree object that should exist in the object database. // _id = ObjectId.FromRaw(@in, off.value); off.value += Constants.OBJECT_ID_LENGTH; } if (subcnt > 0) { bool alreadySorted = true; _children = new DirCacheTree[subcnt]; for (int i = 0; i < subcnt; i++) { _children[i] = new DirCacheTree(@in, off, this); // C Git's ordering differs from our own; it prefers to // sort by Length first. This sometimes produces a sort // we do not desire. On the other hand it may have been // created by us, and be sorted the way we want. // if (alreadySorted && i > 0 && TreeComparison(_children[i - 1], _children[i]) > 0) { alreadySorted = false; } } if (!alreadySorted) { Array.Sort(_children, TreeComparison); } } else { // Leaf level trees have no children, only (file) entries. // _children = NoChildren; } _childCount = subcnt; }
/// <summary>Should be called after having called one of the format methods</summary> /// <returns>the patch id calculated for the provided diff.</returns> public virtual ObjectId GetCalulatedPatchId() { return(ObjectId.FromRaw(digest.Digest())); }
/// <summary>Obtain the ObjectId for the entry.</summary> /// <remarks> /// Obtain the ObjectId for the entry. /// <p> /// Using this method to compare ObjectId values between entries is /// inefficient as it causes memory allocation. /// </remarks> /// <returns>object identifier for the entry.</returns> public virtual ObjectId GetObjectId() { return(ObjectId.FromRaw(IdBuffer, IdOffset)); }
/// <summary> /// Read one entire object or delta from the input. /// </summary> private void IndexOneObject() { long pos = Position(); _crc.Reset(); int c = ReadFromInput(); int typeCode = (c >> 4) & 7; long sz = c & 15; int shift = 4; while ((c & 0x80) != 0) { c = ReadFromInput(); sz += (c & 0x7f) << shift; shift += 7; } switch (typeCode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: Whole(typeCode, pos, sz); break; case Constants.OBJ_OFS_DELTA: c = ReadFromInput(); long ofs = c & 127; while ((c & 128) != 0) { ofs += 1; c = ReadFromInput(); ofs <<= 7; ofs += (c & 127); } long pbase = pos - ofs; SkipInflateFromInput(sz); var n = new UnresolvedDelta(pos, (int)_crc.Value); n.Next = _baseByPos.put(pbase, n); _deltaCount++; break; case Constants.OBJ_REF_DELTA: c = FillFromInput(20); _crc.Update(_buffer, c, 20); ObjectId baseId = ObjectId.FromRaw(_buffer, c); Use(20); DeltaChain r = _baseById.Get(baseId); if (r == null) { r = new DeltaChain(baseId); _baseById.Add(r); } SkipInflateFromInput(sz); r.Add(new UnresolvedDelta(pos, (int)_crc.Value)); _deltaCount++; break; default: throw new IOException("Unknown object type " + typeCode + "."); } }
public virtual void TestAbbreviateIsActuallyUnique() { // This test is far more difficult. We have to manually craft // an input that contains collisions at a particular prefix, // but this is computationally difficult. Instead we force an // index file to have what we want. // ObjectId id = Id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba"); byte[] idBuf = ToByteArray(id); IList <PackedObjectInfo> objects = new AList <PackedObjectInfo>(); for (int i = 0; i < 256; i++) { idBuf[9] = unchecked ((byte)i); objects.AddItem(new PackedObjectInfo(ObjectId.FromRaw(idBuf))); } string packName = "pack-" + id.Name; FilePath packDir = new FilePath(((ObjectDirectory)db.ObjectDatabase).GetDirectory (), "pack"); FilePath idxFile = new FilePath(packDir, packName + ".idx"); FilePath packFile = new FilePath(packDir, packName + ".pack"); FileUtils.Mkdir(packDir, true); OutputStream dst = new BufferedOutputStream(new FileOutputStream(idxFile)); try { PackIndexWriter writer = new PackIndexWriterV2(dst); writer.Write(objects, new byte[Constants.OBJECT_ID_LENGTH]); } finally { dst.Close(); } new FileOutputStream(packFile).Close(); NUnit.Framework.Assert.AreEqual(id.Abbreviate(20), reader.Abbreviate(id, 2)); AbbreviatedObjectId abbrev8 = id.Abbreviate(8); ICollection <ObjectId> matches = reader.Resolve(abbrev8); NUnit.Framework.Assert.IsNotNull(matches); NUnit.Framework.Assert.AreEqual(objects.Count, matches.Count); foreach (PackedObjectInfo info in objects) { NUnit.Framework.Assert.IsTrue(matches.Contains(info), "contains " + info.Name); } try { db.Resolve(abbrev8.Name); NUnit.Framework.Assert.Fail("did not throw AmbiguousObjectException"); } catch (AmbiguousObjectException err) { NUnit.Framework.Assert.AreEqual(abbrev8, err.GetAbbreviatedObjectId()); matches = err.GetCandidates(); NUnit.Framework.Assert.IsNotNull(matches); NUnit.Framework.Assert.AreEqual(objects.Count, matches.Count); foreach (PackedObjectInfo info_1 in objects) { NUnit.Framework.Assert.IsTrue(matches.Contains(info_1), "contains " + info_1.Name ); } } NUnit.Framework.Assert.AreEqual(id, db.Resolve(id.Abbreviate(20).Name)); }
private static ObjectId Hash(byte[] rawText) { return(ObjectId.FromRaw(Constants.NewMessageDigest().Digest(rawText))); }
/// <summary> /// Obtain the ObjectId for the entry. /// <para /> /// Using this method to compare ObjectId values between entries is /// inefficient as it causes memory allocation. /// </summary> /// <returns> object identifier for the entry. </returns> public ObjectId getObjectId() { return(ObjectId.FromRaw(idBuffer(), idOffset())); }