那些年,咱们玩过的Git

做者:玩世不恭的Coder
公众号:玩世不恭的Coder
时间:2020-06-05
说明:本文为原创文章,未经容许不可转载,转载前请联系做者php

哪些年,咱们玩过的Git

前言1、前期工做经常使用基本概念的理解Git环境的搭建用户名和邮箱的配置2、Git的理论基础工做区域工做流程版本库的初始化文件的四种状态Git的初步操做3、关于文件的各类操做文件修改以后版本的回退撤销修改文件的删除4、本地项目远程提交到Github仓库5、Git的分支管理分支的建立与合并单人分支合并时的冲突解决多人协做下的冲突解决6、标签管理总结参考资料css

前言

关于Git,相信每一位该领域的朋友都了解其的强大。Git是一种广受欢迎的代码管理工具,在实际开发中,咱们能够经过Git和团队更好管理咱们的项目版本,也大大提升了团队的开发效率。在实际使用Git的过程当中,咱们通常只须要掌握其中的十几条命令就够用了,Taoye以前对Git也只是停留在会用的状态,而因为对Git内部的一些细节平时接触比较少,因此仍是会有一点盲区存在。因此,乘着考研结束的这段空闲时间,对以前学习过的Git作一个整理,一方面分享给各位读者,另外一方面也方便本身往后的复习。本文主要介绍了在实际开发过程当中所经常使用的一些Git操做,因为博主技术水平有限,在内容上的表述不免会有疏忽和遗漏,也恳请各位Coder多多指教。html

1、前期工做

经常使用基本概念的理解

  • 版本控制

所谓的版本控制是指对软件开发过程当中各类程序代码、配置文件及说明文档等文件变动的管理,是软件配置管理的核心思想之一。简单的讲,就是方便咱们对项目代码的各类版本进行管理。python

咱们能够举个例子来进行说明一下:相信每一位学生,不管是大学毕业或是研究生毕业,都避免不了完成一篇学术性的论文。咱们都知道,学术性论文的撰写都是一个长期的过程,在这个过程也会经历不断地反复修改,这样就会产生多个论文版本。相信每一位有过此经历的同窗都会感到痛苦,版本多了甚至都不知道每个版本的论文内容都修改了啥。而咱们的Git就可以很好的管理各类版本的论文,在每一次提交的时候,均可以在comment中记录咱们对论文的修改内容,而且每个版本的论文均可以进行回滚等操做,也就是随意的切换各类版本。如此一来,岂不快哉???nginx

此外,咱们还可使用廖大大提到的例子来解释一下:在许多游戏中,都会有一个存档的操做,若是你对接下来的挑战Boss没有足够的信心,就能够进行一次存档,当咱们的角色由于挑战Boss而丧命,咱们就能够读取其中的存档而从当前状态继续游戏,而不须要从头再来,假如游戏有保存多个存档的操做,咱们还能够读取不一样的存档来继续游戏。一样地,在咱们对文件进行修改到必定程度的时候,就能够保存一个“快照”,一旦咱们对本身的操做的不满意,就能够进行恢复或是回滚操做,这样就能够“穿梭”到操做以前状态继续工做,而无需从头再来。git

  • 工做区(Working Directory)

能够理解成就是电脑本地磁盘的目录,好比咱们在本地建立了一个temp目录,那这个目录就叫作工做区。github

  • 暂存区(Staging area)

通常存放在"git目录"下的index文件(.git/index)中,因此咱们把暂存区有时也叫做索引(index)。web

  • 版本库(Repository)

咱们的工做区有个隐藏目录.git,它就是Git的本地版本库。sql

对于以上部分概念,有些读者可能不是很了解,你们能够阅读下面内容以后再回过头来进行推敲,相信你们必定会有更加透彻的理解。shell

Git环境的搭建

对于Git的安装,在前面咱们讲解Hexo搭建博客的时候有介绍过,这里咱们再简单的回顾一下。

你可在git官网中根据本身的须要进行下载:git-scm.com/。打开以后你将看到以下内容,就无脑download for Windows

将其下载到指定的磁盘,而后Windows系统下傻瓜式安装便可。安装好后咱们打开cmd终端(win+r -> 输入cmd -> 回车),执行git --version,若出现git version 2.19.2.windows.1之类的版本输出,那么恭喜你已经成功安装Git。

对于Linux操做系统下,咱们能够直接经过命令的形式来进行安装:

1# Linux下安装Git
2sudo apt-get install git
复制代码

用户名和邮箱的配置

咱们在安装完成Git以后,首先第一步要作的就是配置Git的用户名和邮箱,这个是提交项目的用户的惟一标识。

1# 配置用户名和邮箱,配置好以后会写入C:\Users\M的.gitfig文件中
2git config --global user.name "username"
3git config --global user.email "email@qq.com"
复制代码

global说明:global表明全局的意思,也就是说咱们在以后提交的每个项目采用的都是该用户名和邮箱。假如咱们须要在不一样的项目中使用不一样的用户名和邮箱,咱们则不须要添加--global参数。

咱们将此信息配置好以后,就会写入C:\Users\M中的,gitfig文件中。此外,咱们也能够用过如下命令来查询咱们所配置的用户名和邮箱:

1# 查询配置
2git config -l
复制代码

2、Git的理论基础

该部分的内容来自:www.cnblogs.com/best/p/7474…

工做区域

Git本地有三个工做区域:工做目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)。若是在加上远程的git仓库(Remote Directory)就能够分为四个工做区域。文件在这四个区域之间的转换关系以下:

  • Workspace:工做区,就是你平时存放项目代码的地方
  • Index / Stage:暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
  • Repository:仓库区(或本地仓库),就是安全存放数据的位置,这里面有你提交到全部版本的数据。其中HEAD指向最新放入仓库的版本
  • Remote:远程仓库,托管代码的服务器,能够简单的认为是你项目组中的一台电脑用于远程数据交换

本地的三个区域确切的说应该是git仓库中HEAD指向的版本

  • Directory:使用Git管理的一个目录,也就是一个仓库,包含咱们的工做空间和Git的管理空间。
  • WorkSpace:须要经过Git进行版本控制的目录和文件,这些目录和文件组成了工做空间。
  • .git:存放Git管理信息的目录,初始化仓库的时候自动建立。
  • Index/Stage:暂存区,或者叫待提交更新区,在提交进入repo以前,咱们能够把全部的更新放在暂存区。
  • Local Repo:本地仓库,一个存放在本地的版本库;HEAD会只是当前的开发分支(branch)。
  • Stash:隐藏,是一个工做状态保存栈,用于保存/恢复WorkSpace中的临时状态。

工做流程

git的工做流程通常是这样的:

1. 在工做目录中添加、修改文件;

2. 将须要进行版本管理的文件放入暂存区域;

3. 将暂存区域的文件提交到git仓库。

所以,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)

版本库的初始化

咱们须要建立一个目录来做为咱们的项目根目录,进入到该目录以后,右键git bash来启动git的操做窗口

1# 选择对应的目录,右键点击git bash,而后建立一个目标项目目录,并进入该目录
2mkdir temp_project
3cd temp_project
复制代码

以后,咱们须要将建立的目录初始化为Git所能识别仓库,能够经过git init来实现。初始化完成以后,就会在该目录中自动建立出一个.git的隐藏目录,关于咱们项目的版本信息都会存储在该目录当中。

1# 初始化一个仓库,以后会多出.git隐藏文件
2git init
复制代码

以上就是咱们自定义一个仓库的过程。此外,咱们还能够基于已经存在Git仓库来进行操做,在Github中查找本身想要的Git仓库,复制其连接,而后经过git clone来对该仓库进行克隆,从而将该仓库下载到咱们的本地目录中:

1# 使用clone克隆Github中已经存在的仓库
2git clone XXXXXX.git
复制代码

文件的四种状态

咱们要对文件的版本进行控制,首先须要明白当前文件处于什么样的状态,对于不一样状态下的文件,咱们能够进行不一样的操做。而在Git中,文件主要是有四种状态:

  • Untracked: 未跟踪, 此文件在文件夹中, 但并无加入到git库, 不参与版本控制. 经过git add 状态变为Staged.
  • Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中彻底一致. 这种类型的文件有两种去处, 若是它被修改, 而变为Modified. 若是使用git rm移出版本库, 则成为Untracked文件
  • Modified: 文件已修改, 仅仅是修改, 并无进行其余的操做. 这个文件也有两个去处, 经过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
  • Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified

Git的初步操做

了解了文件的状态以后,咱们不妨模拟一个关于论文的例子来初步了解下版本库以及文件的简单操做:

  • 建立一个工做区,并进行初始化
1# 建立一个工做区
2mkdir my_dir
3# 进入工做区
4cd my_dir
5# 经过init命令将工做区转化成Git能够管理的仓库
6git init
7# 在该仓库中建立一个paper.txt,用于编写咱们的论文
8touch paper.txt
复制代码
  • 咱们在paper.txt之中编辑以下内容:
1# 咱们在`paper.txt`之中编辑以下内容:
2Oh, my god, I will write my graduate paper.
3Come on, Taoye.
复制代码
  • 经过add命令将paper.txt文件添加到暂存区
1# 经过add命令将paper.txt文件添加到暂存区
2$ git add paper.txt
复制代码
  • 经过commit命令将暂存区中的内容提交到仓库
1# 经过commit命令将暂存区中的内容提交到仓库,指定提交paper.txt文件
2$ git commit -m "start writing my paper" paper.txt
3
4# 对工做区中的文件统一提交至暂存区
5$ git commit -m "XXXXXXXXXXX"
复制代码

使用commit命令以后,就能将咱们暂存区中的内容提交至仓库中,其中的-m参数表示的是提交说明,用于解释说明本次提价的内容。提交完成以后,咱们能够在Git中经过git status来查看文件的状态:

1# 查看指定文件的状态
2git status paper.txt
3# 查看全部文件的状态
4git status
复制代码

以上操做过程以下图所示:

3、关于文件的各类操做

文件修改以后

在上节中,咱们已经介绍了文件的四种状态,而且以关于论文的例子来初步了解了版本库以及文件库的简单操做。

假设如今论文指导老师对Taoye提出了要求:“Taoye同窗,时间来不及了,你今天必须给我完成论文的摘要部分!!!不然,后果自负!!!”

“Excuse me?今天?我游戏打得正嗨呢。面对老师如此强硬的要求,没办法了,只能暂停上王者的上分阶段了,开始刚论文。”对此,Taoye进行了一个骚气的三下五除二操做,普遍的涉猎各类优秀的学者文献并进行构思,迅速开写paper.txt中的摘要部分,完成以后的内容以下所示:

1Oh, my god, I will write my graduate paper.
2Come on, Taoye!
3
4I have finished the summary today!
复制代码

以后,咱们再经过git status命令来查看一下该论文文件的状态:

1$ git status paper.txt
2On branch master
3Changes not staged for commit:
4  (use "git add <file>..." to update what will be committed)
5  (use "git checkout -- <file>..." to discard changes in working directory)
6
7        modified:   paper.txt
8
9no changes added to commit (use "git add" and/or "git commit -a")
复制代码

此时,咱们能够发现工做区中的内容发生了修改,而且与咱们上一次提交后版本库中的内容不一致,这个时候,Git就会提醒咱们须要再次进行add、commit操做来将修改后的文件添加并提交至版本库。另外,咱们也可使用diff命令来查看据上次提交所修改的内容:

1# 查看据上次提交所修改的内容
2git diff paper.txt
复制代码

当确认文件修改的内容无误以后,咱们就可使用add、commit操做来提交咱们的文件到版本库中:

1# 添加至暂存区
2git add paper.txt
3# 提交至版本库
4git commit -m "finished the summary" paper.txt
5# 查看状态
6git status paper.txt
复制代码

OK,Taoye从白天刚到深夜。如次一来,总算是完成了老师给的要求,兴奋的将内容提交给老师审阅,而后又继续打王者了。

版本的回退

Taoye连续打了12h的游戏,有点累了。从新打开本身完美的论文欣赏一下,却忽然发现有几个错别字,这种低级错误实属不该该出现啊。思虑半刻,Taoye修改以后,再次add commit就完事了:

paper.txt修改以后的内容:

1Oh, my god, I will write my graduate paper.
2Come on, Taoye!
3
4I have finished the summary today!
5Some typos have been fixed.
复制代码

再次add、commit操做:

1git add paper.txt
2git commit -m "fixed the typos" paper.txt
复制代码

也就是说,如今咱们论文总共是有三个版本,分别是:初始化的论文、完成摘要的论文、修改错别字后的论文。咱们能够经过log命令来查看各类版本的论文文件:

1# 显示各类版本文件的详细信息
2$ git log paper.txt
3# 经过一行简单显示文件的信息
4$ git log --pretty=oneline paper.txt
5d7938315aa0f4a4d40c6a94a10ab8db25b50e23b (HEAD -> master) fixed the typos
6454cc579f0fe51fdfd97132384a9c5fcaa1993c2 finished the summary
7dc1dcd9501dec52e6160ce98bb5c118abb805289 start writing my paper
复制代码

从以上log的输出信息,咱们能够知道所提交文件的全部历史记录,其中记录了提交时间、提交做者(邮箱)、提交说明(-m)等信息。而且若是咱们仔细一看,会发现每个版本的文件都会对应一个commit id,这个id其实就至关于每个版本的惟一标识。好比,从上面的输出结果,咱们能够获得第一个版本的commit id = dc1dcd9501dec52e6160ce98bb5c118abb805289,而这个commit id的做用就是方便咱们往后自由“穿梭”到各个版本(就是一种穿越时空的意思)。

Taoye的论文指导老师审阅了摘要内容以后,正言厉色的说道:“你这写的啥玩意儿?牛头不对马嘴,并且竟然还有错别字?”

没办法了,Taoye只能虚心接受老师的批评,再次苦逼的修改论文了。

咱们如今论文是版本三,有没有一种快速有效的方法回退到版本一呢???在Git中,咱们能够经过git reset --hard来实现这个需求,也就是版本的回退。版本的回退能够用两种形式,一种是经过HEAD来基于当前版本进行回退,另外一种是经过commit id来回退到指定的版本,其用法以下所示:

1# HEAD表示的是当前版本,能够经过HEAD^回退到上一个版本
2git reset --hard HEAD^
3git reset --hard HEAD^^     # 回退到上上版本,回退到多少个版本以前就使用多少个^
4git reset --hard HEAD~50    # 回退到50个版本以前
5
6# 指定commit id来进行版本回退
7git reset --hard dc1dcd
复制代码

值得注意的是,咱们经过指定id来进行版本回退的时候,因为id过长,咱们不必全写,只须要传入前几个字符保证id的惟一性便可。有使用过Docker的朋友,应该会熟悉,咱们在指定容器的时候,也是相似的操做。

下面Taoye版本三的论文迅速回退到版本一,骚操做以下:

1$ git reset --hard dc1dcd
2$ cat paper.txt
3Oh, my god, I will write my graduate paper.
4Come on, Taoye.
复制代码

关于版本穿梭的简单解释:其实,在Git中,有个HEAD指针用于指向当前版本,当咱们进行版本回退的时候,其实就是改变HEAD的指向,指向对应的版本也就实现了版本的回退。这有点相似于数据结构中链表的操做。

此外,咱们还能够经过git reflog来查看当前版本文件的变换:

1$ git reflog paper.txt
2dc1dcd9 HEAD@{1}: reset: moving to dc1dcd                       # 版本的回退(回退到版本一)
3d793831 (HEAD -> master) HEAD@{2}: commit: fixed the typos      # 第三次提交(版本三)
4454cc57 HEAD@{3}: commit: finished the summary                  # 第二次提交(版本二)
5dc1dcd9 HEAD@{4}: commit (initial): start writing my paper      # 第一次提交(版本一)
复制代码

撤销修改

假设Taoye在写论文的时候,天天都在不断地修修改改,内心面很是的烦躁,很不是滋味。因而乎,在paper.txt中添加以下一句话:

1I don't like my tutor, he often criticizes me.
复制代码

然而,在打算提交的时候,想了想仍是有点不太妥,要是由于这么一句话,最终致使没法毕业那就完蛋了。对此,咱们在对文件commit以前使用'git status paper.txt'命令发现,能够经过checkout --来进行修改撤销,撤销至修以前的状态,操做以下:

1$ git checkout -- paper.txt
2$ cat paper.txt     # 执行以后,能够发现已经撤销到无最后一句的状态
复制代码

以上是发生在咱们对工做区中的文件进行修改,可是尚未执行git add操做,将工做区中的paper.txt添加至暂存区中的场景,已达到撤销至修改以前的状态。假设咱们在对paper.txt修改以后,再执行git add paper.txt命令将文件添加至暂存区,那么咱们该怎样撤销呢?按照思路,咱们能够先经过git reset HEAD将暂存区中的内容撤销掉放回工做区,而后撤销工做区便可实现需求,对此,有以下操做:

1# 将暂存区中的内容撤销掉放回工做区
2git reset HEAD paper.txt
3# 撤销工做区修改的内容
4git checkout -- paper.txt
复制代码

如此一来,就完美的将I don't like my tutor, he often criticizes me.撤销掉,Taoye也就能顺利毕业了。关于撤销,要记得与版本回退区分开来,撤销是咱们在对文件进行修改可是尚未进行commit的时候发生的,而版本回退是在执行了commit提交操做以后发生的。

文件的删除

在上面的内容中,咱们已经详细的介绍了关于文件的修改、版本回退、撤销等操做,下面咱们来说讲文件在删除以后应该会出现哪些操做。

假设如今出现了这么一种状况:Taoye有个顽皮的妹妹,她在用我电脑的时候,不当心将个人paper.txt论文文件从本地磁盘删除了。一气之下,Taoye将妹妹关进了小黑屋自我检讨七天。悲剧啊,Taoye忙活了将近一个月的论文就此烟消云散,Git该如何挽回这样的结局呢?

paper.txt文件删除以后,咱们使用git status来查看一下文件的状态:

1$ git status
2On branch master
3Changes not staged for commit:
4  (use "git add/rm <file>..." to update what will be committed)
5  (use "git checkout -- <file>..." to discard changes in working directory)
6
7        deleted:    paper.txt
8
9no changes added to commit (use "git add" and/or "git commit -a")
复制代码

在Git看来,你将文件从工做区中删除,其实也是对文件的一种修改。也就是说,如今咱们的工做区中的内容与版本库中的内容不一致(工做区没有了paper.txt文件,而版本库依然存在paper.txt文件)。为了将二者空间中的内容达到一致,咱们如今有两种选择,一是将版本库中的paper.txt文件删除掉,二是将工做区中的paper.txt文件恢复。

有了以上的思路,咱们能够有以下操做:

1# 将版本库中的paper.txt文件删除掉,须要执行commit才会生效
2git rm -f paper.txt
3git commit -m "delete the paper.txt"
4
5# 将工做区中的paper.txt文件恢复
6git checkout -- paper.txt
复制代码

对于文件的删除,须要注意的是,只有提交到版本库的文件,才能进行恢复,对于为提交到版本库的文件是没法进行恢复的。

4、本地项目远程提交到Github仓库

Taoye在以前参加2019年腾讯微信小程序比赛的时候,开发了一个关于侦探推理的项目。Taoye如今想要将该项目从本地提交到Github,该如何实现呢?

咱们在实现该需求以前,首先须要将本地与Github进行联通。对此咱们应该经过ssh在本地生成一个公钥,而后在Github中配置该公钥。操做以下:

1# 一、生成公钥,执行以后会在.ssh目录中生成秘钥文件,其中id_rsa.pub表示的是公钥
2cd ~/.ssh
3ssh-keygen -t rsa 26647879@qq.com
4# 二、进入github,settings -> SSH keys -> add key,而后将id_rsa.put中的公钥复制进去
5# 三、配置好公钥以后,须要验证本地与github的连通性
6ssh -T git@github.com
复制代码

在确认本地与Github联通以后,咱们就能正常地将项目从本地远程提交到Github中了。

  • 登陆Github,建立一个目标仓库,取名为detective,用来存储咱们的项目,并复制其中的.git连接地址
  • 在Github建立仓库以后,须要将该远程仓库与本地关联起来
1# 在本地关联目标仓库,方便以后将项目推送至该远程仓库
2git remote add origin https://XXXXXX.git
复制代码
  • 进入咱们的本地项目,而后初始化为git可管理的仓库
1cd detective
2git init
复制代码
  • 将工做区中项目的全部文件添加至暂存区
1git add ./*
2

复制代码
  • 将暂存区中的内容提交到版本库当中
1git commit -m "commit the detective project" ./*
复制代码
  • 将项目添加到版本库以后,咱们就能够将该项目推送至远程仓库了
1# 第一次推送
2git push -u origin master
3# 推送以后,若是咱们的项目发生了修改,咱们能够不用在使用-u参数进行推送
4git push origin master
5
6# 另外,若是有须要的话,咱们还可使用clone命令将远程仓库克隆到本地
7git clone https://XXXXXX.git
复制代码

5、Git的分支管理

分支是Git当中一个很是重要的概念,分支有点相似于树枝,也就意味着为了不影响主线的正常开发,咱们能够将任务从主线中分离开来,从而造成一个分支,以后的任务都是在分支中来完成的,当任务完成以后,就能够将完整的任务从分支提交到主线。

在前面版本回退一节当中,咱们知道,每一次的提交都会产生一个版本,屡次提交天然也就会产生多个版本。咱们能够将每个版本看作是一个珠子,而多个版本就会经过一条线串联起来,从而造成一条版本链。这个版本链其实就是一个master分支,也就是咱们上面所说的主线,咱们每一次的提交都是基于master分支来完成的,而HEAD指针则是用来指向当前分支(在没有其余分支的前提下,就是指向master)。

下面的图文讲解分支的内容,来自廖大大的教程:https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能肯定当前分支,以及当前分支的提交点:

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也愈来愈长。

当咱们建立新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

你看,Git建立一个分支很快,由于除了增长一个dev指针,改改HEAD的指向,工做区的文件都没有任何变化!

不过,从如今开始,对工做区的修改和提交就是针对dev分支了,好比新提交一次后,dev指针往前移动一步,而master指针不变:

假如咱们在dev上的工做完成了,就能够把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

因此Git合并分支也很快!就改改指针,工做区内容也不变!

合并完分支后,甚至能够删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,咱们就剩下了一条master分支:

分支的建立与合并

在上面,已经介绍了分支的概念及其断链、成链的原理过程,下面咱们经过Git命令来完成分支的建立与合并。

在Git中,咱们能够经过git branch来查看有哪些分支、git branch xxx来建立一个分支,其中带有*号的表示当前分支、git checkout xxx来切换分支:

1# 建立一个名为dev的分支
2$ git branch dev
3# 从master分支切换到dev分支中
4$ git checkout dev
5# 查看当前有多少分支
6$ git branch
7
8# 此外,咱们还实现分支的建立、切换这两个操做合并执行
9$ git checkout -b dev
复制代码

如今,咱们不妨在刚刚建立的dev分支中对paper.txt的内容进行编辑,在最下方添加这么一句话:I'm writing the content of my paper.。编辑完成并保存以后,咱们提交到版本 库,并再次切换到master分支,使用cat命令来查看paper.txt的内容。

1$ git checkout dev      # 切换到dev分支
2$ vim paper.txt         # 编辑paper.txt,并增添一句话
3$ git add paper.txt     # 添加到暂存区
4$ git commit -m "writing the content of this paper" paper.txt   # 提交到版本库
5$ cat paper.txt         # 查看paper.txt内容
6$ git checkout master   # 再次切换到master分支
7$ cat paper.txt         # 查看paper.txt内容
复制代码

采用cat命令两次查看paper.txt内容时,咱们会发如今执行后一次命令时,paper.txt中的内容并无添加新增的一句话,这主要是由于咱们刚刚采用vim编辑paper.txt的时候是基于dev分支进行的,提交也是提交到dev分支,而非master分支,因此当咱们切换到master分支的时候并不可以看见paper.txt编辑后的内容。以下图所示:

而咱们要想在master分支中查看到paper.txt的新内容,则须要将dev分支合并到master主分支中才行,采用的是git merge命令,操做以下:

1$ git checkout master
2$ git merge dev
复制代码

合并完成以后,dev的任务已经完成了,也就没有必要存在了,能够经过git branch -d xxx来删除分支:

1$ git branch -d env
2Deleted branch env (was e9c7421).
复制代码

单人分支合并时的冲突解决

在编程的世界里,多进程占据了一个举足轻重的地位。在高并发、高流量的场景下,咱们通常经过多进程来提升项目的服务效率,以便提升用户体验。话虽如此,可是在使用多进程的时候,许多问题一样会慢慢浮出水面。一样地,Git分支虽然可以方便多个的用户协同开发,可是将多个不一样内容的分支进行合并的时候却会产生冲突,做为一个对技术有追求的Coder,咱们应该要理解为何会产生冲突,以及产生冲突后咱们应该怎样解决。

出现冲突的场景:

  1. 切换到dev分支后,对paper.txt进行编辑,而后将保存后的文件提交到版本库中。
  2. 切换到master分支,对paper.txt进行编辑,将保存后的文件提交到版本库。
  3. master分支下,将dev分支进行合并。
 1# 一、在dev分支中对paper.txt文件进行编辑,并提交到版本库
2git checkout dev
3git vim paper.txt
4git add paper.txt
5git commit -m "the first operation" paper.txt
6
7# 二、在master分支中对paper.txt文件进行编辑,并提交到版本库
8git checkout master
9git vim paper.txt
10git add paper.txt
11git commit -m "the second operation" paper.txt
12
13# 三、在master分支中,将dev分支合并
14git merge dev
复制代码

此时,在咱们执行merge命令进行分支合并的时候,会出现以下内容:

1$ git merge dev
2Auto-merging paper.txt
3CONFLICT (content): Merge conflict in paper.txt
4Automatic merge failed; fix conflicts and then commit the result.
复制代码

从如上Git给咱们提供的信息能够知道,此时已经产生冲突,咱们必须手动解决冲突才能再次提交,使用git status paper.txt也能查看产生冲突的信息。咱们经过vim打开paper.txt文件能够看见以下内容:

 1Oh, my god, I will write my graduate paper.
2Come on, Taoye!
3
4I have finished the summary today!
5Some typos have been fixed.
6I'm writing the content of my paper.
7<<<<<<< HEAD
8
9the second operation.
10=======
11
12the first operation.
13>>>>>>> dev
14

复制代码

对此,咱们要想解决冲突,则须要在master主分支中手动编辑该文件,编辑并保存完成以后,在将文件提交到版本库便可:

1vim paper.txt
2git add paper.txt
3git commit -m "solve the conflict" paper.txt
4
5# 查看分支的合并状况
6git log --graph --pretty=oneline --abbrev-commit
复制代码

下面原则来自廖大大的Git教程:https://www.liaoxuefeng.com/wiki/896043488029600/900005860592480
在实际开发中,咱们应该按照几个基本原则进行分支管理:

  1. 首先,master分支应该是很是稳定的,也就是仅用来发布新版本,平时不能在上面干活;
  2. 那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,好比1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
  3. 你和你的小伙伴们每一个人都在dev分支上干活,每一个人都有本身的分支,时不时地往dev分支上合并就能够了。

因此,团队合做的分支看起来就像这样:

多人协做下的冲突解决

如今导师给Taoye提出的新需求是:两天内完成论文的初稿并提交。

Taoye大量的时间都花费在开黑中了,两天内完成这个任务对Taoye来讲有点困难。因而乎,Taoye想要找妹妹帮忙完成论文的part1部分,而本身完成part2部分。如此一来,两个进程协同进行,也就能完美的实现了导师给的需求。妙哉,妙哉!Taoye心想到这,立马提交本身论文的半成品到远程仓库,而后给妹妹提供一个git连接供其clone。

1# Taoye将本地论文提交到远程仓库
2$ git push origin master
复制代码
1# 妹妹将远程仓库克隆到本地
2$ git clone XXXXXX.git
复制代码

OK,既然两人的本地都有了论文文件,那么接下来就要开始并行完成各自的任务了,为了不本身的操做给主分支带来很差的影响,因而在master分支中建立一个dev分支用来编辑文件。因为妹妹的效率比Taoye要快,因此率先完成了论文part1部分的内容,对此,妹妹有以下操做:

1# 妹妹的操做
2$ git branch dev
3$ git checkout dev
4$ vim paper.txt
复制代码

而且在paper.txt添加内容:sister have finished the part1.,part1部分的内容完成以后,将dev分支迅速推送至远程仓库:

1$ git add paper.txt
2$ git commit -m "sister have finished the part1" paper.txt
3$ git push origin dev
复制代码

OK,Taoye交给妹妹的任务已经完成了,因而就兴奋的出去玩耍了。毕竟这篇论文是属于Taoye的,因此仍是须要认真的完成,天然花费的时间也就更多了。经历了一夜通宵的时间,终因而顺利完成了part2部分的内容,因而屁颠屁颠的将论文提交至远程仓库:

1# Taoye的操做
2$ git checkout dev
3$ vim paper.txt
4# 在paper.txt添加一句:taoye have finished the part2
5$ git add paper.txt
6$ git commit -m "taoye have finished the part2" paper.txt
7$ git push origin dev
复制代码

而就在Taoye推送论文到远程仓库的时候,因为本身推送内容与妹妹推送的内容不一致,因此致使推送失败。咱们经过Git给出的提示信息能够知道,要想解决这个冲突,首先须要经过pull命令将最新的提交拉取下来,而后与本地合并,解决冲突以后再推送到远程仓库。为此,Taoye立马执行了pull命令:

1$ git pull
复制代码

而在执行pull命令的时候,糟糕的问题又接踵而至了,Git提示说:There is no tracking information for the current branch.,也就是说本地的分支与远程没有创建连接。对此,咱们能够创建连接后再执行pull命令:

1$ git branch --set-upstream-to=origin/dev dev
2$ git pull
复制代码

虽然能够执行pull命令,可是会出现冲突提示,因此咱们须要首先手动解决冲突,解决的方式和上节中同样:对paper.txt文件进行编辑,而后提交并推送至远程仓库。因此,Taoye对paper.txt文件进行编辑以后,内容以下:

1taoye have finished the part1
2taoye have finished the part2
复制代码

编辑好后,将文件保存并推送至远程仓库:

1$ git add paper.txt
2$ git commit -m "finished the part1 and part2" paper.txt
3$ git push origin dev
复制代码

因此,在多人协做工做时咱们通常准守以下过程:

  1. 完成任务后首先使用git push origin xxx推送至远程仓库
  2. 若是推送失败,则须要执行git pull命令将最新的提交拉取下来
  3. 若是拉取失败,则可能须要创建链接,因此执行git branch --set-upstream-to=origin/xxx xxx命令
  4. 解决以后,再次执行git pull命令尝试拉取最新提交
  5. 此时,咱们须要对冲突文件进行修改,等到修改完成以后,将文件推送至远程仓库

6、标签管理

在上面的内容中,咱们有介绍过,能够根据版本号(很长的字符串)来实现任意版本之间的穿越。可是经过这种较长字符串版本号的形式对用户并非特别友好,看的脑阔有点疼。因此咱们通常能够给每个版本贴上一个标签,而且能够经过这个标签来定位任意的版本,从而更加容易的实现版本穿越等需求。

在这,咱们也能够将标签看作是版本号的一个别名,使用标签就至关于使用版本号,二者的做用是等价的。若是有使用过Docker的话,应该会知道,在Docker中,咱们每建立一个容器,Docker都会分配一个容器id以便于咱们定位对应的容器,而咱们本身也能够为每个容器定义一个别名。咱们在使用一系列的Docker命令对容器进行操做的时候,既能够经过容器id,也能够经过别名的形式来进行操做。

Git中,咱们主要是采用tag命令来管理标签,因为标签比较的简单,这里就不一一讲解了,与标签相关的命令主要有如下一些:

 1$ git tag                       # 查看全部标签
2$ git tag v1.0                  # 没有指定版本,则默认给当前版本打标签
3# 查看各个版本信息(版本号)
4$ git reflog paper.txt | git log --pretty=oneline paper.txt
5$ git tag v0.9 a35d6b           # 根据版本号来打标签
6# 打标签的同时,给标签添上相应的说明
7$ git tag -a v0.1 -m "version 0.1 released" a35d6b
8$ git show v1.0                 # 查看对应的标签信息
9$ git tag -d v0.9               # 删除标签
10
11$
 git reset --hard v0.9         # 根据标签实现版本穿越
复制代码

总结

总的来说,Git上手仍是很快的,关键在于平时须要增强Git操做命令的训练。以上关于Git的命令只是一部分,但若是掌握上述内容,仍是能够轻松知足Git的实际需求的。若是有兴趣想要了解更多关于Git的知识,能够自行查阅相关的文档或是书籍来进一步的学习。

参考资料

一个小时学会Git:www.cnblogs.com/best/p/7474…
廖雪峰Git教程:www.liaoxuefeng.com/wiki/896043…

相关文章
相关标签/搜索