测开必备|Git操作
一、版本控制
1.1 什么是“版本控制”?
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 在本书所展示的例子中,我们对保存着软件源代码的文件作版本控制,但实际上,你可以对任何类型的文件进行版本控制。
1.2 版本控制的演进
1.2.1 本地版本控制系统
最简单的方法就是每个版本所在的目录标记修改时间等信息,但是有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。 面对这种问题,大多都是采用某种简单的数据库来记录文件的历次更新差异。工作原理是在硬盘上保存补丁集(文件修订前后的变化);通过应用所有的补丁,可以重新计算出各个版本的文件内容。
1.2.2 集中化的版本控制系统
如何让在不同系统上的开发者协同工作? 集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 这类系统诸如 CVS、Subversion等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
这么做最显而易见的缺点是中央服务器的单点故障。 如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。 如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据——包括项目的整个变更历史,只剩下人们在各自机器上保留的单独快照。 本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。
1.2.3 分布式版本控制系统
针对上述问题,分布式版本控制系统(Distributed Version Control System,简称 DVCS), 在这类系统中,像 Git、Mercurial以及 Darcs 等,客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。
二、三大区域
- 工作区:就是你在电脑里能看到的目录。
- 暂存区:英文叫 stage。一般存放在.git目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
- 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是 Git 的版本库。
- git init - 初始化仓库。
- git add . - 添加文件到暂存区。
- git commit - 将暂存区内容添加到仓库中
- git pull - 下载远程代码
- git push - 推送到远程仓库
- git reset - 回退版本
三、分支管理
分支是为了将修改记录的整体流程分叉保存。分叉后的分支不受其他分支的影响,所以在同一个数据库里可以同时进行多个修改。
1. 分支操作
查看分支: git branch
创建分支: git branch <name>
切换分支: git checkout <name> 或者 git switch <name>
创建+切换分支: git checkout -b <name> 或者 git switch -c <name>
合并某分支到当前分支: git merge <name>
删除分支: git branch -d <name>
提交
2. 分支管理策略
master 分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活; 那在哪干活呢?干活都在 dev 分支上,也就是说, dev 分支是不稳定的,到某个时候,比如1.0版本发布时,再把 dev 分支合并到 master 上,在 master 分支发布1.0版本;你和你的小伙伴们每个人都在dev 分支上干活,每个人都有自己的分支,时不时地往 dev 分支上合并就可以了。 所以,团队合作的分支看起来就像这样:
四、标签管理
1. 标签概念
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。
所以,标签也是版本库的一个快照。
Git 的标签虽然是版本库的快照,但其实它就是指向某个 commit 的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
Git有commit,为什么还要引入tag?
"请把上周一的那个版本打包发布,commit号是6a5819e…"
"一串乱七八糟的数字不好找!"
如果换一个办法:
"请把上周一的那个版本打包发布,版本号是v1.2"
"好的,按照tag v1.2查找commit就行!"
所以,tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
同大多数 VCS 一样,Git 也可以对某一时间点上的版本打上标签。人们在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做。
下面来学习如何列出所有可用的标签,如何新建标签,以及各种不同类型标签之间的差别。
2. 创建标签
[root@Git git]# git tag v1.0
3. 查看已有标签
[root@Git git]# git tag v1.0 [root@Git git]# git tag v1.1 [root@Git git]# git tag v1.0 v1.1
4. 删除标签
[root@Git git]# git tag -d v1.1 Deleted tag ‘v1.1’ (was 91388f0) [root@Git git]# git tag v1.0
5. 查看此版本所修改的内容
[root@Git git]# git show v1.0 commit 91388f0883903ac9014e006611944f6688170ef4 Author: "syaving" <"819044347@qq.com"> Date: Fri Dec 16 02:32:05 2016 +0800 commit dir diff –git a/readme b/readme index 7a3d711..bfecb47 100644 — a/readme +++ b/readme @@ -1,2 +1,3 @@ text hello git +use commit [root@Git git]# git log –oneline 91388f0 commit dir e435fe8 add readme 2525062 add readme
五、修改提交
1. 撤销修改
git checkout -- file e.g: git checkout -- readme.txt
解释:把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况:
- 一种是 readme.txt 自修改后还没有被放到暂存区,撤销修改就回到和版本库一模一样的状态;
- 一种是 readme.txt 已经添加到暂存区后,本地又作了修改,撤销修改就回到添加到暂存区后的状态。 总之,就是让这个文件回到最近一次 git commit 或 git add 时的状态。
2. 删除文件
git rm --cached file # 本地保留cached git commit -m "remove file"
⚠️ 此操作会删除版本库文件。
git rm -f README.md # 本地不保留cached git commit -m "remove README.md"
⚠️ git rm 不是 git add的反操作。
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
git checkout -- test.txt
git checkout 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
3. 版本回滚
方法1 git revert
1、找到你误提交之前的版本号 2、git revert -n 版本号 #这里可能会出现冲突,那么需要手动修改冲突的文件。 3、git commit -m xxxx 提交 4、git push 推送到远程 or强推 git push origin HEAD --force
方法2 git reset
git log git reset --hard 目标版本号 git push -f 此时如果用“git push”会报错,因为本地库HEAD指向的版本比远程库的要旧
4. 常规开发流程
一般而言,我们在开发一个feature的时候,会从当前master拉取最新的代码到本地,然后在此代码基础上开发新feature代码,代码开发好以后,经过测试,会讲此feature的代码合并(merge)到master。
假设开发者当前在自己的分支dev,那么一个完整的pull->push流程操作如下:
1. 将master的代码更新到开发分支(dev) git checkout master git pull git checkout dev git merge master git push -u origin dev 2. 当开发分支(dev)上的代码测试通过,要合并到master分支
git checkout master
git pull
git merge dev
git push -u origin master
5. 恢复误撤销的版本
恢复V2版本的撤销
1. git reset --hard V4 2. git push -f