玩转Git、GitHub、GitLab
一. Git基础
1.1 课程综述
- 版本管理的演变:
- VCS出现前:
- 用目录拷贝区别不同版本
- 公共文件容易被覆盖
- 成员沟通成本很高,代码集成效率低下
- 集中式VCS:
- 有集中的版本管理服务器
- 具备文件版本管理和分支管理能力
- 集成效率有明显地提高
- 客户端必须时刻和服务器相连
- 如图所示:
- 分布式VCS:
- 服务端和客户端都有完整的版本库
- 脱离服务器,客户端照样可以管理版本
- 查看历史和版本比较等多数操作,都不需要访问服务器,比集中式VCS更能提高版本管理效率
- VCS出现前:
- Git的特点:最优的存储能力、非凡的性能、开源的、很容易做备份、支持离线操作、很容易定制工作流程。
- 内容与顺序:
- git
- github
- gitlab
github是全球最大的开源社区,纳入了代码存储、持续交付、持续集成等全生命周期的功能。
1.2 安装Git
可以参考安装教程,windows用户安装直接下载按照提示安装即可。
1.3 使用Git之前需要做的最小配置
- 配置user信息(配置user.name和user.email)
git config --global user.name 'your_name'
git config --global user.email '[email protected]'
每次变更的时候能够保存变更者的名称和邮箱,这样出现问题的时候能够找到当事人。
- config的三个作用域:
- 实战操作如图所示:
1.4 创建第一个仓库并配置local用户信息
- 建Git仓库(两种场景)
- 把已有的项目代码纳入Git管理
cd 项目代码所在文件夹
git init
- 新建的项目直接用git管理
cd 某个文件夹
git init you_project #会在当前路径下创建和项目名称同名的文件夹
cd your_project
- 把已有的项目代码纳入Git管理
- 简单提交文件:
- 直接提交到暂存区并直接提交的快捷命令:
git commit -am'提交的文件说明'
1.5 认识工作区和暂存区
- Git和其他版本控制系统如SVN的一个不同之处就是有一个暂存区的概念。
- 工作区:就是在电脑里能够看到的目录
- 暂存区:英文叫stage,或index。一般存放在".git目录"下的index文件(.git/index)中,所以我们把暂存区有时也叫做索引(index)。
- 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
- 区别说明:
- 图示:
- 说明:
- 在上图中,我们可以看到部分 Git 命令是如何影响工作区和暂存区(stage/index)的。
- 图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage/index),标记为 “master” 的是 master 分支所代表的目录树(关于分支问题在下面的文章中会详解)。
- 图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个“指针”。所以,图示的命令中出现 HEAD 的地方可以用 master 来替换(HEAD的概念我们在后面的文章中也会详解)。
- 图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,我们会在后面的文章中将重点介绍,嘿嘿!。
- 当对工作区新增或修改的文件执行 “git add” 命令时,暂存区的目录树被更新,同时工作区新增或修改的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。(如上图)
- 当执行提交操作 “git commit” 时,暂存区的目录树写到版本库的对象库(objects)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。(如上图)
- 当执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。 当执行 "git rm --cached " 命令时,会直接从暂存区删除文件,工作区则不做出改变。
- 当执行 “git checkout .” 或者 "git checkout – " 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
- 当执行 “git checkout HEAD .” 或者 "git checkout HEAD " 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动
- 图示:
1.6 给文件重命名的简便方法
- 使用git mv 命令重命名:
git mv fileOldName fileNewName
- 提交时可以写变更的原因 -m
git commit -m"将xxx文件名称修改"
1.7 通过git log 查看版本演变历史
- 直接命令:
git log
- 简洁地查看git日志:
- 代码:
git log --oneline
- 图示:
- 代码:
- 查看最近的2次git日志:
git log -n2 --oneline
如果要查看多次的话,这里的-n2可以改为其他,比如查看四次则是-n4
- 查看所有分支的日志历史:
git log --all
一般git log默认展示的日志是当前分支的日志;
- 图形化的查看所有分支列表(能够看清分支之间的继承关系):
- 代码:
git log --all -graph
- 图示:
- 代码:
- 获取所有分支最近的4个commit的图形展示:
git log --oneline --all -n4 --graph
1.8 gitk: 通过图形界面工具来查看版本历史
-
gitk 是什么?
- gitk是git图形化的界面软件版本,对仓库的管理更为直观,不需要在命令行中进行繁琐的控制,将各种信息合理的组织在不同的软件窗口中,让一些很繁琐的操作可以在图像软件中只需要一键获得。
- 合理的结合命令行和图形工具可以大大提高软件开发和分支管理的效率。
-
页面展示:
-
提交显示窗口:
目前有很多工具,这个只做了解,感兴趣的同学可以再网上参考相关的资料。
1.9 探秘.git目录
- .git目录下的字目录列表:
- HEAD目录:当我们切换分支的时候,HEAD内指向的目录路径会发生变化,它告诉了我们现在工作的分支在哪个路径上:
- config目录:
- 存放了一些配置信息,比如auther、email等以及配置信息;
如果直接对文件内容进行修改,跟命令修改有一样的修改效果。如果用命令修改,文件内的属性也会对应发生变化。
- refs目录:
- heads是独立的空间,分支; tags是里程碑;
- 如图所示:
- heads里面存储了master和其他分支。而.git的head目录(引用,表示当前工作目录)则指向refs里的head目录(源)
1.10 commit、tree和blob三个对象之间的关系
- 概念解释:
- commit:存储一次提交的信息,包括所在的tree,parent是谁,以及提交的作者是谁等信息;
- tag:标签,实际可当做是commit的别名;
- tree:代表的是目录结构,或者简单理解为代表一个目录;
- blob:用来存储文件内容,或者说标识一个文件
- 每一次commit相当于一次快照,它形成了一个tree目录列表,文件的每一次修改又会生成一个blob,blob信息记录在tree下面。blob代表了一个真正的文件,然后每个tree中指向了blob这个引用(这样能够节约空间和消耗),如图所示:
1.11 分离头指针情况下的注意事项
- 分离头指针的含义:
- 通常我们工作在某一个分支上,比如master分支。而master指针和HEAD指针是一起前进的,每做一次提交,这两个指针就会一起向前挪动一步。
- 分离头指针就是没有任何分支,它只有HEAD工作目录。在这个基础上进行的开发,我们可以保存到新的分支上(
git checkout -b 新的分支名称
),如果不保存,当切换到其他的目录时,会自动抛弃到此部分内容; - 简单来说,分离头指针就是一种非重要内容|一些尝试性内容,可以随时抛弃或者一些尝试。符合要求就可以保存,不想要拉取其他代码时会自动抛弃。
因为拉取其他代码时会自动抛弃内容(分离头指针的内容如果没有与分支绑定,切换到其他分支后是无法找回到分离头指针时的文件的,因为它没有与分支绑定。),所以这点需要注意(git也可能会当做垃圾给清理掉。)。
1.13 进一步理解HEAD和branch
- 在git中HEAD和branch是两个特殊的引用,它们都指向commit。
- 关于HEAD,一般情况下,是HEAD指向branch然后再指向commit,但是当HEAD处于游离状态时它就不再指向branch而是直接指向commit,所以说HEAD是指向活跃分支的游标这句话似乎不太准确,而是指向当前的commit。
- 关于branch,本质是指向commit的引用,这里的commit是单个的commit,当有新的commit提交时,branch会移动到新的commit。但是我们在分支上会提交很多的commit,然后再进行合并的时候是将分支的所有commits合并过去
二. 独自使用Git时的常见场景
2.1 怎么删除不需要的分支?
- 正常的删除
git branch -d xxx
- 强制删除(如果正常删除无法删除,且能够控制删除风险)
git branch -D xxx
2.2 怎么修改最新的commit的message?
- 修改最近一次的commit的message:
-
输入变更命令:
git commit --amend
-
输入后会弹出一个文本内容,我们在里面进行修改我们的message内容:
-
修改完后保存即可,输入以下命令查看最近一次的日志记录,查看message是否改成了最新的:
git log -1
-