一、Git是什么
1.Git是目前世界上最先进的分布式版本管理系统
2.工作原理/流程
workspace:工作区
Index/Stage:暂存区
Repository:仓库区(本地仓库)
Remote:远程仓库
二、SVN和Git的最主要的区别
1.SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器那里得到最新的版本,然后干活,干完后,需要把自己做的活推送到中央服务器,集中式版本控制系统是必须联网才能工作,如果在局域网中还可以,带宽够大,速度够快,如果是在互联网中,如果网速慢的话,就纳闷了。
2.Git是分布式版本控制系统,它没有中央服务器,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都在自己的电脑上,既然每个人的电脑都有一个完整的版本库,那么多人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们俩之间只需要把各自修改推送给对方,就可以看到对方修改了。
三、Git的安装
1.比较傻瓜化,一路向前一下步即可。
四、如何操作Git
1.创建版本库
什么是版本库,版本库又名仓库,英文名Repository,你可以简单的理解就是一个目录,只是这个目录里面的所有文件都被Git管理起来了,每个文件的修改、删除,Git都能跟踪,一般任何时刻都可以追踪历史,或者在将来的某个时刻将文件“还原”。
所以创建版本库也比较简单,比如在某一个盘下面新建一个文件夹”testgit”作为版本库,例如在F盘创建一个testgit文件夹,然后右键该文件夹使用”Git Bash Here”打开:
然后在Git的命令窗口中运行”git init”将当前的testgit目录初始化成Git可以管理的仓库,如下:
此时,在testgit目录下会多一个”.git”的隐藏目录,这个目录是Git用来跟踪和管理版本的,不要乱动这个目录的文件,否则会将Git仓库破坏掉:
2.把文件添加到版本库
在testgit目录下新建一个文件readme.txt,输入内容:111111111111111111
第一步:使用”git add readme.txt”将文件添加到暂存区(Index/Stage)
第二步:使用命令”git commit”将暂存区的文件提交给本地仓库(仓库/版本库)
-m后面的文字是注释
此时,我们可以使用”git status”命令来查看是否还有其他文件没有提交给本地仓库:
说明没有任何文件未提交
现在我们继续修改readme.txt,比如添加一行222222222222222,继续使用”git status”来查看:
上面的命令告诉我们readme.txt文件已经被修改,但是没有添加到暂存区从而可以提交给本地仓库,如果我们想看看readme.txt文件到底修改了哪些内容,可以使用如下命令:git diff readme.txt
可以看到,readme.txt增加了22222222222222222的内容,知道了readme.txt修改了什么内容之后,我们就可以将其提交给仓库,提交修改的方式和提交文件的方式相同:
总结:
添加新文件或修改文件:
1. 添加到暂存区:git add 文件名
2. 提交到本地仓库:git commit -m ‘注释’
五、版本回退
之前我们已经学习了修改文件,现在我们继续修改readme.txt,再增加一行33333333333333,继续add和commit:
现在我们已经对readme.txt进行了3次修改,那么我们想查看一下历史记录,如何查看呢?我们可以使用”git log”来查看:
“git log”命令显示从近到远的日志,最近一次是增加33333333333333,上一次是添加22222222222222,第一次是默认的111111111111111,如果觉得日志显示内容太多,可以使用命令”git log --pretty=oneline”:
现在我们想使用版本回退功能,把当前版本回退到上一个版本,可以使用如下两个命令:
第一种:”git reset --hard HEAD^”,表示回退到上一个版本,要回退到上上版本,就把HEAD^改为HEAD^^,以此类推,如果要回退100个版本,这种方式肯定不方便,可以使用第二种方式。
第二种:”git reset --hard HEAD~100”,回退到之前的第100个版本
示例:
当然我们可以继续使用”git log”来查看当前的历史记录:
我们可以看到增加3333333333333的历史记录不见了,但是现在我们又想回退到最新的版本,我们可以通过“版本号”回退,使用命令:”git reset --hard 版本号”,现在的问题是如何获取版本号,我们可以通过”git reflog”来查看版本号:
我们可以看到,增加3333333333333的版本号是:2fa4a8e,现在我们可以通过命令来恢复:
现在我们又恢复到了增加3333333333333333的版本上了。
总结:
回退版本:git reset --hard HEAD^,git reset --hard HEAD~100
查看历史记录:git log,git log --pretty=oneline
查看版本:git reflog
回退到指定版本:git reset --hard 版本号
六、理解工作区和暂存区的区别
1.工作区:就是你电脑上看到的目录,比如目录testgit里面的文件(.git隐藏目录版本库除外),或者以后需要再新建的目录文件等等都是属于工作区范畴。
2.版本库:Repository,工作区中有一个隐藏目录.git,这个不属于工作区,是版本库,其中包含了很多东西,其中最重要的就是stage(暂存区),还有Git为我们自动创建的第一个分支master,以及指向master分支的一个指针HEAD。
我们前面说明使用Git提交文件到版本库有两步:
第一步:使用”git add”把文件添加到暂存区
第二步:使用”git commit”将暂存区的内容提交到版本(本地仓库)的当前分支上
现在我们在readme.txt中增加444444444444444444内容,并且在该目录中新加文件test.txt,先用”git status”查看一下状态:
然后我们使用”git add”将两个文件都添加到暂存区,再使用”git status”查看:
接着使用”git commit”一次性将两个文件都提交到当前分支:
所以我们总结出来,不管是第一次创建文件,还是修改文件,还是新增文件,处理方式都一致,都是add之后commit就行。
七、Git撤销修改和删除文件操作
1.撤销修改
比如我们在readme.txt中增加一行555555555555555555,先通过命令查看一下:
在还没有提交之前,我们发现添加的5555555555555555有错,需要恢复到以前的版本,可以有如下做法:
(1)如果我们知道要删除哪些内容的话,直接手动修改文件,然后再add到暂存区,最后commit掉
2.删除文件
假如版本库testgit目录中添加了一个文件b.txt,然后提交:
我们可以直接在目录下删除文件:
再运行git status:
可以看到b.txt文件已经被删除,此时有两种选择:一种是直接commit掉,二是从版本库中恢复被删除的文件。
一般情况下,可以直接在文件目录中将文件删除,如果想彻底从版本库中删除此文件的话,可以再运行commit命令提交,只要没有commit之前,我们可以通过”git checkout -- 文件名”就可以恢复被删除的文件:
如果想彻底删除:
从暂存区删除:
提交版本库:
总结:
已经提交的文件被删除
恢复:git checkout -- 文件名
彻底删除:
暂存库删除:git rm 文件名
提交:git commit -m ‘注释’
八、远程仓库
如何添加远程仓库:
现在的场景是:我们已经在本地创建了Git仓库,又想在Gitee(码云)(或GitHub(国外))上创建Git的远程仓库,并且希望这两个仓库同步,这样Gitee的远程仓库可以作为备份,其他人也可以通过该远程仓库来协作。
首先,注册Gitee,登陆Gitee,创建一个新的仓库:
因为Git是分布式版本控制系统,所以需要填写用户名和邮箱来作为一个标识,注意:git config --global参数,有了这个参数,标识你的机器上的所有的Git仓库都会使用这个配置,当然你可以对某个仓库指定不同的用户名和邮箱:
现在我们对本地仓库进行Git全局设置:
然后给Git指定远程个仓库的地址:git remote add origin 远程仓库的URL地址,URL地址在这里:
我们把之前testgit目录下的所有文件commit到本地仓库:
当所有文件都add到暂存区,并且commit到本地仓库后,就可以使用push命令把本地仓库的内容推送到远程仓库,而上面设置的就是远程仓库的地址:(第一次推送的时候要加上-u参数)
注意:有时候要输入用户名和密码:你需要输入你注册Gitee的手机号和密码
到远程仓库看一下:
把本地仓库的内容推送到远程仓库,使用”git push”命令,实际上是把当前分支master推送到远程,由于远程是空的,所以第一次推送master分支的时候,要加上”-u”参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或拉取时就可以简化命令。从现在起,只要本地做了提交commit,就可以通过”git push origin master”把本地的master分支的最新修改推送到Gitee远程仓库上,现在你就拥有了真正的分布式版本库了。
如何从远程仓库克隆到本地:
假如远程仓库有新的内容,我们想克隆到本地,如何克隆?首先登陆Gitee,创建一个新的仓库,名叫testgit2,并添加文件到仓库中:
点击“初始化readme.txt”生成远程仓库的新文件:
此时,远程仓库就准备好了,下一步使用”git clone”克隆一个本地库,首先在本地创建一个testgit2文件夹,然后在该文件夹中克隆:
克隆的地址在这里:
此时我们就可以在克隆的目录中进行修改,然后再add,commit,push到远程仓库
远程仓库:
九、创建合并分支
1.在版本回退里,我们知道,每次提交,Git都把它们串成一条时间线,这条时间线就是第一个分支,到目前为止,我们只有一条时间线,在Git中这个分支(时间线)叫做主分支,即master分支,HEAD严格来说不是指向提交,而是指向master,而master才是指向提交的,所以HEAD指向的就是当前分支。
(1)首先我们来创建dev分支,然后切换到dev分支(使用之前的testgit仓库):
查看分支:
其中”git checkout”命令加上”-b”参数表示创建并切换分支,相当于执行了如下两条命令:
git branch dev #创建dev分支
git checkout dev #切换到dev分支
git branch命令会列出所有的分支,并且当前分支前面有一个”*”。
(2)然后我们在dev分支继续做,比如现在给readme.txt增加6666666666666
(3)现在dev分支工作已经完成,现在我们切换到master分支,继续查看readme.txt内容
发现没有66666666666666内容,因为现在不是dev分支
十、分支管理策略
通常合并分支时,Git一般使用”Fast forward”模式,在这种模式下,删除分支后,会丢掉分支信息,我们可以使用带参数”--no-ff”禁用”Fast forward”模式。
(1)现在我们可以将dev分支的内容合并到master分支,使用命令”git merge dev”:
“git merge”命令用于合并指定分支到当前分支,合并后,再查看readme.txt内容,可以看到和dev分支最新提交的内容完全一致。
注意到上的”Fast-forward”信息,Git告诉我们,这次合并使用”快进方式”,也就是直接把master分支指向dev的当前提交,所以合并速度非常快,合并完成之后,我们就可以把dev分支删除了:
(2)如何解决分支的冲突?
我们新建一个分支,名叫fenzhi1,然后在readme.txt中添加一行7777777777777777,然后提交:
同样,切换到master分支,也在最后一行增加88888888888888888
现在我们在master分支上合并fenzhi1:
查看merge之后的文件,发现Git使用<<<<<<<<,========,>>>>>>>>>标记出不同分支的内容,其中<<<<<<<<<<HEAD是指主分支内容,>>>>>>>>>fenzhi1是指fenzhi1上修改的内容,我们可以手动修改文件之后提交:
如果我们想查看分支合并的情况的话,可以使用”git log”:
十一、Bug分支
在开发过程中,经常会碰到bug,那么有了bug就要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修改完成后,合并分支,然后将临时分支删除掉。
比如我们在开发过程中遇到了一个404 bug的时候,可以创建一个404分支来修复它,但是当前dev分支上还有工作没有提交,比如:
并不是我们不想commit这个dev分支,而是工作进行了一半,还不能提交,比如dev分支还需要2天完成,但是issue-404的bug需要5小时内完成,那怎么办呢?Git还提供了一个stash的功能,可以将当前的工作现场”隐藏起来”,等到以后要用的时候恢复现场继续工作,例如:
此时查看dev分支的状态,发现所有内容已经提交,是干净的。
现在我们就可以创建issue-404分支来修复404的bug了
首先我们要确定在哪个分支上修改bug,比如我们现在是在主分支master上来修复的,所以要在master分支上创建一个临时分支issue404:
修复bug完成之后,切换到master分支,完成合并,最后删除issue-404分支:
切换到master分支,然后禁用了”Fast Forward”模式的前提下进行issue-404分支merge到master分支,然后删除issue-404分支。
现在我们可以回到dev分支继续干活:
运行”git status”发现dev分支是干净的,那么我们的工作现场在哪里呢?我们可以使用命令”git stash list”来查看:
工作现场还在,Git把stash内容存在了某个地方,需要恢复一下,有两种方法恢复现场:
1)”git stash apply”恢复后,在使用”git stash drop”删除
2)“git stash pop”恢复现场的同时把stash内容删除
然后我们就可以在dev分支上继续做后面的工作了。
十二、多人协作‘
当你从远程仓库克隆的时候,实际上Git自动把本地的master分支和远程的master分支对应起来,并且远程库默认的名称是origin
查看远程库的信息使用:git remote,如果要查看详细信息:git remote -v
1. 推送分支
推送分支就是把该分支上的所有本地内容提交到远程库中,推送时,要指定本地分支,这样Git就会把该分支推送到远程对应的分支上,使用命令:git push origin master
比如本地的readme.txt:
远程仓库:
现在我们想把本地更新的readme.txt推送到远程仓库,可以使用如下命令:
远程库:
可以看到推送成功,如果我们现在要推送到其他分支,比如dev分支,那么还是这个命令:
git push origin dev
那么一般情况下,哪些分支要推送呢?
master是主分支,因此要与远程同步,一些修复bug的分支不需要推送到远程,可以先合并到主分支(master),然后再把主分支master推送到远程去。
2. 抓取分支
多人协作时,大家都会往master分支推送各自的修改,现在我们可以模拟另一个同事,可以在另外一台电脑或同一个电脑的另一个目录中克隆,新建目录名为testgit2,接着进入testgit2目录,进行克隆远程库到本地来:
如下目录:
现在我们的同事要在dev分支上做开发,就必须把远程的origin的dev分支弄到本地来,于是可以使用命令创建dev分支:git checkout -b origin/dev
首先我们需要将dev分支推送到远程仓库(在testgit目录中完成):
远程仓库:
其次使用”git checkout -b dev origin/dev”命令把远程origin库的dev分支弄到本地来(在testgit2目录中完成)
如果命令运行出错,则运行”git fetch origin”进行远程同步即可
修改readme.txt(在testgit2中):
远程仓库:
同事已经向origin/dev分支推送了修改内容,而我的目录文件中也对同一个地方做修改,也试图推送到远程库时,如下:
由上可知:推送失败,因为我的同事最新提交的和我试图推送的有冲突,解决办法也很简单,上面已经给出提示了,先用”git pull”把最新的提交从”origin/dev”抓取下来,然后在本地合并,解决冲突,再推送:
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的连接,根据提示,设置本地dev分支和远程origin/dev的连接:
这会”git pull”成功了,并且提示合并有冲突,需要手动解决,解决办法和分支管理中解决冲突的办法一致,解决冲突后,在提交,再push到远程库:
现在我们已经手动将冲突解决了,所以可以再次提交,再次push:
远程库:
因此,多人协作的工作模式一般是这样的:
首先:可以试图使用”git push origin 分支名”去推送自己的修改,如果推送失败,则因为远程分支比你本地更新的早,需要先试用”git pull”试图合并,如果合并有冲突,则手动解决冲突,然后在本地再次提交,再次”git push origin 分支名”去推送。多人远程协作的经验就是,先pull之后进行本地修改,改完再去提交和push。