目录
- 前言
- 本地仓库 (使用Sourcetree)
- 远程仓库 (使用GitHub)
前言
本文仅简单讨论代码的版本控制, 包括版本提交、分支、远程仓库的拉取/推送、版本回退等, 不探讨Git指令, 不涉及多人协作, 更多的是客户端使用过程的记录.
分别使用Sourcetree和GitHub客户端实现对代码的版本控制, 两者操作起来都差不多, 故分别用于演示管理本地仓库和远程仓库. 远程仓库需要服务器来储存项目代码, 自从微软收购GitHub后, 对私有项目也开放免费了, 所以远程客仓库的拉取/推送操作将使用GitHub客户端来演示.
所谓仓库, 可以理解成一个项目, 或者是这个项目对应的文件夹.
本地仓库 (使用Sourcetree)
Sourcetree客户端下载地址https://www.sourcetreeapp.com/
1. 创建本地仓库
新建一个文件夹LocalRepository, 装入一个文件README.md, 随便填入初版信息:
![](https://img.haomeiwen.com/i8900795/2b758295e347a469.png)
打开Sourcetree客户端, 创建本地仓库
![](https://img.haomeiwen.com/i8900795/22025014db6477dd.png)
指定刚才创建的文件夹
![](https://img.haomeiwen.com/i8900795/836c342fbb5141d5.png)
成功创建仓库, 右边数字代表修改量
![](https://img.haomeiwen.com/i8900795/0cd45d2a0c1f73ef.png)
双击进入主界面
![](https://img.haomeiwen.com/i8900795/6a6aaef9ac66442d.png)
勾选待定的文件(表示放入暂存区), 填入版本记录信息, 然后提交, 这时历史版本中就有版本记录了.
![](https://img.haomeiwen.com/i8900795/b14e8f7f3020c8ba.png)
2. 新增版本
我们回到刚才的README.md文件, 新增一行信息:
![](https://img.haomeiwen.com/i8900795/c7e0392418d0b588.png)
然后我们看到Sourcetree中文件状态里新增了未保存的修改:
![](https://img.haomeiwen.com/i8900795/48a8addcc3a0c15e.png)
勾选文件, 填入版本记录信息"下雨了", 然后提交:
![](https://img.haomeiwen.com/i8900795/5551f398919a65f7.png)
可以看到历史中有了版本记录:
![](https://img.haomeiwen.com/i8900795/91cea5de61a91e2c.png)
讨论
至此, 我们已经完成了第一次版本迭代. 但是有个问题, 本次修改版本是直接在主分支master上面进行的, 而master应该用于储存可发布的稳定版本, 不应直接供给开发阶段使用.
实际开发中, 我们应先分离出一个分支进行开发, 调试无误后再合并到master进而发布. 这样即可以防止多人协作同时对master进行操作造成冲突, 同时又可以分出多个分支进行多功能"并行"开发.
假设这样一种情况:
当我们在master上直接开发新功能, 开发到一半的时候发现原来的代码有bug, 这时候我们只有两种选择: 要么写完另一半功能再去调试bug, 要么遗弃现有的一半功能代码去调试bug. 这种做法好比是"线程阻塞式"的, 似乎不符合我们的需求. 那么, 此时分支可以闪亮登场了. 创建一个分支去开发这个新功能, 此时我们会有两个分支: master和新功能分支. 当我们在功能分支上开发到一半的时候发现原来代码有bug, 我们可以切换到master分支去, 另创建一个临时分支用于修复bug, bug修复后将临时分支合并到master用于发布更新, 功能分支调试无误后也合并到master, 最后形成稳定的代码版本.
我们之所以能在各分支之间随意切换, 是因为分支之间的版本管理是相互独立的, 详见下节.
3. 分支
这个例子的流程如下:
当发布"下雨了"这个版本后, 我们新建一个买菜分支去买鱼和豆腐, 买完鱼后才想起家里没有关窗 (代码有bug). 这时我们可以切换到master, 把窗关上(bug修复), 然后重新切回买菜分支, 继续买豆腐, 然后回到家里 (称为合并).
新建分支
点击"分支"按钮, 或者直接在指定版本上右击选择分支...
![](https://img.haomeiwen.com/i8900795/a523ab955760b659.png)
选择指定节点, 起名买菜
![](https://img.haomeiwen.com/i8900795/dd50118b908e2ee6.png)
然后我们看到分支那里, 多了"买菜"这个分支:
![](https://img.haomeiwen.com/i8900795/6ec6cc5a10507c65.png)
这时候当前分支已经切换到买菜这里了, 以后的修改将只对当前分支有效. 要想切换分支, 双击分支中的分支名即可.
返回我们的工程项目文件夹LocalRepository, 新增一个买菜文件:
![](https://img.haomeiwen.com/i8900795/1b4a56b6c4c890da.png)
然后看到文件状态那里有更新, 我们将这个提交一个版本, 备注买鱼, 提交到"买菜"分支 (此时我们正处于这个分支上):
![](https://img.haomeiwen.com/i8900795/f32055346688d1fc.png)
然后点击历史, 查看版本记录:
![](https://img.haomeiwen.com/i8900795/7b8bfdb8d6445ff3.png)
切换分支
此时, 买菜分支比master超前了一个版本(买鱼版本).
我们可以验证下, 在分支中双击master切换到主分支, 此时我们的项目文件夹LocalRepository下买菜文件没有了:
![](https://img.haomeiwen.com/i8900795/4b5c099043360b1e.png)
而切换回买菜分支, 又出现了买菜这个文件:
![](https://img.haomeiwen.com/i8900795/1b4a56b6c4c890da.png)
现在我们切换回master, 新建一个temp分支去修复bug (关窗), 过程和新建买菜差不多, 就只贴关键步骤了. 在temp分支里关窗:
![](https://img.haomeiwen.com/i8900795/cb51f6fd97a091ff.png)
然后temp和买菜分支各有一版不同的修改, 且都超前于master: temp多了"关窗"版本, 而买菜分支则多了"买鱼"版本:
![](https://img.haomeiwen.com/i8900795/0aa70cb21915edac.png)
合并分支
现在bug修复了, 我们将temp合并到master里去.
我们要将某个源分支合并到某个目标分支上, 需要到目标分支上进行操作. 比如我们要把temp的关窗版本合并到master, 需要切换到master中, 然后右击关窗版本选择合并:
![](https://img.haomeiwen.com/i8900795/639b8a22de44e5df.png)
![](https://img.haomeiwen.com/i8900795/e17b0afa4955e390.png)
删除分支
已经生成稳定版本了, 现在可以把temp分支删除了:
![](https://img.haomeiwen.com/i8900795/ce351569ac8924fa.png)
![](https://img.haomeiwen.com/i8900795/68ecd9fcf4c06454.png)
好的, bug修复了, 我们切换回买菜分支, 继续买豆腐:
![](https://img.haomeiwen.com/i8900795/206f1a82811619e0.png)
![](https://img.haomeiwen.com/i8900795/7cc646c2a946f1b4.png)
![](https://img.haomeiwen.com/i8900795/5c19155c84bb92ff.png)
OK, 现在可以回家了. 将买菜分支合并到master.
过程不再重复, 直接看结果:
![](https://img.haomeiwen.com/i8900795/b4c43e60f4ac284d.png)
4. 版本回退
我们在master上叠加两个新版本进行测试:
![](https://img.haomeiwen.com/i8900795/f2864101dea16252.png)
如果我们想回退到天晴了这个版本, 可以右键选择重置到这次提交:
![](https://img.haomeiwen.com/i8900795/f612c1a14d8ae8e2.png)
然后有三种重置方式供我们选择:
![](https://img.haomeiwen.com/i8900795/4b5da663967c2b0d.png)
软合并和混合合并都不会删除开窗版本的内容, 都是变成天晴了版本提交之后开窗版本提交之前的状态. 不同的是, 软合并会将这些修改添加到已暂存区, 而混合合并则还在未暂存区.
强行合并则是丢弃整个开窗版本, 项目文件夹内容变成天晴了这个版本.
暂存文件
我们提交的时候, 只会将暂存文件的内容进行提交记录. 所以我们修改了内容之后, 要确保想要提交的内容放到已暂存文件, 否则提交的时候不会记录该修改内容.
软合并
不会删除开窗版本的内容, 只是将开窗版本的修改置为未提交状态
![](https://img.haomeiwen.com/i8900795/291af8e3a87b0ad6.png)
![](https://img.haomeiwen.com/i8900795/a83c86ff621d73b8.png)
修改的内容被默认添加到已暂存文件区:
![](https://img.haomeiwen.com/i8900795/6490f66b4d122610.png)
混合合并
和软合并唯一不同点是, 修改的内容还在为暂存文件区. 这时如果我们点击选中未暂存文件, 则会被添加到已暂存文件, 这就和软合并一样了.
![](https://img.haomeiwen.com/i8900795/4608c4df45b24630.png)
强行合并
丢弃开窗版本, 内容变成天晴了版本内容:
![](https://img.haomeiwen.com/i8900795/5164e6e5515d27ac.png)
![](https://img.haomeiwen.com/i8900795/dad8a573c5c48f88.png)
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):
![](https://img.haomeiwen.com/i8900795/63a4a04cea868134.png)
选择public表示公开, 任何人可见; 选择private则自己可见, 也可设置成指定人可见. 一般项目都会带有一个自述文件(README.md)用于描述项目以及使用方法等.
![](https://img.haomeiwen.com/i8900795/63ee4f55bd48b6f0.png)
点击Upload files以上传代码文件:
![](https://img.haomeiwen.com/i8900795/7056c4c47d030c3c.png)
直接拖动文件到窗口或者点击选择上传:
![](https://img.haomeiwen.com/i8900795/6297969206cfdfc7.png)
例子中文件内容为一个HelloWord文件夹, 然后里面有个版本记录的文本文件:
![](https://img.haomeiwen.com/i8900795/1cfdaacb93893f00.png)
因为初版内容相对于原始空内容来说也是一种修改, 所以上传完成后GitHub会提示我们提交这个修改:
![](https://img.haomeiwen.com/i8900795/0741843028130e3d.png)
然后返回项目首页, 发现这个文件夹已经上传成功了:
![](https://img.haomeiwen.com/i8900795/5328fb6c5b37396f.png)
2. 下载 (Pull)
点击克隆或者下载按钮, 可以直接下载压缩文件ZIP:
![](https://img.haomeiwen.com/i8900795/939ef61ee65538e4.png)
解压后就会看到我们的HelloWord文件以及README文件:
![](https://img.haomeiwen.com/i8900795/32748d6b0da62617.png)
3. GitHub客户端
如果要克隆远程仓库到本地, 在本地修改内容后push同步到远程仓库, 那么最佳方案就是下载GitHub客户端.
下载地址: https://desktop.github.com/
克隆远程仓库到本地
克隆远程仓库到本地. 点击克隆和下载按钮, 选择Open in Desktop进行克隆:
![](https://img.haomeiwen.com/i8900795/ee4c406e7828f03d.png)
克隆完成后就在我们指定的本地文件夹看到HelloWord文件夹和README文件了:
![](https://img.haomeiwen.com/i8900795/cd7d1b902fa4584a.png)
push
我们在本地修改README文件:
![](https://img.haomeiwen.com/i8900795/ae31ec19dd842be9.png)
然后GitHub客户端有提示有新的修改:
![](https://img.haomeiwen.com/i8900795/5f7287b4e7b1b107.png)
我们提交这个修改, 备注等外卖. 注意, 此次提交仅记录在本地, 如果需要同步到远程仓库, 需要进行push推送操作.
点击History版本记录, 将指定版本push到远端. 点击上传箭头:
![](https://img.haomeiwen.com/i8900795/7e3246dcb160ee63.png)
然后我们查看网页端, HelloWord项目已经有更新了:
![](https://img.haomeiwen.com/i8900795/b8c75e9740bae2c8.png)
pull
相反地, 我们在GitHub网页 (远程仓库) 修改内容, 然后拉取同步到本地.
![](https://img.haomeiwen.com/i8900795/d45658f41c3d8246.png)
![](https://img.haomeiwen.com/i8900795/45d9dc502db48495.png)
![](https://img.haomeiwen.com/i8900795/4c47298859137e46.png)
然后打开GitHub客户端, 刷新一下:
![](https://img.haomeiwen.com/i8900795/97d7cca3c9802def.png)
然后我们看到远端有一个新版本:
![](https://img.haomeiwen.com/i8900795/c86916e23811821e.png)
点击Pull origin拉取之. 然后History就多了个版本记录:
![](https://img.haomeiwen.com/i8900795/c3af2676da96fbfd.png)
同时本地文件也被更新了:
![](https://img.haomeiwen.com/i8900795/99446dc3aee85bc1.png)
网友评论