分布式版本控制系统——Git

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式版本控制系统——Git相关的知识,希望对你有一定的参考价值。

分布式相比于集中式的最大区别在于开发者可以将代码提交到本地,每个开发者通过克隆,在本地机器上拷贝一个完整的git仓库。

下图是经典的git开发过程:
技术图片

git的功能特性如下:

  • 从服务器上克隆完整的git仓库(包括代码和版本信息)到单机上;
  • 在自己的机器上根据不同的开发目的,创建分支,修改代码;
  • 在单机上自己创建的分支上提交代码;
  • 在单机上合并分支;
  • 把服务器上最新版的代码fetch下来,然后跟自己的主分支合并;
  • 生成补丁,把补丁发送给主开发者;

git可以安装在Windows、mac、Linux等操作系统之上,这里将写下如何安装在Linux系统之上,及其基本操作。
一、安装git
非常简单,就一条命令,如下:

[root@git ~]# yum -y install git

二、git库的创建及介绍

[root@git /]# mkdir /git
[root@git /]# cd git/
[root@git git]# git init             # 初始化为git库
Initialized empty Git reposi tory in /git/.git/
[root@git git]# ls -a                   #初始化成功后,会生成一个.git的隐藏目录
.  ..  .git
#生成的隐藏目录是用来跟踪管理版本库的,不建议随便修改其目录中的文件,
#如果改乱了,就把git库给破坏了。

在git版本库中,有三个重要的概念:工作区、暂存区、版本库。

  • 工作区:就是你的系统中可以看到的目录;
  • 暂存区:一般存放在.git目录下的index文件中,所以也会将暂存区叫做索引;
  • 版本库:工作区中的有一个.git隐藏目录,这个不算工作区,而是git的版本库。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

技术图片
上图中,左侧为工作区,右侧为版本库,在版本库中标记为“index”的区域就是暂存区,标记为“master”的是master分支代表的目录树。

当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
三、git库的基本操作

[root@git git]# git config --global user.name "zyz"
[root@git git]# git config --global user.email "zyz@zyz.com"
[root@git git]# echo "aaaa" > test.txt
[root@git git]# git add test.txt
[root@git git]# git commit -m "第一次提交"
#将暂存区的文件提交到版本库,并且一定要使用“-m”选项注明提交说明
[master (root-commit) 9ec7631] 第一次提交
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt
[root@git git]# echo bbbb >> test.txt             # 修改测试文件
[root@git git]# git status            # 查看状态他会说我们这个文件发生更改需要添加
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   test.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@git git]# git add test.txt                  # 添加到暂存区
[root@git git]# git status                 # 再次查看状态他会说需要再次提交这个文件
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   test.txt
#
[root@git git]# git commit -m "第二次提交"           # 提交完毕
[master 8c3c7db] 第二次提交
 1 file changed, 1 insertion(+)
[root@git git]# git status                   # 再次查看状态
# On branch master
nothing to commit, working directory clean
[root@git git]# echo cccc >> test.txt             # 修改第一个测试文件
[root@git git]# echo "第二个测试文件" > test2.txt         # 新建几个测试文件
[root@git git]# echo "第三个测试文件" > test3.txt
[root@git git]# git add test.txt test2.txt test3.txt            # 添加到暂存区
[root@git git]# git status            # 查看状态
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   test.txt                 # 修改
#   new file:   test2.txt                 # 新文件
#   new file:   test3.txt                 # 新文件
#
#上面是提示git被修改,并且添加了两个新的文件
[root@git git]# git commit -m "提交多个版本"                # 将暂存区的多个版本进行提交
[master 92e5155] 提交多个版本
 3 files changed, 3 insertions(+)
 create mode 100644 test2.txt
 create mode 100644 test3.txt
[root@git git]# git log --pretty=oneline          # #查看提交记录,一行对应一次提交记录
92e5155ccbb59913cd717a539a11529b786a564b 提交多个版本
8c3c7dbc6eb90d64899df1d23c0546fe1ffbe064 第二次提交
9ec7631c3c93990f71db83ae04e8b387aa1213d6 第一次提交
#至此,git库下的所有文件都被提交了,那么,我现在将本地的所有文件都删除,查看下git的状态是什么
[root@git git]# rm test*              #删除当前目录下所有的测试文件
[root@git git]# git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    test.txt                  # 删除
#   deleted:    test2.txt
#   deleted:    test3.txt
#上述提示了删除了三个文件,下面说的是修改了但是尚未提交
no changes added to commit (use "git add" and/or "git commit -a")
#那么,我现在若想恢复删除的文件呢?只需进行以下操作:
[root@git git]# git reflog --pretty=oneline               # 查看 提交记录
92e5155 HEAD@{0}: commit: 提交多个版本
8c3c7db HEAD@{1}: commit: 第二次提交
9ec7631 HEAD@{2}: commit (initial): 第一次提交
[root@git git]# ls                    # 确定没有任何测试文件
[root@git git]# git reset --hard 92e5155              # #版本回滚到指定提交的位置
HEAD is now at 92e5155 提交多个版本 
[root@git git]# ls                      #再次查看,被删除的文件又回来了
test2.txt  test3.txt  test.txt
#那么,现在我想要恢复到第一次提交的时候呢?
[root@git git]# git reflog --pretty=oneline             # 同样需要查看提交日志
92e5155 HEAD@{0}: commit: 提交多个版本
8c3c7db HEAD@{1}: commit: 第二次提交
9ec7631 HEAD@{2}: commit (initial): 第一次提交
[root@git git]# git reset --hard HEAD@{2}         #对,在版本回滚时,不但可以指定第一列的ID号,也可以指定其HEAD字段
HEAD is now at 9ec7631 第一次提交
[root@git git]# ls        #再次查看当前工作目录下,恢复到了最初只有一个测试文件的状态
test.txt 
[root@git git]# git reset --hard 92e5155                  #再次恢复到测试文件最多的时候
HEAD is now at 92e5155 提交多个版本
[root@git git]# ls
test2.txt  test3.txt  test.txt

四、撤销修改的操作
关于撤销修改,其实在上面已经展示出来如何从版本库中撤销修改了,那么下面将介绍如何从暂存区、工作台进行撤销修改
1、从工作台撤销修改

[root@git git]# cat test.txt             #确定当前文件内容
aaaa
bbbb
cccc
[root@git git]# echo dddd >> test.txt               #修改文件内容
[root@git git]# cat test.txt                    # #查看修改后的文件
aaaa
bbbb
cccc
dddd
[root@git git]# git checkout -- test.txt                #对工作台执行撤销操作
[root@git git]# cat test.txt                #确认新添加的内容被撤销
aaaa
bbbb
cccc

2、从暂存区撤销修改

[root@git git]# echo "123123" > aaa.txt                    # 创建一个新的测试文件
[root@git git]# git add aaa.txt              # 添加到暂存区
[root@git git]# git status 
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   aaa.txt                  # 新文件
# 
[root@git git]# git reset HEAD aaa.txt              # 撤销
[root@git git]# git status        #再次查看git的状态,提示提交为空,还提示使用git add建立提交
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   aaa.txt                 # 这里已经显示不是新文件
nothing added to commit but untracked files present (use "git add" to track)
#提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

3、从版本库中删除指定版本

[root@git git]# rm test.txt             #删除本地文件
root@git git]# git rm test.txt                #使用git执行rm命令
rm ‘test.txt‘
[root@git git]# git commit -m "删除文件"               #提交到版本库
[master f9bccab] 删除文件
 1 file changed, 3 deletions(-)
 delete mode 100644 test.txt

至此,都只是git版本库的基本操作,那么?我们如何将我们的git
库关联到github上呢?下面是两种情况下的关联方法。
五、将本地git库关联到github
情况一:本地有git库,github库是空的:
1、首先需要先创建一个空的github库。

自行注册github账号并登陆,比较简单,这里就不写了。

技术图片
技术图片
在主机上生成秘钥对,并上传至github上:

[root@git git]# ssh-keygen -t rsa -C "848369866@qq.com"            #执行此命令后,一路按回车即可,“-C”后面是自己的邮箱地址
[root@git git]# cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEKmiwENbVxLSn2tRDUAFVh3muJFXJYqjuOPU+RfCIb42Bv2w52zzasY4rEPgPc865b+NTLk4Xkw4SEEl7qzObf/kDyqtM0d7PjCR+E4/u9MKHo+evgtNJwrNXeoycKc1EHKYWRqAbJ79QulwqDPU7Z2DC9I0ML1Kf6ipRe4biN58imyt/YLxVj9RnmWS6r+umkSM4ukn4DKHGfI1DJxIWEk2jwgQKBmdBB06YZvHBn6VOKaIlCSSHCAWZ51D6EDT8LdZ4jwZmbqN0ypBFG7E6KM5oYPE1hIRnbcy+HB7jYCptNmZhv2eamHH+yL+oMe2Wn/wxwc1gTRfl9Epz1LD7 848369866@qq.com

在github上操作如下,以便添加公钥:
技术图片
技术图片
技术图片
技术图片
输入github账号的密码进行验证:
技术图片
确定添加成功:
技术图片
2、回到新创建的库:
技术图片
技术图片

[root@git git]# ls -a
.  ..  aaa.txt  .git  test2.txt  test3.txt
[root@git git]# git remote add origin git@github.com:zhangyz-nb/test01.git          #执行提示的第一条命令
[root@git git]# git push -u origin master              #进行提交,由于是第一次上传,所以需要使用“-u”选项
#如果执行上述命令后,提示需要输入“yes”,输入即可
Counting objects: 13, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (13/13), 1021 bytes | 0 bytes/s, done.
Total 13 (delta 0), reused 0 (delta 0)
To git@github.com:zhangyz-nb/test01.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

#提示已经提交成功了。

至此,F5刷新我们github上刚刚创建的库的页面,就可以看到我们工作台目录下的那些文件了,如下:
技术图片
六、从github下载到本地git版本库
上述已经演示了如何将本地的git版本库关联到远端的github的空库。

那么这里将展示如何将github已存在的库(库中有内容)下载到本地。

由于在第五步操作时,已经设置好了邮箱及ssh秘钥等操作,所以这里就可以省略这两部操作了,如果没有配置邮箱及ssh秘钥,可参考第五个段落进行配置。

这里就将第五步创建的github库下载到本地。

找到github创建的库,如下:
技术图片
技术图片

[root@git git]# git clone git@github.com:zhangyz-nb/test01.git
Cloning into ‘test01‘...
#执行命令“git clone”,后面的路径就是我们复制的github上的ssh路径
Warning: Permanently added the RSA host key for IP address ‘52.74.223.119‘ to the list of known hosts.
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 13 (delta 0), reused 13 (delta 0), pack-reused 0
Receiving objects: 100% (13/13), done.
[root@git git]# cd test01/
[root@git test01]# ls
test2.txt  test3.txt
[root@git test01]# echo "clone success..." > succed          # 创建一个新的测试文件
[root@git test01]# ls 
succed  test2.txt  test3.txt
[root@git test01]# git add succed        # 添加到暂存区
[root@git test01]# git commit -m "clone succes"         # 提交
[master 4b662bd] clone succes
 1 file changed, 1 insertion(+)
 create mode 100644 succed
[root@git test01]# git push origin master              # 将本地文件推送到github
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 306 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:zhangyz-nb/test01.git
   f9bccab..4b662bd  master -> master
[root@git test01]# git remote              # 查看远端版本库信息
origin

回到github上,刷新库的页面,即可看到新提交的文件,如下:
技术图片

以上是关于分布式版本控制系统——Git的主要内容,如果未能解决你的问题,请参考以下文章

GitHub介绍

GitHub介绍

如何管理在每个 git 版本中添加私有代码片段?

分布式版本控制系统——Git

GIT分布式版本控制系统使用教程

分布式版本控制系统——Git详解