资讯详情

Git - 维护项目

Git - 维护项目

  • 在主题分支中工作
  • 电子邮件应用修补程序
    • 补丁补丁和应用
    • 应用修补程序am
  • 签署远程分支
  • 确定介绍的内容
  • 整合贡献
    • 合并工作流
    • 合并工作流量大
  • 标记你的版本
  • 生成内部版本号
  • 准备版本
  • 简短日志
除了知道如何有效地为项目做出贡献之外,你还可能需要知道如何维护一个项目。这可以包括通过您生成并通过电子邮件发送给您的维修程序的接受和应用程序,或将变更集成到远程分支中作为远程添加到项目中的存储库。无论您是维护标准存储库,还是希望通过验证或批准补丁提供帮助,您都需要知道如何以最清晰、最长期、最可持续的方式接受其他贡献者的工作。format-patch

在主题分支中工作

当你考虑整合新工作时,试试主题分支是个好主意 - 一个专门为尝试新工作而制作的临时分支。这样,补丁就可以很容易地单独调整,如果它不起作用,请保留它,直到你有时间回来。如果你根据你想尝试的工作主题创建一个简单的分支名称,比如或者类似的描述性名称,如果你必须放弃一段时间,然后回来,你可以很容易地记住它。Git 项目的维护人员也倾向于命名这些分支的空间 — 例如 ,其中 是对工作做出贡献的人的缩写。如您所料,您可以根据您的分支创建分支,如下所示:ruby_clientsc/ruby_clientscmaster

$ git branch sc/ruby_client master 

或者,如果您想立即切换它,您可以使用以下选项:checkout -b

$ git checkout -b sc/ruby_client master 

现在,您已经准备好将收到的贡献添加到主题分支中,并确定是否将其合并到长期分支中。

电子邮件应用修补程序

如果您通过电子邮件收到需要集成到项目中的补丁,则需要将补丁应用于主题分支进行评估。通过电子邮件发送的修复程序有两种方法:使用 或 使用 。git applygit am

补丁补丁和应用

假如你从使用 Unix 命令生成修复程序的人收到了修复程序,或者 Unix 命令的某些变体(不推荐使用;请参考下一节)可以使用该命令。假设你在 如果补丁保存在中间,补丁可以用以下方法:git diffdiffgit apply/tmp/patch-ruby-client.patch

$ git apply /tmp/patch-ruby-client.patch 

修改工作目录中的文件。尽管它比补丁更偏执,接受的模糊匹配也更少,但这与操作命令应用补丁几乎相同。如果文件添加、删除和重命名以格式描述,它还将处理文件添加、删除和重命名,但事实并非如此。最后,它是一个所有应用程序或所有暂停模型,要么应用所有内容,要么不应用任何东西,但可以部分应用补丁文件,使工作目录处于一种奇怪的状态。 总体上比 保守得多。它不会为您创建提交 - 操作后,您必须暂存并提交手动引入的更改。patch -p1git diffpatchgit applypatchgit applypatch

您还可以使用来查看补丁是否完全应用,然后再尝试实际应用它 - 可使用补丁操作:git applygit apply --check

$ git apply --check 0001-see-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply 

如果没有输出,维修程序应干净使用。如果检查失败,命令将以非零状态退出,因此您可以根据需要在脚本中使用。

应用修补程序am

若贡献者是 Git 如果用户足够使用该命令生成修复程序,您的工作将更容易,因为修复程序包含作者信息和提交信息。如果可以的话,鼓励你的贡献者使用它,而不是为你生成补丁。你应该只需要留下补丁。format-patchformat-patchdiffgit apply

要应用 请使用生成的修复程序(该命令的名称与从邮箱应用一系列修复程序相同)。从技术上讲,它是读取的mbox构建文件,mbox将一个或多个电子邮件存储在存储在文本文件中的简单纯文本格式。它看起来像这样:format-patchgit amamgit am

From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith <xq.com> Date: Sun, 6 Apr 2008 10:17:23 -0700 Subject: [PATCH 1/2] Add limit to log function  Limit log functionality to the first 20 

这是你在上一节看到的命令输出的开始;它还表示有效mbox电子邮件格式。如果有人通过电子邮件向您发送正确使用的补丁,您将其下载为mbox然后你可以指向格式mbox它将开始应用它看到的所有补丁。如果您可以运行邮件客户端 mbox 将多封电子邮件保存在格式中,可修复程序系列可以保存在一个文件中,然后一次应用一个。git format-patchgit send-emailgit amgit am

但是,如果有人将生成的修复程序文件上传到票据系统或类似系统,文件可以保存在本地,然后将保存在磁盘上的文件传递给应用程序:git format-patchgit am

$ git am 0001-limit-log-function.patch Applying: Add limit to log function 

您可以看到它是干净的应用程序,并自动为您创建一个新的提交。作者的信息来自电子邮件和标题,提交的信息来自电子邮件和文本(在补丁之前)。例如,如果从上面 mbox 本修复程序应用于示例中,生成的提交如下:FromDateSubject

$ git log --pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 Author:     Jessica Smith <xq.com> AuthorDate: Sun Apr 6 10:17:23 2008 -0700 Commit:     Scott Chacon <xqcom> ComitDate: Thu Apr 9 09:19:06 2009 -0700

   Add limit to log function

   Limit log functionality to the first 20

该信息指示应用修补程序的人员及其应用时间。该信息是最初创建修补程序的个人以及最初创建修补程序的时间。CommitAuthor

但是,该修补程序可能无法干净地应用。也许您的主分支与构建补丁的分支相差太远,或者补丁依赖于您尚未应用的另一个补丁。在这种情况下,该过程将失败并询问您要执行的操作:git am

$ git am 0001-see-if-this-helps-the-gem.patch
Applying: See if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Patch failed at 0001.
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".

此命令将冲突标记放在它有问题的任何文件中,这与冲突的合并或衍合操作非常相似。解决此问题的方式大致相同 — 编辑文件以解决冲突,暂存新文件,然后运行以继续执行下一个修补程序:git am --resolved

$ (fix the file)
$ git add ticgit.gemspec
$ git am --resolved
Applying: See if this helps the gem

如果你想让 Git 尝试更智能地解决冲突,你可以向它传递一个选项,这使得 Git 尝试三向合并。默认情况下,此选项不处于打开状态,因为如果修补程序所说的基于的提交不在存储库中,则此选项不起作用。如果您确实有该提交 - 如果补丁基于公共提交 - 那么该选项通常更聪明地应用冲突的补丁:-3-3

$ git am -3 0001-see-if-this-helps-the-gem.patch
Applying: See if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.

在这种情况下,如果没有该选项,补丁将被视为冲突。由于使用了该选项,因此请干净利落地应用补丁。-3-3

如果要从 mbox 应用多个修补程序,则还可以在交互模式下运行该命令,该命令会在找到的每个修补程序时停止,并询问是否要应用它:am

$ git am -3 -i mbox
Commit Body is:
--------------------------
See if this helps the gem
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all

如果您保存了许多补丁,这很好,因为如果您不记得补丁是什么,则可以先查看补丁,或者如果您已经这样做了,则可以不应用补丁。

当应用主题的所有修补程序并将其提交到分支中时,您可以选择是否以及如何将它们集成到运行时间较长的分支中。

签出远程分支

如果您的贡献来自 Git 用户,该用户设置了自己的存储库,将许多更改推送到其中,然后向您发送存储库的 URL 和更改所在的远程分支的名称,则可以将它们添加为远程站点并在本地进行合并。

例如,如果 Jessica 向您发送一封电子邮件,说她在存储库的分支中有一个很棒的新功能,您可以通过添加远程数据库并在本地签出该分支来测试它:ruby-client

$ git remote add jessica git://github.com/jessica/myproject.git
$ git fetch jessica
$ git checkout -b rubyclient jessica/ruby-client

如果她稍后再次向您发送电子邮件,其中包含另一个包含其他强大功能的分支,您可以直接这样做,因为您已经进行了远程设置。fetchcheckout

如果您始终如一地与某人合作,这将非常有用。如果有人偶尔只有一个补丁可以贡献,那么通过电子邮件接受它可能比要求每个人都运行自己的服务器并且必须不断添加和删除遥控器以获得一些补丁更省时。你也不太可能想要拥有数百个遥控器,每个遥控器都只为只贡献一两个补丁的人使用。但是,脚本和托管服务可能会使这变得更容易 - 这在很大程度上取决于您如何开发和贡献者如何开发。

此方法的另一个优点是,您还可以获取提交的历史记录。虽然您可能有合法的合并问题,但您知道他们的工作在您的历史中的位置;适当的三向合并是默认设置,而不必提供并希望补丁是从您有权访问的公共提交生成的。-3

如果您没有始终如一地与某人合作,但仍希望以这种方式从他们那里拉取,则可以向该命令提供远程存储库的 URL。这将执行一次性拉取,并且不会将 URL 另存为远程引用:git pull

$ git pull https://github.com/onetimeguy/project
From https://github.com/onetimeguy/project
 * branch            HEAD       -> FETCH_HEAD
Merge made by the 'recursive' strategy.

确定引入的内容

现在,您有一个包含贡献工作的主题分支。此时,您可以确定要使用它做什么。本节将重新访问几个命令,以便您可以了解如何使用它们来查看在将其合并到主分支中时将要引入的内容。

查看此分支中但不在分支中的所有提交通常很有帮助。您可以通过在分支名称前添加该选项来排除分支中的提交。这与我们之前使用的格式相同。例如,如果您的贡献者向您发送了两个补丁,并且您创建了一个调用并应用这些补丁的分支,则可以运行以下命令:mastermaster–notmaster…contribcontrib

$ git log contrib --not master
commit 5b6235bd297351589efc4d73316f0a68d484f118
Author: Scott Chacon <xq.com>
Date:   Fri Oct 24 09:53:59 2021 -0700

    See if this helps the gem

commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
Author: Scott Chacon <xqcom>
Date:   Mon Oct 22 19:38:36 2021 -0700

    Update gemspec to hopefully work better

要查看每个提交引入了哪些更改,请记住,您可以将该选项传递给,它将附加引入到每个提交的差异。-pgit log

要查看将此主题分支与另一个分支合并会发生什么情况的完整差异,您可能需要使用一个奇怪的技巧来获得正确的结果。你可能会想运行这个:

$ git diff master

此命令为您提供了差异,但它可能会产生误导。如果您的分支自您从中创建主题分支以来一直在向前移动,那么您将获得看似奇怪的结果。发生这种情况是因为 Git 直接比较您所在的主题分支的上次提交的快照和分支上上次提交的快照。例如,如果您在分支上的文件中添加了一行,则快照的直接比较将看起来像主题分支将删除该行。mastermastermaster

如果 是您的主题分支的直接祖先,这不是问题;但是,如果两个历史记录已经分化,则差异将看起来像是您在主题分支中添加所有新内容并删除分支特有的所有内容。mastermaster

您真正希望看到的是添加到主题分支的更改 — 如果将此分支与 合并,您将引入的工作。您可以通过让 Git 将主题分支上的最后一个提交与分支中的第一个共同祖先进行比较来实现此目的。mastermaster

从技术上讲,您可以通过显式找出共同的祖先,然后对其运行diff来做到这一点:

$ git merge-base contrib master
36c7dba2c95e6bbb78dfa822519ecfec6e1ca649
$ git diff 36c7db

或者,更简洁地说:

$ git diff $(git merge-base contrib master)

但是,这两种方法都不是特别方便,因此 Git 提供了另一个用于执行相同操作的简写:三点语法。在命令的上下文中,您可以在另一个分支之后放置三个句点,以便在您正在使用的分支的最后一次提交与其与另一个分支的共同祖先之间执行一个操作:git diffdiff

$ git diff master...contrib

此命令仅显示当前主题分支自 其与 的共同祖先以来引入的工作。这是一个非常有用的语法来记住。master

整合贡献的工作

当您的主题分支中的所有工作都准备好集成到一个更主流的分支中时,问题是如何做到这一点。此外,您希望使用什么整体工作流程来维护您的项目?您有多种选择,因此我们将介绍其中的一些。

合并工作流

一个基本的工作流程是简单地将所有工作直接合并到您的分支中。在这种情况下,您有一个包含基本稳定代码的分支。当您在主题分支中完成工作,或者其他人已经贡献并已验证的工作时,您可以将其合并到主分支中,删除刚刚合并的主题分支,然后重复。mastermaster

例如,如果我们有一个存储库,其中包含两个分支中的工作,该存储库名为“历史记录”,具有多个主题分支,并且我们合并后跟 ,则您的历史记录最终将看起来像“主题分支合并之后”。ruby_clientphp_clientruby_clientphp_client 在这里插入图片描述 这可能是最简单的工作流程,但如果您正在处理更大或更稳定的项目,并且您希望真正小心引入的内容,则可能会有问题。

如果您有更重要的项目,则可能需要使用两阶段合并周期。在此方案中,您有两个长时间运行的分支 和 ,您确定仅当剪切非常稳定的版本并且所有新代码都集成到分支中时才会更新。您可以定期将这两个分支推送到公共存储库。每次有新的主题分支要合并时(在主题分支合并之前),您就将其合并到(主题分支合并之后);然后,当您标记发布时,您将快进到现在稳定的分支所在的位置(在项目发布之后)。masterdevelopmasterdevelopdevelopmasterdevelop

这样,当人们克隆项目的存储库时,他们可以签出以构建最新的稳定版本并轻松保持最新状态,也可以签出 ,这是更前沿的内容。您还可以通过一个分支来扩展此概念,其中所有工作都合并在一起。然后,当该分支上的代码库稳定并通过测试时,将其合并到一个分支中;当它在一段时间内证明自己稳定时,你就会快进你的分支。masterdevelopintegratedevelopmaster

大型合并工作流

Git 项目有四个长期运行的分支:、、和(以前称为“pu”—建议的更新)用于新工作和维护向后移植。当贡献者引入新工作时,它会以类似于我们描述的方式将其收集到维护者存储库的主题分支中(请参阅管理一系列复杂的并行贡献主题分支)。此时,将评估主题以确定它们是否安全并准备好使用,或者它们是否需要更多工作。如果它们是安全的,它们就会合并到 中,并且该分支被推上去,以便每个人都可以尝试集成在一起的主题。masternextseenmaintnext 如果主题仍然需要工作,则会将它们合并到其中。当确定它们完全稳定时,主题将重新合并到 .然后从 重建 和 分支。这意味着几乎总是向前移动,偶尔重新定位,并且更频繁地重新定位:seenmasternextseenmastermasternextseen

标记您的版本

当您决定剪切某个版本时,您可能希望分配一个标记,以便将来可以随时重新创建该版本。您可以创建一个新标记,如 Git 基础知识中所述。如果您决定以维护者的身份对标记进行签名,则标记可能如下所示:

$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Scott Chacon <xq.com>"
1024-bit DSA key, ID F721C45A, created 2021-02-09

如果您确实对标签进行了签名,则可能会遇到分发用于对标签进行签名的公有 PGP 密钥的问题。Git 项目的维护者已通过将他们的公钥作为 blob 包含在存储库中,然后添加一个直接指向该内容的标记来解决此问题。为此,您可以通过运行以下命令来确定所需的密钥:gpg --list-keys

$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub   1024D/F721C45A 2009-02-09 [expires: 2019-02-09]
uid                  Scott Chacon <xq.com>
sub   2048g/45D02282 2009-02-09 [expires: 2019-02-09]

然后,可以通过导出密钥并通过 管道将密钥直接导入 Git 数据库,这会将包含这些内容的新 blob 写入 Git,并返回 blob 的 SHA-1:git hash-object

$ gpg -a --export F721C45A | git hash-object -w --stdin
659ef797d181633c87ec71ac3f9ba29fe5775b92

现在,您已经在 Git 中拥有了密钥的内容,您可以通过指定命令为您提供的新 SHA-1 值来创建一个直接指向该密钥的标记:hash-object

$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92

如果运行 ,则该标记将与所有人共享。如果有人想要验证标记,他们可以直接导入 PGP 密钥,方法是直接从数据库中拉出 blob 并将其导入 GPG:git push --tagsmaintainer-pgp-pub

$ git show maintainer-pgp-pub | gpg --import

他们可以使用该密钥来验证您的所有签名标签。此外,如果您在标记消息中包含说明,则运行将允许您向最终用户提供有关标记验证的更具体说明。git show

生成内部版本号

因为 Git 没有像 ‘v123’ 这样的单调递增数字,或者与每次提交一起使用的等效数字,所以如果你想有一个人类可读的名称来配合提交,你可以在提交上运行。作为响应,Git 会生成一个字符串,其中包含比该提交更早的最新标记的名称,后跟自该标记以来的提交数,最后是所描述的提交的部分 SHA-1 值(前缀为字母“g”,表示 Git):git describe

$ git describe master
v1.6.2-rc1-20-g8c5b85c

这样,您可以导出快照或构建,并将其命名为人们可以理解的名称。事实上,如果你从 Git 存储库克隆的源代码构建 Git,会给你一些类似的东西。如果你描述的是你直接标记的提交,它只给你一个标记名称。git --version

默认情况下,该命令需要带注释的标签(使用 或 标志创建的标签);如果还想利用轻量级(非带注释)标记,请将该选项添加到命令中。您还可以将此字符串用作 or 命令的目标,尽管它依赖于末尾的缩写 SHA-1 值,因此它可能不会永远有效。例如,Linux 内核最近从 8 个字符跳到 10 个字符,以确保 SHA-1 对象的唯一性,因此较旧的输出名称无效。git describe-a-s--tagsgit checkoutgit showgit describe

准备版本

现在,您想要发布一个内部版本。您要做的一件事是为那些不使用 Git 的可怜灵魂创建代码最新快照的存档。执行此操作的命令是:git archive

$ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
$ ls *.tar.gz
v1.6.2-rc1-20-g8c5b85c.tar.gz

如果有人打开该压缩包,他们将在目录下获得项目的最新快照。您也可以以大致相同的方式创建 zip 存档,但通过将选项传递给 :project–format=zipgit archive

$ git archive master --prefix='project/' --format=zip > `git describe master`.zip

您现在拥有了一个不错的压缩包和项目版本的zip存档,您可以将其上传到您的网站或通过电子邮件发送给人们。

简短日志

现在是时候通过电子邮件发送您的邮件列表,其中包含想知道您的项目中正在发生的事情的人。使用该命令是快速获取自上次发布或电子邮件以来添加到项目中的内容的一种很好的方法。它总结了您为其提供的范围内的所有提交;例如,如果您的最后一个版本名为 v1.0.1,则下面为您提供了自上次版本以来所有提交的摘要:git shortlog

$ git shortlog --no-merges master --not v1.0.1
Chris Wanstrath (6):
      Add support for annotated tags to Grit::Tag
      Add packed-refs annotated tag support.
      Add Grit::Commit#to_patch
      Update version and History.txt
      Remove stray `puts`
      Make ls_tree ignore nils

Tom Preston-Werner (4):
      fix dates in history
      dynamic version method
      Version bump to 1.0.2
      Regenerated gemspec for version 1.0.2

您将获得自 v1.0.1 以来所有提交的干净摘要,按作者分组,您可以通过电子邮件将其发送到您的列表。

标签: da4y变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台