[Sourcetree] Git 版本控制详解
本文使用工具:Sourcetree 3.0 +
代码托管平台:码云,也可以选择 GitHub,Gitlab等
准备
一般情况下,我们会将我们的项目新建多个分支,来用于不同的目的:
- master:一般是存放已发版的源码,平时开发不动该版源码
- developer:开发中的源码,平时的改动都提交到该分支,开发期的更改,版本控制一般都是在这个分支内进行;
- testDev(其他):如果项目还有其他的需求,也会新开一个分支来进行,比如某个功能的调研。。。
这里我在码云上面创建了一个测试项目,添加了两个分支:

然后使用 Sourcetree 克隆到本地进行相关的操作;
如下所示,是我们打开的一个仓库:

顶部工具栏
- 提交(commit):提交改动到本地仓库
- 拉取(pull):从远程仓库拉取文件/改动到本地
- 推送(push):提交本地的文件/改动到远程仓库
- 抓取:检测远程是否有更新,如果有变动会在拉取右上角出现数字角标
- 分支:新建本地分支
- 合并:合并本地分支
- 贮藏:当我们想要保存某个状态的内容,可选择贮藏;
- 终端:打开电脑终端,可使用指令操作当前仓库
- 设置:可以配置仓库提交代码模版,远程仓库地址,远程仓库用户名,版本控制忽略文件等
上面常用的是前三个;
左侧工具栏:
- WORKSPACE:当前本地文件的内容/状态
- 分支(branch):本地的分支,这里只有主分支(master)、分支localDev,可以在上面的分支选项新建新的分支;
- 标签(tag):可以为不同的分支添加一些标签
- 远端(remote):这里主要显示远程仓库所有的分支,可根据需要检索到本地追踪
WORKSPACE - 文件状态
当选中左侧文件状态的时候,中间会出现三块区域:已暂存文件、未暂存文件、文件内容;

暂存,即 add ,暂存之后,就可以点击提交(commit),或者点击下方的输入框,输入说明即可提交文件改动到本地仓库;
在已暂存文件区的上面,有两个倒三角的按钮,其内容分别如下图所示

▲ 这里主要是选择显示哪些内容,以及如何显示;

▲ 这里主要是文件的排练方式;
主要提一下点开的那个列表,上半部分主要是文件的排列方式,下半部分是视图的显示方式,有三个选项:
- 无暂存视图:只有一个文件框,已暂存和未暂存的文件混合一起;
- 灵活暂存视图:上半部分是已暂存文件,下半部分是未暂存文件,文件时全部展开的;
- 分体暂存视图:也是上半部分是已暂存文件,下半部分是未暂存文件,区别是两个框是分开可滑动的;
另外,可以看到,每个文件右侧都有三个点的按钮,可以对文件进行相应的操作:
已暂存文件后可供的选项有:未暂存文件、移除文件、在 Finder 中显示;
未暂存文件后面的选项有:暂存文件、丢弃文件、移除文件、忽略文件、在 Finder 中显示;
WORKSPACE - 历史

在这里可以选择历史提交记录中各版本的文件内容,如果是未提交的文件,和上面的内容一样;
WORKSPACE - 搜索
功能不用多说,可以搜索提交的版本等;
分支 - 简介
这里主要是管理本地分支,可以进行分支的新建/切换/删除/合并等;
在分支 master 左侧有个圆圈的标识符,代表当前工作区所处的分支,默认是处在主分支;
选中某个分支,右键,会出现如下的选择列表:

- 检出 xxx:切换当前分支到该分支
- 合并 分支1 至 分支2:将分支1的更改合并到分支2
- 将当前变更变基到 xxx(rebase):就是将该分支未更改前的文件基础更改到某个版本
- 推送到 origin/master(已跟踪):将本地的变更推送到已跟踪的远程分支
- 推送到:选择要推送到的远程分支
- 跟踪远程分支:选择要跟踪的远程分支,跟踪后该本地分支会和跟踪的远程分支对比是否有改动
- 与当前对比:选中的分支与当前分支的对比
- 重命名...:重新命名分支
- 删除 xxx:删除当前分支
- 复制分支名字:复制分支名称
- 创建拉取请求...:抓取远程分支
分支 - 新建分支
新建分支,可通过上方菜单栏的分支按钮:

这里输入分支名称,提交可以选择提交记录中的某个节点,点击创建分支即可;
另一种方式,是选中某个提交的节点,右键,在弹出列表中选择分支:

分支 - 删除分支
方式一
在新建分支的弹出框中,有删除分支的选项,选择后如下图所示:

这里会显示所有的分支:本地分支和远程分支,选择要删除的分支,然后删除即可;
下面有个复选框:忽略合并状态强行删除
如果是删除还未合并改动到主分支的的分支,会有提示,如果勾选该项,无论是否合并,都会强行删除;
方式二
或者选中该分支,右键,选择 删除 分支名称,即可删除!
如果此时该分支有没有合并的改动,会报错:

这里一般会将改动合并到主分支,如果不想要这些改动,可在删除时,勾选 强制删除 复选项:

分支 - 切换分支
在切换分支的时候,本地的仓库内容会随之改变;如果是未提交的改动,将会带入新切换的分支中;
在左侧分支列表,双击某个分支,即可切换到该分支;需要注意的是,在切换分支的时候,要将当前分支所有的改动进行提交,否则切换时会有提示,当然,可以选择忽略这些改动,强行切换:

如果勾选了复选框:放弃本地变更,在当前分支所做的改动都会丢失,这个功能要慎用,如果是没必要保存的更改可以选择放弃;
如果没有勾选该复选框,本地的改动会带到切换后的分支;是否需要提交,根据自身需求来决定,一般情况下,在某个分支做的改动,最好是提交到当前的分支;各个分支之间,在合并之前应当相互独立;
如果是报下面的错误,就需要将更改提交后,再进行切换了:

另外一种切换分支的方法是,选中待切换的分支,然后右键选择检出 分支名称,即可将当前分支切换到该分支;
分支 - 本地分支跟踪远程分支
选中某个分支右键,会看到下图所示的部分内容,含有 已跟踪 字样的是标示当前本地分支对应的远程分支;

当跟踪了某个远程分支,该本地分支会和远程分支做比较,文件改动的标示都是在该两个分支间进行;
我们可以在 跟踪远程分支 中来切换本地分支要跟踪的远程分支,一般情况下,我们本地分支的名称和远程分支是一致的,分别跟踪即可;当然,也可以随意切换,但是不建议这么做;
分支 - 合并分支
在某个分支开发完成后,例如,我在branch1分支新建了一个文件,然后将所有的更改提交到该分支

然后,切换回主分支,此时会发现项目中没有刚刚新建的文件;然后,选中刚刚的分支,右键,选中 合并branch1 至 master,如果没有冲突即可将刚刚的改动合并到 master 分支

合并后,再去项目中查看,就会有刚刚新建的那个文件了;
分支 - 回滚/重置
如果我们某次合并后,版本出现了无法修复的问题,想要回滚/重置这次操作,可以在版本记录中,选中某个提交记录,然后右键:

这里可以选择,提交回滚,来回滚上次的提交/合并;
如果我们想之间回到某次提交,可以选择该记录,右键选择 将 master 重置到这次提交;
分支 - 变更基
假设我们正在 branch1 分支进行开发,这时有人提交了部分更改到远程 master 分支,我们在本地 master 分支拉取了更新后,想要在此更新的基础上继续进行 branch1 的开发,这时就需要将这些更新添加到 branch1 分支中;
切换回主分支,将远程的更改拉取下来;
然后,切换到 branch1 分支;
选中 master 分支,右键,选择 **将当前变更变基到 master
这时,可能会有冲突,根据提示解决一下即可!到此,就将更新合并到 branch1 分支中了;
标签(Tag)- 新建
在我们的提交记录中,对于某些比较重要的提交,我们可以使用 tag 来进行标记;选中某次提交,然后右键,选择 标签:

点击添加后,在左侧的 标签 一栏就会出现我们刚刚新建的 tag

标签 - 检出Tag
如果我们想要以某个 tag 为基础进行一些操作,我们可以选择 检出 该tag:选中 tag ,右键,检出 tag

或者直接双击该 tag:

这里需要注意这个提示,我们检出的 tag,会在 分支 列表下新建一个名为 HEAD 的分支,但他不是一个真正的分支,当我们切换到其他分支的时候,这个分支会消失
点击确定后,可以切换到当前 tag的工作区:

如果我们在此基础上做了改动,想要提交,就需要新建一个分支进行,否则,所有的改动,在切换分支后都会消失(该分支都消失了,改动肯定也不在了);
可以看到,当我们选中该 HEAD 分支时,版本记录中会选中当前的记录,在此基础上 右键,选择 分支 即可检出一个新的分支:

然后,将改动提交到这个分支,在切换回主分支时,就可以将当前的改动合并到主分支了;
远端
这里主要是显示远程仓库的一些分支,我们只能检出/拉取这些分支,不能新增/删除这些分支;
例如,我们检出远程的 testDev 分支:选中该分支,右键选择 检出

这里我们可以重新命名分支,一般是和远程分支一样;复选框本地分支应跟踪远程分支 默认勾选即可,意思是新检出的这个本地分支跟踪这个远程分支的状态;
点击检出后,在 分支 选项下,就会有我们新检出的这个分支

推送(push)
最后简单说一下推送,当我们在本地完成开发后,想要推送到远程仓库,点击推送后:

默认情况下,本地分支跟踪的哪个远程分支,就默认推送到这个分支,当然,我们也可以点击远程分支那一列进行选择,要提交到哪个远程分支:

这里选择将本地的 master 分支的改动,提交到远程的 developer 分支;
合并冲突
在我们合并代码的时候,不可避免的会出现冲突的情况;在我们拉取代码的时候,默认会勾选 立即提交合并的改动;这时,如果有冲突,将拉取不下来,而且会爆错;这时去掉该勾选

拉取之后,会在文件状态,看的冲突的文件:

选中冲突的文件,右键选择 启动外部合并工具

这里也可以直接选择 使用‘我的版本’解决冲突 或者选择 使用‘他人版本’解决冲突,但是一般都使用外面工具

这里会显示该文件所有冲突的地方,可以使用右下方的 Actions 按钮来选择解决冲突的方式;然后关闭,会提示你是否保存,选择保存即可;
如果选择了 Choose neither,需要手动在文件中删除冲突的文件;
冲突的情况很多,解决起来也是不同程度的复杂,开发中应该尽量避免。