차이가 있지만 Git merge에서“이미 최신”보고


286

마스터와 테스트의 두 가지 분기가있는 자식 저장소가 있습니다.

마스터 브랜치와 테스트 브랜치에는 차이가 있습니다.

두 지점 모두 모든 변경 사항이 적용되었습니다.

만약 내가한다면:

자식 체크 아웃 마스터
자식 차이 테스트

차이점을 보여주는 변경 사항이있는 화면이 나타납니다. 테스트 브랜치의 변경 사항을 병합하고 싶습니다.

자식 병합 테스트

그러나 "이미 최신"메시지가 표시됩니다.

그러나 각기 다른 브랜치에서 파일을 검사하면 차이점이 명확하게 나타납니다.

여기에 어떤 문제가 있으며 어떻게 해결합니까?


커밋되지 않은 수정 된 코드가 있습니까?
ozma

답변:


146

"이미 최신"메시지는 병합하려는 지점의 모든 변경 사항이 이미 현재 지점에 병합되었음을 의미합니다. 보다 구체적으로 말하면 병합하려는 지점이 현재 지점의 부모임을 의미합니다 . 축하합니다, 그것은 당신이 할 수있는 가장 쉬운 합병입니다. :)

사용 gitk저장소 살펴보고. "테스트"지점의 레이블은 "마스터"지점 레이블 아래에 있어야합니다.

지사는 부모와 관련하여 최신 정보입니다. 병합에 따르면 마지막 병합 이후 부모에 새로운 변경 사항이 없습니다. 그것은 당신이 당신의 작업 지점에 많은 변화를 가질 수 있고 당신처럼 들리기 때문에 가지가 동일하다는 것을 의미하지는 않습니다.

2019 년 10 월 12 일 수정 :

이 답변에 대한 의견에서 Charles Drake에 따르면 문제를 해결하는 한 가지 해결책은 다음과 같습니다.

git checkout master
git reset --hard test

이것은 다시 '테스트'레벨로 돌아갑니다.

그런 다음 수행하십시오.

git push --force origin master

중앙 리포지토리로 변경 사항을 강제로 되돌리려면


2
거룩한 cr * p! 네가 옳아! 다른 브랜치 (불안정한 개발)가 master와 잘못 병합되었고 테스트 브랜치가 불안정한 하위 집합이라고 생각합니다. 내가 합병하려는 것은 마스터를 '테스트'수준으로 되 돌리는 것이었다.
Charles Darke

2
권리. 그 작업은 의미가 없으므로 Git은 아무것도하지 않습니다. :)
Bombe

24
내가 지금 한 일은 : git checkout master; git reset-하드 테스트; 이것은 다시 '테스트'레벨로 돌아옵니다. 그런 다음 "git push --force origin master"를 수행하여 변경 사항을 중앙 저장소로 되돌 렸습니다.
Charles Darke

22
git이 "부모와 병합을 시도하는 중"이라고 경고했다면 좋았을 것입니다.
Charles Darke

1
원격 측에 이미 존재하는 브랜치의 자손이 아닌 브랜치를 푸시하는 것은 나쁜 것으로 간주됩니다. git-push 및 git-pull에 대한 매뉴얼 페이지의 토론을 참조하십시오.
Bombe

131

원격 마스터에 변경 사항이 있음을 알 때 종종 발생하므로을 사용하여 병합하려고합니다 git merge master. 그러나 이것은 원격 마스터와 병합되지 않지만 로컬 마스터와 병합됩니다.

따라서 병합을 수행하기 전에 마스터를 확인한 다음 수행하십시오 git pull. 그런 다음 새로운 변경 사항을 지점에 병합 할 수 있습니다.


7
분기의 전환을 피할 수있는 방법이 있습니까? 분기에서 병합 할 분기를 당기고 병합 한 다음 병합하는 것과 같은 것입니까?
Japheth Ongeri-inkalimeva

아, 좋아 git fetch현재 다른 지점에 있더라도 마스터 지점을 업데이트 할 것이라고 생각했습니다 . 그렇지 않다는 것이 밝혀졌습니다. 감사! fetch얻을 지점을 지정할 수 있는 옵션이 있다고 확신 합니다.
Raik

1
@Raik 당신은 할 수 git fetch --all있지만, 이것은 가지만 가져 오지만 가져 오지 않습니다.
Ingo Bürk

6
@ JaphethOngeri-inkalimeva 당신은 그냥 할 수 있습니다 git fetch --all && git merge origin/master. master원격 변경 사항을 병합 하기 위해 로컬을 업데이트 할 필요가 없습니다 .
Ingo Bürk

@ IngoBürk 나는 2 개의 브랜치를 가지고 있었고 1은 1로 git merge master, 1은 1로 업데이트 했습니다 git merge origin/master. 또한 체크 아웃했다 mastergit pull2 가지를 업데이트하기 전에. 동일한 내용을 공유했지만 두 지점 사이에 PR을 만들면 diff 파일이 표시되었습니다. git pull대상 분기에 의해 기능 분기로 수정되었습니다 Already up to date! Merge made by the 'recursive' strategy.. "동등한"로컬 브랜치와 원격 브랜치의 병합이 다른 이유는 무엇입니까?
wrapperapps

45

master다음 커밋 히스토리 가있는 브랜치 가 있다고 가정하십시오 .

A -- B -- C -- D

이제 분기 테스트를 작성하고 작업 한 다음 4 개의 커밋을 수행합니다.


                 E -- F -- G -- H
                /
A -- B -- C -- D

master의 머리는 D를 test가리키고 머리는 H를 가리 킵니다.

병합하려는 지점의 HEAD가 병합하려는 지점의 커밋 체인의 상위 항목 인 경우 "이미 최신"메시지가 표시됩니다. 그렇습니다. 여기는 D의 부모입니다 E.

에서 병합에 아무것도 없습니다 test로는 master아무것도에 변경되지 않았기 때문에, master그 이후. 여기서 당신이하고 싶은 것은 문자 그대로 Git master에게 H를 가리 키도록 지시하는 것이므로 마스터의 지점에는 다음과 같은 커밋 기록이 있습니다.

A -- B -- C -- D -- E -- F -- G -- H

이것은 Git 명령의 작업입니다 reset. 작업 디렉토리에이 변경 사항이 반영되기를 원하므로 하드 리셋을 수행해야합니다 .

git reset --hard H

3
나는 과거에 사용하는 git reset --hard것이 매우 과감한 일 이라고 들었습니다. 커밋을 잃을 수 있습니까? 이러한 변경을 수행하는 데 안전한 방법이 git reset --hard있습니까 , 아니면 과장된 위험이 있습니까?
Graham R. Armstrong

1
이 명령은 제정신입니다. 걱정할 필요가 없습니다. --hard옵션에 주의를 기울여야 할 유일한 것은 실제로 작업 디렉토리를 수정하므로 커밋되지 않은 변경 사항이 손실된다는 것입니다. 개인적으로, 나는 git status수동으로 git 명령을 실행하기 전과 후에 레포가 깨끗하거나 예상 상태에 있는지 확인합니다.
Marek Stanley

이렇게하면 "지점과 '원산지 / 마스터'가 분기되었습니다"라는 상태 메시지가 표시됩니다. 어떻게 해결할 수 있습니까?
에이도 95

1
나는 당신에게 하나 이상의 공감대를 줄 수 있기를 바랍니다. 감사!
KMC

--hard옵션이 필요 합니까? 나는이 상황에 몇 번이나 있었고 항상없이없이 재설정되었습니다 --hard. 커밋되지 않은 변경 사항을 잃을 위험없이 잘 작동했습니다.
카시미르

16

나를 위해 일하는 것은 branch1이 있고 branch2에 병합하고 싶다고 가정 해 봅시다.

git 명령 줄을 열고 branch2의 루트 폴더로 이동하여 다음을 입력하십시오.

git checkout branch1
git pull branch1
git checkout branch2
git merge branch1
git push

충돌이있는 경우 git push를 수행 할 필요는 없지만 먼저 충돌을 해결 한 다음 푸시하십시오.


6

병합은 항상 현재 HEAD와 하나 이상의 커밋 (일반적으로 분기 헤드 또는 태그) 사이에
있으며 인덱스 파일은 시작할 때 HEAD 커밋 트리 (즉, 마지막 커밋의 내용)와 일치해야합니다.
즉, git diff --cached HEAD변경 사항을보고하지 않아야합니다.

병합 된 커밋은 이미에 포함되어 HEAD있습니다. "이미 최신"이라고하는 가장 간단한 경우입니다.

즉, 테스트의 커밋이 이미 마스터에 병합되었지만 다른 커밋이 마스터에서 수행되므로 git diff test여전히 약간의 차이가 있습니다.


6

병합하려는 지점의 로컬 사본이 오래 되었기 때문입니다. 에 전화를 걸고 지점 MyBranch을에 병합하려고합니다 ProjectMaster.

_>git status
On branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

nothing to commit, working tree clean

_>git merge ProjectMaster
Already up-to-date.

그러나 병합해야 할 변경 사항이 있음을 알고 있습니다!

여기에 내가 입력 할 때 git merge ProjectMastergit 은이 분기의 로컬 사본을 봅니다 . 현재가 아닐 수도 있습니다 . 이것이 사실인지 확인하기 위해 먼저 Git에게 분기가 오래되었는지 확인하고 uh,을 사용하여 변경 사항을 가져 오도록 지시 fetch합니다. 그런 다음 병합하려는 지점으로 이동하여 발생한 일을 확인합니다.

_>git fetch origin

_>git checkout ProjectMaster
Switched to branch ProjectMaster
**Your branch is behind 'origin/ProjectMaster' by 85 commits, and can be fast-forwarded.**
  (use "git pull" to update your local branch)

아하! 내 로컬 사본은 85 커밋에 의해 오래되었습니다. 이제 Pull누락 된 변경 사항을 아래로 옮긴 다음 MyBranch다시 병합을 시도하십시오.

_>git pull
Updating 669f825..5b49912
Fast-forward

_>git checkout MyBranch-Issue2
Switched to branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

_>git merge ProjectMaster
Auto-merging Runbooks/File1.ps1
CONFLICT (content): Merge conflict in Runbooks/Runbooks/File1.ps1

Automatic merge failed; fix conflicts and then commit the result.

이제 해결해야 할 또 다른 문제가 있습니다.


5

이상하게도 GIT는 로컬 브랜치가 원격 브랜치와 다르다고 생각했기 때문에 이런 일이 일어났습니다. 이것은 분기 그래프에서 볼 수 있습니다. remotes / origin / branch_name과 branch_name의 두 가지 분기가 표시되었습니다.

해결책은 단순히 로컬 리포지를 제거하고 원격에서 다시 복제하는 것입니다. 이 방법으로 GIT는 remotes / origin / branch_name>과 branch_name이 실제로 동일하다는 것을 이해할 것입니다 git merge branch_name.

rm <my_repo>
git clone <my_repo>
cd <my_repo>
git checkout <branch_name>
git pull
git checkout master
git merge <branch_name>

이것이 Acarter와 정확히 같은 대답입니까?
Andrew C

Acarter는 실제로 요점을 놓쳤다 고 생각합니다. 리모컨에는 아무런 변화가 없었습니다. 전혀 문제가되지 않았습니다. "git checkout master"를 선택한 다음 "git merge <branch_name>"을 사용하여 빨리 감기 병합을 수행해야했습니다. 다른 방법은 지점이 마스터보다 앞서서 아무것도하지 않았습니다. Bombe의 대답은 좋은 설명이지만 질문의 "어떻게 해결합니까"에 대답하지 않았습니다.
MrMas

5

git merge origin/master대신 git merge master나를 위해 일했습니다. 따라서 마스터를 기능 분기로 병합하려면 다음을 사용할 수 있습니다.

git checkout feature_branch
git merge origin/master

5

병합하려는 지점을 먼저 체크 아웃 한 다음 당겨서 로컬 버전이 원격 버전과 일치하는지 확인하십시오.

그런 다음 병합을 수행하려는 지점으로 다시 체크 아웃하면 git merge가 작동합니다.


1
이것은 나를위한 것이었다-나는 마스터에있는 동안 당겼다; "브랜치"에 새로운 커밋이 있다는 것을 알게되었습니다. "지점"을 마스터로 병합하려고했습니다- "이미 최신"입니다. 나요 자식 체크 아웃 "지점"- 가지고, 내가 실행하여 "지점"을 업데이트하는 데 필요한 수단 "당신의 지점 뒤에 ... 그리고 빠르게 전달 될 수있다." git pull은 "지점"에있는 동안
sdbbs

3

같은 시나리오가 있는지 확실하지 않지만이 "테스트"브랜치를 "다시 병합"하려고했습니다.

그래서 이전에 병합했지만 병합 중에 일부 특정 변경 사항을 의도적으로 제외하므로 분기 사이에 약간의 차이가 있습니다. 그런 다음 이전에 제외 한 특정 변경 / 파일을 추가하고 싶다는 것을 알고 / 잊어 버렸기 때문에 다시 병합하려고했습니다. 병합을 다시 수행하면 이전에 제외 된 모든 변경 사항이 표시되기를 바랐습니다. , 그러나 내가 틀렸고 대신 "이미 최신"메시지가 대신 나타납니다.

@ Bonbe의 의견 / 답변을 읽었을 때, 그는 맞습니다 .git은 그렇게 행동한다고 ​​생각합니다. 그래서 테스트 브랜치에서 파일을 하드 백업 한 다음 마스터 브랜치를 체크 아웃하고 수동으로 파일을 붙여 넣고 커밋하는 것이 었습니다 마치 새로운 변화 인 것처럼 말입니다.

이것이 올바른 방법인지 확실하지 않거나 다른 사람들 이이 같은 문제를 겪을 수 있도록 도울 수는 있지만 내 특정 사례에 대한 해결책을 제공했습니다.


같은 상황입니다. 시나리오는 "통합"분기를 여러 "기능"분기로 다시 분할하려는 것입니다.
Yadli

2
수동 붙여 넣기 대신 한 분기에서 현재 분기로 파일을 직접 체크 아웃 할 수 있습니다 git checkout srcBranch -- path/to/file. 파일 glob도 사용할 수 있습니다.
Todd

덕분에, 나는 당신의 체크 아웃 방법을 사용하지만, 내가 넣어 checkout srcBranch -- *다음 내 차이점 보았다
portforwardpodcast

2

분기 A를 분기 B에 병합하면 "이미 최신 상태"라고보고되는 ​​경우 항상 반대가 아닙니다. 분기 B가 분기 A의 후손 인 경우에만 해당되며 그렇지 않으면 분기 B는 단순히 A에없는 변경 사항을 가질 수 있습니다.

예:

  1. 마스터 A에서 B 지점을 생성합니다
  2. 마스터에서 일부 변경을 수행하고 이러한 변경을 분기 B에만 병합합니다 (분기 A를 업데이트하거나 업데이트하지 않는 것).
  3. 분기 A에서 일부를 변경하고 A를 B로 병합합니다.

이 시점에서 A에서 B로 병합하면 "이미 최신 상태"로보고되지만 분기 B는 마스터의 업데이트가 있고 분기 A는 그렇지 않으므로 분기가 다릅니다.


2

Git Bash를 사용하여이 시나리오에 직면했습니다.

우리 저장소에는 여러 개의 브랜치가 있으며 각 브랜치는 다른 커밋주기를 가지며 병합은 가끔씩 발생합니다. Old_Branch는 New_Branch의 부모로 사용되었습니다.

Old_Branch는 New_Branch와 병합해야하는 일부 변경 사항으로 업데이트되었습니다.

모든 분기에서 모든 소스를 가져 오기 위해 분기없이 pull 명령을 사용하고있었습니다.

자식 풀 원점

이상하게도 모든 분기에서 모든 커밋을 가져 오는 것은 아닙니다. 표시된 거의 모든 지점과 태그를 표시하는 것으로 생각했습니다.

그래서이 문제를 해결하기 위해 Old_Branch가 최신을 가져 왔습니다.

git checkout Old_Branch

자식 풀 원점 Old_Branch

이제 New_Branch를 확인했습니다

git checkout New_Branch

확실하게 당겨

git pull origin New_ 브랜치

자식 병합 Old_Branch

그리고 viola는 Old_Branch에서 New_Branch로 수정해야 할 충돌을 얻었습니다.


0

나도 마찬가지였다. 그러나 시나리오는 약간 달랐고 마스터 지점이 있었고 release_1 (예 :)을 조각했습니다. release_1 브랜치를 약간 변경하여 원점으로 병합했습니다. 그런 다음 ssh를하고 원격 서버에서 git checkout -b release_1 명령을 사용하여 release_1을 다시 체크 아웃합니다. 실제로 새로운 분기 release_! 원점에서 이미 존재하는 브랜치 release_1을 체크 아웃하는 대신 마스터에서. "-b"스위치를 제거하여 문제 해결


0

나는 같은 문제가 있었다. 리모컨에 변경 사항이 있는데 여전히 "이미 최신"으로 표시되었습니다. 저장소를 다시 복제하면 문제가 해결되었습니다.


0

어리석은 일이지만 일어날 수 있습니다. #91-fix-html-markup이 병합을 수행하는 경우 브랜치 이름 앞에 이슈 참조 (예 :)가 있다고 가정하십시오 .

$ git merge #91-fix-html-markup

이후의 모든 항목 #이 무시 되므로 의도 한대로 작동하지 않습니다.#인라인 주석을 시작 .

이 경우 분기 이름을 생략 #하거나 작은 따옴표를 사용하여 분기 이름을 묶을 수 있습니다 git merge '#91-fix-html-markup'.

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