2

To understand more about git, I try to write a very simple Git server using Python and Flask. I registered an endpoint and redirect the calls to git-http-backend. So far a simple pull works fine. Also simple/small pushes go through.

Now I stumbled over git-upload-pack and git-receive-pack, and I am wondering why or when I would need them? Are they used by git-http-backend in the background? I am not sure if I additionally have to support these commands too.

P.S. I try to wrap my head around SmartHTTP. Does it mean Full-Duplex? Or what is meant to be SmartHTTP vs Dumb? I don't exactly understand what is supposed to be smart if it also just receives and sends/pushes a file?

Daniel Stephens
  • 2,371
  • 8
  • 34
  • 86
  • This is too broad and vague. The g-h-b docs tell you it invokes upload-pack and receive-pack in response to requests over the wire from git clients, what does "why or when I would need them" refer to? g-h-b implements a command shell, running commands like upload-pack and receive-pack in response to client requests over the [git "smart" http protocol](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols). – jthill Jun 13 '20 at 17:22
  • 1
    You don't need anything more from those commands unless you have some need to run them beyond what you can ask g-h-b for. This is Git: basically *anything* you can do with the commands could be legit, the question is "what do you need?". – jthill Jun 13 '20 at 17:23

1 Answers1

6

I presented the smart http protocol in 2011 with Git 1.6.6.

But git-receive-pack and git-upload-pack would be involve even without HTTP, with for instance SSH URL.

I have to know about them because I often install Git on servers where I am not root.
That means the executable git is not in /usr/bin, but in /my/path/to/git/usr/bin

And whenever I do a git clone on my PC from that server (or a git ls-remote), I get:

bash: git-upload-pack: command not found

If I try a git push from my PC to that server:

bash: git-receive-pack: command not found

That is because, when you look at the usr/bin folder of a Git installation, you would see:

-rwxr-xr-x. 1 <auser> <agroup> 3.0M Dec 13  2019 git*
drwxr-xr-x. 5 <auser> <agroup>   45 Jun  8 14:35 ../
drwxr-xr-x. 2 <auser> <agroup>  107 Jun  8 14:35 ./
lrwxrwxrwx. 1 <auser> <agroup>    3 Jun  8 14:35 git-receive-pack -> git*
lrwxrwxrwx. 1 <auser> <agroup>    3 Jun  8 14:35 git-upload-pack -> git*
lrwxrwxrwx. 1 <auser> <agroup>    3 Jun  8 14:35 git-upload-archive -> git*

Meaning git-receive-pack and git-upload-pack are just symlink to git itself(!)

But, because of their naming convention (git-xxx), they are actually calling git with the command receive-pack or upload-pack.
(incidently, that works for any script git-xxx in your $PATH: you can then type git xxx, that will call your git-xxx script)

For my custom Git installation to work, I had to implement git-xxx wrappers:

Example:

/my/path/to/git/git-receive-pack:

#!/bin/bash

source "setenv"
"/my/path/to/git/usr/bin/git" receive-pack "$@"

With setenv setting the right PATH:

export PERLLIB=/my/path/to/git/usr/share/perl5/vendor_perl:/my/path/to/git/opt/endpoint/perl-5.22.0/share/perl5/vendor_perl
export PATH=/my/path/to/git/usr/bin:/my/path/to/git/usr/libexec/git-core:$PATH
export LD_LIBRARY_PATH=/project/${USER}/refer/pcres/current/usr/lib64

And on the client (PC) side, I need, for a remote using the server with custom Git installation, to add:

git config --global remote.origin.uploadpack /my/path/to/git/git-upload-pack
git config --global remote.origin.receivepack=/my/path/to/git/git-receive-pack
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250