Git入门
一、版本控制
1、什么是版本控制
版本控制 是一种记录一个或若干个文件 的内容变化,以便于将来查阅特定版本修订情况的系统。
2、为什么使用版本控制
采用版本控制系统(VCS),可以方便的查询各个阶段(时间节点)的代码,即使你将代码修改的一塌糊涂,你依旧可以很方便的返回到原来的版本,减少额外的工作量。
3、常用版本控制系统分类
(1)本地版本控制系统(VCS)。例如:RCS。
(2)集中化的版本控制系统(CVCS)。例如:CVS、SVN。
(3)分布式版本控制系统(DVCS)。例如:Git。
二、Git
1、什么是Git
Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开源的版本控制软件。
2、Git与其他版本控制系统的区别
区别在于对待数据的方式不同。
大部分版本控制系统(如:CVS,Perforce)将它们保存的信息 看做是一组基本文件 和 每个文件随时间逐步累积的差异。即存储的是每个文件与初始版本的差异。
Git将保存的信息看成 对小型文件系统的一组快照。只要你提交更新或更新Git状态时,它都会对整个文件制作一个快照并保存这个快照的索引,为了高效,当文件没被修改时,Git不再重新存储这个文件,但会保留一个链接指向之前存储的文件。即存储的是每个文件与前一个版本的差异。
3、Git保证数据的完整性
Git中所有的数据在存储前都计算校验和,然后以校验和来引用,这就意味着不可能在Git不知情的情况下修改文件内容或目录。此功能构建在Git底层。若是在传送过程中丢失信息或者损坏文件,Git就能发现。
Git计算校验和的机制是SHA-1散列(hash),是一个由40个十六进制字符(0~9,a~f)组成的字符串,基于Git中文件的内容以及目录结构计算得出。
Git数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。
4、Git特点
(1)分支管理:
对非线性开发模式的强力支持(即允许成千上万个并行开发的分支)。即允许开发团队可以同时推进多个任务,提高效率。
(2)权限控制:
可以对团队中参与开发的人员进行权限控制,可以控制开发人员是否有权限修改代码。
(3)分布式:
不会出现SVN那种单点故障的状态,当远程库的项目崩了,可以从任意一个本地库去获取项目。
(4)版本管理:
SVN采用增量式管理的方式保存版本信息,而Git采取快照的方式保存(很方便的恢复到某个版本)。
5、代码托管中心
代码托管中心的任务:维护远程库。
(1)局域网环境下:
GitLab
(2)外网环境:
GitHub
码云
5、Git三种状态
Git三种状态(committed, modified, staged)
(1)已提交(committed)
表示数据已经安全的保存在本地数据库中。
(2)已修改(modified)
表示修改了文件,但还没有保存到数据库中。
(3)已暂存(staged)
表示对已经修改的文件加了标记,使其包含在下次提交的快照中。
6、Git四个工作区域
Git四个工作区域(远程仓库, 本地库,工作目录, 暂存区域)
(1)远程仓库(Remote repository)
Git用来保存项目的元数据和对象数据库的地方(托管代码的服务器)。克隆仓库时,即拷贝此部分的数据。
(2)本地库(Local Repository)
本地库又叫版本库,本地安全存放数据的位置,里面存放着提交到所有版本的数据。
(3)工作目录(Working Directory)
指的是从项目的某个版本提取出的内容,即从Git压缩数据库中提取出的内容,置于磁盘用于用户使用并修改。
(4)暂存区域(Stage / Index)
指的是一个文件,保存了下次将提交的文件列表的信息,一般在Git仓库的目录中。
7、Git工作流程
(可以在本地新建一个本地库,或者克隆一个远程库)
step1、在工作目录修改文件。(已修改状态)
step2、暂存文件,将文件的快照放入暂存区域。(已暂存状态)
step3、提交更新,找到暂存区域的文件,将快照永久性存储到本地库的目录中。(已提交状态)
step4、最后本地库再同步到远程库中。
三、Git常用命令
1、git init
用于初始化一个本地库。
git init
用于初始化一个本地库,执行完毕后,会在本地创建一个 .git 文件夹(是一个隐藏文件夹)。
.git 目录中存放的是与本地库相关的子目录与文件,不要随意删除与修改。
2、git config
配置git信息。
比如配置开发人员的签名,用于区分不同开发人员的身份。这里的信息与GitHub上的信息无关。
项目级别、仓库级别:(仅在当前本地库范围内有效) git config user.name "Tom" git config user.email "hello@163.com" 系统用户级别:(当前操作系统的范围) git config --global user.name "Tom" git config --global user.email "hello@163.com" 优先级: 项目级别优先于系统级别,二者均存在时,使用项目级别的优先级。二者必定存在一个。 注: 若使用系统用户级别,则执行完毕后,信息会存在于 ~/.gitconfig 文件中。 使用项目级别、仓库级别,则执行完毕后,信息会存在于 ./.git/config 文件中。
3、git remote、git clone、 git pull、 git fetch
用于获取远程库的项目。
git remote -v #查看当前远程仓库,若有多个远程仓库,会将其全部列出。 git remote add fileName url #给远程仓库取个别名
git remote remove fileName #根据别名删除添加的远程仓库 git clone url git clone url projectName 其中: url指的是项目的地址, projectName指的是本地保存的项目名,若不指定,则默认为远程库的项目名。 将远程仓库clone到本地库,此时会将远程仓库完整的克隆下来,包括所有的版本记录以及 .git 文件夹,不用进行 git init 操作。 git fetch 获取远程库的某个分支,需要手动进行合并分支的操作。 方式一: git fetch origin master #从远程的origin仓库的master分支下载代码到本地的origin maste git log -p master.. origin/master #比较本地的仓库和远程参考的区别 git merge origin/master #把远程下载下来的代码合并到本地仓库,远程的和本地的合并 方式二: git fetch origin master:temp #从远程的origin仓库的master分支下载到本地并新建一个分支temp git diff temp #比较master分支和temp分支的不同 git merge temp #合并temp分支到master分支 git branch -d temp #删除temp git pull url 远程分支名:本地分支名 拉取远程分支到本地的操作,git pull是相当于从远程仓库获取最新版本,然后再与本地分支merge(合并)。 即 git pull = git fetch + git merge git pull origin master:branchtest #将远程主机origin的master分支拉取过来,与本地的branchtest分支合并。 如果 :branchtest 不存在,则表示将远程origin仓库的master分支拉取下来与本地当前分支合并。 等价于 git fetch origin master:brantest git merge brantest
4、git status
用于查看当前工作区的状态。
git status
5、git add
用于将工作区的代码 提交到 缓存区。
git add fileName
其中
fileName指的是需要提交的文件名。
6、git rm
用于将缓存区的代码 退回到 工作区。
git rm fileName
7、git commit
用于将缓存区的代码 提交到 本地库。
git commit fileName git commit -m message fileName 注: 使用 -m 时,需要带上 提交信息。不使用 -m 时, 会提示输入 提交信息。
8、git log、git reflog
用于查看历史记录。
git log #用于查看完整的历史记录。 注: 若历史记录过多,可能出现多屏的状态,此时使用 空格 可以向下翻页,使用 b 向上翻页,使用 q 退出。 下面三种均是打印出简洁版的历史记录。 git log --pretty=oneline #每个历史记录只显示一行 git log --oneline #显示当前版本及以前的版本的记录 git reflog #显示所有记录
9、git reset
用于版本的前进和后退,底层通过HEAD指针来操作。
方法一(基于索引值,可以前进与后退): git reset --hard 索引值 方法二(使用异或符号(^),只能后退): git reset --hard HEAD^^^ #一个^表示后退一个版本, 此处表示后退三个版本 方法三(使用(~)符号,只能后退): git reset --hard HEAD~3 #同样表示后退三个版本 reset的参数: --soft 仅在本地库中移动HEAD指针,不会修改缓存区与工作区。 --mixed 在本地库移动HEAD指针,且重置暂存区,不修改工作区。 --hard 在本地库移动HEAD指针,且重置暂存区、工作区。
10、git diff
常用于比较两个分支日志和文件的差异。
git diff xxA..xxB
1. 比较两个分支文件内容的差异
git diff branch1 branch2 --stat //显示出所有有差异的文件列表
git diff branch1 branch2 文件名(带路径) //显示指定文件的详细差异
git diff branch1 branch2 //显示出所有有差异的文件的详细差异
2.比较两个分支日志的差异
git log banch1 ^branch2 //branch1有的,branch2没有的
git log ^branch1 branch2 // branch2有,branch1没有
git log branch1..branch2 //中间是两个点,表示branch2比branch1多提交的
git log branch1...branch2 //中间三个点,不知道哪个分支多提了,就想比较下两个分支的差异
git log --left-right branch1...branch2 显示出每个提交是哪个分支上的,"<"代表该提交在左边的分支 branch1
11、git branch、git checkout、git merge
用于分支管理。创建分支、切换分支、合并分支。
在版本控制系统中,使用多条线同时推进多个任务,即多个分支,可以提高开发效率。分支间彼此独立,可以直接删除、创建某分支。
git branch -v #查看当前所有分支 git branch hot_fix #创建一个hot_fix分支 git checkout hot_fix #切换到hot_fix分支 git merge hot_fix #合并hot_fix分支 合并分支时,可能会造成代码冲突,此时需要手动解决。 在冲突文件中,会出现如下代码: <<<HEAD ==== >>>master 其中: <<<HEAD ==== 表示当前分支的代码 ==== >>>master 表示另一个分支的代码 排除代码后,需要提交到本地库。 git add fileName #将代码从工作区提交到缓存区 git commit -m message #注意,此处不需要再带上文件名
12、git cherry-pick
用于合并某次提交记录。类似于 merge,只是更加灵活。
【基本语法:】 git cherry-pick commit-id # 合并某次提交,commit-id 指的是某次提交记录产生的 id git cherry-pick commit-idA commit-idB # 合并多个提交 git cherry-pick commit-idA..commit-idB # 合并连续的多个提交 【合并冲突时:】 先手动解决冲突。 git add . # 再提交到暂存区 git cherry-pick --continue # 继续合并 git cherry-pick --abort # 可以中断合并,回退到之前状态 git cherry-pick --quit # 可以中断合并,但是保留合并的状态