git和集中式版本管理仓库的区别
操作本地仓库
git不用连接网络就可以直接操作版本库(每台电脑都有一个仓库,操作的是本地仓库)
为什么这么说呢?
git是分布式版本控制系统,每一台电脑都有一个属于自己的仓库。仓库可以理解成一个目录,这个目录里的所有文件都能被git管理起来,每个文件的增删改都可以被记录,还可以进行版本回滚。
示例操作
- 初始化仓库
mkdir gitTest
创建文件文件夹
cd gitTest
进入到文件夹
git init
初始化git仓库
创建一个js文件hello.js
- 编写js代码
现在修改的代码我们称之为工作区
let obj={ a:1, b:2 };
- 执行命令提交到本地
git add hello.js
把hello.js这个文件放到缓存区git commit -m "提交一个文件hello"
这个就是提交到本地仓库了。
-m和文字内容是提交要加描述和评论,为了自己看懂自己改了什么和别人看你改了什么
正在修改的代码叫工作区,add之后的代码是缓存区,commit之后的代码是本地仓库
- 查看提交记录
我们将这个文件多次修改多次执行add和commit操作,提交到本地仓库,然后使用下面的命令可以查看提交记录
git log --pretty=oneline --abbrev-commit
文章图片
- 回退版本
- 回退指定版本
git reset --hard commit_id
这个hard必须要,这个commit_id就是你上边看到的那个每次提交的id
文章图片
- 回退到上一版本
git reset --hard “HEAD^”
文章图片
- 新写的代码写乱了或者删除了文件想恢复重新写怎么办(在工作区)
文章图片
执行以上操作即可恢复到和本地仓库一样的版本
- 上面到过的git add 和 git commit -m 'xxx'
- git status
- 修改文件后查看文件状态
git status
,可以让我们掌握仓库当前的状态,下面的命令输出告诉我们,hello.js被修改过了,但还没有准备提交的修改。
文章图片
- 修改文件后查看文件状态
- git diff
- 使用git diff可以查看工作区相对于缓存区具体修改了哪里
- git log --pretty=oneline
查看历史记录 - git reset --hard commit_id
回退指定版本 - git reset --hard “HEAD^”
回退上一版本 - git reflog
当我们回退到某一版本,但是第二天又后悔了,可以使用git reflog
查看每一次的操作记录,就可以根据操作记录来进行指定的版本的恢复了 - git checkout --filename
新写的代码写乱了或者删除了文件想恢复重新写时,命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令。 - git reset HEAD filename
如果已经提交到了缓存区也可以使用此命令从缓存区撤回 - git rm filename
在git中删除某一个文件 然后使用git commit -m 'xx',文件就从版本库中删除了 - 删除的文件怎么恢复
git rm filename
相当于是删除工作目录中的filename
文件,并把此次删除操作提交到了暂存区。使用git checkout -- filename
相当于是让工作目录filename
恢复到暂存区中filename
的状态,但是工作目录中filename
已经被删除,无法找到文件来再次删除所以报错,必须先使用git restore --staged filename
在暂存区中将删除操作丢弃,然后在git checkout -- filename
就是直接将工作目录中filename
恢复到版本库中的状态。 - 本地仓库关联远程仓库
git remote add origin git@github.com:
/<我们刚刚创建的仓库名称>.git - git push -u origin master
远程仓库是空的所以加上-u
,这行命令是将本地的master内容推送到远程master分支上,并进行关联 - git remote -v
查看关联的远程版本库 - git remote rm origin
取消与名称为origin
远程仓库的关联操作,这里的origin
是远程仓库的名字,如果有改动需要将命令行中的origin
换成修改之后的名字 - git checkout -b dev
创建分支并切换 - git branch dev
创建名叫dev
的分支 - git checkout dev
将分支切换到dev
- git branch
查看当前分支 - git merge dev
合并dev分支 - git branch -d dev
删除dev
分支 - git stash
当有紧急任务需要切换分支时使用这个命令存储当前分支的代码 - git stash list
查看缓存列表 - git stash pop
恢复代码并删除缓存记录
远程仓库
上面已经讲到了git可以记录历史和回滚功能,svn也是有这种功能的。那么我们下一步看看git的远程仓库,再做比较。
上面说到git是分布式管理工具,每一台电脑克隆下来的就是一个版本库。那么很多人开发的时候只需要一台电脑24小时开机为我们服务,我们需要从那一台电脑中克隆下来代码,然后修改之后向那一台电脑提交修改,也可以拉取别人提交的代码。这里的电脑可以理解为一个服务器,而GitHub就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库。
由于本地git和github之间传输是经过ssh加密传输的,所以我们需要进行一些设置。 - 创建SSH KEY
- 先查看自己电脑上的用户文件夹下是否有.ssh文件,如果没有进行一下操作
桌面右键点击git bash here
(只要下载了git都会有这一项)。输入ssh-keygen -t rsa -C "自己的邮箱"
创建.ssh。这时就会在用户文件夹下生成一个.ssh文件夹。
文章图片
文件夹内包含id_rsa
和id_rsa.pub
两个文件,这两个就是SSH Key
的秘钥对,id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥,可以放心地告诉任何人。
文章图片
- 先查看自己电脑上的用户文件夹下是否有.ssh文件,如果没有进行一下操作
- 在github上添加SSH KEY
登陆GitHub
文章图片
当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
最后友情提示,在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放进去。
【git】如果你不想让别人看到Git库,有两个办法,一个是交点保护费,让GitHub把公开的仓库变成私有的,这样别人就看不见了(不可读更不可写)。另一个办法是自己动手,搭一个Git服务器,因为是你自己的Git服务器,所以别人也是看不见的。这个方法我们后面会讲到的,相当简单,公司内部开发必备。
github创建远程仓库及关联本地仓库
- 创建远程仓库
进入你的仓库
文章图片
点击new
文章图片
只需要设置一个名字 其他保持默认即可
文章图片
创建成功之后会生成一个空的远程仓库 - 关联远程仓库
- 这里可以直接执行克隆操作,这样拉下来的文件自动会关联到远程仓库
- 也可以使用本地仓库已有文件关联远程仓库
进到我们的gitTest文件夹,执行以下命令
git remote add origin git@github.com:
/<我们刚刚创建的仓库名称>.git
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
- 将本地代码推送到远程仓库
git push -u origin master
远程仓库是空的所以加上-u
,这行命令是将本地的master内容推送到远程master分支上,并进行关联,以后再进行提交就可以直接git push
啦
文章图片
推送成功后就实现了本地和远程仓库同步了 - 删除远程关联库
如果执行关联操作的时候不小心写错了命令,我们可以通过git remote -v
先查看关联远程仓库的信息,如果确认是错误的那么执行git remote rm origin
(这里的origin是远程仓库的名字,如果有改动需要将命令行中的origin换成修改之后的名字)
为什么会产生分支的概念? 如果项目来了一个新需求,而你只开发了一部分,由于代码不完整就会影响其他成员工作,如果一次性提交的话又会产生代码丢失的后果。
分支的原理 git会将每一次提交串联起来生成一条线,那么这条线就叫分支。初始这条分支名称叫master,master指向最新的提交记录,其中还有一个head属性,指向的是master。
文章图片
这时我们新建了一个分支名叫
dev
,git会新建一个名叫dev
的指针,使指针指向最新的提交记录即master
,当我们切换分支到dev
的时候那么head这个指针就会指向dev
,这时我们开发了新代码就可以随意的在我们自己的分支上提交了,而每一次提交只需要移动dev
的分支即可,master指针不动。文章图片
切换到
dev
分支文章图片
提交代码到dev分支
文章图片
合并分支 当我们的新需求开发完成之后,我们需要合并到
master
主分支上,而git的内部进行合并的方式也是非常简单,直接将master
分支指向dev
所指向的提交记录即可,这时我们甚至可以删除dev
分支,对我们也不会有任何影响。文章图片
分支实战
- 创建分支并切换到
dev
分支git checkout -b dev
加上-b
表示切换并创建相当于git branch dev
和git checkout dev
两个命令的组合
文章图片
- 查看当前的分支
git branch
文章图片
- 在分支上修改内容
在分支上修改内容之后,进行提交,再将分支切换到master分支,我们打开文件看一看master分支上是改之前的,也就意味着只有dev分支上做了更改。
文章图片
更改之后
文章图片
提交
文章图片
切换到master
分支查看改动了dev
分支的内容master
是否跟着修改了
执行git checkout master
之后打开文件
文章图片
结果正符合我们上面所说的 - 合并分支
在master分支上使用git merge dev
合并,执行之后打开文件就是我们修改过的内容了
文章图片
打开文件
文章图片
- 删除分支
开发完之后我们可以将dev
分支删掉
执行git branch -d dev
删除dev
分支
产生冲突的原因是,假如我们有一个
feature1
分支,我们切换到这个分支进行了代码修改,然后我们又切换到了master
分支修改同一行代码或者是别的成员在master
分支上修改了代码进行了提交,那么这时候这两个分支就会产生冲突,这种情况下git就不能进行快速合并了,需要我们手动合并。解决冲突实战 现在我们有一个
hello.js
的文件,文件内容如下文章图片
- 创建名为
feature1
的分支并切换到此分支
文章图片
- 在
feature1
分支上修改hello.js
的内容
文章图片
- 提交
feature1
分支上的内容并切换到master
分支
文章图片
- 在
master
分支上修改hello.js
文件
文章图片
- 提交
master
分支上的内容
文章图片
现在feature1
和master
分支上的内容都提交了,这时git分支是这样的:
文章图片
- 合并代码
文章图片
提示自动合并失败 - 查看冲突文件
hello.js
文章图片
<<<表示所在的分支
========
分割线>>>>>>>>
表示冲突的分支
这时我们手动解决一下,比如我只想要master
上的代码,那就把========
至>>>>>>>>
的代码删除掉即可
手动完毕后提交即可 - 最后删除
feature1
分支git branch -d feature1
- 查看分支合并图
git log --graph
平时我们开发项目的时候一般每次上线的版本都使用
master
分支上的内容,这个分支是稳定的。而我们开发会在dev
分支上开发,多个成员每次提交合并修改代码都在这个分支,当项目上线的时候合并到master
分支上即可。当我们正在
dev
分支上开发的时候,突然有一个紧急的bug需要修改,我们需要创建一个bug分支。这时dev
分支只开发了一部分,那么我们可以使用git stash
保存起来当前的修改。那么会有一个疑问,为什么有了git commit
还会有git stash
这两个不冲突吗?首先git commit
理论上是提交一个阶段能跑的代码,而git stash
是将这个分支的代码推入到git栈中。如果我们有一个bug需要切换分支,使用git commit
那么在别的分支也可以看到我们在dev
分支上做的修改,如果忘记切换分支在别的分支上开发那就比较麻烦了。而git stash
是将这个分支的代码存储起来,然后在执行git stash pop
即可找回我们切换分支之前的代码。实战
dev
分支上的代码
文章图片
- 现在正在开发
dev
分支上的代码
文章图片
现在有一个紧急bug需要改以下然后合并到master
分支上 - 缓存
dev
分支上的代码
文章图片
- 切换分支并创建bug分支
文章图片
- 修改bug
将我是hello.js
改成我是hello.js文件
文章图片
- 提交修改,切换到
master
分支并合并bug分支
文章图片
这时master
分支的内容时这样的:
文章图片
- 修改完毕 切换到
dev
分支
切换分支
文章图片
查看dev
分支下的文件
文章图片
- 还原切换分支之前的代码
查看缓存列表
文章图片
由于dev
分支是从master
分支拉取出来的,那么他一定也存在着这个bug
执行git cherry-pick eea3e28
即可将修改的bug代码携带过来,再进行合并即可。eea3e28
时提交issue
时生成的hash戳
还原
文章图片
还原之后dev
分支上的代码
文章图片
当你的领导给你分配了一个项目,但是只能在
dev
分支上修改,然后提交到dev
分支上。但是github上没有创建此分支。- github创建分支
红框里的内容时搜索或者创建分支
文章图片
master
分支拉取代码,并切换到dev
分支文章图片
- 将项目clone到本地
文章图片
在某个本地文件夹中打开git bash here
执行clone操作
文章图片
进入到项目中
文章图片
- 创建
dev
分支,修改内容并且进行提交
文章图片
修改文件
提交
文章图片
- 推送到远程仓库
推送之前先拉代码
文章图片
提示本地dev
分支需要和远程仓库dev
分支连接
文章图片
提交成功
文章图片
文章图片
github上不保留历史记录 直接回滚到你想要的版本 但是中间的提交记录将会被干掉 新创建一个仓库,先提交几次代码
第一次提交内容
我是第一次提交hello文件
第二次提交内容
我是第二次提交hello文件
第三次提交内容
我是第三次提交hello文件
- 执行
git log
查看提交记录
文章图片
- 回滚本地代码到第一次
文章图片
文章图片
- 执行
git push -f origin
将本地回滚的代码推送到远程仓库,这里需要加强制的选项-f
或--force
;
文章图片
- 查看github
文章图片
- 查看github历史记录
文章图片
文章图片
如果我们想回到
hello2
版本文章图片
我们执行的revert hello2发现文件出现了冲突
文章图片
仔细看看也没有我们想要的第二次的信息,是因为
revert hello2
那一次操作会以 hello1
的状态为参考基准我们使用reset还原以下
文章图片
文章图片
之后再重新执行以下revert
文章图片
执行完毕之后
文章图片
文件显示
文章图片
再进行提交操作
文章图片
github上最新文件
文章图片
再查看历史记录
文章图片
保留了原来的