A major update to Git’s Wire protocol is here – Git Protocol version 2
Git protocol version 2 was announced just yesterday, it is the major update to Git’s wire protocol which controls how clones, fetches and pushes requests are communicated between both clients and the servers. This major update covers the removal of one of the most inefficient parts of Git protocol version 1 and fixes extensibility bottleneck thus unblocking the path to more wire protocol improvements in future.
The major improvements in this update are:
- Server-side filtering of references
- Simplifies client handling of the HTTP transport
- Easy extensibility of new features
These improvements were majorly the motive behind this new protocol especially to enable server-side filtering of references, before version 2 servers responded to all fetch commands with initial reference, listing all references in the complete repository. This complete listing was sent even when the client only cares about updating a single branch which listens out to be quite absurd and unnecessary.
In case of a big repository containing hundreds of thousands of references, the server could end up sending tens of MB of data which is unnecessary and which would eventually be ignored. This typically dominates time and bandwidth resource during a simple fetch request, especially when you are updating a branch or even when you are just checking if you are up-to-date.
Google recently rolled out support for protocol version 2 and have seen a top-notch performance improvement of up to 3 times for non-operational fetches of a single branch on repositories containing more than 500 thousand references.
The Git project has tried on a number of occasions over the years to either limit the initial ref advertisement or move to a new protocol altogether but continued to run into two problems:
- The initial request is rigid and does not include a field that could be used to request that new servers modify their response without breaking compatibility with existing servers and
- Error handling is not well enough defined to allow safely using a new protocol that existing servers do not understand with a quick fallback to the old protocol. To migrate to a new protocol version, we needed to find a side channel which existing servers would ignore but could be used to safely communicate with newer servers.
Now, in every case, a client can issue a request to use version 2, using a transport-specific side channel, and version 2 servers can respond using the new protocol while older servers will ignore the side channel and just respond with an earlier ref advertisement. By placing version information behind a second NUL byte we can skirt around both the infinite loop bug and the explicit disallow of extra arguments besides hostname. Only newer servers will know to look for additional information hidden behind two NUL bytes and older servers won’t croak.
For complete info on the new update and for knowing all about Git protocol version 2 in detail refer here
Source: Google Open Source Blog