mbox series

[v4,0/3] hide-refs: add hook to force hide refs

Message ID pull.1301.v4.git.git.1660575688.gitgitgadget@gmail.com (mailing list archive)
Headers show
Series hide-refs: add hook to force hide refs | expand

Message

Phillip Wood via GitGitGadget Aug. 15, 2022, 3:01 p.m. UTC
Gerrit is implemented by JGit and is known as a centralized workflow system
which supports reference-level access control for repository. If we choose
to work in centralized workflow like what Gerrit provided, reference-level
access control is needed and we might add a reference filter hook hide-refs
to hide the private data.

This hook would be invoked by 'git-receive-pack' and 'git-upload-pack'
during the reference discovery phase, each reference will be filtered with
this hook. The hook executes once with no arguments for each
'git-upload-pack' and 'git-receive-pack' process. Once the hook is invoked,
a version number and server process name ('uploadpack' or 'receive') will
send to it in pkt-line format, followed by a flush-pkt. The hook should
respond with its version number.

During reference discovery phase, each reference will be filtered by this
hook. In the following example, the letter 'G' stands for 'git-receive-pack'
or 'git-upload-pack' and the letter 'H' stands for this hook. The hook
decides if the reference will be hidden or not, it sends result back in
pkt-line format protocol, a response "hide" means the references will hide
to the client and can not fetch its private data even in protocol V2.

            # Version negotiation
            G: PKT-LINE(version=1\0uploadpack)
            G: flush-pkt
            H: PKT-LINE(version=1)
            H: flush-pkt

            # Send reference filter request to hook
            G: PKT-LINE(ref <refname>:<refname_full>)
            G: flush-pkt

            # Receive result from the hook.
            # Case 1: this reference is hidden
            H: PKT-LINE(hide)
            H: flush-pkt

            # Case 2: this reference can be advertised
            H: flush-pkt


To enable the hide-refs hook, we should config hiderefs with force: option,
eg:

            git config --add transfer.hiderefs force:refs/prefix1/
            git config --add uploadpack.hiderefs force:!refs/prefix2/


the hide-refs will be called during reference discovery phase and check each
matched reference, a 'hide' response means the reference will be hidden for
its private data even if allowTipSHA1InWant or allowReachableSHA1InWant are
set to true.

Sun Chao (3):
  hide-refs: add hook to force hide refs
  t1419: add test cases for hide-refs hook
  doc: add documentation for the hide-refs hook

 Documentation/githooks.txt                    |  48 ++++
 Makefile                                      |   1 +
 builtin/receive-pack.c                        |   5 +-
 ls-refs.c                                     |   2 +-
 refs.c                                        | 221 +++++++++++++++++-
 refs.h                                        |   6 +
 serve.c                                       |   2 +
 t/helper/test-hide-refs.c                     | 152 ++++++++++++
 t/helper/test-tool.c                          |   1 +
 t/helper/test-tool.h                          |   1 +
 t/t1419-hide-refs-hook.sh                     | 142 +++++++++++
 t/t1419/common-functions.sh                   |  80 +++++++
 t/t1419/once-0000-abnormal-hide-refs-hook.sh  | 161 +++++++++++++
 ...test-0001-ls-remote-with-hide-refs-hook.sh |  77 ++++++
 ...st-0002-upload-pack-with-hide-refs-hook.sh | 122 ++++++++++
 ...t-0003-receive-pack-with-hide-refs-hook.sh |  87 +++++++
 upload-pack.c                                 |  32 +--
 upload-pack.h                                 |   1 +
 18 files changed, 1111 insertions(+), 30 deletions(-)
 create mode 100644 t/helper/test-hide-refs.c
 create mode 100755 t/t1419-hide-refs-hook.sh
 create mode 100644 t/t1419/common-functions.sh
 create mode 100644 t/t1419/once-0000-abnormal-hide-refs-hook.sh
 create mode 100644 t/t1419/test-0001-ls-remote-with-hide-refs-hook.sh
 create mode 100644 t/t1419/test-0002-upload-pack-with-hide-refs-hook.sh
 create mode 100644 t/t1419/test-0003-receive-pack-with-hide-refs-hook.sh


base-commit: afa70145a25e81faa685dc0b465e52b45d2444bd
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1301%2Fsunchao9%2Frefs_advertise-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1301/sunchao9/refs_advertise-v4
Pull-Request: https://github.com/git/git/pull/1301

Range-diff vs v3:

 1:  01c63ea5fee = 1:  01c63ea5fee hide-refs: add hook to force hide refs
 2:  b8a490cb3df = 2:  b8a490cb3df t1419: add test cases for hide-refs hook
 3:  99755b377f0 ! 3:  8c5ae78de47 doc: add documentation for the hide-refs hook
     @@ Documentation/githooks.txt: If this hook exits with a non-zero status, `git push
      +'git-upload-pack' and 'git-receive-pack' process. Once the hook is invoked,
      +a version number and server process name ('uploadpack' or 'receive') will
      +send to it in pkt-line format, followed by a flush-pkt. The hook should
     -+response with its version number.
     ++respond with its version number.
      +
      +During reference discovery phase, each reference will be filtered by this
      +hook. In the following example, the letter 'G' stands for 'git-receive-pack'
     @@ Documentation/githooks.txt: If this hook exits with a non-zero status, `git push
      +	git config --add uploadpack.hiderefs force:!refs/prefix2/
      +
      +the `hide-refs` will be called during reference discovery phase and
     -+check each matched reference, a 'hide' reponse means the reference will
     -+be hidden for its private data and even the `allowTipSHA1InWant` and
     -+`allowReachableSHA1InWant` is set to true.
     ++check each matched reference, a 'hide' response means the reference will
     ++be hidden for its private data even if `allowTipSHA1InWant` and
     ++`allowReachableSHA1InWant` are set to true.
      +
       [[pre-receive]]
       pre-receive