作为git新手,常见的git clone,push,commit命令已经足够完成一次代码的发布,但是如果不幸碰到问题往往会束手无策,利用网络问答解决了之后也不知其所以然。所以,做一次好奇宝宝吧!

git的安装

  1. 下载安装包,下载完成后,打开你的终端。
    http://git-scm.com/download/
  2. 配置用户名,邮箱 。
    git config --global user.name "你的注册用户名"
    git config --global user.emall "你的注册邮箱"
  3. 终端配置密钥 。
    `ssh-keygen -t rsa
  4. 复制公钥,粘贴到gitlab->my ssh keys。
    cd ~/.ssh
    cat id_rsa.pub
  5. git服务端和本机便打通了,可以通过git clone ssh地址下载代码了 。

安装流程如上所述,可是为什么这么做呢?

Q1:什么是ssh?gitlab上得地址为什么分为ssh和http?

  SSH 为 Secure Shell 的缩写。通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了。

  可以看到,仓库的地址分为ssh和http两种路径,客户端也可以选择通过http或者ssh两种方式来从服务器上获取数据,公司都是用的ssh方式,因为更安全。

Q2:密钥是做什么的,为什么要粘贴公钥到gitlab?

  这要从SSH安全验证的原理说起:
  SSH分为两种级别的安全验证,一种是用户名密码方式,一种是公钥私钥方式。这里用到得是公钥私钥方式。
  密钥方式的验证流程是这样的:
  1. 客户端生成一对密钥:公钥+私钥。(对应git的安装步骤三)
  2. 将客户端生成的公钥复制到服务器上。(对应git的安装步骤四)
  3. 客户端发起连接请求,并发送公钥给服务器。(可以看做在本机执行git命令请求服务器响应)
  4. 服务器寻找这个公钥,找到后验证若合法,就生成一个随机数,用公钥加密。
  5. 服务器把加密后的随机数发送给客户端。
  6. 客户端收到后用私钥解密,将解密的结果发送给服务器。
  7. 服务器将客户端发送的解密结果和加密前数据对比,若能匹配上,则安全验证成功。
  由此可知,有了公钥和私钥才能和远程的gitlab服务器进行连接和交互。每换一台电脑(若电脑上没有私钥)都需要重新生成一次密钥。

git 的文件操作

  如果使用git做版本控制,我们最常用到得命令就是git clone,git add, git commit,git push。正常情况下,有这些命令也够我们完成一次代码的发布了。但是SVN只需要小乌龟一次提交,为什么到git就要两次提交呢?

Q3: git为什么下载比其他版本控制器(如SVN)更快?

  其他版本控制器如SVN,每次更新存储的是文件具体差异。git不保存具体差异,而是把有变化的文件作一个快照存储下来。每次提交更新,都会保存一个指向新快照的索引;若文件没有改动,则索引指向上一个快照。
  所以如果要查看或者使用历史版本,git只需要直接load出来,而svn还需要merge,所以很快。当然git需要的存储空间也更大了,不过git也有自己的优化机制使得空间和时间有个平衡。

  1. 创建一个新分支
  2. 在新分支上有新的修改
  3. 新分支和master分支合并

      如图所示,可以清楚的看到从创建分支到和master合并的整个过程。

Q4: git为什么要分多次提交?

需要从git的工作区域说起。git的工作区域有三个:

  • 工作目录(Working Directory)
    平常我们用IDE开发的那个工程目录,工程根目录下有隐藏的.git文件标识是git目录。
  • 暂存目录(Stage or Index)
    存储文件的快照(快照的解释见上一个问题)
  • 仓库(Git directory)
    有本地仓库和远程仓库。

git基本的工作流程:
  1. 在工作目录中修改文件。
  2. 第一次提交,git add ..。暂存文件,将文件的快照放入暂存区域。
  3. 第二次提交,git commit..。提交更新,找到暂存区域的文件,将快照存储到本地 Git 仓库。
  4. 第三次提交,git push..。提交更新到远程git仓库。
  因为git是分布式的管理文件系统,使得无需联网也可以方便的管理文件的版本。就是得益于本地和远程多次提交的流程。

Q5: git的文件状态有哪些?

文件状态在平常代码修改、执行一次代码提交的过程中,其实就可以看到。

以文件index.js为例:

  1. 在IDE中修改代码(index.js文件)后,运行git status检验git状态:

    可以看到提示的文件状态为modified,并且git提示我们changes not staged,用add命令来staged或者用git checkout filename来放弃staged这次修改。
  2. 执行命令 git add build/js/page/banff/index.js,运行git status检验git状态

    文件状态仍然是modified(已修改),但可以看到提示少了 not staged,表明文件已经staged,等待commit了。
    可以使用git reset HEAD filename命令让文件回到unstage状态。
  3. 执行命令git commit build/js/page/banff/index.js -m 'test'
    (-m 提交注释,必填),
    再运行git status检验git状态:

    可以发现,index.js文件已经不是modified状态,git提示“有一次提交,请使用git push命令发布这个本地commits”
  4. 执行命令git push origin daily/0.0.4

    由于没有遇到冲突,分支已经跟新到最新状态(up-to-date)
    从以上实践过程中,可以得到如下图的文件状态变更过程:

Q6: 每次提交时生成的 key是什么?


  在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算。Git 使用 SHA-1 算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个 SHA-1 哈希值,作为指纹字符串。所以git可以快速的算出你的文件是否有变更。git的每一次提交都对应唯一的commit id。在git中也是通过这个KEY来对应到提交内容。

Q7: git,gitlab,github三者是什么关系?

  • git是一个版本控制工具,通过命令行来操作
  • github,gitlab 都是使用git来做版本控制工具,在此基础上搭建起来的WEB服务,提供给用户存储空间来作为git仓储。
  • gitlab可以把代码部署在自己的服务器上,比如公司就用的公司的服务器,适合做私密的项目。
  • github私有repo比较贵,适合做开源项目

常见git命令

  • git status 查看修改了什么文件,以及文件状态
  • git diff filename 查看具体修改了什么内容
  • git branch 查看当前分支名字
  • git log 查看历史记录
  • git reset --hard HEAD^ 或 git reset --hard commitID
      在git中,用HEAD表示最新版本,那么HEAD^表示上一个版本
  • 回滚
    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
    场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
  • git push origin master:分支名 clone的是master的代码,但是将改动提交到另一个分支上
  • git clone -b 分支名 ssh地址 . clone指定分支的代码
  • 删除远端分支
      git branch -a 可以查看远端分支的名称,会打印出remotes/origin/分支名
      git push origin --delete branchname 删除远端分支

带着问题学git的更多相关文章

  1. 看日记学git摘要~灰常用心的教程

    看日记学git linux 命令行 cd ls / ls -a clear mkdir rmdir echo "hi, good day" > hi.txt touch he ...

  2. 沉浸式学 Git

    沉浸式学 Git cover — contents — about 目录 设置 再谈设置 创建项目 检查状态 做更改 暂存更改 暂存与提交 提交更改 更改而非文件 历史 别名 获得旧版本 给版本打标签 ...

  3. 还在用SVN的人,要不要学Git?

    还在用SVN的人,要不要学Git? 提出这个问题,是因为很多小伙伴还不会使用Git. 在Git之前,是SVN的天下. SVN诞生于2001年,由于较为先进的管理方式而迅速取代了CVS. 很多80后小伙 ...

  4. 小姐姐带你一起学:如何用Python实现7种机器学习算法(附代码)

    小姐姐带你一起学:如何用Python实现7种机器学习算法(附代码) Python 被称为是最接近 AI 的语言.最近一位名叫Anna-Lena Popkes的小姐姐在GitHub上分享了自己如何使用P ...

  5. 超哥带你学GIT

    git入门 git安装 git基础 git分支 github与gitlab与git三个基佬的故事 gitlab与pycharm结合 github使用 git超清技能图 学习git站点: git官网 廖 ...

  6. 带GPG签名的Git tag

    原文地址http://airk000.github.io/git/2013/09/30/git-tag-with-gpg-key Git tag ###Tag用来做什么? Tag即标签,用以给项目仓储 ...

  7. 居然可以像玩游戏一样学Git

    工作中经常用到 git,但是用到的指令也都是比较初级的.简单的.当时学习的过程也是有点痛苦.各种概念理解起来要么靠想象,要么自己创建工程提交记录,然后执行指令,看具体效果.这样学下来是事倍功半. 在搜 ...

  8. Linux下基于HTTP协议带用户认证的GIT开发环境设置

    Git 的访问可以采用 HTTP 或 SSH 协议安全的访问,通常我们使用 gitlib 进行 Web 管理,但是在 Linux 命令行开发环境下,基本都是使用 SSH 协议,只需要在 gitlib ...

  9. 小菜鸟带着梦想学chromium

    风雨送春归, 飞雪迎春到. 已是悬崖百丈冰, 犹有花枝俏. 俏也不争春, 只把春来报. 待到山花烂漫时, 她在丛中笑. 这首卜算子·咏梅可是应了我的心情了.最近换工作,受到频频打击,面试过程中发现满世 ...

随机推荐

  1. Jlink 软件断点和硬件断点

    调试2440 RAM拷贝至SDRAM遇到的问题 汇编代码主要是初始化一些寄存器,关狗,初始化时钟,初始化存储管理器以便访问内存,然后将SoC上4k RAM数据拷贝至SDRAM,然后在SRAM里面运行, ...

  2. 【linux】亲测成功_CentOS7.2/rhel7.2 忘记root密码及重置root密码的方法?

    本文转自:https://www.jb51.net/article/146320.htm  CentOS 7 root密码的重置方式和CentOS 6完全不一样,以进入单用户模式修改root密码为例. ...

  3. PHPExcel 导出包含图片excel

    <?php // 这里用的PHPExcel版本号为1.8.0 // 下载地址https://github.com/PHPOffice/PHPExcel 下载ZIP压缩包 // 下载后将Class ...

  4. SSH整合主要XML代码

    web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2 ...

  5. 【bzoj3488】[ONTAK2010]Highways DFS序+树上倍增+树状数组

    题目描述 一棵n个点的树,给定m条路径,q次询问包含一条路径的给定路径的个数+1 输入 The first line of input contains a single integer N(1< ...

  6. Android中常见的坑有哪些?

    对于安卓开发入门级程序猿而言,由于不熟悉代码.工具等等,掉进一些坑中是难免的,今天小编在网上看到一位大神总结的Android开发中比较常见的坑及其原因和解决办法,赶脚还不错,分享出来,给大家提个醒. ...

  7. [NOIP2017]列队 线段树

    ---题面--- 题解: 之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了.于是今天尝试了线段树的解法. 首先因为每次出列之后的变化都是将当 ...

  8. git使用笔记(八)团队协作

    By francis_hao    Nov 24,2016       本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可.欢迎转载,请注明出处 ...

  9. WCF分布式开发步步为赢(15):错误契约(FaultContract)与异常处理(ExceptionHandle)

    今天学习WCF分布式开发步步为赢系列的15节:错误契约(FaultContract)与异常处理(ExceptionHandle).本节内容作为WCF分布式开发的一个重要知识点,无论在学习还是项目中都应 ...

  10. 关于session variables 和 global variables

    背景 有同学问到这样一个问题:原来的binlog格式是statement,为什么执行了 set global binlog_format='row' 和 set binlog_format='row' ...