한 분기에서 어떤 커밋이 다른 분기에 없는지 확인하는 방법은 무엇입니까?


180

두 가지 develnext있습니다. 드디어 나는 다소 많은 양의 커밋을 가지고 있습니다. 커밋 중 일부는에서 선택되었습니다 next. 또한 다음에 커밋을 추가했습니다 devel.

이제 무엇이 빠졌는지보고 싶기 next때문에 변경 사항을 자세히 테스트하여 적용 할 수 있습니다 next. 내 질문은 지금 어떤 커밋이 devel다음에 아닌지 어떻게 알 수 있습니까?



비교하려는 것은 두 가지의 끝이기 때문에 제목은 약간 오도됩니다. 그리고 나는 두 가지의 특정 (다른) 커밋을 비교하는 해결책을 찾기 위해 여기에 왔습니다
버그 탐지기

답변:


210

거의 사용 git cherry하지 않는 명령 은 아직 체리 피킹되지 않은 커밋을 보여줍니다. 에 대한 설명서 git cherry여기 에 있지만 간단히 말해 다음을 수행 할 수 있습니다.

git checkout devel
git cherry next

... 그리고 다음과 같이 약간의 출력을 참조하십시오.

+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9

로 시작하는 커밋은 +당신이 그 사람이 될 것이다 아직하지 않은 에 벚꽃이 고른 next. 이 경우 지금까지 단 하나의 커밋을 선택했습니다. -v매개 변수를 git cherry명령 에 추가하여 각 커미트의 제목 행을 출력 할 수도 있습니다.


좋아, 이것이 내가 필요한 것. 테스트에 대한 간단한 설명을 얻는 것도 좋지만 스크립트를 작성할 수 있습니다.
Sascha Effert

29
당신은 할 필요가 없습니다 git checkout devel, 당신은 할 수 있습니다 git cherry next devel.
Robin Winslow 8

21
"을 추가하고 싶-v 습니까? " 없이 벚꽃 -v처럼 ls없이 -la. ; -J
Slipp D. Thompson

1
그리고 cherry동등한 커밋을 표시하거나 제외 시키는 방법을 알지 못 합니까? cherry배관 명령처럼 보이지만 많은 옵션을 제공하지는 않습니다. 내가 현재 중간에있는 것에 git cherry대해, 거짓 긍정을 주지만 @sehe git log --cherry-pick는 이전에 선택된 / rebased 커밋을 올바르게 제외합니다.
Slipp D. Thompson

이 문서는 구체적인 예를 제공합니다. git-scm.com/docs/git-cherry#_concrete_example
ams

107

또한 사용할 수 있습니다

git log --left-right --graph --cherry-pick --oneline devel...next

분 기간에 공유되지 않은 실제 다른 커밋 목록을 가져옵니다 .

작동 단어는 --cherry-pick

--cherry-pick

커밋 세트가 대칭 차이로 제한되는 경우 "다른 쪽"의 다른 커밋과 동일한 변경을 유발하는 커밋은 생략하십시오. 예를 들어, A와 B라는 두 개의 분기가있는 경우 해당 옵션의 설명에서 위의 예와 같이 한쪽의 커밋을 모두 나열하는 일반적인 방법은 --left-right입니다. 그러나 다른 브랜치에서 체리 피킹 된 커밋을 보여줍니다 (예 : "b의 3rd"는 브랜치 A에서 체리 피킹 될 수 있음). 이 옵션을 사용하면 이러한 커밋 쌍이 출력에서 ​​제외됩니다.

업데이트 로이 코멘트에 언급, 자식의 최신 버전은 추가 --cherry-mark:

--cherry-mark

--cherry-pick (아래 참조)과 같지만 동등한 커밋은 생략하지 않고 =로 표시하고 +는 +와 동일합니다.


1
이것은 나를 위해 작동하지 않았습니다. 내 버전의 git은 한 줄을 알지 못하므로 제거했습니다. 그런 다음 devel을 교환하고 다음에 작동했습니다. 아주 좋아요!
Sascha Effert

@SaschaEffert : devel과 next를 전환 할 필요가 없었습니다 (2 개가 아닌 3 개의 점에 주목). 즉, 고대 버전의 git (?) 을 사용하면 상황이 다를 수 있지만이 경우 세 점에서 rev-parse 오류가 발생해야합니다.
sehe

2
재미를 위해 2006 년 7 월에 '...'(대칭 차이) rev-parse 구문 이 추가되었고 2008 년 6 월에 해당 문서 가 업데이트되었습니다 . 오픈 소스의 기쁨!
sehe

1
'gls --first-parent --cherry-mark --left-only develop ... next'여기서 gls는 모든 형식이 지정된 내 자식 로그 별칭입니다. cherry-mark는 개발시 체리 피킹 및 비 체리 피킹 커밋을 보여 주지만 다르게 표시합니다.
angularsen

1
어쩌면 더 나은 --no-병합을 추가
MervynYang

51

자식 로그 서브셋을 시도해 볼 수 있습니다.

git log --oneline devel ^next

4
이것은 내 의견으로는 가장 좋은 해결책입니다 (@sehe의 답변은 다음에 커밋을 보여줍니다 --left-only. 그러나 --no-merges병합 커밋을 생략 하여 (예 : 기능 또는 핫픽스 분기가 (별도로) 개발 및 다음 단계로 병합 된 경우) 추가 하여 조금 개선 할 수 있습니다 . 엄밀히 말해서 병합의 충돌 해결은 다른 차이점을 만들 수 있지만 일반적으로 그렇지 않습니다. 이 --no-merges옵션은 다른 답변에도 유용하게 적용 할 수 있습니다.
Alex Dupuy

27

어때요?

git log next..devel

결과는 Byran의 답변 (커밋의 다른 순서)과 비슷하지만 두 답변 모두 지점간에 다른 커밋을 생성합니다.


4
현재 해당 지점에있는 경우 두 번째 지점을 생략 할 수도 있습니다. 즉,git log next..
jmaxyz

BTW '자식 로그 next..devel'는 '자식 로그 devel..next'다르다
유진 Kaurov

1

릴리스 브랜치 (다음)에 통합되지 않은 커밋 목록을 얻으려면 다음을 사용할 수 있습니다.

git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt

자세한 내용은 git-rev-list 를 확인하십시오 .


이 답변의 명령에 문제의 실제 분기가 표시되지 않습니다.next...devel
Alex Dupuy

@AlexDupuy Yah, 꽤 반 답변입니다. 그것은 또한 가장 간단한 대답이 아니며 왜이 접근법이 더 나은지 설명하지 않기 때문에 나는 그것을 1 대 1로 하고 있습니다.
Slipp D. Thompson

-1

@ Mark Longair는 여기에 그의 대답에 못을 박았 지만 통찰력을 더하고 싶습니다.

특히 커밋을 스쿼시하는 것이 하나 이상의 master를 feature_branch로 병합하여 실효 적이 지 않은 경우 큰 PR (Pull Request)을 분리하는 방법에 대한 질문에 응답

내 상황 :
나는 feature_branch30 개의 커밋 으로 크게 만들고 GitHub에서 PR (Pull Request)을 열어서 합병했다 master. 지점 master은 저의 톤을 바꾸었고 저 feature_branch에게는 없었던 200 개의 커밋을 받았습니다 . 갈등을 해결 git checkout feature_branch하고 변경 사항을 내 git merge master것으로 병합했습니다 . 나는에 선택 이 아닌 내가 해결 충돌 대신 잠재적으로 30 배의 하나의 시간이 것 때문에 최신 마스터에 (내 커밋 각각에 대해 한 번). 30 커밋을 1로 먼저 스쿼시하고 최신 정보를 다시 사용하고 싶지 않았습니다.masterfeature_branchmergerebasemasterPR에서 GitHub 리뷰 댓글 기록을 지울 수 있기 때문입니다. 그래서 마스터를 기능 지점으로 병합하고 충돌을 한 번만 해결했습니다. 모든게 괜찮 았어. 그러나 내 PR은 동료들이 검토하기에는 너무 컸습니다. 나는 그것을 나누어야했다. 나는 30 번의 커밋과 OH NO! 그들은 어디에 있습니까? 그들은 master내가 최근에 합병했기 때문에 200 개의 최근 커밋 과 상호 작용 master하고 있습니다 feature_branch! 어떻게해야합니까?

git cherrygit cherry-pick개별 커밋 을 시도하려는 경우 사용법 :

git cherry 구조에 (다양한)!

안에 feature_branch있지만 안에 있지 않은 모든 커밋을 보려면 다음을 master수행하십시오.

git checkout feature_branch
git cherry master

또는 다음 과 같이 feature_branch먼저 수행 하여 모든 지점에서 커밋을 확인할 수 있습니다 git cherry [upstream_branch] [feature_branch]. 다시 말하지만 어떤 커밋이 있는지 확인 feature_branch하지만 upstream_branch( master이 경우)에 있지 않은 커밋이 있는지 확인합니다 .

git cherry master feature_branch

추가 -v하면 커밋 메시지 제목 줄이 표시됩니다.

git cherry -v master

"word count" "-lines"( wc -l)로 파이프하면 커밋 수를 계산합니다.

git cherry master | wc -l

이 수를 GithHub PR에 표시된 커밋 수와 비교하여 git cherry실제로 작동하고 있음을 더 잘 알 수 있습니다. 또한 git 해시를 하나씩 비교하여 git cherryGitHub와 일치하는지 확인할 수 있습니다. 주 git cherry당신이 합병 어떤 병합 커밋 계산하지 않습니다 master에를 feature_branch하지만, GitHub의 것입니다. 따라서 카운트에 약간의 불일치가 있으면 GitHub PR 커밋 페이지에서 "병합"이라는 단어를 검색하면에 표시되지 않는 범인 일 수 있습니다 git cherry. 예 : "지사 '마스터'를 feature_branch로 병합" 이라는 커밋 이 GitHub PR에 표시되지만 실행할 때는 표시되지 않습니다 git cherry master feature_branch. 이것은 괜찮고 기대됩니다.

이제 새로운 diff 브랜치를 선택하여이 diff를 분할하려는 diff를 git cherry master feature_branch찾을 수 있습니다. 로컬로 사용 하거나 GitHub PR에서 커밋을 볼 수 있습니다 .

스쿼시가 어떻게 도움이 될 수 있습니까?

그러나 내 큰 차이를 분할하는 대안 은 내 커밋 30 개를 모두 하나로 스쿼시하고 새 기능 분기에 패치하고 패치 커밋을 부드럽게 재설정 한 다음 git gui파일별로 조각을 추가하거나 조각으로 조각을 추가 하는 데 사용 합니다. 한 줄씩. 하나의 하위 기능을 얻으면 내가 추가 한 것을 커밋 한 다음 새 분기를 확인하고, 더 많은 것을 추가하고, 커밋하고, 새로운 분기를 체크 아웃하는 등 내 큰 기능이 여러 하위 기능으로 나눌 때까지 . 문제는 내 내 30 개 커밋으로 인해 다른 사람에서 다른 200 개 커밋과 혼합되어 있다는 것입니다 git merge master내에 feature_branch리베이스 따라서 비현실적이다, 그래서 다시 주문 (230 개) 커밋을 통해 선별해야 내 30 개 커밋 스쿼시 것 같이.

스쿼시를 대체하기 위해 패치 파일을 사용하는 방법 :

해결 방법은 커밋 30 개 중 "스쿼시 등가"가 포함 된 패치 파일가져 와서 새 포크 master(새 하위 기능 지점)에 패치 한 후 다음과 같이 작업하는 것입니다.

git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master 
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch

이제 30 커밋 패치가 모두 로컬에 적용되었지만 준비되지 않고 커밋되지 않았습니다.

이제 git gui파일, 청크 및 / 또는 라인을 추가하고 큰 PR 또는 "diff"를 분리하는 데 사용하십시오.

이 없으면을 git gui사용하여 Ubuntu에 쉽게 설치할 수 있습니다 sudo apt install git-gui.

이제 git gui파일, 청크 및 / 또는 라인 추가 (git GUI 프로그램에서 마우스 오른쪽 버튼 클릭)를 시작하고 위에서 설명한 것처럼 커밋 기능 분기 30 개를 하위 분기로 나누고 반복적으로 추가, 커밋 및 포크 할 수 있습니다 새 기능 분기 및 모든 변경 사항이 하위 기능 지점에 추가되고 30 커밋 기능이 3 또는 4 하위 기능으로 성공적으로 분할 될 때까지이주기를 반복합니다. 각 하위 기능에 대해 별도의 PR을 열 수 있으며 팀에서 더 쉽게 검토 할 수 있습니다.

참고 문헌 :

  1. 자식 저장소에서 패치 또는 diff 파일을 만들어 다른 다른 자식 저장소에 적용하십시오.

오늘이 답변을 참조해야했지만 빨리 찾을 수 없었습니다. 운 좋게도 쉽게 찾을 수 있도록 공감대가 있었으므로 화면 오른쪽 상단의 어워드 컵 아이콘을 클릭하면 최근에 2 점을 잃어버린 곳이 표시되었습니다. 이제 내 자신의 답변을 여기에서 참조하십시오! 잘만되면 나는 더 이상 downvotes를 얻지 못하지만 downvoter에게 실수로 나를 도와 준 서비스에 감사드립니다!
가브리엘 스테이플
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.