private void ProcessOnePack(ParsedReceivePack receivePack, GitExecutionResult result) { next.PostPackReceive(receivePack, result); var packFilePath = recoveryFilePathBuilder.GetPathToPackFile(receivePack); if (File.Exists(packFilePath)) { File.Delete(packFilePath); } }
public void PrePackReceive(ParsedReceivePack receivePack) { File.WriteAllText(recoveryFilePathBuilder.GetPathToPackFile(receivePack), JsonConvert.SerializeObject(receivePack)); next.PrePackReceive(receivePack); }
public void PostPackReceive(ParsedReceivePack receivePack, GitExecutionResult result) { ProcessOnePack(receivePack, result); RecoverAll(); }
public void ExecuteServiceByName(string correlationId, string repositoryName, string serviceName, ExecutionOptions options, System.IO.Stream inStream, System.IO.Stream outStream) { ParsedReceivePack receivedPack = null; if (serviceName == "receive-pack" && inStream.Length > 0) { // PARSING RECEIVE-PACK THAT IS OF THE FOLLOWING FORMAT: // (NEW LINES added for ease of reading) // (LLLL is length of the line (expressed in HEX) until next LLLL value) // // LLLL------ REF LINE -----------\0------- OHTER DATA ----------- // LLLL------ REF LINE ---------------- // ... // ... // 0000PACK------- REST OF PACKAGE -------- // var pktLines = new List<ReceivePackPktLine>(); var buff1 = new byte[1]; var buff4 = new byte[4]; var buff20 = new byte[20]; var buff16K = new byte[1024 * 16]; while (true) { ReadStream(inStream, buff4); var len = Convert.ToInt32(Encoding.UTF8.GetString(buff4), 16); if (len == 0) { break; } len = len - buff4.Length; var accum = new LinkedList<byte>(); while (len > 0) { len -= 1; ReadStream(inStream, buff1); if (buff1[0] == 0) { break; } accum.AddLast(buff1[0]); } if (len > 0) { inStream.Seek(len, SeekOrigin.Current); } var pktLine = Encoding.UTF8.GetString(accum.ToArray()); var pktLineItems = pktLine.Split(' '); var fromCommit = pktLineItems[0]; var toCommit = pktLineItems[1]; var refName = pktLineItems[2]; pktLines.Add(new ReceivePackPktLine(fromCommit, toCommit, refName)); } // parse PACK contents var packCommits = new List<ReceivePackCommit>(); // PACK format // https://www.kernel.org/pub/software/scm/git/docs/technical/pack-format.html // http://schacon.github.io/gitbook/7_the_packfile.html if (inStream.Position < inStream.Length) { ReadStream(inStream, buff4); if (Encoding.UTF8.GetString(buff4) != "PACK") { throw new Exception("Unexpected receive-pack 'PACK' content."); } ReadStream(inStream, buff4); Array.Reverse(buff4); var versionNum = BitConverter.ToInt32(buff4, 0); ReadStream(inStream, buff4); Array.Reverse(buff4); var numObjects = BitConverter.ToInt32(buff4, 0); while (numObjects > 0) { numObjects -= 1; ReadStream(inStream, buff1); var type = (GIT_OBJ_TYPE)((buff1[0] >> 4) & 7); long len = buff1[0] & 15; var shiftAmount = 4; while ((buff1[0] >> 7) == 1) { ReadStream(inStream, buff1); len = len | ((long)(buff1[0] & 127) << shiftAmount); shiftAmount += 7; } if (type == GIT_OBJ_TYPE.OBJ_REF_DELTA) { // read ref name ReadStream(inStream, buff20); } if (type == GIT_OBJ_TYPE.OBJ_OFS_DELTA) { // read negative offset ReadStream(inStream, buff1); while ((buff1[0] >> 7) == 1) { ReadStream(inStream, buff1); } } var origPosition = inStream.Position; long offsetVal = 0; using (var zlibStream = new ZlibStream(inStream, CompressionMode.Decompress, true)) { // read compressed data max 16KB at a time var readRemaining = len; do { var bytesUncompressed = zlibStream.Read(buff16K, 0, buff16K.Length); readRemaining -= bytesUncompressed; } while (readRemaining > 0); if (type == GIT_OBJ_TYPE.OBJ_COMMIT) { var parsedCommit = ParseCommitDetails(buff16K, len); packCommits.Add(parsedCommit); } offsetVal = zlibStream.TotalIn; } // move back position a bit because ZLibStream reads more than needed for inflating inStream.Seek(origPosition + offsetVal, SeekOrigin.Begin); } } // ------------------- var user = HttpContext.Current.User.Id(); receivedPack = new ParsedReceivePack(correlationId, repositoryName, pktLines, user, DateTime.Now, packCommits); inStream.Seek(0, SeekOrigin.Begin); receivePackHandler.PrePackReceive(receivedPack); } GitExecutionResult execResult = null; using (var capturedOutputStream = new MemoryStream()) { gitService.ExecuteServiceByName(correlationId, repositoryName, serviceName, options, inStream, new ReplicatingStream(outStream, capturedOutputStream)); // parse captured output capturedOutputStream.Seek(0, SeekOrigin.Begin); execResult = resultParser.ParseResult(capturedOutputStream); } if(receivedPack != null) { receivePackHandler.PostPackReceive(receivedPack, execResult); } }