第四节:Git的概述、代码托管平台、常用指令总结、实际案例模拟

一. Git概述

1. Git历史

 Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。 到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。

到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统。

 他们对新的系统制订了若干目标:速度、简单的设计、对非线性开发模式的强力支持(允许成千上万个并行开发的分支)、完全分布式、有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)。

2. Git和SVN对别

(1). SVN

 SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而开发人员工作的时候,用的都是自己的电脑,所以首先要从中央服务器下载最新的版本,然后开发,开发完后,需要把自己开发的代码提交到中央服务器。

 集中式版本控制工具缺点:服务器单点故障、容错性差。

(2). Git

 Git是分布式版本控制系统(Distributed Version Control System,简称 DVCS) ,分为两种类型的仓库:本地仓库和远程仓库。

 本地仓库:是在开发人员自己电脑上的Git仓库

 远程仓库:是在远程服务器上的Git仓库

 Clone:克隆,就是将远程仓库复制到本地

 Push:推送,就是将本地仓库代码上传到远程仓库

 Pull:拉取,就是将远程仓库代码下载到本地仓库

3. Git工作流程

工作流程如下:

 (1).从远程仓库中克隆代码到本地仓库

 (2).从本地仓库中checkout,代码然后进行代码修改

 (3).在提交前先将代码提交到暂存区

 (4).然后将暂存区的代码提交到本地仓库。本地仓库中保存修改的各个历史版本

 (5).修改完成后,需要和团队成员共享代码时,将代码push到远程仓库

4. Git的下载和安装

  下载地址:https://git-scm.com/download,这里以Windows版本为例,安装过程全程下一步,直到安装完成即可。

  安装完成后在电脑桌面(也可以是其他目录)点击右键,如果能够看到如下两个菜单则说明Git安装成功(Git GUI:Git提供的图形界面工具。Git Bash:Git提供的命令行工具。)

二. Git代码托管平台

1. 常见平台

 比较常用的有GitHub、码云、GitLab等。

(1). gitHub( 地址:https://github.com/ )是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名gitHub.

(2). 码云(地址: https://gitee.com/ )是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快.

(3). GitLab (地址: https://about.gitlab.com/ )是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务.

2. 码云的使用

(1). 仓库的创建与配置

(2). 成员配置

 可以通过链接邀请 或者 直接添加。

三. Git常用命令

(下面所有的指令均以码云上的公有仓库myTest1为例,进行操作)

1. 环境配置

 当安装Git后首先要做的事情是设置用户名称和email地址,这是非常重要的,因为每次Git提交都会使用该用户信息,即码云上的提交记录会显示此处配置的用户名。

 注意:这里的用户名称和码云上注册的是没有关系的!!!用户名和邮箱可以随便写,邮箱可以随便编写一个即可。

设置用户信息(在任何目录下,右键,选择Git Bash Here)

【git config --global user.name “ypf”】

【git config --global user.email “ypf@qq.com”】

查看配置信息

【git config --list】

【git config user.name】

通过上面的命令设置的信息会保存在~/.gitconfig文件中  (C:UsersAdministrator.gitconfig)

2.获取Git仓库

 获取Git仓库有两种模式:①. 直接从远程clone一个仓库到本地    ② 先初始化一个git本地仓库,然后和远程仓库建立联系

模式一: 从远程克隆(直接就建立了联系)

 点击右键打开Git Bash窗口,运行【git clone https://gitee.com/ypf0806/mytest1.git】,直接按照码云上的名字clone下来了,名为mytest1,克隆的是所有分支。

 

模式二:先本地初始化→和远程建立联系

 (1). 在电脑的任意位置创建一个空目录(例如repo1)作为我们的本地Git仓库

 (2). 进入这个目录中,点击右键打开Git Bash窗口

 (3). 执行命令【git init】如果在当前目录中看到.git文件夹(此文件夹为隐藏文件夹)则说明Git本地仓库创建成功

(4). 与远程仓库建立关联

3. 工作目录、暂存区和版本库

 工作目录(工作区):包含.git文件夹的目录就是工作目录,主要用于存放开发的代码。  

 暂存区:.git文件夹中有很多文件,其中有一个index文件就是暂存区,也可以叫做stage,暂存区是一个临时保存修改文件的地方。

 版本库:前面看到的.git隐藏文件夹就是版本库,版本库中存储了很多配置信息、日志信息和文件版本信息等。

4. 工作目录下的文件状态

 Git工作目录下的文件存在两种状态:

(1). untracked 未跟踪(未被纳入版本控制)

(2). tracked 已跟踪(被纳入版本控制)

  A. Unmodified 未修改状态

  B. Modified 已修改状态

  C. Staged 已暂存状态

 这些文件的状态会随着我们执行Git的命令发生变化

5. 本地仓库操作

(前提:在本地初始化1个新仓库repo1)

(1). 查看文件状态 【git status】或者简化显示 【git status -s】

如:在repo1下新建 ypf01.txt, 运行指令【git status】 或 【git status -s】

PS:【git status -s】 几种情况说明

 M 代表已修改

 红色??代表未被跟踪 

 绿色A表示加入暂存区

(2). 将未被跟踪的文件加到暂存区 【git add xxx】 

如:运行指令【git add ypf01.txt】,将该文件加入到暂存区。加入后,重新查看文件状态【git stauts -s】

(3). 将暂存区的文件取消暂存【git reset xxx】或 【git reset head xxx】

如:运行指令【git reset ypf01.txt】,该该文件从暂存区中取消,取消后,重新查看文件状态【git status -s】

(4).  将暂存区的文件提交本地仓库

A. 全部提交:【git commit -m "备注"】

B. 单文件提交:【git commit -m "备注" xxx】,xxx代表文件名

如:新增ypf02.txt、ypf02.txt,运行指令【git add ypf01.txt ypf02.txt ypf03.txt】,将这三个文件都添加到暂存区

 单独提交ypf01.txt,【git commit -m "ceshi1" ypf01.txt】,然后查看状态

将剩下的文件都提交到本地仓库, 【git commit -m "all commit"】,然后查看状态,发现暂存区中已经没有文件了

修改ypf02.txt中的内容,查看状态

(5). 文件的删除

A. 【git rm xxx】,自动同步到暂存去了

如:运行指令【git rm ypf03.txt】删除本地文件并且自动同步到暂存区了,然后运行指令【git commit -m "删除文件"】

B.  通过delete删除,没有同步,需要手动添加到暂存区

如:通过delete删除ypf02.txt,然后通过指令【git add ypf02.txt】添加到暂存区,最后通过【git commit -m "delete 02 file"】

(6) 添加到忽略清单中

 将文件添加至忽略列表 (用linux下的命令【touch .gitignore】创建,windows下不能直接创建)

 一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。

常用格式如下

# no .a files
*.a
# but do track lib.a, even though you're ignoring .a files above (配合上面代码,即忽略所有.a结尾的文件,但是除了 lib.a)
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO  (表示TODO这一个文件)
/TODO
# ignore all files in the build/ directory  (表示build下的整个目录都忽略)
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory
doc/**/*.pdf

如:在本地新建ypf04.txt,然后运行指令【touch .gitignore】,内容如下,即忽略ypf04.txt,然后查看状态,发现并没有标记ypf04.txt文件,说明被忽略了。

(7). 查看git提交日志 【git log】

(8). 版本回退 

方案一:

 退回当前版本:【git reset --hard HEAD】

 退回前1个版本:【git reset --hard HEAD^】

 退回前1个版本:【git reset --hard HEAD^^】

如:删除respo1文件夹下的所有内容,然后运行指令【git reset --hard HEAD】,删除的文件又回来了。

方案二:根据版本号删除

    首先可以根据指令 【git log】或 【git reflog】,查看记录

    然后运行指令 【git reset --hard 版本号】,注意,如果通过git log查看版本号,只需要输入前7位数即可。

如:删除repo1下的所有文件,然后运行指令【git reset --hard 847b441】,则退回到 add gitignore版本了 ,删除的文件又回来了

6. 远程仓库操作

(1). 添加远程仓库

 运行【 git remote add <shortname> <url> 】添加一个新的远程 Git 仓库,同时指定一个可以引用的简写别名<shortname>,后续使用这个别名就行了

PS :这里是指本地自己建了一个仓库,通过上面指令与远程仓库建立连接,

比如:在本地新建repo2,然后运行指令【git init】进行本地仓库初始化,然后运行指令 【git remote add origin https://gitee.com/ypf0806/mytest1.git】,进行远程仓库的链接。

(2). 查看远程仓库

 如果想查看已经配置的远程仓库服务器,可以运行 【git remote】 命令。 它会列出指定的每一个远程服务器的简写。 如果已经克隆了远程仓库,那么至少应该能看到 origin (默认clone下来的就是这个别名) ,这是 Git 克隆的仓库服务器的默认名字 

比如:在步骤1的基础上,运行【git remote】指令,如下图:

(3). 从远程克隆仓库

 点击右键打开Git Bash窗口,运行【git clone https://gitee.com/ypf0806/mytest1.git】,直接按照码云上的名字clone下来了,名为mytest1,和远程仓库的名称一样. (PS:地址要用https那个模式地址,SSH地址需要配置公钥私钥)

 然后运行指令【git remote】,如下图,默认已经建立起来了链接

(4). 移除无效的远程仓库

【git remote rm <shortName>】

比如:运行下面指令,多添加几个关联

【git remote add origin2 https://gitee.com/ypf0806/mytest1.git】

【git remote add origin3 https://gitee.com/ypf0806/mytest1.git】

然后运行指令【git remote】进行查看,删除origin2和origin3,【git remote rm origin2 】【git remote rm origin3 】,再次查看

 

(5). fetch获取远程代码

 【git fetch 别名 服务器分支名】(或者简化为 【git fetch】拉取所有分支) 是从远程仓库获取最新版本到本地仓库,不会自动merge,也就是说不会自动同步到本地工作区,他在.git文件夹下的object下。然后还需要执行 【git merge 别名/服务器分支命】就是把本地仓库的文件同步到工作区。

比如:在repo2下(本地初始化,且已经与远程git建立了链接,别名为origin),运行指令【git fetch origin master】

 

然后运行指令【git merge origin/master】,进行同步到本地工作区间

(5). pull获取远程代码

【git pull 别名 服务器分支名】(或者简化【git pull】指拉取服务器上所有分支) 是从远程仓库获取最新版本并merge到本地仓库。

比如在repo3下(本地初始化,且已经与远程git建立了链接,别名为origin),运行指令【git pull origin master】,发现工作区间文件直接同步了

总结:git pull = git fetch+git merge

 注意:如果当前本地仓库不是从远程仓库克隆,而是本地创建的仓库,并且仓库中存在文件,此时再从远程仓库拉取文件的时候会报错(fatal: refusing to merge unrelated histories ),解决此问题可以在git pull命令后加入参数--allow-unrelated-histories

 比如:在repo4下(本地初始化,且已经与远程git建立了链接,别名为origin),新建1个lmr01.txt(且提交到本地仓库),然后运行【git pull origin master】

 解决方案:运行指令【git pull origin master --allow-unrelated-histories】,然后出现下面界面,输入 :wq,保存一下即可。

总结一下流程:

方法1:先在码云上建一个仓库→本地【git init】一个仓库→将本地仓库和远程仓库建立连接【git remote add <shortName> url】

 (1) 拉取远程仓库到本地仓库【git fetch】→将本地仓库同步到工作区【git merge】

 (2) 拉取远程仓库到本地仓库并且同步到工作去【git pull】    推荐!!

方法2:先在码云上建一个仓库→然后【git clone】,直接就在本地创建仓库并且和远程仓库建立起了联系,后续再根据自己需要选择 【git fetch】 or 【git pull】 

7. Git分支

  几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。Git 的master分支并不是一个特殊分支。 它跟其它分支没有区别。 之所以几乎每一个仓库都有 master 分支,是因为git init 命令默认创建它,并且大多数人都懒得去改动它。

前提准备:

 在本地repo5中初始化本地仓库,且与远程仓库建立联系,然后pull所有内容(这里远程仓库默认就1个master分支),远程仓库内容如下:

(1). 查看分支

 # 列出所有本地分支 git branch】

 # 列出所有远程分支 git branch -r】

 # 列出所有本地分支和远程分支 git branch -a】

(2). 创建分支

【git branch 分支名】

  比如在master分支下运行指令【git branch b1】创建b1分支,然后运行指令【git branch】查看本地分支。

注意:基于哪个分支创建新分支,新分支和基于的分支内容相同。

(3). 切换分支

【git checkout 分支名】

比如在master分支下切换到b1分支【git checkout b1】

(4). 推送本地分支到远程(也就是提交代码)

【git push 别名 分支名】

比如:在b1分支下新建了002.txt,现在把b1分支提交到服务器,首先要先把002.txt提交到本地仓库,然后运行指令【git push origin b1】

 登录码云查看,多了一个b1分支。

(5). 合并分支

【git merge 分支名】,比如要把b1分支中的内容合并到master分支里,那么就需要在master分支里运行指令【git merge b1】

A. 先在本地master分支下执行指令【git merge b1】

B. 然后还是在master分支下运行推送指令 【git push origin master】

C. 登录码云,查看master分支,发现002.txt已经同步过来了

注意:

  有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没办法合并它们,同时会提示文件冲突。此时需要我们打开冲突的文件并修复冲突内容,最后执行git add命令来标识冲突已解决 (在master下运行指令 【git merge b3】表示将b3分支合并到master分支中)

比如:基于master分支创建1个b3分支,然后修改b3分支ypf01.txt的内容,然后提交到本地仓库,然后切换到master分支,进行与b3分支的合并。

 

 提交到本地仓库:

切换到master,进行合并(如果冲突,需要提交一下,再提交)

(6). 删除分支 

  删除本地分支:如果要删除的分支中进行了一些开发动作,此时执行上面的删除命令并不会删除分支,如果坚持要删除此分支,可以将命令中的-d参数改为-D    【git branch -d 分支名】 和 【git branch -D 分支名】

注意:要删除某个分支,需要先切换到其它分支,不能在当前分支下删除。

如果要删除远程分支,执行指令 【git push origin –d branchName】

比如在master分支下删除b3分支:

8. Git标签

 像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 、v1.2等)。标签指的是某个分支某个特定时间点的状态。通过标签,可以很方便的切换到标记时的状态。常用的功能有:列出已有的标签、创建新标签、将标签推送至远程仓库、检出标签、删除标签。

(1). 创建标签

【git tag <tagName>】,比如运行下面指令创建 v1、v2标签

(2). 查看标签

【git tag】

(3). 提交标签到远程仓库

【git push <remote> <tagName>】

(4). 检出标签

   新建一个分支,执行某个tag   【git checkout -b <branch> <tagName>】

(5).  删除标签

A. 删除本地标签  【git tag -d <tagName>】

B. 删除远程标签    【git push origin :refs/tags/<tagName>】

四. Git实际使用案例

1. 背景要求

 开发某个网站,为实现某个新的需求,创建一个分支,在这个分支上开展工作。正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。你将按照如下方式来处理:

(1). 切换到你的生产线上分支(Production branch)。

(2). 为这个紧急任务新建一个分支,并在其中修复它。

(3). 在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支。

(4). 切换回你最初工作的分支上,继续工作。

2. 具体步骤

 事先准备:码云上有MyFrame1项目,有三个分支,Master(主分支)、Production(生产分支)、Develop(开发新功能分支)。

(1).  切换到Production分支,基于该分支创建一个 Temp1分支。

【git checkout Production】【git branch Temp1】

 

(2). 切换到Temp1分支上,在Temp1分支上创建个文件,比如 test1.txt, 表示修改了bug,且测试通过,且提交到本地仓库。 

【git checkout Temp1】【touch test1.txt】【git add test1.txt】【git commit -m "edit bug"】

 (3). 切换到Production分支上,合并Temp1分支,推送到远程服务器,然后去重新发布项目

【git checkout Production 】【git merge Temp1】【git push origin Production】

 

 (4). 切回 Develop分支,继续你自己的功能开发

【git checkout Develop】

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
原文地址:https://www.cnblogs.com/yaopengfei/p/14931700.html