由于您当前分支的尖端不在后面,因此更新被拒绝-但是为什么呢?

时间:2020-02-12 21:05:19

标签: git git-rebase

这个问题已经从另一个角度here得到了回答。但是我的问题是试图理解为什么这个问题首先出现。我一直在工作中遇到此问题,建议的解决方案并不能太令人满意,因为它不能真正解决问题本身,并且存在丢失提交的危险。

下面您会发现我发现的最短git交互序列,可以重现该错误:

import numpy as np
# Define matrices M and S
M= np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
H = np.array([0.1, 0.2, 0.3])
# Define matrix S with: S[0] = [0,0,0,0] and S[r>0][c] = M[r][c]xH[r]
S = np.array([[x if r != 0 else 0 for x in [M[r][c] * H[r] for c in range(0, len(M[r]))]] for r in range(len(M))])
# initialize matrix L
L = np.array(np.zeros((int(len(M)),int(len(M[0])))))
#Update Matrix L: L[r][c] = Sum[S[0][c] to S[i=r-1][c]]
for r in range(0, len(L)):
        L[r] = [sum([row[i] for row in S[0:r+1]]) for i in range(0,len(S[0]))]
print("S", S)
print("L", L)

我只是简单地在master中发布文件m,然后在feature中发布文件f,然后在master中提交更改,然后在feature中提交更改。现在,在将更改推送到远程功能分支之前,我想将其重新基于master。

这是命令和上面列表中最后一条命令的错误消息:

   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)

现在-我尝试通过首先从远程功能中拉出(按照消息中的建议)来解决问题,然后解决冲突,并推送至功能:

➜  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.

但是-从现在开始-每次我基于master重新设置功能时,我都会一次又一次地遇到该错误-一次合并冲突,一次又一次该错误。

➜  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

我不明白!

我的意思是-我想做的就是简单地应用以下工作流程:

  • 更改本地要素分支
  • 准备并提交更改
  • git rebase master
  • git push原点功能

我的说法很简单-在将提交推送到远程功能之前,我想在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. git pull origin master),那么我就不会遇到该问题。

我希望这不会太令人困惑,但是我不知道如何简化它,这真的让我很烦。

2 个答案:

答案 0 :(得分:3)

快速的答案是不要重新建立上游分支的基础,此链接说明了问题和解决方案: https://git-scm.com/docs/git-rebase#_recovering_from_upstream_rebase

最基本的选择可能是: 从您的示例开始,错误行之前的分支如下所示:

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

执行时

$ git push origin feature

由于分支的提交方式不同,因此您尝试将分支功能更改为原始/功能是不可能的。

因此您可以删除远程分支的起源/功能

  1. 未设置上游

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

    $ git push origin --delete feature
    
  3. 将更改添加到上游

    $ git push -u origin feature
    

分支这样结束

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

根据此示例,提交b5b045具有提交f043b50的更改,因此不会丢失更改,您可以使用

进行检查
$ git diff f043b50 b5b045

答案 1 :(得分:3)

问题的根源在于您正在重新定购feature。这是一种草率的表达方式:无关紧要的是分支名称,重要是提交的。但是,rebase的工作原理是将一些提交复制到新的(据说是经过改进的)不同的提交中。这要求扔掉(或放弃)旧的(现在很糟糕的)提交。

git push命令调用另一个Git并将其新的和改进的feature提交发送给他们,然后要求其他Git存储库丢弃旧的(现在很糟糕) )提交。它说:不!如果我问你一个问题,我会丢失一些宝贵的承诺!此投诉以这种形式返回:

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

non-fast-forward 错误是另一个Git告诉您的方法,如果它遵循您的礼貌要求更改名称feature以命名新的和改进的提交, ve建议使用它,这将丢失旧的(已被新的和改进的)提交。

当然,这正是您想要要做的。注意:您是否应该执行此操作取决于使用此其他Git存储库的其他所有人(GitHub上的其他人)是否事先同意这会发生。

要使另一个Git(GitHub上的Git)同意放弃其存储库中的提交,必须在此特定的git push操作上设置一个“ force flag”。但是,有两种不同的强制标志:

  • 一般部队:我命令您,其他Git存储库,以这种方式设置分支名称!这是简单有效的方法,不仅丢弃了您替换的旧的和糟糕的提交通过rebase进行新的和改进的提交,还其他人添加的所有其他提交,而您没有用新的改进的副本代替。 (这是其中一个原因,使用此GitHub存储库的每个人都必须事先 同意重新部署。)

  • 强制租赁:我命令您(另一个Git存储库)将分支名称中存储的哈希ID与我认为的值进行比较。如果它们相等,则应使用我现在提供的新值替换该值。 > new 表示您失败无法重新设置基准,那么“强制租用”操作将失败。 GitHub上的另一个Git会说:我存储的哈希ID与您认为的我的ID不匹配。所以我根本不接受您的命令。

如果您和该GitHub存储库的所有其他用户已预先同意可以进行重新基准化,并且您认为某人可能在不使用时提交了一些提交,则应使用--force-with-lease选项到git push来确定是否确实如此。

如果GitHub存储库中没有其他用户(或者他们都没有使用feature分支),则这些都没有必要,您可以简单地使用git push --force。您唯一需要同意的人就是您自己:您是否允许自己强行推feature分支?如果是这样,您可以强行推feature分支。

请注意,如果还有 个其他用户,并且您和他们都同意此强制推送重新设置过程,则您和他们必须 all 注意观察任何强制更新并对所有没有被复制到新的和改进的提交中的提交做自己的基础。这是一个相当复杂的工作流程。确保您和您的所有朋友/同事都已做好准备。