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的远程仓库。
在这一场景中,
git pull
会以本地仓库main分支与远程仓库main分支分叉的那个revision节点为起点,下载对应本地仓库的远程仓库的所有更改。在这个例子中,这个节点即是D的下一节点,也就是E。
git pull
会下载分叉之后的远程commits,也就是A-B-C。之后pull流程会创建一个含有这些分叉的远程变更的commit,将这些变更合并到本地仓库。
在上边的图示中可见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>两个分支中修改了同一个文件的名称
两个分支中分别修改了不同文件中的部分,不会产生冲突,可以直接将两部分合并。
解决冲突的两种方式:自动解决 和人工解决。
自动解决:修改的地方内容不一样,
人工解决:同时修改一个地方的内容,自动解决不了,需要人工解决。
查看冲突所在的文件:
标红的位置就是冲突所在位置
用===========隔开的两部分只能留下一部分
删除后在提交。
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命令,可以查看本地分支跟远程分支是否存在追踪关系,如下图所示,本地dev分支跟远程origin/dev分支存在追踪关系,本地master分支跟远程origin/master分支有追踪关系。
git push origin
来代替
git push origin master:master
如果当前分支没有追踪关系的远程分支会出现什么结果呢?我们来创建一个新的分支,并将其设置为当前分支。
使用命令git checkout -b stt创建一个新的分支stt,参数-b的意思是将新创建的分支设置为当前分支。然后使用git push origin看能不能推送到远程。结果如下图:
我们发现出现一个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
命令的时候就必须要加上
<远程主机名>
这个参数了
版权归原作者 马踏飞燕&lin_li 所有, 如有侵权,请联系我们删除。