看啥推荐读物
专栏名称: 许啊切
前端
目录
相关文章推荐
今天看啥  ›  专栏  ›  许啊切

【开发工具】Git使用原理与常用命令

许啊切  · 掘金  ·  · 2021-05-22 18:39
阅读 110

【开发工具】Git使用原理与常用命令

前言

  在工作中,基本上都是使用Git进行程序版本管理,并且进行多人协同合作开发。但是往往我们并不知道为什么要使用Git,对于那些繁多的git命令也不求甚解,经常一段时间不使用就忘记了,即使记得心里还是虚虚的,担心出错造成代码库崩盘。这一切的根本原因还是在于我们对于git的理解不清晰,虽然可以使用Git版本管理工具,但是在掌握命令行的前提下使用,会更加的得心应手。   相较于先前的集中式存储SVN,Git采用的是分布式存储,带来的好处就是程序的所有版本都存储在每一台分布式的机器上,并且可以在断网情况下继续编写程序。

Git时间线与多人协作

  Git将每次提交都串成一条时间线,这条时间线就是一个分支。   Git 作为一个源码管理系统,不可避免涉及到多人协作。协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去。"工作流程"在英语里,叫做"workflow"或者"flow",原意是水流,比喻项目像水流那样,顺畅、自然地向前流动,不会发生冲击、对撞、甚至漩涡。 Git时间线图解

Git项目库的理解与初始化

  Git项目库怎么理解?其实就是被Git进行管理的文件夹。首先我们要明确的是Git是一个程序版本管理工具,程序的具体实例就是一个文件夹,所以说Git可以进行文件夹内容改动的管理。那么问题就来了,不是什么文件夹都可以被Git管理,我们需要先告诉Git管理哪些文件夹,这个「告诉」的操作就叫做Git项目库初始化,具体操作就是git init

  • git init

  当你在本地新建一个git项目,或者你想把某个文件夹进行Git管理,首先你需要初始化该项目,初始化命令就是git init。完成git项目初始化之后,文件夹内部会多出一个隐藏文件.git(直接打开看不见)。这就是项目的版本库,记载着项目每次提交等信息。

Git项目库的组成

  Git项目库是由两部分组成的:工作区版本库Git项目库组成   如上图所示,git项目库主要分为工作区版本库两个部分,工作区指的就是我们原始的文件夹,而版本库是指git init初始化文件夹后新增的.git文件。注意,.git文件对于我们是隐藏的。   Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,和本地分支(其中Git为我们自动创建第一个分支master),以及指向本地当前分支的一个指针叫HEAD。   这里我们要有一个概念,那就是git在本地项目库中维护了和远程库一样的代码分支,git commit命令事实上是将代码提交到本地维护的代码分支上面,然后接下来在将本地分支同步到远程库的分支上面。 git提交代码图示

版本库.git文件夹内容快照

image.png

工作区与暂存区

git提交代码图示

  我们在提交代码时候,经常先使用git add <filename>将工作区改动的文件添加到暂存区(stage/index),然后使用git commit -m <message>将暂存区的所有改动提交到本地分支,最后再git push origin -u <远程库分支名>将本地分支推送到远程库。   从上面的三个步骤中,可以看到出现了一些新的概念:暂存区(stage/index)工作区本地分支,下面就来梳理一下这三个概念。

  • 工作区(Working Directory)

就是你在电脑里能看到的目录,也是你通过IDE直接进行编程的目录,比如我的test文件夹就是一个工作区: 工作区目录 注意上图中,存在一个隐藏文件夹.git,这个不算工作区,而是Git的版本库。

  • 版本库(Repository)

Git项目库组成 如上面所说,工作区的隐藏文件夹.git不算是工作区,而是Git的版本库。 Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,和本地分支(其中Git为我们自动创建第一个分支master),以及指向本地当前分支的一个指针叫HEAD

git常用命令汇总

添加远程库

git remote add origin <远程库地址> 当你创建好了一个本地项目之后,你希望将其与远程建立的库连接,从而在每次代码写完后,能够提交到代码托管网站,保证了安全性与结构清晰。其中的origin指的是远程库的名字,一般都默认为origin,也可以修改。但不建议,因为写代码是与人交流合作的工作,不要为了张扬个性让别人很难阅读与理解。

提交代码
  • 提交到暂存区 git add . 或者 git add <文件名>
  • 提交到本地分支 git commit -m '<提交说明>'
  • 推送到远程库 git push -u origin <分支名>

以上就是提交代码的三板斧,再具体说明之前,首先我们要建立一个git的形象化模型。 git add   如上图所示,git项目库主要分为工作区版本库两个部分,工作区指的就是我们原始的文件夹,而版本库是指git init初始化文件夹后新增的.git文件。注意,.git文件对于我们是隐藏的。在版本库中,同样主要分为两个部分:暂存区(stage)本地分支。   这里我们要有一个概念,那就是git在本地项目库中维护了和远程库一样的代码分支,git commit命令事实上是将代码提交到本地维护的代码分支上面,然后接下来在将本地分支同步到远程库的分支上面。 git提交代码图示

  暂存区的概念,我理解为充当了一个缓冲的作用,创造一个后悔与再三考虑的机会。推荐廖雪峰的git教程,讲的简单清晰明了。

查看当前项目状态

git status 当我们git add . 之后,忘记了git commit,第二天不知道代码提交到了哪一步,这个时候git status就可以告诉我们暂存区是否干净,本地代码是否需要git push到远程库中。

克隆远程仓库项目到本地

git clone <远程库地址> 当我们想要下载远程库中的项目代码的时候,并没有一键下载的按钮,反而很容易得到项目远程库的地址。这个地址就是为了git clone这条命令而存在的。新手需要注意的一点是,克隆项目之前,先使用命令行进入你希望下载项目的地址,在使用git clone,不然就不知道克隆的项目在哪,增加了挫败感。 git clone -b [分支名] [远程库地址] 另外还需要注意,使用git clone命令克隆下来的代码默认的是主分支代码(取决于设置的默认分支),需要在本地,使用终端,切换分支命令(git checkout 分支名),才能将代码切换。但人都是懒的,有没有指定克隆的代码分支的命令呢?答案是有的。那就是在git clone -b 后面指定分支名。

拉取远程仓库更新

git pull 当别人提交了代码到主分支的时候,而你的代码还是旧的,这个时候远程库主分支上的代码就比你本地领先了一个版本。前面说的编程是与人合作的工作,你需要在新的项目代码上编写自己的模块。这个时候你就需要git pull拉取远程库最新代码。假设你没有这样做,那么当你git commit代码时,就会报错,说你的代码与远程库发生冲突。所以,提交代码前,git pull一下是很好的习惯。

查看分支

上面说了本地具有代码的所有分支,那么有时候我们需要知道目前所在分支,免得写错了分支,更是麻烦。

  • 查看本地分支 git branch
  • 查看远程分支 git branch -r
  • 查看所有分支 git branch -a

创建新分支并切换

git checkout -b <新建分支名> <基于分支名>

切换分支

git checkout <分支名>

合并分支

git checkout <需要合并分支> 先切换到需要合并其他分支的主要分支上 git merge --no-ff <被合并分支名> 基于当前主要分支,创建新结点,合并其他分支 当我们在自己的开发分支开发结束后,管理员需要将开发者的代码合并到主分支上面。这个过程就叫做合并分支,主要过程分为两步,第一步就是切换到你的主分支(例如master)上,然后git merge你想要合并的分支就可以了。 但是不要放松,这里经常会出错,合并失败,代码冲突。这说明两个分支,在同一处代码做了不同的修改。很想,在某个点,你不同的选择产生了两个截然不同的平行宇宙。这个时候,解决的办法只有一个,查找到冲突的地方,手动修改。 非快进式合并

代码回滚

  这个是另一个很重要的技能,防止你该版本出了重大的错误,或者找不到错误的来源。需要进行时光旅行,将代码重置到上一个版本。   在此之前,我们需要明确一个概念,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。在版本库中,存在一个HEAD指针,HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点。 HEAD指针   当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上: 创建dev分支 清楚了这些,那么接下来就是代码回滚了。 git log -[数字] 每一次提交都有一个自动生成的 commit 标识符,这串标识符就是回滚到具体版本所需要的。上面命令中的数字代表了最近几次的提交日志。 git log -3 git reset --hard [commit序号] 该条命令即可回滚到指定的版本。 git reset --hard HEAD^ 该条命令回滚到上一个版本。

提交抵消

最近工作中遇到一种情况,在commit一次代码后,发现这次提交的代码有问题,必须撤销这次commit。如果再手动改回来,首先有点笨,其次难免会有遗漏的地方。 这个时候可以使用git revert,撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销作为一次最新的提交。

 git revert HEAD                  撤销前一次 commit
 git revert HEAD^               撤销前前一次 commit
 git revert <commit> (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)
  撤销指定的版本,撤销也会作为一次提交进行保存。
 // 然后推送到origin
 git push origin <分支名>
复制代码

**git revert 和 git reset的区别 **

  1. git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
  2. 在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
  3. git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。

参考文章

  1. Git教程-廖雪峰
  2. 常用Git命令清单-阮一峰
  3. git revert 用法



原文地址:访问原文地址
快照地址: 访问文章快照