Git入门-01¶
1.Git概述¶
Git是一个免费的,开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。
Git易于学习,占地面积小,性能极快。它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于Subversion,CVS,Perforce 和 ClearCase 等版本控制工具。
1.1何为版本控制¶
在学习Git之前,我们需要先明白一个概念:版本控制。
版本控制是一种记录文件内容变化,一边将来查阅特定版本修订情况的系统。
版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本,方便版本切换。
- 为什么需要版本控制?
从个人开发过渡到团体协作。
1.2版本控制工具¶
1.2.1集中式版本控制工具¶
CVS,SVN(Subversion),VSS……
集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS),诸如CVS,SVN等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连接到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。
这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做什么,而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要远比在每个客户端上维护本地数据库来得轻松容易。
事分两面,有好有坏,这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
1.2.2分布式版本控制工具¶
于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。
在这类系统中,像Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。
分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:
- 服务器断网的情况下也可以进行开发,因为版本控制系统是在本地进行的
- 每个客户端保存的都是整个完整的项目,包含历史记录,更加安全
1.3Git发展历史¶
1.4Git工作机制¶
工作区:指的是你代码存放的磁盘目录位置
除此之外可以通过pull,将代码推送到远程库中
1.5Git和代码托管中心¶
代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库。
局域网:GitLab
互联网:GitHub,Gitee
2.Git安装¶
关于Git的详细介绍:Git - Book (git-scm.com)
Git下载地址:Git - Downloads (git-scm.com)
Git安装教程:Git-详细安装教程
3.Git常用命令¶
命令名称 | 作用 |
---|---|
git config --global user.name 用户名 | 设置用户签名 |
git config --global user.email 邮箱 | 设置用户签名 |
git init | 初始化本地库 |
git status | 查看本地库状态 |
git add 文件名 | 添加到暂存区 |
git commit -m "日志信息" 文件名 | 提交到本地库 |
git reflog | 查看历史记录 |
git reset --hard 版本号 | 版本穿梭 |
3.1设置用户签名¶
命令:
git config --global user.name 你的用户名
git config --global user.email 你的邮箱
用户名和邮箱可以多次设置
可以在c盘的用户home目录下的.gitconfig文件中查看修改内容:
说明:签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。Git 首次安装必须设置一下用户签名,否则无法提交代码。 ※注意:这里设置用户签名和将来登录 GitHub(或其他代码托管中心)的账号没有任何关系。
3.2初始化本地库¶
使用git init
命令初始化本地仓库
1.创建一个项目文件夹,在文件夹下面右键,点击Git Bash Here,就可以将当前的路径赋给git命令行,即进入到当前目录。使用git init命令初始化当前目录:
2.初始化成功之后可以在当前目录下看到.git文件(隐藏文件):
3.3查看本地库状态¶
使用git status
命令来查看本地库状态
3.4添加暂存区¶
使用git add 文件名
命令将工作区的文件添加到暂存区
1.添加过后,Git就可以追踪到该文件:
2.如果在暂存区将该文件的cached删除(不是删除工作区的文件),删除后工作区的该文件又会变回未追踪状态
3.5提交本地库¶
使用git commit -m "日志信息" 文件名
命令将暂存区的缓存文件提交到本地仓库
日志信息必须填写
1.这时如果查看状态,可以看到如下状态,说明已经提交过文件,并且在提交过后文件既没有新增,也没有修改,工作树是干净的
2.也可以通过git reflog命令来查看引用日志信息:下图说明指针head指向了master分支第一次提交的版本
3.还可以使用git log命令来查看详细的日志:不仅可以看到提交的版本号,还可以看到提交者信息和提交时间
3.6修改文件¶
1.如果我们将**追踪过(创建过快照)**的文件再次进行修改,那么此时该文件的状态将是modified,且是红色的。代表已追踪过的文件又修改了,但是没有提交到暂存区。
2.这时,只要将修改过的文件再次添加到暂存区,文件的状态仍是modified,但是已经变为了绿色。代表已追踪过文件又修改了,并且已经提交到了暂存区。
3.将该文件提交commit后,再次查看本地库的状态,就可以看到工作树清空了
4.查看日志,可以看到本地仓库中有两个代码版本,head指针指向了master分支的第二个版本
3.7历史版本¶
3.7.1查看历史版本信息¶
git reflog
查看版本信息
git log
查看版本详细信息
git reflog 和 git log 的区别:
git log
是显示当前的HEAD
和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,……,这样的原则。
git reflog
根本不遍历HEAD
的祖先。它是HEAD
所指向的一个顺序的提交列表:它的undo
历史。reflog
并不是repo
(仓库)的一部分,它单独存储,而且不包含在pushes
,fetches
或者clones
里面,它纯属是本地的。reflog
可以很好地帮助你恢复你误操作的数据,例如你错误地reset
了一个旧的提交,或者rebase
,……,这个时候你可以使用reflog
去查看在误操作之前的信息,并且使用git reset --hard
去恢复之前的状态。
3.7.2版本穿梭¶
git reset 命令 | 菜鸟教程 (runoob.com)
命令:git reset [--soft|--mixed |--hard] [HEAD|版本号]
版本号可以通过 git reflog 命令查看
1.如下,通过命令可以穿梭回第二个版本。
通过git reflog命令查看日志,可以发现head指针已经指向第二个版本了
这时查看文件,可以发现文件的内容变成了第二个版本commit时的内容。
2.通过上述过程,可以将提交过的文件变为任意版本
progit:在 Git中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git对待数据更像是一个快照流。
4.Git分支操作¶
4.1什么是分支¶
在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时候,不会影响主线分支的运行。对于初学者而言,分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)
4.2分支的好处¶
同时并行推进多个功能的开发,提高开发效率。各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。
4.3分支的操作¶
分支命令 | 作用 |
---|---|
git branch 分支名 | 创建分支 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支(事实上是切换HEAD指针的指向) |
git merge 分支名 | 把指定的分支合并到当前分支上 |
4.3.1查看分支¶
git branch -v
查看分支
*
代表当前所在的分支
4.3.2创建分支¶
git branch 分支名
创建分支
git checkout -d 分支名
创建分支并切换到该分支上
4.3.3切换分支¶
git checkout 分支名
切换分支
可以看到当前分支已经切换到hot-fix分支
master、hot-fix 其实都是指向具体版本记录的指针。当前所在的分支,其实是由 HEAD 决定的。所以创建分支的本质就是多创建一个指针。 HEAD 如果指向 master,那么我们现在就在 master 分支上。 HEAD 如果执行 hotfix,那么我们现在就在 hotfix 分支上。 所以切换分支的本质就是**移动 HEAD 指针**。
4.3.4修改分支¶
分支的版本控制和主分支完全一致
比如现在修改hot-fix分支的hello.txt文件,查看该文件状态:
将其添加到暂存区并提交:
查看历史版本记录:
注:这里查看hot-fix分支可以看到之前在master分支上的提交记录,是因为分支的底层仍然是指针,它在创建的时候把复制分支当做父记录。这也是为什么创建一个新分支消耗的内存非常小。
4.3.5删除分支¶
删除本地分支
git branch -d 分支名
删除远程分支
git push remote_name -d remote_branch_name
4.3.6合并分支-正常合并¶
git merge 分支名
:把指定的分支合并到当前分支上
案例演示:在master分支上合并hot-fix分支(正常合并)
4.3.7合并分支-冲突合并¶
冲突产生的原因:合并分支时,**两个分支在同一个文件的同一个位置**有两套完全不同的修改,Git无法替我们确定使用哪一个,必须**人为决定**新代码内容。
案例演示:合并冲突分支
我们分别在master分支和hot-fix分支的同一个文件上的同一行进行修改,并分别commit
现在我们切换回master分支,在master分支上进行分支合并
系统提示:有文件合并冲突,修改冲突然后才能提交结果
这时的本地库状态为:
用vim打开冲突的文件:可以看到产生冲突的地方已经用符号标注出来了,下图中的标注解释为:
<<<<<<< HEAD
当前分支的代码
=======
合并过来的代码
>>>>>>> hot-fix
手动修改文件,并删除特殊符号,保存文件:
保存完文件之后,还要把修改后的文件再添加到暂存区:
然后提交保存:
注意此时commit不能带文件名,否则会提示错误。因为两个分支上的hello.txt都进行了修改,在合并冲突的情况下,git不知道提交的是哪一个文件
合并成功,右上角的MERGING标识消失:
注意:这里的合并只会修改master分支的文件,hot-fix分支的文件没有被修改
4.3.8Git以分支的方式同时管理多个项目¶
https://www.shuzhiduo.com/A/mo5kLl7Kdw/
5.Git团队协作机制¶
5.1团队内协作¶
5.2跨团队协作¶
6.GitHub操作¶
github网址:GitHub
6.1创建远程库¶
- 注册登录账号,点击账号页面
- 点击页面右上方的+号,选择new repository,创建新项目
- 在repository name中填写你的仓库名
注意:仓库名不支持中文,所有的中文符号会被自动识别为-
符号。
- 填写项目简介,简介支持中文
- 点击add a readme file选项,项目会自动创建一个readme文件
-
其他的选项默认即可
-
最后点击按钮创建
6.2远程仓库操作¶
命令名称 | 作用 |
---|---|
git remote -v | 查看当前所有远程地址别名 |
git remote add 别名 远程地址 | 起别名 |
git push 别名 分支 | 推送本地分支上的内容到远程仓库 |
git clone 远程地址 | 将远程仓库的内容克隆到本地 |
git pull 远程库地址别名 远程分支名 | 将远程仓库对于分支最新内容拉下来后与当前本地分支直接合并 |
6.2.1创建远程仓库别名¶
git remote -v
查看当前所有远程地址别名
git remote add 别名 远程地址
给远程仓库起别名
这里使用ssh链接,使用ssh链接前请看6.4SSH免密登录
可以看到拉取远程仓库和推送都可以使用该别名
6.2.2推送本地分支到远程仓库¶
git push 别名 分支
推送本地分支上的内容到远程仓库,如果没有起别名,使用远程地址代替也可以
现在将本地仓库上的master分支推动到远程仓库上:
在远程仓库上查看,已经成功推送文件:
2021年8月13日起,Github不再支持使用密码push,即不再接受帐户密码登录,下面这个push方法过时了:
6.2.3拉取远程库到本地库¶
git pull 远程库地址别名 远程分支名
将远程仓库对于分支最新内容拉下来后与当前本地分支**直接合并**
有时候远程仓库上的代码进行了更新,我们需要将新的代码下载到本地仓库里:
可以使用别名或者直接使用远程仓库进行拉取
这时查看本地文件的状态,发现工作树干净的,说明拉取动作会自动帮你提交本地库:
6.2.4克隆远程仓库到本地¶
git clone 远程地址
将远程仓库的内容克隆到本地
在远程仓库上复制链接:
在本地新建一个空白文件夹git-demo-second,在该文件夹中右键点击git bash here,打开git命令面板,使用克隆命令将远程仓库克隆到本地:
克隆公共仓库的代码不需要登录
克隆成功之后可以发现在git-demo-second目录下,已经成功下载了git-demo仓库的代码:
打开文件夹,不仅可以看到代码文件,还能看到.git隐藏文件:
这说明克隆clone会做如下操作:
- 拉取代码
- 初始化本地仓库
- 创建别名(创建的别名默认为origin,如下:)
6.3团队内协作¶
6.3.1选择邀请合作者¶
如果他人想要推送代码到你的仓库,获取你想要推送代码到他人的仓库,必须得到仓库所有者的许可权限,即仓库所有者拉取他人才能进入团队协作。
仓库拥有者操作:
仓库settings--Collaborators--Add people
输入拉取者的账户名称,选择后点击下方按钮:
复制邀请链接Pending Invite,发送给被邀请者:
被邀请者登录自己的github账号,登录后在浏览器地址栏中粘贴邀请链接,回车:
如下所示,被邀请者点击Accept invitation即可加入团队。
点击Accept invitation后会自动跳转到加入的仓库界面:
加入的合作者可以在自己的本地上直接推送代码到远程仓库中。
6.3.2跨团队协作¶
非团队内的人可以点击fork,将他人的仓库复制到自己的账户下,之后就可以对代码进行修改了。
修改完之后如果要把代码提交到他人的仓库下,要到别人的仓库下点击new pull request:
点击完之后会自动将你修改的代码展示出来,与作者的代码进行对比:
点击上一步的Create pull request后会创建一个拉取请求,可以在这里填写你的提交留言,点击提交,等待作者审批。
仓库所有者可以在仓库的Pull request界面看到别人提交的pull request
点击上一步的pull request标题即可查看提交详情:
点击留言下方的链接可查看别人提交的代码:
也可以给提交者留言(Write):
或者合并别人提交的代码(Merge pull request):
6.4SSH免密登录¶
想要使用ssh免密登录,首先要添加秘钥。
在本地电脑的用户目录下有一个.ssh目录(第一次安装git的用户可能没有该目录,或者打开该目录是空的)
在git命令窗口中,运行命令生成.ssh 秘钥目录:ssh-keygen -t rsa -C 你的邮箱
这里的邮箱是你注册github账号的邮箱
连续三次回车即可:
这时再次打开.ssh目录,可以发现该目录下已经创建了两个文件:
打开id_rsa.pub,全选复制里面的内容
打开之前邮箱对应的账号:点击账号头像--下拉点击Settings--在设置页面选择SSH and GPG keys
点击右上方的New SSH key,将之前复制的内容粘贴到框中,添加title,点击Add SSH key即可添加成功:
SSH的使用1:
之后就可以在本地使用SSH链接拉取仓库
第一次使用ssh的时候会提示是否继续链接,填写yes,回车:
显示成功拉取远程仓库代码
使用2:可以使用ssh免密推送代码到远程仓库