Git reset --hard 并推送到远程存储库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1377845/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git reset --hard and push to remote repository
提问by robertpostill
I had a repository that had some bad commits on it (D, E and F for this example).
我有一个存储库,上面有一些错误的提交(在这个例子中是 D、E 和 F)。
A-B-C-D-E-F master and origin/master
ABCDEF 主和原点/主
I've modified the local repository specifically with a git reset --hard
. I took a branch before the reset so now I have a repo that looks like:
我专门用git reset --hard
. 我在重置之前选择了一个分支,所以现在我有一个看起来像的仓库:
A-B-C master
\ D-E-F old_master
A-B-C-D-E-F origin/master
Now I needed some parts of those bad commits so I cherry picked the bits I needed and made some new commits so now I have the following locally:
现在我需要那些糟糕提交的一些部分,所以我挑选了我需要的部分并进行了一些新的提交,所以现在我在本地有以下内容:
A-B-C-G-H master
\ D-E-F old_master
Now I want to push this state of affairs to the remote repo. However, when I try to do a git push
Git politely gives me the brush off:
现在我想将这种状态推送到远程仓库。然而,当我尝试做一个git push
Git 时,礼貌地让我刷掉:
$ git push origin +master:master --force
Total 0 (delta 0), reused 0 (delta 0)
error: denying non-fast forward refs/heads/master (you should pull first)
To [email protected]:myrepo.git
! [remote rejected] master -> master (non-fast forward)
error: failed to push some refs to '[email protected]:myrepo.git'
How do I get the remote repo to take the current state of the local repo?
如何让远程仓库获取本地仓库的当前状态?
回答by Jakub Nar?bski
If forcing a push doesn't help ("git push --force origin
" or "git push --force origin master
" should be enough), it might mean that the remote server is refusing non fast-forward pushes either via receive.denyNonFastForwardsconfig variable (see git configmanpage for description), or via update / pre-receive hook.
如果强制推送没有帮助(" git push --force origin
" 或 " git push --force origin master
" 应该足够了),这可能意味着远程服务器通过receive.denyNonFastForwards配置变量拒绝非快进推送(请参阅git configmanpage 了解说明),或通过更新/预接收钩子。
With older Git you can work around that restriction by deleting "git push origin :master
" (see the ':' before branch name) and then re-creating "git push origin master
" given branch.
使用较旧的 Git,您可以通过删除“ git push origin :master
”(参见分支名称前的“:”)然后重新创建“ git push origin master
”给定分支来解决该限制。
If you can't change this, then the only solution would be instead of rewriting history to create a commit revertingchanges in D-E-F:
如果你不能改变这一点,那么唯一的解决方案是而不是重写历史来创建一个提交恢复DEF 中的更改:
A-B-C-D-E-F-[(D-E-F)^-1] master A-B-C-D-E-F origin/master
回答by Jealie
To complement Jakub's answer, if you have access to the remote git server in ssh, you can go into the git remote directory and set:
为了补充 Jakub 的回答,如果您可以在 ssh 中访问远程 git 服务器,则可以进入 git 远程目录并设置:
user@remote$ git config receive.denyNonFastforwards false
Then go back to your local repo, try again to do your commit with --force
:
然后返回您的本地存储库,再次尝试使用以下命令进行提交--force
:
user@local$ git push origin +master:master --force
And finally revert the server's setting in the original protected state:
最后将服务器的设置恢复为原始保护状态:
user@remote$ git config receive.denyNonFastforwards true
回答by Aidin
Instead of fixing your "master" branch, it's way easier to swap it with your "desired-master" by renaming the branches. See https://stackoverflow.com/a/2862606/2321594. This way you wouldn't even leave any trace of multiple revert logs.
与其修复您的“主”分支,不如通过重命名分支来更轻松地将其与“所需的主”交换。请参阅https://stackoverflow.com/a/2862606/2321594。这样你甚至不会留下任何多个恢复日志的痕迹。
回答by Wolfgang Fahl
The whole git resetting business looked far to complicating for me.
整个 git 重置业务对我来说看起来很复杂。
So I did something along the lines to get my src folder in the state i had a few commits ago
所以我做了一些事情,让我的 src 文件夹处于我几次提交前的状态
# reset the local state
git reset <somecommit> --hard
# copy the relevant part e.g. src (exclude is only needed if you specify .)
tar cvfz /tmp/current.tgz --exclude .git src
# get the current state of git
git pull
# remove what you don't like anymore
rm -rf src
# restore from the tar file
tar xvfz /tmp/current.tgz
# commit everything back to git
git commit -a
# now you can properly push
git push
This way the state of affairs in the src is kept in a tar file and git is forced to accept this state without too much fiddling basically the src directory is replaced with the state it had several commits ago.
通过这种方式,src 中的事务状态保存在 tar 文件中,并且 git 被迫接受这种状态而无需过多摆弄,基本上 src 目录被替换为它在几次提交前的状态。
回答by Jason Faulkner
For users of GitHub, this worked for me:
对于 GitHub 的用户,这对我有用:
- In any branch protection rules where you wish to make the change, make sure Allow force pushesis enabled
git reset --hard <full_hash_of_commit_to_reset_to>
git push --force
- 在您希望进行更改的任何分支保护规则中,确保启用了允许强制推送
git reset --hard <full_hash_of_commit_to_reset_to>
git push --force
This will "correct" the branch history on your local machine and the GitHub server, but anyone who has sync'ed this branch with the server since the bad commit will have the history on their local machine. If they have permission to push to the branch directly then these commits will show right back up when they sync.
这将“更正”您本地计算机和 GitHub 服务器上的分支历史记录,但是任何因为错误提交而将此分支与服务器同步的人都将在其本地计算机上拥有该历史记录。如果他们有权直接推送到分支,那么这些提交将在同步时正确显示。
All everyone else needs to do is the git reset
command from above to "correct" the branch on their local machine. Of course they would need to be wary of any local commits made to this branch afterthe target hash. Cherry pick/backup and reapply those as necessary, but if you are in a protected branch then the number of people who can commit directly to it is likely limited.
所有其他人需要做的就是git reset
上面的命令来“纠正”他们本地机器上的分支。当然,他们需要警惕在目标哈希之后对该分支进行的任何本地提交。Cherry Pick/backup 并在必要时重新应用那些,但如果你在一个受保护的分支中,那么可以直接提交给它的人数可能是有限的。