我见过一些书籍和文章中有一些非常漂亮的Git分支和提交的图表。如何制作Git历史的高质量可打印图像?


当前回答

Visual Studio代码有一个惊人的扩展-Git Graph:

其他回答

贝壳的颜色更像树枝。

其他一些答案显示了外部工具对图形树进行了很好的着色,部分带有彩色线条信息。这是我的shell方法,它与我在这里对类似表的输出的第一个答案相结合(https://stackoverflow.com/a/61487052).

特征:

您可以定义所有树的颜色你可以用相应的分支颜色染每一列可以将树列放置在不同的位置您可以使用各种git日志别名可以为每个别名定义树列编号你可以通过管道将其输入到较小的-r中,以获取巨大的历史记录

如何使用:

根据下面提到的格式说明,定义您的git日志别名,如所示的几个答案,例如Slipp D.、albfan、kaoru,并将其与代码片段一起粘贴到.gitconfig文件中。从项目路径调用它,通常使用

git-colord YourLogAlias或

git colored YourLogAlias TreeColumnNumber以动态放置树列。

格式化说明:

您的git日志别名必须遵循以下格式规则:

使用唯一字符作为每个提交占位符的列分隔符^…格式:“%h%cr%s”-->。。。格式:“^%h^%cr^%s”将整列用一种颜色着色,或将其留空以采用相应的分支颜色…格式:“^%h^%cr^%s”-->。。。格式:“^%h^%cr^%C(白色)%s%C(重置)”(哈希值和时间为分支颜色)必须使用trunc选项之一通过%><(<N>[,ltrunc|mtrunc|trunc])指定任何列的宽度,但是可以使用行上的任何最后一个提交占位符而不使用它…格式:“^%h^%cr^%C(白色)%s%C(重置)”-->。。。格式:“^%<(7,trunc)%h^%<如果需要额外的修饰字符,请将它们直接放置在提交占位符周围,即提交:…^%C(白色)%<(50,截断)%s%C(重置)…-->…^%C(白色)%<(50,trunc)提交:%s%C(重置)。。。如果使用换行符%n请将它们放在列分隔符之前或末尾…^%C(白色)%<(50,trunc)提交:%s%C(重置)'-->…%n ^%C(白色)%<(50,trunc)提交:%s%C(重置)%n'如果使用列颜色,如上面的%C(白色),则需要添加--color选项…格式:'^%<(7,trunc)%h.…-->--颜色格式:'^%<(7,trunc)%h。。。如果使用--stat选项或类似选项,请在末尾添加一个换行符%n…--stat..格式:“…”-->--stat..格式:“…%n”

其他:

对于具有非空换行符的git日志别名…%n%提交占位符。。。,只有当每行的所有第n列都存在并且使用相同的宽度时,才能将Git图放置在每列n+1处如果在文件.gitconfig中为YourLogAlias定义TreeColumnNumber,则YourLogAlias col必须是名称与正常的git日志输出相比,这个输出速度慢,但很好

示例:

git彩色lgc1

git彩色lgc2

git彩色lgc3

git彩色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"

将Bash代码段也添加到.gitconfig文件中

# 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 e f G? gd gD ge gE GF GG GK gn gN GP gs GS GT h H N 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)、颜色列表和YourLogAlias加载到shell变量中第二个读取每列的长度第三个计算树的最大长度第四个将树加载到数组中第五部分根据案例分析为树上色第六个为非树列着色,并打印类似表的输出

最大的部分是设置树颜色的案例分析。其他部分在我对类似于表的shell输出的链接答案中进行了解释。

请在评论中显示您最喜欢的格式化日志别名,因为我的只是示例。

gitg:基于gtk的存储库查看器。这是新的,但有趣且有用。

我目前正在使用它。

我编写了一个web工具,用于将Git日志转换为漂亮的SVG图形:

Bit Booster-离线提交图形绘制工具

将git-log的输出--prey='%h|%p|%d'直接上载到工具中,然后单击“download-grap.svg”链接。

该工具是纯客户端的,因此您的Git数据不会与我的服务器共享。您还可以在本地保存HTML+JavaScript,并使用“file:///”URL运行它。它在Ubuntu 12.04(精确穿山甲)上的Chrome 48和Firefox 43上进行了验证。

它生成的HTML可以直接发布到任何页面(包括blogspot博客引擎!)。看看这里的一些博客帖子:

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

下面是该工具生成的示例HTML文件的屏幕截图:

http://bit-booster.com/graph.html(工具)

Sourcetree是一个非常好的工具。它确实打印出了一个好看的中等大小的历史和分支图:(以下是在一个实验性Git项目上完成的,只是为了查看一些分支)。支持Windows 7+和Mac OS X 10.6+。

虽然我有时使用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

正如您所看到的,它几乎是一个按键保存别名,基于:

--颜色:清晰外观--图形:可视化父对象--日期顺序:回购最容易理解--装饰:谁是谁--oneline:很多时候你需要知道的关于提交--通过修饰来简化:初步了解的基础(仅标记、相关合并、分支)--all:保存带有或不带有此选项的所有别名的键击--date=relative(%ar):了解回购中的活动(有时分支机构很少在主服务器附近提交,但几个月前就提交了)

请参阅Git的最新版本(1.8.5及以上版本),您可以从装饰占位符%d中的%C(auto)中获益。

从这里开始,您只需要很好地理解gitrevisions,以过滤您需要的任何内容(比如master…develop,其中--简化合并可能有助于实现长期分支)。

命令行背后的强大功能是根据您的需要快速配置(了解存储库不是唯一的密钥日志配置,因此有时需要添加--numstat、--raw或--name状态)。在这里,git日志和别名快速、强大,(随着时间的推移)是您可以实现的最漂亮的图形。更重要的是,默认情况下通过寻呼机显示输出(更不用说),您可以始终快速搜索结果。不相信?您始终可以使用gitgraph等项目解析结果。