Git历史
谈论git之前,我们先来说下 Linux,Linux是一个开源系统,Linus 创建了Linux,但是Linux的壮大是靠着全世界的热心“志愿者”共同参与的
2002年之前,志愿者们把代码通过 diff的方式发给linus,然后linus通过手工的方式合并代码(他觉得CVS、SVN合并代码效率低,太low;使用付费的版本控制工具,又违背了Linux的开源之道)
2002年之后,BitMover公司免费向Linux社区提供BitKeeper 版本控制系统
2005年,一位Linux开发成员 写了一个可以连接BitKeeper 仓库的工具(外挂),试图破解BitKeeper协议(不允许使用者开发类似BitKeeper 的版本控制系统),导致BitMover公司收回了 Linux社区的免费使用权
LInus 决定自己开发一个 版本管理系统
10天后,Git 诞生了(C语言),一个月后,Linux系统的源码已经由git管理了
2008年 GitHub网站上线,为开源项目提供Git存储
集中式与分布式
集中式版本控制系统:CVS、SVN等
分布式版本控制系统:Git、BitKeeper等
集中式特点:有中央服务器,保存所有文件的修订版本,中央服务器崩了 或者没有网络的话,都不能commit代码
分布式特点:没有中央服务器,每个人的电脑都有一个完整的“版本库”,安全性高,某个人的电脑崩了的话,从别人的电脑里在复制一份就可以
Git安装:自行百度
Git工作区与暂存区:
工作区:电脑中能看到的目录就是工作区
工作区的隐藏文件 .git(创建版本库时会被创建,记录版本历史)不算时工作区,是版本库
git add后,将文件放入暂存区(stage),git commit,将stage中的所有文件都提交到 master分支中(git init的时候,自动创建了master分支)
无暂存区
HEAD:本地仓库 当前引用
config:git仓库的配置文件
description:仓库的描述信息
hooks:存放shell脚本
objects:存放所有 git对象
有暂存区(多了index文件)
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
暂存区,降低了commit的粒度:commit操作会全都提交,如果修改了两部分代码,只想提交一部分,此时 可以把想要提交的代码 add入暂存区,降低commit粒度
Git命令:
-
Git创建版本库:git init
-
添加文件到Git仓库:git add、git commit
git add:添加文件,将修改的文件放入暂存区,等待提交
git commit:提交文件,修改的文件直接被Git录入历史 -
版本回退:git log、git reset、git reflog
git log :显示从最近到最远的提交日志,参数 --pretty=oneline :简化log日志,美观
git reset:回退版本,HEAD表示当前版本,HEAD^表示上一版本,HEAD^^表示上两个版本,HADE~100表示上100个版本
git reflog:查看之前所有版本(包括已经被删除的 commit 记录和 reset 的操作),如果之前的记录被清空了,查不到版本id,通过这个命令可以把所有的提交历史都展示
git reset --hard <版本号>:指定回复到哪个版本,版本号不用填全,git会自动寻找
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD
指针,当你回退版本的时候,Git仅仅是把HEAD指针的指向改变了 -
查看状态:git status
-
撤销更改:git checkout、git reset
1)只修改了工作区的文件:git checkout2)修改的文件已经add 暂存区
将 暂存区的修改回退到工作区:git reset,然后再次git checkout,可以丢弃工作区的修改,使用git reflog可以查看所有操作历史
-
删除文件:git rm <file>
本地文件上传git,再删除本地文件后,git status会显示本地删除的文件git rm :从版本库中删除,然后 git commit即可删除干净
如果是工作区误删,直接使用git checkout -- <文件>恢复即可git
checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”
没有添加到版本库 就被删除的文件,是无法恢复的 -
克隆远程库:git clone
添加远程库
gitlab上新建一个项目,然后通过命令
git remote add origin https://git.haodf.net/liuweijian/learngit.git
git push -u origin master
可以将本地内容 同步到远程库中
创建分支
创建分支的本质:新建一个指针 dev,与master指向相同,HEAD之前指向master,新建分支后,HEAD指向 dev(HEAD指向当前分支)
(以下所有截图引自 廖雪峰的Git教程)
创建分支前:
创建分支后:
以上可以看出,新建分支对工作区的内容 完全没有修改,之后的操作 就是针对 dev分支了
将dev 合并到master,就是将master指向 dev的当前提交
删除分支就是将 dev指针删掉
实操
创建并切换分支:git checkout -b dev,相当于 git branch dev 创建分支、git checkout dev 切换分支
切换master并合并dev:git merge <指定分支>
最新版本的git支持 git switch切换分支
删除 dev分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
或者git switch <name>
创建+切换分支:git checkout -b <name>
或者git switch -c <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
合并冲突
新建分支,commit修改的内容,master分支同样修改了该文件,也commit了,这个时候merge的时候会报错,提示merge冲突
冲突的修改内容展示:
修改冲突后,使用 git log --graph --pretty=oneline --abbrev-commit可以查看冲突解决的日志