Git:push 命令

Nov 18, 2021




1git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
2	   [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
3	   [-u | --set-upstream] [-o <string> | --push-option=<string>]
4	   [--[no-]signed|--signed=(true|false|if-asked)]
5	   [--force-with-lease[=<refname>[:<expect>]] [--force-if-includes]]
6	   [--no-verify] [<repository> [<refspec>…​]]

git-push - Update remote refs along with associated objects



当在命令行中没有指定 <repository> 参数时,使用当前分支的 branch.*.remote 配置的值来决定推送到那个远程位置。 如果这个配置没有指定任何值,默认使用 origin

当在命令行中没有指定 <refspec>... 参数或 --all, --mirror, --tags 参数时,使用 remote.*.push 配置的值来查找默认的 <refspec>. 如果这个配置的值没有找到,使用 push.default 的值。


  • <repository>

作为推操作目标的“远程”仓库,这个参数可以是一个 URL 或者远程的名称

  • <refspec>

指定使用哪些源对象(source object)更新远程目前引用(destionation refs)。 <refspec> 的格式是一个可选则 +,紧跟着是源对象 <src>,跟着是一个 :, 跟着是目标引用 <dst>

<src> 通常是你想推送到远程的分支的名称,它也可以是任意的 SHA-1 expression, 例如 master~4HEAD.

<dst> 告诉 Git 当前推送操作想要更新的远程仓库的引用。 这里不能使用任意的 SHA-1 expression, 必须使用实际的命名引用。 If git push [<repository>] without any <refspec> argument is set to update some ref at the destination with <src> with remote.<repository>.push configuration variable, :<dst> part can be omitted—-such a push will update a ref that <src> normally updates without any <refspec> on the command line. Otherwise, missing :<dst> means to update the same ref as the <src>.

如果 <dst> 没有以 refs/ 开头(例如,refs/heads/master), 我们将会根据 <src> 的类型来判断远程引用信息。 - 如果 <dst> 没有二意的解析为一个远程仓库的引用,那么推送到该引用 - 如果 <src> 解析为一个引用,该引用以 refs/heads/ 或者 resfs/tags/ 开头,那么将该作为 <dst> 的前缀添加到 <dst>。 - 其他情况,认为出错了

<src> 指定的引用被用于更新 <dst> 指定的远程引用。 这是否被允许取决于在 refs/*<dst>引用存在的位置,下面将详细描述,在这些部分中,“更新”意味着除删除之外的任何修改,后面的几个部分将以不同的方式处理。

refs/heads/* 名字空间只会接受提交对象(commit objects), 和更新,当这些更新可以被快速合并(fast-forwarded)。

refs/tags/* 名字空间将接受任何类型的对象(提交(commit)、树(tree)和 blobs),并且拒绝对它们的任何更新。

可以推送任何类型的对象到 refs/{tags,heads}/*之外的名字空间。 对于 tags 和 heads 的推送会被是为对 refs/heads/* 的推送,以便判断是否允许当前推送。

I.e. a fast-forward of commits and tags outside refs/{tags,heads}/* is allowed, even in cases where what’s being fast-forwarded is not a commit, but a tag object which happens to point to a new commit which is a fast-forward of the commit the last tag (or commit) it’s replacing. Replacing a tag with an entirely different tag is also allowed, if it points to the same commit, as well as pushing a peeled tag, i.e. pushing the commit that existing tag object points to, or a new tag object which an existing commit points to.

Tree and blob objects outside of refs/{tags,heads}/* will be treated the same way as if they were inside refs/tags/*, any update of them will be rejected.

All of the rules described above about what’s not allowed as an update can be overridden by adding an the optional leading + to a refspec (or using --force command line option). The only exception to this is that no amount of forcing will make the refs/heads/* namespace accept a non-commit object. Hooks and configuration can also override or amend these rules, see e.g. receive.denyNonFastForwards in git-config[1] and pre-receive and update in githooks[5].

Pushing an empty <src> allows you to delete the <dst> ref from the remote repository. Deletions are always accepted without a leading + in the refspec (or --force), except when forbidden by configuration or hooks. See receive.denyDeletes in git-config[1] and pre-receive and update in githooks[5].

The special refspec : (or +: to allow non-fast-forward updates) directs Git to push “matching” branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side.

tag <tag> means the same as refs/tags/<tag>:refs/tags/<tag>.

  • --repo=<repository>

此选项等价于 <repository> 参数。 如果两个参数都指定了,则命令行参数优先。

  • -u
  • --set-upstream

For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less git-pull[1] and other commands. For more information, see branch.<name>.merge in git-config[1].

  • --[no-]thin

These options are passed to git-send-pack[1]. A thin transfer significantly reduces the amount of sent data when the sender and receiver share many of the same objects in common. The default is --thin

  • -q
  • --quiet

禁止所有输出,包括已更新的索引的列表,除非发生错误。 不报告进度状态到标准错误流。

  • -v
  • --verbose


  • -progress

当附属于某个终端时, 进度状态默认在标准错误流上输出。 即使标准错误流没有指向终端,这个标志也会强制执行进度状态。

  • --no-recurse-submodules
  • --recurse-submodules=check|on-demand|only|no

May be used to make sure all submodule commits used by the revisions to be pushed are available on a remote-tracking branch. If check is used Git will verify that all submodule commits that changed in the revisions to be pushed are available on at least one remote of the submodule. If any commits are missing the push will be aborted and exit with non-zero status. If on-demand is used all submodules that changed in the revisions to be pushed will be pushed. If on-demand was not able to push all necessary revisions it will also be aborted and exit with non-zero status. If only is used all submodules will be recursively pushed while the superproject is left unpushed. A value of no or using --no-recurse-submodules can be used to override the push.recurseSubmodules configuration variable when no submodule recursion is required.

  • --[no-]verify

Toggle the pre-push hook. 默认值是 --verify, 这样 hook 可以阻止当前推送操作。 当指定 --no-verify, hook 将被忽略。

  • -4
  • --ipv4


  • -6
  • --ipv6