2016-09-26 2 views
8

나는 리모트 호스트와 함께 자식 리포를 가지고있다. 호스트는 3 개가 미러되어있다.커밋에서힘내 : - 힘을 빌려주 고 여러 번 밀어 넣기

$ git remote -v 
origin [email protected]:username/repo.git (fetch) 
origin [email protected]:username/repo.git (push) 
origin [email protected]:username/repo.git (push) 
origin [email protected]:username/repo.git (push) 

모든 도처에있다.

$ git rev-parse HEAD 
A 

$ cat .git/refs/remotes/origin/master 
A 

I 작성자는 B를 저지하고 밀어 넣습니다. 이제 모든 사람은 커밋 중이 야. B.

$ git push origin master 
To github.com:username/repo.git 
    A...B    master -> master 
To gitlab.com:username/repo.git 
    A...B    master -> master 
To bitbucket.org:username/repo.git 
    A...B    master -> master 

$ git rev-parse HEAD 
B 

$ cat .git/refs/remotes/origin/master 
B 

이제 마지막 커밋에서 실수를 알아 차리고 커밋을 고칠 수 있습니다. 이것은 나를 원격지와 동기화시키지 못하게한다.

$ git rev-parse HEAD 
C 

$ cat .git/refs/remotes/origin/master 
B 

나는 맹목적으로 --force 밀고 피하기 위해 같은, 그래서 --force-with-lease를 사용하지만,이 흥미로운 방법으로 실패합니다. 원격 심판은 내가 그것으로 전달 커밋 동일 마지막에, 그리고 내 로컬 기록이의 SHA1이 .git/refs/remotes/origin/master 커밋 경우

$ git push --force-with-lease origin master 
To github.com:username/repo.git 
+ B...C    master -> master (forced update) 
To gitlab.com:username/repo.git 
! [rejected]  master -> master (stale info) 
To bitbucket.org:username/repo.git 
! [rejected]  master -> master (stale info) 

문제는, --force-with-lease 만 푸시 안전 고려할 것입니다. 첫 번째 미러 (GitHub)가 업데이트되자 마자 내 로컬 원격 참조가 C으로 업데이트되어 GitLab 및 Bitbucket에 대한 푸시 시도가 실패합니다. 이제는 커밋이 C 일 것으로 예상됩니다.

나는 이것을 알아 내고 싶다. 그래서 나는 GitHub 미러가 다시 B로 되 돌린다.

$ git push origin +B:refs/heads/master 
To github.com:username/repo.git 
+ C...B    B -> master (forced update) 
Everything up-to-date 
Everything up-to-date 

이제 리모콘이 푸시를 위해 어떤 커밋을해야하는지 자세히 설명해야합니다. 문서에서 정확하게 업데이트 할 참조를 지정할 수 있다고 말하고 현재 어떤 업데이트를 수행 할 것인지를 --force-with-lease=<refname>:<expect>으로 지정하기 때문에이를 시도합니다.

$ git push --force-with-lease=origin/master:B origin master 
To github.com:username/repo.git 
! [rejected]  master -> master (non-fast-forward) 
To gitlab.com:username/repo.git 
! [rejected]  master -> master (non-fast-forward) 
To bitbucket.org:username/repo.git 
! [rejected]  master -> master (non-fast-forward) 

분명히 뭔가 잘못하고 있습니다. 어쩌면 <refname>이 잘못되었을 수 있습니까? 나는 너무 가깝다고 느낍니다. 내가 뭘 놓치고 있니?

+0

'git push --force-with-lease = $ (git rev-parse origin/master) : B 오리진 마스터'(즉, 이름이 아닌 원시 커밋 ID)를 테스트하는 재미있는 테스트. 이 특별한 경우를 위해 힘내 기가 ID 변환에 이름을 넣을 때 나는 확신하지 못한다. – torek

+0

@torek 주사위를 쓸만한 가치가 있었지만 주사위는 없었습니다. 그것은 똑같은 일을했습니다 (모두 "빨리 감기가 아닙니다"라고 말함). – ivan

+1

흥미 롭습니다. 나는 추측하고있다. (코드는 꽤 꼬여있다.) 그러나 여러 URL 중 force-with-lease 옵션이 어딘가에 잊혀진 것으로 보인다. 각 URL마다 하나의 리모콘 만 있으면 훨씬 더 효과가있을 것입니다. – torek

답변

3

매우 흥미로운 질문입니다! 나는 그것을 밖으로 시도하고 성공적으로 당신이이 테스트의 repos에 힘내 2.11.0로 묘사하는 것을 재현했습니다

내가 성공적으로 모두 --force-with-lease 푸시 할 수 있었다 다음 양식을 사용하여 원격의 URL :

git push --force-with-lease origin +master 

공지 사항 없음 분기 전 + 기호 나를.git-push (1) 매뉴얼 페이지에서

$ git push --force-with-lease origin +master 
Counting objects: 2, done. 
Delta compression using up to 4 threads. 
Compressing objects: 100% (2/2), done. 
Writing objects: 100% (2/2), 232 bytes | 0 bytes/s, done. 
Total 2 (delta 0), reused 0 (delta 0) 
To github.com:hkdobrev/git-test.git 
+ 099b95f...08c7548 master -> master (forced update) 
Counting objects: 2, done. 
Delta compression using up to 4 threads. 
Compressing objects: 100% (2/2), done. 
Writing objects: 100% (2/2), 232 bytes | 0 bytes/s, done. 
Total 2 (delta 0), reused 0 (delta 0) 
To github.com:hkdobrev/git-test2.git 
+ 099b95f...08c7548 master -> master (forced update) 

: 여기서 출력

--force 매칭 또는 다중 푸시 목적지 을 가진 따라서 push.default 세트를 사용하여 가압되는 모든 심판에 적용하는 것으로

remote.*.push으로 구성하면 현재 분기 (원격 보다 엄격하게 뒤에있는 로컬 참조 포함) 이외의 참조를 덮어 쓸 수 있습니다. 하나의 브랜치에만 강제로 푸시하려면 refspec 앞에 +을 사용하여 밀어 넣으십시오 (예 : git push origin +master, 푸시를 master 브랜치로 푸시). 자세한 내용은 위의 <refspec>... 섹션을 참조하십시오.

+0

흥미 롭습니다! 이것은 실제로 효과가 있습니다. – ivan