由于master中的奇怪变化,无法推分支

Lan*_*erX 2 git push

我在分公司工作,让我们说出来mybranch.我不修改master.我想推动改变,origin/feature/mybranch但我有一些问题.奇怪的是我之前做过几次并没有任何问题.

$ git branch
develop
* feature/mybranch
master


$ git push
To http://......
! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'http://....'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration variable
hint: to 'simple', 'current' or 'upstream' to push only the current branch.
Run Code Online (Sandbox Code Playgroud)

什么?主?!所以让我们检查一下master.

$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
 (use "git pull" to update your local branch)


$ git pull
Updating 45c7319..f6b8e97
error: Your local changes to the following files would be overwritten by merge:
    platform/....java
    services/....java
    ...

Please, commit your changes or stash them before you can merge.
Aborting
Run Code Online (Sandbox Code Playgroud)

这显示了7个修改过的文件

$ git status
# On branch master
# Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.

#   (use "git pull" to update your local branch)
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   platform/....java
#       modified:   algorithms/....java
#       ...
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       algorithms/.../
#       and over 1100 files in bin folder. I don't know why gitignore doesn't work now.
Run Code Online (Sandbox Code Playgroud)

这显示了17个(不是上面的7个)修改过的文件.很奇怪......没关系.这些不是我的改变,我想丢弃它们.

$ git checkout -f
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
Run Code Online (Sandbox Code Playgroud)

我仍然有master...... 这些奇怪的变化......

tor*_*rek 13

第1部分:完成您的推动而不必担心 master

(注意:实际上,它已经完成了.请参阅第1部分底部的注释.)

git push没有额外的参数运行.

如果再运行git push两个参数,它们会准确指定要在哪里推送.git文件称之为<repository><refspec>.

在你的情况下,存储库总是origin(这是克隆东西时git设置的通常标准).所以这refspec是更有趣的部分.

这是长1形式:

git push origin feature/mybranch:feature/mybranch
Run Code Online (Sandbox Code Playgroud)

这限制了GIT中只尝试把你的分支feature/mybranch,告诉遥控器,origin,它应该更新分支feature/mybranch方太.

如果省略该:<same-name>部分,则默认使用冒号左侧的分支名称,因此:

git push origin feature/mybranch
Run Code Online (Sandbox Code Playgroud)

完全相同的事情,命令输入少一点.

现在,当你离开时会发生什么<refspec>?答案是在git pushgit config文档中,虽然在我的1.8.4.3文本版本中它很难阅读,而我上面链接的在线版本,如果有的话,更糟糕的是:-)

当命令行没有指定使用<refspec> ... arguments或--all, - mirror, - batgs选项推送什么时,该命令通过查询remote.*.push configuration来查找默认值,如果是没有找到,尊重push.default配置决定推送什么(请参阅gitlink:git-config [1]了解push.default的含义).

为了简化这个有很多,我可以告诉2,你有没有设置任何remote.origin.pushpush.default,所以你得到的"默认默认",这就是所谓matching的,这意味着你的git push电话了origin隐喻的网络电话上说:

嘿,你有什么分支?

它说:

我有masterfeature/mybranch.

所以你的git然后说:

好吧,这就是我认为master应该是的,这就是我认为feature/mybranch应该是的.

他说:

哇,伙计,这会master挫败几个转速!

......那就是你得到的! [rejected] master -> master (non-fast-forward)东西.

所以,有几个非常简单的解决方案.

解决方案#0:什么都不做

如果您仍然可以使用原始push输出,那么您应该可以看到如下内容:

   a430f6d..676699a  feature/mybranch -> feature/mybranch
 ! [rejected]        master -> master (non-fast-forward)
Run Code Online (Sandbox Code Playgroud)

这意味着即使更改master -> master被拒绝,也会feature/mybranch -> feature/mybranch接受更改.你想要推动的分支,你做到了!你刚刚得到这个令人讨厌的错误信息就成功了(现在你想知道如何处理分支master).

解决方案#1:明确表示 push

如果您运行:

git push origin feature/mybranch
Run Code Online (Sandbox Code Playgroud)

你的Git和Origin的Git会有一个较短的对话.而不是你的Git问他"嘿,whaddaya到了那里?" 然后尝试推送所有 "匹配"分支,你的只会说:"我有一些更新feature/mybranch".你落后的事实master将是无关紧要的; 你和你的Git,以及远程Git都不会看到那里.

解决方案#2:改变你的想法 push.default

这只适用于你的git足够新,但到目前为止,大多数是:

git config --global push.default simple
Run Code Online (Sandbox Code Playgroud)

Git 人员计划将更改(从Git版本2.0开始)更改为"默认默认值",因为matching在很多时候,结果会变得比有用更烦人.新的"默认默认值"将是simple.(有关这意味着什么的详细信息,请参阅git配置文档.)

(设置--global版本将更改您的默认默认值,但不会更改为其他人.如果任何存储库 - 您自己或其他人 - 具有本地push.default设置,将覆盖您的个人全局设置,但对于那些没有,您的全局设置是git将使用的.您可以选择在每个仓库中设置本地设置,这将影响您和使用您自己的仓库的任何其他人,但是您需要记住在所有仓库中设置它.)


1实际上这只是半长形式:您可以refs/heads/在每个分支名称前面添加它以使其更长.那只是为了炫耀.:-)

2我猜,真的,但这是一个非常安全的赌注.配置remote.origin.push并且push.default可能已经知道所有这些东西的人.


第2部分:为什么不master更新?

我对此不太确定,但看起来好像有人意外地将一堆(17).java二进制文件提交到master分支中,可能是因为没有正确的.gitignore.

在某些时候,他们注意到,哎呀,不想要所有这些二进制文件!所以他们更新.gitignore并承诺了这一点,但可能实际上并没有git rm --cached全部,所以有些仍然被跟踪.如果现在列出的文件被忽略,那么git"服从提交"而不是ignore指令,你会得到很多:

# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   bin/b1
Run Code Online (Sandbox Code Playgroud)

根据您git add.gitignore库存中的内容,可以添加存储库中的跟踪文件(覆盖忽略条目),并使它们"暂存以提交"并提交它们.

在任何情况下,你master的两个转速落后,并且肯定有一些二进制文件 - 你的feature/mybranch分支可能有一个"坏" .gitignore(它的一些变化),也不会忽略二进制文件的"正确设置".

Git注意到你的7个二进制文件(可能是用你的功能分支功能重新构建的)与分支上签入的内容不匹配master.这些将被"不安全地"破坏(至少,就git而言).如果/当你这么做git checkout -f master(或等同的东西)时,git会破坏它们,但你仍然留下"未跟踪"的文件,暗示一个坏的.gitignore.

一旦你确定在你的工作树中破坏任何东西是安全的 - 你已经把所有工作都省去了 - 你可以这样做来重新同步你masterorigin/master:

git checkout -f master
git fetch   # resync with origin in case they've fixed more stuff
git reset --hard origin/master
Run Code Online (Sandbox Code Playgroud)

假设您不想在分支中使用二进制文件,请检查各种.gitignore文件并确保它们是正确的 - 您可能需要修复一些文件.然后,使用git ls-files和/或git ls-tree查看索引和repo中的内容(git ls-tree要求您指定特定的树对象,例如,git ls-tree HEAD:bin查看bin树中的内容,如果存在).

要删除已提交(即使忽略)的文件,例如,删除以下内容中的所有内容bin:

git rm --cached -r bin
Run Code Online (Sandbox Code Playgroud)

(--cached说只删除索引中的东西),或者你可以允许git删除二进制文件.一旦你有正确的东西"git rm"-ed和任何更新的.gitignore文件添加,git commit改变:

$ cat bin/.gitignore
*
!.gitignore
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   bin/.gitignore
#   deleted:    bin/b1
#   deleted:    bin/b2
#
$ git commit -m 'remove binaries, ignore them in the future'
[master ac60888] remove binaries, ignore them in the future
 3 files changed, 1 insertion(+)
 create mode 100644 bin/.gitignore
 delete mode 100644 bin/b1
 delete mode 100644 bin/b2
Run Code Online (Sandbox Code Playgroud)

(最后,根据需要重建任何已删除的二进制文件,运行测试,在适当的情况下执行推送等)

(这有可能是你希望.java在树枝上的二进制文件,或者你没有,但没有一个人搞掂任何.gitignore条目,等等;所以这就是为什么我对这个肯定要少得多.)