csdn测开涨薪技术-Git原理及使用全套教程

前言

工欲善其事,必先利其器【文章末尾给大家留下了大量的福利】

Git是啥?

Git是分布式的版本库。

那么什么是分布式的版本库呢?说实话,第一次看到这句话时我的内心也是懵逼的。现在我们先不解释这个概念,总之你现在需要知道的就是:

Git非常强大,非常好用,比SVN好使1万倍,是编写代码、修改Bug、发布程序、持续集成,自动化运维、参与开源、居家旅行的必备神器。

Git为什么这么牛掰呢 ?因为它是Linus Torvalds开发的。Linus Torvalds是谁?Linus Torvalds是这个世界最牛掰的程序员,他21岁时就开发出了Linux。

等你认真读完这个手册,就会知道什么是分布式的版本库以及它相对于集中式版本库的好处。

下面我们正式开始进入 Git的世界。

安装Git

Linux

在Linux安装Git非常简单,只需一行命令

$ sudo yum install git-all
$ git --version

Mac

现在Mac都默认安装Git,如果没有可以运行下面的命令

$ brew install git
$ git --version

Get Started

安装完Git,让我们开始第一次Git之旅。在终端运行下面的命令

$git config --global user.name "tianle"
$git config --global user.email "tianle@dangdang.com"

$git init git-demo
$cd git-demo
$echo "Git学习" > README.md
$git add README.md
$git commit -m 'init repo and add README.md'
$git log

执行完以上命令,我们就已经建立了一个Git仓库,并且将文件README.md交由Git管理。是不是很简单!

如果你现在想把这个README.md分享给别人,就需要连接远程版本库,那么可以执行下面的命令。如果你比较自私不想分享你的成果,那么你现在就已经完成了第一个Git的"Hello World",可以跳到下一章了。

$git remote add origin git@github.com:christian-tl/git-demo.git
$git push origin master

这样你就将README.md推到了远程仓库的master分支,其他的小伙伴就可以看到了。他们不光能看到,还能修改完善这个文件。这就是工作的协作。

好了,现在我们愉快的结束了第一次Git之旅。你和Git已经不是那么陌生了。

Icongit config 设置 user.name user.email 只需在首次使用git时设置,之后就无需再设置了。
如果是首次连接使用远程版本库的话,需要把当前用户的公钥传到远程版本库上,否则无法使用ssh协议

基本使用

由于Git是分布式的版本库,所以Git完全可以在没有网络的情况下使用,每个人的开发机都可以作为一个独立的版本库存在,开发者可以在自己的开发机管理代码版本,而不依赖于远程版本库。

所以,在使用Git时并不是必须有一个远程服务器的存在。但是在实际工作中的绝大部分时间里团队的成员之间都需要协作,提交(push)自己的修改和同步别人的代码(pull) .所以本文还是描述实际工作中的使用Git作为版本管理工具的协作方法。

团队开发中使用Git的基本流程:

  • 克隆远程版本库
  • 基于远程develop分支建立本地develop分支
  • 基于develop分支建立本地特性分支feature
  • 在feature分支编写程序
  • 切换到develop分支,合并feature的修改
  • 把本地develop分支的修改推到远程develop

上述流程基本上可以覆盖90%的日常开发工作。

下面我们就通过一个简单的例子说明上述的流程,看看是如何用Git进行实际代码协作的。

  • 克隆远程版本库
    $git clone git@github.com:christian-tl/git-demo.git
  • 基于远程develop分支建立本地develop分支
    $cdgit-demo
    $git checkout -b develop origin/develop
  • 基于develop分支建立本地特性分支feature
    $git branch feature
    $git checkout feature
  • 在feature分支编写程序
    $viREADME.md
    $via.txt
    $git add README.md a.txt
    $git commit -m'add a.txt , change README.md'
  • 切换到develop分支,合并feature的修改
    $git checkout develop
    $git pull
    $git merge feature
  • 把本地develop分支的修改推到远程develop
    $git push

我们看到了一坨命令,是不是有点头晕眼花?是不是觉得Git很难用?没关系,你的想法是特别正常的。大部分人在最初接触Git时都想过放弃,觉得既然用SVN很简单为啥还要学着么难用的技术呢。实话实说Git的学习曲线确实很高,比SVN/CVS这种傻瓜式的版本控制工具要难很多。没办法,这个世界上没有什么完美的事情。我们要辩证的来看, 要想获得高收益就一定会付出一些代价。我们付出的代价就是多付出一点时间把Git的命令,对象存储原理弄明白,这对我们之后的整个开发流程都会有巨大的帮助。所以这个代价是值得的。

我们目前看到的命令是:git clone, git branch, git checkout, git add, git commit, git merge, git pull, git push

这些都是Git最重要的命令,伴随着整个Git的使用过程。当然,在实际工作中不会像示例里这么简单,我们经常需要用 git status 查看工作区和暂存区状态,用 git log 查看提交版本,用git diff 查看不同区域的差异,用 git reset 重置版本库,用 git rebase 合并提交与分支,用 cherry-pick 拣选提交,用 git fetch从远程版本库下载,用 git tag 建立里程碑,等等。Git有170多个命令,没有必要知道每个命令怎么用,也不可能做到。其实只要把上面列的命令会用了,工作中就基本够用了。后面的篇幅会详细介绍每个命令的用法。

在详细学习Git命令之前,我们要先了解一些Git的基本概念。这些概念非常的重要,它可以帮助我们理解Git的原理,这样我们才能更好的理解和使用命令,而不是对命令死记硬背。

Git最重要的概念就是工作区,暂存区,版本库,Git对象。

Git目录

执行 git init 或 git clone 之后会生成一个目录, 我们的开发都是在这个目录下进行的。这里面有我们所有的代码文件,我们把这个目录叫做项目目录。

比如:git clone git@github.com:christian-tl/git-demo.git 或git init git-demo 后 ,生成的这个 git-demo 目录就是项目目录。

在项目目录下有一个Git目录,除了Git目录之外的都是工作目录

Git目录

'Git目录'是项目存储所有历史和元信息的目录 - 包括所有的对象(commits,trees,blobs,tags).

每一个项目只能有一个'Git目录'(这和SVN,CVS的每个子目录中都有此类目录相反), Git目录是项目的根目录下的一个名为 .git 的隐藏目录. 如果你查看这个目录的内容, 你可以看到所有的重要文件。

还是回到前面Get Started的例子

$cd git-demo ; ll -al
drwxr-xr-x 9 christian staff 306 5 5 16:21 .git # 这个就是Git目录
-rw-r--r-- 1 christian staff 10 5 5 15:23 README.md # 这个是刚刚创建的文件
$cd .git ; tree -L 1
|-- HEAD # 记录当前处在哪个分支里
|-- config # 项目的配置信息,git config命令会改动它
|-- description # 项目的描述信息
|-- hooks/ # 系统默认钩子脚本目录
|-- index # 索引文件
|-- logs/ # 各个refs的历史信息
|-- objects/ # Git本地仓库的所有对象 (commits, trees, blobs, tags)
|-- refs/ # 标识每个分支指向了哪个提交(commit)。

这个.git目录中还有几个其他的文件和目录,但都不是很重要。不用太关注。

工作目录

Git的 '工作目录' 存储着你现在签出(checkout)来用来编辑的文件. 当你在项目的不同分支间切换时, 工作目录里的文件经常会被替换和删除. 所有历史信息都保存在 'Git目录'中 ; 工作目录只用来临时保存签出(checkout) 文件的地方, 你可以编辑工作目录的文件直到下次提交(commit)为止.

'工作目录'包括在项目目录下,除了 .git 外的其他所有文件和目录

在我们的例子中对应关系如下。

项目目录:git-demo

Git目录:git-demo/.git

工作目录:git-demo下除了.git目录之外的全部

.git目录详解

对.git目录先有个基本了解对后面的学习有很大帮助。

HEAD文件

HEAD文件就是一个只有一行信息的纯文本文件。这行内容记录的是当前头指针的引用,通常是指向一个分支的引用 ,有时也是一个提交(commit)的SHA值

$ cat .git/HEAD
ref: refs/heads/master #HEAD文件的内容只有这一行,表明当前处于master分支
$ git checkout dd98199
Note: checking out 'dd98199'.

You are in 'detached HEAD' state.
...

$ cat .git/HEAD
dd981999876726a1d31110479807e71bba979c44 #这种情况是”头指针分离“模式,不处于任何分支下。HEAD的值就是某一次commit的SHA

config文件

config文件记录着项目的配置信息,也是一个普通的纯文本文件。git config命令会改动它(当然也可以手工编辑)。 
这个文件里面配置了当前这个版本库的基本属性信息,上游版本库信息,本地分支与上游的映射关系,命令别名等。
总之是一个很有用的文件。在你的.git目录里看到的config文件内容基本上是下面的样子。

#基本配置
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
#上游版本库
[remote "origin"]
url = http://git.dangdang.com/stock/shopstock-update.git
fetch = +refs/heads/*:refs/remotes/origin/*
#本地分支与上游版本库分支的映射
[branch "master"]
remote = origin
merge = refs/heads/master
#当前仓库Git命令别名
[alias]
st = status

Icon如果没有添加远程版本库,[remote "origin"]和[branch "master"]是不存在的;如果没有设置alias那么[alias]也是不存在的。

所以如果仅仅是git init之后的一个本地仓库,那么只有[core]配置项 

hooks目录

钩子(hooks)是一些在.git/hooks目录的脚本, 在被特定的事件触发后被调用。当git init命令被 调用后, 一些非常有用的示例钩子脚本被拷到新仓库的hooks目录中; 但是在默认情况下它们是不生效的。 把这些钩 子文件的".sample"文件名后缀去掉就可以使它们生效。知道这个目录的用途就好,一般用不到。

index文件

git暂存区存放index文件中,所以我们把暂存区有时也叫作索引(index)。索引是一个二进制格式的文件,里面存放了与当前暂存内容相关的信息,包括暂存的文件名、文件内容的SHA1哈希串值和文件访问权限。暂存区是贯穿于整个Git使用流程的重要概念,所以index文件就很重要。由于是二进制所以我们无法查看具体内容,但是可以用git ls-files --stage 命令查看暂存区里面的文件

$git ls-files --stage
100644 44601d12328ea8e04367337184dcccb85859610e 0 README.md

暂存区会在后面介绍,平时几乎不需要直接查看index文件,大家只需要知道index就是暂存区,非常重要就好。

objects目录

Git对象(blob,tree,commit,tag)都保存在objects目录里面,所以objects目录就是真正的仓库。objects里面的目录结构组织的很有特点,是以SHA值的前2位作为目录,后38位作为这个目录下的文件名。

$tree objects/
objects/
├── 44
│ └── 601d12328ea8e04367337184dcccb85859610e
├── dd
│ └── 981999876726a1d31110479807e71bba979c44
├── e7
│ └── 77199b859e8e98db46e4897dc7076d07866042
├── info
└── pack

我们的工作目录里的所有文件,代码、库文件、图片等都会变成git对象存在这个objects目录下。每个文件都是一个二进制文件。可以通过 git cat-file -p SHA值来查看文件的内容。

refs目录

refs目录下面是一些纯文本文件,分别记录着本地分支和远程分支的SHA哈希值。文件的数量取决于分支的数量。

$tree refs
refs
├── heads
│ ├── develop # 记录本地develop分支的SHA哈希值
│ └── master # 记录本地master分支的SHA哈希值
├── remotes
│ └── origin
│ ├── develop # 记录远程版本库develop分支的SHA哈希值
│ └── master # 记录远程版本库master分支的SHA哈希值
└── tags
└── v1.0 # 记录里程碑V1.0的SHA哈希值

回想前面介绍的 HEAD文件, HEAD文件的内容记录了当前处于哪个分支,值是 ref: refs/heads/master 。

而 refs/heads/master文件 记录了master分支的最新提交的SHA哈希值 ,Git就是通过HEAD文件和refs/heads下面的文件来判断当前分支及分支最新提交的。

$cat HEAD
ref: refs/heads/master # 说明当前处于master分支

$cat refs/heads/master
dd981999876726a1d31110479807e71bba979c44 # master分支的最新提交SHA哈希值

logs目录

logs目录下面是几个纯文本文件&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值