힘내 푸시 오류 : 체크 아웃 분기 업데이트 거부


196

일부 병합 충돌을 해결하고 커밋 한 후 변경 사항을 푸시하려고 시도하고 다음 오류가 발생했습니다.

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master
Done
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To C:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:/Development/GIT_Repo/Project'

누구 든지이 오류의 원인을 알고 있습니까?



6
당신은 실제로 이제 망할 놈의 2.3.0 (2015 년 2 월)와 비 베어 REPO에 전달할 수있는 안전한 방법을 가지고 git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

답변:


229

이유 : 비 Bare 저장소로 추진하고 있습니다.

두 가지 유형의 저장소가 있습니다. 베어 및 비 베어

베어 리포지토리에는 작업중인 사본이 없으며 해당 저장소로 푸시 할 수 있습니다. 이것들은 Github에서 얻는 리포지토리 유형입니다! 베어 리포지토리를 만들려면 다음을 사용할 수 있습니다.

git init --bare

간단히 말해 베어가 아닌 저장소로 푸시 할 수 없습니다(편집 : 글쎄, 현재 체크 아웃 된 리포지토리의 분기로 푸시 할 수 없습니다. 베어 리포지토리를 사용하면 체크 아웃되지 않은 분기로 푸시 할 수 있습니다. 가능하지만 비 베어 리포지토리로 푸시하는 것은 일반적이지 않습니다) . 당신이 할 수있는 일은 다른 저장소에서 가져오고 병합하는 것입니다. 이 방법은pull request Github에서 볼 수있는 방식입니다. 당신은 그들에게서 당신을 끌어 당기라고 요구하고, 당신은 그들에게 강제로 밀어 넣지 않습니다.


업데이트 : 최신 git 버전 (현재 2.3.0)에서 VonC 덕분에 비 베어 리포지토리의 체크 아웃 된 분기로 푸시 할 수 있습니다 . 그럼에도 불구하고 여전히 더러운 작업 트리로 밀 수 는 없습니다. 어쨌든 안전한 작업은 아닙니다.


1
예! 맞습니다 감사합니다! 약 백만 가지 작업을 수행하면서 실수로 작업 디렉토리를 복제했습니다 .... doh!
Funky

25
실제로, 베어가 아닌 저장소로 잘 밀어 넣을 수 있으며 현재 체크 아웃 된 하나의 분기로 밀어 넣을 수는 없습니다 .
Nowhere man

1
실제로 수십 가지 다른 시나리오가 있습니다. 예를 들어, 일부 리포지토리는 내 워크 스테이션과 랩톱에 있습니다 (코드가 아니라 참고 사항). 각각에는 "워크 스테이션"과 "노트북"의 두 가지가 있습니다. 워크 스테이션에서는 "워크 스테이션"만 체크 아웃하고 랩탑의 "워크 스테이션"브랜치 (또는 그 반대)까지만 푸시합니다.
아무데도 남자

8
당신은 실제로 이제 망할 놈의 2.3.0 (2015 년 2 월)와 비 베어 REPO에 전달할 수있는 안전한 방법을 가지고 git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

1
@skelly github에 복사하는 동안 복제본이 노출되지 않았습니다. 따라서 두 복제본에 모든 기록이 있지만 github의 사본에는 커밋이 체크 아웃되어 있지 않지만 사본을 사용하면 작업 할 수 있습니다!
Shahbaz

115

나는 원격에 체크 아웃 된 것이 (실제로되어 있지 않은) 것을 확인한 다음 맨손으로 확인 하여이 문제를 해결했습니다.

$ git config --bool core.bare true

그 후 git push가 정상적으로 작동했습니다.


3
이것은 내가 찾던 하나의 라이너 수정입니다 .. 그러나 아마도 @shahbaz 답변과 같은 맨손이 아닌 repos를 설명 할 수 있습니다
Mr5o1

이렇게하면 변경 히스토리를 푸시 할 수 있지만 변경 사항은 베어-레포 리포지토리에 반영되지 않습니다.
jhill515

당신 git config core.bare falsegit reset --hard ?
항공기

1
위에서 언급했듯이 리모컨을 누르면 리모컨이 수정되지 않습니다.
user1097111

46

요약

리포지토리의 체크 아웃 된 분기로 푸시 할 수 없습니다. 리포지토리의 사용자 가 데이터 및 기록 손실로 끝날 수있는 방식으로 엉망이되기 때문입니다. . 그러나 동일한 저장소의 다른 지점으로 푸시 할 수 있습니다.

베어 리포지토리에는 분기가 체크 아웃되지 않으므로 항상 베어 리포지토리의 모든 분기로 푸시 할 수 있습니다.

문제 부검

지점이 체크 아웃되면 커밋은 현재 브랜치의 헤드를 부모로하여 새로운 커밋을 추가하고 브랜치의 헤드를 새로운 커밋으로 이동시킵니다.

그래서

A ← B
    ↑
[HEAD,branch1]

된다

A ← B ← C
        ↑
    [HEAD,branch1]

그러나 누군가가 그 사이에서 그 지점으로 밀 수 있다면, 사용자는 git 호출 분리 헤드 모드 에 도달 할 것입니다 :

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

이제 사용자는 다른 지점을 명시 적으로 체크 아웃하지 않아도 더 이상 branch1에 없습니다. 더 나쁜 것은 사용자가 이제 지점 외부 에 있으며 새로운 커밋이 매달려 있다는 것입니다 .

      [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

이 시점에서 사용자가 다른 지점을 체크 아웃하면이 매달려있는 커밋은 Git의 가비지 수집기에 대한 공정한 게임이됩니다 .



22

나를 위해 다음과 같은 트릭을 수행했습니다.

git config --global receive.denyCurrentBranch updateInstead

Git을 사용하여 거의 모든 드라이브 F :를 Windows 10 데스크톱과 Windows 10 랩톱간에 동기화하도록 설정했습니다. 두 컴퓨터에서 위의 명령을 실행했습니다.

먼저 네트워크에서 데스크톱의 F 드라이브를 공유했습니다. 그런 다음 다음을 실행하여 랩톱에서 복제 할 수있었습니다.

F: git clone 'file://///DESKTOP-PC/f'

불행히도, 모든 파일은 내 랩탑에서 "F : \ f \"로 끝나고 F : \로 직접 끝나지 않았습니다. 그러나 수동으로 잘라서 붙여 넣을 수있었습니다. Git은 여전히 ​​새 위치에서 근무했습니다.

그런 다음 랩톱의 파일을 변경하고 커밋 한 다음 다시 데스크탑으로 푸시하려고했습니다. 위에서 언급 한 git config 명령을 실행하기 전까지는 작동하지 않았습니다.

Windows PowerShell 내에서 두 컴퓨터 모두에서이 명령을 모두 실행했습니다.

업데이트 : 경우에 따라 변경 사항을 푸시하는 데 여전히 문제가있었습니다. 마지막으로 컴퓨터에서 다음을 실행하여 변경 사항을 가져 오기 시작했습니다. 최신 커밋을 가져 오려고합니다.

git pull --all --prune


1
나는이 지역을 git repo보다 선호한다 :git config receive.denyCurrentBranch updateInstead
klor

21

원격 컴퓨터에서 푸시하려는 repo / 디렉토리로 cd하고

$ git config core.bare true

작동하지 않습니다. 저장소는 밀어 넣은 후에도 비어 있습니다.
Sören

위의 jhil515가 말했듯이, 베어 파일이 아닌 파일은 데이터베이스 만 업데이트되지 않습니다.
Denis Cousineau

14

기존 리포지토리가 이미 있으므로

git config --bool core.bare true

원격 저장소에서 충분해야합니다.

core.bare 문서에서

true (bare = true) 인 경우, 작업 디렉토리와 연관된 저장소가없는 것으로 가정합니다. 이 경우 git-add 또는 git-merge와 같이 작업 디렉토리를 필요로하는 많은 명령이 비활성화됩니다 (단, 푸시 할 수는 있습니다).

이 설정은 리포지토리가 생성 될 때 git-clone 또는 git-init에 의해 자동으로 추측됩니다. 기본적으로 "/.git"로 끝나는 리포지토리는 베어 (bare = false) 인 것으로 가정하고 다른 모든 리포지토리는 베어 (bare = true) 인 것으로 가정합니다.


12

TLDR

  1. 당기고 다시 누르십시오 : git pull &&& git push.
  2. 여전히 문제가 있습니까? 다른 지점으로 밀어 넣고 git push origin master:foo원격 저장소에 병합하십시오.
  3. 또는 추가하여 푸시를 강제 실행하십시오 -f( denyCurrentBranch무시해야 함).

기본적으로 오류는 리포지토리가 원격 코드로 최신 상태가 아님을 나타냅니다 (인덱스 및 작업 트리가 푸시 한 내용과 일치하지 않음).

일반적으로 pull먼저 최근 변경 사항을 push가져와야합니다.

도움이되지 않으면 다음과 같이 다른 지점으로 이동하십시오.

git push origin master:foo

그런 다음 원격 저장소의이 분기를 다시 마스터와 병합하십시오.

과거 커밋을 의도적으로 git rebase변경하고 변경 사항으로 repo를 재정의하려는 경우 -f/ --force매개 변수 를 추가하여 강제로 푸시하고 싶을 수도 있습니다 (하지 않은 경우 권장하지 않음 rebase). 여전히 작동하지 않으면 다음 receive.denyCurrentBranchignore통해 자식 메시지에서 제안한대로 원격으로 설정해야합니다 .

git config receive.denyCurrentBranch ignore

3

어쩌면 원격 리포지토리가 푸시하려는 지점에있을 수 있습니다. 원격 시스템에서 다른 지점을 체크 아웃 할 수 있습니다. 나는이 오류가 사라진 것 보다이 작업을 수행했으며 원격 저장소에 성공했습니다. github.com 대신 ssh를 사용하여 내 서버를 연결합니다.


1

git repo가 ​​같은 위치에서 실수로 두 번 초기화 되었기 때문에이 오류가 발생했습니다. .git 폴더가 남아 있기 때문에 git은 저장소가 베어지지 않은 것으로 가정합니다. .git 폴더와 작업 디렉토리 데이터를 제거하면 문제가 해결되었습니다.


1
제 상황에서는 이것이 사실이었습니다. .git원격 에서 폴더를 제거하면 초기 커밋을 푸시 할 수있었습니다.
tim.rohrer 1

0

progit을 읽는 동안 놀 때이 오류가 발생했습니다. 로컬 리포지토리를 만든 다음 동일한 파일 시스템의 다른 리포지토리에서 가져 와서 편집하고 푸시하려고했습니다. NowhereMan의 답변을 읽은 후 빠른 수정은 "원격"디렉토리로 이동하여 다른 커밋을 일시적으로 체크 아웃하고 변경 한 디렉토리에서 푸시 한 다음 돌아가서 마스터에 헤드를 다시 넣는 것이 었습니다.


0

그것은 나를 위해 작동합니다

  1. git config --global receive.denyCurrentBranch updateInstead

  2. git push origin master

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