回滚、还原、重置和变基
- 关键词:Git For Teams – 读书笔记
Part2 在工作流中使用命令
多人团队
作为项目负责人,“我来帮你”应该是你的口头禅。在你希望保持一致的地方,提供详细的指示、模板和自动化的脚本。
- 学习目的:
- 在代码托管系统上设置一个新的项目
- 使用clone下载一个远程仓库
- 使用push将你的变更上传到一个仓库
- 使用fetch刷新远程仓库中的可用分支列表
- 使用pull合并远程仓库中的变更
- 解释使用pull、rebase和merge更新分支带来的影响
1 设置项目
1.1 创建新项目
如今,大多数代码托管系统远远不只是一个能够储存共享仓库的地方。它们还提供了工单系统、基本的工作流优化、项目文档仓库和更多功能。
Github(通常用于开源项目)、Bitbucket(通常用于内部团队和想要免费私有项目托管的小团队)和GitLab(通常用于因为安全原因需要在内部托管代码的中型公司)。
1.2 建立权限管理
需要设置两种权限:谁能够看到这个项目(“读”),以及谁可以提交到这个项目(“写”)。
一般来说,团队项目会有一个称为“项目”(主项目)的单独仓库,和许多包含每个开发者工作的衍生项目。如果你在内部项目中工作,则可以选择让所有人直接在“项目”的仓库中工作;但如果你倾向于维护一个干净的中央仓库,则可以选择让每个开发者在一份派生的“项目”中工作。
1.3 上传项目仓库
git remote –verbose(检查你是否已经设置好一个远程连接)
git remote add nickname project-url(添加一个远程仓库连接)
git remote remove nickname(移除一个远程连接)
git push nickname branch_name(将仓库的本地副本上传到远程服务器)
git push –all nickname(与别人共享所有的本地分支)
1.4 在README中记录项目
2 设置开发者
开发者的参与程度分为以下三个层次:
下载项目的压缩包,再也不回到项目页面
为了保持本地代码最新而克隆项目仓库,但不打算修改项目
为了贡献工作而克隆项目仓库
2.1 消费者
消费者不打算为项目做出贡献。
git clone https:…
git fetch –all(为了更新仓库的本地副本,你需要fetch拉取项目最新的变更)
git branch –all(列出仓库所有分支)
你将会看到两组分支:你的本地分支和远程跟踪分支。
git branch –all –verbose(为了获取每个分支中的更多细节)
git log personal/master(为了查看添加到仓库的master分支上的变更历史记录)
git log –patch personal/master & git diff master personal/master(添加–patch来查看每个提交的更改或使用diff命令查看所有变更的摘要)
以上这个命令会以补丁的格式展示所有变更。寻找被添加(标记为+)或被删除(标记为-)的行。
git checkout personal/master(如果你倾向于签出整个代码库,可以签出分支顶端)
git checkout master(你将会处于分离式HEAD状态。签出master分支以回到其本地副本)
一旦即评审完这些更改,就可以通过变基更新master分支的本地副本,从而添加新的更改:
git rebase personal/master
使用rebase命令可提供一个更干净的图形化历史记录。
git merge personal/master(使用merge命令来更新你的本地分支)
2.2 贡献者
2.3 维护者
可以使用自己的约定来命名远程连接:
git remote add nickname https:….
git remote add personal https:….
git remote rename origin official
3 参与开发
你会参与四种主要活动:完成新提出的更改、保持分支最新、审查提出的更改、以及发布完成的工作。
3.1 构建完美的提交
有两种基本的提交方法:展示思维过程和呈现最终解决方案。
- 优秀的提交对象具有如下特征:
- 只包含相关的代码。没有作用域跃迁,没有“只修复了空白字符的问题”
- 遵从项目的编码标准,包含行内文档
- 大小合适。或许是100行代码。或许是一个大型重构,更改了一个函数名,一致1000行代码受到了影响
- 用最佳的提交说明描述工作
“不论付出什么代价,保证以后我不会因为鬼区太懒而感到懊悔。”
- 你的提交说明应该包含以下内容:
- 使用标准化格式的简略描述(少于60字),以便检索日志
- 一段稍长的解释,说明当前代码为什么有问题,以及为什么你的更改很重要
- 关于更改如何解决手头问题的高层描述
- 概述更改可能产生的副作用
- 所做更改的摘要,以便阅读代码diff时能够确认提交说明。但阅读diff不是用来猜测所发生更改的办法
- 工单编号,或指向源码的引用,提议的更改可以、已经或将要在其中进行讨论
- 谁会受到这个更改的影响(例如针对开发者的优化、或针对用户的改进)
- 列出文档哪些地方需要更新
- 一份好的提交说明应该如下:
git commit
[#321] Stop clipping trainer meta-data on video nodes at small screen size.
-Removes an unnecessary overflow: hidden that was causing some clipping.
Resolves #321
它在精简的提交说明开头用括号包含了工单号,以便以后更容易地读取日志。精简的描述(用于精简日志视图)解释了站点访问者看到的现象。消息的说明解释了用于解决这个问题的技术实现。提交消息的最后一行将会被工单系统捕捉到,并将工单的状态从“进行中”移动到“需要评审”
3.2 保存分支最新
更新项目分支的本地副本:
git checkout master
git pull –rebase=preserve
3.3 评审工作
- 基本过程如下:
- 添加一个到相关仓库的远程连接
- 从那个仓库中获取可用的分支
- 为你想要仔细检查的分支创建一份本地副本
- 将其他分支中你想要的更改并入你的工作
- 将修订后的分支推送回相关的远程仓库
git remote show(远程仓库的精简列表)
git remote show personal(远程仓库personal的全部细节)
git branch –remotes
git checkout –tracking remote_nickname/branch(将一个远程分支复制到你的本地仓库)
git log –oneline remote_nickname/branch & git diff current_branch…remote_nickname/branch(在不创建工作副本的情况下检查一个远程分支)
3.4 合并完成的工作
git checkout master & git pull –rebase=preserve(并入项目分支中的更新)
git checkout 2378-add-test & git rebase master(将一个完成的工单分支合并到一个公共的项目分支)
git checkout master & git merge –no-ff 2378-add-test(最后,将完成的工单分支合并到公共的项目分支)
3.5 解决合并和变基冲突
Git会在任何文件的冲突位置添加下面三行冲突信息:«««<、=======、»»»>。
有时Git会弄错应该放置标记的地方,因此你不应该简单地删除其中一整块区域,或另一块区域。
注意:有一个辅助程序,git-imerge,用于合并两个分支顶端的提交。
如果你想要合并一个分支,并知道其中包含了一个问题的修复,就可以强制Git使用另一个分支来更新你自己的分支:
git checkout branch_to_update & git merge –strategy-option=theirs incoming_branch
3.6 发布工作
在你第一次向指定分支上传你的更改时,需要指明想要使用的远程仓库和分支名。
git push –set–upstream origin branch(将包含提议更改的分支上传至远程仓库)
一旦你在远程仓库建立了这个分支:git push
如果你在分支拥有多个远程仓库:git push remote_nickname
为了将新工作发布到共享分支上:
git checkout master
git pull –rebase=preserve
git checkout 2378-add-test
git rebase master
git merge –no–ff 2378-add-test
git push
git branch –delete 2378-add-test
git push remote_nickname –delete 2378-add-test
4 样例工作流
团队协作情况时,写下每个贡献者和维护者在项目期间需要使用的命令。
4.1 基于冲刺的工作流
每周部署,这会鼓励细粒度的工单并帮助开发者尽快在产品中看到他们的工作。如果一些工单范围较广,它们可能需要在几个“冲刺”中完成。
仓库设置有五种不同类型的分支:开发分支、工单分支、QA分支、主分支和补丁分支。
每周部署工作流中的分支类型 | 分支类型 | 描述 | 基线分支 |
---|---|---|---|
dev | 集成 | 用于放置通过同行评审的代码 | 工单分支 |
ticket#-decriptive-name | 开发 | 用于完成工单中标识的工作 | dev |
qa | 集成 | 用于每个冲刺结束前的质量保证测试,没有通过QA测试的代码会从这个分支上移除 | dev |
master | 集成 | 用于部署测试全部通过的代码 | qa |
hotfix-ticket#-description | 开发 | 用于为产品中发现的紧急问题开发对策 | master上最新的发布标签 |
- 完成工单时需要的Git命令:
用远程的名称替换origin,用工单分支的名称替换1234-new_ticket_branch。
git checkout dev
git pull –rebase=preserve origin dev
git checkout -b 1234-new_ticket_branch
完成工作
git add –all
git commit
在共享工作前,确保该分支包含了新的提交:
git checkout dev
git pull –rebase=preserve
git checkout 1234-new_ticket_branch
git rebase dev
最后,与其他人共享新的工作:
git push origin 1234-new_ticket_branch
完成同行评审时需要的Git命令,评审者将工单分支合并到开发分支并从主仓库中删除这个工单分支。
git checkout dev
git pull –rebase=preserve
git checkout 1234-new_ticket_branch
进行评审工作
git merge –no–ff 1234-new_ticket_branch master
git branch –delete 1234-new_ticket_branch
git push –delete 1234-new_ticket_branch
- 质量保证(周一至周二)的工作内容:
- dev分支上运行着自动化的测试集,用于捕获新加入的功能分支中可能引入的任何回归
- dev分支上的所有工作都被合并到qa分支进行测试。开发工作在dev分支上继续
- 在共享文档中创建一份冲刺列表,将并入qa分支的工单中的用户故事复制到文档中
- 所有团队成员有义务完成共享文档中工单列表的测试。可能还需要有人来完成滚动更新的测试
- 为任何没通过质量保证测试的问题创建一个新的工单,使它可以在发布前进行修复、撤销
- 设置qa分支时需要的命令:
git checkout dev
git pull –rebase=preserve
git checkout qa
git merge –no–ff dev
git push
- 移除在发布前没能通过QA的工单时需要的命令:
git log –oneline –grep ticket-number(找到需要撤销的提交)
git revert commit
git revert –mainline 1 merge_commit(理想情况下,应该使用–on–ff合并工作分支,这样会产生一个便于撤销的提交ID)
- 发布日(周三)的工作内容:
- qa分支被合并到master分支并添加标签
- 在线上更新仓库,使用为发布准备的带标签的提交
- 为开发团队下周的工作安排优先级
- 准备部署时需要的命令:
git checkout master
git merge qa
git tag(找到最新的标签,以确定下一个标签的编号)
git tag –annotate -m tag_name
git push –tags
在标签添加后,它通过–annotate参数部署,通过-m参数添加说明。
- 发布日(周四)的工作内容:
- 向社区用户公布前一天上线的更改。多出的一天处理生成环境出现的意外和bug
- 在前一天新建的优先事项列表上继续开发
每次部署都被打上了标签,因此你的第一步是获取全部标签列表,并定位到代码库中当前活跃的版本。
创建补丁分支时需要的命令:
git checkout master
git tag(查看标签列表,确定当前活跃的标签)
git checkout -b hotfix-issue-description tag_name
4.2 没有同行评审的可信开发者
git checkout master
git fetch origin
git diff origin/master
三种方法来合并工作:
git merge origin/master(合并所有工作)
git merge -X ours origin/master(保留我自己的工作)
git merge -X theirs origin/master(舍弃我自己的工作)