git入门(1)

一 ,概述

这一篇作为git的入门级介绍,主要简单的讲一讲

  1. git是什么,和现有的什么东西类似
  2. 讲一讲git的工作区,缓存区,和本地仓库
  3. git 使用的入门操作,主要讲一讲在刚开始使用git的时候运用到的一些基础指令

二, git是什么

当我们想要学习一个东西的时候我们的惯常思维是,这个东西能干什么,和我现有的东西有什么相同点和不同点。
我们就沿着这个思路来聊一聊。
首先呢,还是git的定义

git是一个 分布式 版本控制工具

这里面有两个点:

  • 版本控制工具
  • 分布式的

2.1 关于版本控制工具

  目前常见的版本控制工具就是svn和git了吧。版本控制系统主要是为了记录开发中的相关文件和代码的修订版本,为每一个修订制作一个快照,这样的话便于回溯到某个历史版本,就像当你正在写一封信,你可能需要修改很多次,在修改了第n+1次之后,你突然发现,我靠,还是第一个版本更靠谱啊,怎么办,ctrl z 是回不去了。当然如果你用了版本管理工具来进行了这些文件的管理,并且每个版本都进行了提交,这个事情就是小菜一碟了。他可以帮你回到任何一个历史的版本,这样是不是很爽,哈哈,当然,这一个问题git和svn都能解决。

2.2 分布式的

  分布式的版本管理工具,这一点是git 和其他一些管理工具的重要区别,为什么是一些儿不是全部呢,因为分布式并不是git独有的,其他的比如Mercurial等。不过这个特点是git和svn的一个重要区别。
  相对分布式的版本管理系统,还有一种叫集中式的版本管理工具,svn就是属于集中式的版本管理工具。
  二者的区别:

  1. 集中式
       集中式的版本管理都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们(每个用户,或者说开发人员)都通过客户端连到这台服务器,取出最新的文件或者提交更新,这只是最新的一个服务器内容,并不包含历史,所以被称为快照。多年以来,这 已成为版本控制系统的标准做法。
      这种做法带来了许多好处,特别是相较于老式的本地 VCS 来说。现在,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。
      事分两面,有好有坏。这么做最显而易见的缺点是中央服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
      要是中央服务器的磁盘发生故障,碰巧没做备份,或者备份不够及时,就还是会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录,而被客户端提取出来的某些快照数据除外,但这样的话依然是个问题,你不能保证所有的数据都已经有人事先完整提取出来过。本地版本控制系统也存在类似问题,只要整个项 目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险
    2.分布式
      分布式版本控制系统中,客户端(每个用户,或者说开发人员)并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。

2.3 关于git和svn的区别的一些理解

  那么git和svn有什么区别呢,在我的使用感受中,比较重要的区别有:

  1. git比较重要的特性是branch分支特性。
      这个特性有什么功能呢?比如当前项目中有A,B两个大需求,A的上线时间是两周后,B的是三周后,两个需求需要并行开发,这样的话,为了并行开发(A,B两个项目的代码不会相互污染),就需要类似两个仓库来支撑代码的管理,隔离两个代码。在git中一个仓库下可以有两个branch(分支)来支持并行开发,当然,在svn中也有分支的概念,但是他其实对原仓库进行了一个克隆,相对git来说是比较重的。
  2. git的存储分为 work----stag-----repository三个区
    work是当前工作正在修改的文件所处的存储区;
    stag是 在 git 执行 git add操作以后,文件存储的区域;
    repository 是在执行 git commit操作以后文件存储的区域。
    相对来说svn只有本地仓库,直接执行的就是commit 操作,而且在commit之前要先update才行,也就是说在提交之前先进行合并(merge)以及可能的冲突解决。这里只是简述一下,下面会具体讲述三个区域。

三, git 的存储区

git入门(1)_第1张图片
git存储区域

git 在本地的存储区域如上图所示,就只有这三个存储区域,我们总是在这些区域之间操作来操作去,来实现代码的提交,回滚等操作。

1.working dirctory是当前工作正在修改的文件所处的存储区;
2.staging area是 在 git 执行 git add操作以后,文件存储的区域;
3.respository 是在执行 git commit操作以后文件存储的区域。

3.1 三个区对应的一个工作场景

这三个工作区对应的是这样一个工作场景:
产品来了一个大需求:

  1. 我们将任务分解为功能 A,B,C
  2. 我们将 功能继续细分,比如 A.1, A.2 B.1, B.2 ... (他们可能就是一个个接口的开发)
  3. 我们当前所在的工作是一直在编辑工作区的 A.1 需要的文件,
    3.1. 但是中间我们想要暂停一下去做其他的工作,这个时候可以先做一个 git add . 操作,他会把 当前工作区(woring directory)的修改添加到 缓存区(staging area ),
    3.2. 后来我们接着回来工作,又编辑一会儿,终于做完了A.1,我们再执行一次git add . 把当前的也加入 staging area。
    3.3. 然后执行一次 git commit -m "我终于搞完了 A.1" 将这一段时间的所有操作提交进 本地的仓库(respository)。
  4. 在我们为了完成A功能中间可能需要很多次commit (对应 A.1, A.2...)
  5. 在我们完成了A功能的时候我们可能想提交到远程,因为开发B功能的同事需要A功能的支持。这个时候我们执行一次 git push操作

所以,stag区只是一个缓存的区域,在stag区的文件并不会形成一个完整的功能,一般都是完成了一个小功能,也就是阶段性的任务的时候我们会进行一次commit操作,可能我们为了一个功能需要多次commit支持。

3.2 对比svn的操作

  1. 相对来说svn只有本地仓库,而且是和远程库强关联的,直接执行的就是commit 操作,这个操作会将文件推送到远程服务器端,而且在commit之前要先update才行,也就是说在提交之前先进行合并(merge)以及可能的冲突解决。也就是说svn的本地仓库和远程仓库是强关联的,在往本地仓库提交的时候就需要merge操作。
  2. git 没有这么强制的要求,你可以先commit,只会会进入本地的仓库,就是上图中的 repository 只要 不进行git push 操作,就不会往远端进行推送。所以在 git 执行 git commit 的时候不用担心冲突,因为只是在本地,都没有和远端发生联系。
  3. git中是执行git push操作的时候才会推送到远端,这个时候会比较本地和远端的版本(依靠commit id ),如果本地低于远端的版本要先执行一次 git pull操作,把远端的代码拉下来。合并完以后再次执行 git push 才能推送到远端。

四,git的基本操作

在三当中我们也聊了,我们的git 操作主要是围绕他的三个区域来进行的,当然我们现在要加上一个远程服务器端remote。本节我们主要围绕一些实例来进行。

4.1 git ,gitlab ,github 的区别 以及 日常的代码管理方式

1.为什么要讲这个呢,是因为我们平时和这些强相关。
  git是一种分布式的版本管理工具,他有自己的一套规范,比如怎么存储,如何同步之类的。
  我们常用的是git客户端,就是在本地安装了一个git软件,可以按照git指定的规范来管理我们的文件。但是我们可能还是想做一个可视化更好一点的中心服务器,再增加一些权限管理等功能来管理我们的文件。gitlab和github就是这样的管理软件,实现了可视化的git管理操作,又集成了权限管理等功能。
2.日常的代码管理方式
  正常情况下很多公司都是将代码放到gitlab上面(暴露了我在小公司...),放一张图片。


git入门(1)_第2张图片
1-查看当前组.png

点击图中的 learn 组(group) 会进入下面的页面


git入门(1)_第3张图片
2-项目详情.png

点击http的向下箭头,会出现


git入门(1)_第4张图片
3-项目详情附属.png

  上面两张图基本上公司使用git,而你只是git使用者,不负责初始化和权限管理等工作最先接触到两个页面。(登录页除外。。。)
图一:
  gitlab的项目管理有一个 group(组)的概念(图中是learn组,实际中有可能是多个group),一般比如前端的所有项目是一个组,后端的所有项目是一个组,运维的所有项目是一个组,当然可以根据业务再细分。而具体到每个用户可以属于一个或者多个组。进来以后先看看你属于哪个组,能够看见那些project(项目)。
图二:
  看起来信息量有点大,实际上只需要关注1,2就可以了。3是复制按钮,简单。当我们发现我们能够看到git-learn这个项目的时候,我们肯定想的,我怎么能够把它搞到本地来接着开发呢。接下来我们来说说怎么把一个远程项目搞到本地。

4.2 如何把gitlab的远程项目搞到本地

我们下载或者上传东西,常用的传输协议是http和ssh ,git这两种都支持。只是因为ssh安全性更好,所以推荐使用。
首先我们要有个git客户端来支持git 的shell操作
mac 和linux的shell自带了这些,windows的需要安装一个客户端。
安装的方式是:git的安装

1.使用http将项目搞下来

➜  learn mkdir git-test
➜  learn cd git-test 
➜  git-test ll
➜  git-test pwd
/Users/admin/work/learn/git-test
➜  git-test 
➜  git-test 
➜  git-test git clone http://192.168.43.3/learn/git-learn.git
Cloning into 'git-learn'...
Username for 'http://192.168.43.3': chenchuang
Password for 'http://[email protected]': 
warning: You appear to have cloned an empty repository.
➜  git-test ll
total 0
drwxr-xr-x  3 admin  staff   102B  4 22 21:50 git-learn
➜  git-test 

  在克隆远程项目时使用的主要是 git clone {url} 命令。可以看到,在过程中需要输入你在gitlab中的用户名和密码,这个一般管理员会帮你建好,告诉你(也有可能自己注册哈,这些常见操作都很简单)。这也是我们为什么要使用ssh的方式。

2. ssh传输方式搞下项目

因为ssh实际上是使用公钥加密传输的方式,所以就不需要用户名密码验证了。
2.1 添加本地公钥到gitlab
2.1.1 先生成本地公钥
先检查看看本地是否有了

➜  git-test cd ~/.ssh 
➜  .ssh ll
total 32
-rw-r--r--  1 admin  staff   154B  1  4 17:12 config
-rw-------  1 admin  staff   1.6K  1  4 16:13 id_rsa
-rw-r--r--  1 admin  staff   410B  1  4 16:13 id_rsa.pub
-rw-r--r--  1 admin  staff   2.3K  3  8 09:44 known_hosts
➜  .ssh 

  可以看到我的本地已经有了,加入没有,也不用担心,直接执行 ssh-keygen

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
The key fingerprint is:
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a [email protected]

注意这命令执行的时候一路回车,不需要输入密码等信息,要不然后面操作会变麻烦。
2.1.2 拷贝公钥到gitlab
将id_rsa.pub文件中的数据全部拷贝到剪切板。

➜  git-test cd ~/.ssh 
➜  .ssh ll
total 32
-rw-r--r--  1 admin  staff   154B  1  4 17:12 config
-rw-------  1 admin  staff   1.6K  1  4 16:13 id_rsa
-rw-r--r--  1 admin  staff   410B  1  4 16:13 id_rsa.pub
-rw-r--r--  1 admin  staff   2.3K  3  8 09:44 known_hosts
➜  .ssh cat id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVSXBLgxwYKcLxf7OovmKIRM06g5Rljm/vYbxlMCFKTT9ws0ePUHa8UZln9LjBS1hpMhh7xaNwFjXBoRglDcMugdzmBXyabyoGxXDwnk+8hGw02Hj9lALD2fuB2G+KTE03tQ5T1osulsLtI4MEDIEkkBzu92HrY+rpDXy7iPnQ0+FLerJYm0is/3QHG6yoCq6i+Ww7j3C1qTHw9GbvKVC6l6siYMlDzT+PiW1sFjgMx/kf8Tg6h5KBN2BxMHjVIJnGjQsT9mf3qggnsIyIAu0HLlUPl9MBCS8RLqLiq5mZPgdw6MW8MqA6YQOaOpcxP2g5Jhjt6zW3EPKvzOecSeDN [email protected]
➜  .ssh 

这个时候回过头去看第二张图中的 标记1, 翻译一下就是在没有添加 SSH key 的时候是没有办法通过ssh协议来进行push和pull操作的。在第三张图中有显示http和ssh两种协议方式。怎么添加呢,上几张图更好理解。


git入门(1)_第5张图片
4-个人设置相关.png

git入门(1)_第6张图片
5-添加公钥的页面.png

添加完成后项目详情页优先显示的是ssh协议了

git入门(1)_第7张图片
6-项目详情页

  总结来说,就是在 个人的 ---setting---->SSH Keys页面进行添加 保存即可。图5-添加公钥的页面 中的标记2就是剪切板中复制的公钥。

2.2 使用git clone 进行克隆操作


➜  git-test 
➜  git-test git clone [email protected]:learn/git-learn.git
Cloning into 'git-learn'...
The authenticity of host '192.168.43.3 (192.168.43.3)' can't be established.
ECDSA key fingerprint is SHA256:FyIMYzew6ZMPjGeKSrdzI21odNscY27/FVGBKk4oj/4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.43.3' (ECDSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.
➜  git-test 

可以看到,这次不需要输入密码了,只是ssh第一次的时候需要输入个yes,以后就不会了。
需要注意的是使用ssh和http对应的url是不同的。下面分别是两个url。

[email protected]:learn/git-learn.git
http://192.168.43.3/learn/git-learn.git

经历了这么多我们总算把git项目从服务器给搞到了本地也是挺不容易了。下面就可以进行愉快的开发了,当然,开发完后还是要提交的。

4.3 add,commit,push,pull等操作

本节,主要介绍git开发中常见的一些操作

1.git add 实现 work---->stag
2.git commit 实现 stag---->local repository
3.git push 实现 local repository---->remote repository
4.git pull 实现 remote repository---->local repository

4.3.1 我们做了一些操作,比如添加了一些文件test.txt ,内容是“this is a file to test git !!!!”

➜ git-test ll
total 0
drwxr-xr-x  3 admin  staff   102B  4 22 22:30 git-learn
➜  git-test cd git-learn 
➜  git-learn git:(master) ll
➜  git-learn git:(master) vim test.txt
➜  git-learn git:(master) ✗  
➜  git-learn git:(master) ✗ cat test.txt 
this is a file to test git !!!!

然后我们执行一个git status 命令来看一下


➜  git-learn git:(master) ✗ git status
On branch master

No commits yet

Untracked files:
  (use "git add ..." to include in what will be committed)

    test.txt

nothing added to commit but untracked files present (use "git add" to track)
➜  git-learn git:(master) ✗ 

可以看到提示我们有文件可以使用git add 操作。执行 git add . 就把当前目录下的东西都加入到 stag区了。然后接着 git status 看一下状态

➜  git-learn git:(master) ✗ git add .
➜  git-learn git:(master) ✗ 
➜  git-learn git:(master) ✗ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached ..." to unstage)

    new file:   test.txt

➜  git-learn git:(master) ✗ 

告诉我们可以commit的文件有 test.txt
我们来执行一次 git commit 操作

➜  git-learn git:(master) ✗ git commit  -m "这是我的第一次提交!!!"
[master (root-commit) 78ea189] 这是我的第一次提交!!!
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt
➜  git-learn git:(master) git status
On branch master
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

nothing to commit, working tree clean
➜  git-learn git:(master) 

关于git commit 中 -m 是增加了这次提交的的备注,有利于代码的回溯。这个时候可以看到在git status中是 “nothing to commit, working tree clean”
让我们往远端推送一次吧:


➜  git-learn git:(master) git push origin master 
Counting objects: 3, done.
Writing objects: 100% (3/3), 274 bytes | 274.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To 192.168.43.3:learn/git-learn.git
 * [new branch]      master -> master
➜  git-learn git:(master)           
➜  git-learn git:(master) 
➜  git-learn git:(master) git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working tree clean
➜  git-learn git:(master) 

git push 中的参数 origin 是远端的一个代表,master是对应的远端分支。
到此,我们就完成了一次简单模型的git使用。后面我们再深入一些。

五,git的branch操作

  git的一大利器就是branch(分支),git可以快速创建分支。分支的好处是什么呢。我们可以再举一个业务中的例子。比如产品规划了两个大需求A和B,在A中需要新建一个库db_A,B需要新建一个库db_B,A,B需要同时开发,但是上线时间不同,A是在两周后,B是在一周后。这就需要A,B之间的代码是完全隔离的,但是本身又属于同一个项目,所以说只是暂时的隔离。
  这种特性在svn中也是可以实现的,svn中也有分支的概念,但他实际上是把项目给拷贝了一份出来。所以比较重,用的人也很少。而branch在git中则是一个比较廉价的东西。下面我们就来试试吧。

一个分支的应用:
  我们目前的方式是master是稳定分支,也就是测试通过的代码才能进入master,就是可以上线的代码。所以对应的还有各种开发分支,对应一个大需求可能都有一个新的分支。所以在第四节中代码来下来我们不会直接去改动,因为刚拉下来的时候默认是在master分支的,需要checkout 到其他分支。
  比如你执行 git clone把代码文件拉下来以后,需要看一下远端有哪些分支,可以使用git branch -a 命令:

ZL:git-learn zhaolu$ 
ZL:git-learn zhaolu$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
ZL:git-learn zhaolu$ 

可以看到本地只有一个master,远端也是只有一个master。
这个时候h
比如有一个开发的 develop 分支。
我们应该接着在4.3之前执行 一个分支的操作

git checkout -b dev origin/dev

这个命令会在本地新建一个 名字叫 dev的分支,关联远程的 dev分支
关于git branch的操作可以看:git branch 的相关操作
在4.3之后测试没有问题的代码可以合并到master分支上。

git checkout master //回到master分支上
git merge dev     // 将dev分支上的东西合并到master上面

这样才是一个比较正常的操作。

你可能感兴趣的:(git入门(1))