Git合并允许我们执行快进和不快进的分支合并。什么时候使用快进合并,什么时候不使用快进合并?


当前回答

也有可能有人想要有个性化的功能分支,代码只是放在一天结束的时候。这样就可以更详细地跟踪开发过程。

我不想用无法工作的代码污染主开发,因此——no-ff可能正是人们所寻找的。

顺便说一句,可能没有必要在个性化的分支上提交工作代码,因为只要没有其他人在同一分支上工作,历史可以被重写git rebase -i并强制到服务器上。

其他回答

Git可视化

以下是不同的git日志可视化。这些是树的样子,从dev创建三个分支,称为1 2 3,然后合并和不快速前进。我将把设置代码放在底部。您可以将一段命令粘贴到您的终端中,以快速设置和重置不同的git场景,这对学习git非常有帮助。

注意,使用快进,git甚至没有指示合并。

--no-ff         --ff (default)

* Merge 3
| * 3
* | Merge 2     * Merge 3
| | * 2         | * 3
| |/            * | Merge 2
* / Merge 1     | | * 2
|/              | |/
| * 1           * / 1
|/              |/
* main          * main

将这种方法与重基方法进行比较是值得的。

安装/拆卸

你可以重复运行它,它会删除并重新初始化repo。它适用于windows,所以我认为你只需要改变文件路径和rd删除目录命令,如果你使用*nix。

要查看使用快进的行为,请从最后的合并命令中删除——no-ff。如果您想查看提交id,请删除漂亮的部分。

cd \user\docs\code\learning\github\sandbox
rd /s /q 0.git 1 2 3
git init --bare 0.git
git clone 0.git 1
cd 1
git config user.name "user"
git config user.email "user@email.com"
git commit --allow-empty -m main
git switch -c 1 main
git commit --allow-empty -m 1
git switch -c 2 main
git commit --allow-empty -m 2
git switch -c 3 main
git commit --allow-empty -m 3
git switch main
git merge --no-ff 1
git merge --no-ff 2
git merge --no-ff 3
git log --graph --oneline --first-parent --all --pretty=%s

除了列出的使用原因——no-ff之外,在目标分支中保持正确的父顺序是另一个原因。

Using --no-ff, the parent order in the last commit in the resulting branch will be independent of the parent order in the last commit of the branch you are merging, its first parent will be in the target branch, not in the branch you merged. If you perform a ff, the last commit of the branch you are merging would be incorporated to the target branch as the last one, so the first parent of the last commit in target branch will be pointing to a commit out of the mainline. This is probably not what you want.

例如,您可以使用——first-parent来过滤分支历史记录,以只查看对分支的主要更改,或者想要执行默认使用第一个父节点的其他操作,如revert。如果分支没有保持正确的父引用,结果将与预期不同。

当你想对你的特性分支有一个清晰的概念时,——no-ff选项很有用。因此,即使在此期间没有提交,FF也是可能的——有时你仍然希望主线中的每个提交都对应于一个特性。因此,您将带有一堆提交的特性分支视为单个单元,并将它们合并为单个单元。当你使用-no-ff进行特性分支合并时,从你的历史记录中可以清楚地看到。

如果你不关心这样的事情——你可能会在任何可能的时候使用FF。这样你会有更像svn的工作流程的感觉。

例如,本文作者认为——no-ff选项应该是默认选项,他的推理与我上面概述的接近:

Consider the situation where a series of minor commits on the "feature" branch collectively make up one new feature: If you just do "git merge feature_branch" without --no-ff, "it is impossible to see from the Git history which of the commit objects together have implemented a feature—you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache [if --no-ff is not used], whereas it is easily done if the --no-ff flag was used [because it's just one commit]."

当我们在开发环境中工作并将我们的代码合并到登台/生产分支时,Git没有快进可能是一个更好的选择。通常,当我们在一个特性的开发分支中工作时,我们倾向于多次提交。在以后使用多次提交跟踪更改可能会很不方便。如果我们使用Git合并登台/生产分支,那么它将只有1次提交。任何时候我们想要还原特性,只要还原那个提交。生活很简单。

也有可能有人想要有个性化的功能分支,代码只是放在一天结束的时候。这样就可以更详细地跟踪开发过程。

我不想用无法工作的代码污染主开发,因此——no-ff可能正是人们所寻找的。

顺便说一句,可能没有必要在个性化的分支上提交工作代码,因为只要没有其他人在同一分支上工作,历史可以被重写git rebase -i并强制到服务器上。