2016-11-02 3 views
1

하나의 특정 병합 커밋에 병합 된 모든 커밋을 제외하고 두 태그 사이에 자식 로그를 출력하는 방법을 알아 냈습니다.힘내 로그 : 특정 병합에서 커밋을 제외하십시오

예를 들면. 내 커밋 로그가이 같은 보였다 경우

TAGA          TAGB 
    |  C---F---H---K   Q---T---V  | 
    v /   \  /  \ v 
    A---B---D---G---J---L---M---O---R---U---W---X 
      \ /  \  /
       E---I   N---P---S 

을 그리고 난에 트렁크에 소개 된 모든 커밋 제외하기를 원 L을 병합을 커밋. (이 예에서는 C, F, H, K을 제외하고 싶습니다.)

가 현재 내 자식 라인은 다음과 같다 :
git log --oneline --no-merges TAGB ^TAGA 

두 태그 (주 사이의 모든 커밋 목록을 것이다, 내가 제외하고있어, 이는 자신을 병합-저지른 이유 J, L, U & W 하지가 존재한다).

A,B,C,D,E,F,G,H,I,K,M,N,O,P,Q,R,S,T,V,X 

사람이, F, H & K C를 제외하는 방법을 알고 있나요? 예 :

A,B,D,E,G,I,M,N,O,P,Q,R,S,T,V,X 

도움이 되셨습니까?

답변

1

저렴하고 올인원 - 힘내 - 표현 방법이 없습니다. 그래프 워킹 코드는 --first-parent (Vimsha's answer에서와 같이)을 따르거나 병합의 모든 부모를 따릅니다. 따라서 배타적 인 ^K (또는 ^L^2 또는 커밋 K을 명명하는 다른 방법)에는 C--F--H--K 시퀀스가 ​​아닌 에서 모든 커밋에 도달 할 수있는 부수 효과가 있습니다 ().

우리가 원하는 목록을 얻을 수 있지만 더 많은 작업이 필요합니다. 첫째, 흥미로운 해시의 전체 목록을 생성합니다

tempfile1=$(mktemp) 
git rev-list --no-merges TAGB ^TAGA > $tempfile1 

이 (git loggit rev-list 거의 같은 명령하고, 동일한 소스에서 내장되어 있습니다를, 그들 사이의 주요 차이점은 rev-list 단지 전체 해시를 인쇄한다는 것입니다 ID). 다음으로, 제외 할 해시의 전체 목록을 생성합니다

tempfile2=$(mktemp) 
git rev-list --no-merges K ^B > $tempfile2 

(어떻게 B을 찾을 수 있습니까?당신이K을 발견하고는 말, 것을 알고 일단 글쎄, 난 당신이 찾을 수 있도록 B는, L^L^2 사이의 병합 기지, L^2, 어떻게 처음에 K을 찾았어요, 궁금해? -하지만 그 ID는 git merge-base이고 그 두 이름이 있습니다.)이 예에서는 --no-merges이 실제로 필요하지 않지만 좀 더 복잡한 예에서는 필요합니다. --first-parent도 마찬가지입니다. (메모를 추가하려면 편집 : 당연히 우리는 절대로 --no-merges을 필요로하지 않습니다. 제외 목록이며 병합은 이미 제외되었습니다.)

이제 "tempfile2에있는 해시를 제외한 모든 임시 파일을 임시 파일 1에서 찾았 으면합니다. 이 작업을 수행하는 Unix 도구 세트 명령은 comm입니다. (리눅스 버전에서는 입력을 정렬해야하며 실제로 을 확인하므로이를 물리 칠 때 --nocheck-order이 필요합니다. comm이 사용하는 기본 알고리즘은 파일의 라인이 인 것만으로과 같아야합니다. . 또는, 당신이 두 파일을 정렬 할 수있는 경우가 :. 예를 들어 sort -o $tempfile1 $tempfile1을하지만 그 비용이 불필요)

comm 유틸리티는 전적으로 정렬해야 파일 1과 파일 2, 을 읽고 세 개의 텍스트 열을 생산하고 있습니다. 출력으로 : file1의 행만; 줄 파일 2에만 있습니다. 두 파일의 행

"파일 1의 줄만"필요합니다. 즉, file2에 나타나는 줄을 버립니다. 열 1.

-2      의

-1             억제 인쇄 : 그건 다행스럽게도 아직 더 후 처리를해야 할 것 같다 "텍스트 열 1",하지만 것       컬럼 2의 인쇄를 억제.

-3 열             억제 인쇄 3.

그래서 우리는 열 2, 3 억제 :

comm -23 $tempfile1 $tempfile2 

을하고이 표준 출력에, 우리는 것 SHA-1의 전체 목록을 생성 같은 git log 표시합니다.

마지막 단계는 쉬운 충분하다, git log --oneline이 출력 후크하는 것입니다

git log --oneline --stdin --no-walk 

--no-walk 우리가하기 때문에 원하는 것입니다있는 모든 그래프를 저지 산책을하기에서 git log (또는 git rev-list을)하지 않도록 예방 우리는 방문 할 모든 커밋의 전체 목록을 제공하고 있습니다. --stdincomm에서 가져온 수정 버전의 피드입니다.

우리가 지금 필요한 것은 임시 파일 정리 좀 쉘 포장입니다 : 이것은 물론, 모든 안된 (

#! /bin/sh -e 

# note the -e option -- this avoids the need for a lot of || exit 
# clauses (to handle any early failures) 

tempfile1=$(mktemp) 
trap "rm -f $tempfile1" 0 1 2 3 15 
tempfile2=$(mktemp) 
trap "rm -f $tempfile1 $tempfile2" 0 1 2 3 15 

git rev-list --no-merges TAGB ^TAGA > $tempfile1 
git rev-list --no-merges K ^B > $tempfile2 
comm -23 $tempfile1 $tempfile2 | git log --oneline --stdin --no-walk 

을하고 찾으려하거나 얻을 것 곳은 장소를 생략 인수로 두 태그 및 병합 L 측면 번호, 1 또는 2와 함께 한면을 제외 시키십시오.

0

here

--first-부모가 첫 번째 부모가 병합 커밋보고에 커밋에 따라 문서 --first-parent

git log --oneline --no-merges --first-parent TAGB ^TAGA 

보십시오. 이 옵션은 특정 주제 분기의 진화를 볼 때 더 나은 개요를 제공 할 수 있습니다. 왜냐하면 분기 분기로 병합하는 것이 시간 에서 업데이트 된 업스트림으로 조정되는 경향이 있기 때문이며이 옵션을 사용하면 개별 커밋을 무시할 수 있습니다 그러한 병합을 통해 이 (가) 귀하의 기록에 반영되었습니다. --bisect와 결합 할 수 없습니다.

+0

안녕하세요 Vimsha, 예 그러나 --first-parent 옵션 중 하나만 제외하면 하나의 특정 병합 만 제외 할 수 있습니다. 모든 병합이 아닙니다. – Ben

관련 문제