Git 是当前流行的分布式版本控制管理工具,最初由 Linux Torvalds (Linux 之父) 创造,于 2005 年发布。
官网地址:https://git-scm.com/
Git诞生:https://www.liaoxuefeng.com/wiki/896043488029600/896202815778784
版本控制
什么是 版本控制?我为什么要关心它呢?
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 我们通常对保存着软件源代码的文件作版本控制,但实际上,你可以对任何类型的文件进行版本控制。
如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能),采用版本控制系统(VCS)是个明智的选择。 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。
使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。 但额外增加的工作量却微乎其微。
版本控制系统应具备功能
协同修改:多人并行不悖的修改 服务器端的同一个文件。 数据备份:不仅保存目录和文件的当前状态,还能够保存每一个提交过的历史状态。 版本管理:在保存每一个版本的文件信息的时候要做到不保存重复数据,以节约存储空 间,提高运行效率。这方面SVN 采用的是增量式管理的方式,而Git 采取了文 件系统快照的方式。 权限控制:对团队中参与开发的人员进行权限控制。对团队外开发者贡献的代码进行审核——Git 独有。 历史记录:查看修改人、修改时间、修改内容、日志信息。将本地文件恢复到某一个历史状态。 分支管理:允许开发团队在工作过程中多条生产线同时推进任务,进一步提高效率。集中式与分布式的不同
Git 采用与 CSV/SVN 完全不同的处理方式,前者采用分布式,而后面两个都是集中式的版本管理。
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有 “中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件 A,你的同事也在他的电脑上改了文件 A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当 “中央服务器” 的电脑,但这个服务器的作用仅仅是用来方便 “交换” 大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
SVN与Git的最主要的区别
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了。
Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
Git 三大区域
- 工作区(Working Directory)
- 暂存区(Staging Area)
- 版本库(Repository)
使用Git的时候有3个工作区的概念:Git 仓库、工作目录以及暂存区域。其中工作目录比较好理解,就是我们开发时修改文件的那些目录,Git 仓库就是我们项目目录下面的 .git
目录中的内容,而暂存区域是保存已经被Git标记过,将要提交保存到Git数据库中的文件的地方
文件从我们创建到编辑完提交Git帮我们记录,一共要经历3种状态:已修改(modified)、 已暂存(staged)和已提交(committed)
- 刚刚开始时编辑文件,这个时候文件是处于 已修改(modified) 状态,文件是在工作目录
- 修改完文件,我们执行
git add
,这个时候文件就变为 已暂存(staged)状态,文件信息进入暂存区域,内容被保存到Git数据库中 - 然后我们执行
git commit
,文件就变为已提交(committed)状态,创建了一个提交记录保存到了Git 仓库
Git命令行管理版本
想要让Git对一个目录进行版本控制需要以下几个步骤:
- 进入要管理的文件夹
- 执行初始化命令
- 管理目录下的文件状态
- 管理指定文件
- 生成版本
- 查看版本记录
创建版本库
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,又或者在将来某个时刻可以 还原 某个指定版本
创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录,也不一定必须在空目录下创建Git仓库,选择一个已经有东西的目录也是可以的
创建目录
$ mkdir gitRepository
可以使用dos命令创建也可以右键新建文件夹,创建一个空文件夹。
进入创建的目录
$ cd gitRepository/
查看当前目录的位置
$ pwd
/e/gitRepository
执行初始化命令
通过git init
命令把这个目录变成Git可以管理的仓库:
$ git init
Initialized empty Git repository in E:/gitRepository/.git/
Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),当前目录下多了一个.git
的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
如果你没有看到.git
目录,那是因为这个目录默认是隐藏的,用ls -ah
命令就可以看见。或者在资源管理器中设置隐藏的项目即可查看。
管理和查看文件状态
查看文件状态
git status
管理文件:
git add 文件名 # 管理指定文件
git add . # 管理指定全部修改过的文件
管理后的文件会从 红色 变 绿色
生成版本
git commit -m '描述信息'
简单解释一下git commit
命令,-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
嫌麻烦不想输入-m "xxx"
行不行?确实有办法可以这么干,但是强烈不建议
git commit
命令执行成功后会告诉你,1 file changed
:1个文件被改动(我们新添加的readme.txt文件);2 insertions
:插入了两行内容(readme.txt有两行内容)。
查看版本记录
在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log
命令查看:
git log
git log
命令显示从最近到最远的提交日志。如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数:
$ git log --pretty=oneline
edc39f3a3bb12b154914e9338862f56934247beb (HEAD -> master) 第三次提交
bd58d63cba06cf63a83b75b9302a445a8693d4d3 第二次添加
d47037d191d3b7f3a2867bab4c9289fe180b984a gitTest1第一次添加
c0a8218e729190384186d65ce6b356165e5d7b5e 第一次创建三个文件
版本回退
现在,你已经学会了修改文件,然后把修改提交到Git版本库
像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit
。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit
恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
首先Git必须知道当前版本是哪个版本,在Git中用HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
回退到之前的版本
当前版本回退到上一个版本,就可以使用git reset
命令,这样我们就回退到指定的版本了
git log
git reset --hard 版本号
回退到之后的版本
假如你回退到了某个版本,突然又想想恢复到新版本应该怎么办?
在Git中,总是有后悔药可以吃的。当你用git reset --hard HEAD^
回退到指定版本时,再想恢复到未回退版本,就必须找到未回退版本的commit id。Git提供了一个命令git reflog
用来记录你的每一次命令:
git reflog
git reset --hard 版本号
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
。- 穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本。 - 要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本。
Git分支
分支概述可参考:https://www.liaoxuefeng.com/wiki/896043488029600/896954848507552
分支命令的使用
- 查看分支
git branch
- 创建分支
git branch 分支名称
- 切换分支
git checkout 分支名称
- 分支合并(可能差生冲突)
分支合并的同时先切换分支在合并
git merge 要合并的分支
- 删除分支
git branch -d 分支名称
远程仓库
GitHub
引用文章地址:https://www.liaoxuefeng.com/wiki/896043488029600/896954117292416
- 创建仓库
点击create repository ,进入下面的页面创建仓库完成
- 在GitHub上添加远程库
给远程仓库起别名
git remote add origin 远程仓库地址
向远程推送代码
git push -u origin 分支
- 从GitHub远程库克隆
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone
命令克隆。
克隆远程仓库代码
git clone 远程仓库地址
切换分支
git checkout 分支名
- 案例
码云
rebase 使用
rebase在git中是一个非常有魅力的命令,使用得当会极大提高自己的工作效率;相反,如果乱用,会给团队中其他人带来麻烦。
它的作用简要概括为:可以对某一段线性提交历史进行编辑、删除、复制、粘贴;因此,合理使用rebase命令可以使我们的提交历史干净、简洁!
提示:不要通过rebase对任何已经提交到公共仓库中的commit进行修改
合并多个commit为一个完整commit
当我们在本地仓库中提交了多次,在我们把本地提交push到公共仓库中之前,为了让提交记录更简洁明了,我们希望把如下分支B、C、D三个提交记录合并为一个完整的提交,然后再push到公共仓库。
现在我们在测试分支上添加了四次提交,我们的目标是把最后三个提交合并为一个提交,这里我们使用命令:
git rebase -i [startpoint] [endpoint]
其中-i
的意思是--interactive
,即弹出交互式的界面让用户编辑完成合并操作,[startpoint]
[endpoint]
则指定了一个编辑区间,如果不指定[endpoint]
,则该区间的终点默认是当前分支HEAD
所指向的commit
(注:该区间指定的是一个前开后闭的区间)。
在查看到了log日志后,我们运行以下命令:
将某一段commit粘贴到另一个分支上
多人协同开发工作流
什么是Git工作流?
Git工作流你可以理解为工作中团队成员遵守的一种代码管理方案
GitFlow工作流
GitFlow工作流程使用两个分支代替了单个主分支去记录项目的历史。 master 分支存储正式的发布历史记录,develop 分支充当功能的集成分支。使用版本号标记 master 分支中的所有提交也很方便。
Forking工作流
自定义Git
配置文件
Git 使用简单的 .ini 文件作为配置文件,配置文件中记录了很多 Git 命令使用的各种选项和设置,Git 支持不同级别的配置文件,下面按照优先级从高到低的顺序对它们进行介绍:
当前仓库的配置文件:当前仓库/.git/config
git config --local user.name 'userName'
git config --local user.name 'userName@qq.com'
全局配置文件:~/.gitconfig 文件 :当前用户的配置文件。可以通过传递—global 选项使Git 读或写这个特定的文件。
git config --global user.name 'userName'
git config --global user.name 'userName@qq.com'
系统配置文件:/etc/gitconfig 文件:包含了适用于系统所有用户和所有库的值。如果你传递参数选项’—system’ 给 git config,它将明确的读和写这个文件。注意:需要有root权限
git config --system user.name 'userName'
git config --system user.name 'userName@qq.com'
应用场景
git remote add origin 地址 默认添加在本地配置文件中(--local)
Git免密登陆
URL中体现
原来的地址:https://github.com/xiaohaijia/GitTest.git
修改后的地址:https://用户名:密码@github.com/xiaohaijia/GitTest.git
git remote add origin https://用户名:密码@github.com/xiaohaijia/GitTest.git
git push origin master
SSH实现
生成公钥和私钥(默认放在 ~/.ssh目录下,id_rsa.pub公钥,id_rsa私钥)
$ ssh-keygen
$ cat ~/.ssh/id_rsa.pub
拷贝公钥内容到GitHub
配置成功
在Git本地配置ssh地址
git remote add origin git@github.com:xiaohaijia/GitTest.git
以后使用
git push origin master
Git忽略文件
让Git不在管理当前目录下的某些文件
git如果需要忽略某个文件夹,可以在初始化之后,在仓库根目录下创建一个.gitignore文件,添加需要忽略的文件和文件夹即可
不需要从头写.gitignore
文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore不需要从头写`.gitignore`文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:[https://github.com/github/gitignore](https://github.com/github/gitignore)
忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的
.class
文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
GitHub任务管理
- issuess
Issues(问题单)是一种伟大的工作方式,它用于对项目进行跟踪、增强和排错。它们就像电子邮件一样 —— 除了它们可以与团队的其他成员进行分享和讨论。大多数软件项目都会有某种错误跟踪器,GitHub 的错误跟踪器称为“Issues”,并且在每个仓库中都有自己的 Issues 部分。 - wiki
项目的文档