首页 > 代码库 > 分布式管理控制系统Git与项目托管平台Github相关概念、操作方法与常用命令

分布式管理控制系统Git与项目托管平台Github相关概念、操作方法与常用命令

简介

技术分享
GitHub 是一个面向开源及私有软件项目的托管平台
因为它只支持 Git 作为唯一版本库格式进行托管,所以命名GitHub

技术分享
Git是一个开源的分布式版本控制系统
可以有效、高速的处理从很小到非常大的项目版本管理
它也是目前世界上最先进的分布式版本控制系统

什么是版本控制系统呢?
简单地说,它有以下功能

  • 备份(记录多个版本文件的功能)
  • 记录操作时间线(查看历史操作,进行版本回滚、前进的功能)
  • 多端共享代码(代替各种云盘的功能)
  • ‘自动’合并(解决多人开发冲突问题)

这样的一个系统的优点是不言而喻的
如果没有版本控制系统,我们的工作一定会变得非常困难


介绍一下Git和SVN的区别

集中式版本控制系统SVN
版本库集中放在中央服务器,工作时首先要从中央服务器得到最新版本,工作完成后,再推送到中央服务器。集中式版本控制系统必须联网才能工作,如果没网就GG了

分布式版本控制系统Git
Git是没有中心服务器的,每个人机器上都是一个完整的库,平时开发代码时的中央服务器其实和我们自己机器上的库内容基本是完全一样的,工作时完全不需要互联网


Git的去中心化意味着没有权威、没有主力,人人平等
这对社区影响是巨大的,Github上的fork功能,允许你fork任何一个你喜欢的项目,然后按自己的喜好修改成自己的项目,或是发起pull request请原作者merge你的功能到他们项目里去(这同样也得益于Git另一项与SVN很大不同的功能——分支策略),而且大多数开源项目都会鼓励你去fork它们。这里面没有权威,没有主从,所有人只要有兴趣都可以在其他人的基础上去构建更强大或是更有领域针对性的项目

安装

安装包去Git官网下载就好了
安装完毕后,在桌面或任意文件夹右键就会发现多了两个选项

技术分享

证明我们安装成功了
在开始菜单中找到Git Bash点开

我们还需要配置用户名和邮箱作为标识
输入命令:
git config --global user.name <username>
git config --global user.email <useremail>
技术分享

什么信息也没反馈给我们就代表成功了(下面介绍的命令也是一样)
git config --global 是全局配置
当然我们可以针对某个库设置特定用户名和邮箱

管理

首先我在桌面创建了一个文件夹demo作为我们的项目文件夹
内部创建了一个foo.txt的文件
在文件夹内部Git Bash(这样比较方便,cd定位盘符太麻烦,pwd命令查看当前目录)

技术分享

输入命令 git init(创建本地仓库)

技术分享

现在我们的目录就变成了Git可以管理的仓库
我们把文件夹选项改成显示隐藏文件就会发现

技术分享

git为我们在目录中创建了一个.git的文件

技术分享

它就是跟踪管理版本的奥秘所在
不要胡乱删改它里面的文件就可以了

基本概念

为了更好的理解我们接下来匪夷所思的操作
我们有必要了解一下Git基本概念

工作区Working Directory
我们电脑上可以显示的目录就是工作目录
比如说我们的例子中,工作区只有一个foo.txt文件

版本库Repository
隐藏文件.git就是版本库,它也叫做仓库
仓库里所有文件都通过Git来实现版本管理,Git都能跟踪并记录在该目录中发生的所有更新
版本库中最重要的就是stage/index缓存区和Git为我们创建的主分支master
还有一个指向master的指针head

缓存区Stage
缓存区就是版本库内的一个区域,用来缓存我们的修改

此外还要注意,所有版本控制系统,只能够跟踪文本的改动,例如txt、html、css、js等等
但是图片、音频等二进制文件,它只能够知道文件大小变动了多少
至于变动了什么,它们无法知道

工作流程

我们Git大体的工作流程就是这样地

  1. git add 把文件从工作区添加到版本库中的缓存区
  2. git commit 提交代码,把缓存区所有内容提交到当前分支

技术分享

每次提交后系统都会记录一下这次操作的相关信息
形成一张张“快照”
通过它们我们就可以实现“回溯”
内部其实就是指针与链表

技术分享

基本操作

了解了相关概念以及流程之后
我们来看看具体的操作
首先我在我们工作区的foo.txt文件内输入一行文字:aaa

文件提交

1.工作区→缓存区
输入命令:git add <filename>
将foo.txt文件添加到仓库的缓存区

技术分享

如果想要将工作区全部文件添加到缓存区就使用git add .

2.缓存区→主分支
输入命令:git commit -m ‘xxx‘
-m是message的意思,后面的字符串就代表本次提交的注释

技术分享

查看状态

完成这两步后,我们就算是已经提交foo.txt了
使用git status命令可以查看仓库状态
(commit提交前后,最好使用一下这个命令)

技术分享

由于我对foo.txt文件的修改,文件夹中产生了备份文件foo.txt.bak
所以git提示我们它还没有上传它
没关系,我们不需要这个文件删掉就好了

技术分享

这回Git提示我们工作区干净了,没什么要提交的了

增删信息

现在我在foo.txt中再添加一行bbb
技术分享

恩关了文件夹后我忘了改什么了,怎么办?
使用命令:git diff <filename>

技术分享

可以清晰的看出我们所作出的修改
这回可以安心提交了,同样git addgit commit

技术分享

版本查看

继续向foo.txt文件中添加一行ccc,然后提交到本地仓库
到目前为止,我们的仓库中已经有了三个版本的foo.txt了
使用命令git log查看我们的版本信息

技术分享

黄色的那几行就代表版本号
(GG我第一次提交注释first submit中间居然没加-,强迫症)
如果大家觉得乱七八糟的东西太多
可以输入:git log --pretty=oneline
只显示版本号和版本注释

技术分享

版本回溯

终于到了这一步
如果我们想要回到上个版本
请输入:git reset --hard HEAD^
如果我们想要回到上上个版本
请输入:git reset --hard HEAD^^
如果我们想要回到10000个版本之前
可以敲一天“^”
不过更简便的操作是git reset --hard HEAD~10000

当然我们很少这么丧心病狂的回溯
现在我们来试着回溯一步

技术分享

好了Git提示我当前穿越成功了
使用cat <filename>查看文件验证一下

技术分享

果然这就是我们foo.txt的第二个版本

历史记录

再次查看版本信息
我们发现第三次版本的信息没有了

技术分享

不用担心,既然我们能穿越回来也能穿越回去
不过稍微麻烦一点点
要想回到最新版本foo-3.0,我们需要知道它的版本号
但问题是版本信息查不到了
这时需要我们查看历史记录
命令:git reflog

技术分享

看到黄字没,猜猜那是神马
没错就是版本号的前7位
有了它我们就可以穿越回去了

版本前进

前进版本命令:git reset --hard <version>

技术分享

如此一来我们便可以回到最新版本

技术分享

撤销修改

现在我们当前的最新版本foo-3.0又添加了一行ddd
可是我又后悔了,我想要撤销
目前我们有两种办法

  1. 直接手动修改,或者Ctrl+Z
  2. 版本回溯

第一种简单粗暴,我们的例子实在太简单了,所以一个Ctrl+X就解决了
但实际开发中可没这么轻松
第二种又比较麻烦,我不想这么做

那怎么办?
我们可以使用git checkout -- <filename>

技术分享

技术分享

这个命令的作用就是讲我们在工作区所作出的改变全部撤销(恢复到上一次commit)
不过如果在此之前我们已经将工作区保存到缓存区了,那么只能恢复到缓存的状态(恢复到上一次add)

怕大家不理解,我再演示一下第二种情况
在foo.txt中再次输入ddd
但是这次我先把它保存到缓存区

技术分享

然后输入撤销指令

技术分享

我们发现撤销失败了,因为它恢复到我们缓存区的状态,依然没有任何变化

技术分享

文件删除

在这个控制台中
我们还可以删除文件
命令:rm <filename>

技术分享

再次查看文件发现确实不在了

技术分享

如果我们没有提交到缓存区同样使用撤销命令恢复文件

技术分享

分支机制

如果我们在开发过程中遇到了非常复杂的任务
写了一半后到深夜了,提交吧,代码不完整其他人没法开发;不提交,还可能丢失代码
所以我们需要利用Git中一个非常重要的机制——分支branch
在自己的分支上工作,什么时候完成,什么时候合并分支
既不影响别人,同时也更加安全 ( ̄_, ̄ )

分支原理

  1. 我们每经过一次commit提交就是一个时间点,Git将这些时间点串联成一条时间线
    最开始只有默认的master主分支,HEAD指针指向当前分支的当前版本
    技术分享

  2. 现在我们创建自己的分支dev(命令:git branch dev),Git会开辟一个指针,它会指向master指向的版本
    技术分享

  3. 有了dev分支我们还需要切换到dev分支(命令:git checkout dev),此时HEAD指针指向dev
    技术分享

  4. 这样我们在dev分支上开发,只有dev指针在动,master指针没有动
    技术分享

  5. 当我们在dev分支上完成任务后,就需要将它合并到主分支master
    合并前需要将分支切换回master(命令:git branch master)
    技术分享

  6. HEAD指针重新指向了master主分支,然后我们就可以合并了(命令:git merge dev)
    技术分享

  7. 这是正常的情况,如果在合并的时候发生了冲突,你修改了文件file,但是你的另一个朋友也修改了file中的相同语句,并且上传到了master主分支,这时就需要手动解决冲突调整代码后,再合并
    技术分享

  8. 合并完成dev分支就没有用了,删除即可(命令:git branch -d dev)
    技术分享

分支策略

在开发中,我们使用分支管理应该遵循以下原则

  1. master主分支仅用来发布新版本,平时不要在master分支上开发,master分支应与远程仓库保持同步
  2. 平常开发都在dev分支上,正式版本发布前,把dev分支合并到master上,dev分支也应与远程保持同步(git push/git pull解决冲突)
  3. 团队每位成员都在本地的各自dev分支上干活,不时地往远程dev分支上push/pull(git push/pull解决冲突)

分支使用

上面的分支原理已经把分支命令都介绍的差不多了
我再通过例子把流程扫一遍
现在我重新创建一个demo文件夹
内部有一个文档foo.txt,内容aaa
add、commit提交到本地仓库
现在主分支上就有我们的foo-1.0了

创建与切换分支

其实分支的创建和切换是可以通过一个命令同时完成的
现在我们创建一个叫做dev的分支并切换到它上面
输入命令:git checkout -b dev

技术分享

它相当于下面俩个命令的并集
创建分支dev git branch dev
切换分支dev git checkout dev

查看分支

创建并切换完毕后,我们可以来查看全部分支
输入命令:git branch

技术分享

可以看到蓝字dev就表示我们当前在dev分支
我们输入的命令显示了全部分支,并且当前分支dev用绿字高亮了

合并分支

现在我们在foo.txt添加一行bbb
然后add、commit提交到本地仓库
dev分支的任务就算完成了
合并前需要切换回主分支
输入命令:git checkout master

技术分享

此时的foo.txt仍然是我们的foo-1.0版本
也就是说肯定没有我们添加的bbb

技术分享


现在可以合并了
输入命令:git merge dev

技术分享

现在主分支就是我们的foo-2.0版本了

技术分享

删除分支

查看一下分支,此时dev还是存在的

技术分享

我们不需要它删掉就好了
输入命令:git branch -d dev

技术分享

合并分支Git默认使用Fast forward模式,删除分支后,分支信息消失
合并时如果使用命令git merge --no-ff -m <comment> <branch>可以禁用Fast forward模式
这样删除分支,信息也不会丢失

解决冲突

我们当前的foo-2.0内容是aaabbb
现在我重新创建一个dev分支,添加ccc,提交add、commit
技术分享

再回到master主分支,添加ddd,提交add、commit
技术分享

现在我再合并分支
技术分享

Git提示我们产生了冲突
查看仓库状态
技术分享
Git提供给了我们冲突的详细信息

此时我们再查看文件
技术分享
它向我们标记了不同分支的内容
这样我们就可以手动修改代码解决冲突了
(统一master分支和dev分支的代码)

隐藏现场

当我们在dev分支上开发的时候,突然发现主分支master上有bug
此时就遇到了问题,修复这个bug需要一定时间但是我们dev上的工作还没有完成
没有关系,我们可以隐藏当前工作现场
在此之前我们先查看一下仓库状态
技术分享
Git提示我们还没有提交foo.txt

隐藏工作现场使用命令:git stash
技术分享

这次再查看一下仓库状态
技术分享
可以看到我们的工作现场确实被Git隐藏了

工作现场

被我们隐藏的现场我们时可以查看的
使用命令:git stash list
技术分享

恢复现场

然后我们就可以安心的切换到master主分支修改bug
(比如新建临时issue分支,修改bug后回到master主分支,再删除issue分支)
bug修复后,回到我们的dev分支
恢复现场,我们又两个选择

  1. git stash pop 恢复现场并且销毁stash list中的记录
  2. git stash apply 恢复现场但不销毁记录,使用git stash drop删除栈顶记录

直接删除stash中的内容
技术分享

手动删除stash中的内容
技术分享

Github远程仓库

Git的远程仓库也就是Github
首先我们需要注册Github账号
不过注册后还没完,要想让本地仓库和远程仓库建立连接
我们需要设置SSH加密,SSH 是建立在应用层基础上的安全协议
在本地Git和远程Github之间建立信任关系

创建SSH Key

打开你的用户主目录
技术分享
看看有没有这两个文件

技术分享

如果没有的话,打开命令行
输入命令:ssh-keygen -t rsa –C “email@xx.com”
后面输入你自己的邮箱
如果对网络有一些了解,id_rsa是私钥不能泄露给别人,id_rsa.pub公钥无所谓

有了这两个文件后
登录Github账号,进入右上的设置选项

技术分享

在左侧的Personal settings
点击SSH and GPG keys
技术分享

然后点击右侧的New SSH Key
技术分享

输入标题后,将id_rsa.pub公钥内容原封不动的拷贝到Key栏里,最后Add SSH Key即可
技术分享

如果看到了这个恭喜你成功了
技术分享

添加远程库

上面我们也说到了,开发项目我们的本地Git仓库最好和远程Github仓库保持同步
同样在Github中,在右上找新建仓库
技术分享

输入仓库名、可选的描述等等就可以创建了
技术分享

然后我们就可以将这个空仓库克隆到本地
本地开发完,又可以同步到Github
技术分享

本地库→远程库

首先,我们按照Github的提示
在本地的demo仓库中运行命令
git remote add origin <url>
技术分享
(在控制台中Shift + Ins粘贴)
(输入命令时必须是 git init 由Git管理的仓库)

将本地库的master分支同步到远程库的主分支
输入命令:git push -u origin master

技术分享

命令中的-u其实是吧本地库和远程库关联起来了
所以我们以后再同步的时候
只需输入命令:git push origin master 就可以了

现在我们再登录Github就可以发现远程库已经更新了

技术分享

开发时,master主分支要经常与远程库同步,修复bug的临时分支不需要同步

远程库→本地库

刚才我们从本地库同步到远程库
现在我们从远程库克隆到本地库

我把本地的demo仓库删掉
技术分享
在Github中我们还可以找到这个地址

输入命令git clone <url>克隆远程库的代码到本地
技术分享

当我们从远程库克隆代码到本地,Git就会自动将本地master和远程建立联系了
不过我们的克隆只能把远程的master分支拷贝到本地
如果想要将远程dev分支拷贝过来的话
使用命令:git fetch origin dev

查看远程库信息

想要查看远程库的信息
输入命令:git remote
查看远程库详细信息
输入命令:git remote -v

技术分享

远程库的默认名称就是origin

访问网页

如果我们想要访问自己远程库的网页怎么做呢?
很简单,在Github中创建新分支“gh-pages”
技术分享

这样我们就可以访问自己的页面了
技术分享

Git常用命令

最后最后时间不早了
感觉还是有好多东西没总结
日后再说吧
总结一下Git的常用命令
命令中我使用了一些特殊含义词汇如下

描述 含义
<num> 数字
<url> 地址
<filename> 文件名称
<branchname> 分支名称
<version-id> 版本号
<comment> 注释字符串
<local-branchname> 本地分支名称
<remote-branchname> 远程分支名称


命令 含义
mkdir <filename> 创建空目录
cat <filename> 查看文件内容
rm <filename> 删除文件
pwd 显示当前目录的路径
git init 把当前的目录变成git管理仓库,生成隐藏文件.git
git add <filename> 工作区某文件添加到缓存区
git add . 工作区文件全部添加到缓存区
git commit –m <comment> 提交文件
git status 查看仓库状态
git diff <filename> 查看文件修改内容
git log 查看历史记录
git reset --hard HEAD^ 版本回溯(回退次数为^个数)
git reset --hard HEAD~<num> 版本回溯n次
git reset --hard <version-id> 版本前进
git reflog 查看历史记录的版本号
git checkout -- <filename> 撤销文件在工作区的修改
git remote add origin <url> 关联远程库
git push –u origin <branchname> 将某分支关联并推送到远程库(master)
git push origin <branchname> 将某分支推送到远程库对应的分支上
git push origin <local-branchname>:<remote-branchname> 将某分支推送到远程库的某分支上
git clone <url> 从远程库克隆文件到本地(master分支)
git fetch origin <branchname> 从远程库分支拷贝到本地相应分支(非master分支)
git fetch origin <remote-branchname>:<local-branchname> 从远程库某分支拷贝到本地某分支(非master分支)
git checkout <branchname> 切换到某分支
git checkout –b <branchname> 创建并切换到某分支上
git branch 查看当前所有的分支
git branch <branchname> 创建某分支
git branch –d <branchname> 删除某分支
git merge <branchname> 在当前的分支上合并某分支
git stash 隐藏当前工作待恢复现场后继续工作
git stash list 查看所有被隐藏的文件列表
git stash pop 恢复隐藏文件并删除记录
git stash apply 恢复隐藏的文件但不删除记录
git stash drop 删除隐藏文件记录
git remote 查看远程库信息
git remote –v 查看远程库详细信息


==主页传送门==

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    分布式管理控制系统Git与项目托管平台Github相关概念、操作方法与常用命令