git-push(1)手册页
目录位置:git安装位置/Git/mingw64/share/doc/git-doc/git-push.html 谷歌翻译了一下
名称
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>…]]
描述
使用本地引用更新远程引用,同时发送完成给定引用所需的对象。
每次通过建立 hooks ,向存仓库推送代码时,都可以使它发生有趣的事情。请参阅git-receive-pack(1)的文档。
当命令行未使用<repository>参数指定将信息推送到何处时,将参考当前分支的 branch.*.remote 配置来确定将信息推送到何处。如果缺少配置,则默认为origin。
当在命令行中没有使用<refspec>参数或--all,--mirror,--tags选项来指定推送内容,该命令将通过参照 remote.*.push 配置来查找默认的<refspec>,如果没有找到它,push.default配置决定推送内容(见git-config为(1)中 push.default 的含义)。
当命令行和配置均未指定要推送的内容时,将使用默认行为,该行为对应于push.default 的 simple 值:当前分支被推送到相应的上游分支,但是作为安全措施,如果上游分支与本地分支的名称不同,将取消推送。
选项
<repository>
作为推送操作目标的“远程”repository。此参数可以是URL(请参阅下面的GIT URLS部分)或遥控器的名称(请参见下面的REMOTES部分)。
<refspec> ...
指定要使用哪个源对象更新的目标引用。<refspec>参数的格式是可选的plus +,其后是源对象<src>,然后是冒号:,然后是目标ref <dst>。
<src>通常是您要推送的分支的名称,但它可以是任意的“ SHA-1表达式”,例如master~4或 HEAD(请参见gitrevisions(7))。
<dst>告知通过此推送更新远程端的哪个引用。此处不能使用任意表达式,必须命名实际引用。如果git push [<repository>]未<refspec>设置任何参数以<src>使用 remote.<repository>.push配置变量更新目标处的某些引用,:<dst>则可以省略part-这样的推送将更新<src>通常<refspec>在命令行上没有任何更新的引用。否则,缺少 :<dst>表示要更新与相同的ref <src>。
<src>引用的对象用于更新远程端的<dst>引用。默认情况下,仅当<dst>不是标记(带注释或轻量级)时才允许,然后仅当它可以快速转发<dst>时才允许。通过具有可选的领导+,你可以让Git更新<DST> REF即使是默认不允许的(比如,它不是一个快进。)这并不会试图合并<来源>为<DST> 。有关详细信息,请参见下面的示例。
tag <tag>的含义与相同refs/tags/<tag>:refs/tags/<tag>。
推送空的<src>允许您从远程repository中删除<dst>引用。
特殊的refspec :(或+:允许进行非快速更新)指示Git推送“匹配”分支:对于本地存在的每个分支,如果远程上已经存在同名分支,则更新远程端侧。
--all
推送所有分支(即ref下的ref refs/heads/);不能与其他<refspec>一起使用。
--prune
删除没有本地副本的远程分支。例如,tmp如果不再存在具有相同名称的本地分支,则将删除远程分支。这也遵守refspecs,例如 git push --prune remote refs/heads/*:refs/tmp/*,确保 不存在的远程对象refs/tmp/foo将被删除refs/heads/foo。
--mirror
代替命名每个ref推的,则指定下的所有参考文献refs/(包括但不限于refs/heads/,refs/remotes/和refs/tags/)被镜像到远程repository。新创建的本地ref将被推送到远程端,本地更新的ref将在远程端强制更新,而已删除的ref将从远程端删除。如果remote.<remote>.mirror设置了配置选项,则这是默认设置。
-n
--dry-run
除了实际发送更新外,执行所有其他操作。
-- porcelain
产生机器可读的输出。每个引用的输出状态行将以制表符分隔,并发送到stdout而不是stderr。将给出参考的完整符号名称。
--delete
从远程repository中删除所有列出的参考。这与在所有引用之前加冒号相同。
--tags
refs/tags除了在命令行上明确列出的refspecs外,还将推送下面的所有refs 。
--follow-tags
推送所有不带此选项将被推送的引用,并推送带注释的标签,refs/tags这些标签从远程丢失,但指向被推送的引用可到达的提交。也可以使用配置变量指定push.followTags。有关详细信息,请参见push.followTags在GIT-配置(1)。
--[no-]signed
--signed=(true|false|if-asked)
GPG对推送请求进行签名,以更新接收方的ref,以使其可以通过挂钩进行检查和/或记录。如果false或--no-signed,则不会尝试签名。如果true或--signed,则如果服务器不支持签名的推送,则推送将失败。如果设置为if-asked,则仅当服务器支持签名的推送时才签名。如果实际调用失败,则推送也将gpg --sign失败。有关接收端的详细信息,请参见 git-receive-pack(1)。
--[no-]atomic
如果可用,请在远程使用原子事务。所有参考均已更新,或者如果出错,则不会更新任何参考。如果服务器不支持原子推送,则推送将失败。
-o
--push-option
将给定的字符串传输到服务器,服务器将它们传递到接收前和接收后钩子。给定的字符串不得包含NUL或LF字符。
--receive-pack=<git-receive-pack>
--exec=<git-receive-pack>
远端git-receive-pack程序的路径。通过ssh推送到远程repository时,有时会很有用,并且您的程序没有位于默认$ PATH的目录中。
--[no-]force-with-lease
--force-with-lease=<refname>
--force-with-lease=<refname>:<expect>
通常,“ git push”拒绝更新不是用于覆盖它的本地引用的祖先的远程引用。
如果远程引用的当前值是期望值,则此选项将覆盖此限制。否则“ git push”将失败。
想象一下,您必须重新整理已经发布的内容。您必须绕过“必须快速转发”规则,才能用重新设置的历史记录替换最初发布的历史记录。如果您在重新定居时有其他人建立在您的原始历史之上,则远程分支的尖端可能随着她的提交而前进,而盲目地推动--force将失去她的工作。
使用此选项,您可以说您希望更新的历史记录是您要重新定位并希望替换的历史记录。如果远程引用仍然指向您指定的提交,则可以确保没有其他人对引用进行任何操作。就像对引用进行“租赁”而不显式锁定它一样,并且仅当“租赁”仍然有效时才更新远程引用。
--force-with-lease 仅通过在不指定详细信息的情况下,就可以通过要求其当前值与我们为它们提供的远程跟踪分支的值相同来保护所有将要更新的远程引用。
--force-with-lease=<refname>,而无需指定期望值,将通过要求其当前值与我们拥有的远程跟踪分支相同,来保护命名的ref(单独)(如果要更新)。
--force-with-lease=<refname>:<expect>如果要更新命名的ref(如果要更新),则将要求其当前值与指定值相同<expect>(允许与我们为refname提供的远程跟踪分支不同),从而保护它(单独)使用此表单时,我们甚至不必拥有这样的远程跟踪分支。如果<expect>为空字符串,则命名引用必须不存在。
请注意,除此形式以外,所有其他形式都--force-with-lease=<refname>:<expect> 明确指定了ref的预期当前值,这些形式仍处于实验阶段,随着我们对该功能的经验积累,它们的语义可能会发生变化。
“ --no-force-with-lease”将取消命令行上所有以前的--force-with-lease。
关于安全性的一般说明:提供此选项时没有期望的值,即 与隐式运行在遥控器上并在后台(例如 ,在cronjob中的repository中)隐式运行的任何内容--force-with-lease或--force-with-lease=<refname>与之交互作用非常差。git fetchgit fetch origin
它提供的保护措施可以--force确保您的工作所基于的后续更改不会被破坏,但是如果某些后台进程在后台更新引用,这将是微不足道的。除了远程跟踪信息以外,我们没有其他任何信息,可以启发您希望看到的参考文献,并愿意为之烦恼。
如果您的编辑器或其他系统正在git fetch后台运行,那么减轻此问题的一种方法就是简单地设置另一个遥控器:
git remote add origin-push $(git config remote.origin.url)
git fetch origin-push
现在,当后台进程运行时git fetch origin,引用origin-push不会更新,因此命令如下:
git push --force-with-lease origin-push
除非您手动运行,否则将失败git fetch origin-push。当然,此方法被运行的东西完全击败了git fetch --all,在这种情况下,您需要禁用它或做一些更单调的事情:
git fetch#从远程更新'master'
git tag base master#标记我们的基点
git rebase -i master#重写一些提交
git push --force-with-lease = master:base master:master
也就是说base,为您已经看到并愿意覆盖的上游代码版本创建标签,然后重写历史记录,最后master如果远程版本仍位于base,则 强制将更改推送到,而不管您本地中的本地版本remotes/origin/master已更新为什么。背景。
-f
--force
通常,该命令拒绝更新不是用于覆盖它的本地引用的祖先的远程引用。同样,当使用--force-with-leaseoption 时,命令拒绝更新其当前值与预期值不匹配的远程引用。
该标志禁用这些检查,并可能导致远程repository丢失提交。小心使用。
请注意,这--force适用于所有推送的ref,因此在push.default设置为matching或配置了多个推送目标的情况下使用它remote.*.push可能会覆盖当前分支以外的其他ref(包括严格位于其远程副本后面的本地ref)。要仅将一个推送强制到一个分支,请+在refspec前面使用a 进行推送(例如git push origin +master,强制推送到该master分支)。有关<refspec>...详细信息,请参见上面的 部分。
--repo = <repository>
此选项等效于<repository>参数。如果两者都指定,则命令行参数优先。
-u
--set-upstream
对于每个最新的或成功推送的分支,请添加上游(跟踪)引用,该引用由无参数 git-pull(1)和其他命令使用。有关详细信息,请参见branch.<name>.merge在GIT-配置(1)。
--[no-]thin
这些选项被传递给git-send-pack(1)。当发送方和接收方共享许多相同的对象时,精简传输会大大减少发送的数据量。默认值为\-thin。
-q
--quiet
禁止所有输出,包括更新的引用列表,除非发生错误。进展不会报告给标准错误流。
-v
--verbose
详细地运行。
--progress
除非指定了-q,否则默认情况下,将状态错误报告到标准错误流时,将在标准错误流上报告该状态。即使标准错误流未定向到终端,该标志也会强制显示进度状态。
--no-recurse-submodules
--recurse-submodules=check|on-demand|only|no
可用于确保要推送的修订所使用的所有子模块提交在远程跟踪分支上均可用。如果使用check,则Git将验证至少要在子模块的一个远程上可用的所有要在修订版本中进行更改的子模块提交都可用。如果缺少任何提交,则推送将被中止并以非零状态退出。如果按需使用,则将推送要推送的修订中已更改的所有子模块。如果按需无法推送所有必要的修订,它将也被中止并以非零状态退出。如果仅使用该选项,则在不按下超级项目的情况下将递归推送所有子模块。否或使用的值--no-recurse-submodules 当不需要子模块递归时,可用于覆盖push.recurseSubmodules配置变量。
--[no-]verify
拨动预推钩(请参阅githooks(5))。默认值为--verify,为挂钩提供了阻止推送的机会。使用--no-verify,挂钩将被完全绕过。
-4
--ipv4
仅使用IPv4地址,忽略IPv6地址。
-6
--ipv6
仅使用IPv6地址,而忽略IPv4地址。
GIT URLS
通常,URL包含有关传输协议,远程服务器的地址以及repository路径的信息。根据传输协议,某些信息可能不存在。
Git支持ssh,git,http和https协议(此外,可以使用ftp和ftps进行获取,但这效率低下且不建议使用;请勿使用它)。
本机传输(即git:// URL)不进行身份验证,在不安全的网络上应谨慎使用。
以下语法可以与它们一起使用:
ssh:// [user @] host.xz [:port] /path/to/repo.git/
git://host.xz [:port] /path/to/repo.git/
http [s]://host.xz [:port] /path/to/repo.git/
ftp [s]://host.xz [:port] /path/to/repo.git/
ssh协议也可以使用类似scp的语法:
[user @] host.xz:path / to / repo.git /
仅当第一个冒号前没有斜杠时,才识别此语法。这有助于区分包含冒号的本地路径。例如,foo:bar可以将本地路径指定为绝对路径,或./foo:bar避免被误解为ssh url。
ssh和git协议还支持〜username扩展:
ssh:// [user @] host.xz [:port] /〜[user] /path/to/repo.git/
git://host.xz [:port] /〜[user] /path/to/repo.git/
[user @] host.xz:/〜[user] /path/to/repo.git/
对于本地repository(Git本身也支持),可以使用以下语法:
/path/to/repo.git/
文件:///path/to/repo.git/
这两种语法几乎是等效的,除了在克隆时(前者暗示--local选项时)。有关详细信息,请参见git-clone(1)。
当Git不知道如何处理某种传输协议时,它将尝试使用remote- <transport>远程帮助程序(如果存在)。要显式请求远程帮助者,可以使用以下语法:
<运输> :: <地址>
其中,<地址>可以是路径,服务器和路径,也可以是被调用的特定远程帮助程序识别的类似于URL的任意字符串。有关详细信息,请参见gitremote-helpers(1)。
如果存在大量类似名称的远程repository,并且您想为它们使用不同的格式(这样,您使用的URL将被重写为有效的URL),则可以创建以下形式的配置部分:
[url "<actual url base>"] insteadOf = <other url base>
例如,与此:
[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 = <other url base>
例如,与此:
[url "ssh://example.org/"] pushInsteadOf = git://example.org/
像“ git://example.org/path/to/repo.git”之类的网址将被重写为“ ssh://example.org/path/to/repo.git”以进行推送,但是pull仍将使用原始网址。
远程 REMOTES
可以使用以下任一名称代替URL作为<repository>参数:
在GIT中的配置文件中的远程:$GIT_DIR/config,
目录中的$GIT_DIR/remotes文件,或
目录中的$GIT_DIR/branches文件。
所有这些还允许您从命令行省略refspec,因为它们每个都包含git默认情况下将使用的refspec。
在配置文件中命名为remote
您可以选择提供以前使用git-remote(1),git-config(1)甚至通过手动编辑$GIT_DIR/config文件配置的远程名称。该遥控器的URL将用于访问repository。如果您未在命令行上提供refspec,则默认情况下将使用此遥控器的refspec。配置文件中的条目将如下所示:
[remote "<name>"] url = <url> pushurl = <pushurl> push = <refspec> fetch = <refspec>
将<pushurl>仅用于推动。它是可选的,默认为<url>。
$GIT_DIR/remotes 中的命名文件
您可以选择在中提供文件名$GIT_DIR/remotes。该文件中的URL将用于访问repository。如果未在命令行上提供refspec,则此文件中的refspec将用作默认值。该文件应具有以下格式:
URL: one of the above URL format Push: <refspec> Pull: <refspec>
Push:线被用于通过GIT中推和 Pull:线通过使用GIT中拉和GIT取。可以为其他分支映射指定多行Push:和多Pull:行。
$GIT_DIR/branches 中的命名文件
您可以选择在中提供文件名$GIT_DIR/branches。该文件中的URL将用于访问repository。该文件应具有以下格式:
<url>#<head>
<url>是必须的; #<head>是可选的。
如果您没有在命令行上提供refspec,则git将使用以下refspec之一,具体取决于操作。 <branch>这个文件中的名称$GIT_DIR/branches和 <head>默认master。
git fetch使用:
refs/heads/<head>:refs/heads/<branch>
git push用途:
HEAD:refs / heads / <head>
输出
“ git push”的输出取决于所使用的传输方法。本节介绍了推送Git协议时(本地或通过ssh)的输出。
推送状态以表格形式输出,每行代表一个引用的状态。每行的格式为:
<flag> <summary> <from> -> <to> (<reason>)
如果使用--porcelain,则输出的每一行均采用以下格式:
<flag> \t <from>:<to> \t <summary> (<reason>)
仅当使用--porcelain或--verbose选项时,才会显示最新引用的状态。
flag
指示参考状态的单个字符:
(space)
成功推动快速前进;
+
成功进行强制更新;
-
对于成功删除的引用;
*
成功推送新ref;
!
对于被拒绝或无法推送的ref;和
=
对于最新的ref,不需要推送。
summary
对于成功推送的ref,摘要以适合用作参数的形式显示了ref的旧值和新值 git log(<old>..<new>在大多数情况下, 这是<old>...<new>强制性的非快进更新)。
对于失败的更新,将给出更多详细信息:
rejected
Git根本没有尝试发送引用,这通常是因为它不是快速转发的,并且您没有强制执行更新。
远程拒绝
远端拒绝更新。通常是由远程侧的钩子引起的,或者是由于远程repository具有以下有效的安全选项之一:( receive.denyCurrentBranch用于推送到检出的分支),receive.denyNonFastForwards(用于强制性非快进更新)receive.denyDeletes或 receive.denyDeleteCurrent。请参阅git-config(1)。
远程故障
远程端未报告对引用的成功更新,可能是由于远程端的临时错误,网络连接中断或其他临时错误。
from
被推送的本地引用的名称,减去其 refs/<type>/前缀。在删除的情况下,将省略本地引用的名称。
to
要更新的远程引用的名称,减去其 refs/<type>/前缀。
reason
易于理解的解释。在成功推入ref的情况下,不需要解释。对于失败的参考,将描述失败的原因。
关于快进的注意事项
当更新将用于指向提交A的分支(或更通常为ref)更改为指向另一个提交B的分支时,当且仅当B是A的后代时,才称为快进更新。
在从A到B的快进更新中,原始提交A建立在其之上的提交集合是新提交B建立在其之上的提交的子集。因此,它不会丢失任何历史记录。
相反,非快速更新将丢失历史记录。例如,假设您和其他人从同一提交X开始,并且您建立了一个导致提交B的历史记录,而另一个人建立了一个导致提交A的历史记录。历史记录如下所示:
B
/
--- X --- A
进一步假设其他人已经将导致A的更改推回到原始repository,您从中获得两个原始提交X。
另一个人进行的推送将以前指向提交X的分支更新为指向提交A的分支。这是一个快进操作。
但是,如果您尝试推送,则将尝试使用提交B更新分支(现在指向A)。这不能快进。如果这样做,则提交A引入的更改将丢失,因为现在每个人都将开始在B的基础上进行构建。
默认情况下,该命令不允许进行不是快进的更新,以防止此类历史记录丢失。
如果您不想丢失工作(从X到B的历史记录)或其他人的工作(从X到A的历史记录),则需要首先从repository中获取历史记录,创建包含已完成更改的历史记录双方,并将结果推回去。
您可以执行“ git pull”,解决潜在的冲突,并“ git push”结果。“ git pull”将在提交A和B之间创建合并提交C。
B---C
/ /
--- X --- A
使用生成的合并提交更新A将快速进行,并且您的推送将被接受。
或者,您可以使用“ git pull --rebase”在A之上的X和B之间重新设置更改,并将结果推回去。重新设置基础将创建一个新的提交D,该提交将在A的顶部建立X和B之间的更改。
B D
/ /
--- X --- A
同样,使用此提交更新A将快速进行,您的推送将被接受。
还有另一种常见情况,当您尝试推送时,您可能会遇到非快进拒绝,即使您将其推送到其他人都没有推送到的repository中也是有可能的。自己推送提交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在源repository中找到匹配的引用(很可能会找到refs/heads/master),并使用它更新repository中的相同引用(例如refs/heads/master)origin。如果master不存在,则将创建它。
git push origin HEAD
一种方便的方式将当前分支推到远程上的相同名称。
git push mothership master:satellite/master dev:satellite/dev
使用匹配master(例如refs/heads/master)的源ref 更新satellite/master(最可能是 refs/remotes/satellite/master)mothershiprepository中匹配的ref ;对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的 originrepository。这种形式可以方便地推送当前分支,而无需考虑其本地名称。
git push origin master:refs/heads/experimental
通过复制当前分支experimental在originrepository中创建master分支。仅当本地名称和远程名称不同时,才需要使用此表单在远程repository中创建新的分支或标记。否则,引用名称本身将起作用。
git push origin :experimental
experimental在originrepository中找到匹配的参考(例如refs/heads/experimental),然后将其删除。
git push origin +dev:master
使用dev分支更新原始repository的master分支,从而允许非快速更新。 这可能会使未引用的提交悬在原始repository中。 请考虑以下情况,其中不可能实现快进:
o --- o --- o --- A --- B起源/母版
\
X --- Y --- Z dev
上面的命令会将原始repository更改为
A --- B(未命名的分支)
/
o --- o --- o --- X --- Y --- Z主
提交A和B将不再属于具有符号名称的分支,因此将不可访问。这样,这些提交将被git gc源repository上的命令删除。
安全
提取和推送协议的目的不是防止一方从另一不打算共享的repository中窃取数据。如果您需要保护私人数据免受恶意对等,最好的选择是将其存储在另一个repository中。这适用于客户端和服务器。特别是,服务器上的名称空间对于读取访问控制无效。您只应向对整个repository具有读访问权限的客户机授予对名称空间的读访问权限。
已知的攻击媒介如下:
受害者发送“ have”行,广告它拥有的对象的ID,这些对象的ID并不是明确要共享的,但是如果对等体也有它们,则可以用来优化传输。攻击者选择要窃取的对象ID X并将引用发送给X,但由于受害者已经拥有X,因此不需要发送X的内容。现在,受害者认为攻击者拥有X,并将X的内容稍后发送回攻击者。(通过在客户端有权访问的命名空间中创建对X的引用,然后将其提取,这种攻击对于客户端在服务器上执行是最直接的。服务器在客户端上执行此操作的最可能方式是“将“ X”合并到公共分支,并希望用户在该分支上做其他工作并将其推送回服务器,而不会注意到合并。)
与#1一样,攻击者选择要窃取的对象IDX。受害者发送攻击者已经拥有的对象Y,并且攻击者错误地声称拥有X而不是Y,因此受害者将Y作为对X的增量发送。该增量向攻击者揭示了与Y相似的X区域。