回滚、还原、重置和变基

  • 关键词: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(舍弃我自己的工作)