目录搜索
GuidesgitattributesgiteverydaygitglossarygitignoregitmodulesgitrevisionsgittutorialgitworkflowsAdministrationgit archivegit bundlegit cleangit filter-branchgit fsckgit gcgit instawebgit reflogBasic Snapshottinggit addgit commitgit diffgit mvgit resetgit rmgit statusBranching and Merginggit branchgit checkoutgit loggit mergegit mergetoolgit stashgit tagDebugginggit bisectgit blamegit grepEmailgit amgit format-patchgit request-pullgit send-emailExternal Systemsgit fast-importgit svnGetting and Creating Projectsgit clonegit initGitgit annotategit archimportgit bisect-lk2009git check-attrgit check-mailmapgit check-ref-formatgit checkout-indexgit cherrygit citoolgit columngit credentialgit credential-cachegit credential-storegit cvsexportcommitgit cvsimportgit cvsservergit diff-filesgit diff-treegit difftoolgit fast-exportgit fetch-packgit fmt-merge-msggit get-tar-commit-idgit guigit http-backendgit http-fetchgit http-pushgit imap-sendgit index-packgit interpret-trailersgit ls-remotegit ls-treegit mailinfogit mailsplitgit merge-filegit merge-indexgit merge-one-filegit merge-treegit mktaggit mktreegit name-revgit notesgit p4git pack-objectsgit pack-redundantgit pack-refsgit parse-remotegit patch-idgit prunegit prune-packedgit quiltimportgit receive-packgit remote-extgit remote-fdgit remote-testgitgit repackgit replacegit rereregit send-packgit sh-i18ngit sh-setupgit shellgit show-branchgit show-indexgit stripspacegit unpack-filegit unpack-objectsgit upload-archivegit upload-packgit vargit verify-commitgit verify-taggit whatchangedgit worktreeInspection and Comparisongit describegit shortloggit showMiscellaneousapi credentialsapi indexgitcligitcore tutorialgitcredentialsgitcvs migrationgitdiffcoregithooksgitkgitnamespacesgitremote helpersgitrepository layoutgitsubmodulesgittutorial 2gitwebgitweb.confpack formatUser ManualPatchinggit applygit cherry-pickgit rebasegit revertPlumbing Commandsgit cat-filegit check-ignoregit commit-treegit count-objectsgit diff-indexgit for-each-refgit hash-objectgit ls-filesgit merge-basegit read-treegit rev-listgit rev-parsegit show-refgit symbolic-refgit update-indexgit update-refgit verify-packgit write-treeServer Admingit daemongit update-server-infoSetup and Configgitgit configgit helpSharing and Updating Projectsgit fetchgit pullgit pushgit remotegit submodule
文字

名称

gitworkflows  - 使用 Git 推荐的工作流程概述

概要

git *

描述

本文档试图写下并激励一些用于git.git其自身的工作流元素。一般来说,许多想法都适用,尽管涉及较少人员的较小项目很少需要完整的工作流程。

我们制定了一套rules快速参考,试图激励他们每个人。不要总是从字面上理解它们; 你应该重视你的行为的好的理由比manpages更高,比如这个。

单独更改

作为一般规则,您应该尝试将您的更改分成小逻辑步骤,并提交它们中的每一个。它们应该是一致的,独立于任何后续的提交,通过测试套件等,这使得评审过程变得更加容易,并且历史对以后的检查和分析更有用,例如使用 git-blame [1] 和 git -bisect [1] 。

要做到这一点,请尝试从一开始就将工作分成几个小步骤。把一些承诺压在一起比把一个大承诺分成几个承诺总是更容易。不要害怕在这个过程中做出太小或不完美的步骤。您可以稍后返回git rebase --interactive并在发布之前编辑提交。您可以使用git stash save --keep-index独立于其他未提交的更改来运行测试套件; 请参阅 git-stash [1] 的 EXAMPLES 部分。

管理分支

有两个主要的工具可以用来包含另一个分支的变化: git-merge [1] 和 git-cherry-pick [1] 。

合并有很多优点,所以我们试图通过合并来解决尽可能多的问题。Merging upwards仍然偶尔有用; 例如,请参阅下面的“向上合并”。

最重要的是,在分支层面合并工作,而 Merging upwards 在提交层面工作。这意味着合并可以平等地承担1,10或者1000次提交的变更,这意味着工作流程对于大量贡献者(和贡献)的扩展要好得多。合并也更容易理解,因为合并提交是一个“承诺”,其中包含所有父母的所有更改。

当然有一个折衷:合并需要更仔细的分支管理。以下小节讨论重要的一点。

Graduation

由于特定功能从实验到稳定,它也是软件相应分支之间的“graduates”。git.git使用以下内容integration branches

  • maint 跟踪应该进入下一个“维护版本”的提交,即更新最后发布的稳定版本;

  • master 跟踪应该进入下一个版本的提交;

  • next 旨在作为测试主题的测试分支,用于测试 master 的稳定性。第四个官方分支的用法稍有不同:

  • pu (提议的更新)是一个尚未准备好包含的事物的集成分支(请参阅下面的“集成分支”)。

四个分支中的每一个通常都是它上面的直系子代。

从概念上讲,功能进入一个不稳定的分支(通常nextpu),“graduates” 进入master下一个版本,一旦被认为足够稳定。

向上合并

上面讨论的“向下的分级”不能通过实际向下合并来完成,但是,因为这会将all不稳定分支上的变化合并到稳定分支中。因此如下:

规则:向上合并

始终将修复提交给需要它们的最早受支持的分支。然后(定期)将集成分支向上并入彼此。

这提供了一个非常受控制的修复流程。如果你注意到你已经应用了一个修补程序,例如master它也是必需的maint,你需要向下选择它(使用git-cherry-pick [1])。这会发生几次,没有什么可担心的,除非你经常这样做。

topic branches

任何不平凡的功能都需要多个补丁才能实现,并且可能会在其生命周期中得到额外的错误修复或改进。

在集成分支上直接提交所有内容会导致很多问题:错误提交不能撤消,因此必须逐一恢复,这会导致当您忘记恢复一组更改的一部分时,会产生令人困惑的历史记录和更多的错误可能性。并行工作会混淆变化,进一步造成混乱。

使用 “topic branches” 解决了这些问题。这个名字很自我解释,有一个警告来自上面的“合并向上”规则:

规则:主题分支

为每个主题(功能,错误修正...)建立一个支路。把它关在最早的整合分支上,你最终想要将它合并到它。

很多事情可以很自然地完成:

  • 要将功能/错误修复引入集成分支,只需将其合并即可。如果话题进一步发展,再次合并。(请注意,您不一定必须先将其合并到最早的集成分支,例如,您可以先将一个错误修正合并到next该测试中,给它一些测试时间,并maint在知道它稳定时合并。)

  • 如果您发现需要分支的新功能other才能继续处理主题,请合并othertopic。(但是,不要只是“习惯性地”这样做,见下文。)

  • 如果你发现你错误的分支,并想“移回”时间,请使用 git-rebase [1]。注意最后一点与另外两个分支冲突:在其他地方合并过的主题不应该重新分配。我们应该指出,“习惯性地”(定期没有真正的理由)将一个整合分支合并到你的主题中 - 并且通过扩展将任何上游合并到任何下游的任何东西上规则:仅在定义明确的点处合并到下游不合并到下游,除非有一个很好的理由:上游 API 更改会影响您的分支; 你的分支不再合并到上游干净; 等等。另外,被合并的主题突然包含多个单独的(完全分离的)更改。由此产生的许多小规模合并将大大混乱历史。任何后来调查文件历史的人都必须查明合并是否影响了开发中的主题。上游甚至可能会无意中合并成一个“更稳定”的分支。等等。缩小整合如果你按照最后一段,现在你会有很多小的主题分支,偶尔也会想知道它们是如何相互作用的。也许合并它们的结果甚至不起作用?但另一方面,我们希望避免将它们合并到“稳定”的任何位置,因为这样的合并不能轻易地被撤消。当然,解决方案是进行可以撤消的合并:合并到一个丢弃分支中。规则:丢弃集成分支为了测试几个主题的交互,将它们合并到一个丢弃分支中。

  • git.git有一个正式的抛弃式集成分支称为pu分支管理,用于释放假设您正在使用上面讨论的合并方法,当您发布项目时,您需要执行一些额外的分支管理工作。从master分支创建功能发布,因为master跟踪应该进入下一个功能发布的提交。该master分支应该是一个超集maint。如果这个条件不成立,那么maint包含一些不包含的提交master。这些提交所代表的修复程序因此不会包含在您的功能版本中。要验证它master确实是超集maint,请使用git log:配方:验证主控是主线的超集

  • git log master..maint这个命令不应该列出任何提交。否则,请检查master并合并maint到它中。现在可以继续创建功能版本。将标签应用于master指示发布版本的提示:配方:发布标签git tag -s -m "Git X.Y.Z" vX.Y.Z master您需要将新标签推送到公共Git服务器(请参阅下面的“分布式工作流程”)。这使标签可供其他人跟踪您的项目。推送也可以触发更新后的挂钩来执行与版本相关的项目,例如构建发布 tarball 和预先格式化的文档页面。类似地,对于维护版本,maint跟踪要发布的提交。因此,在上述步骤中只需标记和推送,maint而不是master。维护分支管理功能发布后功能发布后,您需要管理维护分支机构。首先,如果您希望继续发布针对最近发布的功能发布的维护修复,那么您必须创建另一个分支来跟踪提交对于以前 release.To 做到这一点,当前维护分支被复制到与以前的版本版本号命名的另一个分支(如 MAINT-XY(Z-1 ),其中 XYZ 是当前版本). Recipe:复制 MAINT

  • git branch maint-X.Y.(Z-1) maintmaint分支应该现在可以快速转发到新发布的代码,以便可以为当前版本追踪维护修复:配方:将更新维护更新到新版本

  • git checkout maint

  • git merge --ff-only master如果合并由于不是快进而失败,那么可能会maint在功能发布中错过一些修复。如果分支的内容按上一节所述进行验证,则不会发生这种情况。功能发布后的 next 和 pu 的分支管理功能发布后,集成分支next可以选择性地从master使用存活主题的提示进行回卷和重新构建上next:食谱:倒带和重建

  • git checkout next

  • git reset --hard master

  • git merge ai/topic_in_next1

  • git merge ai/topic_in_next2

这样做的好处是,历史next将是清洁的。例如,合并到一些主题next可能最初看起来很有前途,但后来发现不合要求或不成熟。在这种情况下,这个话题被撤销了,next但事实仍然存在于它曾经合并和恢复的历史中。通过重新创建next,您可以将这些主题的另一个化身作为一个干净的平台重试,而功能发布是历史上的一个很好的一点。

如果你这样做,那么你应该公布一个公告,表明next被重新卷绕和重建。

可以遵循相同的倒带和重建过程pupu如上所述,公告是没有必要的,因为它是一个不计分支。

分布式工作流程

在最后一节之后,您应该知道如何管理主题。总的来说,你不会是唯一一个从事这个项目的人,所以你将不得不分享你的工作。

粗略地说,有两个重要的工作流程:合并和补丁。重要的区别是合并工作流可以传播完整的历史记录,包括合并,而修补程序则不能。这两个工作流程可以并行使用:在 git.git之中,只有子系统维护人员使用合并工作流程,而其他人都发送补丁。

请注意,维护者可能会施加限制,例如“拒绝签名”要求,所有提交包含的提交/补丁都必须遵守。请参阅您的项目文档以获取更多信息。

合并工作流程

合并工作流程通过复制上游和下游之间的分支来工作。上游可以将贡献合并到官方历史中; 下游根据他们的正式历史工作。

有三个主要工具可以用于此:

  • git-push [1] 将您的分支机构复制到远程存储库,通常是所有相关方都可以读取的存储库;

  • git-fetch [1] 将远程分支复制到您的存储库; 和

  • git-pull [1] 可以一次完成提取和合并。请注意最后一点。不要not使用git pull,除非你真的想合并远程 branch.Getting 改变了容易:配方:推/拉:发布分支/主题git push <remote> <branch>和告诉大家,在那里他们可以获取from.You仍然要告诉其他人的手段,如邮件。(Git提供 git-request-pull [1] 向上游维护人员发送预格式化的pull请求以简化此任务。)如果您只想获取集成分支的最新副本,保持最新也很容易:配方:推/拉:保持最新使用git fetch <remote>git remote update以保持最新。然后简单地将您的主题分支从稳定的遥控器中分离出来,如前所述。如果您是维护人员并想要将其他人的主题分支合并到集成分支,他们通常会通过邮件发送请求。这样的请求看起来像请从 <url> <branch> 拉出来,在这种情况下,git pull可以一次完成提取和合并,如下所示.Recipe:推/拉:合并远程主题git pull <url> <branch>,偶尔维护者在尝试时可能会遇到合并冲突从下游拉动变化。在这种情况下,他可以要求下游进行合并,并自己解决冲突(也许他们会更好地知道如何解决冲突)。这是下游罕见的情况之一should从上游合并。补丁工作流程如果您是以电子邮件的形式向上游发送更改的贡献者,则应像往常一样使用主题分支(请参阅上文)。然后使用git-format-patch [1]生成相应的电子邮件(强烈推荐通过手动格式化它们,因为它使维护者的生活更容易) .Recipe:format-patch / am: 发布分支/主题

  • git format-patch -M upstream..topic 把它们变成预先格式化的补丁文件

  • git send-email --to=<recipient> <patches>

有关更多使用说明,请参阅 git-format-patch [1] 和 git-send-email [1] 手册页。

如果维护人员告诉您,您的修补程序不再适用于当前上游,则必须重新标记您的主题(因为无法进行格式化修补程序合并,所以无法使用合并):

教程: format-patch / am: 使主题保持最新

git pull --rebase <url> <branch>

然后,您可以修复重新绑定期间的冲突。大概你没有发布你的主题,除了通过邮件,所以重新发布它不是问题。

如果您收到这样的补丁系列(作为维护者,或者作为发送给它的邮件列表的读者),将邮件保存到文件,创建新的主题分支并用于git am导入提交:

教程:format-patch / am:导入补丁

git am < patch

值得指出的一个特性是三路合并,如果发生冲突可以提供帮助:git am -3将使用包含在补丁中的索引信息来计算合并基数。有关其他选项,请参阅 git-am [1] 。

上一篇:下一篇: