Git의 다른 지점에있는 지점 인 '병합'이 아닌 '덮어 쓰기'는 어떻게합니까?


257

나는 두 가지를 가지고 email와 staging. staging최신 버전이며 더 이상 email지점 의 이전 변경 사항이 필요 하지 않지만 삭제하고 싶지 않습니다.

난 그냥 모든 내용을 덤프하려는 그래서 staging으로 email그래서 그들은 동일에 두 점 커밋. 가능합니까?


답변:


196

'ours'병합 전략을 사용할 수 있습니다 :

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our branch head

26
나는 이것을 시도했는데, 나에게 거꾸로 보인다? 이것은 전자 메일의 내용을 스테이징으로 덤프하지 않습니까?
— Max

27
@Max 나는 같은 혼란을 겪었고 많은 문제를 일으켰습니다. 최신 지사 (준비)에서이 명령을 수행 한 다음 기존 지사 (이메일)에 대해 일반적인 병합 / PR을 수행해야합니다.
— MrGlass

7
;각 명령의 끝에 왜 ? 나는없이 ;있었고 그것은 효과가있는 것 같습니다. 또한이 답변은 불완전합니다. 세 번째 단계는 이전 지점 (이메일)을 체크 아웃 한 다음 준비와 다시 병합하는 것입니다.
— Rosdi Kasim

4
git rebase -s theirs <oldbranc> <newbranch> 어느 지점에 관계없이 잘 작동합니다. rebase에서 '그들의'는 실제로 새로운 브랜치입니다. 왜냐하면 '우리'는 현재 커밋을 적용하는 헤드이기 때문입니다.
— Rolf

4
@Rolf : 그러나 rebase는 병합 정보를 제거하고 히스토리를 평평하게합니다. 반드시 당신이 무엇을했는지는 아닙니다. 이미 게시 된 기록으로 작업하는 경우에도 좋은 생각이 아닙니다.
— knittl

99

'email'과 'staging'두 가지를 동일하게하려면 'email'분기에 태그를 지정한 다음 'email'분기를 'staging'하나로 재설정하십시오.

$ git checkout email
$ git tag old-email-branch
$ git reset --hard staging

'이메일'브랜치에서 '스테이징'브랜치를 리베이스 할 수도 있습니다. 그러나 결과에는 두 가지의 수정 사항이 포함됩니다.


1
당신은 아마 평균 git checkout, git check내 지식에 존재하지 않는
— knittl

4
맞습니다. git 명령을 완료하는 데 익숙해서 항상 "git check <TAB>"을 작성하여 "git checkout"을 작성합니다! 수정했습니다.
— Sylvain Defresne

17
자식 리셋 나누기 당신의 repo 복제 한 다른 사람들의 REPO
— 제프리 드 스멧

나는 이것이 정답이라고 믿는다. email지점의 헤드는 동일한 헤드를 가리켜 야하며 staging둘 다 동일한 커밋, 동일한 히스토리를 갖습니다.
— cicerocamargo

76

나는 몇 가지 답변을 보았으며 그것이 충돌없이 해결할 수있는 유일한 절차입니다.

branch_old의 branch_new에서 모든 변경 사항을 원하면 다음을 수행하십시오.

git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new

이 네 가지 명령을 적용하면 문제없이 branch_old를 푸시 할 수 있습니다


5
HEAD를 재설정하고 싶지 않기 때문에 귀하의 답변은 실제로 내 문제에 가장 잘 맞습니다. 더 오래된 지점에 항목을 병합 할 때 최신 지점의 최신 파일에 대한 환경 설정을 지정하고 문제없이 작업하십시오! +1
— 스토브

"우리의 병합"후에 branch_new를 원격으로 푸시 했는데이 방법이 효과적이었습니다. 내가 밀어야 했습니까? 아니면없이 일했을까요? (로컬 브랜치 또는 원격을 사용하는지 확실하지 않습니다). 감사!
— aspergillusOryzae

왜 간단히 아래를 할 수 없습니까? 자식 체크 아웃 branch_old 자식 병합에서 가져온 그들의 branch_new 단서 -s stackoverflow.com/questions/14275856/...을
— Ripu Daman의에게

그것은 병합 전략 '그들의'를 찾을 수 없다고 말합니다.
— arango_86 '10

나를 위해 완벽하게 작동 아무것도 설정하라는없는 장점이 있습니다
— 로맹

68

다른 답변은 나에게 올바른 단서를 주었지만 완전히 도움이되지 않았습니다.

나를 위해 일한 것은 다음과 같습니다.

$ git checkout email
$ git tag old-email-branch # This is optional
$ git reset --hard staging
$
$ # Using a custom commit message for the merge below
$ git merge -m 'Merge -s our where _ours_ is the branch staging' -s ours origin/email
$ git push origin email

우리의 전략과 합병하는 네 번째 단계가 없다면, 푸시는 빨리 감기가 아닌 업데이트로 간주되며 GitHub에 의해 거부됩니다.


병합 커밋 메시지가 잘못되었지만 그래도 훌륭하게 작동합니다.
— cdunn2001

cdunn2001, 궁금합니다. 예상했던 병합 커밋 메시지는 무엇이며 어떻게 엉망이 되었습니까?
— Shyam Habarakada 2016 년

"원격 추적 지점 '원본 / 이메일'을 전자 메일에 병합"이라고 말합니다. 스테이징에 대해서는 언급하지 않습니다. 그러나 큰 문제는 없습니다. 커밋을 수정하거나을 사용하십시오 merge -m 'This is not my beautiful house.' -s ours origin/email.
— cdunn2001

@ShyamHabarakada, 나는 당신이 말한대로하고, 빨리 감기가 아닌 업데이트에 관한 문제를 얻습니다. 네 번째 단계를 수행해도 아무 일도 일어나지 않기 때문입니다.
— kommradHomer

네 번째 단계에서는 원본 / 이메일을 사용해야하며, 로컬 이메일만으로는 작동하지 않습니다.
— Travis Reeder

45

나와 같고 병합을 처리하지 않으려면 병합 대신 힘을 사용하지 않고 위의 단계를 수행하면 산만 한 로그 용지 흔적이 만들어집니다.

git checkout email
git reset --hard staging
git push origin email --force

참고 : 이것은 절대로 다시 이메일로 내용을보고 싶지 않은 경우에만 해당됩니다.


1
git push origin email --2 단계 왼쪽 지점이 분기되어 힘이 작동하지 않았습니다. 따라서 2 단계 이후에 이것이 내가 한 것입니다 : git reset origin / email and git push
— user3505394

2
이것이 바로 "머지가 아니라 덮어 쓰는 방법"이라는 질문이었습니다. 대답을 받아 들여야합니다.
— jozols

17

모든 내용이의 내용 old_branch으로 업데이트 되도록 두 개의 브랜치를 병합하고 싶었습니다.new_branch

나를 위해 이것은 매력처럼 작동했습니다.

$ git checkout new_branch
$ git merge -m 'merge message' -s ours origin/old_branch
$ git checkout old_branch
$ git merge new_branch
$ git push origin old_branch

10

어때요?

git branch -D email
git checkout staging
git checkout -b email
git push origin email --force-with-lease

@emptywalls는 서버가 거부 할 수 있다는 경고없이 사용자에게 강제로 푸시하지 않기 때문에 필요한 이유를 설명하지 않습니다. 즉, 그것은 한 개발자 프로젝트를위한 실행 가능한 옵션입니다
— David Costa

@DavidCosta 왜 이것이 서버에 의해 거부됩니까? 이것은 간단한 전자 메일 삭제 및 전자 메일에 스테이징 복사 '입니다. 그래서'스테이징 '의 모든 내용을'이메일 '로 덤프하여 둘 다 동일한 커밋을 가리 키도록합니다. 여기.
— Arek S

@ArekS GitLab에서 분기가 "보호됨"으로 설정된 경우 서버 측 후크에 의해 거부 될 수 있습니다. 문제는 다른 사람이이 작업을하기 전에 전자 메일에서 자신의 지점을 가져 와서 푸시하려고하면 참조가 더 이상 일치하지 않는다는 것입니다 (일부 커밋이 사라지기 때문에)
— David Costa

1
필자는 원본을 --force에서 --force-with-lease로 편집하여 비파괴 방식으로 트릭을 수행합니다.
— frandroid

1
이것은 브랜치를 날려 버리고 소스 브랜치에서 깨끗하게 시작하려는 경우 가장 좋은 방법입니다.
— Shane

6

다른 답변은 불완전하게 보였습니다.
아래에서 전체를 시도했지만 정상적으로 작동했습니다.

참고 :
1. 아래에서 시도하기 전에 저장소를 안전한 곳에 보관하십시오.

세부 :
모든 개발 dev에 지점에서 발생 1.
2. 품질 보증 분기 DEV 단지 같은 카피
시간 3 시간, 개발 코드 요구 / 덮어 쓰기에 대한 품질 보증 지점을 이동합니다

dev 분기에서 qa 분기를 덮어 써야합니다.

1 부 :
아래 명령으로 이전 qa가 최신 개발자로 업데이트되었습니다.

git checkout dev
git merge -s ours qa
git checkout qa
git merge dev
git push

마지막 푸시에 대한 자동 주석은 다음과 같습니다.

// Output:
//  *<MYNAME> Merge branch 'qa' into dev,*  

이 주석은 역순으로 보입니다. 위 순서도 역순으로 보입니다.

2 부:

다음은 예상치 못한 새로운 로컬 커밋 개발, 불필요한 커밋
을 버리고 개발에 영향을 미치지 않는 것입니다.

git checkout dev

// Output:
//  Switched to branch 'dev'  
//  Your branch is ahead of 'origin/dev' by 15 commits.  
//  (use "git push" to publish your local commits)


git reset --hard origin/dev  

//  Now we threw away the unexpected commits

3 부 :
모든 것이 예상 한대로 확인하십시오.

git status  

// Output:
//  *On branch dev  
//  Your branch is up-to-date with 'origin/dev'.  
//  nothing to commit, working tree clean*  

그게 다야.
1. 오래된 품질 보증 이제 새로운 dev에 지점 코드를 덮어 씁니다
2. 지역이 깨끗한 (원격 원산지는 / dev는 그대로입니다)


6

가장 쉬운 방법 :

//the branch you want to overwrite
git checkout email 

//reset to the new branch
git reset --hard origin/staging

// push to remote
git push -f

이제 이메일 분기와 준비가 동일합니다.


2
경고 : email분기의 모든 커밋이 삭제됩니다 . email브랜치를 삭제하고 브랜치 헤드에서 새로 생성하는 것과 같습니다 staging.
— 카메론 허드슨

2
git checkout email
git merge -m "Making email same as staging disregarding any conflicts from email in the process" -s recursive -X theirs staging

1
주석이 명령의 병합 주석과 별개로 작성된 경우이 답변이 더 명확했을 것입니다. -X의 기능과이 병합에 어떤 영향을 미치는지 간략하게 설명하십시오. 그래도 고마워. :)
— noelicus

의견을 보내 주셔서 감사합니다. 나중에 답변을 편집 할 수 있습니다.
— Willa

0

이것은 원래의 새로운 브랜치를 변경하지 않으며 최종 커밋 전에 추가 수정을 할 수있는 기회를 제공합니다.

git checkout new -b tmp
git merge -s ours old -m 'irrelevant'
git checkout old
git merge --squash tmp
git branch -D tmp
#do any other stuff you want
git add -A; git commit -m 'foo' #commit (or however you like)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.