Git合并没有自动提交

是否有可能做一个git merge,但没有提交?

“man git merge”是这样说的:

With --no-commit perform the merge but pretend the merge failed and do not autocommit,
to give the user a chance to inspect and further tweak the merge result before
committing.

但是当我尝试使用git merge--no-commit时,它仍然自动提交。以下是我所做的:

$> ~/git/testrepo$ git checkout master
Switched to branch 'master'


$> ~/git/testrepo$ git branch
* master
v1.0


$> ~/git/testrepo$ git merge --no-commit v1.0
Updating c0c9fd2..18fa02c
Fast-forward
file1 |    1 +
1 files changed, 1 insertions(+), 0 deletions(-)


$> ~/git/testrepo$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

随后的git log显示了从v1.0分支合并到主分支的所有提交。

357458 次浏览

你误解了合并的意思。

--no-commit防止MERGE COMMIT发生,只有当合并两个不同的分支历史时才会发生;在你的例子中,情况并非如此,因为Git指示它是“快进”。然后Git只按顺序应用已经在分支上出现的提交。

注意在进行合并时的输出—它显示的是Fast Forward

在这种情况下,你想做:

git merge <name-of-branch> --no-commit --no-ff

重要的:如果你这样做,那么你不能在暂存区对文件做任何更改,例如,你不能删除/添加文件或对文件做任何更改。

如果你想合并这些更改,然后提交,就像你手动输入了所有合并的更改一样(而不是传统的合并),你需要在之后运行rm .git/MERGE_HEAD,这将迫使git忘记合并的发生。

如果你只想在一次提交中提交所有的更改,就像你自己输入一样,——squash也可以

$ git merge --squash v1.0
$ git commit

我更喜欢这种方式,这样我就不需要记住任何罕见的参数。

git merge branch_name

然后它会说你的分支通过“#”提交领先,你现在可以弹出这些提交,并将它们放入下面的工作更改中:

git reset @~#

例如,如果在合并之后,它提前1次提交,使用:

git reset @~1

注意:在Windows上,需要引号。(正如杰克在评论中指出的那样)例如:

git reset "@~1"

当分支中只有一个提交时,我通常会这样做

git merge branch_name --ff

老问题有很多答案,但这太大了,不适合评论。


正如另一个答案所提到的,将v1.0合并到master会导致快进合并。事实上,并没有合并。v1.0标签有一个提交,它的父提交是master的提示。刚刚将master指针提前了一次提交。

如果这样做会导致糟糕的合并,你真正应该做的是什么?在v1.0标签处给了我们一个错误的提交。

更合适的解决方案是将1.0版本快速合并到master中,添加一个提交给master以纠正错误的代码。之后,要么删除v1.0标记并重新创建它,要么重新标记v1.0并强制推送标记。更好的方法是,从修复v1.0的提交创建一个v1.0.1标记。

从编码的角度来看,所有其他答案都指向了错误的解决方案。

你也可以

git cherry-pick <commit hash>

对于每次提交,如果你想保存提交历史记录…

我并没有看到一个“nice”;使用git merge命令合并来自另一个分支的多个提交的方法,而不需要在某些地方添加合并提交(即只有你想包含的提交)