名称
git-push - 更新远程引用以及关联的对象
概要
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
[--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
[-u | --set-upstream] [--push-option=<string>]
[--[no-]signed|--signed=(true|false|if-asked)]
[--force-with-lease[=<refname>[:<expect>]]]
[--no-verify] [<repository> [<refspec>…]]
[--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
[--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
[-u | --set-upstream] [--push-option=<string>]
[--[no-]signed|--signed=(true|false|if-asked)]
[--force-with-lease[=<refname>[:<expect>]]]
[--no-verify] [<repository> [<refspec>…]]
描述
使用本地引用更新远程引用,同时发送完成给定引用所需的对象。
你可以通过设置钩子来让有趣的事情发生在仓库中。请参阅git-receive-pack(1)的文档。
当命令行没有指定将<repository>参数推 branch.*.remote送到何处时,将查阅当前分支的配置以确定推送的位置。如果配置丢失,则默认为原点。
当在命令行中没有指定,可以把什么<refspec>... 参数或--all,--mirror,--tags选项,该命令将查找默认<refspec>通过咨询remote.*.push配置,如果没有找到它,荣誉push.default配置来决定推什么(见的git-配置(1)为的意思push.default)。
如果命令行和配置都未指定要推送的内容,则使用默认行为,对应于以下simple 值push.default:当前分支被推送到相应的上游分支,但是作为安全措施,如果上游分公司不具有与本地相同的名称。
OPTIONS
<repository><库>
作为推送操作目标的“远程”存储库。该参数可以是URL(请参阅下面的GIT URLS部分)或远程名称(请参阅下面的REMOTES部分)。
<refspec>…
用什么源对象指定要更新的目标引用。参数<refspec>的格式是一个可选的plus +,后跟源对象<src>,后跟一个冒号:,后跟目标ref <dst>。
<src>通常是您想要推送的分支名称,但它可以是任意的“SHA-1表达式”,如master~4or HEAD(请参阅gitrevisions(7))。
<dst>通过这个推送来告诉远程端的哪个ref被更新。任意表达式不能在这里使用,实际的ref必须被命名。如果git push [<repository>]没有任何<refspec>参数被设置为<src>使用 remote.<repository>.push配置变量更新目标的一些ref ,:<dst>则可以省略部分 - 这样的推动将更新<src>通常<refspec>在命令行上没有任何更新的ref 。否则,缺少 :<dst>意味着更新相同的参考<src>。
由<src>引用的对象用于更新远程端的<dst>引用。默认情况下,只有当<dst>不是标签(带注释或轻量级标签)时才允许使用,只有在<dst>可以快进时。通过具有可选的领导+,你可以让Git更新<DST> REF即使是默认不允许的(比如,它不是一个快进。)这并不会试图合并<来源>为<DST> 。有关详细信息,请参阅下面的示例。
tag <tag>的意思是一样的refs/tags/<tag>:refs/tags/<tag>。
推一个空的<src>允许你从远程仓库中删除<dst> ref。
特殊的refspec :(或+:允许非快进更新)指示Git推送“匹配”分支:对于本地存在的每个分支,如果远程已存在的同名分支已经存在,则更新远程端侧。
--all- 所有
推动所有分支(即参考下refs/heads/); 不能与其他<refspec>一起使用。
--prune- 修剪
删除没有本地副本的远程分支机构。例如,tmp如果同名的本地分支不再存在,远程分支将被删除。这也尊重refspecs,例如git push --prune remote refs/heads/*:refs/tmp/*,refs/tmp/foo如果refs/heads/foo 不存在, 将确保远程将被删除。
--mirror- 镜子
代替命名每个裁判推的,指定了下的所有参考文献refs/(包括但不限于refs/heads/,refs/remotes/和refs/tags/)被镜像到远程存储库。新创建的本地参考将被推送到远端,本地更新的参考将在远端强制更新,删除的参考将从远端移除。如果remote.<remote>.mirror设置了配置选项,这是默认值。
-n--dry-run-n
--dry运行
除了实际发送更新之外,其他的一切
--porcelain- 瓷
生成机器可读的输出。每个ref的输出状态行将被制表符分隔,并发送到stdout而不是stderr。参考文献的完整符号名称将被给出。
--delete- 删除
所有列出的ref都从远程仓库中删除。这和用冒号前缀所有的引用是一样的。
--tags--tags
refs/tags除了在命令行中明确列出的refspecs之外,所有的ref 都被压入。
--follow-tags--follow标签
推送所有没有这个选项的推送的引用,并且推送refs/tags在远程丢失的注释标记,但是指向从被推送的引用可达的提交。这也可以通过配置变量来指定push.followTags。有关详细信息,请参见push.followTags在GIT-配置(1)。
--[no-]signed--signed=(true|false|if-asked)GPG-签署推送请求来更新接收端的refs,允许通过钩子检查和/或被记录。如果false或者--no-signed,不会尝试签名。如果true或者--signed,如果服务器不支持签名推送,推送将失败。如果设置为if-asked,则当且仅当服务器支持签名推送时签名。如果实际的呼叫gpg --sign失败,推送也将失败。有关接收端的详细信息,请参阅 git-receive-pack(1)。
--[no-]atomic- [无糖]原子
如果可用,请使用远程端的原子事务。或者所有的ref都被更新,或者错误的,没有ref被更新。如果服务器不支持原子推送,推送将失败。
-o <option>--push-option=<option>-o <选项>
--push选项= <选项>
将给定的字符串传输到服务器,将它们传递给预接收以及接收后挂接。给定的字符串不能包含NUL或LF字符。当--push-option=<option>给出多个时,它们都按命令行上列出的顺序发送到另一端。如果--push-option=<option>命令行中没有,push.pushOption 则使用配置变量的值。
--receive包= <GIT-接收包>
--exec = <GIT-接收包>
远程端的git-receive-pack程序的路径。在通过ssh推送到远程仓库时有时很有用,而且您没有在默认$ PATH目录中的程序。
--[no-]force-with-lease
--force-with-lease=<refname>
--force-with-lease=<refname>:<expect>通常情况下,“git push”拒绝更新一个不是本地ref的祖先的远程ref,用来覆盖它。
如果远程ref的当前值是期望值,则此选项将覆盖此限制。否则,“git推”失败。
想象一下,你必须重新发布你已经发表的内容。你将不得不绕过“必须快进”的规则,以取代你最初发表的历史与重新发布的历史。如果其他人在你重新装修的基础上建立在原始历史的基础上,那么遥控器的尖端可能会随着她的承诺而前进,而盲目地推动--force她将失去她的工作。
这个选项可以让你说,你期望你正在更新的历史是你重塑和要取代的。如果远程引用仍然指向您指定的提交,可以确定没有其他人对引用做任何事情。这就像在ref上“租赁”而不明确地锁定它,只有在“租约”仍然有效的情况下才更新远程参考。
--force-with-lease 单独一个,没有指定细节,将通过要求它们的当前值与我们为它们的远程跟踪分支相同来保护将被更新的所有远程参考。
--force-with-lease=<refname>,而不指定期望的值,如果将要更新的话,将通过要求其当前值与我们对它的远程跟踪分支相同来保护指定的ref(单独)。
--force-with-lease=<refname>:<expect>将保护指定的ref(单独),如果它将被更新,通过要求其当前值与指定值相同<expect>(允许与refname的远程跟踪分支不同),或者当使用这种形式时,我们甚至不需要有这样的远程跟踪分支)。如果<expect>是空字符串,则命名的ref必须不存在。
请注意,除此之外的所有形式都--force-with-lease=<refname>:<expect> 明确指定了ref的预期当前值,但它们仍然是实验性的,并且随着我们获得此功能的经验,它们的语义可能会发生变化。
“--no-force-with-lease”会在命令行中取消之前的所有--force-lease-lease。
关于安全的一般注意事项:提供这个选项,没有期望的值,也就是 与远程运行的任何隐式地运行在后台的任何东西(--force-with-lease或者--force-with-lease=<refname>交互)git fetch,例如git fetch origin 在cronjob的仓库中。
它提供的保护--force是确保您的工作没有基于的后续更改不被破坏,但是如果某些后台进程正在更新后台中的refs,则会被轻微地击败。除了远程跟踪信息外,我们没有其他任何东西可以作为启发式的参考,预计你会看到并且愿意闯入。
如果您的编辑器或其他系统正在git fetch后台运行,则可以通过简单的方式设置另一个远程:
git远程添加原始推送$(git配置remote.origin.url)
git获取原点推送
现在,当后台进程运行时git fetch origin,引用origin-push将不会被更新,因此命令如下:
git push -force-with-lease origin-push
除非你手动运行,否则会失败git fetch origin-push。这个方法当然完全被运行的东西所击败git fetch --all,在这种情况下,你需要禁用它,或者做一些更乏味的事情,比如:
git fetch # update 'master' from remote git tag base master # mark our base point git rebase -i master # rewrite some commits git push --force-with-lease=master:base master:master
base即为上游代码的版本创建一个标签,这些代码是您已经看到并且愿意覆盖的版本,然后重写历史记录,最后,master如果远程版本仍在,则 强制推送更改base,无论本地remotes/origin/master更新到背景。
-F
- 力
通常,这个命令拒绝更新远程ref,这个远程ref不是本地ref的祖先,用来覆盖它。另外,当使用--force-with-lease选项时,该命令拒绝更新当前值与预期值不匹配的远程参考。
该标志禁用这些检查,并可能导致远程存储库丢失提交; 小心使用它。
请注意,--force适用于所有被推送的引用,因此使用它push.default设置为matching或配置有多个remote.*.push可能覆盖除当前分支以外的引用(包括严格位于其远程对象后面的本地引用)的多个推送目标。要只强制推送一个分支,可以使用+refspec前面的一个按钮(例如git push origin +master强制推送master分支)。有关<refspec>...详情,请参阅上面的 部分。
--repo = <库>
这个选项等同于<repository>参数。如果两者都指定,则命令行参数优先。
-u
--set上游
对于每个最新或成功推送的分支,添加上游(跟踪)引用,由无参数的 git-pull(1)和其他命令使用。有关详细信息,请参见branch.<name>.merge在GIT-配置(1)。
- [无糖]薄
这些选项被传递给git-send-pack(1)。当发送方和接收方共享许多相同的对象时,精简传输可以显着减少发送的数据量。默认是\ - 瘦。
-q
- 安静
禁止所有输出,包括更新的引用列表,除非发生错误。进度不报告给标准错误流。
-v
--verbose
运行详细。
- 进展
当连接到终端时,默认情况下标准错误流会报告进度状态,除非指定-q。即使标准错误流没有指向终端,该标志也会强制进行状态。
--no-递归,子模块
--recurse-子模块=检查|点播|只有|无
可用于确保所推送的版本使用的所有子模块提交在远程跟踪分支上可用。如果检查使用Git会确认,在被推动的修订改变了所有子模块提交可用的子模块的至少一个遥控器上。如果缺少任何提交,推送将被中止并以非零状态退出。如果使用按需,则会推送修订中被更改的所有子模块。如果按需不能推动所有必要的修改,它也将被中止并以非零状态退出。如果只使用了所有的子模块,那么在超级项目被放下的时候,所有的子模块都将被递归推送。值为no或正在使用--no-recurse-submodules 可以用于在不需要子模块递归时覆盖push.recurseSubmodules配置变量。
- [无糖]验证
切换预推钩(见githooks(5))。默认是 - 验证,让钩子有机会阻止推送。用--no-verify,钩子被完全绕过。
-4
--ipv4
仅使用IPv4地址,忽略IPv6地址。
-6
--ipv6
只使用IPv6地址,忽略IPv4地址。
GIT URLS
通常,URL包含有关传输协议的信息,远程服务器的地址以及存储库的路径。根据传输协议,这些信息可能不存在。
Git支持ssh,git,http和https协议(另外,ftp和ftps可以用于读取,但效率不高,不推荐使用,不要使用它)。
本地传输(即git:// URL)不进行身份验证,应在不安全的网络上谨慎使用。
以下语法可以与它们一起使用:
SSH:// [用户@] host.xz [:端口] /path/to/repo.git/
GIT中://host.xz [:端口] /path/to/repo.git/
HTTP [S]://host.xz [:端口] /path/to/repo.git/
FTP [S]://host.xz [:端口] /path/to/repo.git/
ssh协议也可以使用另一种类似scp的语法:
[用户@] host.xz:路径/到/ repo.git /
只有在第一个冒号前没有斜杠,才能识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径foo:bar可以被指定为绝对路径或./foo:bar避免被误解为ssh url。
ssh和git协议还支持〜用户名扩展:
SSH:// [用户@] host.xz [:端口] /〜[用户] /path/to/repo.git/
GIT中://host.xz [:端口] /〜[用户] /path/to/repo.git/
[用户@] host.xz:/〜[用户] /path/to/repo.git/
对于本地支持的本地存储库,可以使用以下语法:
/path/to/repo.git/
文件:///path/to/repo.git/
这两种语法大多是等价的,除了克隆时,前者意味着--local选项。有关详细信息,请参阅git-clone(1)。
当Git不知道如何处理某个传输协议时,它会尝试使用remote- <transport>远程助手(如果存在的话)。要显式请求远程帮助程序,可以使用以下语法:
<运输> :: <地址>
其中<address>可能是一个路径,一个服务器和一个路径,或者是由被调用的特定的远程助手识别的任意的URL类型的字符串。有关详细信息,请参阅gitremote-helpers(1)。
如果存在大量类似命名的远程存储库,并且您希望为其使用不同的格式(例如,您使用的URL将被重写为工作的URL),则可以创建表单的配置部分:
[url“<actual url base>”]
insteadOf = <其他网址>
例如,用这个:
[url“git://git.host.xz/”]
insteadOf = host.xz:/ path / to /
insteadOf = work:
像“work:repo.git”或像“host.xz:/path/to/repo.git”这样的URL将被重写在任何需要URL为“git://git.host.xz/repo git的”。
如果您想重写仅用于推送的URL,则可以创建表单的配置部分:
[url“<actual url base>”]
pushInsteadOf = <其他网址库>
例如,用这个:
[url“ssh://example.org/”]
pushInsteadOf = git://example.org/
像“git://example.org/path/to/repo.git”这样的URL将被重写为“ssh://example.org/path/to/repo.git”来推送,但是pulls仍然会使用原始网址。
遥控器
可以使用下列其中一个名称来代替URL作为<repository>参数:
一个远程的Git配置文件:$GIT_DIR/config,
目录中的$GIT_DIR/remotes文件,或
目录中的$GIT_DIR/branches文件。
所有这些也允许你从命令行中省略refspec,因为它们都包含一个git将默认使用的refspec。
在配置文件中命名远程
您可以选择使用git-remote(1),git-config(1)甚至通过手动编辑来提供以前配置的远程$GIT_DIR/config文件的名称。这个远程的URL将被用来访问版本库。当你不在命令行上提供一个refspec的时候,这个远程的refspec将被默认使用。配置文件中的条目将如下所示:
[远程“<名称>”]
url = <url>
pushurl = <pushurl>
push = <refspec>
fetch = <refspec>
将<pushurl>仅用于推动。这是可选的,默认为<url>。
在中命名的文件 $GIT_DIR/remotes
您可以选择提供文件的名称$GIT_DIR/remotes。该文件中的URL将被用于访问存储库。当你不在命令行中提供一个refspec时,这个文件中的refspec将被用作默认值。该文件应该具有以下格式:
网址:以上网址格式之一
推:<refspec>
拉:<refspec>
Push:行被git push使用, Pull:行被git pull和git fetch使用。多个Push:和Pull:行可能被指定为额外的分支映射。
在中命名的文件 $GIT_DIR/branches
您可以选择提供文件的名称$GIT_DIR/branches。该文件中的URL将被用于访问存储库。该文件应该具有以下格式:
<URL>#<HEAD>
<url>是必须的; #<head>是可选的。
根据操作,如果你没有在命令行中提供一个参数,git将使用以下参数之一。 <branch>这个文件中的名称$GIT_DIR/branches和 <head>默认master。
git fetch使用:
参考文献/头/ <HEAD>:参考文献/头/ <分支>
git push使用:
HEAD:参考文献/头/ <HEAD>
OUTPUT
“git push”的输出取决于使用的传输方法; 本节将介绍在推送Git协议(本地或通过ssh)时的输出。
推送的状态以表格形式输出,每行代表一个参考的状态。每一行都是这样的形式:
<flag> <summary> <from> - > <to>(<reason>)
如果使用 - 瓷器,那么输出的每一行的格式如下:
<flag> \ t <from>:<to> \ t <summary>(<reason>)
只有在使用--porcelain或--verbose选项时,才会显示最新的参考状态。
旗
指示ref的状态的单个字符:
(空间)
为成功推进快速前进;
+
成功强制更新;
-
为成功删除参考;
*
为成功推新的参考;
!
对于被拒绝或失败的裁判来说; 和
=
对于一个裁判是最新的,并不需要推。
概要
对于成功推送的引用,摘要以适合用作参数的形式git log(<old>..<new>大多数情况下 <old>...<new>为强制非快进更新)显示ref的新值和新值 。
对于失败的更新,将给出更多详细信息:
拒绝
Git根本没有尝试发送ref,通常是因为它不是快进的,你没有强制更新。
远程拒绝
远端拒绝更新。通常由远程端的钩子引起,或者是因为远程存储库具有以下有效的安全选项之一:( receive.denyCurrentBranch用于推送到签出的分支)receive.denyNonFastForwards(用于强制非快进更新)receive.denyDeletes或 receive.denyDeleteCurrent。请参阅git-config(1)。
远程故障
远程端没有报告ref的成功更新,可能是因为远程端的临时错误,网络连接中断或其他瞬时错误。
从
被推送的本地ref的名字,减去它的 refs/<type>/前缀。在删除的情况下,本地ref的名称被省略。
至
正在更新的远程参考的名称,减去它的 refs/<type>/前缀。
原因
一个人类可读的解释。在成功推裁裁的情况下,不需要解释。对于失败的参考文献,描述了失败的原因。
关于快进的注意事项
当一个更新改变了一个用于指向提交A的分支(或者更一般地说,一个ref)来指向另一个提交B时,当且仅当B是A的后代时,它被称为快进更新。
在从A到B的快速更新中,原始提交A建立在其上的提交集是新提交B建立在其上的提交的子集。因此,它不会失去任何历史。
相反,非快进更新将失去历史记录。例如,假设你和其他人开始了同一个提交X,并且你建立了一个导致提交B的历史,而另一个人建立了一个导致提交A的历史。历史看起来像这样:
乙
/
--- X ---一
进一步假设另一个人已经将导致A的改变推回到你从中获得原始提交X的原始存储库。
其他人完成的推送更新了用于指向提交X的分支,指向提交A.这是一个快进。
但是如果你试图推,你会尝试更新的分支(即现在指向在A)与承诺B.这确实不是快进。如果你这样做了,由A提交的更改将会丢失,因为每个人现在都将开始在B之上构建。
默认情况下,该命令不允许不是快进的更新来防止这种历史丢失。
如果您不想失去工作(从X到B的历史记录)或其他人的工作(从X到A的历史记录),则需要先从存储库中获取历史记录,创建一个包含已完成更改的历史记录由双方共同推动,并将结果推回。
你可以执行“git pull”,解决潜在的冲突,“git push”结果。“git pull”会在提交A和B之间创建合并提交C.
公元前
/ /
--- X ---一
使用生成的合并提交更新A将快进,您的推送将被接受。
或者,你可以用A和G之间的变化来重新设置X和B之间的变化,然后把结果推回去。rebase将创建一个新的提交D,在A之上构建X和B之间的变化。
BD
/ /
--- X ---一
再一次地,用这个提交更新A将会快进,你的推送将被接受。
还有一种常见的情况是,当你尝试推送时,你可能遇到非快进拒绝,甚至当你推入没有其他人推入的仓库时也是如此。在你自己推送提交A之后(在本节的第一张图片中),用“git commit --amend”代替它以产生提交B,并且试图推出它,因为忘记了你已经推出了A。在这种情况下,只有当你确定没有人同时提取你以前的提交A(并开始构建它)时,才可以运行“git push --force”来覆盖它。换句话说,“git push --force”是一个保留的方法,你的意思是失去历史。
例子
git push
像git push <remote><remote>是当前分支的远程(或者origin,如果没有为当前分支配置远程)那样工作。
git push origin
如果没有额外的配置,将当前分支推送到已配置的上游(remote.origin.merge配置变量)(如果它与当前分支具有相同的名称),并在没有其他推送的情况下出错。
当给定<refspec>时,该命令的默认行为可以通过设置push远程的选项或push.default 配置变量进行配置。
例如,默认为仅推送当前分支以origin 供使用git config remote.origin.push HEAD。任何有效的<refspec>(如以下示例中的那样)都可以配置为默认值 git push origin。
git push origin :
推“匹配”分支到origin。有关“匹配”分支的说明,请参阅上面“ 选项”一节中的<refspec> 。
git push origin master
找到一个master在源代码库中匹配的引用(很可能会找到refs/heads/master),并使用它更新存储库中的同一个引用(例如refs/heads/master)origin。如果master不存在,它会被创建。
git push origin HEAD
一个方便的方法来推动当前分支在遥控器上相同的名称。
git push mothership master:satellite/master dev:satellite/dev
使用与master(例如refs/heads/master)相匹配的源代码来更新存储库中匹配satellite/master(最可能 refs/remotes/satellite/master)的引用mothership; 为dev和做同样的事情satellite/dev。
这是为了仿效在相反的方向git fetch上运行的mothership使用git push,以便整合所做的工作satellite,并且当你只能以一种方式进行连接时(通常是必需的)卫星可以接入母体,但是母体不能连接到卫星,因为后者是在防火墙后面或不运行sshd)。
在机器git push上运行这个之后satellite,你会ssh进入mothership并运行git merge那里来完成git pull那个被运行的模拟mothership来拉取所做的更改satellite。
git push origin HEAD:master
按当前分支到远程REF匹配master的 origin存储库。这个表格很方便的推送当前分支而不用考虑它的本地名字。
git push origin master:refs/heads/experimental
创建分支experimental在origin通过复制当前库master分支。只有当本地名称和远程名称不同时,才需要在远程存储库中创建新的分支或标签; 否则,裁判名称本身将工作。
git push origin :experimental
找到一个experimental在origin库中匹配的ref (例如refs/heads/experimental),并将其删除。
git push origin +dev:master
使用dev分支更新源存储库的主分支,允许非快进更新。 这可能会导致原始存储库中悬而未决的提交。 考虑以下情况,快进是不可能的:
o --- o --- o --- A --- B原点/主
\
X --- Y --- Z开发
上面的命令会将源存储库更改为
A --- B(无名分支)
/
o --- o --- o --- X --- Y --- Z主人
提交A和B将不再属于具有符号名称的分支,因此将无法访问。因此,这些提交将通过git gc源存储库上的命令删除。
安全
获取和推送协议并不旨在防止一方从另一个不希望共享的存储库中窃取数据。如果您拥有需要防止恶意对等方的私人数据,则最佳选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的名称空间对读取访问控制无效; 您应该只允许对客户端的名称空间的读取访问权限,您将信任的读取权限访问整个存储库。
已知的攻击媒介如下:
受害者发送“有”行广告的对象的ID没有明确的意图共享,但可以用来优化转让,如果对方也有。攻击者选择一个对象ID X来窃取并向X发送一个ref,但是不需要发送X的内容,因为受害者已经拥有了它。现在受害者认为攻击者有X,然后将X的内容发回给攻击者。(这种攻击对于客户端来说是非常简单的,通过在客户端可以访问的命名空间中创建对X的引用,然后获取它,服务器在客户端执行它的最可能的方式是“合并“X到一个公共分支,并希望用户在这个分支上做额外的工作,并把它推回到服务器,而不会注意到合并。)
和#1一样,攻击者选择一个对象ID X来窃取。受害者发送一个攻击者已经拥有的对象Y,而攻击者错误地声称有X而不是Y,所以受害者发送Y作为对X的delta。这个delta揭示了X与攻击者类似的X的区域。
GIT
所述的部分的git(1)套件
最后更新2018-02-02 16:16:03协调世界时