개발관련/Git

Git으로 분기점 찾는 방법

Rateye 2021. 11. 24. 12:30
728x90
반응형
질문 : Git으로 분기점 찾기?

브랜치 마스터와 A가있는 저장소와 둘 사이에 많은 병합 활동이 있습니다. 마스터를 기반으로 브랜치 A가 생성되었을 때 내 저장소에서 커밋을 어떻게 찾을 수 있습니까?

내 저장소는 기본적으로 다음과 같습니다.

-- X -- A -- B -- C -- D -- F  (master) 
          \     /   \     /
           \   /     \   /
             G -- H -- I -- J  (branch A)

git merge-base (--all) 가 찾은 것이 아닌 개정 A를 찾고 있습니다.

답변

나는 똑같은 것을 찾고 있었고이 질문을 발견했습니다. 물어봐 주셔서 감사합니다!

그러나, 나는 그렇게하지 여기에있는 답변은 아주 당신이 (또는 내가 찾던 것을) 물어 대답을하는 것 발견 - 그들이 제공하는 것 G 대신의 커밋 커밋합니다. A

그래서 다음과 같은 트리 (시간순으로 할당 된 문자)를 만들었으므로 테스트 할 수 있습니다.

A - B - D - F - G   <- "master" branch (at G)
     \   \     /
      C - E --'     <- "topic" branch (still at E)

이것은 당신의 것과는 약간 다른 것 같습니다. 왜냐하면 제가 (당신의 것이 아니라이 그래프를 참조하는) B를 받았지만 A (그리고 D 나 E는 아님)를 얻었는지 확인하고 싶었 기 때문입니다. 다음은 SHA 접두사 및 커밋 메시지에 첨부 된 문자입니다 (누구에게나 흥미로운 경우 여기에서 내 저장소를 복제 할 수 있음).

G: a9546a2 merge from topic back to master
F: e7c863d commit on master after master was merged to topic
E: 648ca35 merging master onto topic
D: 37ad159 post-branch commit on master
C: 132ee2a first commit on topic branch
B: 6aafd7f second commit on master before branching
A: 4112403 initial commit on master

따라서 목표는 B 찾기 입니다. 약간의 땜질 후에 내가 찾은 세 가지 방법이 있습니다.


1. 시각적으로 Gitk를 사용하여:

다음과 같은 트리가 시각적으로 표시되어야합니다 (마스터에서 볼 때).

마스터에서 gitk 화면 캡처

또는 여기 (주제에서 볼 때) :

주제에서 gitk 화면 캡처

두 경우 모두 그래프에서 B 커밋을 선택했습니다. 클릭하면 전체 SHA가 그래프 바로 아래의 텍스트 입력 필드에 표시됩니다.


2. 시각적으로, 그러나 터미널에서:

git log --graph --oneline --all

(편집 / --decorate 수 있습니다. 이것은 분기 이름, 태그 등의 표시를 추가합니다. 아래 출력은 그 용도를 반영하지 않으므로 위의 명령 줄에 추가하지 않습니다.)

다음을 보여줍니다 ( git config --global color.ui auto 라고 가정).

git log --graph --oneline --all의 출력

또는 일반 텍스트 :

*   a9546a2 merge from topic back to master
|\  
| *   648ca35 merging master onto topic
| |\  
| * | 132ee2a first commit on topic branch
* | | e7c863d commit on master after master was merged to topic
| |/  
|/|   
* | 37ad159 post-branch commit on master
|/  
* 6aafd7f second commit on master before branching
* 4112403 initial commit on master

두 경우 모두 6aafd7f 커밋이 가장 낮은 공통점 (예 : 내 그래프의 B A 됩니다.


3. 껍데기 마법으로:

위와 같은 것을 원하는지 아니면 하나의 개정판 만 가져 오는 단일 명령을 원하는지 질문에 지정하지 않습니다. 음, 후자는 다음과 같습니다.

diff -u <(git rev-list --first-parent topic) \
             <(git rev-list --first-parent master) | \
     sed -ne 's/^ //p' | head -1
6aafd7ff98017c816033df18395c5c1e7829960d

~ / .gitconfig에 다음과 같이 넣을 수도 있습니다 (참고 : 후행 대시가 중요합니다.주의를 기울여 주신 Brian 에게 감사드립니다).

[alias]
	oldest-ancestor = !zsh -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' -

다음 (따옴표로 묶인) 명령 줄을 통해 수행 할 수 있습니다.

git config --global alias.oldest-ancestor '!zsh -c '\''diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne "s/^ //p" | head -1'\'' -'

참고 : zsh 그냥 간단하게 수 있었다 bash 하지만 sh 작동하지 않습니다 - <() 구문은 바닐라에 존재하지 않습니다 sh . (이 페이지의 다른 답변에 대한 의견으로 알려 주신 @conny에게 다시 한 번 감사드립니다!)

참고: 위의 대체 버전:

동일한 브랜치를 비교할 때 위의 내용이 떨어질 수 있다는 점지적한 liori 에게 감사하며, 믹스에서 sed 형식을 제거하고이를 "안전하게"만드는 대체 diff 형식을 제시합니다 (즉, 결과를 반환합니다 (즉, 가장 최근 커밋) 마스터와 마스터를 비교할 때도) :

.git-config 행으로 :

[alias]
	oldest-ancestor = !zsh -c 'diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1' -

셸에서 :

git config --global alias.oldest-ancestor '!zsh -c '\''diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1'\'' -'

따라서 내 테스트 트리 (한동안 사용할 수 없었습니다. 죄송합니다. 돌아 왔습니다)에서 이제 마스터와 토픽 모두에서 작동합니다 (각각 커밋 G와 B 제공). 다른 양식에 대해 다시 한 번 감사드립니다.


그래서, 그것이 제가 [그리고 liori] 생각 해낸 것입니다. 그것은 나를 위해 일하는 것 같습니다. 또한 유용 할 수있는 몇 가지 추가 별칭을 허용합니다.

git config --global alias.branchdiff '!sh -c "git diff `git oldest-ancestor`.."'
git config --global alias.branchlog '!sh -c "git log `git oldest-ancestor`.."'

행복한 git-ing!

출처 : https://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git
728x90
반응형