暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

git基础之三

架构思考 2020-06-26
336

linux中的diff命令使用示例:

--- a.txt 表示要对源文件进行删减操作,+++ b.txt 表示要对目标文件进行增加操作。

@@ -1,3 +1,3 @@表示源文件从第一行开始的三行,目标文件从第一行开始的三行。

接下来的五行的意思是,a不变,删除b和c,加上e和f,就能从a.txt得到b.txt。



在git中,git diff命令用于比较工作区相对于暂存区的差异。

git diff HEAD用于比较工作区相对于最新提交的差异。

git diff --cached:用于比较暂存区相对于最新提交的差异。




本地代码仓如何与远程代码仓交互?

在github上新建一个repo,同时在本地新建一个repo,然后在本地代码仓中执行git remote add origin git@github.com:hz-tdso/testGit.git(在本地为远程代码仓git@github.com:hz-tdso/testGit.git起一个别名origin。)和git push -u origin master(将本地代码仓的代码推送到远程仓库)。


如果git push -u origin master失败,则需要在本地执行ssh-keygen生成公钥(保存在~/.ssh目录下)。然后在将公钥部署到github的代码中,并赋予公钥以write权限。然后就可以执行git push -u origin master了。


git remote show可以列出远程仓库的别名(默认就是origin)。

git remote show origin:可以列出远程仓库的详细信息。


此时查看分支图,则如下图所示:

发现本地会多出一个分支remotes/origin/master,这个分支是远程代码仓的分支在本地代码仓中的对应分支。


git pull其实包含两步,git fetch和git merge。先执行git fetch,将本地的origin/master更新为远程的master,然后执行git merge将origin/master合并到master分支上。git push时,git会先将master同步到origin/master上,然后将origin/master分支更新到远程的master上。(不确定)


此时,如果修改文件并commit,则git status如下:

提示我master分支超前origin/master分支一个提交。对应的分支图如下:



我本地创建了一个新文件,并进行了commit和push。此时,master和origin/master都指向最新的提交,HEAD指向master。此时如果执行git checkout remotes/origin/master,HEAD指针是直接指向remotes/origin/master所指向的commit节点的,而不是指向remotes/origin/master指针。git branch -av可以查看指针的指向情况:

可以看到HEAD是直接指向commit节点b9df48a的,而不是指向origin/master指针的。这说明git是不允许用户直接操作remotes/origin/master分支的。



现在有另一个用户2在我刚刚执行的push之前clone了代码仓。然后我push了,然后用户2执行git remote show origin,会得到如下提示:

提示用户2本地代码已经落后了。git能给出这个提示是因为git remote show origin命令会获取远程代码仓的分支信息,并与用户2的本地代码仓进行比较,推断出本地代码仓的分支落后了。


现在用户2执行git pull,会得到如下信息:

重点看“99503f9..b9df48a  master  ->  origin/master”这一行。

99503f9..b9df48a 表示用户2的本地代码仓中最新的commit节点从99503f9变成了b9df48a。

master  ->  origin/master 表示用户2的本地代码仓中代表着远程代码仓分支的origin/master与远程代码仓中的master分支保持一致。(箭头左侧的master是指远程代码仓中的master分支。)


上图信息中还告诉了用户2本次merge是fast-forward。git首先将远程代码仓的master分支同步到本地的origin/master上,然后将本地的origin/master分支合并到本地的master分支上。由于同步完成之后,本地的origin/master超前master一次提交。所以git会优先选择fast-forward方式进行merge。(个人理解,不太确定。)

----------------------------------------------------------------------------------

现在我和用户2与远程代码仓保持一致。

我修改了hello.txt的第一行,并commit和push了。分支图如下:

与此同时,用户2也修改了hello.txt的第一行,并正常commit了。分支图如下:

当用户2进行git push时,会报如下错误:

push失败了,显然是因为用户2和我修改了同一个文件的同一行导致的。git提示用户2先执行git pull。


用户2执行git pull时,会提示merge有冲突:


此时分支图如下:


与git pull之前用户2的分支图作对比,可以发现git首先将远程代码仓的master分支同步到了本地的origin/master上,然后试图将origin/master合并到master上。


当手动解决完冲突并git add和git commit之后,分支图如下:

git status给出如下信息:

提示说master分支超前origin/master两次提交,是add 4和add 3这两次?


然后执行git push,执行完之后分支图如下:


此时,我执行git pull,分支图变化如下:


git pull其实是整合了git fetch和git merge。下面再次模拟冲突,演示分步执行git fetch 和 git merge的效果。


我在本地把hello.txt修改为"hello wolrd 15"并push。

我的分支图(与远程代码仓的分支图一致)如下:


用户2在本地把hello.txt修改为"hello world 16"并commit。

此时,用户2的分支图如下:


用户2再执行git fetch,分支图如下:


可以看到,git fetch命令将远程的master分支同步到了origin/master分支上。再执行git merge origin/master,解决完冲突并git add 和git commit之后,分支图如下:

可以看到,分支图和直接执行git pull的效果是一样的。



我修改hello.txt,然后push,则我本地的分支图和远程的分支图如下:

用户2修改hello.txt,并commit,然后pull,得到的分支图如下:

用户2执行了git push,得到的分支图如下:


我执行git fetch之后的分支图如下:


我再执行git merge origin/master,得到的分支图如下:

可以看到,merge时实际上git是fast-forward了的,从git status也能得到验证:


文章转载自架构思考,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论