请通过git send-email将补丁发送到第一封电子邮件中。

3
我目前正在大学的额外课程中完成一个小作业。任务是编写一个完成某项工作x的小程序,并为其编写一个Makefile。我们需要将这两个文件作为纯文本邮件发送给我们的讲师。然后,我们需要对程序进行一些更改,并将更改作为补丁发送到第一封电子邮件中。我们需要再次重复此过程。
类似于这样:
程序1 |--> 更改2的补丁 |--> 更改3的补丁
虽然我在编程方面没有问题,但我不太明白如何通过git send-email来实现这一点。对于初学者,详细解释这个过程将非常受益。

1
这个问题的描述太宽泛了。你具体在哪个环节遇到了困难?你是否熟悉使用 git 来跟踪代码变更?你知道如何生成补丁吗?你已经尝试过什么了,现有文档的哪些部分是不足的? - undefined
我习惯使用git来跟踪变更。然而,我从未有机会通过git与他人合作,这应该是这个任务的主要目的。我还学会了使用git format-patch创建补丁。虽然我能够为每个子任务创建必要的补丁,但我无法以某种方式将这三封邮件链接在我的讲师邮箱中(用他自己的话说:我希望在我的邮箱中看到三封邮件,以某种方式“链接”起来)。希望这样更清楚明白! - undefined
1
如何发送第一封电子邮件?我需要从那里开始,还有如何将源代码附加到git send-email中。没有附件选项。 - undefined
3个回答

1

以下是如何通过电子邮件进行几轮审查的步骤:

  • 可选择为当前版本打标签(这将有助于下一轮)
    • 可选择为基础提交也打标签(在此之上创建分支的提交)
  • 准备第一个版本:git format-patch --cover-letter --output-directory patches --thread=shallow
    • 编辑封面信(patches/0000-cover-letter*):添加正文(参见星号)并修复主题(参见星号)
    • 关于“链接”:此命令将为封面信创建一个Message-ID,它将是电子邮件线程中的第一封电子邮件。每个补丁都会回复封面信(“shallow”样式)。
  • 记下封面信的Message-ID;它是文本/补丁文件中的一个电子邮件头
  • 使用git send-email patches发送出去

第二轮:

  • 可选地标记当前版本
  • 再次执行git format-patch,但加入一些额外的选项:
    • --in-reply-to=<Message-ID>:使用您记录的第一轮中的Message-ID
    • -v 2表示“第二轮”
    • 可选地使用--range-diff <base> <previous tag> <current>以生成封面信的“范围差异”(两个系列/分支之间的差异)
      • 这就是那些可选标记派上用场的地方
  • 在封面信中,您可以只讨论发生了什么变化,或者讨论发生了什么变化,并在此基础上提供整个上一轮的上下文(复制-粘贴即可)
  • 完成剩余步骤

参考资料

部分内容基于提交补丁


1
不错的补充。点赞了。 - undefined

1

现在您提出了一些具体的问题:

虽然我能够为每个子任务创建必要的补丁,但我无法在我的讲师邮箱中"某种方式"将这三封电子邮件链接起来。

这更多是一个邮件问题,而不是一个 git 问题。通常情况下,电子邮件通过回复以前的消息进行“连接”;在大多数客户端中,这样的回复链将显示为一条对话“线程”。

因此,在发送第一封电子邮件后,您将会回复它,可能会修改主题,并包括第一个补丁的内容(使用git format-patch生成),并按照同样的方式处理第二个补丁。

您实际上可以使用 git format-patchgit send-email 从命令行完成这些操作。首先生成您的补丁:

$ mkdir patches
$ git format-patch -o patches master

然后使用git send-email发送这些补丁,利用--in-reply-to命令行选项将您的消息链接到先前的消息。这需要将先前消息的message-id作为参数传递,因此您需要查看原始消息以获取message-id头的值。然后您可以运行:

git send-email \
  --in-reply-to ...message-id-here... \
  --from you@your.address \
  --to teacher@school.address \
  patches

这将发送两封电子邮件,主题看起来像:

[PATCH 1/2] first line of commit message here

并且:

[PATCH 2/2] first line of next commit message here

对于每封电子邮件,git会提示您是否要发送它:
From: lars@example.com
To: lars@example.com
Subject: [PATCH 1/2] made a patch
Date: Thu,  3 Sep 2015 11:42:23 -0400
Message-Id: <1441294944-28084-1-git-send-email-lars@example.com>
X-Mailer: git-send-email 2.4.0
In-Reply-To: <20150903153652.GE4975@example.com>
References: <20150903153652.GE4975@example.com>

    The Cc list above has been expanded by additional
    addresses found in the patch commit message. By default
    send-email prompts before sending whenever this occurs.
    This behavior is controlled by the sendemail.confirm
    configuration setting.

    For additional information, run 'git send-email --help'.
    To retain the current behavior, but squelch this message,
    run 'git config --global sendemail.confirm auto'.

Send this email? ([y]es|[n]o|[q]uit|[a]ll): 

第一个回复将是对原始消息的回复,第二个补丁将是对第一个回复的回复。在我的邮件客户端中,它看起来像这样:
   1   4  sF 03-09-2015 To lars@exampl  Test message for git                                         (➥)
   2   4 N F 03-09-2015 To lars@exampl  └─>[PATCH 1/2] made a patch                               (✉ me)
   3   4 N F 03-09-2015 To lars@exampl    └─>[PATCH 2/2] hey look no hands                        (✉ me)

(请注意,为了使git成功发送电子邮件,您可能需要提供一些配置。如果它不能正常工作,则git help send-email是开始的地方。)

如何发送第一封邮件(无回复),到目标IP地址。我需要在第一封邮件中附上源代码。您能否详细说明git format-patch命令? - undefined
只是一个简单的问题,我用这个方法在Linux内核中发送了一些补丁,但我的电子邮件地址会公开显示在档案中,有没有办法阻止这种情况发生? - undefined

1
请注意,在“发送电子邮件”部分之前,您还可以使用 --validate option来调用钩子sendemail-validate(即钩子路径中名为'sendemail-validate'的可执行文件(默认情况下为.git/hooks)。
这允许您在发送这些补丁之前进行一些检查。
随着Git 2.32(2021年第二季度), "git send-email"(man) 学会了尊重core.hooksPath配置,这是一个Git 2.9设置,我之前在这里提到过

请查看提交 c824393(2021年3月23日),作者为Robert Foss(robertfoss
(由Junio C Hamano -- gitster --于2021年3月30日合并至提交 1ba947c

git-send-email:尊重core.hooksPath设置

署名:Robert Foss
署名:Ævar Arnfjörð Bjarmason

get-send-email 目前假设存储库中存在 'sendemail-validate' 钩子。

自从 867ad08("hooks: allow customizing where the hook directory is",2016-05-04,Git v2.9.0-rc0 -- merge listed in batch #13)引入 'core.hooksPath' 配置选项以来,这不再是真实情况。

不要再假定一个 hardcoded 存储库相对路径,而是查询 git 获取钩子目录的实际路径。


请注意,从 Git 2.32 (2021 年第二季度) 开始, "git send-email --validate"(man) 选项的消息将发生变化。
查看 commit ea7811b, commit d21616c, commit e585210 (2021年4月6日) 由 Ævar Arnfjörð Bjarmason (avar) 提交。
(由 Junio C Hamano -- gitster -- 合并于 commit 2279289, 2021年4月13日)

git-send-email:改进--validate错误输出

署名:Ævar Arnfjörð Bjarmason

改善我们在--validate错误时发出的输出,以:
  • 使用"FILE:LINE"代替"FILE: LINE",以匹配 "grep -n"、编译器错误信息等。
  • 在提到文件名后不要说“补丁包包含”,只需将其保留为“FILE:LINE: is longer than[...]”。
    说“contains a”听起来像是我们在谈论整个文件,但实际上我们是逐行检查它。
  • 不要仅仅说“被sendemail-validate hook拒绝”,而是将其与system_or_msg()的输出结合起来,说明挂钩死亡时使用了什么退出代码。

我曾尝试让行长度检查器注明所有超过限制的行。
我认为这样做不值得,但我已经保留了测试变更,以检查我们是否在发现第一行过长时立即停止。

 patch contains a line longer than 998 characters

您有:

 is longer than 998 characters\n" .

在 Git 2.35(2022年第一季度)中,命令行完整性对于 "git send-email"(man)选项进行了微调,并提到了 format-patch

参考commit a2ce608commit 2b7b758 (2021年10月25日由Thiago Perrotta(thiagowfx提交)。
(于2021年11月29日由Junio C Hamano -- gitster --commit 7c2abf1中合并)

send-email文档:添加format-patch选项

签名:Thiago Perrotta

git-send-email(1)没有提到可以接受 "git format-patch"(man) 选项。
增加概要和描述以提及它。

git send-email现在在其手册页中包括:

  • 'git send-email' [<options>] <file|directory>...
  • 'git send-email' [<options>] <format-patch options>

[...] 可以传递给 git send-email,也可以理解为 git format-patch 的选项。


"

git send-email -v 3(man)曾被扩展为git send-email --validate 3,当用户希望将其传递给format-patch时:这已在Git 2.40(2023年第一季度)中进行了更正。

"

请查看8774aa5提交(2022年11月26日),作者为Kyle Meyer (kyleam)
(由Junio C Hamano -- gitster --531d13d提交中合并,日期为2023年1月27日)

send-email:将'-v N'转发到format-patch

签署者:Kyle Meyer

send-email中继承了其format-patch调用的无法识别的参数。
传递'-v N'会导致错误,因为-v被视为send-email的--validate
例如,
git send-email -v 3 @{u}
会失败并显示
fatal: ambiguous argument '3': unknown revision or path not in the
working tree.  [...]
为了避免这种情况,将短选项--reroll-count添加到send-email的主选项列表中,并在format-patch调用中显式提供它。
还有其他一些format-patch选项,send-email无法正确中继,包括至少-n-N和diff选项-D
放弃这些选项,因为处理它们更加复杂:
  • 它们需要配置send-email以不忽略选项大小写
  • send-email使用不同的选项集进行三个GetOptions()调用,最后一个是主要的选项集。
    与最后一个GetOptions调用消耗的-v不同,-n-N-D选项被较早的调用作为缩写消耗。

在 Git 2.41 (2023 年第二季度) 中,sendemail-validate 验证钩子学会通过环境变量传递输入文件的总数以及每个调用在序列中的位置。

请参见 提交 3c8d3ad (2023 年 4 月 14 日),作者为 Robin Jarry (rjarry)
(由 Junio C Hamano -- gitster --提交 c4c9d55 中合并,2023 年 4 月 25 日)

send-email:在验证环境中导出补丁计数器

建议者:Phillip Wood
签署者:Robin Jarry

发送补丁系列(带有封面信或不带)时,每个电子邮件/补丁文件都会独立调用sendemail-validate。
当其中一个补丁依赖于先前的补丁时,可能无法以有意义的方式使用此挂钩。
想要检查整个系列的某些属性的挂钩需要知道哪个补丁是最终补丁。
通过GIT_SENDEMAIL_PATCH_COUNTERGIT_SENDEMAIL_PATCH_TOTAL环境变量向挂钩公开当前和总补丁数,以便实现增量和全局验证。
在连续调用验证挂钩之间共享任何其他状态必须通过外部手段完成。
例如,通过将其存储在git config(man) sendemail.validateWorktree条目中。

githooks现在在其手册页面中包含:

执行钩子时设置以下环境变量。

GIT_SENDEMAIL_FILE_COUNTER

一个基于1的计数器,每个包含要发送的电子邮件的文件都会增加1(不包括任何FIFO)。该计数器不遵循补丁系列计数器方案。它将始终从1开始,并在GIT_SENDEMAIL_FILE_TOTAL结束。

GIT_SENDEMAIL_FILE_TOTAL

将被发送的文件总数(不包括任何FIFO)。
该计数器不遵循补丁系列计数器方案。它将始终等于正在发送的文件数量,无论是否有封面信。

例如,这些变量可用于验证补丁系列。

Git附带的示例sendemail-validate钩子检查所有已发送的补丁(不包括封面信)是否可以在上游存储库默认分支之上应用而不产生冲突。留下了一些占位符,以便在应用给定系列的所有补丁之后执行其他验证步骤。


在 Git 2.41 (Q2 2023) 中, "git send-email"(man) 学会了通过从命令行传递额外参数来将电子邮件头部提供给验证钩子。

查看提交 a8022c5提交 56addda(2023年4月19日)由Michael Strawbridge (none)完成。
(由Junio C Hamano -- gitster --提交 b6e9521中合并,2023年5月10日)

send-email:将头信息暴露给git-send-email的sendemail-validate钩子

Cc:Luben Tuikov
Cc:Junio C Hamano
Cc:Ævar Arnfjörð Bjarmason
Acked-by:Luben Tuikov
Signed-off-by:Michael Strawbridge

为了增加 Git 钩子的灵活性,现在将 git-send-email(man) 所要发送的电子邮件的 SMTP 标头信息作为第二个参数传递到 sendemail-validate 钩子中。
例如,可以根据主题中的关键字或特定的电子邮件地址来执行操作。
现在,githooks 已经包含在其 man page 中:
此钩子由git send-email调用。
它接受这些命令行参数。它们是:
  1. 保存要发送的电子邮件内容的文件名。
  2. 保存电子邮件SMTP头的文件名。
SMTP头以与它们传递给用户的邮件传输代理(MTA)相同的方式传递。实际上,提供给用户的MTA的电子邮件是$2的内容后跟$1的内容。
下面显示了一些常见标题的示例。请注意大写和多行制表符结构。
From: Example from@example.com To: to@example.com Cc: cc@example.com, A author@example.com, One one@example.com, two@example.com Subject: PATCH-STRING
以非零状态退出会导致git send-email在发送任何电子邮件之前中止。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接