git pull & git push的详细使用

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的远程仓库。

img

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

img

在上边的图示中可见commit H。这次commit就是那次新增加的commit,其中含有远程仓库的A-B-C的提交节点,以及合并之后的log信息。这个示例是git pull可以使用的多个合并策略的其中一个。如果向git pull命令传递一个 --rebase选项,那么合并策略则随之改变为rebase合并,而不是直接合并。下个例子会展示rebase合并的pull命令是如何工作的。假设下面示例的工作场景与第一张示图的场景一致,然后我们在同一场景上执行了git pull --rebase

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OO0kgVJ-1680057907055)(git pull & git push的详细使用.assets/v2-7dee89e1cea7ce9a51ca8dc6942ce838_720w.webp)]

如上图所示,可以看到使用了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:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SgeLShYu-1680057907057)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azBsOTZzbHlqMzBvbTA2bjc0Yi5qcGc)]

本地提交了D0和D1:

只要你不与 origin 服务器连接,你的 origin/master 指针就不会移动。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H54LiM4p-1680057907059)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azBsenVsbG5qMzBvaDA4OXdlbS5qcGc)]

同步

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

git fetch origin

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NINvorth-1680057907061)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azByZG5pNGRqMzBtazBmdmRnZS5qcGc)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-isuRgguZ-1680057907063)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azB3enQwZ3ZqMzBtZDA2Zzc2dy5qcGc)]

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

在 origin/master 后继续工作

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

git checkout -b test origin/master

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HHCCQOrW-1680057907067)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azMzcnp2b3FqMzBtbDBiaW14Zi5qcGc)]

合并

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SKEtZIJD-1680057907069)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azM3Ync4OHJqMzBtbTA5b3dlcC5qcGc)]

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

$ git chekout master
$ git merge origin/master

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ot2cjuOL-1680057907071)(git pull & git push的详细使用.assets/aHR0cHM6Ly93czEuc2luYWltZy5jbi9sYXJnZS8wMDZWckpBSmd5MWc1azE3enBuaHhqMzBvaTA5dWFhYy5qcGc)]

冲突解决

git冲突的场景

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

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

关于push和pull其实就分别是用本地分支合并到远程分支 和 将远程分支合并到本地分支

所以这两个过程中也可能存在冲突。

git的合并中产生冲突的具体情况:
  <1>两个分支中修改了同一个文件(不管什么地方)
  <2>两个分支中修改了同一个文件的名称
两个分支中分别修改了不同文件中的部分,不会产生冲突,可以直接将两部分合并。

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

自动解决:修改的地方内容不一样,

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

查看冲突所在的文件:

img

标红的位置就是冲突所在位置

用===========隔开的两部分只能留下一部分

删除后在提交。

git push

常用写法及其省略格式

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

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

正常写法

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

git push origin dev:test

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

省略:<远程分支名>

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

git push origin dev

来代替

git push origin dev:dev

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

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

git push origin 

来代替

git push origin master:master

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

image-20230304192908472

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

在这里插入图片描述

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

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

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

git push

来代替命令:

git push origin dev:dev

需要保证本地仓库只跟一台远程主机有关联即可。其实我们在正常的开发中,远程主机确实只有一个,那就是我们克隆的远程项目的主机。如果不使用特殊的操作,根本用不着跟其他主机建立联系。
在这里插入图片描述

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

git push

来代替命令:

git push origin dev:dev

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

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐