private string EnableCapabilities() { var line = new StringBuilder(); if (_includeTags) { _includeTags = wantCapability(line, OPTION_INCLUDE_TAG); } if (_allowOfsDelta) { wantCapability(line, OPTION_OFS_DELTA); } if (wantCapability(line, OPTION_MULTI_ACK_DETAILED)) { _multiAck = MultiAck.DETAILED; } else if (wantCapability(line, OPTION_MULTI_ACK)) { _multiAck = MultiAck.CONTINUE; } else { _multiAck = MultiAck.OFF; } if (_thinPack) { _thinPack = wantCapability(line, OPTION_THIN_PACK); } if (wantCapability(line, OPTION_SIDE_BAND_64K)) { _sideband = true; } else if (wantCapability(line, OPTION_SIDE_BAND)) { _sideband = true; } return(line.ToString()); }
private void Negotiate(ProgressMonitor monitor) { var ackId = new MutableObjectId(); int resultsPending = 0; int havesSent = 0; int havesSinceLastContinue = 0; bool receivedContinue = false; bool receivedAck = false; NegotiateBegin(); for (; ; ) { RevCommit c = _walk.next(); if (c == null) { goto END_SEND_HAVES; } pckOut.WriteString("have " + c.getId().Name + "\n"); havesSent++; havesSinceLastContinue++; if ((31 & havesSent) != 0) { continue; } if (monitor.IsCancelled) throw new CancelledException(); pckOut.End(); resultsPending++; if (havesSent == 32) { continue; } for (; ; ) { PacketLineIn.AckNackResult anr = pckIn.readACK(ackId); switch (anr) { case PacketLineIn.AckNackResult.NAK: // More have lines are necessary to compute the // pack on the remote side. Keep doing that. resultsPending--; goto END_READ_RESULT; case PacketLineIn.AckNackResult.ACK: // The remote side is happy and knows exactly what // to send us. There is no further negotiation and // we can break out immediately. _multiAck = MultiAck.OFF; resultsPending = 0; receivedAck = true; goto END_SEND_HAVES; case PacketLineIn.AckNackResult.ACK_CONTINUE: case PacketLineIn.AckNackResult.ACK_COMMON: case PacketLineIn.AckNackResult.ACK_READY: // The server knows this commit (ackId). We don't // need to send any further along its ancestry, but // we need to continue to talk about other parts of // our local history. MarkCommon(_walk.parseAny(ackId)); receivedAck = true; receivedContinue = true; havesSinceLastContinue = 0; break; } if (monitor.IsCancelled) throw new CancelledException(); } END_READ_RESULT: if (receivedContinue && havesSinceLastContinue > MAX_HAVES) { break; } } END_SEND_HAVES: if (monitor.IsCancelled) throw new CancelledException(); pckOut.WriteString("done\n"); pckOut.Flush(); if (!receivedAck) { _multiAck = MultiAck.OFF; resultsPending++; } while (resultsPending > 0 || _multiAck != MultiAck.OFF) { PacketLineIn.AckNackResult anr = pckIn.readACK(ackId); resultsPending--; switch (anr) { case PacketLineIn.AckNackResult.NAK: // A NAK is a response to an end we queued earlier // we eat it and look for another ACK/NAK message. // break; case PacketLineIn.AckNackResult.ACK: // A solitary ACK at this point means the remote won't // speak anymore, but is going to send us a pack now. // goto END_READ_RESULT_2; case PacketLineIn.AckNackResult.ACK_CONTINUE: case PacketLineIn.AckNackResult.ACK_COMMON: case PacketLineIn.AckNackResult.ACK_READY: // We will expect a normal ACK to break out of the loop. // _multiAck = MultiAck.CONTINUE; break; } if (monitor.IsCancelled) throw new CancelledException(); } END_READ_RESULT_2: ; }
private string EnableCapabilities() { var line = new StringBuilder(); if (_includeTags) _includeTags = wantCapability(line, OPTION_INCLUDE_TAG); if (_allowOfsDelta) wantCapability(line, OPTION_OFS_DELTA); if (wantCapability(line, OPTION_MULTI_ACK_DETAILED)) _multiAck = MultiAck.DETAILED; else if (wantCapability(line, OPTION_MULTI_ACK)) _multiAck = MultiAck.CONTINUE; else _multiAck = MultiAck.OFF; if (_thinPack) _thinPack = wantCapability(line, OPTION_THIN_PACK); if (wantCapability(line, OPTION_SIDE_BAND_64K)) _sideband = true; else if (wantCapability(line, OPTION_SIDE_BAND)) _sideband = true; return line.ToString(); }
private void Negotiate(ProgressMonitor monitor) { var ackId = new MutableObjectId(); int resultsPending = 0; int havesSent = 0; int havesSinceLastContinue = 0; bool receivedContinue = false; bool receivedAck = false; NegotiateBegin(); for (; ;) { RevCommit c = _walk.next(); if (c == null) { goto END_SEND_HAVES; } pckOut.WriteString("have " + c.getId().Name + "\n"); havesSent++; havesSinceLastContinue++; if ((31 & havesSent) != 0) { // We group the have lines into blocks of 32, each marked // with a flush (aka end). This one is within a block so // continue with another have line. // continue; } if (monitor.IsCancelled) { throw new CancelledException(); } pckOut.End(); resultsPending++; // Each end will cause a result to come back. if (havesSent == 32) { // On the first block we race ahead and try to send // more of the second block while waiting for the // remote to respond to our first block request. // This keeps us one block ahead of the peer. // continue; } for (; ;) { PacketLineIn.AckNackResult anr = pckIn.readACK(ackId); switch (anr) { case PacketLineIn.AckNackResult.NAK: // More have lines are necessary to compute the // pack on the remote side. Keep doing that. resultsPending--; goto END_READ_RESULT; case PacketLineIn.AckNackResult.ACK: // The remote side is happy and knows exactly what // to send us. There is no further negotiation and // we can break out immediately. _multiAck = MultiAck.OFF; resultsPending = 0; receivedAck = true; goto END_SEND_HAVES; case PacketLineIn.AckNackResult.ACK_CONTINUE: case PacketLineIn.AckNackResult.ACK_COMMON: case PacketLineIn.AckNackResult.ACK_READY: // The server knows this commit (ackId). We don't // need to send any further along its ancestry, but // we need to continue to talk about other parts of // our local history. MarkCommon(_walk.parseAny(ackId)); receivedAck = true; receivedContinue = true; havesSinceLastContinue = 0; break; } if (monitor.IsCancelled) { throw new CancelledException(); } } END_READ_RESULT: if (receivedContinue && havesSinceLastContinue > MAX_HAVES) { // Our history must be really different from the remote's. // We just sent a whole slew of have lines, and it did not // recognize any of them. Avoid sending our entire history // to them by giving up early. // break; } } END_SEND_HAVES: // Tell the remote side we have run out of things to talk about. // if (monitor.IsCancelled) { throw new CancelledException(); } pckOut.WriteString("done\n"); pckOut.Flush(); if (!receivedAck) { // Apparently if we have never received an ACK earlier // there is one more result expected from the done we // just sent to the remote. // _multiAck = MultiAck.OFF; resultsPending++; } while (resultsPending > 0 || _multiAck != MultiAck.OFF) { PacketLineIn.AckNackResult anr = pckIn.readACK(ackId); resultsPending--; switch (anr) { case PacketLineIn.AckNackResult.NAK: // A NAK is a response to an end we queued earlier // we eat it and look for another ACK/NAK message. // break; case PacketLineIn.AckNackResult.ACK: // A solitary ACK at this point means the remote won't // speak anymore, but is going to send us a pack now. // goto END_READ_RESULT_2; case PacketLineIn.AckNackResult.ACK_CONTINUE: case PacketLineIn.AckNackResult.ACK_COMMON: case PacketLineIn.AckNackResult.ACK_READY: // We will expect a normal ACK to break out of the loop. // _multiAck = MultiAck.CONTINUE; break; } if (monitor.IsCancelled) { throw new CancelledException(); } } END_READ_RESULT_2: ; }