Visual Studio 如何合并当你得到错误“提示:你有不同的分支,需要指定如何协调它们,”

drkbr07n  于 2022-12-30  发布在  其他
关注(0)|答案(3)|浏览(1325)

我正在与1其他开发人员谁创建了一个分支,需要与主合并。
我在尝试将Visual Studio社区中的Git(不是Visual Studio代码)拉入Bitbucket存储库时遇到此错误
如果我尝试推送,它会说"无法推送,因为您的本地分支在远程分支后面"。
这是错误:

Hint: You have divergent branches and need to specify how to reconcile them.
Hint: You can do so by running one of the following commands sometime before
Hint: your next pull:
Hint: 
Hint:   git config pull.rebase false  # merge
Hint:   git config pull.rebase true   # rebase
Hint:   git config pull.ff only       # fast-forward only
Hint: 
Hint: You can replace "git config" with "git config --global" to set a default
Hint: preference for all repositories. You can also pass --rebase, --no-rebase,
Hint: or --ff-only on the command line to override the configured default per
Hint: invocation.
Git failed with a fatal error.
Git failed with a fatal error.
Need to specify how to reconcile divergent branches.

我发现了很多讨论这个的东西
https://laracasts.com/discuss/channels/code-review/git-pull-error-pulling-without-specifying-how-to-reconcile-divergent-branches-is-discouraged?page=1&replyId=773818
How can I deal with this Git warning? "Pulling without specifying how to reconcile divergent branches is discouraged"
但他们都没有解释为什么会发生这种情况,以及这些行动实际上做了什么。
我怎样才能将其他分支中的内容合并到master中,为什么出现此消息,提示中的所有建议有什么效果?
谢啦,谢啦

b1payxdu

b1payxdu1#

正如Git中经常出现的令人困惑的东西一样,其中涉及到一些历史。
首先要知道的是git pull做了太多的东西,嗯,对一些人(我)来说,它做了太多;其他人喜欢它做这么多;但实际上,它有两个任务,每个任务都有自己的Git命令:

  1. git pull运行git fetch。将 * 赋给 * git pull的大多数(但不是全部)参数直接传递给git fetch。因此git pull表示 * 运行git fetch *,git pull origin somebranch表示 * 运行git fetch origin somebranch *。
    1.假设第一步成功,git pull运行第二个Git命令。
    设置步骤2的原因非常简单:git fetch * 从其他Git仓库获取新提交,并将这些新提交填充到你自己的仓库中,你现在可以访问它们。但随后它就停止了。你可以访问新提交,但还没有任何东西在使用新提交。要使用新提交,你还需要第二步。
    最初,第二步总是git mergegit merge命令相当大且复杂,但它的含义很容易描述:***Merge * 意味着 * 合并工作 *。**Git会尝试使用简单而愚蠢的自动化规则来获取你已经完成的工作(如果你已经完成了)和他们已经完成的工作(如果他们已经完成了),并合并这些工作。这些规则不知道你是如何或为什么完成这些工作的,或者你所做的任何改变 * 意味着 * 什么。它们只是基于diffs中的"行"来工作。
    然而,这里有四种可能性:
  • 也许你没有做任何工作,他们也没有做任何工作。你没有得到新的提交。实际上没有什么事情要做,git merge也没有做任何事情。
  • 也许你做了一些工作,而他们什么也没做;没有新的提交;没有什么可做的,git merge也没有做什么。
  • 也许你什么都没做,而他们做了一些工作。你得到了一些新的提交。将你的工作不足与他们的实际工作结合起来是很容易的,如果你允许的话,git merge会走捷径。
  • 也许你和他们都成功了。你有新的提交 你从他们那里得到了新的提交,git merge必须使用它简单而愚蠢的规则来合并工作。Git在这里不能走任何捷径,你会得到一个全面的合并。

Git * 可能 * 能够采取的捷径是在向前拖动分支名称的同时检查他们最近的提交。git merge命令称之为 * fast-forward merge *,尽管实际上并没有涉及到 * merge *。这种不真正的合并是微不足道的,而且通常非常安全:唯一可能出错的是最近一次提交没有正常运行(在这种情况下,你可以回到旧版本)。因此,"快进"合并是非常友好的:没有复杂的逐行合并规则会出错。许多人喜欢这种"合并"。
有时候捷径是不可能的,有时候有些人不 * 希望 * Git走捷径(出于某些原因,我们不会在这里讨论,以保持这个答案简短,或简称为我)。有一种方法可以告诉git merge * 不要走捷径,即使你可以 *。
因此,仅对于git merge,就有三种可能性:

  • 无事可做(并且git merge总是愿意无事可做);
  • 快进是可能的,但也许Git不应该这么做;以及
  • 快进是不可能的,这意味着这个合并不是微不足道的。

git merge命令有一些选项,可以告诉它在除"nothing to do"之外的所有情况下要做什么:

  • (无标志):如果可能,进行快进,如果不可能,尝试真正的合并。
  • --ff-only:如果可以的话就快进,如果不行,就报一个错误,说不能快进;不要尝试合并。
  • --no-ff:即使可以快进,也不要使用快捷方式:在每种情况下尝试完全合并(当然除了"无事可做"的情况)。

git pull命令接受所有这些标志,并将它们传递给git merge(如果您选择让git pull运行git merge作为其步骤2)。

但是等等,还有更多

并不是每个人都希望Git进行合并,假设你做了一个或两个新的提交,我们称之为IJ,而你的git fetchorigin带来了两个新的提交,我们称之为KL,这就给了你一个提交集,如果你要绘制它们,可能看起来像这样:

I--J   <-- your-branch
         /
...--G--H   <-- main
         \
          K--L   <-- origin/main

您可以 * 快进 * 您的main以匹配他们的origin/main

I--J   <-- your-branch
         /
...--G--H
         \
          K--L   <-- main, origin/main

而且,无论你是否这样做,你都可以将你的提交J与他们的提交L合并,生成一个新的合并提交M

I--J
         /    \
...--G--H      M   <-- your-branch (HEAD)
         \    /
          K--L   <-- origin/main

但是有些人更喜欢 * rebase * 他们的提交--在这个例子中是IJ--这样他们就 * 在 * 提交L之后,所以现在的情况看起来像这样:

I--J   [abandoned]
         /
...--G--H--K--L   <-- origin/main
               \
                I'-J'  <-- your-branch

这里,我们将IJ * 复制-到新的和改进的提交I'J'中,这些提交对L做了与I-JH所做的相同的 * 更改 *。但是这些提交有不同的大丑陋哈希ID,看起来像是在origin的家伙提交了他们的K-L之后才提交的。
git pull命令可以执行这种重定基准:

git switch your-branch
git pull --rebase origin main

运行git fetch来获取提交,然后使用正确的参数运行git rebase,让Git将I-J复制到I'-J',如上图所示。它可能有合并冲突,你必须先解决-Git会移动分支名称your-branch来选择最后一次复制的提交:J',在这个例子中。
git pull编写后不久,就添加了--rebase。由于许多人希望这种事情 * 自动 * 发生,git pull获得了 * 默认 * 使用--rebase的能力。您已将分支配置为执行此操作(通过将branch.*branch*.rebase设置为true)和git pull将为您执行一个重定基操作。(注意,重定基操作所基于的提交现在取决于两件事:分支的 upstream 设置,以及一些可以传递给git pull的参数(我在这个例子中明确地说明了一些事情,这样我们就不必担心更小的细节,但实际上,你需要担心)。
这让我们回到2006年或2008年左右
在Git的开发过程中,我们有:

  • git fetch:从其他地方(例如“上游”或origin仓库)获取新提交,通常更新origin/*风格的远程跟踪名称;
  • git merge:不执行任何操作,或者快进,或者真合并某个指定的提交或分支的上游;
  • git rebase:使用指定的提交或分支的上游提交,将一组现有提交复制到新的和改进的提交,然后放弃原始提交,使用副本提交;以及
  • git pull:使用分支的上游参数或显式参数,运行git fetch,然后运行git mergegit rebase

因为git merge可以接受--ff-only--no-ff参数,所以git pull必须能够将这些参数传递给git merge * 如果 * 我们使用git merge
随着时间的推移,更多的选项开始出现,比如自动隐藏、rebase的“分叉点”等等,而且,事实证明,很多人都希望将rebase作为git pull的默认设置,所以Git获得了一个新的配置选项branch.autoSetupRebase,当设置为remotealways时,这正是这些人想要的(尽管今天实际上有四种设置;我不记得当时它有没有四个,也懒得去检查)。

时间继续前进,我们来到了21世纪20年代

到目前为止(2020年到2022年之间),git pull对很多,甚至是大多数Git新手来说都是“错误的"。我个人的建议是"避免”git pull。首先运行git fetch,然后查看git fetch的内容。然后,如果git fetch执行了很多操作,接下来可能会使用git log。* 然后 ,一旦您确定是要使用git merge的任意选项,还是要使用git rebase的任意选项, 运行该命令 *。**如果您使用此选项,你可以完全控制一切。你可以决定发生什么,而不是从Git那里得到一些惊喜。**我喜欢这个选项:这很简单!2当然,你需要运行至少两个命令。3但是你可以在这两个命令之间运行额外的命令,这会很有用。
尽管如此,如果git pull带来了 * 可以 * 合并到git merge --ff-only下的新提交,这通常会变成我想要的:快进,或者停下来,让我看看周围,决定是要重定基、合并,还是其他我可能想要的东西。[1]这通常也是其他人想要的,现在git pull,运行时没有任何参数,可以直接告诉它这样做:

git config --global pull.ff only

实现了这一点。
与此同时,你在问题中提示的另外两个git config --global命令使第二个命令成为merge或rebase。因此,现在,在2022年,告诉git pull做 * 我 * 希望它做的事情是很容易的。此外,Git维护者似乎已经接受了我的观点:git pull * 没有 * 一些预先考虑是 * 坏 * 的,新手不应该使用它,所以他们设置了git pull,现在它 * 要求 * 你选择这三个选项中的一个,如果你想不带参数运行它。
所以,你需要选择一个。旧的 * 默认值 * 是 * git config pull.rebase false,但这是一个糟糕的默认值。我不推荐它。我 * 推荐 * git config pull.ff only(尽管由于15年以上的习惯,我实际上还没有使用它)。

1一个真实的例子:我遇到了一些bug,这对我来说是个问题。我对我知道是错误的代码做了一个修改,但让我完成了我的工作。我提交了这个可怕的黑客攻击。然后我等待上游做出修改。他们做了修改,我带来了新的提交。如果他们已经修复了bug,我想放弃我的修复,而不是合并或重新定位它。如果他们还没有修复bug,我想重新设置我的hack(可能需要也可能不需要一些调整)。“他们修复了bug吗”测试需要一些git pull自己无法测试的东西。
2请注意,运行带 * 参数的git pull * 不应该产生这种抱怨,我运行它的次数仍然不多,所以我不太确定bug是什么,但是在新特性实现的头一两轮中,git pull有一个错误会不适当地抱怨。我相信它在2.35中得到了修复,并且几乎肯定它在2.36中得到了修复,应该随时都能出来。

kxxlusnw

kxxlusnw2#

我在使用Visual Studio时遇到了这个问题-以下命令为我解决了这个问题

git config pull.rebase false
avwztpqn

avwztpqn3#

我遇到了同样的问题。为我解决这个问题的是运行以下代码行:

git config pull.rebase false
git pull
git commit -m "my commit message"
git push

然后,再次运行“git status”,检查是否一切正常。

相关问题