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


257

나는 두 가지를 가지고 emailstaging. 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.