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

    image.png

  • 回退版本

    • 回退指定版本

    既然有记录就可以回退,执行以下命令
    git reset --hard commit_id 这个hard必须要,这个commit_id就是你上边看到的那个每次提交的id
    image.png

    • 回退到上一版本
      git reset --hard “HEAD^”

    image.png

  • 新写的代码写乱了或者删除了文件想恢复重新写怎么办(在工作区)
    image.png
    执行以上操作即可恢复到和本地仓库一样的版本
常用命令
  • 上面到过的git add 和 git commit -m 'xxx'
  • git status

    • 修改文件后查看文件状态git status,可以让我们掌握仓库当前的状态,下面的命令输出告诉我们,hello.js被修改过了,但还没有准备提交的修改。
      image.png
  • 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:<github用户名>/<我们刚刚创建的仓库名称>.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文件夹。

    image.png
    文件夹内包含id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
    image.png

  • 在github上添加SSH KEY
    登陆GitHub
    image.png

为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。

当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。

最后友情提示,在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放进去。

如果你不想让别人看到Git库,有两个办法,一个是交点保护费,让GitHub把公开的仓库变成私有的,这样别人就看不见了(不可读更不可写)。另一个办法是自己动手,搭一个Git服务器,因为是你自己的Git服务器,所以别人也是看不见的。这个方法我们后面会讲到的,相当简单,公司内部开发必备。

github创建远程仓库及关联本地仓库

  • 创建远程仓库
    进入你的仓库
    image.png
    点击new
    image.png
    只需要设置一个名字 其他保持默认即可
    image.png
    创建成功之后会生成一个空的远程仓库
  • 关联远程仓库

    • 这里可以直接执行克隆操作,这样拉下来的文件自动会关联到远程仓库
    • 也可以使用本地仓库已有文件关联远程仓库
      进到我们的gitTest文件夹,执行以下命令

    git remote add origin git@github.com:<github用户名>/<我们刚刚创建的仓库名称>.git
    添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。

  • 将本地代码推送到远程仓库
    git push -u origin master远程仓库是空的所以加上-u,这行命令是将本地的master内容推送到远程master分支上,并进行关联,以后再进行提交就可以直接git push
    image.png
    推送成功后就实现了本地和远程仓库同步了
  • 删除远程关联库
    如果执行关联操作的时候不小心写错了命令,我们可以通过git remote -v先查看关联远程仓库的信息,如果确认是错误的那么执行git remote rm origin(这里的origin是远程仓库的名字,如果有改动需要将命令行中的origin换成修改之后的名字)

git分支

为什么会产生分支的概念?

如果项目来了一个新需求,而你只开发了一部分,由于代码不完整就会影响其他成员工作,如果一次性提交的话又会产生代码丢失的后果。

分支的原理

git会将每一次提交串联起来生成一条线,那么这条线就叫分支。初始这条分支名称叫master,master指向最新的提交记录,其中还有一个head属性,指向的是master。
image.png
这时我们新建了一个分支名叫dev,git会新建一个名叫dev的指针,使指针指向最新的提交记录即master,当我们切换分支到dev的时候那么head这个指针就会指向dev,这时我们开发了新代码就可以随意的在我们自己的分支上提交了,而每一次提交只需要移动dev的分支即可,master指针不动。
image.png
切换到dev分支
image.png
提交代码到dev分支
image.png

合并分支

当我们的新需求开发完成之后,我们需要合并到master主分支上,而git的内部进行合并的方式也是非常简单,直接将master分支指向dev所指向的提交记录即可,这时我们甚至可以删除dev分支,对我们也不会有任何影响。
image.png

分支实战

  • 创建分支并切换到dev分支
    git checkout -b dev加上-b表示切换并创建相当于git branch devgit checkout dev两个命令的组合
    image.png
  • 查看当前的分支
    git branch
    image.png
  • 在分支上修改内容
    在分支上修改内容之后,进行提交,再将分支切换到master分支,我们打开文件看一看master分支上是改之前的,也就意味着只有dev分支上做了更改。
    image.png
    更改之后
    image.png
    提交
    image.png
    切换到master分支查看改动了dev分支的内容master是否跟着修改了
    执行git checkout master之后打开文件
    image.png
    结果正符合我们上面所说的
  • 合并分支
    在master分支上使用git merge dev合并,执行之后打开文件就是我们修改过的内容了
    image.png
    打开文件
    image.png
  • 删除分支
    开发完之后我们可以将dev分支删掉
    执行git branch -d dev删除dev分支

解决冲突

产生冲突的原因是,假如我们有一个feature1分支,我们切换到这个分支进行了代码修改,然后我们又切换到了master分支修改同一行代码或者是别的成员在master分支上修改了代码进行了提交,那么这时候这两个分支就会产生冲突,这种情况下git就不能进行快速合并了,需要我们手动合并。

解决冲突实战

现在我们有一个hello.js的文件,文件内容如下
image.png

  • 创建名为feature1的分支并切换到此分支
    image.png
  • feature1分支上修改hello.js的内容
    image.png
  • 提交feature1分支上的内容并切换到master分支
    image.png
  • master分支上修改hello.js文件
    image.png
  • 提交master分支上的内容
    image.png
    现在feature1master分支上的内容都提交了,这时git分支是这样的:
    image.png
  • 合并代码
    image.png
    提示自动合并失败
  • 查看冲突文件hello.js
    image.png
    <<<<HEAD表示所在的分支
    ========分割线
    >>>>>>>>表示冲突的分支
    这时我们手动解决一下,比如我只想要master上的代码,那就把========>>>>>>>>的代码删除掉即可
    手动完毕后提交即可
  • 最后删除feature1分支
    git branch -d feature1
  • 查看分支合并图
    git log --graph

bug分支

平时我们开发项目的时候一般每次上线的版本都使用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分支上的代码
    image.png
  • 现在正在开发dev分支上的代码
    image.png
    现在有一个紧急bug需要改以下然后合并到master分支上
  • 缓存dev分支上的代码
    image.png
  • 切换分支并创建bug分支
    image.png
  • 修改bug
    我是hello.js改成我是hello.js文件
    image.png
  • 提交修改,切换到master分支并合并bug分支
    image.png
    这时master分支的内容时这样的:
    image.png
  • 修改完毕 切换到dev分支
    切换分支
    image.png
    查看dev分支下的文件
    image.png
  • 还原切换分支之前的代码
    查看缓存列表
    image.png
    由于dev分支是从master分支拉取出来的,那么他一定也存在着这个bug
    执行 git cherry-pick eea3e28即可将修改的bug代码携带过来,再进行合并即可。
    eea3e28时提交issue时生成的hash戳
    还原
    image.png
    还原之后dev分支上的代码
    image.png

多人协作

当你的领导给你分配了一个项目,但是只能在dev分支上修改,然后提交到dev分支上。但是github上没有创建此分支。

  • github创建分支
    红框里的内容时搜索或者创建分支
    image.png

创建成功之后会自动从master分支拉取代码,并切换到dev分支
image.png

  • 将项目clone到本地
    image.png
    在某个本地文件夹中打开git bash here执行clone操作
    image.png
    进入到项目中
    image.png
  • 创建dev分支,修改内容并且进行提交
    image.png
    修改文件
    提交
    image.png
  • 推送到远程仓库
    推送之前先拉代码
    image.png
    提示本地dev分支需要和远程仓库dev分支连接
    image.png
    提交成功
    image.png
    image.png

回滚代码

github上不保留历史记录 直接回滚到你想要的版本 但是中间的提交记录将会被干掉

新创建一个仓库,先提交几次代码
第一次提交内容我是第一次提交hello文件
第二次提交内容我是第二次提交hello文件
第三次提交内容我是第三次提交hello文件

  • 执行 git log查看提交记录
    image.png
  • 回滚本地代码到第一次
    image.png
    image.png
  • 执行git push -f origin <branch_name>
    将本地回滚的代码推送到远程仓库,这里需要加强制的选项 -f--force
    image.png
  • 查看github
    image.png
  • 查看github历史记录
    image.png

回滚并保留原来的数据

还以上面提交记录为准
image.png
如果我们想回到hello2版本
image.png
我们执行的revert hello2发现文件出现了冲突
image.png
仔细看看也没有我们想要的第二次的信息,是因为revert hello2那一次操作会以 hello1 的状态为参考基准
我们使用reset还原以下
image.png
image.png
之后再重新执行以下revert
image.png
执行完毕之后
image.png
文件显示
image.png
再进行提交操作
image.png
github上最新文件
image.png
再查看历史记录
image.png
保留了原来的


mengyuhang4879
13 声望7 粉丝