etc./StackOverFlow

예쁜 Git 분기 그래프

청렴결백한 만능 재주꾼 2022. 2. 7. 06:19
반응형

질문자 :krosenvold


나는 몇몇 책과 기사에서 Git 브랜치와 커밋에 대한 정말 보기 좋은 그래프를 본 적이 있습니다. Git 기록의 고품질 인쇄 가능한 이미지를 만들려면 어떻게 해야 합니까?



업데이트 2: Git의 Visualizing branch topology 질문에 이 답변의 개선된 버전을 게시했습니다. 왜냐하면 그것이 훨씬 더 적절하기 때문입니다. 해당 버전에는 작성자와 커미터 정보를 모두 표시 lg3 이 답변을 역사적인(& 담당자, 인정할 것입니다) 이유로 남겨두지만 정말로 삭제하고 싶은 유혹이 있습니다.

내 두 개의 센트 ~/.gitconfig 파일에 두 개의 별칭이 있습니다.

 [alias] lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all lg = !"git lg1"

git lg / git lg1 은 다음과 같습니다.자식 LG1

git lg2 는 다음과 같습니다.자식 LG2


(참고: 이제 fracz's , Jubobs' 또는 Harry Lee's 와 같이 이 질문에 대한 훨씬 더 적절한 답변이 있습니다.)


Slipp D. Thompson

여기에 있는 많은 답변이 훌륭하지만 별칭이나 추가 항목을 설정하지 않고 간단한 한 줄 대 점 답변을 원하는 사람들을 위해 다음과 같습니다.

 git log --all --decorate --oneline --graph

모든 사람이 항상 git log 수행하는 것은 아니지만 필요할 때 다음을 기억하십시오.

" A Dog " = git log -- a ll -- d ecorate -- o neline -- g raph

여기에 이미지 설명 입력


Patoshi パトシ

텍스트 출력의 경우 다음을 시도할 수 있습니다.

 git log --graph --abbrev-commit --decorate --date=relative --all

또는:

 git log --graph --oneline --decorate --all

또는 : 여기 graphviz를의 도면에 대한 별칭 DAG의 그래프.

저는 개인적으로 gitx , gitk --allgitnub 합니다.


keo

Gitgraph.js를 사용하면 저장소 없이도 예쁜 Git 브랜치를 그릴 수 있습니다. 브랜치를 구성하고 브라우저에서 커밋하고 렌더링하는 JavaScript 코드를 작성하기만 하면 됩니다.

 var gitGraph = new GitGraph({ template: "blackarrow", mode: "compact", orientation: "horizontal", reverseArrow: true }); var master = gitGraph.branch("master").commit().commit(); var develop = gitGraph.branch("develop").commit(); master.commit(); develop.commit().commit(); develop.merge(master); 

Gitgraph.js로 생성된 샘플 그래프

또는 metro 템플릿 사용:

GitGraph.js 지하철 테마

또는 커밋 메시지, 작성자 및 태그:

커밋 메시지가 있는 GitGraph

JSFiddle로 테스트하십시오.

@bsara의 Git Grapher 로 생성합니다.


fracz

TikZ 및 PGF 위에 구축된 gitdags 는 벡터 그래픽 커밋 그래프 등을 손쉽게 생성할 수 있는 작은 LaTeX 패키지입니다.

기존 저장소의 자동 생성 그래프를 목적으로하지 않습니다 커밋 gitdags ; 그것이 생성하는 그래프는 교육 목적으로 만 의미됩니다.

ASCII 커밋 그래프의 대안으로 Git 질문에 대한 답변을 위한 그래프를 생성하는 데 자주 사용합니다.

다음은 단순 리베이스의 효과를 보여주는 그래프의 예입니다.

여기에 이미지 설명 입력

 \documentclass{article} \usepackage{subcaption} \usepackage{gitdags} \begin{document} \begin{figure} \begin{subfigure}[b]{\textwidth} \centering \begin{tikzpicture} % Commit DAG \gitDAG[grow right sep = 2em]{ A -- B -- { C, D -- E, } }; % Tag reference \gittag [v0p1] % node name {v0.1} % node text {above=of A} % node placement {A} % target % Remote branch \gitremotebranch [origmaster] % node name {origin/master} % node text {above=of C} % node placement {C} % target % Branch \gitbranch {master} % node name and text {above=of E} % node placement {E} % target % HEAD reference \gitHEAD {above=of master} % node placement {master} % target \end{tikzpicture} \subcaption{Before\ldots} \end{subfigure} \begin{subfigure}[b]{\textwidth} \centering \begin{tikzpicture} \gitDAG[grow right sep = 2em]{ A -- B -- { C -- D' -- E', {[nodes=unreachable] D -- E }, } }; % Tag reference \gittag [v0p1] % node name {v0.1} % node text {above=of A} % node placement {A} % target % Remote branch \gitremotebranch [origmaster] % node name {origin/master} % node text {above=of C} % node placement {C} % target % Branch \gitbranch {master} % node name and text {above=of E'} % node placement {E'} % target % HEAD reference \gitHEAD {above=of master} % node placement {master} % target \end{tikzpicture} \subcaption{\ldots{} and after \texttt{git rebase origin/master}} \end{subfigure} \caption{Demonstrating a typical \texttt{rebase}} \end{figure} \end{document}

jub0bs

Gitg 는 GNOME용 Gitk 및 GitX(KDE 등에서도 작동함)의 복제본으로 예쁜 색상의 그래프를 보여줍니다.

활발히 개발되고 있습니다(2012년 기준). 커밋(그래프 노드)을 시간순 또는 위상 순으로 정렬하고 선택한 분기로 연결되지 않는 커밋을 숨길 수 있습니다.

대규모 리포지토리 및 복잡한 종속성 그래프에서 잘 작동합니다.

linux-git 및 linux-2.6 저장소를 보여주는 샘플 스크린샷:

리눅스 자식

리눅스-2.6


Mechanical snail

방금 HTML/Canvas 를 사용하여 예쁜 Git 커밋 그래프를 생성할 수 있는 하나의 도구를 작성했습니다.

그리고 사용하기 쉬운 jQuery 플러그인을 제공합니다.

[깃허브] https://github.com/tclh123/commits-graph

시사:

시사


Harry Lee

Sourcetree 는 정말 좋은 것입니다. 보기 좋은 중간 크기의 기록 및 분기 그래프를 인쇄합니다. (다음은 일부 분기를 보기 위해 실험적인 Git 프로젝트에서 수행됩니다.) Windows 7 이상 및 Mac OS X 10.6 이상을 지원합니다.

Sourcetree의 출력 예


nonopolarity

git-forest 는 내가 1년 이상 사용해 온 훌륭한 Perl 스크립트이며 git log 명령을 더 이상 직접 사용하지 않습니다.

다음은 이 스크립트에서 내가 좋아하는 몇 가지입니다.

  • 유니코드 문자를 사용하여 그래프에 선을 그려 그래프 선을 보다 연속적으로 표시합니다.
  • --reverse 를 그래프 출력과 결합할 git log 명령으로는 불가능합니다.
  • git log 사용하여 커밋 목록을 가져오므로 git log 전달하는 모든 옵션도 이 스크립트에도 전달할 수 있습니다.

다음과 같이 git-forest 를 사용하는 별칭이 있습니다.

 [alias] tree = "forest --pretty=format:\"%C(red)%h %C(magenta)(%ar) %C(blue)%an %C(reset)%s\" --style=15 --reverse"

터미널에서 출력은 다음과 같습니다.

여기에 이미지 설명 입력


Tuxdude

Git 로그를 예쁜 SVG 그래프로 변환하기 위한 웹 도구를 작성했습니다.

Bit-Booster - 오프라인 커밋 그래프 그리기 도구

git log --pretty='%h|%p|%d' 의 출력을 도구에 직접 업로드한 다음 "graph.svg 다운로드" 링크를 클릭합니다.

이 도구는 순수 클라이언트 측이므로 Git 데이터는 내 서버와 공유되지 않습니다. HTML + JavaScript를 로컬에 저장하고 "file:///" URL을 사용하여 실행할 수도 있습니다. Ubuntu 12.04 (Precise Pangolin)의 Chrome 48 및 Firefox 43에서 확인되었습니다.

모든 페이지(blogspot 블로깅 엔진 포함!)에 직접 게시할 수 있는 HTML을 생성합니다. 여기에서 블로그 게시물 중 일부를 살펴보십시오.

http://bit-booster.blogspot.ca/

다음은 도구에서 생성된 샘플 HTML 파일의 스크린샷입니다.

http://bit-booster.com/graph.html (도구)


G. Sylvie Davies

관련 질문 에 대한 답변에서 찾은 Graphviz 스크립트를 기반으로 Git 저장소의 요약 보기를 생성하는 Ruby 스크립트 를 해킹했습니다. 모든 선형 기록을 생략하고 "흥미로운" 커밋, 즉 여러 부모, 여러 자식이 있거나 분기 또는 태그로 가리키는 커밋만 보여줍니다. 다음은 jQuery에 대해 생성하는 그래프의 스니펫입니다.

jQuery 샘플

git-big-pictureBranchMaster 는 태그, 분기, 병합 등이 어떻게 관련되어 있는지만 표시하여 그래프의 상위 수준 구조만 표시하려는 유사한 도구입니다.

이 질문 에는 더 많은 옵션이 있습니다.


Matt McHenry

세 가지 사용자 지정 명령을 추가했습니다: git tree , git streegit vtree . 그 순서대로 짚고 넘어가겠습니다.

 [alias] tree = log --all --graph --decorate=short --color --format=format:'%C(bold blue)%h%C(reset) %C(auto)%d%C(reset)\n %C(black)[%cr]%C(reset) %x09%C(black)%an: %s %C(reset)' 

여기에 이미지 설명 입력


git streegit vtree 를 사용하여 Bash를 사용하여 서식 지정을 도왔습니다.

 [alias] logx = log --all --graph --decorate=short --color --format=format:'%C(bold blue)%h%C(reset)+%C(dim black)(%cr)%C(reset)+%C(auto)%d%C(reset)++\n+++ %C(bold black)%an%C(reset)%C(black): %s%C(reset)' stree = !bash -c '" \ while IFS=+ read -r hash time branch message; do \ timelength=$(echo \"$time\" | sed -r \"s:[^ ][[]([0-9]{1,2}(;[0-9]{1,2})?)?m::g\"); \ timelength=$(echo \"16+${#time}-${#timelength}\" | bc); \ printf \"%${timelength}s %s %s %s\n\" \"$time\" \"$hash\" \"$branch\" \"\"; \ done < <(git logx && echo);"'

git_stree


 [alias] logx = log --all --graph --decorate=short --color --format=format:'%C(bold blue)%h%C(reset)+%C(dim black)(%cr)%C(reset)+%C(auto)%d%C(reset)++\n+++ %C(bold black)%an%C(reset)%C(black): %s%C(reset)' vtree = !bash -c '" \ while IFS=+ read -r hash time branch message; do \ timelength=$(echo \"$time\" | sed -r \"s:[^ ][[]([0-9]{1,2}(;[0-9]{1,2})?)?m::g\"); \ timelength=$(echo \"16+${#time}-${#timelength}\" | bc); \ printf \"%${timelength}s %s %s %s\n\" \"$time\" \"$hash\" \"$branch\" \"$message\"; \ done < <(git logx && echo);"'

git_vtree


이것은 Git 버전 1.9a에서 작동합니다. 색상 값 'auto'는 이번 릴리스에서 데뷔할 예정입니다. 브랜치 이름이 다른 색상을 갖게 되므로 좋은 추가 기능입니다. 이렇게 하면 예를 들어 로컬 분기와 원격 분기를 쉽게 구별할 수 있습니다.


gospes

그것은 그들이 어떻게 생겼는지에 달려 있습니다. 다음과 같은 사진을 만드는 gitx 를 사용합니다.

간단한 줄거리

24방향 문어 병합에서 git log --graphgitk 를 비교할 수 있습니다 (원래 http://clojure-log.n01se.net/date/2008-12-24.html에서 ).

24-way Git 문어 병합. 원래 URL은 http://lwn.net/images/ns/kernel/gitk-octopus.png였습니다.


Dustin

더 자세한 텍스트 출력을 보려면 다음을 시도하십시오.

 git log --graph --date-order -C -M --pretty=format:"<%h> %ad [%an] %Cgreen%d%Creset %s" --all --date=short

$HOME/.gitconfig 파일에 별칭을 추가할 수 있습니다.

 [alias] graph = log --graph --date-order -C -M --pretty=format:\"<%h> %ad [%an] %Cgreen%d%Creset %s\" --all --date=short

user780819

셸에 대한 멋지고 깨끗한 테이블과 같은 Git 그래프 출력

그래프 트리 외에 일반적으로 해시 사용

그래프 트리 외에 일반적으로 해시 사용

또는 추가 열에서

또는 추가 열에서

편집 : 모든 설명을 읽지 않고 바로 시작하고 싶습니까? 편집 6으로 이동합니다.

정보 : 쉘에 대한 분기와 유사한 색상 버전은 두 번째 답변( https://stackoverflow.com/a/63253135/ )도 참조하십시오.

이 질문에 대한 모든 답변에서 지금까지 쉘에 대한 깨끗한 테이블과 같은 출력을 보여주지 않았습니다. 가장 가까운 것은 내가 시작한 gospes의이 답변이었습니다.

내 접근 방식의 핵심은 사용자에게 표시되는 트리 문자만 계산하는 것입니다. 그런 다음 공백으로 개인 길이만큼 채우십시오.

Git 외에 다음 도구가 필요합니다.

  • 그렙
  • 반죽
  • 인쇄
  • 세드
  • 시퀀스
  • 트르
  • 화장실

대부분 모든 Linux 배포판에 탑재되어 있습니다.

코드 조각은

 while IFS=+ read -r graph hash time branch message;do # Count needed amount of white spaces and create them whitespaces=$((9-$(sed -nl1000 'l' <<< "$graph" | grep -Eo '\\\\|\||\/|\ |\*|_' | wc -l))) whitespaces=$(seq -s' ' $whitespaces|tr -d '[:digit:]') # Show hashes besides the tree ... #graph_all="$graph_all$graph$(printf '%7s' "$hash")$whitespaces \n" # ... or in an own column graph_all="$graph_all$graph$whitespaces\n" hash_all="$hash_all$(printf '%7s' "$hash") \n" # Format all other columns time_all="$time_all$(printf '%12s' "$time") \n" branch_all="$branch_all$(printf '%15s' "$branch")\n" message_all="$message_all$message\n" done < <(git log --all --graph --decorate=short --color --pretty=format:'+%C(bold 214)%<(7,trunc)%h%C(reset)+%C(dim white)%>(12,trunc)%cr%C(reset)+%C(214)%>(15,trunc)%d%C(reset)+%C(white)%s%C(reset)' && echo); # Paste the columns together and show the table-like output paste -d' ' <(echo -e "$time_all") <(echo -e "$branch_all") <(echo -e "$graph_all") <(echo -e "$hash_all") <(echo -e "$message_all")

우리가 사용하는 필요한 공백을 계산하기 위해

 sed -nl1000 'l' <<< "$graph"

트리 문자만 선택하는 것보다 모든 문자(행당 1000개까지)를 얻으려면 다음을 수행하십시오. * | / \ _ 및 공백

 grep -Eo '\\\\|\||\/|\ |\*|_'

마지막으로 숫자를 세고 선택한 길이 값(예제에서는 9)에서 결과를 뺍니다.

우리가 사용하는 공백의 계산된 양을 생성하기 위해

 seq -s' ' $whitespaces

다음으로 위치 번호를 자릅니다.

 tr -d '[:digit:]'

그런 다음 그래프 선의 끝에 추가합니다. 그게 다야!

Git에는 이미 '%><(amount_of_characters,truncate_option)' 구문을 사용하여 출력 지정자의 길이 를 형식화하는 좋은 옵션이 있습니다. 이 옵션은 왼쪽 '>' 또는 오른쪽 '<' 쪽에서 공백을 추가하고 다음에서 문자를 자를 수 있습니다. 시작 'ltrunc', 중간 'mtrunc' 또는 끝 'trunc'.

위의 printf cmd는 해당 Git 열에 대해 동일한 길이 값을 사용하는 것이 중요합니다.

필요에 따라 깔끔한 테이블 모양의 출력물을 재미있게 꾸며보세요.

추가의:

올바른 길이 값을 얻으려면 다음 스니펫을 사용할 수 있습니다.

 while read -r graph;do chars=$(sed -nl1000 'l' <<< "$graph" | grep -Eo '\\\\|\||\/|\ |\*|_' | wc -l) [[ $chars -gt ${max_chars:-0} ]] && max_chars=$chars done < <(git log --all --graph --pretty=format:' ')

위의 올바른 길이 값으로 $max_chars를 사용하십시오.

편집 1 : 밑줄 문자가 git 트리에서도 사용되는 것을 확인하고 그에 따라 위의 코드 조각을 편집합니다. 다른 문자가 누락된 경우 댓글을 남겨주세요.

편집 2 : 분기 및 태그 항목 주위의 대괄호를 제거하려면 편집 3에서와 같이 git 명령에서 "%d" 대신 "%D"를 사용하십시오.

편집 3 : 아마도 "자동" 색상 옵션이 분기 및 태그 항목에 가장 선호하는 옵션입니까?

Git 브래킷이 없는 자동 색상 헤드 및 태그 테이블과 같은 셸 출력

git 명령의 이 부분을 변경합니다(색상 214 ).

 %C(214)%>(15,trunc)%D%C(reset)

자동으로

 %C(auto)%>(15,trunc)%D%C(reset)

EDIT 4 : 아니면 그 부분에 대한 자신만의 색상 혼합이 마음에 드시나요? 깜박이는 머리와 함께 멋진 출력이 나오나요?

Git 트리 멋진 스타일의 테이블과 같은 출력

머리, 가지 이름 및 태그의 스타일을 지정하려면 먼저 EDIT 3에서와 같이 git 명령에 "자동" 색상 옵션이 필요합니다.

그런 다음 이 세 줄을 추가하여 알고 있는 색상 값을 우리 자신의 값으로 바꿀 수 있습니다.

 # branch name styling branch=${branch//1;32m/38;5;214m} # head styling branch=${branch//1;36m/3;5;1;38;5;196m} # tag styling branch=${branch//1;33m/1;38;5;222m}

라인 직전

 branch_all="$branch_all$(printf '%15s' "$branch")\n"

우리의 코드 스 니펫에서. 교체 값은 위의 색상을 생성합니다.

예를 들어 head의 대체 값은 다음과 같습니다.

 3;5;1;38;5;196

어디서 3; 기울임꼴, 5를 나타냅니다. 깜박임 및 1;38;5;196 색상. 자세한 내용은 여기에서 시작하십시오. 참고: 이 동작은 선호하는 터미널에 따라 다르므로 사용하지 못할 수 있습니다.

그러나 원하는 색상 값을 선택할 수 있습니다.

git 색상 값 및 이에 상응하는 ANSI 개요

여기에 이미지 설명 입력

여기에서 git color/style 옵션이 있는 목록을 찾을 수 있습니다.

정확한 색상을 위해 콘솔에서 출력이 필요한 경우(위 그림은 스택 오버플로에 의해 축소됨) 다음을 사용하여 출력을 생성할 수 있습니다.

 for ((i=0;i<=255;i++));do while IFS='+' read -r tree hash;do echo -e "$(printf '%-10s' "(bold $i)") $hash $(sed -nl500 'l' <<< "$hash"|grep -Eom 1 '[0-9;]*[0-9]m'|tr -d 'm')" done < <(git log --all --graph --decorate=short --color --pretty=format:'+%C(bold '$i')%h%C(reset)'|head -n 1) done

Git 로그 출력의 첫 번째 커밋을 사용하는 Git 프로젝트 경로에서.

편집 5 : 회원 "Andras Deak"가 언급했듯이 이 코드를 사용하는 몇 가지 방법이 있습니다.

1) 별칭으로 :

alias는 매개변수를 허용하지 않지만 함수는 허용 하므로 .bashrc에서 정의하십시오.

 function git_tably () { unset branch_all graph_all hash_all message_all time_all max_chars ### add here the same code as under "2) as a shell-script" ### }

git 프로젝트 경로 바로 아래 또는 git 프로젝트 경로를 첫 번째 매개변수로 사용하여 원하는 곳 어디에서든 git_tably(테이블과 같은 형식에서 파생) 함수를 호출합니다.

2) 쉘 스크립트로 :

Git 프로젝트 디렉토리를 첫 번째 매개변수로 전달하는 옵션과 함께 사용하거나 비어 있는 경우 일반 동작처럼 작업 디렉토리를 사용합니다. 우리는 완전히

 # Edit your color/style preferences here or use empty values for git auto style tag_style="1;38;5;222" head_style="1;3;5;1;38;5;196" branch_style="38;5;214" # Determine the max character length of your git tree while IFS=+ read -r graph;do chars_count=$(sed -nl1000 'l' <<< "$graph" | grep -Eo '\\\\|\||\/|\ |\*|_' | wc -l) [[ $chars_count -gt ${max_chars:-0} ]] && max_chars=$chars_count done < <(cd "${1:-"$PWD"}" && git log --all --graph --pretty=format:' ') # Create the columns for your preferred table-like git graph output while IFS=+ read -r graph hash time branch message;do # Count needed amount of white spaces and create them whitespaces=$(($max_chars-$(sed -nl1000 'l' <<< "$graph" | grep -Eo '\\\\|\||\/|\ |\*|_' | wc -l))) whitespaces=$(seq -s' ' $whitespaces|tr -d '[:digit:]') # Show hashes besides the tree ... #graph_all="$graph_all$graph$(printf '%7s' "$hash")$whitespaces \n" # ... or in an own column graph_all="$graph_all$graph$whitespaces\n" hash_all="$hash_all$(printf '%7s' "$hash") \n" # Format all other columns time_all="$time_all$(printf '%12s' "$time") \n" branch=${branch//1;32m/${branch_style:-1;32}m} branch=${branch//1;36m/${head_style:-1;36}m} branch=${branch//1;33m/${tag_style:-1;33}m} branch_all="$branch_all$(printf '%15s' "$branch")\n" message_all="$message_all$message\n" done < <(cd "${1:-"$PWD"}" && git log --all --graph --decorate=short --color --pretty=format:'+%C(bold 214)%<(7,trunc)%h%C(reset)+%C(dim white)%>(12,trunc)%cr%C(reset)+%C(auto)%>(15,trunc)%D%C(reset)+%C(white)%s%C(reset)' && echo); # Paste the columns together and show the table-like output paste -d' ' <(echo -e "$time_all") <(echo -e "$branch_all") <(echo -e "$graph_all") <(echo -e "$hash_all") <(echo -e "$message_all")

3) 자식 별칭으로 :

아마도 가장 편안한 방법은 .gitconfig에 git 별칭을 추가하는 것입니다.

 [color "decorate"] HEAD = bold blink italic 196 branch = 214 tag = bold 222 [alias] count-log = log --all --graph --pretty=format:' ' tably-log = log --all --graph --decorate=short --color --pretty=format:'+%C(bold 214)%<(7,trunc)%h%C(reset)+%C(dim white)%>(12,trunc)%cr%C(reset)+%C(auto)%>(15,trunc)%D%C(reset)+%C(white)%s%C(reset)' tably = !bash -c '" \ while IFS=+ read -r graph;do \ chars_count=$(sed -nl1000 \"l\" <<< \"$graph\" | grep -Eo \"\\\\\\\\\\\\\\\\|\\||\\/|\\ |\\*|_\" | wc -l); \ [[ $chars_count -gt ${max_chars:-0} ]] && max_chars=$chars_count; \ done < <(git count-log && echo); \ while IFS=+ read -r graph hash time branch message;do \ chars=$(sed -nl1000 \"l\" <<< \"$graph\" | grep -Eo \"\\\\\\\\\\\\\\\\|\\||\\/|\\ |\\*|_\" | wc -l); \ whitespaces=$(($max_chars-$chars)); \ whitespaces=$(seq -s\" \" $whitespaces|tr -d \"[:digit:]\"); \ graph_all=\"$graph_all$graph$whitespaces\n\"; \ hash_all=\"$hash_all$(printf \"%7s\" \"$hash\") \n\"; \ time_all=\"$time_all$(printf \"%12s\" \"$time\") \n\"; \ branch_all=\"$branch_all$(printf \"%15s\" \"$branch\")\n\"; \ message_all=\"$message_all$message\n\"; \ done < <(git tably-log && echo); \ paste -d\" \" <(echo -e \"$time_all\") <(echo -e \"$branch_all\") <(echo -e \"$graph_all\") \ <(echo -e \"$hash_all\") <(echo -e \"$message_all\"); \ '"

모든 프로젝트 경로에서 git tably 호출하는 것보다.

Git은 헤드, 태그 등을 직접 변경할 수 있을 정도로 강력합니다. 위와 같이 여기에서 가져왔습니다.

또 다른 멋진 옵션 은 가장 선호하는 나무 색상을 선택하는 것입니다.

 [log] graphColors = bold 160, blink 231 bold 239, bold 166, bold black 214, bold green, bold 24, cyan

그것은 당신에게 미친 것처럼 보이지만 항상 테이블과 같은 git 로그 출력을 제공합니다.

멋진_git_tree_tablelike_image

너무 많이 깜박입니다! 가능한 것을 보여주기 위해서입니다. 지정된 색상이 너무 적으면 색상이 반복됩니다.

클릭 한 번이면 완전한 .gitconfig 참조를 볼 수 있습니다.

편집 6 : 귀하의 긍정적 인 투표로 인해 스 니펫을 개선했습니다. 이제 거의 모든 git log 명령으로 이를 제공할 수 있으며 더 이상 코드를 조정할 필요가 없습니다. 시도 해봐!

어떻게 작동합니까?

  • 항상 .gitconfig에서 Git 로그 명령을 정의합니다(아래 형식).
  • git 그래프가 표시되는 양수 트리 열 번호를 정의합니다(선택 사항).

그럼 그냥 전화

git tably YourLogAlias

git 프로젝트 경로 아래 또는

git tably YourLogAlias TreeColNumber

여기서 TreeColNumber는 위에서 항상 정의된 값을 덮어씁니다.

git tably YourLogAlias | less -r

거대한 기록에 유용한 less로 출력을 파이프합니다.

Git 로그 별칭은 다음 형식 규칙을 따라야 합니다.

  • 각 열은 선택해야 하는 열 구분 기호로 표시되어야 하며 고유하지 않은 경우 문제를 일으킬 수 있습니다.

    ^ in ...format:'^%h^%cr^%s' 는 트리, 해시, 시간 및 커밋 열을 생성합니다.

  • 로그 명령의 모든 커밋 자리 표시자 전에 trunc 옵션 중 하나와 함께 %><(<N>[,ltrunc|mtrunc|trunc])

    (구문 설명은 https://git-scm.com/docs/pretty-formats 참조 ),

    그러나 개행의 마지막 커밋 자리 표시자는 줄 바꿈 없이 사용할 수 있습니다.

    ...format:'^%<(7,trunc)%h^%<(12,trunc)%cr^%s'

  • (committer: , <>) 와 같은 장식을 위해 추가 문자가 필요한 경우

    ...%C(dim white)(committer: %cn% <%ce>)%C(reset)...

    테이블과 같은 출력을 얻으려면 커밋 자리 표시자 전후에 직접 작성해야 합니다.

    ...%C(dim white)%<(25,trunc)(committer: %cn%<(25,trunc) <%ce>)%C(reset)...

  • %C(white)...%C(rest) 와 같은 열 색상을 사용하려면 컬러 출력에 --color 옵션이 필요합니다.

    ...--color...format:'^%C(white)%<(7,trunc)%h%C(rest)...

  • --stat 옵션 또는 이와 유사한 것을 사용하는 경우 끝에 %n

    ...--stat...format:'...%n'...

  • 줄 바꿈을 사용하지 않거나 빈 형식만 사용하는 한 모든 열에 git 그래프를 배치할 수 있습니다 format:'...%n'

    비어 있지 않은 줄 바꿈의 경우 ...%n%CommitPlaceholder... 각 줄의 모든 n번째 열이 존재하고 동일한 너비를 사용하는 경우에만 모든 열 n+1에 git 그래프를 배치할 수 있습니다.

  • 특정 로그 별칭에 대해 정의된 트리 열 번호의 이름은 YourLogAlias-col

일반 git 로그 출력과 비교할 때 이것은 느리지 만 훌륭합니다.

이제 .gitconfig에 추가할 개선된 스니펫

 [color "decorate"] HEAD = bold blink italic 196 branch = 214 tag = bold 222 [alias] # Delimiter used in every mylog alias as column seperator delim = ^ # Short overview about the last hashes without graph mylog = log --all --decorate=short --color --pretty=format:'^%C(dim white)%>(12,trunc)%cr%C(reset)^%C(bold 214)%<(7,trunc)%h%C(reset)' -5 # Log with hashes besides graph tree mylog2 = log --all --graph --decorate=short --color --pretty=format:'%C(bold 214)%<(7,trunc)%h%C(reset)^%C(dim white)%>(12,trunc)%cr%C(reset)^%C(auto)%>(15,trunc)%D%C(reset)^%C(white)%<(80,trunc)%s%C(reset)' mylog2-col= 3 # Log with hashes in an own column and more time data mylog3 = log --all --graph --decorate=short --color --pretty=format:'^%C(dim white)%>(12,trunc)%cr%C(reset)^%C(cyan)%<(10,trunc)%cs%C(reset)^%C(bold 214)%<(7,trunc)%h%C(reset)^%C(auto)%<(15,trunc)%D%C(reset)^%C(white)%s%C(reset)' mylog3-col= 4 tably = !bash -c '" \ \ \ declare -A col_length; \ apost=$(echo -e \"\\u0027\"); \ delim=$(git config alias.delim); \ git_log_cmd=$(git config alias.$1); \ git_tre_col=${2:-$(git config alias.$1-col)}; \ [[ -z "$git_tre_col" ]] && git_tre_col=1; \ [[ -z "$git_log_cmd" ]] && { git $1;exit; }; \ \ \ i=0; \ n=0; \ while IFS= read -r line;do \ ((n++)); \ while read -d\"$delim\" -r col_info;do \ ((i++)); \ [[ -z \"$col_info\" ]] && col_length[\"$n:$i\"]=${col_length[\"${last[$i]:-1}:$i\"]} && ((i--)) && continue; \ [[ $i -gt ${i_max:-0} ]] && i_max=$i; \ col_length[\"$n:$i\"]=$(grep -Eo \"\\([0-9]*,[lm]*trunc\\)\" <<< \"$col_info\" | grep -Eo \"[0-9]*\" | head -n 1); \ [[ -n \"${col_length[\"$n:$i\"]}\" ]] && last[$i]=$n; \ chars_extra=$(grep -Eo \"trunc\\).*\" <<< \"$col_info\"); \ chars_extra=${chars_extra#trunc)}; \ chars_begin=${chars_extra%%\\%*}; \ chars_extra=${chars_extra%$apost*}; \ chars_extra=${chars_extra#*\\%}; \ case \" ad aD ae aE ai aI al aL an aN ar as at b B cd cD ce cE ci cI cl cL cn cN cr \ cs ct d D ef G? gd gD ge gE GF GG GK gn gN GP gs GS GT h HN p P s S t T \" in \ *\" ${chars_extra:0:2} \"*) \ chars_extra=${chars_extra:2}; \ chars_after=${chars_extra%%\\%*}; \ ;; \ *\" ${chars_extra:0:1} \"*) \ chars_extra=${chars_extra:1}; \ chars_after=${chars_extra%%\\%*}; \ ;; \ *) \ echo \"No Placeholder found. Probably no tablelike output.\"; \ continue; \ ;; \ esac; \ if [[ -n \"$chars_begin$chars_after\" ]];then \ len_extra=$(echo \"$chars_begin$chars_after\" | wc -m); \ col_length["$n:$i"]=$((${col_length["$n:$i"]}+$len_extra-1)); \ fi; \ done <<< \"${line#*=format:}$delim\"; \ i=1; \ done <<< \"$(echo -e \"${git_log_cmd//\\%n/\\\\n}\")\"; \ \ \ git_log_fst_part=\"${git_log_cmd%%\"$apost\"*}\"; \ git_log_lst_part=\"${git_log_cmd##*\"$apost\"}\"; \ git_log_tre_part=\"${git_log_cmd%%\"$delim\"*}\"; \ git_log_tre_part=\"${git_log_tre_part##*\"$apost\"}\"; \ git_log_cmd_count=\"$git_log_fst_part$apost $git_log_tre_part$apost$git_log_lst_part\"; \ col_length[\"1:1\"]=$(eval git \"${git_log_cmd_count// --color}\" | wc -L); \ \ \ i=0; \ while IFS=\"$delim\" read -r graph rest;do \ ((i++)); \ graph_line[$i]=\"$graph\"; \ done < <(eval git \"${git_log_cmd/ --color}\" && echo); \ \ \ i=0; \ l=0; \ while IFS= read -r line;do \ c=0; \ ((i++)); \ ((l++)); \ [[ $l -gt $n ]] && l=1; \ while IFS= read -d\"$delim\" -r col_content;do \ ((c++)); \ [[ $c -le $git_tre_col ]] && c_corr=-1 || c_corr=0; \ if [[ $c -eq 1 ]];then \ [[ \"${col_content/\\*}\" = \"$col_content\" ]] && [[ $l -eq 1 ]] && l=$n; \ count=$(wc -L <<< \"${graph_line[$i]}\"); \ whitespaces=$(seq -s\" \" $((${col_length[\"1:1\"]}-$count))|tr -d \"[:digit:]\"); \ col_content[$git_tre_col]=\"${col_content}$whitespaces\"; \ else \ col_content[$c+$c_corr]=\"$(printf \"%-${col_length[\"$l:$c\"]}s\" \"${col_content:-\"\"}\")\"; \ fi; \ done <<< \"$line$delim\"; \ for ((k=$c+1;k<=$i_max;k++));do \ [[ $k -le $git_tre_col ]] && c_corr=-1 || c_corr=0; \ col_content[$k+$c_corr]=\"$(printf \"%-${col_length[\"$l:$k\"]:-${col_length[\"${last[$k]:-1}:$k\"]:-0}}s\" \"\")\"; \ done; \ unset col_content[0]; \ echo -e \"${col_content[*]}\"; \ unset col_content[*]; \ done < <(eval git \"$git_log_cmd\" && echo); \ "' "git-tably"

어디 테이블에

  • 첫 번째 단락은 delim(iter), YourLogAlias 및 YourLogAlias-col을 쉘 변수에 로드합니다.
  • 두 번째는 각 열의 길이를 읽습니다.
  • 세 번째는 최대를 계산합니다. 나무의 길이
  • 네 번째는 트리를 배열에 로드합니다.
  • 다섯 번째는 테이블과 같은 출력을 구성하고 인쇄합니다.

결과:

여기에 이미지 설명 입력

여기에 이미지 설명 입력

여기에 이미지 설명 입력

또는 즉시 새로운 TreeColNumber 사용

여기에 이미지 설명 입력

다시: 당신의 필요에 따라 깨끗한 테이블과 같은 출력물을 스타일링하는 즐거움을 누려보세요.

주석에서 선호하는 형식의 Git 로그 별칭을 공유할 수도 있습니다. 때때로 나는 위의 텍스트에 가장 높은 평가를 받은 것들을 포함하고 이미지도 추가할 것입니다.


onemorequestion

이 문제에 대한 나의 견해는 다음과 같습니다.

스크린샷:

스크린샷

용법:

git hist - 현재 브랜치의 히스토리를 보여줍니다.

git hist --all - 모든 분기의 그래프 표시(리모컨 포함)

git hist master devel - 둘 이상의 브랜치 간의 관계를 표시합니다.

git hist --branches - 모든 로컬 브랜치 표시

--topo-order 를 추가하여 날짜 대신 위상적으로 커밋을 정렬합니다(이 별칭의 기본값).

혜택:

  • 일반 --decorate 처럼 보이므로 다른 분기 이름에 대해 별도의 색상을 사용합니다.
  • 커미터 이메일 추가
  • 커밋 상대 및 절대 날짜 추가
  • 날짜별로 커밋 정렬

설정:

 git config --global alias.hist "log --graph --date-order --date=short \ --pretty=format:'%C(auto)%h%d %C(reset)%s %C(bold blue)%ce %C(reset)%C(green)%cr (%cd)'"

drzymala

gitg : gtk 기반 저장소 뷰어입니다. 새롭지만 흥미롭고 유용합니다.

현재 사용하고 있습니다.


saeedgnu

가끔 gitg 를 사용하지만 항상 명령줄로 돌아갑니다.

 [alias] # Quick look at all repositories loggsa = log --color --date-order --graph --oneline --decorate --simplify-by-decoration --all # Quick look at active branch (or refs pointed) loggs = log --color --date-order --graph --oneline --decorate --simplify-by-decoration # Extend look at all repo logga = log --color --date-order --graph --oneline --decorate --all # Extend look at active branch logg = log --color --date-order --graph --oneline --decorate # Look with the date logda = log --color --date-order --date=local --graph --format=\"%C(auto)%h%Creset %C(blue bold)%ad%Creset %C(auto)%d%Creset %s\" --all logd = log --color --date-order --date=local --graph --format=\"%C(auto)%h%Creset %C(blue bold)%ad%Creset %C(auto)%d%Creset %s\" # Look with the relative date logdra = log --color --date-order --graph --format=\"%C(auto)%h%Creset %C(blue bold)%ar%Creset %C(auto)%d%Creset %s\" --all logdr = log --color --date-order --graph --format=\"%C(auto)%h%Creset %C(blue bold)%ar%Creset %C(auto)%d%Creset %s\" loga = log --graph --color --decorate --all # For repositories without subject body commits (Vim repository, git-svn clones) logt = log --graph --color --format=\"%C(auto)%h %d %<|(100,trunc) %s\" logta = log --graph --color --format=\"%C(auto)%h %d %<|(100,trunc) %s\" --all logtsa = log --graph --color --format=\"%C(auto)%h %d %<|(100,trunc) %s\" --all --simplify-by-decoration

보시다시피 다음을 기반으로 별칭을 저장하는 거의 키 입력입니다.

  • --color: 선명한 모양
  • --graph: 부모 시각화
  • --date-order: repo에서 가장 이해하기 쉬운 보기
  • --decorate: 누구인가
  • --oneline: 여러 번 커밋에 대해 알아야 할 모든 것
  • --simplify-by-decoration: 첫인상을 위한 기본(단지 태그, 관련 병합, 분기)
  • --all: 이 옵션이 있거나 없는 모든 별칭으로 키 입력 저장
  • --date=relative (%ar): repo의 활동 이해

최신 버전의 Git(1.8.5 이상)에서는 장식 자리 표시자 %d에서 %C(auto)의 이점을 얻을 수 있습니다.

당신이 필요로하는 모든 곳에서하는 것이 좋은 이해입니다 gitrevisions 필터에 어떤 당신은 (뭔가 master..develop 같은 필요 --simplify-merges 장기 가지로 도움을 줄 수).

명령줄의 힘은 필요에 따른 빠른 구성입니다(리포지토리는 고유한 키 로그 구성이 아니므로 --numstat, --raw 또는 --name-status를 추가해야 하는 경우가 있습니다. 여기 git log 별칭은 빠르고 강력하며 (시간이 지남에 따라) 얻을 수 있는 가장 아름다운 그래프입니다. 게다가 기본적으로 호출기를 통해 출력이 표시되므로(말하자면) 결과 내에서 항상 빠르게 검색할 수 있습니다. 확신이 서지 않으십니까? 결과를 항상 구문 분석할 수 있습니다 gitgraph 와 같은 프로젝트와 함께 .


albfan

Git을 위한 훨씬 더 나은 명령줄 도구인 tig https://github.com/jonas/tig 를 제안합니다.

Homebrew를 사용하여 macOS에 tig를 설치할 수 있습니다.

 $ brew install tig $ tig

여기에 이미지 설명 입력


nodejh

Slipp의 멋진 답변을 약간 조정하면 그의 별칭을 사용하여 하나의 분기만 기록할 수 있습니다.

 [alias] lgBranch1 = log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(bold white)— %an%C(reset)%C(bold yellow)%d%C(reset)' --abbrev-commit --date=relative lgBranch2 = log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(bold white)— %an%C(reset)' --abbrev-commit lg = !"git lg1"

지금 할 수 있는 --all

 git lgBranch1 <branch name>

또는

 git lgBranch1 --all

Peter Ajtai

Visual Studio Code에는 놀라운 확장 기능이 있습니다. Git Graph :

힘내 그래프


kaushalpranav

그래프 기록을 보기 위해 ~/.gitconfig 에 이 git log

 [alias] l = log --all --graph --pretty=format:'%C(auto)%h%C(auto)%d %s %C(dim white)(%aN, %ar)'

이것이 제자리에 있으면 git l 은 다음과 같이 출력합니다.

여기에 이미지 설명 입력

Git2.12 log.graphColors 구성 옵션을 사용하여 그래프의 선 색상을 사용자 정의할 수도 있습니다.

로그 형식은 --oneline 과 유사하며 작성자 이름 ( .mailmap )과 상대 작성자 날짜가 추가됩니다 . 커밋 해시 등에 기본 색상을 사용하도록 Git에 지시하는 %C(auto) 구문은 Git >= 1.8.3 에서 지원됩니다.


Eugene Yarmash

gitk 또는 gitk --all 시도하십시오. 그러나 img 인쇄/저장 기능이 없습니다.


Adrian Panasiuk

git -c core.pager='less -SRF' log --oneline --graph --decorate

이것은 여기의 많은 답변과 유사한 내 터미널 변형입니다. 나는 줄 바꿈을 방지하기 less 전달되는 플래그를 조정하는 것을 좋아합니다.

예제 출력

명령이 약간 번거롭기 때문에 빠른 액세스를 위해 이것을 별칭으로 설정했습니다.


Andy

깃그래프

Git 리포지토리의 커밋 기록에 대한 PNG 또는 SVG 표현을 생성합니다.


EddieG098

껍질에 대한 더 분기 같은 색상 버전입니다.

이자형

일부 다른 답변은 부분적으로 색상이 지정된 선 정보와 함께 외부 도구로 멋지게 채색된 그래프 트리를 보여줍니다. 이것은 표와 같은 출력에 대한 첫 번째 답변과 결합된 셸에 대한 접근 방식입니다( https://stackoverflow.com/a/61487052 ).

특징:

  • 모든 나무 색상을 정의할 수 있습니다.
  • 모든 컬럼을 해당 가지 색상으로 염색할 수 있습니다.
  • 나무 기둥을 다른 위치에 배치할 수 있습니다.
  • git log 별칭을 사용할 수 있습니다.
  • 각 별칭에 대해 트리 열 번호를 정의할 수 있습니다.
  • 거대한 기록을 위해 less -r 로 파이프할 수 있습니다.

사용 방법:

사용자 정의 git log 에서, 예를 들면 같이 여러 답변에서와 같이 별칭을 Slipp D. , albfan , 카오루 아래에 언급 된 서식 지침 및 코드와 함께 당신의 .gitconfig 파일에 붙여 넣습니다. 일반적으로 다음과 같이 프로젝트 경로에서 호출하십시오.

git colored YourLogAlias 또는

git colored YourLogAlias TreeColumnNumber 를 사용하여 즉시 트리 열을 배치합니다.

포맷 지침:

git log 별칭은 다음 형식 규칙을 따라야 합니다.

  • 모든 커밋 자리 표시자에 대해 열 구분 기호로 고유한 문자를 사용하십시오. 예: ^
    ...format:'%h%cr%s' -->
    ...format:'^%h^%cr^%s'
  • 전체 열을 한 가지 색상으로 색칠하거나 비워 두어 해당 분기 색상을 적용합니다.
    ...format:'^%h^%cr^%s' -->
    ...format:'^%h^%cr^%C(white)%s%C(reset)' (분기 색상의 해시 및 시간)
  • %><(<N>[,ltrunc|mtrunc|trunc]) 로 열 너비를 지정해야 하지만 줄의 마지막 커밋 자리 표시자는 그것 없이 사용할 수 있습니다.
    ...format:'^%h^%cr^%C(white)%s%C(reset)' -->
    ...format:'^%<(7,trunc)%h^%<(12,trunc)%cr^%C(white)%<(50,trunc)%s%C(reset)'
  • 추가 장식 문자가 필요한 경우 커밋 자리 표시자 주위에 직접 배치합니다. 즉, Commit:
    ...^%C(white)%<(50,trunc)%s%C(reset)... -->
    ...^%C(white)%<(50,trunc)Commit:%s%C(reset)...
  • 줄 바꿈을 사용하는 경우 %n 열 구분 기호 앞이나 끝에 넣습니다.
    ...^%C(white)%<(50,trunc)Commit:%s%C(reset)' -->
    ...%n^%C(white)%<(50,trunc)Commit:%s%C(reset)%n'
  • %C(white) 와 같은 열 색상을 사용하는 경우 --color 옵션을 추가해야 합니다.
    ...format:'^%<(7,trunc)%h... -->
    ...--color...format:'^%<(7,trunc)%h...
  • --stat 옵션 또는 이와 유사한 것을 사용하는 경우 끝에 %n
    ...--stat...format:'...' -->
    ...--stat...format:'...%n'

여러 가지 잡다한:

  • 비어 있지 않은 줄 바꿈이 있는 git log ...%n%CommitPlaceholder... , 각 줄의 n번째 열이 모두 존재하고 동일한 너비를 사용하는 경우에만 모든 열 n+1에 Git 그래프를 배치할 수 있습니다.

  • YourLogAlias-col 은 YourLogAlias에 대한 .gitconfig 파일에서 TreeColumnNumber를 정의하는 경우 이름 YourLogAlias

  • 일반 git log 출력에 비해 느리지만 좋습니다.

예:

git colored lgc1 이자형

git colored lgc2 이자형

git colored lgc3 이자형

git colored lgc4 이자형

코드 스니펫:

.gitconfig 파일에 다음 줄을 추가합니다.

 [alias] # Define your unique column separator delim = ^ # Define your 'git log' aliases and optional tree column numbers lgc1 = log --all --graph --color --pretty=format:'^%<(7,trunc)%h^%C(white)%<(15,trunc)- %ar -%C(reset)^%<(35,trunc)%s^%C(white)%an%C(reset)' lgc2 = log --all --graph --color --pretty=format:'%D^%<(7,trunc)%h^%<(35,trunc)%s^%C(white)%<(20,trunc)%an%C(reset)^%C(white) (%ar)%C(reset)' lgc2-col = 2 lgc3 = log --all --graph --color --pretty=format:'%<(7,trunc)%h%d^%<(11,trunc)%cs%C(reset)^%s%n^%C(white)%<(11,trunc)%cr%C(reset)^%C(white)%<(25,trunc)From %an%C(reset)^%C(white)%ae%C(reset)%n' lgc3-col = 2 lgc4 = log --all --graph --color --pretty=format:'%h^%C(white)%<(25,trunc)%an%C(reset)^%C(white)%<(31,trunc)%aD%C(reset)^%s%n^%C(dim white)%<(25,trunc)%ae%C(reset)^%>(31,trunc)%D%C(reset)%n' lgc4-col = 3 # Define your whitespace seperated tree color list color-list = "1;38;5;222 1;38;5;69 1;38;5;250 1;38;5;70 1;31 1;38;5;93 1;33 2;38;5;11 1;38;5;48 1;35 1;32 1;38;5;111 1;38;5;160 1;38;5;130 1;36 38;5;21"

.gitconfig 파일에도 Bash 스니펫을 추가합니다.

 # This is the Bash snippet which does all the magic colored = !bash -c '" \ \ \ declare -A col_length col_colored; \ apost=$(echo -e \"\\u0027\"); \ delim=$(git config alias.delim); \ git_log_cmd=$(git config alias.$1); \ graph_col=${2:-$(git config alias.$1-col)}; \ color_list=( $(git config alias.color-list) ); \ [[ -z \"$graph_col\" ]] && graph_col=1; \ [[ -z \"$git_log_cmd\" ]] && { git $1;exit; }; \ \ \ i=0; \ n=0; \ while IFS= read -r line; do \ ((n++)); \ while read -d\"$delim\" -r col_info;do \ ((i++)); \ [[ -z \"$col_info\" ]] && col_length[\"$n:$i\"]=${col_length[\"${last[$i]:-1}:$i\"]} && ((i--)) && continue; \ [[ $i -gt ${i_max:-0} ]] && i_max=$i; \ [[ \"${col_info:1:1}\" = \"C\" ]] && col_colored[\"$n:$i\"]=1; \ col_length[\"$n:$i\"]=$(grep -Eo \"\\([0-9]*,[lm]*trunc\\)\" <<< \"$col_info\" | grep -Eo \"[0-9]*\" | head -n 1); \ [[ -n \"${col_length[\"$n:$i\"]}\" ]] && last[$i]=$n; \ chars_extra=$(grep -Eo \"\\trunc\\).*\" <<< \"$col_info\"); \ chars_extra=${chars_extra#trunc)}; \ chars_begin=${chars_extra%%\\%*}; \ chars_extra=${chars_extra%$apost*}; \ chars_extra=${chars_extra#*\\%}; \ case \" ad aD ae aE ai aI al aL an aN ar as at b B cd cD ce cE ci cI cl cL cn cN cr \ cs ct d D ef G? gd gD ge gE GF GG GK gn gN GP gs GS GT h HN p P s S t T \" in \ *\" ${chars_extra:0:2} \"*) \ chars_extra=${chars_extra:2}; \ chars_after=${chars_extra%%\\%*}; \ ;; \ *\" ${chars_extra:0:1} \"*) \ chars_extra=${chars_extra:1}; \ chars_after=${chars_extra%%\\%*}; \ ;; \ *) \ echo \"No Placeholder found. Probably no table-like output.\"; \ continue; \ ;; \ esac; \ if [[ -n \"$chars_begin$chars_after\" ]];then \ len_extra=$(echo \"$chars_begin$chars_after\" | wc -m); \ col_length[\"$n:$i\"]=$((${col_length[\"$n:$i\"]}+$len_extra-1)); \ fi; \ done <<< \"${line#*=format:}$delim\"; \ i=1; \ done <<< \"$(echo -e \"${git_log_cmd//\\%n/\\\\n}\")\"; \ \ \ git_log_fst_part=\"${git_log_cmd%%\"$apost\"*}\"; \ git_log_lst_part=\"${git_log_cmd##*\"$apost\"}\"; \ git_log_tre_part=\"${git_log_cmd%%\"$delim\"*}\"; \ git_log_tre_part=\"${git_log_tre_part##*\"$apost\"}\"; \ git_log_cmd_count=\"$git_log_fst_part$apost $git_log_tre_part$apost$git_log_lst_part\"; \ col_length[\"1:1\"]=$(eval git \"${git_log_cmd_count// --color}\" | wc -L); \ \ \ i=0; \ while IFS=\"$delim\" read -r graph rest;do \ ((i++)); \ graph_line[$i]=\"$graph\"; \ done < <(eval git \"${git_log_cmd/ --color}\" && echo); \ \ \ i=0; \ l=0; \ msg_err=; \ color_list_ind=-1; \ color_list_num=${#color_list[*]}; \ color_repeat_ind=1; \ if [[ $color_list_num -eq 0 ]];then \ echo \"No tree colors specified via color-list under section [alias] in your .gitconfig\"; \ echo \"Therefore collecting available Git colors, which may take a while ...\"; \ while read -d\"[\" -r char;do \ color=$(sed -nl99 \"l\" <<< \"$char\"); \ case \"$color\" in \ *\"m\"*) \ color=${color%%m*}; \ ;; \ *) \ continue; \ ;; \ esac; \ case \" $color_list \" in \ *\" $color \"*) \ continue; \ ;; \ *) \ color_list=\"$color_list$color \"; \ ;; \ esac; \ done <<< \"$(git log --all --color --graph --pretty=format:)\"; \ echo -e \"Temporary used color-list = \\\"${color_list% }\\\"\\n\"; \ color_list=( ${color_list% } ); \ color_list_num=${#color_list[*]}; \ fi; \ while IFS= read -r line;do \ ((i++)); \ j=-1; \ case_off=; \ graph_colored=; \ graph_line_last=\"${graph_line[$i-1]}\"; \ graph_line=\"${graph_line[$i]}\"; \ graph_line_next=\"${graph_line[$i+1]}\"; \ while IFS= read -r char;do \ ((j++)); \ case \"$case_off$char\" in \ [^\\ \\_\\*\\/\\|\\\\]|\"case_off\"*) \ graph_colored=\"${graph_colored}\\033[${point_color}m$char\\033[0m\"; \ case_off=\"case_off\"; \ ;; \ \" \") \ graph_colored=\"${graph_colored}$char\"; \ case \"$char_last\" in \ \" \") \ unset color_ind[$j]; \ ;; \ esac; \ ;; \ \"*\") \ case \"${graph_line_last:$j:1}\" in \ \"*\") \ :; \ ;; \ \"|\") \ case \"${graph_line_last:$(($j-1)):1}\" in \ \"\\\\\") \ color_ind[$j]=${color_ind_last[$j-1]:-${color_ind[$j-1]}}; \ ;; \ *) \ :; \ ;; \ esac; \ ;; \ \" \") \ case \"${graph_line_last:$(($j-1)):1}\" in \ \"\\\\\") \ color_ind[$j]=${color_ind_last[$j-1]:-${color_ind[$j-1]}}; \ ;; \ \"/\") \ case \"${graph_line_last:$(($j+1)):1}\" in \ \"/\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ \" \") \ new_col_ind=${#color[*]}; \ while true;do \ ((color_list_ind++)); \ [[ $color_list_ind -ge $color_list_num ]] && color_list_ind=$color_repeat_ind; \ [[ $color_list_ind -ge $color_list_num ]] && break; \ new_color=${color_list[$color_list_ind]}; \ case \"$new_color\" in \ \"\"|[\\ ]*) \ continue; \ ;; \ \"${color[${color_ind[$j-1]}]}\") \ [[ $(($color_list_num-$color_repeat_ind)) -gt 1 ]] && continue; \ ;;& \ *) \ color[$new_col_ind]=$new_color; \ color_ind[$j]=$new_col_ind; \ last_new_colored_line=$i; \ break; \ ;; \ esac 2>/dev/null; \ done; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ \" \") \ case \"${graph_line_last:$(($j+1)):1}\" in \ \"/\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ *) \ new_col_ind=${#color[*]}; \ while true;do \ ((color_list_ind++)); \ [[ $color_list_ind -ge $color_list_num ]] && color_list_ind=$color_repeat_ind; \ [[ $color_list_ind -ge $color_list_num ]] && break; \ new_color=${color_list[$color_list_ind]}; \ case \"$new_color\" in \ \"\"|[\\ ]*) \ continue; \ ;; \ \"${color[${color_ind[$j-1]}]}\") \ [[ $(($color_list_num-$color_repeat_ind)) -gt 1 ]] && continue; \ ;;& \ *) \ color[$new_col_ind]=$new_color; \ color_ind[$j]=$new_col_ind; \ last_new_colored_line=$i; \ break; \ ;; \ esac 2>/dev/null; \ done; \ ;; \ esac; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ \"\"|[^\\ \\_\\*\\/\\|\\\\]) \ new_col_ind=${#color[*]}; \ while true;do \ ((color_list_ind++)); \ [[ $color_list_ind -ge $color_list_num ]] && color_list_ind=$color_repeat_ind; \ [[ $color_list_ind -ge $color_list_num ]] && break; \ new_color=${color_list[$color_list_ind]}; \ case \"$new_color\" in \ \"\"|[\\ ]*) \ continue; \ ;; \ \"${color[${color_ind[$j-1]}]}\") \ [[ $(($color_list_num-$color_repeat_ind)) -gt 1 ]] && continue; \ ;;& \ *) \ color[$new_col_ind]=$new_color; \ color_ind[$j]=$new_col_ind; \ last_new_colored_line=$i; \ break; \ ;; \ esac 2>/dev/null; \ done; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ graph_colored=\"${graph_colored}\\033[${color[${color_ind[$j]}]}m$char\\033[0m\"; \ point_color=${color[${color_ind[$j]}]}; \ ;; \ \"|\") \ case \"${graph_line_last:$j:1}\" in \ \" \") \ case \"${graph_line_last:$(($j-1)):1}\" in \ \"/\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ \"\\\\\") \ color_ind[$j]=${color_ind_last[$j-1]:-${color_ind[$j-1]}}; \ ;; \ *) \ case \"${graph_line_last:$(($j+1)):1}\" in \ \"/\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ esac; \ ;; \ \"|\") \ case \"${graph_line_last:$(($j-1)):1}\" in \ \"\\\\\") \ case \"${graph_line:$(($j+1)):1}\" in \ \"\\\\\") \ :; \ ;; \ \" \") \ color_ind[$j]=${color_ind_last[$j-1]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ *) \ :; \ ;; \ esac; \ ;; \ \"*\") \ case \"${graph_line:$(($j-1)):1}\" in \ \"/\") \ if [[ $last_new_colored_line -eq $(($i-1)) ]];then \ new_col_ind=${#color[*]}; \ while true;do \ ((color_list_ind++)); \ [[ $color_list_ind -ge $color_list_num ]] && color_list_ind=$color_repeat_ind; \ [[ $color_list_ind -ge $color_list_num ]] && break; \ new_color=${color_list[$color_list_ind]}; \ case \"$new_color\" in \ \"\"|[\\ ]*) \ continue; \ ;; \ \"${color[${color_ind[$j-1]}]}\") \ [[ $(($color_list_num-$color_repeat_ind)) -gt 1 ]] && continue; \ ;;& \ *) \ color[$new_col_ind]=$new_color; \ color_ind[$j]=$new_col_ind; \ break; \ ;; \ esac 2>/dev/null; \ done; \ else \ color_ind[$j]=${color_ind_last[$j]}; \ fi; \ ;; \ *) \ :; \ ;; \ esac; \ ;; \ \"/\") \ color_ind[$j]=${color_ind[$j]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ graph_colored=\"${graph_colored}\\033[${color[${color_ind[$j]}]}m$char\\033[0m\"; \ ;; \ \"/\") \ case \"${graph_line_last:$(($j)):1}\" in \ \"|\") \ case \"${graph_line_last:$(($j+1)):1}\" in \ \"/\") \ case \"${graph_line_next:$j:1}\" in \ \"|\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ \" \") \ color_ind[$j]=${color_ind[$j]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ *) \ color_ind[$j]=${color_ind[$j]}; \ ;; \ esac; \ ;; \ *) \ case \"${graph_line_last:$(($j+2)):1}\" in \ \"/\"|\"_\") \ color_ind[$j]=${color_ind[$j+2]}; \ ;; \ *) \ case \"${graph_line_last:$(($j+1)):1}\" in \ \"/\"|\"_\"|\"|\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ \"*\") \ case \"${graph_line:$(($j+1)):1}\" in \ \"|\") \ if [[ $last_new_colored_line -eq $(($i-1)) ]];then \ color_ind[$j]=${color_ind_last[$j+1]}; \ else \ new_col_ind=${#color[*]}; \ while true;do \ ((color_list_ind++)); \ [[ $color_list_ind -ge $color_list_num ]] && color_list_ind=$color_repeat_ind; \ [[ $color_list_ind -ge $color_list_num ]] && break; \ new_color=${color_list[$color_list_ind]}; \ case \"$new_color\" in \ \"\"|[\\ ]*) \ continue; \ ;; \ \"${color[${color_ind[$j-1]}]}\") \ [[ $(($color_list_num-$color_repeat_ind)) -gt 1 ]] && continue; \ ;;& \ *) \ color[$new_col_ind]=$new_color; \ color_ind[$j]=$new_col_ind; \ break; \ ;; \ esac 2>/dev/null; \ done; \ fi; \ ;; \ *) \ color_ind[$j]=${color_ind_last[$j+1]}; \ ;; \ esac; \ ;; \ *) \ case \"${graph_line_last:$j:1}\" in \ \"\\\\\") \ :; \ ;; \ \" \") \ case \"${graph_line_last:$(($j+1)):1}\" in \ \"*\") \ color_ind[$j]=${color_ind[$j+1]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ esac; \ ;; \ esac; \ ;; \ esac; \ graph_colored=\"${graph_colored}\\033[${color[${color_ind[$j]}]}m$char\\033[0m\"; \ ;; \ \"\\\\\") \ case \"${graph_line_last:$(($j-1)):1}\" in \ \"|\"|\"\\\\\") \ color_ind[$j]=${color_ind_last[$j-1]:-${color_ind[$j-1]}}; \ ;; \ \"*\") \ new_col_ind=${#color[*]}; \ while true;do \ ((color_list_ind++)); \ [[ $color_list_ind -ge $color_list_num ]] && color_list_ind=$color_repeat_ind; \ [[ $color_list_ind -ge $color_list_num ]] && break; \ new_color=${color_list[$color_list_ind]}; \ case \"$new_color\" in \ \"\"|[\\ ]*) \ continue; \ ;; \ \"${color[${color_ind[$j-1]}]}\") \ [[ $(($color_list_num-$color_repeat_ind)) -gt 1 ]] && continue; \ ;;& \ *) \ color[$new_col_ind]=$new_color; \ color_ind[$j]=$new_col_ind; \ break; \ ;; \ esac 2>/dev/null; \ done; \ ;; \ \" \") \ case \"${graph_line_last:$(($j-2)):1}\" in \ \"\\\\\"|\"_\") \ color_ind[$j]=${color_ind_last[$j-2]:-${color_ind[$j-2]}}; \ ;; \ *) \ case \"${graph_line_last:$j:1}\" in \ \"|\") \ color_ind[$j]=${color_ind_last[$j]:-${color_ind[$j]}}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ esac; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ graph_colored=\"${graph_colored}\\033[${color[${color_ind[$j]}]}m$char$char\\033[0m\"; \ ;; \ \"_\") \ case \"${graph_line:$(($j-2)):1}\" in \ \"\\\\\"|\"_\") \ color_ind[$j]=${color_ind[$j-2]}; \ ;; \ \" \"|\"/\") \ k=2; \ while [[ \"${graph_line:$(($j+$k)):1}\" = \"_\" ]];do \ k=$(($k+2)); \ done; \ case \"${graph_line:$(($j+$k)):1}\" in \ \"/\") \ case \"${graph_line_last:$(($j+$k+1)):1}\" in \ \"*\") \ color_ind[$j]=${color_ind[$j+$k+1]}; \ ;; \ \" \") \ case \"${graph_line_last:$(($j+$k)):1}\" in \ \"\\\\\") \ color_ind[$j]=${color_ind[$j+$k]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ \"|\") \ case \"${graph_line:$(($j+$k+1)):1}\" in \ \"|\") \ color_ind[$j]=${color_ind[$j+$k+2]}; \ ;; \ \" \") \ color_ind[$j]=${color_ind[$j+$k+1]}; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ ;; \ *) \ [[ -n \"$msg_err\" ]] && echo -e \"Unknown case in graph_line $i: $graph_line for char $char at position $j\nwith the former graph_line $(($i-1)): $graph_line_last\"; \ ;; \ esac; \ graph_colored=\"${graph_colored}\\033[${color[${color_ind[$j]}]}m$char\\033[0m\"; \ ;; \ esac; \ char_last=$char; \ done <<< \"$(grep -Eo \".\" <<< \"${graph_line%%$delim*}\")\"; \ for key in ${!color_ind[*]};do \ color_ind_last[$key]=${color_ind[$key]}; \ done; \ \ \ c=0; \ ((l++)); \ [[ $l -gt $n ]] && l=1; \ while IFS= read -d\"$delim\" -r col_content;do \ ((c++)); \ [[ $c -le $graph_col ]] && c_corr=-1 || c_corr=0; \ if [[ $c -eq 1 ]];then \ [[ \"${col_content/\\*}\" = \"$col_content\" ]] && [[ $l -eq 1 ]] && l=$n; \ whitespaces=$(seq -s\" \" $((${col_length[\"1:1\"]}-$j))|tr -d \"[:digit:]\"); \ col_content[$graph_col]=\"${graph_colored}$whitespaces\"; \ elif [[ ${col_colored[\"$l:$c\"]:-0} -eq 0 ]];then \ col_content[$c+$c_corr]=\"\\033[${point_color:-0}m$(printf \"%-${col_length[\"$l:$c\"]}s\" \"${col_content:-\"\"}\")\\033[0m\"; \ else \ col_content[$c+$c_corr]=\"$(printf \"%-${col_length[\"$l:$c\"]}s\" \"${col_content:-\"\"}\")\"; \ fi; \ done <<< \"$line$delim\"; \ for ((k=$c+1;k<=$i_max;k++));do \ [[ $k -le $graph_col ]] && c_corr=-1 || c_corr=0; \ col_content[$k+$c_corr]=\"$(printf \"%-${col_length[\"$l:$k\"]:-${col_length[\"${last[$k]:-1}:$k\"]:-0}}s\" \"\")\"; \ done; \ unset col_content[0]; \ echo -e \"${col_content[*]}\"; \ unset col_content[*]; \ done < <(git $1 && echo); \ "' "git-colored"

설명:

  • 첫 번째 단락은 delim(iter), color-list 및 YourLogAlias를 쉘 변수에 로드합니다.
  • 두 번째는 모든 열의 길이를 읽습니다.
  • 세 번째는 트리의 최대 길이를 계산합니다.
  • 네 번째는 트리를 배열에 로드합니다.
  • 사례 분석을 기반으로 하는 다섯 번째 색상은 나무입니다.
  • 여섯 번째는 트리가 아닌 열에 색상을 지정하고 테이블과 같은 출력을 인쇄합니다.

가장 큰 부분은 나무 색상을 설정하는 경우 분석입니다. 다른 부분은 표와 같은 셸 출력에 대한 내 연결된 답변에 설명되어 있습니다.

내 것은 예시일 뿐이므로 주석에 좋아하는 형식의 로그 별칭을 표시하세요.


onemorequestion

시도 해보세요 . ASCII 다이어그램을 이미지로 변환할 수 있습니다. Git 브랜치를 염두에 두고 설계한 것은 아니지만 결과에 깊은 인상을 받았습니다.

소스(txt 파일):

 +--------+ | hotfix | +---+----+ | --*<---*<---* ^ | \--*<---* | +---+----+ | master | +--------+

명령:

 java -jar ditaa0_9.jar ascii-graph.txt

결과:

여기에 이미지 설명 입력

또한 배경색, 점선, 다양한 모양 등을 지원합니다. 예를 참조하십시오.


fracz

~/.oh-my-zsh/plugins/git/git.plugin.zsh 파일의 일부 별칭:

 gke='\gitk --all $(git log -g --pretty=%h)' glg='git log --stat' glgg='git log --graph' glgga='git log --graph --decorate --all' glgm='git log --graph --max-count=10' glgp='git log --stat -p' glo='git log --oneline --decorate' glog='git log --oneline --decorate --graph' gloga='git log --oneline --decorate --graph --all' glol='git log --graph --pretty='\''%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\'' --abbrev-commit' glola='git log --graph --pretty='\''%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\'' --abbrev-commit --all'

shuaihanhungry

저장소가 GitLab에 있는 경우 브라우저에서 SVG로 렌더링되는 그래프 표현을 사용할 수 있습니다.

여기에 이미지 설명 입력


bugmenot123

Raphael 웹 그래픽 라이브러리의 데모 중 하나로 펑키한 Git 커밋 그래프가 있습니다.

데모는 정적이지만 코드를 가져와 정적 데이터를 라이브 데이터 세트로 바꾸는 것은 충분히 쉬워야 합니다. JSON 형식의 Git 커밋 데이터라고 생각합니다.

데모는 여기: http://dmitrybaranovskiy.github.io/raphael/github/impact.html


Spudley

출처 : http:www.stackoverflow.com/questions/1057564/pretty-git-branch-graphs

반응형