【问题标题】:Write git commit message before 'git commit'在 'git commit' 之前写下 git commit 消息
【发布时间】:2010-09-19 00:01:24
【问题描述】:

我正在学习来自 Perforce 的 Git。

据我所知,您必须在提交时的同一步骤中编写提交消息。还是我错过了如何更早地编写消息并让它一直存在直到我准备好提交。

我真的很喜欢 perforce 中的工作流程,您可以在其中随时编辑更改列表描述,然后在您准备好时签入。就我个人而言,我喜欢多次打开描述并在编写代码时记录下来,或者在我想到要指出的值得注意的事情时记录下来。

可以用 Git 吗?

【问题讨论】:

  • 好问题。据我从 git-commit 手册页可以看出,您不能直接执行此操作(您可以使用 -F 并将提交消息存储在 git 之外),但是由于 git 允许您逐步构建提交,因此您会期望也可以使用提交消息来做到这一点。

标签: git


【解决方案1】:

查看带有git commit-t <file> 标志

这使您可以指定一个文件作为提交消息的基础。编辑器仍会被调用,但至少您可以使用预先创建的提交消息。

或者,您可以在 git 中使用另一个工作流,它可能更适合您的工作方式:

使用 git,您可以在与主线不同的分支上工作,并使用自己的消息进行大量小提交。尽管这些提交中的每一个本身可能无法解决您正在处理的问题,但它们确实提供了一种使用您可能在提交消息文件中更新的相同类型的消息来保存工作的中间状态的方法。

一旦您准备好提交您的工作总和,您可以一起使用rebase 命令和squash 这些提交。然后将使用您用于较小提交的所有单独消息调用您的编辑器,然后您可以将它们一起编辑成一条消息。

这比听起来容易得多,恕我直言,这是一种更像 git 的方法。

【讨论】:

  • 将此标记为答案,因为 -t 最像我想要的。不过,有兴趣了解其他工作流程,谢谢!
  • 我对 git 很陌生,刚刚看到这个。所以我的理解是rebase/squash 我可以将分支中的所有小提交归结为一个提交?在进行拉取请求时,“git 方式”是什么?将所有提交压缩为一个并拉取我的分支,还是保留所有提交以供上游维护人员查看?另外,如果我的拉取请求有很多提交,并且它被合并了,最终的上游仓库是显示所有这些提交,还是只显示“从拉取请求合并”?
  • “更像 git 的方法”的问题在于,每个提交消息仍然是在为其编写的代码之后编写的——更改很小的事实改善了问题,但并没有消除它。 OP 想要的东西(并且 Perforce 鼓励,至少对于少数人来说)是在编写一行代码之前编写更改列表描述。它使您处于不同的心态,这有时会有所帮助。
  • 请从this other answer添加-F选项,该选项无需打开编辑器即可提交。
  • 关于git rebase && git squash 工作流程的要点!此外,绝对没有理由不能将这两个工作流程一起使用。保留提交消息草稿对于跟踪待办事项列表和其他清单非常有用,以防止您在编写较小的增量提交时忘记任何事情。这样一来,您压缩的提交消息就可以包含您的所有进度。
【解决方案2】:

只要您没有push 对他人的承诺,您就可以提交git commit --amend。这将允许您修改您的提交以及您的提交消息。

我发现这确实有助于“尽早并经常提交”,而不会被琐碎的提交数量所淹没。

【讨论】:

  • hmm,还是理解git的做事方式,但这似乎颠覆了提交checkpoints的点,最后一次commit确实是“commit in progress”。
  • 它具有这样做的灵活性。你不需要使用它,但如果你需要它,它就在那里。
  • @AK 在私有分支上做,没有人知道你正在重写 HEAD
【解决方案3】:

您可以使用这些别名:

git config --global alias.prepare '!${EDITOR:-vi} $(git rev-parse --git-dir)/.template'
git config --global alias.commitp '!git commit -F $(git rev-parse --git-dir)/.template'

用法:

git prepare
EDITOR=nano git prepare # heeds standard EDITOR variable
git commitp

这会将您的提交消息保存在.git/.template

但不是这样,您实际上应该只使用经常提交原子和小更改的工作流程,并在必要时使用功能分支对这些更改进行分组。如果与git merge --no-ff $branch合并,以后可以使用git log --first-parent忽略分支。

【讨论】:

  • IMO 这是一个很好的答案。最后一段不需要贬低。
  • 确实有用。并且要在提交时编辑消息,在 -F 之前添加 -e (这似乎更符合操作的 Perforce 期望;和我的)。
  • 将 .template 重命名为 GITGUI_MSG 可与 git gui 一起使用,正如 @johnny 评论的另一个答案。
  • +1 创新方法!请记住,这种方法不能很好地与git stashgit checkout 配合使用,因为如果您同时处理多个分支,您很容易最终覆盖草稿消息。我确信git hash-objectgit write-tree 可用于使并行工作流更友好。
【解决方案4】:

您可以使用git gui 并在工作时将其保持打开状态。为您将要进行的错误修复编写提交消息,然后进行实际的代码更改,暂存并提交。

【讨论】:

  • git gui 是 git 套件的一部分,因此它适用于 git 可用的所有平台。
  • 编辑以反映这一点。谢谢。
  • git gui,至少在版本 0.13 中作为 git 1.7.4.msysgit.0 的一部分,在提交之间将提交消息保存在 .git/GITGUI_MSG 中,所以你甚至不需要离开它在您工作时打开...您甚至可以将该文件用作您的临时编辑位置 - 这样,如果您使用 GUI,您将拥有您的笔记,如果您从命令行提交,您只需使用 -t .git/GITGUI_MSG ...
【解决方案5】:

我相信这个问题的动机是能够在编写任何代码之前编写描述(提交消息)(当然可以在编写代码时对其进行修改)。 (之前使用过 Perforce 和类似 Perforce 的系统,我知道有时在这种思维框架中会有所帮助,在实际编写代码之前,先写下你将要做什么的描述。)

除了将消息写入文件并使用-t <file> (--template=<file>) 或-F <file> (--file=<file>) 标志到git commit,另一种方法如下:

  1. 使用git commit --allow-empty 进行空提​​交。就像任何git commit 一样,这将打开一个编辑器,您可以在其中编写消息。编写它并完成提交。

  2. 更改您的代码。

  3. 使用git add 添加要添加的文件,然后使用git commit --amend(或者如果您不想使用git add 选择特定文件,则只需git commit -a --amend)。这将使之前的非空提交现在不再为空,并且您还可以编辑消息以更接近您实际所做的(如果您愿意的话)。

(如果您正在与其他人合作,请记住不要在这样做时git push:不要修改您已经推送的提交!)

当然,保持提交尽可能小和原子的建议仍然适用,但这种方式可以让您在编写代码之前编写消息。 (git commit --amend 方法已在另一个答案中提出;我只是另外指出,您可以使用git commit --allow-empty 一路走下去。)

【讨论】:

  • 不推送空提交(带描述)的问题是,先写描述的原因之一是向别人宣布你的意图。 Perforce 变更列表描述的价值之一是其他人可以阅读您正在进行的工作的描述。所以如果我看到 Bob 正在处理文件 foo.c 我可以阅读他的描述以了解他打算做什么,如果它与我打算做的冲突,我可以打电话给 Bob,我们可以弄清楚如何继续.
【解决方案6】:

将其写入文件;在您工作时保持更新。在实际提交时包含最终版本。

如果您使用 git 的图形前端,那么您必须指定哪个,以便有人可以专门帮助它。一般来说,您可以简单地粘贴消息。

从命令行使用 git,它会打开带有临时文件的编辑器,您可以将消息读入其中(例如 vim 中的 :r 文件名)。

或者您可以使用您的 shell 将该文件作为 -m 参数的值来读取:

# bash example, may work elsewhere
git commit -m "$(<filename)"

【讨论】:

  • -1:恕我直言,这不是一个好的答案。我们都知道我们可以事先在其他地方写下一些东西——这非常明显。很明显,发帖者要求 git 的一个功能来满足他们的需求。
  • @camh:Git 很灵活,不会试图接管你的整个过程。在提交时使用你最喜欢的编辑器 git 的一个特性。
  • @camh 但在某种程度上,这就是 perforce 真正在做的事情。由于 git 有 -F 标志,您可以保持提交消息的文件是最新的,并且只需使用 -F 标志。也就是说git对它有特殊的支持。如果你真的想要,你甚至可以编写一个 git 脚本来为你编辑它。它所要做的就是调用 vi,但这是一个非常简单的任务,所以......
  • @Roger:我理解这一点,但您的回答没有解决这个问题:“Git 可能吗?”他们至少可以参考与您的答案非常相关的git-commit -F
  • @camh:如果您认为自己有更好的答案,请发表。我通常更喜欢坚持使用我所有工具的一致方式。对你来说清楚的事情可能对 OP 来说并不清楚,他们问他们是否遗漏了一些明显的东西。
【解决方案7】:

内置,据我所知。如果你真的很绝望,你可以像COMMIT="Fix for bug #14453"COMMIT="$COMMIT and bug #4329"一样在终端中写它,然后像git commit -m "$COMMIT"一样提交。

【讨论】:

    【解决方案8】:

    commit 命令使用--file &lt;path&gt; 参数。

    git commit --file <absolute or relative path to file>
    

    并将文件的绝对或相对路径>替换为文件的路径。

     

    repository 目录上方目录中的相对文件示例:

    git commit --file ../commit-message.txt
    

     

    您可以在任何文本编辑器中处理提交消息并将其保持打开状态。只需保存文件,然后使用恒定的提交命令提交即可。它从文本文件 (.txt) 中获取消息,而无需打开编辑器。

    【讨论】:

      【解决方案9】:

      -t &lt;file&gt; 答案的替代方案,如果您打算每次都使用它,请设置:
      git config commit.template &lt;file&gt;
      这将在每次提交时隐式使用 -t

      【讨论】:

        【解决方案10】:

        另一个简单的选择是编写一个不做任何更改的 git commit,然后修改:

        $ git commit --allow-empty
        # create message
        $ git commit --allow-empty --amend
        # edit message
        

        你可以创建一个别名:

        $ git config --global alias.draft 'commit --allow-empty'
        $ git draft
        # create message
        $ git draft --amend
        # edit message
        

        这具有 git 提交的所有好处:

        • 您将在 reflog 中获得“备份”,以防您出错。
        • 您可以像往常一样将文件添加到索引并--amend 将它们添加到提交中。
        • 您可以将草稿消息推送到您的功能分支。

        【讨论】:

          【解决方案11】:

          为了补充 MatrixFrog 的答案,GitKraken GUI (https://support.gitkraken.com/working-with-commits/commits/) 提供了类似的功能。它允许在实施实际更改之前/同时在 GUI 内起草提交消息。

          另外,它允许设置一个模板来构造提交体,例如:


          变化:

          --

          新测试:

          酒吧

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-11-23
            • 1970-01-01
            • 2021-05-15
            • 2012-05-30
            相关资源
            最近更新 更多