版本控制产品非常的多,现在影响力最大且使用最广泛的是Git与SVN,其中Git属于分布式版本控制器而SVN属于集中式版本控制器。对于分布式版本控制器,每台工作的电脑都有版本库,而集中式版本控制器的版本库放在一个中央服务器上。分布式版本控制器很安全,不用担心中央服务器崩掉后版本库就没了。

Git环境配置

windows直接去官网下载就行了,装完之后唯一需要配置的就是用户名和邮箱,因为git是分布式版本控制,每台电脑都得有相应的标识。使用下面的git命令完成配置。

git config --global user.name xxx
git config --global user.email xxx

git仓库包括四个工作区域——working directory(工作目录)、stage(暂存区)、local repository(本地仓库)、remote repository(远程仓库)。使用如下的命令可以将当前所处文件夹转换成git仓库(不包含remote repository)。

git init

这个文件夹的结构如下图所示,其中stage(暂存区)、local repository(本地仓库)位于隐藏子文件夹.git内。

Fig1. Git仓库的结构

使用如下命令将git仓库和一个远程仓库关联起来,这里以gitee为例。要使用gitee提供的远程仓库,首先要配置ssh,使用如下命令获得ssh公钥。

在gitee配置ssh公钥
ssh-keygen -t rsa # 获取 ssh -T git@gitee.com # 检查是否配置成功

把公钥告诉gitee,之后gitee就允许你用git命令进行操作了。注意,这个操作只需要做一次!!!不是每次都要配置一遍公钥!!!

然后再gitee上面新建一个远程仓库,就可以使用下面的命令将git仓库和这个远程仓库关联起来了。

git remote add origin 要链接的那个远程仓库的ssh 
git pull origin master --allow-unrelated-histories
git push -u origin master

需要注意的点

  • 命令中的origin是这个远程仓库的别名,命名为origin是一种习惯,不是强制要求。
  • 不加-u参数只是将local repository中的内容推送到远程,加上-u则会额外进行关联操作,关联之后再推送就可以不加-u参数了,直接写成git push origin master
  • 如果连接错了仓库了,使用git remote rm <仓库别名>删除该连接
  • master是git默认的主分支。当前push的分支必须和远程分支相对应,不然会报错,push不上去

上面说的是先初始化一个git仓库再和远程仓库进行关联,还有一种方法可以直接得到和远程仓库关联的git仓库,这种方法就是先创建远程仓库,再克隆到本地,使用如下命令。

git clone 仓库的ssh

到此为止,我们已经顺利得到一个包含四个工作区域的git仓库了!下面讲一下如何在四个工作区域之间传递(如下图)以及git中文件的4中状态。

  • untracked:一个新创建的文件,没有被add。
  • unmodified:文件已经在(local)repository了且对应work directory中的文件没有发生修改。
  • modified:文件已经在(local)repository了且对应work directory中的文件发生了修改。
  • staged:暂存状态,放在stage(index)区的文件,等待被一次性commit到(local)repository。
Fig2. 文件各种状态的转换

Git分支管理工作流

git对分支进行管理速度非常快,因为它实际上管理的是指针。其中Head指针用于确定当前所处分支,“分支名”指针用于确定当前所处分支的最新提交。各个分支之间可以认为是平行宇宙,互不影响(在A分支下创建新分支B之初,A和B的working directory是完全相同的,不需要再粘贴复制一遍文件,完全通过指针实现,但是新建文件并commit到B分支后,A的working directory就是没有这个文件的,就此分叉了)。

Fig3. 文件各种状态的转换

既然是平行宇宙,下面考虑这样一种情况——如果A和B分支commit了一个叫test.txt的文本文件,但是二者内容并不相同,此时想将B合并到A分支,会发生什么呢?会报错!发生冲突。虽然报错了,但是我们还是会得到一个“合并的”test.txt文件,只不过这个文件内被git使用特定符号进行标注了,告知我们哪里发生了冲突。要想解决冲突,就得手动修改“合并的”这个test文件。然后再提交。

最后是多人协作的一般流程

  1. 首先,可以尝试用git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并,如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

常用bash命令和git命令

  • D::切换到D磁盘。
  • cd:打印当前所在目录。
  • cd d1\e1:切换到当前磁盘下的d11目录。
  • cd ..:回退到当前磁盘下的上一级目录。
  • dir:列出当前目录下的所有文件。
  • mkdir dd:当前所在目录下创建名为dd的目录。
  • rmdir dd:当前所在目录下删除名为dd的目录。
  • type nul>123.txt:当前所在目录下创建名为123的txt文件。
  • del 123.txt:删除当前所在目录下名为123的txt文件。
  • move 源文件路径 新目录路径:移动文件。
  • cls: clear screen。
  • git init:将一个文件夹初始化为git仓库(不含remote repository)。
  • git status:查询git仓库当前状态。
  • git add .:将所有文件的修改放到stage区等待commit。
  • git add filename:将filename指定的文件修改放到stage区等待commit后进入local repository。
  • git rm filename:将filename指定的文件修改放到stage区等待commit后彻底移除。
  • git commit -m “里面写此次修改的提示信息”:将stage区的修改提交到(local)repository。
  • git checkout -- filename:使用(local)repository中对应filename的文件覆盖带掉work directory中的,用于撤销修改。
  • git diff filename:查看还没有add到stage区的名为filename的文件和(local)repository中对应文件的区别。
  • git log --pretty=oneline:查看历次版本信息和版本号。
  • git reset --hard 版本号:将(local)repository回退到指定版本号。
  • git reflog:查看历史信息,用于当从版本3跳到版本1,又想在找到版本3的版本号从而回跳到版本3。
  • git remote add 远程库别名 要链接的那个远程仓库的ssh :添加一个远程链接。
  • git pull 远程库别名 分支名:将指定远程库的指定分支抓取下来和local repository中的内容合并。
  • git push 远程库别名 分支名:将本地分支(注意和远程仓库分支的对应)推送到远程库,如果远程库没有该分支则进行创建。
  • git clone 要链接的那个远程仓库的ssh:将一个远程仓库克隆到本地并建立链接。
  • git branch:列举处所有分支。
  • git branch -m 新分支名:重新命名当前分支。
  • git branch 分支名:创建分支。
  • git branch -d 分支名:删除分支。
  • git switch 分支名:切换到指定分支。
  • git switch -c 分支名:创建再切换分支。
  • git merge 分支名:将指定分支合并到当前分支。
  • git log --graph:git 仓库历史变化图。