Git 中文参考(三)(6)https://developer.aliyun.com/article/1565825
遥控
可以使用以下某个名称而不是 URL 作为参数:
- Git 配置文件中的一个遥控器:
$GIT_DIR/config
, $GIT_DIR/remotes
目录中的文件,或$GIT_DIR/branches
目录中的文件。
所有这些也允许你从命令行省略 refspec,因为它们每个都包含一个 git 将默认使用的 refspec。
在配置文件中命名为 remote
您可以选择使用 git-remote [1] , git-config [1] 提供之前配置的遥控器的名称,甚至可以手动编辑$GIT_DIR/config
文件。此远程的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则默认情况下将使用此远程的 refspec。配置文件中的条目如下所示:
[remote "<name>"] url = <url> pushurl = <pushurl> push = <refspec> fetch = <refspec>
仅用于推送。它是可选的,默认为
。
$GIT_DIR/remotes
中的命名文件
您可以选择在$GIT_DIR/remotes
中提供文件名。此文件中的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则此文件中的 refspec 将用作默认值。该文件应具有以下格式:
URL: one of the above URL format Push: <refspec> Pull: <refspec>
git push 使用Push:
行, git pull 和 git fetch 使用Pull:
系。可以为其他分支映射指定多个Push:
和Pull:
行。
$GIT_DIR/branches
中的命名文件
您可以选择在$GIT_DIR/branches
中提供文件名。此文件中的 URL 将用于访问存储库。该文件应具有以下格式:
<url>#<head>
是必需的;
#
是可选的。
根据操作,如果您没有在命令行上提供一个 refitpec,git 将使用以下 refspec 之一。 是
$GIT_DIR/branches
中此文件的名称,默认为master
。
git fetch 使用:
refs/heads/<head>:refs/heads/<branch>
git push 使用:
HEAD:refs/heads/<head>
配置的远程跟踪分支
您经常通过定期重复从中获取相同的远程存储库。为了跟踪这种远程存储库的进度,git fetch
允许您配置remote..fetch
配置变量。
通常这样的变量可能如下所示:
[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/*
此配置以两种方式使用:
- 运行
git fetch
时未指定要在命令行上获取的分支和/或标记,例如,git fetch origin
或git fetch
,remote..fetch
值用作 refspecs-它们指定要获取的 refs 和要更新的本地 refs。上面的示例将获取origin
中存在的所有分支(即,与值的左侧匹配的任何 ref,refs/heads/*
)并更新refs/remotes/origin/*
层次结构中的相应远程跟踪分支。 - 当使用显式分支和/或标记运行
git fetch
以在命令行上获取时,例如,git fetch origin master
,在命令行上给出的< refspec>确定要取出的内容(例如示例中的master
,这是master:
的简写,这反过来意味着“获取 ] master 分支但是我没有明确说出要从命令行“更新它的远程跟踪分支”,并且示例命令将只获取 _ 主 _ 分支。remote..fetch
值确定更新哪个远程跟踪分支(如果有)。当以这种方式使用时,remote..fetch
值对决定 _ 获取 _ 的内容没有任何影响(即,当命令行列出 refspecs 时,这些值不用作 refspecs);它们仅用于决定 _ 其中 _ 通过充当映射来存储所获取的引用。
后一次使用remote..fetch
值可以通过在命令行上给出--refmap=
参数来覆盖。
修枝
Git 有一个默认的保存数据,除非它被明确地丢弃;这延伸到持有本地对引用的本地引用,这些引用本身已经删除了那些分支。
如果留下累积,这些过时的引用可能会使具有大量分支流失的大而繁忙的存储库的性能变差,例如使git branch -a --contains
等命令的输出不必要地冗长,并影响任何可以使用完整的已知引用集的其他任何东西。
这些远程跟踪引用可以作为一次性删除,其中包括:
# While fetching $ git fetch --prune <name> # Only prune, don't fetch $ git remote prune <name>
要将引用修剪为正常工作流程的一部分而不需要记住运行它,请在配置中全局设置fetch.prune
,或者在远程设置remote..prune
。见 git-config [1] 。
事情变得棘手和具体。修剪功能实际上并不关心分支,而是将修剪本地<→远程引用作为远程 refspec 的函数(参见上面的和配置远程跟踪分支] )。
因此,如果遥控器的 refspec 包括例如refs/tags/*:refs/tags/*
,或您手动运行,例如git fetch --prune "refs/tags/*:refs/tags/*"
它不会是被删除的过时远程跟踪分支,而是远程上不存在的任何本地标记。
这可能不是您所期望的,即您想要修剪远程,但也要从中明确地获取标记,因此当您从中获取时,您将删除所有本地标记,其中大多数可能不是来自
]遥远的第一名。
因此在使用像refs/tags/*:refs/tags/*
这样的 refspec 或任何其他可能将多个遥控器的引用映射到同一本地命名空间的 refspec 时要小心。
由于在遥控器上保持最新的分支和标签是一个常见的用例,--prune-tags
选项可以与--prune
一起提供,以修剪遥控器上不存在的本地标签,并强制 - 更新那些不同的标签。也可以使用配置中的fetch.pruneTags
或remote..pruneTags
启用标签修剪。见 git-config [1] 。
--prune-tags
选项相当于在遥控器的 refspecs 中声明了refs/tags/*:refs/tags/*
。这可能会导致一些看似奇怪的互动:
# These both fetch tags $ git fetch --no-tags origin 'refs/tags/*:refs/tags/*' $ git fetch --no-tags --prune-tags origin
在没有--prune
或其配置版本的情况下提供它时不会出错的原因是为了配置版本的灵活性,并在命令行标志之间以及配置版本之间保持 1 = 1 的映射。
例如,合理的是配置~/.gitconfig
中的fetch.pruneTags=true
,以便在git fetch --prune
运行时修剪标签,而不会在没有--prune
的情况下每次调用git fetch
。
使用--prune-tags
修剪标签在获取 URL 而不是命名远程时也有效。这些将在原点上找不到所有修剪标签:
$ git fetch origin --prune --prune-tags $ git fetch origin --prune 'refs/tags/*:refs/tags/*' $ git fetch <url of origin> --prune --prune-tags $ git fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'
OUTPUT
“git fetch”的输出取决于所使用的传输方法;本节介绍通过 Git 协议(本地或通过 ssh)和 Smart HTTP 协议获取时的输出。
获取的状态以表格形式输出,每行代表单个 ref 的状态。每一行的形式如下:
<flag> <summary> <from> -> <to> [<reason>]
仅当使用–verbose 选项时,才会显示最新引用的状态。
在使用配置变量 fetch.output 指定的紧凑输出模式中,如果在另一个字符串中找到整个或
,则在另一个字符串中将其替换为
*
。例如,master -> origin/master
变为master -> origin/*
。
flag
一个表示 ref 状态的字符:
(space)
成功获得快进;
+
成功的强制更新;
-
成功修剪参考;
t
成功更新标签;
*
成功获取新参考;
!
对于被拒绝或未能更新的引用;和
=
对于一个最新的 ref,不需要提取。
summary
对于成功获取的 ref,摘要以适合用作git log
的参数的形式显示 ref 的旧值和新值(在大多数情况下这是..
,而强制非快速的...
- 转发更新)。
from
从中获取远程引用的名称,减去其refs//
前缀。在删除的情况下,远程 ref 的名称是“(none)”。
to
要更新的本地引用的名称减去其refs//
前缀。
reason
一个人类可读的解释。在成功获取 refs 的情况下,不需要解释。对于失败的 ref,描述了失败的原因。
例子
- 更新远程跟踪分支:
$ git fetch origin
- 上述命令从远程 refs / heads / namespace 复制所有分支,并将它们存储到本地 refs / remotes / origin / namespace,除非分支。< name> .fetch 选项用于指定非默认 refspec。
- 明确使用 refspecs:
$ git fetch origin +pu:pu maint:tmp
- 这通过从远程存储库中的分支(分别)
pu
和maint
获取来更新(或根据需要创建)本地存储库中的分支pu
和tmp
。pu
分支即使不快进也会更新,因为它带有加号前缀;tmp
不会。 - 查看远程分支,无需在本地存储库中配置远程:
$ git fetch git://git.kernel.org/pub/scm/git/git.git maint $ git log FETCH_HEAD
- 第一个命令从
git://git.kernel.org/pub/scm/git/git.git
的存储库中获取maint
分支,第二个命令使用FETCH_HEAD
检查 git-log [1] 的分支。最终将通过 git 的内置内务处理删除获取的对象(参见 git-gc [1] )。
安全
提取和推送协议的目的不是为了防止一方窃取不打算共享的其他存储库中的数据。如果您需要保护私有数据免受恶意对等方的攻击,那么最佳选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的命名空间对读访问控制无效;您应该只将命名空间的读访问权授予您信任的客户端,并具有对整个存储库的读访问权限。
已知的攻击向量如下:
- 受害者发送“有”行,宣传其拥有的对象的 ID,这些对象并未明确地用于共享,但如果对等方也拥有它们,则可用于优化转移。攻击者选择一个对象 ID X 来窃取并向 X 发送一个 ref,但不需要发送 X 的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有 X,并且稍后会将 X 的内容发送回攻击者。 (这种攻击对于客户端在服务器上执行是最直接的,通过在客户端有权访问的命名空间中创建 ref,然后获取它。服务器在客户端上执行它的最可能方式是“将“X”合并到一个公共分支中,并希望用户在此分支上执行其他工作,并将其推送回服务器,而不会注意到合并。)
- 与#1 一样,攻击者选择一个对象 ID X 来窃取。受害者发送攻击者已经拥有的对象 Y,并且攻击者错误地声称拥有 X 而不是 Y,因此受害者将 Y 作为针对 X 的增量发送。该增量显示 X 的区域与攻击者的 Y 类似。
BUGS
使用–recurse-submodules 只能在已检出的子模块中获取新的提交。例如,上游在超级项目的刚刚提取的提交中添加了一个新的子模块,子模块本身无法获取,因此无法在以后检查该子模块而无需再次进行提取。预计将在未来的 Git 版本中修复。
也可以看看
GIT
部分 git [1] 套件
git-pull
贡献者:Mrhuangyi
名称
git-pull - 从另一个存储库或本地分支获取并与其集成
概要
git pull [<options>] [<repository> [<refspec>…]]
描述
将来自远程存储库的更改合并到当前分支中。在默认模式下,git pull
是git fetch
的缩写,后跟git merge FETCH_HEAD
。
更确切地说, git pull 使用给定参数运行 git fetch 并调用 git merge 将检索到的分支头合并到当前分支中。使用--rebase
,它运行 git rebase 而不是 git merge 。
<库>应该是传递给 git-fetch [1] 的一个远程存储库的名称。 <的 Refspec>可以命名任意远程引用(例如,标签的名称),或者甚至是具有相应远程跟踪分支的引用集合(例如,refs / heads / *:refs / remotes / origin / *),但通常它是远程存储库中分支的名称。
< repository>和< branch>的默认值从 git-branch [1] --track
设置的当前分支的“远程”和“合并”配置中读取。
假设存在以下历史记录并且当前分支为“master
”:
A---B---C master on origin / D---E---F---G master ^ origin/master in your repository
因为它偏离本地master
(即E
),所以“git pull
”将从远程master
分支获取并重放相应的更改,直到它的当前提交(C
)在master
上面并将结果记录在新提交中,同时记录两个父提交的名称以及描述更改的用户的日志消息。
A---B---C origin/master / \ D---E---F---G---H master
有关详细信息,请参阅 git-merge [1] ,包括如何呈现和处理冲突。
在 Git 1.7.0 或更高版本中,要取消一个有冲突的合并,请使用git reset --merge
。 警告:在旧版本的 Git 中,不鼓励使用未提交的更改运行 git pull :尽管或许可行,但它可能会使您处于难以退出的冲突状态
如果任何远程更改与本地未提交的更改重叠,则将自动取消合并并且不更改工作树。通过 git-stash [1] 拉动或存放它们之前,通常最好在工作顺序中进行任何局部更改。
OPTIONS
-q
--quiet
这将传递给基础 git-fetch 以在传输过程中进行静噪报告,并在合并期间将基础 git-merge 传递给静噪输出。
-v
--verbose
传递–verbose 到 git-fetch 和 git-merge。
--[no-]recurse-submodules[=yes|on-demand|no]
此选项控制是否应该获取和更新所有已填充子模块的新提交(请参阅 git-config [1] 和 gitmodules [5] )。
如果通过 rebase 完成检出,则本地子模块提交也会被重新设置。
如果通过合并完成更新,则解析并检出子模块冲突。
与合并相关的选项
--commit
--no-commit
执行合并并提交结果。此选项可用于覆盖–no-commit。
使用–no-commit 执行合并但假装合并失败并且不自动提交,以便让用户有机会在提交之前检查并进一步调整合并结果。
--edit
-e
--no-edit
在提交成功的机械合并之前调用编辑器以进一步编辑自动生成的合并消息,以便用户可以解释并证明合并。 --no-edit
选项可用于接受自动生成的消息(通常不鼓励这样做)。
较旧的脚本可能取决于不允许用户编辑合并日志消息的历史行为。他们将在运行git merge
时看到编辑器打开。为了便于将此类脚本调整为更新的行为,可以在环境变量GIT_MERGE_AUTOEDIT
的开头设置为no
。
--ff
当合并解析为快进时,仅更新分支指针,而不创建合并提交。这是默认行为。
--no-ff
即使合并解析为快进,也要创建合并提交。这是在 refs / tags / 层次结构中合并未存储在其自然位置的带注释(且可能已签名)的标记时的默认行为。
--ff-only
拒绝以非零状态合并和退出,除非当前HEAD
已经是最新的,或者合并可以解析为快进。
-S[<keyid>]
--gpg-sign[=<keyid>]
GPG 签署生成的合并提交。 keyid
参数是可选的并且默认为提交者标识;如果具体指定,它必须粘在没有空格的选项上。
--log[=<n>]
--no-log
除了分支名称之外,还使用最多< n>的单行描述填充日志消息。正在合并的实际提交。另见 git-fmt-merge-msg [1] 。
使用–no-log 不会列出正在合并的实际提交中的单行描述。
--signoff
--no-signoff
在提交日志消息的末尾由提交者逐行添加签名。签收的含义取决于项目,但它通常证明提交者有权在同一许可下提交此作品并同意开发者原产地证书(参见 developercertificate.org/
] 欲获得更多信息)。
使用–no-signoff 时不要添加类似 Sign-off-by 的短行。
--stat
-n
--no-stat
在合并结束时显示 diffstat。 diffstat 也由配置选项 merge.stat 控制。
使用-n 或–no-stat 时,在合并结束时不显示 diffstat。
--squash
--no-squash
生成工作树和索引状态,就好像发生了真正的合并(合并信息除外),但实际上没有提交,移动HEAD
或记录$GIT_DIR/MERGE_HEAD
(导致下一个git commit
命令到创建合并提交)。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支(或章鱼的情况下更多)相同。
使用–no-squash 执行合并并提交结果。此选项可用于覆盖–squash。
-s <strategy>
--strategy=<strategy>
使用给定的合并策略;可以多次提供,以按照应该尝试的顺序指定它们。如果没有-s
选项,则使用内置的策略列表(合并单个头时 git merge-recursive ,否则使用 git merge-octopus )。
-X <option>
--strategy-option=<option>
将合并策略特定选项传递给合并策略。
--verify-signatures
--no-verify-signatures
验证正在合并的侧分支的提示提交是否使用有效密钥签名,即具有有效 uid 的密钥:在默认信任模型中,这意味着签名密钥已由可信密钥签名。如果侧分支的提示提交未使用有效密钥签名,则合并将中止。
--summary
--no-summary
同义词–stat 和–no-stat;这些已被弃用,将来会被删除。
--allow-unrelated-histories
默认情况下,git merge
命令拒绝合并不共享共同祖先的历史记录。在合并独立开始生命的两个项目的历史时,此选项可用于覆盖此安全性。由于这是一种非常罕见的情况,因此默认情况下不会启用任何配置变量来启用它,也不会添加。
-r
--rebase[=false|true|merges|preserve|interactive]
如果为 true,则在获取后将当前分支重新绑定在上游分支的顶部。如果存在与上游分支对应的远程跟踪分支,并且自上次提取以来上游分支已重新定位,则 rebase 使用该信息来避免重新定位非本地更改。
设置为merges
时,使用git rebase --rebase-merges
进行 rebase,以便本地合并提交包含在 rebase 中(有关详细信息,请参阅 git-rebase [1] )。
设置为 preserve 时,将--preserve-merges
选项的 rebase 传递给git rebase
,以便本地创建的合并提交不会被展平。
如果为 false,则将当前分支合并到上游分支中。
当为interactive
时,启用 rebase 的交互模式。
如果要使git pull
始终使用--rebase
而不是合并,请参见 git-config [1] 中的pull.rebase
,branch..rebase
和branch.autoSetupRebase
。
| 注意 | 这是一种潜在的 _ 危险 _ 操作模式。它重写了历史,当你已经发布了这段历史时,它并不是一个好兆头。除非您仔细阅读 git-rebase [1] ,否则不能使用此选项。 |
--no-rebase
先覆盖–rebase。
--autostash
--no-autostash
在开始 rebase 之前,根据需要隐藏本地修改(参见 git-stash [1] ),并在完成后应用存储条目。 --no-autostash
用于覆盖rebase.autoStash
配置变量(参见 git-config [1] )。
此选项仅在使用“–rebase”时有效。
Git 中文参考(三)(8)https://developer.aliyun.com/article/1565827