目录
- 前言
- 本地仓库 (使用Sourcetree)
- 远程仓库 (使用GitHub)
前言
本文仅简单讨论代码的版本控制, 包括版本提交、分支、远程仓库的拉取/推送、版本回退等, 不探讨Git指令, 不涉及多人协作, 更多的是客户端使用过程的记录.
分别使用Sourcetree和GitHub客户端实现对代码的版本控制, 两者操作起来都差不多, 故分别用于演示管理本地仓库和远程仓库. 远程仓库需要服务器来储存项目代码, 自从微软收购GitHub后, 对私有项目也开放免费了, 所以远程客仓库的拉取/推送操作将使用GitHub客户端来演示.
所谓仓库, 可以理解成一个项目, 或者是这个项目对应的文件夹.
本地仓库 (使用Sourcetree)
Sourcetree客户端下载地址https://www.sourcetreeapp.com/
1. 创建本地仓库
新建一个文件夹LocalRepository, 装入一个文件README.md, 随便填入初版信息:

打开Sourcetree客户端, 创建本地仓库

指定刚才创建的文件夹

成功创建仓库, 右边数字代表修改量

双击进入主界面

勾选待定的文件(表示放入暂存区), 填入版本记录信息, 然后提交, 这时历史版本中就有版本记录了.

2. 新增版本
我们回到刚才的README.md文件, 新增一行信息:

然后我们看到Sourcetree中文件状态里新增了未保存的修改:

勾选文件, 填入版本记录信息"下雨了", 然后提交:

可以看到历史中有了版本记录:

讨论
至此, 我们已经完成了第一次版本迭代. 但是有个问题, 本次修改版本是直接在主分支master上面进行的, 而master应该用于储存可发布的稳定版本, 不应直接供给开发阶段使用.
实际开发中, 我们应先分离出一个分支进行开发, 调试无误后再合并到master进而发布. 这样即可以防止多人协作同时对master进行操作造成冲突, 同时又可以分出多个分支进行多功能"并行"开发.
假设这样一种情况:
当我们在master上直接开发新功能, 开发到一半的时候发现原来的代码有bug, 这时候我们只有两种选择: 要么写完另一半功能再去调试bug, 要么遗弃现有的一半功能代码去调试bug. 这种做法好比是"线程阻塞式"的, 似乎不符合我们的需求. 那么, 此时分支可以闪亮登场了. 创建一个分支去开发这个新功能, 此时我们会有两个分支: master和新功能分支. 当我们在功能分支上开发到一半的时候发现原来代码有bug, 我们可以切换到master分支去, 另创建一个临时分支用于修复bug, bug修复后将临时分支合并到master用于发布更新, 功能分支调试无误后也合并到master, 最后形成稳定的代码版本.
我们之所以能在各分支之间随意切换, 是因为分支之间的版本管理是相互独立的, 详见下节.
3. 分支
这个例子的流程如下:
当发布"下雨了"这个版本后, 我们新建一个买菜分支去买鱼和豆腐, 买完鱼后才想起家里没有关窗 (代码有bug). 这时我们可以切换到master, 把窗关上(bug修复), 然后重新切回买菜分支, 继续买豆腐, 然后回到家里 (称为合并).
新建分支
点击"分支"按钮, 或者直接在指定版本上右击选择分支...

选择指定节点, 起名买菜

然后我们看到分支那里, 多了"买菜"这个分支:

这时候当前分支已经切换到买菜这里了, 以后的修改将只对当前分支有效. 要想切换分支, 双击分支中的分支名即可.
返回我们的工程项目文件夹LocalRepository, 新增一个买菜文件:

然后看到文件状态那里有更新, 我们将这个提交一个版本, 备注买鱼, 提交到"买菜"分支 (此时我们正处于这个分支上):

然后点击历史, 查看版本记录:

切换分支
此时, 买菜分支比master超前了一个版本(买鱼版本).
我们可以验证下, 在分支中双击master切换到主分支, 此时我们的项目文件夹LocalRepository下买菜文件没有了:

而切换回买菜分支, 又出现了买菜这个文件:

现在我们切换回master, 新建一个temp分支去修复bug (关窗), 过程和新建买菜差不多, 就只贴关键步骤了. 在temp分支里关窗:

然后temp和买菜分支各有一版不同的修改, 且都超前于master: temp多了"关窗"版本, 而买菜分支则多了"买鱼"版本:

合并分支
现在bug修复了, 我们将temp合并到master里去.
我们要将某个源分支合并到某个目标分支上, 需要到目标分支上进行操作. 比如我们要把temp的关窗版本合并到master, 需要切换到master中, 然后右击关窗版本选择合并:


删除分支
已经生成稳定版本了, 现在可以把temp分支删除了:


好的, bug修复了, 我们切换回买菜分支, 继续买豆腐:



OK, 现在可以回家了. 将买菜分支合并到master.
过程不再重复, 直接看结果:

4. 版本回退
我们在master上叠加两个新版本进行测试:

如果我们想回退到天晴了这个版本, 可以右键选择重置到这次提交:

然后有三种重置方式供我们选择:

软合并和混合合并都不会删除开窗版本的内容, 都是变成天晴了版本提交之后开窗版本提交之前的状态. 不同的是, 软合并会将这些修改添加到已暂存区, 而混合合并则还在未暂存区.
强行合并则是丢弃整个开窗版本, 项目文件夹内容变成天晴了这个版本.
暂存文件
我们提交的时候, 只会将暂存文件的内容进行提交记录. 所以我们修改了内容之后, 要确保想要提交的内容放到已暂存文件, 否则提交的时候不会记录该修改内容.
软合并
不会删除开窗版本的内容, 只是将开窗版本的修改置为未提交状态


修改的内容被默认添加到已暂存文件区:

混合合并
和软合并唯一不同点是, 修改的内容还在为暂存文件区. 这时如果我们点击选中未暂存文件, 则会被添加到已暂存文件, 这就和软合并一样了.

强行合并
丢弃开窗版本, 内容变成天晴了版本内容:


5. Sourcetree&Git部分名词解释
摘自https://www.cnblogs.com/fisherbook/p/11397168.html
克隆(clone):从远程仓库URL加载创建一个与远程仓库一样的本地仓库
提交(commit):将暂存文件上传到本地仓库(我们在Finder中对本地仓库做修改后一般都得先提交一次,再推送)
检出(checkout):切换不同分支
添加(add):添加文件到缓存区
移除(remove):移除文件至缓存区
暂存(git stash):保存工作现场
重置(reset):回到最近添加(add)/提交(commit)状态
合并(merge):将多个同名文件合并为一个文件,该文件包含多个同名文件的所有内容,相同内容抵消
抓取(fetch):从远程仓库获取信息并同步至本地仓库
拉取(pull):从远程仓库获取信息并同步至本地仓库,并且自动执行合并(merge)操作,即 pull=fetch+merge
推送(push):将本地仓库同步至远程仓库,一般推送(push)前先拉取(pull)一次,确保一致
分支(branch):创建/修改/删除分枝
标签(tag):给项目增添标签
工作流(Git Flow):团队工作时,每个人创建属于自己的分枝(branch),确定无误后提交到master分枝
终端(terminal):可以输入git命令行
远程仓库 (使用GitHub)
如果只需要上传代码到GitHub而不涉及后续修改迭代, 那么使用网页就够了.
1. 上传 (Push)
注册GitHub账号, 在右上角点击+号创建远程仓库 (保存在GitHub):

选择public表示公开, 任何人可见; 选择private则自己可见, 也可设置成指定人可见. 一般项目都会带有一个自述文件(README.md)用于描述项目以及使用方法等.

点击Upload files以上传代码文件:

直接拖动文件到窗口或者点击选择上传:

例子中文件内容为一个HelloWord文件夹, 然后里面有个版本记录的文本文件:

因为初版内容相对于原始空内容来说也是一种修改, 所以上传完成后GitHub会提示我们提交这个修改:

然后返回项目首页, 发现这个文件夹已经上传成功了:

2. 下载 (Pull)
点击克隆或者下载按钮, 可以直接下载压缩文件ZIP:

解压后就会看到我们的HelloWord文件以及README文件:

3. GitHub客户端
如果要克隆远程仓库到本地, 在本地修改内容后push同步到远程仓库, 那么最佳方案就是下载GitHub客户端.
下载地址: https://desktop.github.com/
克隆远程仓库到本地
克隆远程仓库到本地. 点击克隆和下载按钮, 选择Open in Desktop进行克隆:

克隆完成后就在我们指定的本地文件夹看到HelloWord文件夹和README文件了:

push
我们在本地修改README文件:

然后GitHub客户端有提示有新的修改:

我们提交这个修改, 备注等外卖. 注意, 此次提交仅记录在本地, 如果需要同步到远程仓库, 需要进行push推送操作.
点击History版本记录, 将指定版本push到远端. 点击上传箭头:

然后我们查看网页端, HelloWord项目已经有更新了:

pull
相反地, 我们在GitHub网页 (远程仓库) 修改内容, 然后拉取同步到本地.



然后打开GitHub客户端, 刷新一下:

然后我们看到远端有一个新版本:

点击Pull origin拉取之. 然后History就多了个版本记录:

同时本地文件也被更新了:

网友评论