简体   繁体   English

更新被拒绝,因为您当前分支的提示落后 - 但为什么?

[英]Updates were rejected because the tip of your current branch is behind - but why?

This question has been answered from another perspective here .这个问题已经从另一个角度回答了这里 But my question is about trying to understand why this problem arises in the first place.但我的问题是首先试图理解为什么会出现这个问题。 I have been running into this issue at work and the suggested solution is not overly satisfying as it doesn't really address the issue itself and comes with the danger of losing commits.我在工作中一直遇到这个问题,建议的解决方案并不过分令人满意,因为它并没有真正解决问题本身,并且有丢失提交的危险。

Below you'll find the shortest sequence of git interaction I found to reproduce the error:您将在下面找到我发现的最短的 git 交互序列来重现错误:

   git clone git@github.com:joyofdata/test3.git
   cd test3
   echo "1" > m
   git add .
   git commit -m "m1"
   git push origin master

   git checkout -b feature
   git push -u origin feature
   echo "1" > f
   git add .
   git commit -m "f1"
   git rebase master
   git push origin feature

   git checkout master
   echo "2" >> m
   git add .
   git commit -m "m2"
   git push origin master

   git checkout feature
   echo "2" >> f
   git add .
   git commit -m "f2"
   git rebase master
   git push origin feature (error - see next code box)

I simply version a file m in master, then a file f in feature, then I commit a change in master, then I commit a change in feature.我只是在 master 中对文件 m 进行版本控制,然后在 feature 中对文件 f 进行版本控制,然后在 master 中提交更改,然后在功能中提交更改。 Now before pushing my change to remote feature branch I want to rebase it on master.现在,在将我的更改推送到远程功能分支之前,我想将其重新设置在 master 上。

This is the command and the error message of the last command in above list:这是上面列表中最后一个命令的命令和错误消息:

➜  test3 git:(feature) git push origin feature
To github.com:joyofdata/test3.git
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'git@github.com:joyofdata/test3.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Now - I try to solve the issue by first pulling from remote feature (as suggested in the message), then I resolve the conflict, push to feature:现在 - 我尝试通过首先从远程功能中提取(如消息中建议的那样)来解决问题,然后解决冲突,推送到功能:

➜  test3 git:(feature) git pull origin feature
From github.com:joyofdata/test3
 * branch            feature    -> FETCH_HEAD
Auto-merging f
CONFLICT (add/add): Merge conflict in f
Automatic merge failed; fix conflicts and then commit the result.

➜  test3 git:(feature) ✗ vim f
➜  test3 git:(feature) ✗ git add .
➜  test3 git:(feature) git commit -m "deconflicted"
[feature 3fb647e] deconflicted

➜  test3 git:(feature) git push origin 
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 565 bytes | 565.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To github.com:joyofdata/test3.git
   0f31f60..3fb647e  feature -> feature

But - from now on - I'm going to run again and again and again into that error every time I rebase feature on master - again a merge conflict and again that error.但是 - 从现在开始 - 每次我在 master 上重新设置功能时,我都会一次又一次地运行该错误 - 再次发生合并冲突,再次出现该错误。

➜  test3 git:(feature) git rebase master
First, rewinding head to replay your work on top of it...
Applying: f1
Applying: f1
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
Applying: f2

➜  test3 git:(feature) git push origin  
To github.com:joyofdata/test3.git
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'git@github.com:joyofdata/test3.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

I don't get it!我不明白!

I mean - what I want to do is simply applying the following workflow:我的意思是 - 我想要做的只是应用以下工作流程:

  • change in local feature branch本地功能分支的变化
  • stage and commit that change阶段并提交该更改
  • git rebase master git rebase 大师
  • git push origin feature git push 原点功能

I simple terms - before pushing a commit to remote feature I want to rebase feature on master.我简单地说 - 在推送对远程功能的提交之前,我想在主控上重新设置功能。 If I merge master into feature ( git pull origin master or git merge master if local master is up to date) then I don't run into that issue.如果我将 master 合并到 feature 中( git pull origin mastergit merge master如果本地 master 是最新的),那么我不会遇到这个问题。

I hope this isn't too confusing but I don't know how to put it more simple and it's really annoying me.我希望这不会太令人困惑,但我不知道如何说得更简单,这真的让我很烦。

The quick answer is don't rebase upstream branches, this link explains the problem and the solution: https://git-scm.com/docs/git-rebase#_recovering_from_upstream_rebase快速回答是不要重新设置上游分支,此链接解释了问题和解决方案: https : //git-scm.com/docs/git-rebase#_recovering_from_upstream_rebase

A rudimentary option could be this: Starting from your example, before the error line the branches looks like this:一个基本的选项可能是这样的:从你的例子开始,在错误行之前,分支看起来像这样:

$ git log --pretty=oneline --graph --all
* b5b045591ec6584e8f896d85399b7ed5b08d8098 (HEAD -> feature) f2
* 5187c95d6d91b550b9b2cc10ad673a52add620f6 f1
* cea62f3fd0349390115ee5e263730656b7a52d2d (origin/master, master) m2
| * f043b50940593c1ded4631f3681420ad57c0b190 (origin/feature) f1
|/
* 4847339d95d8f02c25538da7e51be14cbb30530d m1

when execute执行时

$ git push origin feature

You try to include changes from branch feature to origin/feature wich is imposible because they have diferent commits.您尝试包含从分支功能到原点/功能的更改,这是不可能的,因为它们具有不同的提交。

So you can delete the remote branch origin/feature所以你可以删除远程分支源/功能

  1. Unset upstream取消上游设置

    $ git checkout feature $ git branch --unset-upstream
  2. Remove remote branch删除远程分支

    $ git push origin --delete feature
  3. Push your changes adding upstream将您的更改推送到上游

    $ git push -u origin feature

Branch ends like this分支是这样结束的

$ git log --pretty=oneline --graph --all
* b5b045591ec6584e8f896d85399b7ed5b08d8098 (HEAD -> feature) f2
* 5187c95d6d91b550b9b2cc10ad673a52add620f6 f1
* cea62f3fd0349390115ee5e263730656b7a52d2d (origin/master, master) m2
* 4847339d95d8f02c25538da7e51be14cbb30530d m1

According to this example the commit b5b045 has the changes of commit f043b50 so there is not losing changes, you can check with根据此示例,提交 b5b045 具有提交 f043b50 的更改,因此不会丢失更改,您可以检查

$ git diff f043b50 b5b045

The root of the problem is that you are rebasing your feature .问题的根源在于您正在重新设定您的feature This is a sloppy way to phrase it: it's not the branch name that matters, it is the commits that matter.这是一种草率的表述方式:重要的不是分支名称,重要的是提交 But rebase works by copying some commits, to new and (supposedly) improved different commits.但是 rebase 通过将一些提交复制到新的和(据说)改进的不同提交来工作。 This require throwing away —or abandoning—the old (and now lousy) commits.这需要扔掉——或放弃——旧的(现在很糟糕)的提交。

The git push command calls up another Git and sends them your new and improved feature commits, then asks that other Git repository to throw away its old (and now lousy) commits. git push命令调用另一个 Git 并将您的新的和改进的feature提交发送给他们,然后要求其他 Git 存储库丢弃其旧的(现在很糟糕)的提交。 It says: No!它说:不! If I do ask you ask, I'll lose some precious commits!如果我问你问,我会失去一些宝贵的承诺! This complaint comes back in this form:此投诉以这种形式返回:

 ! [rejected] feature -> feature (non-fast-forward)

The non-fast-forward error is the other Git's way of telling you that if it obeyed your polite request to change its name feature to name the new and improved commits you've suggested it use, this would lose the old (outdated by new-and-improved) commits.非快进错误是另一种 Git 告诉你的方式,如果它服从你的礼貌请求,改变它的名称feature来命名你建议它使用的新的和改进的提交,这将失去旧的(新的已经过时) -and-improved) 提交。

Of course, that's precisely what you want it to do.当然,这正是你想要它做的。 Note: whether you should do this depends on whether everyone else who uses this other Git repository—the one over on GitHub—has agreed in advance that this is going to happen.注意:您是否应该这样做取决于使用另一个 Git 存储库的其他人(GitHub 上的那个)是否已经事先同意这将会发生。

To make the other Git, the one over on GitHub, agree to discard commits from its repository, you must set a "force flag" on this particular git push operation.为了让另一个 Git,即 GitHub 上的那个,同意放弃其存储库中的提交,您必须在这个特定的git push操作上设置一个“强制标志”。 There are two different kinds of force flag, though:但是,有两种不同类型的强制标志:

  • General force: I command you, other Git repository, to set your branch name this way!通用力:我命令你,其他 Git 仓库,这样设置你的分支名称! This is simple and effective and discards not only the old and lousy commits you've replaced with new and improved commits via rebase, but also every other commit that anyone else added that you didn't also replace with a new and improved copy.这是简单而有效的和丢弃,不仅你通过重订新的和改进的提交取代了旧的和糟糕的提交,而且每隔提交其他任何人补充你不有新的和改进的副本替换。 (That's one reason, of several, that everyone who uses this GitHub repository must agree in advance that rebasing will happen.) (这是使用此 GitHub 存储库的每个人都必须事先同意将发生变基的几个原因之一。)

  • Force-with-lease: I command you, other Git repository, to compare the hash ID stored in your branch name to the value I think you have. Force-with-lease:我命令您,其他 Git 存储库,将存储在您的分支名称中的哈希 ID 与我认为您拥有的值进行比较。 If they are equal, you should then replace that value with the new value I am supplying now.如果它们相等,那么您应该用我现在提供的新值替换该值。 This variant of force-push is safer: if you rebased some commits, but someone else has, since then, added new commits that you failed to rebase, your force-with-lease operation will fail. force-push 的这种变体更安全:如果您重新调整某些提交的基础,但此后其他人添加了您未能重新调整基础的提交,则您的 force-with-lease 操作将失败。 The other Git, over at GitHub, will say: The hash ID I had stored does not match the one you said you thought I had. GitHub 上的另一个 Git 会说:我存储的哈希 ID 与您说的您认为我拥有的不匹配。 So I did not accept your command after all.所以我终究没有接受你的命令。

If you and all other users of this GitHub repository have agreed in advance that rebasing can happen, and you think someone might have snuck in a few commits while you weren't looking, you should use the --force-with-lease option to git push to find out whether that's actually the case.如果您和此 GitHub 存储库的所有其他用户事先同意可以进行变基,并且您认为有人可能在您不注意的情况下偷偷地提交了一些提交,则应该使用--force-with-lease选项git push以了解是否确实如此。

If there are no other users of the GitHub repository (or none of them use the feature branch), none of this is necessary and you can simply use git push --force .如果 GitHub 存储库没有其他用户(或他们都没有使用feature分支),则这些都不是必需的,您可以简单地使用git push --force The only person you need to agree with is yourself: do you give yourself permission to force-push the feature branch?您唯一需要同意的人就是您自己:您是否允许自己强制推送feature分支? If so, you may force-push the feature branch.如果是这样,您可以强制推送feature分支。

Note that if there are other users, and you and they all agree to this force push rebase process, you and they must all take care to observe any forced updates and do your own rebasing of any commits that didn't get copied to new and improved commits yet.请注意,如果其他用户,你和他们都同意这一点力推rebase过程,你和他们必须照顾遵守任何强制更新,做你自己认为没有被复制到任何新的提交重订基期和改进提交。 This is a fairly complex work-flow;这是一个相当复杂的工作流程; be sure that you and all of your friends / co-workers are ready for it.确保您和您所有的朋友/同事都准备好了。

暂无
暂无

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

相关问题 更新被拒绝,因为您当前分支的尖端在后面...不正确 - Updates were rejected, because the tip of your current branch is behind… Not true Git 更新被拒绝,因为您当前分支(主)的尖端在后面但是分支是最新的? - Git Updates were rejected because the tip of your current branch (main) is behind BUT branch is up to date? GitLab 更新被拒绝,因为您当前分支的尖端落后于其远程对应分支 - GitLab Updates were rejected because the tip of your current branch is behind its remote counterpart Gradle-release-plugin 更新被拒绝,因为您当前分支的尖端落后 - Gradle-release-plugin Updates were rejected because the tip of your current branch is behind 源树推送:提示:更新被拒绝,因为当前分支的尖端落后 - Source Tree Push : hint: Updates were rejected because the tip of your current branch is behind Github 错误“更新被拒绝,因为您当前分支的提示落后” - Github error "Updates were rejected because the tip of your current branch is behind" git:“更新被拒绝,因为您当前分支的尖端落后..”但是如何查看差异? - git: "Updates were rejected because the tip of your current branch is behind.." but how to see differences? 如何解决 git 错误:“更新被拒绝,因为您当前分支的提示落后了” - How to resolve git error: "Updates were rejected because the tip of your current branch is behind" 更新被拒绝,因为你当前分支的尖端落后于它的远程分支 - Updates were rejected because the tip of your current branch is behind its remote counterpart 收到错误“更新被拒绝,因为您当前分支的提示落后了” - Getting error “Updates were rejected because the tip of your current branch is behind”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM