技术知识文章集合TECHNICAL ARCHIVE · 807 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTGIT

git pull & git push 的详细使用

所属分类
Git
文件格式
Markdown
原始路径
git/07-git pull & git push的详细使用
本文目录3 个章节
  1. git pull
  2. git fetch
  3. git push

git pull & git push 的详细使用

Category(分类): git Status: 已读

原文:git pull & git push的详细使用(CSDN)。 本文为整理版本,原文部分配图因防盗链缺失,此处已删除占位图,保留文字讲解与有效配图。

git pull

常用

pull 意为拉,这里引申为拉取代码。

在 Git 命令中使用 pull,会将你的远程代码拉取到本地并进行合并。

格式:

git pull <远程主机名> <远程分支名>:<本地分支名>

如果远程分支是与当前分支合并,则冒号后面的部分可以省略。

比如一般的,在公司中,我们都会自己在本地建一个和公司分支名相同的分支,这里取名为 test-git。

那么这个命令一般为:

git pull origin test-git

这表示我们拉取远程(origin 一般为远程主机名)分支 test-git 到本地分支 test-git 并进行合并。

工作流程

git pull 命令首先会执行 git fetch 命令,这一操作用于下载远程仓库的内容。之后执行 git merge 命令来合并远程内容,合并的结果会在本地创建一个合并 commit。为了更好的理解这一系列下载和合并的流程,可以参考下图所示流程。假设我们的仓库有一个名叫 main 的分支以及一个别名为 origin 的远程仓库。

git pull 合并流程

在这一场景中,git pull 会以本地仓库 main 分支与远程仓库 main 分支分叉的那个 revision 节点为起点,下载对应本地仓库的远程仓库的所有更改。在这个例子中,这个节点即是 D 的下一节点,也就是 E。git pull 会下载分叉之后的远程 commits,也就是 A-B-C。之后 pull 流程会创建一个含有这些分叉的远程变更的 commit,将这些变更合并到本地仓库。

git pull 创建合并commit

在上边的图示中可见 commit H。这次 commit 就是那次新增加的 commit,其中含有远程仓库的 A-B-C 的提交节点,以及合并之后的 log 信息。这个示例是 git pull 可以使用的多个合并策略的其中一个。如果向 git pull 命令传递一个 --rebase 选项,那么合并策略则随之改变为 rebase 合并,而不是直接合并。

如使用了 rebase 合并的 pull 命令,没有创建一个新的 H commit。相反,rebase 过程中复制了远程仓库的 A-B-C 三个 commits 到本地仓库,然后重新排列了本地仓库 main 分支的提交历史,将本地在分岔点之后的新变更(E-F-G)排列到远程仓库的 C 节点之后。

省略写法

将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并:

git pull origin master:brantest

如果远程分支是与当前分支合并,则冒号后面的部分可以省略:

git pull origin master

在某些场合,Git 会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在 git clone 的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的 master 分支自动"追踪"origin/master 分支。

Git 也允许手动建立追踪关系:

$ git branch --set-upstream master origin/next

上面命令指定 master 分支追踪 origin/next 分支。

如果当前分支与远程分支存在追踪关系,git pull 就可以省略远程分支名:

git pull origin

上面命令表示,本地的当前分支自动与对应的 origin 主机"追踪分支"(remote-tracking branch)进行合并。

如果当前分支只有一个追踪分支,连远程主机名都可以省略:

git pull

上面命令表示,当前分支自动与唯一一个追踪分支进行合并。

如果合并需要采用 rebase 模式,可以使用 --rebase 选项:

git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

git fetch

常用

fetch 意为拿来,取来,这里引申为取来代码。

fetch 与 pull 不同之处在于,pull 相当于是 fetch 和 merge(合并)两者结合,fetch 单独拿出来,只是一个取,告诉 Git 去获取它有你没有的数据,我们 merge 之后,会将服务器上的任何更新(假设有人这时候推送到服务器了)合并到你的当前分支。

工作流程

Git 的 clone 命令会为你自动将远程主机命名为 origin,拉取它的所有数据,创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master。同时 Git 也会给你一个与 origin 的 master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础。

本地有提交,远程也有别人的推送:

远程库有人推送,提交了 C0 和 C1;本地提交了 D0 和 D1。只要你不与 origin 服务器连接,你的 origin/master 指针就不会移动。

同步:

如果要同步远程库到你的工作,运行 git fetch origin 命令:

git fetch origin

这个命令查找 "origin" 是哪一个服务器,从中抓取本地没有的数据,并且更新本地数据库,移动 origin/master 指针指向新的、更新后的位置。

要特别注意的一点是 fetch 抓取到新的远程跟踪分支时,本地的工作区(workspace)不会自动生成一份可编辑的副本,抓取结果是直接送到版本库(Repository)中。

打个比方,在远程库 origin 新建了一个分支 dev,git fetch 后本地不会生成一个新的分支 dev(可用 git branch 查看),只有一个不可以修改的 origin/dev 指针。

在 origin/master 后继续工作:

如果想要在 origin/master 分支上工作,可以新建分支 test 并将其建立在远程跟踪分支之上:

git checkout -b test origin/master

这会给你新建一个用于工作的本地分支 test,并且起点位于 origin/master。

合并:

如果想把拉取的结果合并到本地分支,需要手动合并。使用如下命令:

$ git checkout master
$ git merge origin/master

冲突解决

git 冲突的场景:

  • 情景一:多个分支代码合并到一个分支时;
  • 情景二:多个分支向同一个远端分支推送代码时。

实际上,push 操作即是将本地代码 merge 到远端库分支上。

关于 push 和 pull 其实就分别是用本地分支合并到远程分支、将远程分支合并到本地分支,所以这两个过程中也可能存在冲突。

git 的合并中产生冲突的具体情况:

  1. 两个分支中修改了同一个文件(不管什么地方);
  2. 两个分支中修改了同一个文件的名称。

两个分支中分别修改了不同文件中的部分,不会产生冲突,可以直接将两部分合并。

解决冲突的两种方式:自动解决和人工解决。

  • 自动解决:修改的地方内容不一样;
  • 人工解决:同时修改一个地方的内容,自动解决不了,需要人工解决。

查看冲突所在的文件(标红的位置就是冲突所在位置),用 ============ 隔开的两部分只能留下一部分,删除后再提交。

冲突标记示例

git push

常用写法及其省略格式

push 命令的作用是将本地当前分支的代码推送到远程指定的分支上,在多人协作中,小组成员就能在远程主机中看到自己修改的代码了。命令的格式如下:

git push <远程主机名> <本地分支名>:<远程分支名>

正常写法

填写所有的参数,这么写比较清晰明了,不容易弄混,适合 <本地分支名> 和 <远程分支名> 不一样的情况。举个栗子:

git push origin dev:test

意思是将本地的 dev 分支上的代码推送到远程主机名为 origin 中 test 的分支上。如果远程的 test 分支不存在,则会被创建,这也是一种创建远程分支的办法。

省略 :<远程分支名>

如果本地分支名和远程分支名一样的情况下,可以省略 :<远程分支名>。如果远程主机中不存在该分支,那么会被创建。我们就可以使用命令:

git push origin dev

来代替

git push origin dev:dev

省略 <远程主机名> 和 :<远程分支名>

如果本地分支已经跟远程分支建立了追踪关系,那么可以省略 <远程主机名> 和 :<远程分支名>。使用 git branch -vv 命令,可以查看本地分支跟远程分支是否存在追踪关系。

git push origin

来代替

git push origin master:master

如果当前分支没有追踪关系的远程分支会出现什么结果呢?我们来创建一个新的分支 stt,并将其设置为当前分支。使用命令 git checkout -b stt 创建一个新的分支 stt,参数 -b 的意思是将新创建的分支设置为当前分支。然后使用 git push origin 看能不能推送到远程。

结果出现一个 fatal 错误,提示说找不到上游的分支,意思就是远程没有与当前分支对应的追踪关系,需要用命令 git push --set-upstream origin stt 先建立关系才行。输入这条命令之后,git 会将本地 stt 分支推送到远程的 stt 分支上,并建立两者的追踪关系。

无上游分支报错

set-upstream 建立追踪关系

省略 <远程主机名> <本地分支名>:<远程分支名>

在之前的命令中,我们都会添加 <远程主机名> 来指定要推送到哪一台主机上,但如果连主机名都不想写,可以吗?当然可以,我们只需要保证本地仓库只跟一台远程主机有关联即可。其实我们在正常的开发中,远程主机确实只有一个,那就是我们克隆的远程项目的主机。如果不使用特殊的操作,根本用不着跟其他主机建立联系。

远程主机

假如我们当前的分支是在 dev 下面,所以我们就可以通过命令:

git push

来代替命令:

git push origin dev:dev

假如后来我们新增了一台或者多台远程主机(主机 2、主机 3、主机 4……等等),那么在使用 push 命令的时候就必须要加上 <远程主机名> 这个参数了。

807 DOCUMENTS · 12 COLLECTIONS
ARCHIVE SEARCH807 篇文章