{
    "mode": "man",
    "parameter": "git-receive-pack",
    "section": "1",
    "url": "https://www.chedong.com/phpMan.php/man/git-receive-pack/1/json",
    "generated": "2026-05-30T05:14:57Z",
    "synopsis": "git-receive-pack <directory>",
    "sections": {
        "NAME": {
            "content": "git-receive-pack - Receive what is pushed into the repository\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "git-receive-pack <directory>\n\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "Invoked by git send-pack and updates the repository with the information fed from the remote\nend.\n\nThis command is usually not invoked directly by the end user. The UI for the protocol is on\nthe git send-pack side, and the program pair is meant to be used to push updates to remote\nrepository. For pull operations, see git-fetch-pack(1).\n\nThe command allows for creation and fast-forwarding of sha1 refs (heads/tags) on the remote\nend (strictly speaking, it is the local end git-receive-pack runs, but to the user who is\nsitting at the send-pack end, it is updating the remote. Confused?)\n\nThere are other real-world examples of using update and post-update hooks found in the\nDocumentation/howto directory.\n\ngit-receive-pack honours the receive.denyNonFastForwards config option, which tells it if\nupdates to a ref should be denied if they are not fast-forwards.\n\nA number of other receive.* config options are available to tweak its behavior, see git-\nconfig(1).\n",
            "subsections": []
        },
        "OPTIONS": {
            "content": "<directory>\nThe repository to sync into.\n",
            "subsections": [
                {
                    "name": "--http-backend-info-refs",
                    "content": "Used by git-http-backend(1) to serve up $GITURL/info/refs?service=git-receive-pack\nrequests. See --http-backend-info-refs in git-upload-pack(1).\n",
                    "long": "--http-backend-info-refs"
                }
            ]
        },
        "PRE-RECEIVE HOOK": {
            "content": "Before any ref is updated, if $GITDIR/hooks/pre-receive file exists and is executable, it\nwill be invoked once with no parameters. The standard input of the hook will be one line per\nref to be updated:\n\nsha1-old SP sha1-new SP refname LF\n\nThe refname value is relative to $GITDIR; e.g. for the master head this is\n\"refs/heads/master\". The two sha1 values before each refname are the object names for the\nrefname before and after the update. Refs to be created will have sha1-old equal to 0{40},\nwhile refs to be deleted will have sha1-new equal to 0{40}, otherwise sha1-old and sha1-new\nshould be valid objects in the repository.\n\nWhen accepting a signed push (see git-push(1)), the signed push certificate is stored in a\nblob and an environment variable GITPUSHCERT can be consulted for its object name. See the\ndescription of post-receive hook for an example. In addition, the certificate is verified\nusing GPG and the result is exported with the following environment variables:\n\nGITPUSHCERTSIGNER\nThe name and the e-mail address of the owner of the key that signed the push certificate.\n\nGITPUSHCERTKEY\nThe GPG key ID of the key that signed the push certificate.\n\nGITPUSHCERTSTATUS\nThe status of GPG verification of the push certificate, using the same mnemonic as used\nin %G?  format of git log family of commands (see git-log(1)).\n\nGITPUSHCERTNONCE\nThe nonce string the process asked the signer to include in the push certificate. If this\ndoes not match the value recorded on the \"nonce\" header in the push certificate, it may\nindicate that the certificate is a valid one that is being replayed from a separate \"git\npush\" session.\n\nGITPUSHCERTNONCESTATUS\n\nUNSOLICITED\n\"git push --signed\" sent a nonce when we did not ask it to send one.\n\nMISSING\n\"git push --signed\" did not send any nonce header.\n\nBAD\n\"git push --signed\" sent a bogus nonce.\n\nOK\n\"git push --signed\" sent the nonce we asked it to send.\n\nSLOP\n\"git push --signed\" sent a nonce different from what we asked it to send now, but in\na previous session. See GITPUSHCERTNONCESLOP environment variable.\n\nGITPUSHCERTNONCESLOP\n\"git push --signed\" sent a nonce different from what we asked it to send now, but in a\ndifferent session whose starting time is different by this many seconds from the current\nsession. Only meaningful when GITPUSHCERTNONCESTATUS says SLOP. Also read about\nreceive.certNonceSlop variable in git-config(1).\n\nThis hook is called before any refname is updated and before any fast-forward checks are\nperformed.\n\nIf the pre-receive hook exits with a non-zero exit status no updates will be performed, and\nthe update, post-receive and post-update hooks will not be invoked either. This can be useful\nto quickly bail out if the update is not to be supported.\n\nSee the notes on the quarantine environment below.\n",
            "subsections": []
        },
        "UPDATE HOOK": {
            "content": "Before each ref is updated, if $GITDIR/hooks/update file exists and is executable, it is\ninvoked once per ref, with three parameters:\n\n$GITDIR/hooks/update refname sha1-old sha1-new\n\nThe refname parameter is relative to $GITDIR; e.g. for the master head this is\n\"refs/heads/master\". The two sha1 arguments are the object names for the refname before and\nafter the update. Note that the hook is called before the refname is updated, so either\nsha1-old is 0{40} (meaning there is no such ref yet), or it should match what is recorded in\nrefname.\n\nThe hook should exit with non-zero status if it wants to disallow updating the named ref.\nOtherwise it should exit with zero.\n\nSuccessful execution (a zero exit status) of this hook does not ensure the ref will actually\nbe updated, it is only a prerequisite. As such it is not a good idea to send notices (e.g.\nemail) from this hook. Consider using the post-receive hook instead.\n",
            "subsections": []
        },
        "POST-RECEIVE HOOK": {
            "content": "After all refs were updated (or attempted to be updated), if any ref update was successful,\nand if $GITDIR/hooks/post-receive file exists and is executable, it will be invoked once\nwith no parameters. The standard input of the hook will be one line for each successfully\nupdated ref:\n\nsha1-old SP sha1-new SP refname LF\n\nThe refname value is relative to $GITDIR; e.g. for the master head this is\n\"refs/heads/master\". The two sha1 values before each refname are the object names for the\nrefname before and after the update. Refs that were created will have sha1-old equal to\n0{40}, while refs that were deleted will have sha1-new equal to 0{40}, otherwise sha1-old and\nsha1-new should be valid objects in the repository.\n\nThe GITPUSHCERT* environment variables can be inspected, just as in pre-receive hook, after\naccepting a signed push.\n\nUsing this hook, it is easy to generate mails describing the updates to the repository. This\nexample script sends one mail message per ref listing the commits pushed to the repository,\nand logs the push certificates of signed pushes with good signatures to a logger service:\n\n#!/bin/sh\n# mail out commit update information.\nwhile read oval nval ref\ndo\nif expr \"$oval\" : '0*$' >/dev/null\nthen\necho \"Created a new ref, with the following commits:\"\ngit rev-list --pretty \"$nval\"\nelse\necho \"New commits:\"\ngit rev-list --pretty \"$nval\" \"^$oval\"\nfi |\nmail -s \"Changes to ref $ref\" commit-list@mydomain\ndone\n# log signed push certificate, if any\nif test -n \"${GITPUSHCERT-}\" && test ${GITPUSHCERTSTATUS} = G\nthen\n(\necho expected nonce is ${GITPUSHNONCE}\ngit cat-file blob ${GITPUSHCERT}\n) | mail -s \"push certificate from $GITPUSHCERTSIGNER\" push-log@mydomain\nfi\nexit 0\n\n\nThe exit code from this hook invocation is ignored, however a non-zero exit code will\ngenerate an error message.\n\nNote that it is possible for refname to not have sha1-new when this hook runs. This can\neasily occur if another user modifies the ref after it was updated by git-receive-pack, but\nbefore the hook was able to evaluate it. It is recommended that hooks rely on sha1-new rather\nthan the current value of refname.\n",
            "subsections": []
        },
        "POST-UPDATE HOOK": {
            "content": "After all other processing, if at least one ref was updated, and if\n$GITDIR/hooks/post-update file exists and is executable, then post-update will be called\nwith the list of refs that have been updated. This can be used to implement any repository\nwide cleanup tasks.\n\nThe exit code from this hook invocation is ignored; the only thing left for git-receive-pack\nto do at that point is to exit itself anyway.\n\nThis hook can be used, for example, to run git update-server-info if the repository is packed\nand is served via a dumb transport.\n\n#!/bin/sh\nexec git update-server-info\n\n",
            "subsections": []
        },
        "QUARANTINE ENVIRONMENT": {
            "content": "When receive-pack takes in objects, they are placed into a temporary \"quarantine\" directory\nwithin the $GITDIR/objects directory and migrated into the main object store only after the\npre-receive hook has completed. If the push fails before then, the temporary directory is\nremoved entirely.\n\nThis has a few user-visible effects and caveats:\n\n1. Pushes which fail due to problems with the incoming pack, missing objects, or due to the\npre-receive hook will not leave any on-disk data. This is usually helpful to prevent\nrepeated failed pushes from filling up your disk, but can make debugging more\nchallenging.\n\n2. Any objects created by the pre-receive hook will be created in the quarantine directory\n(and migrated only if it succeeds).\n\n3. The pre-receive hook MUST NOT update any refs to point to quarantined objects. Other\nprograms accessing the repository will not be able to see the objects (and if the\npre-receive hook fails, those refs would become corrupted). For safety, any ref updates\nfrom within pre-receive are automatically rejected.\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "git-send-pack(1), gitnamespaces(7)\n",
            "subsections": []
        },
        "GIT": {
            "content": "Part of the git(1) suite\n\n\n\nGit 2.34.1                                   02/26/2026                          GIT-RECEIVE-PACK(1)",
            "subsections": []
        }
    },
    "summary": "git-receive-pack - Receive what is pushed into the repository",
    "flags": [
        {
            "flag": "",
            "long": "--http-backend-info-refs",
            "arg": null,
            "description": "Used by git-http-backend(1) to serve up $GITURL/info/refs?service=git-receive-pack requests. See --http-backend-info-refs in git-upload-pack(1)."
        }
    ],
    "examples": [],
    "see_also": [
        {
            "name": "git-send-pack",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/git-send-pack/1/json"
        },
        {
            "name": "gitnamespaces",
            "section": "7",
            "url": "https://www.chedong.com/phpMan.php/man/gitnamespaces/7/json"
        }
    ]
}