目录
Git是什么
Git工作流程
Git下载
Git环境配置
Git基础
初始化本地仓库
文件的两种状态
文件加入and取消暂存区
文件提交与删除
文件添加至忽略列
日志记录操作
比较文件差异
还原文件
远程仓库
常见的Git托管平台
远程仓库操作
推送和拉取
多人协作冲突问题
ssh协议推送
Git分支
分支是什么
创建分支
切换分支
提交分支至远程仓库
合并分支
删除分支
恢复删除分支
删除远程仓库分支
分支训练
重点注意(分支):
标签
标签概念
标签基本使用
检出与删除标签
Git工作流
GitFlow是什么
每个工作流程的作用
工作方式示例
部分图片来自百战程序员
Git是一种代码托管技术。在开发中,Git是一种代码托管技术,很多代码托管平台也是基于Git来实现的。Git可以帮我们做到很多的事情,比如代码的版本控制,分支管理等。
注意:
我们可以把Git理解成是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。正是因为有了Git的存在,现在很多工作才可以变得相对轻松。
四个工作区域:
Workspace: 工作区,就是你平时存放项目代码的地方
Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
工作流程
Git的工作流程一般是这样的:
在Windows操作系统中安装 Git之前,先从官方网站( https://git-scm.com/)下载合适的Git版本。
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息。
设置用户信息
git config --global user.name "baizhan"
git config --global user.email "[email protected]"
查看配置信息
检查当前的设置
git config --list
git config user.name
注意:
通过上面的命令设置的信息会保存在C:用户/user.gitconfig文件中。
如果是全新的开始
如果这是你第一次使用Git,那么就先从创建一个全新的目录开始吧。打开终端机窗口,并试着操作以下命令(命令后面的#是说明,不需要输入):
mkdir tmp #创建tmp目录
git init #初始化这个目录让Git对这个目录开始进行版本控制。
小提示:
git init 命令会在上述目录中创建一个名为 .git 的隐藏目录,并在其中创建一个版本库。该目录为文件,查看->显示隐藏目录。整个Git的精华都集中在这个目录中了,现在不先讲细节,只是体会一下使用Git的感觉,后续在详细介绍。
重点:有.git这个文件夹的文件夹,那么该文件夹就是工作目录
注意:
Git不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。
untracked未跟踪状态
未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
tracked跟踪状态
被纳入版本控制
查看文件状态命令
git status
文件加入暂存区命令
语法结构
git add 文件名
特殊命令:git add .
作用:将该目录下所有非暂存状态的文件保存到暂存区
文件取消暂存区命令
语法结构
git reset 文件名
如果仅是通过git add命令把移动加到暂存区,还不算是完成整个流程。如果想让暂存区的内容永久保存下来,就要使用git commit命令。
文件提交命令
git commit -m "提交信息"
参数:
如果不加m参数,会进入类似vim编辑。
删除文件
git rm 文件名
注意:
删除的文件只是删除工作目录的文件,我们的版本库里面还是存在的。 删除文件会把这个文件直接放入暂存区。
但是版本库中还是有这个文件,如果需要将版本库中的也删除掉,那么需要git commit一次
挽救已被删除的文件或目录
git checkout 文件名
注意:
当使用git checkout命令时,Git 会切换到指定的分支,但如果后面接的是文件名或路径,Git则不会切换分支,而是把文件从.git目录中复制一份到当前的工作目录。更精准地说,这个命令会把暂存区中的内容或文件拿来覆盖工作目录中。
如果想把所有删除文件都挽救回来,可以使用以下命令:
git checkout .
小技巧:
这个技巧不仅可以将删除的文件挽救回来,当改动某个文件后反悔了,也可以用它把文件恢复到上一次Commit的状态。不是所有情况下都能恢复被删除的文件的。因为整个Git的记录都是放在根目录下的 .git目录中,如果这个目录被删除了,也就意味着历史记录也被删除了,那么删除的文件也就不能恢复了。
一般我们总会有些文件无需纳入Git的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。在这种情况下,我们可以在工作目录中创建一个名为 .gitignore的文件(文件名称固定),列出要忽略的文件模式。
忽略规则
# / 表示 当前文件所在的目录
# 忽略public下的所有目录及文件
/public/*
#不忽略/public/assets,就是特例的意思,assets文件不忽略
!/public/assets
# 忽略具体的文件
index.class
# 忽略所有的class
*.class
# 忽略 a.class b.class
[ab].class
注意:
查看日志
git log
参数:
获取日志信息
git reflog
diff是指的是两个事物的不同。例如在Linux系统中,
diff命令会逐行比较两个文本的差异然后显示出来。
git diff命令格式
语法结构:
git diff :比较工作区和暂存区文件的差异
git diff [--cached] : 比较暂存区和版本库文件的差异
注意:
对于恢复修改的文件,就是将文件从仓库中拉到本地工作区,即 仓库区 ----> 暂存区 ----> 工作区。
对于修改的文件有三种情况:
情况I
只是修改了文件,没有任何 git 操作,直接一个命令就可回退
$ git checkout -- aaa.txt # aaa.txt为文件名
提示:使用该命令需要先将文件提交到版本库中
例子:我们还是使用上面测试文件差异的b.info文件
情况II
修改了文件,并提交到暂存区(即编辑之后,git add但没有gitadd但没有 git commit )
$ git log --oneline # 可以省略
$ git reset HEAD # 回退到当前版本
$ git checkout -- aaa.txt # aaa.txt为文件名
注意:
情况II 和 情况III 只有回退的版本不一样,对于 情况II,并没有 $ git commit,仓库版本也就不会更新和记录,所以回退的是当前版本
例子:我们将b.info修改一下,添加数据I love you,此时版本库里的数据时update b.info
情况III
修改了文件,并提交到仓库区(即编辑之后git add和gitadd和 git commit -m )
$ git log --oneline # 可以省略
$ git reset HEAD^ # 回退到上一个版本
$ git checkout -- aaa.txt # aaa.txt为文件名
注意:
git reset 版本号 ---- 将暂缓区回退到指定版本,根据 $ git log --oneline 显示的版本号,可以回退到任何一个版本,也可通过 HEAD 来指定版本。
重点:如果回退到了上一个版本,那么现版本将会消失,现版本里保存的文件将无法找到
我们可以借助互联网上提供的一些代码托管服务来实现,其中比较常用的有GitHub、码云、GitLab等。
首先我们需要先创建一个远程仓库
添加远程仓库
添加一个新的远程Git仓库,同时指定一个可以引用的简写。
git remote add
注意:
远程仓库的url在这里复制
查看远程仓库
如果想查看已经配置的远程仓库服务器,可以运行git remote命令。它会列出指定的每一个远程服务器的简写。如果已经克隆了远程仓库,那么至少应该能看到origin,这是Git克隆的仓库服务器的默认名。
语法命令:
git remote
克隆远程仓库
如果你想获得一份已经存在了的Git仓库的拷贝,这时就要用到git clone命令。Git克隆的是该Git仓库服务上的几乎所有数据(包括日志信息、历史记录等),而不仅仅是复制工作所需要的文件。当你执行git clone 命令的时候,默认配置下远程Git仓库中的每一个文件的每一个版本都将被拉取下来。
语法结构:
git clone 远程仓库地址url
移除无效的远程仓库
如果因为一些原因想要移除一个远程仓库,可以使用git remote rm
git remote rm 远程仓库名字
注意:
此命令只是从本地移除远程仓库的记录,并不会真正影响到远程仓库。
Git远程仓库_推送
当你想分享你的代码时,可以将其推送到远程仓库。
git push [remote-name][branch-name]
参数:
remote-name = 仓库名
Branch-name = 分支名
例子:将文件推送到blog仓库中
从远程仓库中拉取
语法结构:
git pull [remote-name][branch-name]
remote-name = 仓库名
Branch-name = 分支名
例子:创建一个新的工作目录,并连接远程仓库,然后拉取
注意:
git pull是从远程仓库获取最新版本到本地仓库,会自动merge
当两个人同时操作同一个文件时就会出现冲突问题
如何解决:第二个人提交过后会报错,然后将该文件从远程仓库再获取一次,手动删除不要的代码
为什么会出现冲突问题
下载远程仓库
由此我们可以发现,如果两个人都更改了同一个文件并且都push到了远程仓库,那么后面push的人一定会报冲突错误,那么如何解决该问题呢?
1、首先git pull将文件拉取下来
根据拉取信息会发现,自动合并了a.info文件,那么就是a.info文件出现了冲突问题,我们来vim一下a.info文件
Git支持的传输协议
由于Git的远程仓库不在我们本地,当我们在使用远程仓库的时候(例如克隆,拉取,推送)就会涉及到数据的网络传输,Git支持多种数据传输协议,包括:
本地协议(Local)
什么是SSH协议
SSH为Secure Shell(安全外壳协议)的缩写,由IETF的网络小组(Network Working Group)所制定。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。
配置SSH协议
以使用Git提供的命令行工具Git Bash生成公钥和私钥,具体操作过程如下:
1.使用命令ssh -keygen -t rsa生成公钥和私钥
ssh -keygen -t rsa
注意:
执行完成后在window本地用户.ssh目录(C:\Users\用户名.ssh)下生成如下名称的公钥和私钥。
2.复制公钥文件内容至服务器上
3.配置完成后就可以正常传输数据了
分支是什么
有人可能认为,所谓的“开分支”,就是把文件先复制到另外的目录,然后进行改动,之后再合并,把文件与原本的文件比对之后放回原来的目录……其实,Git不是这样做的。
分支像贴纸一样
可以把分支想象成一张贴纸,贴在某一个Commit上面。
当做了一次新的Commit之后,这个新的Commit会指向它的前一个Commit。
而接下来“当前的分支”,也就是HEAD所指的这个分支,会贴到刚刚做的那个Commit 上,同时HEAD也会跟着前进。
结论:
Git中的分支并不是通过复制目录或文件来进行改动形成的,它就是一个指标、一张贴纸,贴在某个Commit 上而已。
一个分支不够,就来两个
如果一个分支不够说明,那就来两个。通过git branch cat命令创建一个新的分支。它就像一张贴纸,与master贴在同一个地方。
接下来执行git checkout cat命令,切换到cat分支。此时, HEAD转而指向cat分支,表示它是“当前的分支”。
接着进行一次新的Commit,这个新的Commit会指向前一次Commit。
然后,cat分支上的“贴纸”就会被撕下来,转而贴到最新的那个Commit上;当然HEAD也是一样。
重点:
只有commit过后,分支的改动才会在新的commit生效,旧的commit不会生效,也就是相当于我在分支中创建了一个文件a1.info,
1、如果没有commit,master中也会有这个文件,因为此时这两个分支都指向了同一个版本号,改变这个版本两个分支都会生效
2、如果commit了,那么分支的操作就会在新的版本生效,不关当前版本的事
git branch 分支名字
git checkout 分支名字
git push 远程仓库名字 分支名字
git merge 分支名字
git branch -d b1
注意:
如果要删除的分支中进行了一些开发动作,此时执行上面的删除命令并不会删除分支,如果坚持要删除此分支,可以将命令中的-d参数改为-D 。
删除分支的时候会报信息,Deleted branch cat(was b1729234),而信息后面有一串代码b1729234,那就是版本号,删除分支只是删除了该版本的贴纸,并不会删除该版本,所以可以通过新建一个分支指向该版本号实现恢复删除分支
git branch new_cat 版本号
注意:
这个命令"请帮我创建一个叫做new_cat的分支,让它指向版本号对应的版本",也就是在拿一张贴纸贴回去。
git push origin -d 分支名字
工作场景如下
为实现某个新的需求,创建一个分支(dev)。在这个分支上开展工作。正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。
你将按照如下方式来处理:
1、空的git是没有分支的,
只有创建了文件并且commit过后才会出现分支master
2、只有commit过后,分支的改动才会在新的commit生效,旧的commit不会生效,也就是相当于我在分支a1中创建了一个文件a1.info,
1、如果没有commit,master中也会有这个文件,因为此时这两个分支都指向了同
个版本,改变这个版本两个分支都会生效
2、如果commit了,那么分支的操作就会在新的版本生效,不关当前版本的事
3、在哪个分支创建的新分支,那么这个新分支拷贝的就是哪个分支的目录
Git可以给历史中的某一个提交打上标签,以示重要。比较有代表性的是人们会使用这个功能来标记发布结点(v1.0、v1.2等)。标签指的是某个分支某个特定时间点的状态。通过标签,可以很方便的切换到标记时的状态。
什么时候用标签
通常开发软件时会完成特定的“里程碑”,如软件版号1.0.0或beta-release之类的,这时就很适合使用标签做标记。
标签与分支有什么区别
标签与分支的区别是,分支会随着Commit而移动,但标签不会。之前介绍过当Git往前推,进一个Commit时,它所在的分支会跟着向前移动。而标签一旦贴上去不管Commit怎么前进,标签都会留在原来贴的那个位置上。因此,分支可以看成是“会移动的标签”。
注意:
这两者在被删除的时候,都不会影响到被指到的那个对象。
列出已有标签
git tag
创建标签
git tag 标签名字
查看标签信息
git show 标签名
标签推送远程仓库
git push [remote] [tag]
检出标签
新建一个分支,指向某个tag
git checkout -b [branch] [tag]
删除本地标签
git tag -d [tag]
删除远程标签
$ git push origin :refs/tags/标签名字
注意:
:refs/tags/是固定写法。
Git Flow是什么
在使用Git的过程中如果没有清晰流程和规划,否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护。GitFlow工作流通过为功能开发、发布准备和维护分配独立的分支,让发布迭代过程更流畅。严格的分支模型也为大型项目提供了一些非常必要的结构。
Git Flow 的常用分支
解释:
所有在Master分支上的Commit应该打上Tag,一般情况下Master不存在Commit,Devlop分支基于Master分支创建
Feature分支做完后,必须合并回Develop分支, 合并完分支后一般会删点这个Feature分支,但是我们也可以保留。
Release分支基于Develop分支创建,打完Release分之后,我们可以在这个Release分支上测试,修改Bug等。同时,其它开发人员可以基于开发新的Feature 发布Release分支时,合并Release到Master和Develop, 同时在Master分支上打个Tag记住Release版本号,然后可以删除Release分支了。
注意:
一旦打了Release分支之后不要从Develop分支上合并新的改动到Release分支。
hotfix分支基于Master分支创建,开发完后需要合并回Master和Develop分支,同时在Master上打一个tag。
此时公司来了两个人zhangsan、lisi,现在给他们分配任务,zhangsan制作登录模块,lisi制作页面模块