힘내 재설정-하드 및 원격 저장소로 푸시


199

나는 약간의 커밋이있는 저장소를 가지고있었습니다 (이 예에서는 D, E 및 F).

ABCDEF 마스터 및 원산지 / 마스터

로컬 저장소를 특별히로 수정했습니다 git reset --hard. 재설정 전에 지점을 가져 왔으므로 이제는 다음과 같은 저장소가 있습니다.

A-B-C master  
     \ D-E-F old_master

A-B-C-D-E-F origin/master

이제 나쁜 커밋의 일부가 필요했기 때문에 필요한 비트를 선택하고 새로운 커밋을 만들었으므로 이제 로컬로 다음을 수행했습니다.

A-B-C-G-H master
     \ D-E-F old_master

이제이 상태를 원격 저장소로 푸시하고 싶습니다. 그러나 git pushGit을 정중하게 하려고 하면 솔이 나옵니다.

$ 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 git@git.example.com:myrepo.git  
! [remote rejected] master -> master (non-fast forward)  
error: failed to push some refs to 'git@git.example.com:myrepo.git'  

원격 저장소를 로컬 저장소의 현재 상태로 가져 오려면 어떻게해야합니까?


2
는이 '거의', 예를 들면 "나는 개정 역사 문제를 밀어 어떻게"여러 가지의 중복 여기에 답을 볼 수있다 stackoverflow.com/questions/253055/...
CB 베일리

2
사실이며 게시하기 전에 StackOverflow에서 답변을 검색했습니다. 그러나 내 검색은 git push --force로 문제를 해결 한 답변 만 나타났습니다. 귀하의 게시물에 연결 주셔서 감사합니다 :)
robertpostill

2
곧 (git1.8.5는, Q4 2013) 할 수 DO가 git push -force주의 깊게 더 .
VonC

답변:


286

강제 푸시가 도움이되지 않는 경우 ( " git push --force origin"또는 " git push --force origin master"이면 충분합니다.) 원격 서버가 receive.denyNonFastForwards 구성 변수 ( 설명 은 git config 맨 페이지 참조) 를 통해 비 빨리 감기 푸시를 거부하고 있음을 의미 할 수 있습니다 . 또는 업데이트 / 사전 수신 후크를 통해.

이전 Git을 사용하면 " git push origin :master"(브랜치 이름 앞에 ':'참조) 를 삭제 한 다음 git push origin master지정된 브랜치 를 " " 다시 작성 하여 해당 제한 사항을 해결할 수 있습니다 .

이것을 변경할 수 없다면, 유일한 해결책은 기록을 다시 쓰는 대신 DEF에서 커밋 되돌리기 변경 사항만드는 것입니다 .

ABCDEF-[(DEF) ^-1] 마스터

ABCDEF 원산지 / 마스터

2
@ JakubNarębski, 감사합니다. get revert HEAD~N도와주었습니다. N커밋 수입니다. 예를 들어, 이전 커밋이 필요한 경우 다음을 사용합니다.git revert HEAD~1
Maksim Dmitriev

1
이 작업을 수행하면 다른 모든 지역 마스터를 깰 수 있습니다.
톰 브리토

24

Jakub의 답변을 보완하기 위해 ssh에서 원격 git 서버에 액세스 할 수 있다면 git remote 디렉토리로 이동하여 다음을 설정할 수 있습니다.

user@remote$ git config receive.denyNonFastforwards false

그런 다음 로컬 리포지토리로 돌아가서 다시 커밋을 수행하십시오 --force.

user@local$ git push origin +master:master --force

마지막으로 서버 설정을 원래 보호 상태로 되돌립니다.

user@remote$ git config receive.denyNonFastforwards true

이에 대한 소스 포지의 맞춤형 정보 는 pete.akeo.ie/2011/02/denying-non-fast-forward-and.html 도 참조하십시오 .
hlovdal

denyNonFastForwards 사용을 비활성화하는 방법에 대한 자세한 지침은 vi이 SO 게시물에서 제공됩니다. stackoverflow.com/a/43721579/2073804
ron190


1

전체 자식 재설정 사업은 나를 복잡하게 만들었습니다.

그래서 몇 줄 전에 커밋 한 상태에서 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

이런 식으로 src의 업무 상태는 tar 파일로 유지되며 git은 너무 많은 방해 없이이 상태를 수락해야합니다. 기본적으로 src 디렉토리는 여러 커밋 이전 상태로 바뀝니다.


0

GitHub 사용자의 경우 다음과 같이 작동했습니다.

  1. 변경하려는 지점 보호 규칙에서 강제 푸시 허용 이 활성화되어 있는지 확인하십시오.
  2. git reset --hard <full_hash_of_commit_to_reset_to>
  3. git push --force

이것은 로컬 머신과 GitHub 서버에서 분기 히스토리를 "수정"하지만, 잘못된 커밋 이후이 분기를 서버와 동기화 한 사람은 로컬 머신에서 히스토리를 갖게됩니다. 지점에 직접 푸시 할 권한이있는 경우 이러한 커밋은 동기화 될 때 바로 백업됩니다.

다른 모든 사람들은 git reset로컬 컴퓨터에서 분기를 "수정"하라는 명령을 위에서부터 수행 합니다. 물론 대상 해시 후에이 분기에 수행 모든 로컬 커밋에주의해야합니다 . 체리 선택 / 백업 및 필요에 따라 이들을 다시 적용하되, 보호 된 지사에있는 경우 직접 커밋 할 수있는 사람의 수가 제한 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.