Git에서 특정 커밋을 병합하는 방법
저는 GitHub 저장소에서 지점으로 이동하여 저만의 것을 커밋했습니다.원래 저장소의 기능은 다음과 같습니다.HEAD.
이전 커밋 없이 Marge만 하고 싶습니다.어떻게 해야 하나?모든 커밋을 병합하는 방법을 알고 있습니다.
git branch -b a-good-feature
git pull repository master
git checkout master
git merge a-good-feature
git commit -a
git push
git cherry-pick 여기에 답이 있을 겁니다
기존 커밋에 의해 추가된 변경을 적용합니다.
이 투고에서 체리 줍기의 결과에 대한 bdonlan의 답변을 읽는 것을 잊지 마세요.
"브런치에서 모든 커밋을 꺼내고 지정된 커밋을 다른 커밋으로 푸시합니다." 여기서,
A-----B------C
\
\
D
다음과 같이 됩니다.
A-----B------C
\
\
D-----C'
이 커밋의 문제는 git이 커밋을 그들 앞에 있는 모든 이력을 포함한다고 간주한다는 것입니다.
서 C C'는 다르다.
SHA-1
마찬가지로, 체리는 한 지점에서 다른 지점으로 커밋을 선택하는 것은 기본적으로 패치를 생성하고 적용하는 것을 수반하며, 따라서 이력을 잃게 됩니다.
이 커밋 ID의 변경은 git의 Marge 기능을 다른 것들과 분리한다(단, 드물게 사용한다면 이를 덮어쓸 휴리스틱스가 있다).
그러나 더 중요한 것은 기능 의존성을 무시한다는 것입니다.C가 실제로 B에 정의된 함수를 사용했다면 알 수 없습니다.
git cherry-pick을 사용하여 하나의 커밋을 현재 브랜치에 적용할 수 있습니다.
::git cherry-pick d42c389f
를 들어, 커밋 마게 되다를 .e27af03XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
git checkout master
git cherry-pick e27af03
git push
예를 들어 다음 사항을 이해하도록 하겠습니다.
예를 들어 마스터라는 브랜치가 X <commit-id>를 가리키고 Y <sha1>을 가리키는 새로운 브랜치가 있습니다.
여기서 Y <commit-id> = <master> 브랜치커밋 - 소수의 커밋
이제 Y 브런치의 경우 마스터 브런치와 새 브런치 사이의 커밋을 갭 클로즈해야 합니다.이하의 순서에 따릅니다.
순서 1:
git checkout -b local origin/new
local은 지점 이름입니다.임의의 이름을 붙일 수 있습니다.
순서 2:
git merge origin/master --no-ff --stat -v --log=300
마스터 브랜치에서 새로운 브랜치로 커밋을 Marge하고 로그 메시지의 Marge 커밋을 만듭니다.또, Marge 하고 있는 실제 커밋은 최대 <n>개입니다.
Git merge에 대한 자세한 내용과 파라미터는 다음을 참조하십시오.
git merge --help
또, 특정의 커밋을 Marge 할 필요가 있는 경우는, 다음을 사용할 수 있습니다.
git cherry-pick <commit-id>
나는 체리픽을 즐겨 먹었지만 가끔 이상한 문제가 있다는 것을 알았다.마이크로소프트에서 25년간 근무한 Raymond Chen의 블로그에 체리 따기가 특정 경우에 문제를 일으킬 수 있는 시나리오가 기재되어 있습니다.
경험의 법칙 중 하나는 한 지점에서 다른 지점으로 선택한 후 나중에 지점 간에 결합하면 조만간 문제가 발생할 수 있다는 것입니다.
이 주제에 대한 Raymond Chen의 블로그 참조: https://devblogs.microsoft.com/oldnewthing/20180312-00/?p=98215
레이먼드의 블로그에서 유일하게 문제가 된 것은 그가 완전한 작업 예를 제시하지 않았다는 것입니다.그래서 여기서 하나를 제공하려고 합니다.
위의 질문에서는 a-good-feature 브랜치의 HEAD가 지적한 커밋만을 마스터로 Marge하는 방법을 묻고 있습니다.
그 방법은 다음과 같습니다.
- 마스터 브랜치와 a-feature 브랜치 사이의 공통 조상을 찾습니다.
- 이 상위 항목에서 새 분기를 만들면 이 새 분기를 패치라고 합니다.
- Cherry는 이 새로운 패치브런치에 커밋을 1개 이상 선택합니다.
- 패치 브런치를 마스터브런치와 정상적인 기능의 브런치 양쪽에 Marge 합니다.
- 이제 마스터 브랜치에는 커밋이 포함되며 마스터 브랜치 및 a-기능 브랜치에도 새로운 공통 상위 항목이 있습니다.이것에 의해, 나중에 추가의 마지가 실행되면, 장래의 문제가 해결됩니다.
이러한 명령어의 예를 다음에 나타냅니다.
git checkout master...a-good-feature [checkout the common ancestor]
git checkout -b patch
git cherry-pick a-good-feature [this is not only the branch name, but also the commit we want]
git checkout master
git merge patch
git checkout a-good-feature
git merge -s ours patch
a-good-feature 브랜치에 Marge된 마지막 행은 "-s are" merge strategy를 사용한 것입니다.그 이유는 a-good-feature 브랜치에서 새로운 공통 조상을 가리키는 커밋을 작성하기만 하면 되기 때문입니다.또, 그 브랜치에 코드가 이미 존재하고 있기 때문에, 머지 경합이 발생하지 않게 하고 싶다고 생각하고 있습니다.Marge할 커밋이 최신이 아닌 경우 이 처리가 더욱 중요합니다.
부분 병합에 대한 시나리오와 세부 사항은 매우 깊어질 수 있으므로 Raymond Chen의 블로그 10개 부분을 모두 읽고 무엇이 잘못될 수 있는지, 어떻게 하면 피할 수 있는지, 그리고 왜 이것이 작동하는지 완전히 이해할 것을 권장합니다.
마스터 브랜치에 변경을 커밋한 경우.이제 같은 커밋을 릴리스 브랜치로 이동하려고 합니다.커밋 ID(예:xyzabc123)를 확인합니다.
이제 명령어를 따라보세요.
git checkout release-branch
git cherry-pick xyzabc123
git push origin release-branch
선두의 답변에서는, 특정의 커밋으로부터 현재의 브랜치에의 변경의 적용 방법에 대해 설명합니다.만약 당신이 "합병하는 방법"을 의미하는 것이라면, 그들이 제안하는 대로 체리 픽을 사용하세요.
그러나 실제로 합병을 원하는 경우, 즉 두 부모(현재 브랜치 상의 기존 커밋과 변경 적용원 커밋)를 가진 새로운 커밋을 원하는 경우 체리픽으로는 이를 달성할 수 없습니다.
예를 들어 빌드 프로세스가 git 조상을 이용하여 최신 태그를 기반으로 버전 문자열을 자동으로 설정하는 경우 진정한 병합 이력을 갖는 것이 바람직할 수 있습니다.git describe를 참조해 주세요.
대신 을 할 수 .git merge --no-commit인덱스를 수동으로 조정하여 원하지 않는 변경 사항을 제거합니다.
이 나뭇가지에 A 끝의 합니다.B:
git checkout A
git merge --no-commit B
두 되었습니다. 팁 now with of 、 제 、 제 、 commits 、 commits 、 commits 、 commits 、 commits 、 commits 、 commits 、 。 현재 팁 커밋은A ★★★★★★★★★★★★★★★★★」B그러나 B 브런치에서의 이전 커밋 변경 등 원하는 것보다 많은 변경이 적용될 수 있습니다.이러한 불필요한 변경을 실행 취소한 후 커밋해야 합니다.
(처음에는 작업 디렉토리와 인덱스의 상태를 Marge 전의 상태로 되돌리는 간단한 방법이 있을 수 있습니다.따라서 처음부터 원하는 커밋을 선택할 수 있습니다.하지만 나는 어떻게 하면 그 깨끗한 슬레이트를 얻을 수 있을지 모르겠다. git checkout HEAD ★★★★★★★★★★★★★★★★★」git reset HEAD둘 다 머지 상태를 삭제하고 이 메서드의 목적을 무시합니다.)
따라서 원하지 않는 변경을 수동으로 실행 취소합니다.예를 들어,
git revert --no-commit 012ea56
않는 012ea56.
조정을 마치면 커밋을 작성합니다.
git commit -m "Merge in commit 823749a from B which tweaked the timeout code"
이제 원하는 변경만 가능하며, 조상 트리는 기술적으로 B에서 병합한 것으로 나타납니다.
.git cherry-pick <commit-number>
시나리오:저는 릴리스라는 브랜치에 있으며 마스터 브랜치에서 릴리스 브랜치로 변경 내용을 몇 개만 추가하고 싶습니다.
순서 1: 변경을 추가하는 브랜치를 체크 아웃 합니다.
git checkout release
순서 2: 추가할 변경의 커밋 번호를 가져옵니다.
예를들면
git cherry-pick 634af7b56ec
3: § 3:git push
주의: 병합할 때마다 별도의 커밋 번호가 생성됩니다.동작하지 않는 Marge의 커밋 번호를 취득하지 말아 주세요.대신 추가할 일반 커밋의 커밋 번호입니다.
제 사용 사례에서도 CI CD에 대한 비슷한 요구가 있었습니다.git flow를 develope 및 master branch에서 사용했습니다.개발자는 변경 사항을 직접 병합하여 개발하거나 기능 브랜치로부터의 풀 요청을 통해 자유롭게 작성할 수 있습니다.그러나 마스터하기 위해 Jenkins를 통해 자동화된 방법으로 개발 브랜치로부터의 안정적인 커밋만 병합합니다.
이 경우 체리픽은 좋은 선택이 아닙니다.단, commit-id에서 local-branch를 작성한 후 해당 local-branch를 마스터에 Marge하여 mvn clean verify를 실행합니다(maven 사용).성공하면 localCheckout=true 옵션과 pushChanges=false 옵션이 있는 maven 릴리스 플러그인을 사용하여 운영 버전 아티팩트를 nexus에 릴리스합니다.마지막으로 모든 것이 성공했을 때 변경사항과 태그를 원래 위치로 푸시합니다.
샘플 코드 스니펫:
수동으로 수행하는 경우 마스터 상태라고 가정합니다.단, jenkins에서는 repo를 체크 아웃할 때 기본 브랜치(설정되어 있는 경우 마스터)에 있습니다.
git pull // Just to pull any changes.
git branch local-<commitd-id> <commit-id> // Create a branch from the given commit-id
git merge local-<commit-id> // Merge that local branch to master.
mvn clean verify // Verify if the code is build able
mvn <any args> release:clean release:prepare release:perform // Release artifacts
git push origin/master // Push the local changes performed above to origin.
git push origin <tag> // Push the tag to origin
이렇게 하면 두려움 없는 합병이나 충돌 지옥에서 완전한 제어가 가능합니다.
더 나은 선택지가 있다면 얼마든지 조언해 주세요.
체리픽을 처음 사용하는 경우 GitHub 데스크톱 버전을 사용해 보십시오.체리픽 옵션을 선택하면 GitHub에서 커밋을 푸시할 브랜치를 선택하도록 요구됩니다.
1)
2)
답을 제시하겠습니다.즉, Export를 통해 수동으로 타겟 브랜치를 변경하고 커밋하는 것입니다.또한 Turtle 등의 툴을 사용하는 경우 export는 이를 실현하는 효과적인 방법이 될 수 있습니다.이것이 SVN에서 잘 작동하는 것을 알고 있으며, 지금까지 git의 일부 테스트에서도 동일한 성공을 거두고 있습니다.이것들이 100% 동일하다면 향후 기능 브랜치 병합으로 인한 충돌 해결은 없을 것입니다.
들어 보겠습니다.
c:/git/MyProject_Master/ModuleA/
c:/git/MyProject_FeatureA//
로부터 모든 .A의 특징 A의 특징.이것은 큰 프로젝트이고 다른 모듈이 있다고 가정해 봅시다.또한 모듈A는 기능 브랜치의 새로운 변경으로 컴파일러나 기능상의 문제를 일으킬 수 있는 의존관계가 없다는 것을 경험으로 알고 있습니다.모듈 A - Torte로부터의 내보내기모듈 A를 선택합니다.마지막으로 각 파일의 파일 차이 체크를 실행하여 변경 내용을 확인하고 diff 도구를 사용하여 모든 콜이 여전히 호환되는지 확인합니다.컴파일되는지 확인하고 철저히 테스트합니다.밋, . 이 svn에 오랜 시간 합니다.이 솔루션은 svn에 대해 오랜 시간 테스트되었으며 효과적입니다.
언급URL : https://stackoverflow.com/questions/881092/how-to-merge-a-specific-commit-in-git
'source' 카테고리의 다른 글
| 이전 버전의 Cocapod를 다운그레이드 또는 설치하는 방법 (0) | 2023.04.17 |
|---|---|
| Swift 4 모드에서 Swift 3 @objc 추론 사용은 권장되지 않습니다. (0) | 2023.04.17 |
| 비트맵 이미지의 특정 픽셀 색상 찾기 (0) | 2023.04.17 |
| 사용되지 않는 크기의 대체With Font: iOS 7? (0) | 2023.04.17 |
| 삽입 명령 실행 및 SQL에 삽입된 ID 반환 (0) | 2023.04.17 |

