第四节: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仓库
远程仓库:是在远程服务器上的Git仓库
Clone:克隆,就是将远程仓库复制到本地
Push:推送,就是将本地仓库代码上传到远程仓库
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. 常见平台
(1). gitHub( 地址:https://github.com/ )是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名gitHub.
(2). 码云(地址: https://gitee.com/ )是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快.
(3). GitLab (地址: https://about.gitlab.com/
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:\Users\Administrator\.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】,
(4). 与远程仓库建立关联
3. 工作目录、暂存区和版本库
工作目录(工作区):包含.git文件夹的目录就是工作目录,主要用于存放开发的代码。
4. 工作目录下的文件状态
Git工作目录下的文件存在两种状态:
(1). untracked 未跟踪(未被纳入版本控制)
(2). tracked 已跟踪(被纳入版本控制)
A. Unmodified 未修改状态
B. Modified 已修改状态
这些文件的状态会随着我们执行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 reflog】可以查看回退后的所有日志,回退记录也包括,即回退后,想恢复之前的版本,可以通过该命令查看日志。
然后运行指令 【git reset --hard 版本号】,注意,如果通过git log查看版本号,只需要输入前7位数即可。
如:删除repo1下的所有文件,然后运行指令【git reset --hard 847b441】,则退回到 add gitignore版本了 ,删除的文件又回来了
6. 远程仓库操作
(1). 添加远程仓库
比如:在本地新建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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。