Skip to content

Commit 9eda381

Browse files
committed
feat: git graph with Claude 3.7
1 parent 38edc9b commit 9eda381

File tree

3 files changed

+97
-8
lines changed

3 files changed

+97
-8
lines changed

src/views/history/components/CommitTable/GitGraph.vue

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const props = defineProps<{
88
activeBranches?: string[]
99
// 是否被选中
1010
isSelected?: boolean
11+
// 标记哪些分支不应该向上延伸
12+
branchEndingUp?: string[]
1113
}>()
1214
1315
// SVG宽度将根据分支数量动态计算
@@ -53,8 +55,18 @@ function getBranchColorFromData(branchName: string): string {
5355
return props.graphData.sourceBranchColors[branchName]
5456
}
5557
56-
// 如果没有找到预处理的颜色,返回默认颜色
57-
return '#888888'
58+
// 生成一个基于分支名的稳定颜色
59+
// 使用分支名作为唯一标识符来生成一个稳定的哈希值
60+
let hash = 0;
61+
for (let i = 0; i < branchName.length; i++) {
62+
hash = ((hash << 5) - hash) + branchName.charCodeAt(i);
63+
hash = hash & hash; // 转换为32位整数
64+
}
65+
66+
// 使用哈希值选择一个颜色
67+
// 黄金比例法生成分散均匀的颜色
68+
const hue = (hash % 360 + 360) % 360; // 确保是正数
69+
return `hsl(${hue}, 70%, 45%)`; // 使用 HSL 颜色格式
5870
}
5971
6072
// 计算当前提交涉及的所有分支
@@ -95,10 +107,10 @@ const allBranches = computed(() => {
95107
<g v-if="graphData">
96108
<!-- 第1层: 先绘制所有活跃分支的竖线 -->
97109
<template v-for="(branch, index) in allBranches" :key="`branch-${index}`">
98-
<!-- 垂直分支线 - 贯穿整个图表 -->
110+
<!-- 垂直分支线 - 如果是最后一个提交则不向上延伸 -->
99111
<line
100112
:x1="getBranchPosition(branch)"
101-
y1="0"
113+
:y1="props.branchEndingUp?.includes(branch) ? SVG_HEIGHT / 2 : 0"
102114
:x2="getBranchPosition(branch)"
103115
:y2="SVG_HEIGHT"
104116
:stroke="getBranchColorFromData(branch)"

src/views/history/components/CommitTable/ListItem.vue

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { ref } from 'vue'
2+
import { computed, ref } from 'vue'
33
import CopyButton from '../CopyButton/index.vue'
44
import GitGraph from './GitGraph.vue'
55
@@ -20,19 +20,35 @@ const emit = defineEmits(['select'])
2020
const hoveredCell = ref<string | null>(null)
2121
2222
function getBranchColorFromGraphData(branchName: string): string {
23+
if (!props.graphData) return '#888888'
24+
25+
// 检查当前提交的主分支颜色
2326
if (props.graphData.branch === branchName && props.graphData.branchColor) {
2427
return props.graphData.branchColor
2528
}
2629
30+
// 检查目标分支颜色
2731
if (props.graphData.targetBranch === branchName && props.graphData.targetBranchColor) {
2832
return props.graphData.targetBranchColor
2933
}
3034
35+
// 检查源分支颜色
3136
if (props.graphData.sourceBranchColors && props.graphData.sourceBranchColors[branchName]) {
3237
return props.graphData.sourceBranchColors[branchName]
3338
}
3439
35-
return '#888888'
40+
// 生成一个基于分支名的稳定颜色
41+
// 使用分支名作为唯一标识符来生成一个稳定的哈希值
42+
let hash = 0;
43+
for (let i = 0; i < branchName.length; i++) {
44+
hash = ((hash << 5) - hash) + branchName.charCodeAt(i);
45+
hash = hash & hash; // 转换为32位整数
46+
}
47+
48+
// 使用哈希值选择一个颜色
49+
// 黄金比例法生成分散均匀的颜色
50+
const hue = (hash % 360 + 360) % 360; // 确保是正数
51+
return `hsl(${hue}, 70%, 45%)`; // 使用 HSL 颜色格式
3652
}
3753
3854
// 解析Git引用字符串为数组
@@ -100,6 +116,33 @@ function handleDoubleClick() {
100116
console.error('Error sending commit details:', error)
101117
}
102118
}
119+
120+
// 计算在当前提交处结束(不应向上延伸)的分支
121+
const branchEndingUp = computed(() => {
122+
if (!props.graphData) return []
123+
124+
const endingBranches = []
125+
126+
// 当前提交的相关分支
127+
if (props.graphData.branch) {
128+
// 当前分支如果没有父提交,则结束于此
129+
if (!props.commit.parents || props.commit.parents.length === 0) {
130+
endingBranches.push(props.graphData.branch)
131+
}
132+
}
133+
134+
// 源分支在此结束
135+
if (props.graphData.sourceBranches && props.graphData.sourceBranches.length) {
136+
props.graphData.sourceBranches.forEach(branch => {
137+
// 如果源分支不等于主分支,则在此结束
138+
if (branch !== props.graphData.branch) {
139+
endingBranches.push(branch)
140+
}
141+
})
142+
}
143+
144+
return endingBranches
145+
})
103146
</script>
104147

105148
<template>
@@ -117,7 +160,11 @@ function handleDoubleClick() {
117160
<span
118161
class="ref-item"
119162
:class="{ tag: ref.isTag, branch: !ref.isTag }"
120-
:style="{ color: !ref.isTag ? getBranchColorFromGraphData(ref.name) : undefined, borderColor: !ref.isTag ? getBranchColorFromGraphData(ref.name) : undefined }"
163+
:style="{
164+
backgroundColor: !ref.isTag ? `${getBranchColorFromGraphData(ref.name)}20` : undefined,
165+
color: !ref.isTag ? getBranchColorFromGraphData(ref.name) : undefined,
166+
borderColor: !ref.isTag ? getBranchColorFromGraphData(ref.name) : undefined
167+
}"
121168
>
122169
{{ ref.displayName }}
123170
</span>
@@ -126,7 +173,12 @@ function handleDoubleClick() {
126173
</template>
127174
</div>
128175
<div class="branch-col commit-cell" :style="{ width: `${columnWidths.branch}px` }">
129-
<GitGraph :graph-data="graphData" :active-branches="activeBranches" :is-selected="isSelected" />
176+
<GitGraph
177+
:graph-data="graphData"
178+
:active-branches="activeBranches"
179+
:is-selected="isSelected"
180+
:branch-ending-up="branchEndingUp"
181+
/>
130182
</div>
131183
<span
132184
class="hash-col commit-cell" :style="{ width: `${columnWidths.hash}px` }" @mouseenter="hoveredCell = 'hash'"
@@ -231,6 +283,7 @@ function handleDoubleClick() {
231283
.branch-name-col {
232284
white-space: normal;
233285
overflow: visible;
286+
padding: 0px;
234287
}
235288
236289
.refs-container {

src/views/history/components/CommitTable/index.vue

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@ const activeBranches = computed(() => {
6969
}
7070
})
7171
72+
// 收集所有提交中的分支引用信息
73+
props.commits.forEach(commit => {
74+
if (commit.refs) {
75+
const refsList = commit.refs.split(',').map(ref => ref.trim())
76+
77+
refsList.forEach(ref => {
78+
// 处理各种分支格式
79+
if (!ref.includes('tag:') && !ref.includes('refs/tags/')) {
80+
let branchName = ref
81+
82+
// 清理分支名称
83+
if (ref.includes('refs/heads/')) {
84+
branchName = ref.replace('refs/heads/', '')
85+
}
86+
else if (ref.includes('refs/remotes/')) {
87+
branchName = ref.replace('refs/remotes/', '')
88+
}
89+
90+
branches.add(branchName)
91+
}
92+
})
93+
}
94+
})
95+
7296
return Array.from(branches)
7397
})
7498

0 commit comments

Comments
 (0)