1git-send-pack 2============= 3 4Overall operation 5----------------- 6 7. Connects to the remote side and invokes git-receive-pack. 8 9. Learns what refs the remote has and what commit they point at. 10 Matches them to the refspecs we are pushing. 11 12. Checks if there are non-fast-forwards. Unlike fetch-pack, 13 the repository send-pack runs in is supposed to be a superset 14 of the recipient in fast-forward cases, so there is no need 15 for want/have exchanges, and fast-forward check can be done 16 locally. Tell the result to the other end. 17 18. Calls pack_objects() which generates a packfile and sends it 19 over to the other end. 20 21. If the remote side is new enough (v1.1.0 or later), wait for 22 the unpack and hook status from the other end. 23 24. Exit with appropriate error codes. 25 26 27Pack_objects pipeline 28--------------------- 29 30This function gets one file descriptor (`out`) which is either a 31socket (over the network) or a pipe (local). What's written to 32this fd goes to git-receive-pack to be unpacked. 33 34 send-pack ---> fd ---> receive-pack 35 36It somehow forks once, but does not wait for it. I am not sure 37why. 38 39The forked child calls rev_list_generate() with that file 40descriptor (while the parent closes `out` -- the child will be 41the one that writes the packfile to the other end). 42 43 send-pack 44 | 45 rev-list-generate ---> fd ---> receive-pack 46 47 48Then rev-list-generate forks after creates a pipe; the child 49will become a pipeline "rev-list --stdin | pack-objects", which 50is the rev_list() function, while the parent feeds that pipeline 51the list of refs. 52 53 send-pack 54 | 55 rev-list-generate ---> fd ---> receive-pack 56 | ^ (pipe) 57 v | 58 rev-list 59 60The child process, before calling rev-list, rearranges the file 61descriptors: 62 63. what it reads from rev-list-generate via pipe becomes the 64 stdin; this is to feed the upstream of the pipeline which will 65 be git-rev-list process. 66 67. what it writes to its stdout goes to the fd connected to 68 receive-pack. 69 70On the other hand, the parent process, before starting to feed 71the child pipeline, closes the reading side of the pipe and fd 72to receive-pack. 73 74 send-pack 75 | 76 rev-list-generate 77 | 78 v [0] 79 rev-list [1] ---> receive-pack 80 81The parent then writes to the pipe and later closes it. There 82is a commented out waitpid to wait for the rev-list side before 83it exits, I again do not understand why. 84 85The rev-list function further sets up a pipe and forks to run 86git-rev-list piped to git-pack-objects. The child side, before 87exec'ing git-pack-objects, rearranges the file descriptors: 88 89. what it reads from the pipe becomes the stdin; this gets the 90 list of objects from the git-rev-list process. 91 92. its stdout is already connected to receive-pack, so what it 93 generates goes there. 94 95The parent process arranges its file descriptors before exec'ing 96git-rev-list: 97 98. its stdout is sent to the pipe to feed git-pack-objects. 99 100. its stdin is already connected to rev-list-generate and will 101 read the set of refs from it. 102 103 104 send-pack 105 | 106 rev-list-generate 107 | 108 v [0] 109 git-rev-list [1] ---> [0] git-pack-objects [1] ---> receive-pack 110 111 112