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:<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文件夹。


    文件夹内蕴含id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露进来,id_rsa.pub是公钥,能够释怀地通知任何人。

  • 在github上增加SSH KEY
    登陆GitHub

为什么GitHub须要SSH Key呢?因为GitHub须要辨认出你推送的提交的确是你推送的,而不是他人假冒的,而Git反对SSH协定,所以,GitHub只有晓得了你的公钥,就能够确认只有你本人能力推送。

当然,GitHub容许你增加多个Key。假设你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只有把每台电脑的Key都增加到GitHub,就能够在每台电脑上往GitHub推送了。

最初情谊提醒,在GitHub上收费托管的Git仓库,任何人都能够看到喔(但只有你本人能力改)。所以,不要把敏感信息放进去。

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

github创立近程仓库及关联本地仓库

  • 创立近程仓库
    进入你的仓库

    点击new

    只须要设置一个名字 其余放弃默认即可

    创立胜利之后会生成一个空的近程仓库
  • 关联近程仓库

    • 这里能够间接执行克隆操作,这样拉下来的文件主动会关联到近程仓库
    • 也能够应用本地仓库已有文件关联近程仓库
      进到咱们的gitTest文件夹,执行以下命令

    git remote add origin git@github.com:<github用户名>/<咱们刚刚创立的仓库名称>.git
    增加后,近程库的名字就是origin,这是Git默认的叫法,也能够改成别的,然而origin这个名字一看就晓得是近程库。

  • 将本地代码推送到近程仓库
    git push -u origin master近程仓库是空的所以加上-u,这行命令是将本地的master内容推送到近程master分支上,并进行关联,当前再进行提交就能够间接git push

    推送胜利后就实现了本地和近程仓库同步了
  • 删除近程关联库
    如果执行关联操作的时候不小心写错了命令,咱们能够通过git remote -v先查看关联近程仓库的信息,如果确认是谬误的那么执行git remote rm origin(这里的origin是近程仓库的名字,如果有改变须要将命令行中的origin换成批改之后的名字)

git分支

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

如果我的项目来了一个新需要,而你只开发了一部分,因为代码不残缺就会影响其余成员工作,如果一次性提交的话又会产生代码失落的结果。

分支的原理

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 devgit 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分支上的内容

    当初feature1master分支上的内容都提交了,这时git分支是这样的:
  • 合并代码

    提醒主动合并失败
  • 查看抵触文件hello.js

    <<<<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分支上的代码
  • 当初正在开发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 <branch_name>
    将本地回滚的代码推送到近程仓库,这里须要增强制的选项 -f--force
  • 查看github
  • 查看github历史记录

回滚并保留原来的数据

还以下面提交记录为准

如果咱们想回到hello2版本

咱们执行的revert hello2发现文件呈现了抵触

认真看看也没有咱们想要的第二次的信息,是因为revert hello2那一次操作会以 hello1 的状态为参考基准
咱们应用reset还原以下


之后再从新执行以下revert

执行结束之后

文件显示

再进行提交操作

github上最新文件

再查看历史记录

保留了原来的