Git commit --amend合并了两个提交

时间:2015-02-20 14:22:53

标签: git git-commit amend

我有一个远程'dev'分支,正在本地工作。

我使用提交消息“my_feature”对'dev'进行了第一次提交,将我的本地分支置于远程提前1次提交。

然后我开发了一些新东西并制作了git add -u,准备提交。 然后我意识到我想将之前的提交消息重写为“my_feature(1/2)”,使我当前的提交消息为“my_feature(2/2)”,将我的本地分支置于远程提前2次提交。

所以我创建了一个git commit --amend(认为它只会编辑上一个提交的消息),将“my_feature”提交消息编辑为“my_feature(1/2)”并且...... 结束于单个提交标记为“my_feature(1/2)”包含所有更改(第一次提交+暂存文件差异) - 我的索引现在已经清理。

所以,如果我做对了,我的命令实际上做了提交,还提交了暂存文件,这产生了一个(合并?)提交?

我没想到Git会做这样的事情。我只想编辑旧的提交消息,而不是将旧的提交消息与我当前的暂存文件合并。 (现在我考虑一下rebase可能会更好。)

虽然我可以理解为什么git commit --amend可以提交(即使我只想编辑提交消息),我有一些问题需要理解Git如何将我的两个提交合并为一个{{1} }命令。

任何人都可以向我澄清这一点吗?

commit

3 个答案:

答案 0 :(得分:5)

如果您有暂存文件并执行

git commit --amend

您将创建一个新提交,其中包含上一次提交中的所有内容以及所有已暂存的提交,此新提交将替换上一次提交作为您已检出的分支的提示。

没有任何暂存文件的

git commit --amend可用于更改提交消息,但请注意,即使在没有暂存文件的情况下,您也会获得新的sha1,换句话说就是新的提交。

来自documentation

  

用于修改当前分支的提示。准备您希望像往常一样替换最新提交的树对象(这包括通常的-i / -o和显式路径),并且提交日志编辑器使用来自当前分支的提示的提交消息进行播种。您创建的提交将替换当前提示 - 如果它是合并,则将当前提示的父项作为父项 - 因此将丢弃当前的提交。

答案 1 :(得分:3)

这是预期的行为。来自git commit documentation

  

<强> - 修改

     

通过创建新提交替换当前分支的提示。记录的树照常准备(包括-i-o选项和显式路径规范的效果),原始提交的消息用作起始点,而不是空消息,当没有通过-m-F-c等选项从命令行指定其他消息时。新提交具有与当前提交相同的父级和作者({ {1}}选项可以反击这个)。

     

这是一个粗略的等价物:

--reset-author
     

但可用于修改合并提交。

     

如果修改已发布的提交,则应了解重写历史记录的含义。 (参见git-rebase[1]中的“从上游恢复中恢复”部分。)


要理解的重要部分是$ git reset --soft HEAD^ $ ... do something else to come up with the right tree ... $ git commit -c ORIG_HEAD 。这将从您的历史记录中“删除”提交,但不会更改您的工作树或索引。

看看documentation of git reset。强调我的。

  

<强> - 软

     

根本不触及索引文件或工作树(但是将头重置为,就像所有模式一样)。这会将所有已更改的文件保留为“要提交的更改”,因为 git status 会将其置于其中。

答案 2 :(得分:2)

git commit --amend会为最近的提交添加暂存的更改。由于它合并你的两个我怀疑有两个提交而是一个。

man page解释了这一点:

--amend
    Replace the tip of the current branch by creating a new commit. The
    recorded tree is prepared as usual (including the effect of the -i and
    -o options and explicit pathspec), and the message from the original
    commit is used as the starting point, instead of an empty message, when
    no other message is specified from the command line via options such as
    -m, -F, -c, etc. The new commit has the same parents and author as the
    current one (the --reset-author option can countermand this).

    It is a rough equivalent for:

        $ git reset --soft HEAD^
        $ ... do something else to come up with the right tree ...
        $ git commit -c ORIG_HEAD

    but can be used to amend a merge commit.

    You should understand the implications of rewriting history if you
    amend a commit that has already been published. (See the "RECOVERING
    FROM UPSTREAM REBASE" section in git-rebase[1].)

因为您描述了处理多个提交,我将解释上述描述工作流程的方式:

A--B (origin/dev) (dev)

编辑文件,然后添加登台(git add -u):

$ git commit # edit a good message (see below)

A--B (origin/dev)
    \
     C (dev)

现在重复:

$ git commit # edit another awesome message (see below)

A--B (origin/dev)
    \
     C--D (dev)

但是现在你意识到提交C有一个错误的提交消息。所以我们做了一个改变:

$ git rebase -i origin/dev

在编辑器中,您会看到提交C和D及其主题行和关键字pick。找到您要修复的提交,然后将pick更改为reword,然后保存该文件。

git将打开另一个编辑器,让您修复提交消息。保存并继续。

关于提交消息的说明(因为我试图传播这个词):

http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message

Capitalized, short (50 chars or less) summary

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.

Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug."  This convention matches up with commit messages generated
by commands like git merge and git revert.

Further paragraphs come after blank lines.

- Bullet points are okay, too

- Typically a hyphen or asterisk is used for the bullet, followed by a
  single space, with blank lines in between, but conventions vary here

- Use a hanging indent