수정 된 커밋을 원격 Git 리포지토리에 어떻게 푸시합니까?

소스 코드로 약간 작업했을 때 평소 커밋을 한 다음 원격 저장소로 푸시했습니다. 그러나 소스 코드로 수입품을 정리하는 것을 잊어 버렸습니다. 따라서 이전 커밋을 대체하기 위해 amend 명령을 수행합니다.

> git commit --amend

불행히도 커밋을 리포지토리로 푸시 할 수 없습니다. 다음과 같이 거부됩니다.

> git push origin
To //my.remote.repo.com/stuff.git/
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'

어떻게해야합니까? (원격 저장소에 액세스 할 수 있습니다.)



답변

사실 한 번에 밀어 --force.git저장소와 리누스 꾸중있어 BIG TIME . 일반적으로 이것은 다른 사람들에게 많은 문제를 일으킬 것입니다. 간단한 답변은 “하지 마십시오”입니다.

나는 다른 사람들이 어쨌든 그렇게하는 요리법을 보았으므로 여기서는 반복하지 않을 것입니다. 그러나 다음은 –force (또는 + master)로 수정 된 커밋을 푸시 한 후 상황을 복구하기위한 팁 입니다.

  1. git reflog수정 한 이전 커밋을 찾는 데 사용 합니다 (호출하면을 수정 old하여 새로 만든 커밋을 호출합니다 new).
  2. old와 같은 new트리를 기록하여 와 사이에 병합을 만듭니다 .newgit checkout new && git merge -s ours old
  3. 이것을 마스터에게 병합 git merge master
  4. 결과로 마스터를 업데이트하십시오. git push . HEAD:master
  5. 결과를 밀어 내십시오.

를 사용해서 개정하고 결과 병합 당신이 선호하는 것을 볼 수 있습니다 볼 수 푸시를 강제로 말소 커밋에 그런 불행한 충분히 있었다 사람들은 자신의 작품을 기반으로 한하는 new동안 old. 그들의 나중에 병합이 사이의 충돌이 표시되지 않습니다 old그리고 new그들이 고통을하지 않아도, 당신의 개정으로 인한 것을.


답변

Git 안전 기능이 보입니다. Git은 브랜치로 원격 브랜치를 업데이트하지 않습니다. 브랜치의 헤드 커밋은 푸시하려는 브랜치의 현재 헤드 커밋의 직접적인 후손이 아니기 때문입니다.

이것이 사실이 아니라면, 거의 같은 시간에 같은 저장소로 밀고있는 두 사람은 동시에 새로운 커밋이 들어 왔으며 마지막으로 밀린 사람은 이전 푸셔의 작업을 그들은 이것을 깨달았습니다.

당신이 밀고있는 유일한 사람이라는 것을 알고 있고 수정 된 커밋을 푸시하거나 브랜치를 되 돌리는 커밋을 푸시하려는 경우, -f스위치 를 사용하여 Git이 원격 브랜치를 업데이트하도록 ‘강제’할 수 있습니다 .

git push -f origin master

원격 저장소가 구성 변수를 사용하여 맨 끝에서 비 빨리 푸시를 거부 할 수 있기 때문에 Git이 작동하지 않을 수도 있습니다 receive.denynonfastforwards. 이 경우 거부 사유는 다음과 같습니다 ( ‘원격 거부 됨’부분 참고).

 ! [remote rejected] master -> master (non-fast forward)

이 문제를 해결하려면 원격 저장소의 구성을 변경하거나 더티 해킹으로 분기를 삭제하고 다시 만들 수 있습니다.

git push origin :master
git push origin master

일반적으로 마지막 매개 변수 git push는 형식 을 사용합니다 <local_ref>:<remote_ref>. 여기서 local_ref로컬 저장소 remote_ref의 분기 이름이고 원격 저장소의 분기 이름입니다. 이 명령 쌍은 두 개의 속기를 사용합니다. :masternull local_ref는 null 분기를 원격 측으로 푸시하는 것을 의미 master합니다. 즉, 원격 분기를 삭제합니다. 없는 지점 이름 :은 지정된 이름의 로컬 지점을 동일한 이름의 원격 지점으로 푸시합니다. master이 상황에서는 짧습니다 master:master.


답변

빠른 답변 : 여기에 간단한 답변을 게시 한 사람이 아무도 없다는 사실은 Git CLI가 보여주는 절박한 사용자 적대감을 보여줍니다.

어쨌든, 당신이 강요를 시도하지 않았다고 가정 할 때, 이것을하는 “명백한”방법은 먼저 당기는 것입니다. 이렇게하면 수정 한 (그리고 더 이상 가지고 있지 않은) 변경 사항이 다시 적용됩니다.

충돌이 해결되면 다시 푸시 할 수 있습니다.

그래서:

git pull

풀 오류가 발생하면 로컬 리포지토리 구성에 문제가있을 수 있습니다 (.git / config 분기 섹션에 잘못된 참조가 있음).

그리고 후에

git push

어쩌면 “Trivial merge”에 대해 주제와 추가 커밋을받을 수도 있습니다.


답변

짧은 대답 : 수정 된 커밋을 공개 리포지토리로 푸시하지 마십시오.

긴 대답 : git commit --amendand 같은 몇몇 Git 명령 git rebase은 실제로 히스토리 그래프를 다시 작성합니다. 변경 사항을 게시하지 않는 한 괜찮습니다. 일단 변경하면 누군가가 이미 변경 사항을 가져 와서 다시 가져 오면 실패 할 수 있기 때문에 실제로 역사와 관련해서는 안됩니다. . 커밋을 수정하는 대신 변경 사항을 적용하여 새로 커밋해야합니다.

그러나 실제로 수정 된 커밋을 푸시하려면 다음과 같이하십시오.

$ git push origin +master:master

선행 +부호는 “빨리 감기”커밋이 발생하지 않더라도 푸시가 발생하도록합니다. 추진중인 변경 사항이 이미 공개 리포지토리에있는 변경 사항 의 직접적인 후손 인 경우 빨리 감기 커밋이 발생합니다 .


답변

다음은 이미 작성한 후 변경 사항을 푸시하는 매우 간단하고 깨끗한 방법입니다 commit --amend.

git reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master

다음은 무엇입니까?

  • 분기 헤드를 상위 커밋으로 재설정합니다.
  • 이 마지막 커밋을 보관하십시오.
  • 원격으로 강제 푸시합니다. 이제 원격에 마지막 커밋이 없습니다.
  • 당신의 숨결을 터 뜨리십시오.
  • 깨끗하게 커밋하십시오.
  • 리모콘으로 미십시오.

다른 지점이나 원격지에 적용 할 경우 “origin”과 “master”를 변경해야합니다.


답변

로컬 수정 커밋을 버리고 새로운 변경 사항을 맨 위에 추가하여 문제를 해결했습니다.

# Rewind to commit before conflicting
git reset --soft HEAD~1

# Pull the remote version
git pull

# Add the new commit on top
git add ...
git commit
git push


답변

나는 같은 문제가 있었다.

  • 이미 푸시 된 마지막 커밋을 실수로 수정했습니다.
  • 로컬에서 많은 변경을 수행하고 약 5 번 커밋
  • 푸시 시도, 오류, 당황, 원격 병합, 많은 내 파일이 없음, 푸시, 실패 등

Git 초보자 인 나는 그것이 완전한 FUBAR 라고 생각했다 .

솔루션 : @bara가 제안한 + 로컬 백업 분기 생성

# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>

# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad

# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"

# Switch back to the original branch
git checkout feature/1234

# Pull the from remote (named 'origin'), thus 'repairing' our main problem
git pull origin/feature/1234

# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php

어쩌면 그것은 빠르고 깨끗한 해결책이 아니며 내 역사 (5 대신 1 커밋)를 잃어 버렸지 만 하루의 작업을 절약했습니다.