如何正确地推一个Git ?

时间:2021-07-14 16:23:48

I've set up a remote non-bare "main" repo and cloned it to my computer. I made some local changes, updated my local repository, and pushed the changes back to my remote repo. Things were fine up to that point.

我设置了一个远程的非裸“main”repo并将其克隆到我的计算机上。我做了一些本地更改,更新了本地存储库,并将更改推回远程repo。到那时为止一切都很好。

Now, I had to change something in the remote repo. Then I changed something in my local repo. I realized that the change to the remote repo was not needed. So I tried to git push from my local repo to my remote repo, but I got an error like:

现在,我得在遥控器上换些东西。然后我在本地回购中改变了一些东西。我意识到不需要对远程repo进行更改。因此,我试图从本地repo推到远程repo,但我得到了一个错误,比如:

To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes before pushing again. See the 'Note about fast-forwards' section of git push --help for details.

为了防止您丢失历史,在再次推动之前,不快速前进的更新被拒绝合并远程更改。查看git推送的“快速转发”部分——帮助了解细节。

I thought that probably a

我想可能是a

git push --force

would force my local copy to push changes to the remote one and make it the same. It does force the update, but when I go back to the remote repo and make a commit, I notice that the files contain outdated changes (ones that the main remote repo previously had).

将强制我的本地副本将更改推到远程副本并使其相同。它会强制更新,但是当我回到远程repo并提交时,我注意到文件包含过时的更改(主远程repo以前有过的更改)。

As I mentioned in the comments to one of the answers:

正如我在对其中一个答案的评论中提到的:

[I] tried forcing, but when going back to master server to save the changes, i get outdated staging. Thus, when i commit the repositories are not the same. And when i try to use git push again, i get the same error.

[I]尝试强制执行,但是当返回到主服务器保存更改时,我得到了过时的暂存。因此,当我提交存储库时,它们并不相同。当我尝试再次使用git push时,我得到了相同的错误。

How can I fix this issue?

我如何解决这个问题?

7 个解决方案

#1


1653  

Just do:

只做:

git push origin <your_branch_name> --force

or if you have a specific repo:

或者如果你有特定的回购:

git push https://git.... --force

This will delete your previous commit(s) and push your current one.

这将删除之前的提交并推送当前提交。

It may not be proper, but if anyone stumbles upon this page, thought they might want a simple solution...

这可能是不恰当的,但是如果有人偶然发现这一页,他们可能想要一个简单的解决方案……

Short flag

Also note that -f is short for --force, so

还要注意-f是力的缩写

git push origin <your_branch_name> -f

will also work.

也会工作。

#2


194  

And if push --force doesn't work you can do push --delete. Look at 2nd line on this instance:

如果push——force不工作,你可以做push——删除。在这个例子中,请看第二行:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push

But beware...

但是要小心…

Never ever go back on a public git history!

In other words:

换句话说:

  • Don't ever force push on a public repository.
  • 不要强行推动公共存储库。
  • Don't do this or anything that can break someone's pull.
  • 不要这样做或做任何会破坏别人吸引力的事情。
  • Don't ever reset or rewrite history in a repo someone might have already pulled.
  • 不要用别人可能已经提取的回购操作来重置或重写历史。

Of course there are exceptionally rare exceptions even to this rule, but in most cases it's not needed to do it and it will generate problems to everyone else.

当然,即使是这条规则也有例外的情况,但在大多数情况下不需要这样做,它会给其他人带来问题。

Do a revert instead.

And always be careful with what you push to a public repo. Reverting:

对你向公众推销的东西一定要小心。回复:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

In effect, both origin HEADs (from the revert and from the evil reset) will contain the same files.

实际上,两个源头(从恢复和恶意重置)将包含相同的文件。


edit to add updated info and more arguments around push --force

Consider pushing force with lease instead of push, but still prefer revert

Another problem push --force may bring is when someone push anything before you do, but after you've already fetched. If you push force your rebased version now you will replace work from others.

另一个问题推——力可能带来的是当有人在你之前推了什么东西,但在你已经拿过东西之后。如果你现在推动你的基于基础的版本,你将取代其他人的工作。

git push --force-with-lease introduced in the git 1.8.5 (thanks to @VonC comment on the question) tries to address this specific issue. Basically, it will bring an error and not push if the remote was modified since your latest fetch.

git push——git 1.8.5中引入的force-with-lease(感谢@VonC对这个问题的评论)试图解决这个特定的问题。基本上,它会带来一个错误,如果远程在您的最新fetch之后被修改,则不会被推。

This is good if you're really sure a push --force is needed, but still want to prevent more problems. I'd go as far to say it should be the default push --force behaviour. But it's still far from being an excuse to force a push. People who fetched before your rebase will still have lots of troubles, which could be easily avoided if you had reverted instead.

这是很好的,如果你确实确定需要一个推力,但仍然想防止更多的问题。我想说的是,它应该是默认的推动行为。但这还远不能成为强行推进的借口。在你重新建立基地之前取得你的票的人仍然会有很多的麻烦,这是可以很容易避免的,如果你已经恢复。

And since we're talking about git --push instances...

既然我们说的是git——push instances…

Why would anyone want to force push?

@linquize brought a good push force example on the comments: sensitive data. You've wrongly leaked data that shouldn't be pushed. If you're fast enough, you can "fix"* it by forcing a push on top.

@linquize在评论中给出了一个很好的推力例子:敏感数据。你错误地泄露了不该泄露的数据。如果你的速度足够快,你可以通过推顶来“修复”它。

* The data will still be on the remote unless you also do a garbage collect, or clean it somehow. There is also the obvious potential for it to be spread by others who'd fetched it already, but you get the idea.

*数据将仍然在远程,除非您也做垃圾收集,或以某种方式清理它。很明显,它也有可能被其他已经获得它的人所传播,但是你懂的。

#3


16  

First of all, I would not make any changes directly in the "main" repo. If you really want to have a "main" repo, then you should only push to it, never change it directly.

首先,我不会直接在“main”repo中做任何更改。如果你真的想要一个“main”repo,那么你应该只推它一下,不要直接改变它。

Regarding the error you are getting, have you tried git pull from your local repo, and then git push to the main repo? What you are currently doing (if I understood it well) is forcing the push and then losing your changes in the "main" repo. You should merge the changes locally first.

关于您所犯的错误,您是否尝试过从本地的repo中提取git,然后将git推到主要的repo?您当前正在做的(如果我理解得很清楚的话)是强制执行,然后在“main”repo中丢失更改。您应该首先将更改合并到本地。

#4


13  

If I'm on my local branch A, and I want to force push local branch B to the origin branch C I can use the following syntax:

如果我在我的本地分支A上,我想把push local分支B推到源分支C,我可以使用以下语法:

git push --force origin B:C

#5


10  

I would really recommend to:

我真的建议:

  • push only to the main repo

    只推到主界面。

  • make sure that main repo is a bare repo, in order to never have any problem with the main repo working tree being not in sync with its .git base. See "How to push a local git repository to another computer?"

    确保主repo是一个裸repo,以避免主repo工作树与它的.git基不同步产生任何问题。参见“如何将本地git存储库推到另一台计算机?”

  • If you do have to make modification in the main (bare) repo, clone it (on the main server), do your modification and push back to it

    如果您确实需要在main(裸)repo中进行修改,那么克隆它(在主服务器上),进行修改并将其回推

In other words, keep a bare repo accessible both from the main server and the local computer, in order to have a single upstream repo from/to which to pull/pull.

换句话说,保持一个从主服务器和本地计算机都可以访问的裸repo,以便有一个上游repo从/到/拉。

#6


5  

This was our solution for replacing master on a corporate gitHub repository while maintaining history.

这是我们的解决方案,在维护历史的同时,在企业gitHub存储库中替换master。

push -f to master on corporate repositories is often disabled to maintain branch history. This solution worked for us.

为了维护分支历史,常常禁用在企业存储库上的push -f。这个解决方案对我们有效。

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

push your branch to desiredOrigin and create a PR

将你的分支推到desiredOrigin并创建一个PR

#7


2  

use this following command:

使用下面这个命令:

git push -f origin master

#1


1653  

Just do:

只做:

git push origin <your_branch_name> --force

or if you have a specific repo:

或者如果你有特定的回购:

git push https://git.... --force

This will delete your previous commit(s) and push your current one.

这将删除之前的提交并推送当前提交。

It may not be proper, but if anyone stumbles upon this page, thought they might want a simple solution...

这可能是不恰当的,但是如果有人偶然发现这一页,他们可能想要一个简单的解决方案……

Short flag

Also note that -f is short for --force, so

还要注意-f是力的缩写

git push origin <your_branch_name> -f

will also work.

也会工作。

#2


194  

And if push --force doesn't work you can do push --delete. Look at 2nd line on this instance:

如果push——force不工作,你可以做push——删除。在这个例子中,请看第二行:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push

But beware...

但是要小心…

Never ever go back on a public git history!

In other words:

换句话说:

  • Don't ever force push on a public repository.
  • 不要强行推动公共存储库。
  • Don't do this or anything that can break someone's pull.
  • 不要这样做或做任何会破坏别人吸引力的事情。
  • Don't ever reset or rewrite history in a repo someone might have already pulled.
  • 不要用别人可能已经提取的回购操作来重置或重写历史。

Of course there are exceptionally rare exceptions even to this rule, but in most cases it's not needed to do it and it will generate problems to everyone else.

当然,即使是这条规则也有例外的情况,但在大多数情况下不需要这样做,它会给其他人带来问题。

Do a revert instead.

And always be careful with what you push to a public repo. Reverting:

对你向公众推销的东西一定要小心。回复:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

In effect, both origin HEADs (from the revert and from the evil reset) will contain the same files.

实际上,两个源头(从恢复和恶意重置)将包含相同的文件。


edit to add updated info and more arguments around push --force

Consider pushing force with lease instead of push, but still prefer revert

Another problem push --force may bring is when someone push anything before you do, but after you've already fetched. If you push force your rebased version now you will replace work from others.

另一个问题推——力可能带来的是当有人在你之前推了什么东西,但在你已经拿过东西之后。如果你现在推动你的基于基础的版本,你将取代其他人的工作。

git push --force-with-lease introduced in the git 1.8.5 (thanks to @VonC comment on the question) tries to address this specific issue. Basically, it will bring an error and not push if the remote was modified since your latest fetch.

git push——git 1.8.5中引入的force-with-lease(感谢@VonC对这个问题的评论)试图解决这个特定的问题。基本上,它会带来一个错误,如果远程在您的最新fetch之后被修改,则不会被推。

This is good if you're really sure a push --force is needed, but still want to prevent more problems. I'd go as far to say it should be the default push --force behaviour. But it's still far from being an excuse to force a push. People who fetched before your rebase will still have lots of troubles, which could be easily avoided if you had reverted instead.

这是很好的,如果你确实确定需要一个推力,但仍然想防止更多的问题。我想说的是,它应该是默认的推动行为。但这还远不能成为强行推进的借口。在你重新建立基地之前取得你的票的人仍然会有很多的麻烦,这是可以很容易避免的,如果你已经恢复。

And since we're talking about git --push instances...

既然我们说的是git——push instances…

Why would anyone want to force push?

@linquize brought a good push force example on the comments: sensitive data. You've wrongly leaked data that shouldn't be pushed. If you're fast enough, you can "fix"* it by forcing a push on top.

@linquize在评论中给出了一个很好的推力例子:敏感数据。你错误地泄露了不该泄露的数据。如果你的速度足够快,你可以通过推顶来“修复”它。

* The data will still be on the remote unless you also do a garbage collect, or clean it somehow. There is also the obvious potential for it to be spread by others who'd fetched it already, but you get the idea.

*数据将仍然在远程,除非您也做垃圾收集,或以某种方式清理它。很明显,它也有可能被其他已经获得它的人所传播,但是你懂的。

#3


16  

First of all, I would not make any changes directly in the "main" repo. If you really want to have a "main" repo, then you should only push to it, never change it directly.

首先,我不会直接在“main”repo中做任何更改。如果你真的想要一个“main”repo,那么你应该只推它一下,不要直接改变它。

Regarding the error you are getting, have you tried git pull from your local repo, and then git push to the main repo? What you are currently doing (if I understood it well) is forcing the push and then losing your changes in the "main" repo. You should merge the changes locally first.

关于您所犯的错误,您是否尝试过从本地的repo中提取git,然后将git推到主要的repo?您当前正在做的(如果我理解得很清楚的话)是强制执行,然后在“main”repo中丢失更改。您应该首先将更改合并到本地。

#4


13  

If I'm on my local branch A, and I want to force push local branch B to the origin branch C I can use the following syntax:

如果我在我的本地分支A上,我想把push local分支B推到源分支C,我可以使用以下语法:

git push --force origin B:C

#5


10  

I would really recommend to:

我真的建议:

  • push only to the main repo

    只推到主界面。

  • make sure that main repo is a bare repo, in order to never have any problem with the main repo working tree being not in sync with its .git base. See "How to push a local git repository to another computer?"

    确保主repo是一个裸repo,以避免主repo工作树与它的.git基不同步产生任何问题。参见“如何将本地git存储库推到另一台计算机?”

  • If you do have to make modification in the main (bare) repo, clone it (on the main server), do your modification and push back to it

    如果您确实需要在main(裸)repo中进行修改,那么克隆它(在主服务器上),进行修改并将其回推

In other words, keep a bare repo accessible both from the main server and the local computer, in order to have a single upstream repo from/to which to pull/pull.

换句话说,保持一个从主服务器和本地计算机都可以访问的裸repo,以便有一个上游repo从/到/拉。

#6


5  

This was our solution for replacing master on a corporate gitHub repository while maintaining history.

这是我们的解决方案,在维护历史的同时,在企业gitHub存储库中替换master。

push -f to master on corporate repositories is often disabled to maintain branch history. This solution worked for us.

为了维护分支历史,常常禁用在企业存储库上的push -f。这个解决方案对我们有效。

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

push your branch to desiredOrigin and create a PR

将你的分支推到desiredOrigin并创建一个PR

#7


2  

use this following command:

使用下面这个命令:

git push -f origin master