Git-初步

关于Git工作区、暂存区、版本库几个概念用一张图片来说明:

对于上图的9点说明:

1、图中左侧为工作区,右侧为版本库。在版本库中标记为index的区域是暂存区,标记为master的是master分支所代表的目录树。

2、图中可以看出,此时HEAD实际是指向master分支的一个“游标”,所以图示的命令中出现HEAD的地方可以用master来替换

3、图中的objects标示的区域为git的对象库,实际位于.git/objects目录下

4、当对工作区修改(新增)的文件执行git add命令时,

  • 4.1、暂存区的目录树会被更新
  • 4.2、工作区修改(新增)的文件内容会被写入到对象库的一个新对象中
  • 4.3、该对象的ID被记录在暂存区的文件索引中

5、当执行提交(git commit)操作时

  • 5.1、暂存区的目录树会写到版本库(对象库)中
  • 5.2、master分支会做响应的更新,即master最新指向的目录树就是提交时原暂存区的目录树

6、当执行 git reset HEAD 命令时

  • 6.1、暂存区的目录树会被重写,会被master分支指向的目录树所替换,但是工作区不受影响

7、当执行git rm --cached <file> 命令时

  • 7.1、直接从暂存区删除文件,工作区则不会改变

8、当执行 git checkout . 或者 git checkout -- <file>命令时:

  • 8.1、会用暂存区全部的文件或者指定的文件替换工作区的文件,这个操作很危险,会清除工作区中未添加到暂存区的改动。

9、当执行 git checkout HEAD . 或 git checkout HEAD <file>命令时

  • 9.1、用HEAD指向的master分支中的全部或部分文件替换暂存区和工作区中的文件。这个命令也是危险的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

关于git diff命令的说明,如下图所示:

通过使用不同的参数调用git diff命令,可以对工作区、暂存区和HEAD中的内容进行比较,上图就展示了不同的git diff命令的作用范围。


一、

You Job is create text File.

版本控制软件用来回朔自己所做的修改。


Git采用的方式是,对文件做的每一点细微的改动,都单独保存为一个新的文件,然后对该文件用SHA1加密算法压缩,任何一个文件都可以被该算法压缩成20个字节。

也就是说,有2的160次方个文件。压缩后的文件就像原文件的指纹。


SHA1 文件名 //不管多大的文件经过该命令后,就生成了20个字节用来代表原文件。


Git is at it's heart very stupid simple.  Git从本质上来说非常简单。愚蠢的简单、精妙的设计

道生一、一生二、二生三、三生万物。

Git的学习还是从底层的模型、原理学起。这样的学习曲线能更容易掌握。

================================================================

二、

Git的由来,由linux内核的开发者所创造。

Git的意思:“Git  which is British English slang fora stupid or unpleasant person.

linux下的安装:

1、在线安装:$apt-get install git-core

2、离线安装:

wget http://git-core.googlecode.com/files/git-1.7.7.1.tar.gz

tar -zxvf git git-1.7.7.1.tar.gz

cd git-1.7.7.1

===============================================================

三、

1、初始化仓库repository

git init

2、提交自己的name 和 邮件地址【对文件的修改人的记录】说明,以后对源码的提交和修改都是这个人做的。可以通过email联系到修改人。

git config --global user.name 'yinjk'

git config --global user.email 'yinjk@neusoft.com'

3、刚才提交的信息在哪儿放着呢?

cd ~转到家目录,在家目录下有一个.gitconfig文件,其中包含了我们在第二步种添加的信息。

4、cd - 回到我们刚才的的工作目录

5、在工作目录的.git目录下也有一个config文件

然后,执行 git config user.name 'fangchengping'

git config user.email fangchengping@neusoft.com

注意观察config文件内的变化,多了刚才添加的人员信息。

说明:git有2个配置文件,一个在家目录下,为全局的配置文件,一个在仓库的根目录下有一个配置文件。有的还在/etc目录下有配置文件。

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

git的三个区域

1、Repository  //执行git init 之后生成的一个空的仓库,我们将来所有的代码都放到该仓库中...,如果将来想copy仓库到某地方,只要copy该目录.git到其它地方即可。

2、Working directory //就是我们刚才建立main.c所在的目录,只不过main.c没有被git管理起来

3、Staging area / index  //在你Working directory中的内容要提交到仓库中,不能一步到位,而是先提交到该Stage area区,之后才能提交到Repository数据仓库中

命令:git add '文件名"放到Staging area,然后git commit ,把文件放到Repository数据仓库中。

如: git add main.c  //执行该命令后,在.git目录下面多了一个index文件

git commit -m "Init Project"//-m 后面接着的是你提交文件时的一些注释信息,供以后自己查看 【多了一个logs目录和一个COMMIT_EDITMSG文件】

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

对于以上的操作,我们已经把main.c提交到repository中了,现在把working directory中的main.c删除,然后从仓库里面检出来如下:

rm main.c

git checkout -f HEAD //在工作目录下就又找到了main.c

.git目录是真正的文件所在,要是把.git目录拿到别的地方,也可以直接使用该数据仓库中的文件,工作目录中的文件只是该文件的一个快照。所以丢失了无所谓,只要通过上面的命令就可以找回来

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

git的核心对象

每一个对象包含3部分:类型、大小、内容。

Every object consists of three things -- a type , a size and  content .The size is simply the size of contents,the contents depends on what type of object it is.and there are three different types of object.


git包括3种类型的对象:

blob:用于存储文件数据,通常是一个文件,树中的叶子节点

tree:像一个目录,它是一些其它树和叶子blob的集合。

      Tree is a simple object that has a bunch of pointers to blobs and other trees -- it generally represents the contents of a directory or sub directory.

commit:point to a single tree.making it as what the project looked like at a certain point in time.

      Commit object points to a single tree,marking it as what the project looked like at a certain point in time.it contains meta-information about that point in time,such as a timestamp,the author of the changes since the last commit ,a pointer to the previous commit ,etc.


通过命令 git show -s --pretty=raw "commint对象哈希值的前几位",可以查看commit对象的内容。

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

命令:git hash-object main.c //计算main.c文件的哈希值

git add . //把文件main.c加入到Staging area中 ,然后在.git/object/目录下面有一个fc目录,正好跟我们对文件main.c得到的哈希值的前俩个字母相同。然后进入该目录查看,看到里面有个文件,文件名正哈就是剩下的那38个字母。O(∩_∩)O哈哈~。它就是上面提到的blob对象,然而在该目录下面还有2个文件,他们分别代表tree对象和commit对象。

在工作目录总输入git show "哈希值的前几位" //只要跟其它的文件能区分开就可以。这个命令就可以看见刚才提交的文件的内容了。

要想查看.git/objects/目录下面的文件到底是blob、tree还是commit只用用命令git cat-file -t "哈希值的前几位"就可知道到底是何种git对象了。

我们查看一个tree对象包含的内容用如下命令:git ls-tree "tree对象哈希值的前几位",就可以看到该tree对象的内容。tree对象保存blob对象的名字。

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

4讲:

Tag object 

The tag object is a way to mark a specific commit as special in some way.it is normally used to tag certain commits as specific release or somethings along those lines.


5讲:

find .git/objects/ -type f | wc -l 查看查找的目录下有几个文件

git commit -a -m "message commit"  合并了git add 和 git commit 命令 参数-a 说明提交当前目录下所有修改过的文件。

打标签:保存过程中的某一状态,只要指定一个名字就能提取出来,用来代替hash值。

ls -al .git/refs/tags/ 发现该目录是空的,然后我们用命令gti tag v1.0来打一个tag,然后这个目录下就有内容了。里面多了v1.0,其内容为一个当前状态下的commit,该对象为commint类型。刚才打的tag为轻量级tag,在objects目录下对象数量并不会增加。

git tag -a milestone1.0 -m "this is first stable version"重量级的tag在objects目录下的对象数量增加了1。在.git/refs/tags/目录下面增加了一个对象【该对象的类型为tag类型,指向了/objects/目录下的tag对象,而该对象指向了真正的commit对象】的同时在objects/目录下对象的数量也增加了1。

通过tag把内容提取出来:

cat .git/HEAD

cat .git/refs/heads/master

cat .git/refs/tags/v1.0

通过上述命令可以看到tag下的commit和heads下的commit是不一样的,现在我们把tag指定的内容提取出来:

git archive --format=tar --prefix=ruby/ v1.0 | gzip > /tmp/ruby1.0.tar.gz

git checkout v1.0


6讲:分支、合并 讲解

master是一个分支,而且是一个缺省分支。指向当前的工作commit

查看当前的分支用命令:git branch //该命令列出的结果前面打*的说明是当前使用的分支。在.git目录下面有一个HEAD文件,该文件是一个文本文件,其内容为refs/heads/master,然后查看master文件的内容,发现其为一commit,即为当前活动的分支。

基于当前的commit创建了一个分支,用命令git branch testing

cat .git/HEAD  //保存了master所指向的commit,指向活动的分支

.git/refs/heads  //该目录下是所有的分支,包括master 、branch等等....

git checkout testing //切换到testing分支,即当前活动的分支变为testing,现在再看一下HEAD,发现HEAD已经指向了testing

用命令git branch testing创建testing分支之后,在看.git/refs/heads/目录下的master和testing指向的内容就不一样了,新的分支开始朝另外一个方向走了。

验证:

现在已经有了2个分支,master和testing,当前活动分支为testing,看看某文件内容,然后在用命令git checkout master切换到master分支,在看看某文件内容是不一样的,o(∩_∩)o...

合并操作:

现在在master分支下面执行命令git merge testing就把在testing分支下面做的修改合并到master分支下面了。

刚才做了把testing分支删除的操作,testing分支已经没有用处了,现在可以删除了,用命令git branch -D testing删除testing分支。

2个分支修改了同一个文件的合并【有冲突的情况下合并操作】:

一个当前分支下,又创建了另外一个分支,新的分支对文件进行了修改。这种情况下的merge非常简单,只要执行命令git merge tempbr即可。其实本质是把master重新指向了新的commit从而完成了merge。

两个分支有同一个父节点的时候,这种情况下,合并是比较复杂的,有各种各样的合并算法。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值