git pull
git-pull
Name
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
。
<repository> 应该是传递给 git-fetch [1]的远程仓库的名称。 <refspec> 可以为任意的远程参考(例如,标签的名称)或者甚至是具有相应远程跟踪分支的参考集合(例如,refs / heads / *:refs / remotes / origin / *)命名,但是通常它是远程存储库中分支的名称。
从 git-branch [1]设置的当前分支的“remote”和“merge”配置中读取 <repository> 和 <branch> 的默认值--track。
假设存在以下历史记录并且当前分支是“ master
”:
A---B---C master on origin
/
D---E---F---G master
^
origin/master in your repository
然后,“ git pull
”将从远程master
分支获取并重放更改,因为它从本地master
(即E
)分离,直到其当前的
commit(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]提取或存储它们之前,先在工作顺序中进行任何本地更改。
选项
-q --quiet
这被传递给底层的 git-fetch,以便在传输过程中压制报告,并在合并过程中将潜在的 git-merge 压制成静噪输出。
-v --verbose
Pass --verbose git-fetch 和 git-merge。
--no-递归-子模块= YES |on-demand| 无
该选项控制是否应该提取和更新所有已填充子模块的新提交(请参阅 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
即使合并解析为快进,也可以创建合并提交。这是合并注释(可能有符号)标记时的默认行为。
--ff-only
拒绝合并而后以非零状态退出,除非电流HEAD
已经是最新的或合并可以解决为快进。
--log=<n> --no-log
除了分支名称之外,还可以用来自至多 <n> 实际提交的单行描述来填充日志消息。另请参阅 git-fmt-merge-msg [1]。
使用 --no-log 不会列出要合并的实际提交的单行描述。
--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 | preserve | interactive
如果为 true,则在获取后重新绑定上游分支顶部的当前分支。如果存在与上游分支相对应的远程跟踪分支,并且上游分支自上次获取后重新分配,则重新分配使用该信息以避免重新分配非本地更改。
设置为保留时,使用--preserve-merges
传递给选项的
rebase,git rebase
以便本地创建的合并提交不会变平。
如果为 false,则将当前分支合并到上游分支中。
当interactive
,使得交互模式重新调整。
如果你想让git pull经常使用 --rebase而不是合并,看pull.rebase,branch.<name>.rebase 和branch.autoSetupRebase在 git-config [1],
Note | This is a potentially dangerous mode of operation. It rewrites history, which does not bode well when you published that history already. Do not use this option unless you have read git-rebase1 carefully. |
---|
--no-rebase
早先覆盖--rebase。
--autostash --no-autostash
在开始 rebase 之前,如果需要,将局部修改存储(请参阅 git-stash [1]),并在完成时应用存储条目。--no-autostash
可以覆盖rebase.autoStash
配置变量(请参阅 git-config [1])。
该选项仅在使用“--rebase”时有效。
与 fetch 相关的选项
--all
取回所有远端。
-a --append
追加 refs 的 ref 名称和对象名称到现有的内容.git/FETCH_HEAD
。如果没有这个选项,旧的数据.git/FETCH_HEAD
将被覆盖。
--depth=<depth>
将提取限制为从每个远程分支历史记录的提示中指定的提交数量。如果获取到由git clone创建的 --depth=<depth> 选项(请参阅 git-clone [1]),请将历史记录加深或缩短为指定的提交数。深化提交的标签不会被提取。
--deepen=<depth>
与 --depth 相似,只是它指定了来自当前浅层边界而不是每个远程分支历史记录的提示的提交数。
--shallow-since=<date>
加深或缩短浅储存库的历史记录以在 <date> 之后包含所有可访问的提交。
--shallow-exclude=<revision>
加深或缩短浅储存库的历史记录以排除可从指定远程分支或标记访问的提交。该选项可以多次指定。
--unshallow
如果源存储库已完成,请将浅层存储库转换为完整存储库,以消除浅存储库施加的所有限制。
如果源存储库较浅,则尽可能多地获取,以便当前存储库具有与源存储库相同的历史记录。
--update-shallow
默认情况下,从浅仓库中获取时,git fetch
拒绝需要更新 .git / shallow 的引用。该选项更新 .git / shallow 并接受此类参考。
-f --force
当git fetch与<rbranch>:<lbranch> refspec 一起使用时,它拒绝更新本地分支<lbranch>,除非<rbranch>获取的远程分支是后代<lbranch>。该选项将覆盖该检查。
-k --keep
持续下载的包。
--no-tags
默认情况下,指向从远程存储库下载的对象的标签将在本地获取并存储。该选项将禁用此自动标记。远程的默认行为可以通过远程。<name> .tagOpt 设置指定。请参阅 git-config [1]。
-u --update-head-ok
默认情况下git fetch
拒绝更新对应于当前分支的前端。此标志禁用检查。这纯粹是供内部使用git pull
来沟通git fetch
,除非你是该项目的拥有者,否则你不应该使用它。
--upload-pack <upload-pack>
当给出并且从中获取的存储库被处理时git fetch-pack,--exec=<upload-pack>被传递给该命令以指定在另一端运行的命令的非默认路径。
--progress
当连接到终端时,默认情况下,标准错误流中会报告进度状态,除非指定了 -q 。即使标准错误流未定向到终端,此标志也会强制进度状态。
-4 --ipv4
仅使用 IPv4 地址,忽略 IPv6 地址。
-6 --ipv6
仅使用 IPv6 地址,忽略 IPv4 地址。
<repository>
作为提取或拉取操作源的“远程”存储库。此参数可以是 URL(请参阅下面的 GIT URLS 部分)或远程名称(请参阅下面的 REMOTES 部分)。
<refspec>
指定要获取哪些引用以及哪些本地引用要更新。当命令行中没有 <refspec> 时,remote.<repository>.fetch取而代之的是从变量中读取(参见 git-fetch [1])。
一个 <refspec> 参数的格式是一个可选的 plus +,后跟 source <src>,后跟一个冒号:,后跟目标 ref <dst>。当 <dst> 为空时,可以省略冒号。<src> 通常是 ref,但它也可以是拼写完整的十六进制对象名称。
tag <tag>意味着与refs/tags/<tag>:refs/tags/<tag>相同; 它请求将所有内容都提取到给定的标签。
匹配 <src> 的远程 ref 被取出,如果 <dst> 不是空字符串,匹配它的本地引用使用 <src> 进行快速转发。如果使用可选的 plus +,即使不引起快速更新,本地 ref 也会被更新。
Note | When the remote branch you want to fetch is known to be rewound and rebased regularly, it is expected that its new tip will not be descendant of its previous tip (as stored in your remote-tracking branch the last time you fetched). You would want to use the + sign to indicate non-fast-forward updates will be needed for such branches. There is no way to determine or declare that a branch will be made available in a repository with this behavior; the pulling user simply must know this is the expected usage pattern for a branch. |
---|
Note | There is a difference between listing multiple |
---|
Git 网址
通常,URL 包含有关传输协议,远程服务器地址和存储库路径的信息。根据传输协议,这些信息可能不存在。
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/
- https://host.xz:port/path/to/repo.git/
- ftps://host.xz:port/path/to/repo.git/
ssh 协议也可以使用另一种类似 scp 的语法:
- user@host.xz:path / to / repo.git /只有在第一个冒号前没有斜线时才能识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径
foo:bar
可以被指定为绝对路径或./foo:bar
避免被误解为 ssh url。ssh 和 git 协议还支持〜用户名扩展:
- 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/
对于本地支持的本地存储库,可以使用以下语法:
- /path/to/repo.git/
- file:///path/to/repo.git/
这两种语法大多是相同的,除了克隆时,前者意味着 --local 选项。有关详细信息,请参阅 git-clone [1]。
当 Git 不知道如何处理某个传输协议时,它会尝试使用remote-<transport>远程助手(如果存在)。要显式请求远程助手,可以使用以下语法:
- <transport>::<address>where <address> may be a path, a server and path, or an arbitrary URL-like string recognized by the specific remote helper being invoked. See gitremote-helpers[1] for details.If there are a large number of similarly-named remote repositories and you want to use a different format for them (such that the URLs you use will be rewritten into URLs that work), you can create a configuration section of the form: [url "<actual url base>"] insteadOf = <other url base>For example, with this: [url "git://git.host.xz/"] insteadOf = host.xz:/path/to/ insteadOf = work:a URL like "work:repo.git" or like "host.xz:/path/to/repo.git" will be rewritten in any context that takes a URL to be "git://git.host.xz/repo.git".If you want to rewrite URLs for push only, you can create a configuration section of the form: [url "<actual url base>"] pushInsteadOf = <other url base>For example, with this: [url "ssh://example.org/"] pushInsteadOf = git://example.org/a URL like "git://example.org/path/to/repo.git" will be rewritten to "ssh://example.org/path/to/repo.git" for pushes, but pulls will still use the original URL.RemotesThe name of one of the following can be used instead of a URL as <repository> argument:
- a remote in the Git configuration file:
$GIT_DIR/config
,
- a file in the
$GIT_DIR/remotes
directory, or
- a file in the
$GIT_DIR/branches
directory.
All of these also allow you to omit the refspec from the command line because they each contain a refspec which git will use by default.
Named remote in configuration file
You can choose to provide the name of a remote which you had previously configured using git-remote[1], git-config[1] or even by a manual edit to the $GIT_DIR/config
file. The URL of this remote will be used to access the repository. The refspec of this remote will be used by default when you do not provide a refspec on the command line. The entry in the config file would appear like this:
[remote "<name>"]
url = <url>
pushurl = <pushurl>
push = <refspec>
fetch = <refspec>
The <pushurl> is used for pushes only. It is optional and defaults to <url>.
Named file in $GIT_DIR/remotes
You can choose to provide the name of a file in $GIT_DIR/remotes
. The URL in this file will be used to access the repository. The refspec in this file will be used as default when you do not provide a refspec on the command line. This file should have the following format:
URL: one of the above URL format
Push: <refspec>
Pull: <refspec>
Push:
lines are used by git push
and Pull:
lines are used by git pull
and git fetch
. Multiple Push:
and Pull:
lines may be specified for additional branch mappings.
Named file in $GIT_DIR/branches
You can choose to provide the name of a file in $GIT_DIR/branches
. The URL in this file will be used to access the repository. This file should have the following format:
<url>#<head>
<url> is required; #<head> is optional.
Depending on the operation, git will use one of the following refspecs, if you don’t provide one on the command line. <branch> is the name of this file in $GIT_DIR/branches and <head> defaults to master.
git fetch uses:
refs/heads/<head>:refs/heads/<branch>
git push uses:
HEAD:refs/heads/<head>
Merge strategies
The merge mechanism (git merge and git pull commands) allows the backend merge strategies to be chosen with -s option. Some strategies can also take their own options, which can be passed by giving -X<option> arguments to git merge and/or git pull.
resolve
This can only resolve two heads (i.e. the current branch and another branch you pulled from) using a 3-way merge algorithm. It tries to carefully detect criss-cross merge ambiguities and is considered generally safe and fast.
recursive
This can only resolve two heads using a 3-way merge algorithm. When there is more than one common ancestor that can be used for 3-way merge, it creates a merged tree of the common ancestors and uses that as the reference tree for the 3-way merge. This has been reported to result in fewer merge conflicts without causing mismerges by tests done on actual merge commits taken from Linux 2.6 kernel development history. Additionally this can detect and handle merges involving renames. This is the default merge strategy when pulling or merging one branch.
The recursive
strategy can take the following options:
ours
This option forces conflicting hunks to be auto-resolved cleanly by favoring our
version. Changes from the other tree that do not conflict with our
side are reflected to the merge result. For a binary file, the entire contents are taken from our
side.
This should not be confused with the ours
merge strategy, which does not even look at what the other tree contains at all. It discards everything the other tree did, declaring our
history contains all that happened in it.
theirs
This is the opposite of ours
; note that, unlike ours
, there is no theirs
merge stragegy to confuse this merge option with.
patience
With this option, merge-recursive
spends a little extra time to avoid mismerges that sometimes occur due to unimportant matching lines (e.g., braces from distinct functions). Use this when the branches to be merged have diverged wildly. See also git-diff[1] --patience
.
diff-algorithm=patience|minimal|histogram|myers
Tells merge-recursive
to use a different diff algorithm, which can help avoid mismerges that occur due to unimportant matching lines (such as braces from distinct functions). See also git-diff[1] --diff-algorithm
.
ignore-space-change ignore-all-space ignore-space-at-eol
Treats lines with the indicated type of whitespace change as unchanged for the sake of a three-w
ay merge. Whitespace changes mixed with other changes to a line are not ignored. See also git-diff[1] -b
, -w
, and --ignore-space-at-eol
.
- If
their
version only introduces whitespace changes to a line,our
version is used;
- If
our
version introduces whitespace changes buttheir
version includes a substantial change,their
version is used;
- Otherwise, the merge proceeds in the usual way. renormalize This runs a virtual check-out and check-in of all three stages of a file when resolving a three-way merge. This option is meant to be used when merging branches with different clean filters or end-of-line normalization rules. See "Merging branches with differing checkin/checkout attributes" in gitattributes[5] for details. no-renormalize Disables the renormalize option. This overrides the merge.renormalize configuration variable. no-renames Turn off rename detection. See also git-diff[1] --no-renames. find-renames=<n> Turn on rename detection, optionally setting the similarity threshold. This is the default. See also git-diff[1] --find-renames. rename-threshold=<n> Deprecated synonym for find-renames=<n>. subtree=<path> This option is a more advanced form of subtree strategy, where the strategy makes a guess on how two trees must be shifted to match with each other when merging. Instead, the specified path is prefixed (or stripped from the beginning) to make the shape of two trees to match. octopus This resolves cases with more than two heads, but refuses to do a complex merge that needs manual resolution. It is primarily meant to be used for bundling topic branch heads together. This is the default merge strategy when pulling or merging more than one branch. ours This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches. Note that this is different from the -Xours option to the recursive merge strategy. subtree This is a modified recursive strategy. When merging trees A and B, if B corresponds to a subtree of A, B is first adjusted to match the tree structure of A, instead of reading the trees at the same level. This adjustment is also done to the common ancestor tree.With the strategies that use 3-way merge (including the default, recursive), if a change is made on both branches, but later reverted on one of the branches, that change will be present in the merged result; some people find this behavior confusing. It occurs because only the heads and the merge base are considered when performing a merge, not the individual commits. The merge algorithm therefore considers the reverted change as no change at all, and substitutes the changed version instead.Default behaviourOften people use git pull without giving any parameter. Traditionally, this has been equivalent to saying git pull origin. However, when configuration branch.<name>.remote is present while on branch <name>, that value is used instead of origin.In order to determine what URL to use to fetch from, the value of the configuration remote.<origin>.url is consulted and if there is not any such variable, the value on the URL: line in $GIT_DIR/remotes/<origin> is used.In order to determine what remote branches to fetch (and optionally store in the remote-tracking branches) when the command is run without any refspec parameters on the command line, values of the configuration variable remote.<origin>.fetch are consulted, and if there aren’t any, $GIT_DIR/remotes/<origin> is consulted and its Pull: lines are used. In addition to the refspec formats described in the OPTIONS section, you can have a globbing refspec that looks like this:refs/heads/*:refs/remotes/origin/*A globbing refspec must have a non-empty RHS (i.e. must store what were fetched in remote-tracking branches), and its LHS and RHS must end with /*. The above specifies that all remote branches are tracked using remote-tracking branches in refs/remotes/origin/ hierarchy under the same name.The rule to determine which remote branch to merge after fetching is a bit involved, in order not to break backward compatibility.If explicit refspecs were given on the command line of git pull, they are all merged.When no refspec was given on the command line, then git pull uses the refspec from the configuration or $GIT_DIR/remotes/<origin>. In such cases, the following rules apply:
- If branch.<name>.merge configuration for the current branch <name> exists, that is the name of the branch at the remote site that is merged.
- If the refspec is a globbing one, nothing is merged.
- Otherwise the remote branch of the first refspec is merged.
Examples
- Update the remote-tracking branches for the repository you cloned from, then merge one of them into your current branch: $ git pull $ git pull originNormally the branch merged in is the HEAD of the remote repository, but the choice is determined by the branch.<name>.remote and branch.<name>.merge options; see git-config[1] for details.
- Merge into the current branch the remote branch
next
:
$ git pull origin next
This leaves a copy of next
temporarily in FETCH_HEAD, but does not update any remote-tracking branches. Using remote-tracking branches, the same can be done by invoking fetch and merge:
$ git fetch origin $ git merge origin/next
If you tried a pull which resulted in complex conflicts and would want to start over, you can recover with git reset
.
Security
The fetch and push protocols are not designed to prevent one side from stealing data from the other repository that was not intended to be shared. If you have private data that you need to protect from a malicious peer, your best option is to store it in another repository. This applies to both clients and servers. In particular, namespaces on a server are not effective for read access control; you should only grant read access to a namespace to clients that you would trust with read access to the entire repository.
The known attack vectors are as follows:
- The victim sends "have" lines advertising the IDs of objects it has that are not explicitly intended to be shared but can be used to optimize the transfer if the peer also has them. The attacker chooses an object ID X to steal and sends a ref to X, but isn’t required to send the content of X because the victim already has it. Now the victim believes that the attacker has X, and it sends the content of X back to the attacker later. (This attack is most straightforward for a client to perform on a server, by creating a ref to X in the namespace the client has access to and then fetching it. The most likely way for a server to perform it on a client is to "merge" X into a public branch and hope that the user does additional work on this branch and pushes it back to the server without noticing the merge.)
- As in #1, the attacker chooses an object ID X to steal. The victim sends an object Y that the attacker already has, and the attacker falsely claims to have X and not Y, so the victim sends Y as a delta against X. The delta reveals regions of X that are similar to Y to the attacker.
Bugs
Using --recurse-submodules can only fetch new commits in already checked out submodules right now. When e.g. upstream added a new submodule in the just fetched commits of the superproject the submodule itself can not be fetched, making it impossible to check out that submodule later without having to do a fetch again. This is expected to be fixed in a future Git version.
See also
git-fetch[1], git-merge[1], git-config[1]