Git non-fast-forward 거부 됨


88

이 질문이 여러 번 요청 된 것 같지만 해결책은 일반적으로 "디렉토리를 삭제하고 새로 체크 아웃하여 작업을 다시 수행했습니다."입니다. 커밋하고 푸시했지만 커밋 메시지에서 잘못된 티켓 번호를 참조했음을 깨달았습니다. 그래서 빠른 해결책을 찾기 위해 SO를 찾았고 결국 터미널에 다음을 입력했습니다.

$ git reset --soft HEAD^
$ git commit -m "... correct message ..."

유일한 문제는 다음과 같은 오류 메시지가 표시된다는 것입니다.

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-flow 모델을 사용하고 있으며 개발 브랜치에서 작업 중입니다. git을 다시 행복하게 만들기 위해 어떻게 다시 병합 할 수 있습니까?


답변:


52

git push:

git push origin +develop

24
그것은 해결책이지만 Brian Campbell의 의견을 읽고 이것을 사용하기 전에 무엇을하고 있는지 이해하십시오.
thelem

5
git push origin + master
Aniket Thakur 2013

에 대해도 참고를 참조하십시오 receive.denyNonFastForwards에서 브라이언 캠벨의 대답 : +또는 --force그들이-누구가-한하는 구성 방법에 따라 충분히 강력한하지 않을 수 있습니다 자신의 Git 저장소를.
torek

174

당신이 밀어 경우가 서버에 커밋 한 다음 (로컬로 커밋이 다시 git reset, git rebase, git filter-branch, 또는 다른 어떤 역사 조작) 한 다음 다시 쓴 서버에 백업 커밋 밀어, 당신은 당겨했다 다른 사람을 망치는 것입니다. 여기에 예가 있습니다. A를 커밋하고 서버로 푸시했다고 가정합니다.

-*-*-A <-마스터

-*-*-A <-원산지 / 마스터

이제 A를 다시 작성하기로 결정했습니다. 앞서 언급 한대로 재설정하고 다시 커밋합니다. 이것은 매달린 커밋 A를 남기고 결국 도달 할 수 없기 때문에 가비지 수집됩니다.

-*-*-ㅏ
    \
     A '<-마스터

-*-*-A <-오리진 / 마스터

다른 사람, 예를 들어 Fred master가이 작업을 수행하는 동안 서버에서 내려 오면 A에 대한 참조를 갖게되며 다음에서 작업을 시작할 수 있습니다.

-*-*-A '<-마스터

-*-*-A <-오리진 / 마스터

-*-*-AB <-fred / master

이제 A '를 원점 / 마스터로 밀어 넣을 수 있다면 빨리 감기가되지 않을 것입니다. 역사에 A가 없을 것입니다. 따라서 Fred가 다시 당기려고하면 갑자기 병합해야하고 A 커밋을 다시 도입해야합니다.

-*-*-A '<-마스터

-*-*-A <-오리진 / 마스터

-*-*-AB- \ 
    \ * <-프레드 / 마스터
     ㅏ'--/

Fred가이를 알아 차리면 리베이스를 수행하여 커밋 A가 다시 나타나지 않도록 할 수 있습니다. 하지만 그는 이것을 알아 차리고 이것을 기억해야합니다. A를 뽑은 사람이 한 명 이상인 경우 트리에 추가 A 커밋이 발생하지 않도록 모두 리베이스해야합니다.

따라서 일반적으로 다른 사람이 가져 오는 저장소의 기록을 변경하는 것은 좋지 않습니다. 그러나 다른 사람이 해당 리포지토리에서 가져 오지 않는다는 사실을 알게되면 (예 : 자신의 개인 리포지토리이거나 쉽게 조정할 수있는 프로젝트에서 작업하는 다른 개발자 한 명만있는 경우) 강제로 수행 할 수 있습니다. 다음을 실행하여 업데이트하십시오.

git push -f

또는

git push origin +master

둘 다 비 빨리 감기 푸시에 대한 검사를 무시하고 서버에있는 내용을 새 A '개정으로 업데이트하여 A 개정을 포기하여 결국 가비지 수집됩니다.

receive.denyNonFastForwardsconfig 옵션을 사용하면 강제 푸시가 완전히 비활성화 될 수 있습니다. 이 옵션은 공유 저장소에서 기본적으로 활성화됩니다. 이 경우 정말 강제로 푸시하고 싶다면 가장 좋은 방법은 브랜치를 삭제하고 git push origin :master; git push origin master:master. 그러나이 denyNonFastForwards옵션은 위에 설명 된 이유로 활성화됩니다. 공유 저장소에서 이는 이제이를 사용하는 모든 사람이 새로운 기록에 대한 리베이스를 보장해야 함을 의미합니다.

공유 저장소에서는 일반적으로 문제를 해결하는 새 커밋을 맨 위에 푸시하는 것이 좋습니다. git revert이전 커밋의 변경 사항을 취소하는 커밋을 생성 하는 데 사용할 수 있습니다 .


훌륭한 교육을 받았으며 결국 명령을 받았지만 내 브랜치는 develop (git-flow 기반)이라고 불렀고 다른 사람은 +develop명령을 입력했습니다. 그래서 수표는 그에게갑니다. 어쨌든 당신은 천문학적 점수를 얻었습니다 : P
rynmrtn 2011

7
또는 덜 git push --force
알기 쉬운

3
@Panique 서로를 차단하지 않고 (한 번에 한 사람 만 작업 할 수 있도록 허용) 변경 사항없이 서로 덮어 쓰지 않고 여러 사람이 크고 복잡한 코드베이스에서 동시에 작업하도록 허용하려고합니다. 각 사람이 독립적으로 변경하고 이러한 변경 사항을 병합 할 수 있어야합니다. 병합 (수동이든 자동이든)은 예기치 않은 문제를 일으킬 수 있습니다. 그래서 당신은 그것이 잘못되었을 때 무슨 일이 일어 났는지 알아 내기 위해 가능한 한 많은 정보를 유지하기를 원합니다. 이것은 본질적으로 복잡합니다. 더럽지 않고 어려운 문제 일뿐입니다.
Brian Campbell

원격 저장소 기록을 다시 작성하기 위해 -f 및 + 옵션을 모두 시도했습니다. 두 옵션 모두에서 빨리 감기가 아닌 문제가 발생했습니다. [5:05 PM] $ git push -f origin local_A : remote_A Counting objects : 35, done. 최대 2 개의 스레드를 사용하는 델타 압축. 개체 압축 : 100 % (18/18), 완료. 개체 쓰기 : 100 % (21/21), 7.41KiB, 완료. 총 21 (델타 9), 재사용 0 (델타 0) 원격 : 기록 손실을 방지하기 위해 비 빨리 감기 업데이트가 거부되었습니다. 다시 푸시하기 전에 원격 변경 사항 (예 : 'git pull')을 병합하십시오. 자세한 내용은 'git push --help'의 '빨리 감기에 대한 참고 사항'섹션을 참조하십시오.
Srikanth

4
@Srikanth receive.denyNonFastForwardsconfig 옵션을 사용하여 강제 푸시를 완전히 비활성화 할 수 있습니다. 이 옵션은 공유 저장소에서 기본적으로 활성화됩니다. 이 경우 정말 강제로 푸시하고 싶다면 가장 좋은 방법은 브랜치를 삭제하고 git push origin :remote_A; git push origin local_A:remote_A. 그러나 공유 저장소에서 이런 종류의 워크 플로를 수행하는 것이 왜 나쁜 생각인지에 대해 위에서 쓴 내용을 읽어보십시오. 제거하거나 다시 작성하려는 커밋에 심각한 문제를 일으키는 경우에만이 작업을 수행해야합니다.
Brian Campbell

14

당신은 당신을 위해 git pull물건을 자동 병합 할 수있는을해야 할 수도 있습니다. 그런 다음 다시 커밋 할 수 있습니다. 충돌이있는 경우 해결하라는 메시지가 표시됩니다.

gitconfig를 업데이트하지 않은 경우 가져올 브랜치를 지정해야합니다.

예를 들면 :

git pull origin develop:develop

빨리 감기가 아닌 것에 대해 여전히 화가났습니다. 강제로 병합하는 방법에 대한 의견이 있으십니까? ! [rejected] develop -> develop (non-fast-forward)
rynmrtn 2011

나는 스위치가 -f라고 생각하지만 틀릴 수 있습니다. kernel.org/pub/software/scm/git/docs/git-pull.html
Tony

이것은 부분적으로 작동합니다. 그래도 github에 업데이트가 표시되지 않습니다 (이전 커밋이 a를 사용하더라도 최신 커밋으로 git push origin develop
표시됨

7

나는 EGit을 사용하고 있었고 나는 또한이 문제에 직면했습니다. rebase현재 지점으로 시도했지만 작동했습니다.

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