Simplify merge handling, add more tests

This further simplifies handling of merges, which was made correct in commit 675e79c. We now
correctly set both source and destination commit references, where an empty source reference means
the base of the branch being merged into.
This commit is contained in:
Alex Palaistras 2019-08-06 11:49:40 +01:00
parent 472cd57dcd
commit 72d1059416
6 changed files with 112 additions and 32 deletions

View File

@ -13,7 +13,7 @@ CMD = $(CURDIR)/grawkit
# Default executables to use.
SHELL = /bin/bash
DIFF = $(shell which colordiff || which diff)
DIFF = $(shell which colordiff 2> /dev/null || which diff)
# Test files to execute.
TESTS ?= $(shell find tests/*)

34
grawkit
View File

@ -25,9 +25,9 @@ function add_branch(name) {
# Branches created before the first commit is established extend to the
# beginning of time.
if (state["HEAD"] != "") {
branches[len["branches"],"merges"] = state["branch"] "|" state["HEAD"]
branches[len["branches"],"merges"] = state["branch"] "||" state["HEAD"]
} else {
branches[len["branches"],"merges"] = len["branches"] "|0"
branches[len["branches"],"merges"] = len["branches"] "||0"
}
len["branches"] += 1
@ -131,7 +131,7 @@ function render_label(idx, class, name, _, buf, tw, w, h, hspc, vspc) {
# > Function `render_merge` renders merge paths for a branch pointed to by `idx`.
function render_merge(idx, _, buf, tmp, refs, fields, m, i, hspc) {
# Do not render merge paths for branch with no commits.
if (branches[idx,"merges"] == "") {
if (branches[idx,"refs"] == "") {
return
}
@ -148,24 +148,15 @@ function render_merge(idx, _, buf, tmp, refs, fields, m, i, hspc) {
for (i in fields) {
split(fields[i], m, "|")
if(length(m) == 2) {
# this is actually added by "git branch" command
# Add starting point to source branch ending point.
tmp = "M" m[1] * style["branch/spacing"] "," m[2] * style["commit/spacing"]
# Add starting point to target branch ending point.
tmp = "M" m[1] * style["branch/spacing"] "," m[3] * style["commit/spacing"]
# Add Bezier curve leading to target branch starting point.
tmp = tmp " C" hspc "," m[2] * style["commit/spacing"]
tmp = tmp " " hspc "," m[2] * style["commit/spacing"]
tmp = tmp " " hspc "," refs[1] * style["commit/spacing"]
} else {
# Add starting point to target branch ending point.
tmp = "M" m[1] * style["branch/spacing"] "," m[3] * style["commit/spacing"]
# Add Bezier curve leading to specific commit from source branch.
tmp = tmp " C" hspc "," m[3] * style["commit/spacing"]
tmp = tmp " " hspc "," m[3] * style["commit/spacing"]
# Add Bezier curve leading to specific commit from source branch.
tmp = tmp " C" hspc "," m[3] * style["commit/spacing"]
tmp = tmp " " hspc "," m[3] * style["commit/spacing"]
tmp = tmp " " hspc "," m[2] * style["commit/spacing"]
}
# Set default starting point for merge to beginning of branch, if none is set.
tmp = tmp " " hspc "," ((m[2] == "") ? refs[1] : m[2]) * style["commit/spacing"]
# Draw the path.
buf = buf "\n\t\t" sprintf(svg["path"], tmp)
@ -240,7 +231,7 @@ BEGIN {
# Branch definitions.
branches[0,"name"] = "master"
branches[0,"refs"] = ""
branches[0,"merges"] = "0|0"
branches[0,"merges"] = "0||0"
branches[0,"tags"] = ""
len["branches"] = 1
@ -352,9 +343,10 @@ $0 ~ rule["merge"] {
add_commit("merge", "Merge commit")
# Add merge reference from last commit in source branch to target branch.
# branch|from-commit|to-commit
# Format: to-branch|from-commit|to-commit
split(branches[i,"refs"], refs, ",")
merge = state["branch"] "|" refs[length(refs)] "|" state["HEAD"]
if (branches[i,"merges"] == "") {
branches[i,"merges"] = merge
} else {

View File

@ -29,9 +29,5 @@
}
.branch-master {stroke: #002b36; fill: #002b36}
]]></style>
<g class="merge">
<g class="branch-master">
<path class="branch" d="M0,0 C0,0 0,0 0,0" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 496 B

View File

@ -62,7 +62,7 @@ git commit
</g>
<g class="branch-test-second">
<path class="branch" d="M0,50 C100,50 100,50 100,200" />
<path class="branch" d="M0,300 C100,300 100,300 100,200" />
<path class="branch" d="M0,300 C100,300 100,300 100,250" />
</g>
<g class="branch-test-first">
<path class="branch" d="M0,50 C50,50 50,50 50,150" />

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -66,14 +66,11 @@ git merge feature/ZZ-704_take-it-to-the-limit
</g>
<g class="branch-feature-xyz-12-fix-foo">
<path class="branch" d="M50,50 C100,50 100,50 100,100" />
<path class="branch" d="M50,250 C100,250 100,250 100,100" />
<path class="branch" d="M50,250 C100,250 100,250 100,150" />
</g>
<g class="branch-develop">
<path class="branch" d="M50,0 C50,0 50,0 50,50" />
</g>
<g class="branch-master">
<path class="branch" d="M0,0 C0,0 0,0 0,0" />
</g>
</g>
<g class="branch-feature-abc-66-make-bar">
<path class="branch" d="M200,300 L200,350" />

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

95
tests/07-multi-merge.svg Normal file
View File

@ -0,0 +1,95 @@
<!--
git commit
git branch first
git branch second
git checkout first
git commit
git checkout second
git commit
git commit
git checkout first
git merge second
git checkout second
git commit
git commit
git checkout master
git merge second
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 212 420">
<style type="text/css"><![CDATA[
.branch {
fill: none;
stroke-width: 10;
stroke-linecap: round;
}
.commit {
fill: #fff;
stroke-width: 5;
}
.label-tag {
fill: #333;
}
.label-rect {
stroke: none;
}
.label-text {
font-family: Inconsolata, Consolas, monospace;
font-size: 14px;
fill: #fff;
stroke: none;
}
.branch-master {stroke: #002b36; fill: #002b36}
.branch-first {stroke: #268bd2; fill: #268bd2}
.branch-second {stroke: #859900; fill: #859900}
]]></style>
<g class="merge">
<g class="branch-second">
<path class="branch" d="M0,50 C100,50 100,50 100,150" />
<path class="branch" d="M50,250 C100,250 100,250 100,200" />
<path class="branch" d="M0,400 C100,400 100,400 100,350" />
</g>
<g class="branch-first">
<path class="branch" d="M0,50 C50,50 50,50 50,100" />
</g>
<g class="branch-master">
<path class="branch" d="M0,0 C0,0 0,0 0,50" />
</g>
</g>
<g class="branch-second">
<path class="branch" d="M100,150 L100,350" />
<circle class="commit" cx="100" cy="150" r="7.5" />
<circle class="commit" cx="100" cy="200" r="7.5" />
<circle class="commit" cx="100" cy="300" r="7.5" />
<circle class="commit" cx="100" cy="350" r="7.5" />
<g class="label-branch" transform="translate(150,350)">
<rect x="0" y="-14" width="52" height="24" rx="3" class="label-rect" />
<text x="5" y="2" textLength="42" class="label-text">second</text>
</g>
</g>
<g class="branch-first">
<path class="branch" d="M50,100 L50,250" />
<circle class="commit" cx="50" cy="100" r="7.5" />
<circle class="commit" cx="50" cy="250" r="7.5" />
<g class="label-branch" transform="translate(150,250)">
<rect x="0" y="-14" width="45" height="24" rx="3" class="label-rect" />
<text x="5" y="2" textLength="35" class="label-text">first</text>
</g>
</g>
<g class="branch-master">
<path class="branch" d="M0,50 L0,400" />
<circle class="commit" cx="0" cy="50" r="7.5" />
<circle class="commit" cx="0" cy="400" r="7.5" />
<g class="label-branch" transform="translate(150,400)">
<rect x="0" y="-14" width="52" height="24" rx="3" class="label-rect" />
<text x="5" y="2" textLength="42" class="label-text">master</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB