小丁带你走进git世界五-远程仓库

一、文件,指令讲解

首先讲一下远程仓库和本地仓库在文件上面的区别,首先我们来看下对比图(当然这里说的区别是在于.git文件下面的文件内容,至于里面内容我们不会关注)這裡我们进行了相同的操作就是本地仓库里面新建了version.txt内容也是一样的v1.0:

图一

图二

图一为本地仓库,图二为克隆的远程仓库,首先我们应该看一下config里面的区别:

图三

图四

很容易看到了区别就是图四为远程仓库内容。

从这个文件中我们可以了解到:

1,本地库的当前分支为master,其关联的远程库名称为origin(不同的名称可以指向同一个远程库,参见git remote命令)

2,远程库origin所在的位置为(URL):https://github.com/dwlsxj/BattleHeart.git
然后进行了version.txt的编辑和提交。这是我们刚才新建version.txt(远程)以及再添加内容为“v1.0”,在添加到暂存区,提交到本地提交中,最后提交到远程服务器,下面是我们生成的commit对象和git对象还有就是tree对象内容:

$ find .git/objects/ -type f
.git/objects/18/6c4629f6de8c956548570a113fa181d9b22692   commit对象
.git/objects/90/e34626d7993cf8d6c5e3e458744df4a9a31594   tree对象
.git/objects/c6/94c68edd99aeefa053f25308cd71ecca922036   blob对象

接下来我们就来看一下这个commit对象和tree对象下面的树分支和commit的指向内容。

$ git cat-file -t 186c46
commit

$ git cat-file -t 90e346
tree

$ git cat-file -t c694c6
blob

$ git cat-file -p 186c46
tree 90e34626d7993cf8d6c5e3e458744df4a9a31594
author BattleHeart <[email protected]126.com> 1452303321 +0800
committer BattleHeart <[email protected]126.com> 1452303321 +0800
inital commit

$ git cat-file -p 90e346
100644 blob c694c68edd99aeefa053f25308cd71ecca922036    version.txt

$ git cat-file -p c694c6
V1.0

当我们git  push origin master(命令格式:git push [remote-name] [branch-name])时候会生成一个我们会发现.git/refs/文件夹下多了一个remote文件夹

我们跟进去看一下会有一个默认origin服务器名称,下面会有一个master分支,也就是这个代表的是远程服务器的master分支并不代表我们本地的master分支。看一下这个master分支内容和本地分支的内容是否一致,因为我们刚才将提交的内容提交到origin服务器上,应该两个分支引用指向的commit记录是一样的。

根据上面图中,标号1代表的是本地master分支指向的内容,而标号2代表的是远程服务器上面master分支只想的内容。(186c46正是我们的提交记录commit对象)
接下来我们的操作就是在进行添加一个本地内容修改下version.txt,修改内容为添加版本为v1.1。然后我们不提交到远程服务器上面看一下这两个master指向。当然不用猜就已经知道结果了,肯定指向的内容是不一样的。
修改文件后生成的blob对象

$ find .git/objects/  -type f
.git/objects/18/6c4629f6de8c956548570a113fa181d9b22692
.git/objects/90/e34626d7993cf8d6c5e3e458744df4a9a31594
.git/objects/9f/aadaec6f7c8657372544e6f414f9b0b6910279
.git/objects/c6/94c68edd99aeefa053f25308cd71ecca922036

提交到本地版本控制中。

$ git commit -m ‘second commit version.txt‘
[master 5777c82] second commit version.txt
1 file changed, 1 insertion(+)

提交之后产生的commit对象和新的tree对象内容

$ find .git/objects/ -type f
.git/objects/18/6c4629f6de8c956548570a113fa181d9b22692
.git/objects/57/77c8270e24ff7417fa6f8d27f73c068acd42b0
.git/objects/90/e34626d7993cf8d6c5e3e458744df4a9a31594
.git/objects/9f/aadaec6f7c8657372544e6f414f9b0b6910279
.git/objects/a4/3a49679a6ecd3cbcdd889aeb9906b8620e7976
.git/objects/c6/94c68edd99aeefa053f25308cd71ecca922036

看一下了两个master分支内容:

$ cat .git/refs/heads/master
5777c8270e24ff7417fa6f8d27f73c068acd42b0

$ cat .git/refs/remotes/origin/master
186c4629f6de8c956548570a113fa181d9b22692

啊哈,果然不出我们所料,这就是说明本地提交的记录还没有提交的远程服务器上面所以说这个远程服务器的master分支还是指向了原来的commit对象。
当我们使用的了git   fetch  [remote-name]从服务器里面拉去数据的时候会产生一个FETCH_HEAD指针。这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。这时候我们会发现有一个FETCH_HEAD指针是一个指向远程最后一次获取的指针位置。首先我们看一下这个FETCH_HEAD指针的主要作用:

也就是说我们每次获取的本地没有的文件后都会有一个fetch_HEAD,这个指针和本地的HEAD指针有着区别,这样我们现在还看不出来因为本地和服务器上的记录都是一样的。这时候我们来在服务器上面添加一个readme文件提交上去,再在本地获取。
添加readme文件这里是在服务器上直接提交的记录,所以跟本地数据没有任何关系。

当我们使用git  fetch  origin命令的之后,我们来看一下.git/objects在服务器上产生的新的commit记录和tree对象还有git对象内容。

$ find    .git/objects/ -type f
.git/objects/18/6c4629f6de8c956548570a113fa181d9b22692
.git/objects/50/204399d2b99a020ac03dbca151570a959b7523
.git/objects/56/f565ecbaa66b236c42914bfd7e93a5eb0844f7
.git/objects/57/77c8270e24ff7417fa6f8d27f73c068acd42b0
.git/objects/90/e34626d7993cf8d6c5e3e458744df4a9a31594
.git/objects/9f/aadaec6f7c8657372544e6f414f9b0b6910279
.git/objects/a4/3a49679a6ecd3cbcdd889aeb9906b8620e7976
.git/objects/c6/94c68edd99aeefa053f25308cd71ecca922036
.git/objects/e0/26393257f8b7519ac7c378c6ff470ca737fe10

这里面有三个对象是git  fetch后新增加的就是如下几个,然后我们通过查看其类型以及其中的内容就能看到确实是从服务器上拉取出来的数据。

$ git cat-file -t 502043
commit

$ git cat-file -p 502043
tree e026393257f8b7519ac7c378c6ff470ca737fe10
parent 186c4629f6de8c956548570a113fa181d9b22692
author BattleHeart <[email protected]> 1452324317 +0800
committer BattleHeart <[email protected]> 1452324317 +0800

Create commit Readme

Create commit Readme

$ git cat-file -t 56f565
blob

$ git cat-file -p 56f565
# BattleHeart
README

$ git cat-file -t e02639
tree

$ git cat-file -p e02639
100644 blob 56f565ecbaa66b236c42914bfd7e93a5eb0844f7    README.md
100644 blob c694c68edd99aeefa053f25308cd71ecca922036    version.txt

其实这时候我们来看一下git的历史记录图。

这里的lol命令是我取的别名log  –oneline  –decorate  –graph  –all。可以看到这个命令分了两个,就是说origin/master是服务器的master分支。我们来看一下master分支。

$ cat .git/refs/heads/master                       本地分支引用
5777c8270e24ff7417fa6f8d27f73c068acd42b0

$ cat .git/refs/remotes/origin/master     服务器master分支引用
50204399d2b99a020ac03dbca151570a959b7523

也就是说本地分支引用是没有变化的,变化的是服务器master分支引用的地址从186c46变化到了最新的502043这个commit提交记录上面了。其实这之后FETCH_HEAD也会将最新的commit记录在里面(这里不是指向master分支上而是指向了commit记录上面),也就是说FETCH_HEAD指的是: 某个branch在服务器上的最新状态。其中每一行对应于远程服务器的一个分支.当前分支指向FETCH_HEAD, 就是这个文件第一行对应的那个分支。这里服务器里面只有一个master分支是默认的分支。

虽然说拉去出来的数据但是并不是我们想要的,拉去的数据并没有放在本地仓库指向的内容里面而是服务器分支指向的内容里面。这时候我们是用git merge来进行合并。也就是说这个FETCH_HEAD里面存在的是服务器上每一个分支上面最后一个提交记录内容,当然我们也可以使用git  merge  FETCH_HEAD这个命令来合并分支,但是多条分支记录的时候他只会取出第一条merge记录。这时候我们就需要使用服务器的分支来进行合并了,比如origin/test指针就可以git  merge  origin/test。这与后面要讲的git  pull的区别就是从服务器上面获取下来的内容分支之类的不会直接合并到本地,而是自己去合并但是git pull是git pull = git fetch + git merge的操作。

git  pull命令:
接下来我们就来演示下git pull内容,首先我们在服务上面新建了一个空的仓库,把这个空的仓库拉到本地来,新建一个文件a,在文件a里面添加一条记录this is file a on local master,把他提交到本地仓库里面,我们看一下如下操作:
新建一个文件a并赋值。

$ echo ‘this is file a on local master‘ > a

看一下文件内容

$ cat a
this is file a on local master

添加到暂存区内将添加的文件

$ git add .

将文件添加版本记录中去。

$ git commit -m ‘local first commit‘
[master (root-commit) 7358cc0] local first commit
warning: LF will be replaced by CRLF in a.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)

create mode 100644 a

这时候看一下产生的对象

$ find .git/objects/ -type f
.git/objects/34/da50374fa7eaa9d2ea609198237ed8af97c7e9
.git/objects/73/58cc0797e6bf72393ab54c543c6261784c27dc
.git/objects/7e/8f2d0c90cdd5dffd9bfb5f32604f74199725e4

分别查看一下这些对象的类型以及对象的内容:

$ git cat-file -t 34da50
tree

$ git cat-file -p 34da50
100644 blob 7e8f2d0c90cdd5dffd9bfb5f32604f74199725e4    a

$ git cat-file -p 7e8f2d
this is file a on local master

$ git cat-file -p 7358cc
tree 34da50374fa7eaa9d2ea609198237ed8af97c7e9
author BattleHeart <[email protected]126.com> 1452330539 +0800
committer BattleHeart <[email protected]126.com> 1452330539 +0800

local first commit

这时候我们将新的文件提交到服务器上面。

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 235 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/dwlsxj/test.git
* [new branch]      master -> master

OK提交成功了,这时候.git/refs就会生成一个remote文件文件里面有默认服务器名称origin文件夹,该文件夹下面保存了服务器上最新的master分支指向的内容。让我们来看一下:

$ cat .git/refs/remotes/origin/master               服务器master分支
7358cc0797e6bf72393ab54c543c6261784c27dc

$ cat .git/refs/heads/master                              本地master分支
7358cc0797e6bf72393ab54c543c6261784c27dc

这时候是一样的,因为服务器分支和本地分支是一样的。接下来我们在服务器分支上面修改下a文件如下图所示:

这时候我们会想到服务器上面会产生commit记录这时候服务器的master分支的指向就不再是本地这个指向了。
这时候我们也来修改下本地的a文件。添加文本内容为this is file a on local master second edit。提交到版本控制中。看一下所有的操作内容:
编辑文件a

$ vim a

将a文件添加到暂存区内容

$ git add .
warning: LF will be replaced by CRLF in a.
The file will have its original line endings in your working directory.

看一下新生成的git对象内容

$ find .git/objects/ -type f
.git/objects/34/da50374fa7eaa9d2ea609198237ed8af97c7e9
.git/objects/73/58cc0797e6bf72393ab54c543c6261784c27dc
.git/objects/7e/8f2d0c90cdd5dffd9bfb5f32604f74199725e4
.git/objects/af/cc87af98402de78840dc0737700a62345abff4

将修改的a文件提交到记录里面。

$ git commit -m ‘local second commit on master‘
[master warning: LF will be replaced by CRLF in a.
The file will have its original line endings in your working directory.
de7c4cd] local second commit on master
warning: LF will be replaced by CRLF in a.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)

这时候我们来看一下提交记录的图,这时候HEAD指针是指向最新的master分支的,但是服务器的master分支则是指向原有的commit记录。

$ git lol
* de7c4cd (HEAD -> master) local second commit on master
* 7358cc0 (origin/master) local first commit

看一下产生的tree对象以及tree对象内容,还有commit对象。

$ find .git/objects/ -type f
.git/objects/34/da50374fa7eaa9d2ea609198237ed8af97c7e9
.git/objects/66/e33f7b7a44ad93bcb3a049075e666b9041f63c
.git/objects/73/58cc0797e6bf72393ab54c543c6261784c27dc
.git/objects/7e/8f2d0c90cdd5dffd9bfb5f32604f74199725e4
.git/objects/af/cc87af98402de78840dc0737700a62345abff4
.git/objects/de/7c4cd49e32f197afc6161d0d6f5e6d413212c8

$ git cat-file -t 66e33f
tree

$ git cat-file -p 66e33f
100644 blob afcc87af98402de78840dc0737700a62345abff4    a

$ git cat-file -p  afcc87
this is file a on local master
this is file a on local master second edit

$ git cat-file -p  de7c4c
tree 66e33f7b7a44ad93bcb3a049075e666b9041f63c
parent 7358cc0797e6bf72393ab54c543c6261784c27dc
author BattleHeart <[email protected]126.com> 1452331483 +0800
committer BattleHeart <[email protected]126.com> 1452331483 +0800

local second commit on master

OK,到了这里我们就要开始见证奇迹的时候到了,因为我们同时修改了a文件都是从第一次提交的commit记录里面衍生出来的(服务器上和本地提交),接下来就是见证奇迹了。

$ git pull origin
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/dwlsxj/test
7358cc0..67f70c5  master     -> origin/master
Auto-merging a
CONFLICT (content): Merge conflict in a
Automatic merge failed; fix conflicts and then commit the result.

Pull之后我们先不着急看a文件的内容,我们先来看一下生成的对象内容。

$ find .git/objects/ -type f
.git/objects/34/da50374fa7eaa9d2ea609198237ed8af97c7e9
.git/objects/59/7f7359a768d3e98b65cd8b1558e09489d920b3
.git/objects/66/e33f7b7a44ad93bcb3a049075e666b9041f63c
.git/objects/67/f70c522e9e5b748445abbb41ea0cfa0fd171f9
.git/objects/73/58cc0797e6bf72393ab54c543c6261784c27dc
.git/objects/7e/8f2d0c90cdd5dffd9bfb5f32604f74199725e4
.git/objects/af/cc87af98402de78840dc0737700a62345abff4
.git/objects/de/7c4cd49e32f197afc6161d0d6f5e6d413212c8
.git/objects/de/fb97746b25d3963454d4ff69fc903956b12075
.git/objects/f5/537ea43f681442d2656105a2f348284181ef95

接下来就要看一下新增加的对象内容,其实我们猜想就能才想到肯定有三个对象是git对象和commit对象、tree对象因为这是在服务器上提交记录产生的。那么还多一个对象是什么呢?我们来看一下吧。

[email protected] MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git cat-file -t 597f73   该对象是服务器上提交内容对象
blob

对象的内容如下

[email protected] MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git cat-file -p 597f73
this is file a on local master
this is file a on server master

接下来67f70c是提交记录,是和上面blob一起的

[email protected] MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git cat-file -t 67f70c
commit

[email protected]-20150201IC MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git cat-file -p 67f70c
tree f5537ea43f681442d2656105a2f348284181ef95
parent 7358cc0797e6bf72393ab54c543c6261784c27dc
author BattleHeart <[email protected]> 1452330567 +0800
committer BattleHeart <[email protected]> 1452330567 +0800

this is file a on server master

this is file a on server master

接下来是tree对象内容,都是服务器上第二次提交产生的。

[email protected] MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git cat-file -t f5537ea
tree

$ git cat-file -p f5537ea
100644 blob 597f7359a768d3e98b65cd8b1558e09489d920b3    a
$ git cat-file -t defb97
blob

哎呦,这个对象叼了,这个对象是在本地产生的,产生的冲突文件,我们会发现我没有将Administrator这一行去掉是因为我们现在文件是由冲突的,我们可以看到master|MERGING

[email protected] MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git cat-file -p defb97
this is file a on local master
<<<<<<< HEAD
this is file a on local master second edit
=======
this is file a on server master
>>>>>>> 67f70c522e9e5b748445abbb41ea0cfa0fd171f9

那么下来我们看一下commit的图是如何的:

我们发现origin/master分支指向也更新为了最新的记录。并且现在还是两个分支,因为还有冲突没有解决。这时候我们需要解决冲突在提交就好了。

并将其提交到记录里面这时候我们就会发现最后的commit图就合并到了一起。

[email protected] MINGW64 ~/Desktop/rrr/test (master|MERGING)
$ git add .

$ git commit -m ‘merge‘
[master 0dd66df] merge

[email protected]-20150201IC MINGW64 ~/Desktop/rrr/test (master)
$ git lol
*   0dd66df (HEAD -> master) merge

|
| * 67f70c5 (origin/master) this is file a on server master

* | de7c4cd local second commit on master

|/

* 7358cc0 local first commit

最后来一张图清晰地告诉大家git fetch和git push的区别。

二、结束语

本篇文章分析完毕,希望各位能够喜欢并且指正里面的错误,分析的有不正确的就指出来。谢谢啦。

时间: 2024-10-25 05:28:47

小丁带你走进git世界五-远程仓库的相关文章

小丁带你走进git的世界三-撤销修改(转)

一.撤销指令 git checkout还原工作区的功能 git reset  还原暂存区的功能 git clean  还没有被添加进暂存区的文件也就是git还没有跟踪的文件可以使用这个命令清除他们 git revert 撤销本次提交. 二.指令讲解 Git checkout 首先我们对文件的一个修改,对master.txt进行了修改 修改结果我们利用上面的知识来进行查看. 新增加了Test这么一段话,如果我们想要将工作区的内容添加到暂存区会使用git  add这个命令,如果我们想要还原工作区内容

小丁带你走进git的世界四-重写历史记录

一.git对象文件创建 开篇先补充一个知识点,就是比如我建立一个文件之后,使用git add就会生成一个git对象,但是git对象生成后可以在.git/objects里面对应,首先我们来初始化一个仓库git init. $ git init 然后我们来创建两个文件文件名分别为a和b. $ touch a b 将a文件添加到暂存区,然后再将b添加到暂存区,我们会想到这时候有两个git对象产生,但是git对象对应.git/objects文件. $ git add . $ find .git/obje

小丁带你走进git的世界三-撤销修改

一.撤销指令 git checkout还原工作区的功能 git reset  还原暂存区的功能 git clean  还没有被添加进暂存区的文件也就是git还没有跟踪的文件可以使用这个命令清除他们 git revert 撤销本次提交. 二.指令讲解 Git checkout 首先我们对文件的一个修改,对master.txt进行了修改 修改结果我们利用上面的知识来进行查看. 新增加了Test这么一段话,如果我们想要将工作区的内容添加到暂存区会使用git  add这个命令,如果我们想要还原工作区内容

小心公共wifi 之小白客带你走进黑客世界:kali linux下的无线攻击技术

本文标签: 黑客世界 wifi安全 无线攻击技术 公共wifi不安全 kali+linux 原文地址:http://whosmall.com/?post=460 我们常说公共wifi不安全,那么到底不安全在哪些地方呢?当不怀好意者和你同在一个wifi下,你的手机或者笔记本会被监听吗?除了上网被监视以外,还会产生什么不好的后果?介于小伙伴们对于wifi这一块比较感兴趣,在这篇文章里,就先为大家普及一下在公共wifi下究竟有多危险. 实验环境 一台装有kali linux的笔记本(模拟攻击者)ip地

小丁是怎样入门git的

0x01前言 既然没有华丽的出场,那就平凡的分享,首先我要说明一点本篇文章针对Git初学者,对我自己学Git的资源的整合,其实本篇索引应该在我写Git系列文章的时候就紧跟着放上索引的,由于时间问题没有来得及整理,这里我详细整理下文章内容.其实说到git的文章已经很多了,这里分享下我的学习过程和自己摸索的过程. 个人整理Git学习资源请点击这里:(yes,I’m here)       1.小丁带你走进Git世界一-git简单配置 http://www.cnblogs.com/dwlsxj/p/G

带你走进虚拟化世界之kvm(转载)

http://chuck.blog.51cto.com/10232880/1720953 带你走进虚拟化世界之kvm 2015-12-08 23:10:46 标签:云计算 虚拟化 kvm 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://chuck.blog.51cto.com/10232880/1720953 一.走进云计算 云计算:云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问, 进入可配置的计算

带你走进虚拟化世界之KVM

带你走进虚拟化世界之KVM 一.走进云计算 云计算:云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问, 进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务),这些资源能够被快速提供,只需投入很少的管理工作,或与服务供应商进行很少的交互. 1.1 云计算的特点和优势 1)云计算是一种使用模式 2)云计算必须通过网络访问 3)弹性计算,按需付费 1.2 在云计算之前的模式或技术 1)IDC托管 2)IDC租用 3)虚拟主机(卖空间的) 4)vps:虚拟专

Git 学习笔记&lt;远程仓库与标签管理&gt; (四)

什么是远程仓库? 就像第一章介绍的那样,远程仓库可以储存你编写的所有源码和资源文件. 甚至也可以当网盘使,不过当然有很多契合git管理文本的特性. 下面就要以 github 为示例远程仓库进行介绍.  (也可以自己弄一台服务器作远程仓库). 创建仓库 在主页找到 +New repository 或者右上角的加号里有.输入名字 描述 然后没钱只能public就能确定了.然后呢,点名字打开你的仓库.(主页右下角可以找到) 关于与远程仓库的连接 首先你打开你的保险箱得先证明身份吧,不然我怎么知道你是客

解决git push至远程仓库失败的问题

产生问题的原因: 远程仓库存在本地不存在的文件, 一个常见的例子是创建repository时勾选了README.md, 但此时本地还没有这个文件, 就会导致本地文件无法同步到远程仓库的问题. 解决方法: 在git push至远程仓库之前, 先将远程仓库文件同步至本地. 执行下面命令 git pull --rebase origin master 原文地址:https://www.cnblogs.com/shaohsiung/p/9535934.html