简体   繁体   English

避免在分叉存储库上合并提交的原因是什么?

[英]What is the reason for avoiding a merge commit on a forked repository?

There is a question here which has an excellent answer, but a highly upvoted comment on the question says that for some projects the answer is not acceptable : 这里有一个问题有一个很好的答案,但对该问题的高度评价表示,对于某些项目,答案是不可接受的

I quote the comment:我引用评论:

The surprising answer by @Olufemi seems to do what you want, except that as ChristianGosch notes in a comment, you end up with a "merge commit" on top of your branch, and "nothing to compare" will not appear. @Olufemi 的令人惊讶的答案似乎可以满足您的要求,除了正如 ChristianGosch 在评论中指出的那样,您最终会在您的分支顶部获得“合并提交”,并且不会出现“没有可比较的”。 That seems unacceptable to many projects for which you want to make branches for them to pull.对于您想要为其创建分支供他们拉取的许多项目来说,这似乎是不可接受的。 So is there really no way to do this most basic of contributor workflows in github without running arcane git commands on a personal computer?那么,如果不在个人计算机上运行神秘的 git 命令,真的没有办法在 github 中执行这个最基本的贡献者工作流吗? Or maybe I should just throw away my whole repo and re-fork every time I want to contribute??或者也许我应该在每次我想贡献的时候扔掉我的整个回购并重新分叉? – nealmcb Dec 7 '14 at 22:14 – nealmcb 2014 年 12 月 7 日 22:14

And the comment mentioned in the comment:以及评论中提到的评论:

Another one: This works fine if you did that not before already, but afterwards there is the "merge commit" on top of your commit history.另一个:如果您之前没有这样做,这很好用,但之后在您的提交历史记录顶部有“合并提交”。 Thus "nothing to compare" will not appear.因此“没什么可比较的”不会出现。 Instead one must use "Edit" button and manually interchange base and fork for this to work.相反,必须使用“编辑”按钮并手动交换 base 和 fork 才能工作。 – Christian Gosch Oct 23 '14 at 14:04 – Christian Gosch 2014 年 10 月 23 日 14:04

Other comments on that question indicates that a rebase in stead of a merge solves this issue.关于该问题的其他评论表明,rebase 而不是合并解决了这个问题。

My question is this "What exactly is the issue with having a merge commit and when would you want to avoid it?"我的问题是“合并提交到底有什么问题,你什么时候想避免它?” Do these merge commits add up over time?这些合并提交是否会随着时间的推移而增加? Does it affect future "sync to base repository" actions?它会影响未来的“同步到基础存储库”操作吗?

And a second question: Since I just followed the steps in this answer and now do have this "merge commit" how can I fix it if it was an issue to me?第二个问题:由于我只是按照此答案中的步骤进行操作,现在确实有此“合并提交”,如果这对我来说是个问题,我该如何解决?

TL;DR TL;博士

Merge commits can create histories like this:合并提交可以创建这样的历史记录:

A-->B-->C-->D------>N
 \           \     /
  X---------->M-->Y

Some people prefer linear histories over histories that results from merge commits:有些人更喜欢线性历史而不是合并提交的历史:

A-->B-->C-->D-->X-->Y

In order to produce such linear histories, run git rebase <main repository branch> from the fork branch before running git merge <fork branch> in the main repository branch.为了产生这样的线性历史,在主存储库分支中运行git merge <fork branch>之前,从 fork 分支运行git rebase <main repository branch>

The problem问题

If you have a scenario like this:如果你有这样的场景:

A-->B-->C-->D    main repo
 \
  X              fork

and create a merge commit in order to keep the fork up to date, it will look like this:并创建一个合并提交以使 fork 保持最新,它将如下所示:

A-->B-->C-->D    main repo
 \           \
  X---------->M  fork

When you then add another commit somewhere and merge it back, it will look like:然后,当您在某处添加另一个提交并将其合并回来时,它将如下所示:

A-->B-->C-->D------>N  main repo
\            \     /
 X----------->M-->Y    fork

You would have multiple merge commits and all merge commits would be visible in the history.您将有多个合并提交,并且所有合并提交都将在历史记录中可见。

Some repository maintainer prefer linear histories like:一些存储库维护者更喜欢线性历史,例如:

A-->B-->C-->D-->X

over histories with merge commits like:合并提交的历史记录,例如:

A-->B-->C-->D------>N  main repo
 \           \     /
  X---------->M-->Y    fork

Solution解决方案

If you want to prevent this, you could use rebase merges.如果你想防止这种情况,你可以使用 rebase 合并。

Let's start like this, again:让我们再次这样开始:

A-->B-->C-->D    main repo
 \
  X              fork

Rebasing would move X to the top (run git rebase <branch from main repo> in the fork):变基会将 X 移到顶部(在 fork 中运行git rebase <branch from main repo> ):

A-->B-->C-->D     main repo
             \
              X'  fork

You can then directly fast-forward any commits to the main repo without merge commits.然后,您可以直接将任何提交快进到主存储库,而无需合并提交。

A-->B-->C-->D-->X'

No advantage without disadvantages没有缺点就没有优点

If you rebase a branch, you cannot simply push to the branch but you need to force push.如果你变基一个分支,你不能简单地推送到分支,但你需要强制推送。

If you do that, you will overwrite the branch with your history and other people working on that branch will be forced to checkout the branch again if they do not want to clone it, again.如果这样做,您将用您的历史记录覆盖该分支,并且在该分支上工作的其他人如果不想再次克隆它,将被迫再次签出该分支。

For example, multiple people could work on that fork:例如,多个人可以在该分叉上工作:

A-->B-->C-->D    main repo
 \
  X              fork, local copy of someone else

If you rebase it, it will look like this:如果你重新设置它,它将如下所示:

A-->B-->C-->D    main repo
|            \
|             X' fork
 \
  X              local copy of someone else

If that person pulls, it would result in another merge commit where a commit is merged with an identical commit:如果该人拉动,它将导致另一个合并提交,其中一个提交与一个相同的提交合并:

A-->B-->C-->D       main repo
|            \
|             X'    fork
 \             \
  X-------------M   local copy of someone else

In order to prevent that, they need to pull with the --rebase option.为了防止这种情况,他们需要使用--rebase选项进行拉取。 The result will look like the fork afterwards:之后的结果将类似于分叉:

A-->B-->C-->D    main repo
             \
              X' fork, local copy of someone else

This will even work if the person has worked on commits:如果这个人已经提交过,这甚至会起作用:

Before rebasing:变基之前:

A-->B-->C-->D    main repo
|            \
|             X' fork
 \
  X-->Y          local copy of someone else

After rebasing ( git pull --rebase ):变基后( git pull --rebase ):

A-->B-->C-->D       main repo
             \
              X'    fork
               \
                Y'  local copy of someone else

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM