Documentation / technical / send-pack-pipeline.txton commit Fix formatting for urls section of fetch, pull, and push manpages (63c97ce)
   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