Git提交--修改合并的两个提交



我有一个远程"dev"分支,并且正在本地处理它。

我在"dev"上进行了第一次提交,提交消息为"my_feature",使本地分支比远程分支领先1个提交。

然后我开发了一些新的东西,并制作了一个git add -u,准备提交。然后我意识到,我想将以前的提交消息修改为"my_feature(1/2)",以使当前的提交消息为"my_feature(2/2)",使本地分支比远程分支提前2次提交。

所以我做了一个git commit --amend(认为它只会编辑上一次提交的消息),将"my_feature"提交消息编辑为"my_fFeature(1/2)",然后最终得到一个标记为"my_feature(1/2)"的提交,其中包含我的所有更改(第一个提交+暂存文件差异)--我的索引现在是干净的。

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

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

虽然我可以理解为什么git commit --amend可以提交(即使我只想编辑一条提交消息),但我很难理解Git是如何用commit命令将我的两个提交合并为一个的

有人可以向我澄清吗?

$ git --version
git version 1.7.10.4

如果您有暂存文件并执行

git commit --amend

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

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

来自文件:

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

这是预期行为。来自git commit文档。

--修改

通过创建新的提交来替换当前分支的顶端。记录的树照常准备(包括-i-o选项以及显式路径规范的效果),并且当没有通过-m-F-c等选项从命令行指定其他消息时,来自原始提交的消息被用作起点,而不是空消息。新提交与当前提交具有相同的父级和作者(--reset-author选项可以取消此项)。

它大致相当于:

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

但是可以用于修改合并提交。

如果你修改了已经发布的承诺,你应该理解改写历史的含义。(请参阅git-REBASE[1]中的"从上游数据库恢复"部分。)


需要理解的重要部分是git reset --soft HEAD^。这将从您的历史记录中"删除"提交,但不会更改您的工作树或索引。

请查看git reset的文档。强调我的。

--soft

根本不接触索引文件或工作树(但将头重置为,就像所有模式一样)。这会让所有更改后的文件"Changes to committed",正如git status所说。

git commit --amend将向最近的提交添加阶段性更改。由于合并了你的两个,我怀疑不是两个提交,而是一个。

手册页对此进行了解释:

--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)

但是现在您意识到commit C有一个错误的commit消息。所以我们做了一个调整:

$ git rebase -i origin/dev

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

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

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

https://thoughtbot.com/blog/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

最新更新