원격 파일을 덮어 쓰도록 강제로“git push”


766

로컬 파일을 푸시하고 병합 충돌을 처리하지 않고도 원격 리포지토리에 저장하고 싶습니다. 로컬 버전이 원격 버전보다 우선합니다.

Git으로 어떻게 할 수 있습니까?


106
git push origin --force당신을 위해 작동 하지 않았다?


.git 파일 또는 관련 작업 복사본 만 재정의할지 확실하지 않습니다. 그것이 git 저장소라면, git push가 답입니다. 원격 작업 복사본을 업데이트하려면 수신 후 후크를 사용해야합니다.
Pierre-Olivier Vares

@Mike 그것은 어떤 이유로 나를 위해 작동합니다 ... OP와 무슨 일이 있었는지 궁금해

강제 푸시가 작동하지 않을 수있는 원인은 원격 리포지토리에서 명시 적으로 비활성화되었을 수 있기 때문입니다 (이디 오 및 / 또는 악성 기여자로 인해 손실이 발생하지 않도록하기 위해) config receive.denyNonFastforwards.
Frank Nocke

답변:


1085

다음을 사용하여 로컬 리포지토리를 원격 리포지토리로 강제 설정할 수 있어야합니다.

git push -f <remote> <branch>

(예 :) git push -f origin master. 오프 떠나 <remote><branch>설정 한 모든 현지 지사를 밀어 강제--set-upstream .

다른 사람들이이 저장소를 공유하는 경우 개정 내역이 새 개정 내역과 충돌 할 수 있습니다. 변경 시점 이후에 로컬 커밋이 있으면 유효하지 않게됩니다.

최신 정보 : 사이드 노트를 추가 할 것이라고 생각했습니다. 다른 사람들이 검토 할 변경 사항을 작성하는 경우, 변경 사항이있는 브랜치를 작성하고 주기적으로 리베이스하여 기본 개발 브랜치를 최신 상태로 유지하는 것은 드문 일이 아닙니다. 다른 개발자들에게 이러한 상황이 주기적으로 발생할 수 있음을 알리기 만하면 무엇을 기대해야하는지 알게됩니다.

업데이트 2 : 시청자 수가 증가함에 따라 시청자가해야 할 일에 대한 정보를 추가하고 싶습니다.upstream 강제 푸시가 발생할 .

레포를 복제하고 다음과 같은 커밋을 추가했다고 가정 해보십시오.

            D ---- E 주제
           /
A ---- B ---- C 개발

그러나 나중에 development지점에가 발생하여 rebase실행하면 다음과 같은 오류가 발생합니다 git pull.

포장 풀기 : 100 % (3/3) 완료
<리 포지션>에서
 * 브랜치 개발-> FETCH_HEAD
자동 병합 <파일>
충돌 (콘텐츠) : <locations>에서 충돌 병합
자동 병합에 실패했습니다. 충돌을 수정 한 다음 결과를 커밋하십시오.

여기에서 나는 갈등을 고칠 수는 commit있지만 실제로 추한 커밋 기록을 남길 수 있습니다.

       C ---- D ---- E ---- F 주제
      / /
A ---- B -------------- C 개발

사용하기가 유혹적 git pull --force이지만 조심 스러울 수 있으므로 조심해야합니다.

            D ---- E 주제

A ---- B ---- C '개발

아마도 가장 좋은 옵션은을 수행하는 것 git pull --rebase입니다. 이를 위해서는 이전과 같은 충돌을 해결해야하지만 커밋 대신 각 단계마다을 사용 git rebase --continue합니다. 결국 커밋 히스토리가 훨씬 나아질 것입니다.

            D '--- E'주제
           /
A ---- B ---- C '개발

업데이트 3 : 컵 케이크가 그의 답변에서 언급 한 것처럼--force-with-lease "safer"강제 푸시로 옵션을 사용할 수도 있습니다 .

"임대"를 사용하여 강제로 푸시하면 원격에 예상치 않은 새로운 커밋이 있으면 (기술적으로는 아직 원격 추적 분기로 가져 오지 않은 경우) 강제 푸시가 실패 할 수 있습니다. 당신은 실수로 당신이 아직 몰랐던 다른 사람의 커밋을 덮어 쓰고 싶지 않고 자신의 것을 덮어 쓰고 싶어합니다.

git push <remote> <branch> --force-with-lease

--force-with-lease다음 중 하나를 읽으면 사용법 에 대한 자세한 내용을 배울 수 있습니다 .


5
이것이 선택된 답변이므로 여기에 의견을 말하겠습니다. 혼자서 작업 할 때 힘을 사용하는 것은 문제가되지 않습니다. 예를 들어, 내 클라우드 호스트는 자체 git으로 시작합니다. 로컬에서 작업하고 프로젝트를 빌드하고 클라우드 호스트 (OpenShift)에 배치하려면 두 개의 별도 git 프로젝트가 있습니다. 내 로컬 및 OpenShift. 원하는대로 로컬을 가져 오지만 이제 OpenShift에서 미리 보려고합니다. 그런 다음 -f플래그를 사용하여 처음으로 OpenShift로 푸시합니다 . 본질적으로 로컬 git을 OpenShift에 넣습니다.
Wade

128

강제로 밀고 싶다

기본적으로 원하는 것은 원격 지점을 덮어 쓰기 위해 로컬 지점을 강제로 푸시하는 것입니다.

다음 각 명령에 대한 자세한 설명을 보려면 아래의 세부 정보 섹션을 참조하십시오. 기본적으로 Git을 사용하여 4 가지 옵션을 사용할 수 있습니다.

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

git push <remote> <branch> --force-with-lease

각 명령에 대한 자세한 설명을 보려면 아래의 긴 답변 섹션을 참조하십시오.

경고 : 강제 푸시는 원격 분기를 푸시하려는 분기의 상태로 덮어 씁니다. 이것을 사용하기 전에 이것이 실제로하고 싶은지 확인하십시오. 그렇지 않으면 실제로 유지하려는 커밋을 덮어 쓸 수 있습니다.

강제 추진 세부 사항

리모트 및 브랜치 지정

특정 지점과 리모컨을 완전히 지정할 수 있습니다. -f플래그의 짧은 버전입니다--force

git push <remote> <branch> --force
git push <remote> <branch> -f

지점 생략

분기 푸시 분기를 생략하면 Git은 구성 설정에 따라 분기를 파악합니다. 2.0 이후 Git 버전에서, 새로운 저장소는 현재 체크 아웃 된 브랜치를 푸시하기위한 기본 설정을 갖습니다 :

git push <remote> --force

2.0 이전에는 새로운 리포지토리에 여러 로컬 브랜치를 푸시하는 기본 설정이 있습니다. 해당 설정은 remote.<remote>.pushpush.default설정입니다 (아래 참조).

리모컨 및 지점 생략

리모트와 브랜치를 모두 생략하면 Git 구성 설정 git push --force에 따라 동작 이 결정됩니다 push.default.

git push --force
  • Git 2.0부터 기본 설정 simple은 기본적으로 현재 브랜치를 업스트림 원격 상대방으로 푸시합니다. 리모컨은 지점의 branch.<remote>.remote설정 에 따라 결정되며, 그렇지 않으면 기본적으로 원본 저장소로 설정됩니다.

  • Git 버전 2.0 이전의 기본 설정은 matching기본적으로 모든 로컬 브랜치를 원격의 동일한 이름을 가진 브랜치에 푸시합니다 (기본값은 origin).

git-config (1) 매뉴얼 페이지의 온라인 버전을push.defaultgit help config거나 더 많은 설정을 읽을 수 있습니다 .

보다 안전하게 밀어 붙이기 --force-with-lease

"임대"를 사용하여 강제로 푸시하면 원격에 예상치 않은 새로운 커밋이 있으면 (기술적으로는 아직 원격 추적 분기로 가져 오지 않은 경우) 강제 푸시가 실패 할 수 있습니다. 당신은 실수로 당신이 아직 몰랐던 다른 사람의 커밋을 덮어 쓰고 싶지 않고 자신의 것을 덮어 쓰고 싶어합니다.

git push <remote> <branch> --force-with-lease

--force-with-lease다음 중 하나를 읽으면 사용법 에 대한 자세한 내용을 배울 수 있습니다 .


네 말이 맞지만 이것은 예외적 인 상황 에서만 사용해야 합니다.
Scott Berrevoets

1
@ScottBerrevoets " 내가 선호하는 것은 내가 가진 것을 푸시하고 통합하기보다는 원격으로 덮어 쓰는 것입니다. "

알고 있지만 OP는이 작업의 결과를 인식하지 못할 수 있습니다. 당신은 기술적으로 질문에 대답했지만, 이것을하지 않는 경고는 적절하지 않다고 생각합니다.
Scott Berrevoets

1
@ScottBerrevoets 나는 새로운 --force-with-lease옵션을 언급했기 때문에 중재자가 내 답변을 정식으로 병합하도록 노력하고 있습니다;)


32

다른 기여자에게 문제가 될 수있는 강제 푸시를 피하기위한 다른 옵션은 다음과 같습니다.

  • 새로운 커밋을 전용 브랜치에 넣습니다.
  • 당신의 재설정 master에를origin/master
  • 전용 브랜치를에 병합 master하고 항상 전용 브랜치에서 커밋을 유지합니다 (위에 새 브랜치가 생성되어 master전용 브랜치가 반영됨). 를 시뮬레이트하는 전략에 대해서는 " 한 분기를 다른 분기처럼 만들기위한 git 명령
    "을 참조하십시오 .git merge --strategy=theirs

이렇게하면 아무 것도 강요하지 않고 마스터를 원격으로 푸시 할 수 있습니다.


결과는 "push -force"와 어떻게 다릅니 까?
alexkovelsky

6
@alexkovelsky 강제 푸시는 히스토리를 다시 작성하여 리포지토리의 다른 사용자가 새로 푸시 한 커밋과 일치하도록 로컬 리포지를 재설정하도록합니다. 이 방법은 새로운 커밋 만 생성하며 강제 푸시가 필요하지 않습니다.
VonC

1
나는 당신이 당신의 대답에 "제목을 강요하고 싶지 않다"라는 제목을 추가 할 것을 제안한다 :)
alexkovelsky

@alexkovelsky 좋은 지적입니다. 그에 따라 답변을 편집했습니다.
VonC

4

git push -f는 팀의 다른 사람이 작성한 원격 변경 사항을 재설정하기 때문에 약간 파괴적입니다. 보다 안전한 옵션은 {git push --force-with-lease}입니다.

{--force-with-lease}가하는 일은 예상 한 상태가 아닌 한 지점 업데이트를 거부하는 것입니다. 즉, 아무도 업스트림 지점을 업데이트하지 않았습니다. 실제로 이것은 참조가 해시이고 상위 체인을 내재적으로 값으로 인코딩하기 때문에 업스트림 참조가 예상 한 것인지 확인하여 작동합니다. {--force-with-lease}에게 정확히 무엇을 확인할지 알 수 있지만 기본적으로 현재 원격 참조를 확인합니다. 이것이 실제로 의미하는 것은 Alice가 지점을 업데이트하고 원격 저장소로 푸시하면 지점의 참조 포인팅 헤드가 업데이트된다는 것입니다. 이제 Bob이 리모컨을 가져 오지 않으면 리모컨에 대한 로컬 참조가 오래되었습니다. 그가 {--force-with-lease}를 사용하여 푸시하려고 할 때, git은 새로운 리모컨에 대해 로컬 심판을 확인하고 푸시를 거부합니다. {--force-with-lease}를 사용하면 다른 사람이 변경 사항을 원격으로 변경하지 않은 경우에만 강제 푸시 할 수 있습니다. 안전 벨트가 켜진 상태에서 {--force}입니다.



0

Tortoisegit을 사용하여 간단한 단계

로컬 파일을 커밋하고 git 저장소로 푸시하는 GIT.

단계 :

1) 숨김 숨김 이름 변경

2) 당겨

3) 숨김 팝

4) 커밋 하나 개 이상의 파일을 변경에게 설명 세트 저자와 날짜를 저지 제공

5) 푸시

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