Skip to content

Commit 3533002

Browse files
Refactor all subcommands to accomodate new diverse branching system
Signed-off-by: Jacob Stopak <[email protected]>
1 parent e3afcc8 commit 3533002

File tree

14 files changed

+127
-235
lines changed

14 files changed

+127
-235
lines changed

git_sim/add.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def __init__(self, files: List[str]):
1616
self.hide_first_tag = True
1717
self.allow_no_commits = True
1818
self.files = files
19+
settings.hide_merged_chains = True
1920

2021
try:
2122
self.selected_branches.append(self.repo.active_branch.name)
@@ -37,7 +38,7 @@ def construct(self):
3738

3839
self.show_intro()
3940
self.get_commits()
40-
self.parse_commits(self.commits[0])
41+
self.parse_commits(self.commits[0], 0)
4142
self.recenter_frame()
4243
self.scale_frame()
4344
self.vsplit_frame()

git_sim/branch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def construct(self):
1717

1818
self.show_intro()
1919
self.get_commits()
20-
self.parse_commits(self.commits[0])
20+
self.parse_commits(self.commits[0], 0)
2121
self.recenter_frame()
2222
self.scale_frame()
2323

git_sim/cherrypick.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ def construct(self):
5454

5555
self.show_intro()
5656
self.get_commits()
57-
self.parse_commits(self.commits[0])
57+
self.parse_commits(self.commits[0], 0)
5858
self.orig_commits = self.commits
5959
self.get_commits(start=self.commit)
60-
self.parse_commits(self.commits[0], shift=4 * m.DOWN)
60+
self.parse_commits(self.commits[0], 0, shift=4 * m.DOWN)
6161
self.center_frame_on_commit(self.orig_commits[0])
6262
self.setup_and_draw_parent(
6363
self.orig_commits[0],

git_sim/commit.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def __init__(self, message: str, amend: bool):
1818
self.defaultNumCommits = 4 if not self.amend else 5
1919
self.numCommits = 4 if not self.amend else 5
2020
self.hide_first_tag = True
21+
settings.hide_merged_chains = True
2122

2223
try:
2324
self.selected_branches.append(self.repo.active_branch.name)
@@ -51,7 +52,7 @@ def construct(self):
5152
)
5253
self.commits[0] = amended
5354

54-
self.parse_commits(self.commits[self.i])
55+
self.parse_commits(self.commits[0], 0)
5556
self.center_frame_on_commit(self.commits[0])
5657

5758
if not self.amend:

git_sim/git_sim_base_command.py

Lines changed: 99 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ def __init__(self):
2525
self.trimmed = False
2626
self.prevRef = None
2727
self.topref = None
28-
self.i = 0
2928
self.numCommits = settings.commits
3029
self.defaultNumCommits = settings.commits
3130
self.selected_branches = []
3231
self.stop = False
3332
self.zone_title_offset = 2.6 if platform.system() == "Windows" else 2.6
33+
self.arrow_map = []
3434

3535
self.logo = m.ImageMobject(settings.logo)
3636
self.logo.width = 3
@@ -81,31 +81,50 @@ def get_commits(self, start="HEAD"):
8181
self.get_commits(start=start)
8282

8383
def parse_commits(
84-
self, commit, prevCircle=None, shift=numpy.array([0.0, 0.0, 0.0]), dots=False
84+
self, commit, i, prevCircle=None, shift=numpy.array([0.0, 0.0, 0.0])
8585
):
86-
if self.stop:
87-
return
88-
if self.i < self.numCommits and commit in self.commits:
86+
isNewCommit = commit.hexsha not in self.drawnCommits
87+
88+
if i < self.numCommits and commit in self.commits:
8989
commitId, circle, arrow, hide_refs = self.draw_commit(
90-
commit, prevCircle, shift, dots
90+
commit, i, prevCircle, shift
9191
)
9292

9393
if commit != "dark":
94-
if not hide_refs and not self.stop:
95-
self.draw_head(commit, commitId)
96-
self.draw_branch(commit)
97-
self.draw_tag(commit)
98-
self.draw_arrow(prevCircle, arrow)
99-
if self.stop:
100-
return
101-
if self.i == 0 and len(self.drawnRefs) < 2:
94+
if not hide_refs and isNewCommit:
95+
self.draw_head(commit, i, commitId)
96+
self.draw_branch(commit, i)
97+
self.draw_tag(commit, i)
98+
if (
99+
not isinstance(arrow, m.CurvedArrow)
100+
and [arrow.start.tolist(), arrow.end.tolist()] not in self.arrow_map
101+
):
102+
self.draw_arrow(prevCircle, arrow)
103+
self.arrow_map.append([arrow.start.tolist(), arrow.end.tolist()])
104+
elif (
105+
isinstance(arrow, m.CurvedArrow)
106+
and [arrow.get_start().tolist(), arrow.get_end().tolist()]
107+
not in self.arrow_map
108+
):
109+
self.draw_arrow(prevCircle, arrow)
110+
self.arrow_map.append(
111+
[arrow.get_start().tolist(), arrow.get_end().tolist()]
112+
)
113+
if i == 0 and len(self.drawnRefs) < 2:
102114
self.draw_dark_ref()
103115

104-
if self.i < len(self.commits) - 1:
105-
self.i += 1
106-
self.parse_commits(self.commits[self.i], circle, dots=True)
107-
else:
108-
self.i = 0
116+
if i < self.numCommits: # len(self.commits) - 1:
117+
i += 1
118+
commitParents = list(commit.parents)
119+
if len(commitParents) > 0:
120+
if settings.invert_branches:
121+
commitParents.reverse()
122+
123+
if settings.hide_merged_chains:
124+
self.parse_commits(commitParents[0], i, circle)
125+
else:
126+
for p in range(len(commitParents)):
127+
self.parse_commits(commitParents[p], i, circle)
109128

110129
def show_intro(self):
111130
if settings.animate and settings.show_intro:
@@ -170,9 +189,7 @@ def get_centers(self):
170189
centers.append(commit.get_center())
171190
return centers
172191

173-
def draw_commit(
174-
self, commit, prevCircle, shift=numpy.array([0.0, 0.0, 0.0]), dots=False
175-
):
192+
def draw_commit(self, commit, i, prevCircle, shift=numpy.array([0.0, 0.0, 0.0])):
176193
if commit == "dark":
177194
commitFill = m.WHITE if settings.light_mode else m.BLACK
178195
elif len(commit.parents) <= 1:
@@ -193,29 +210,54 @@ def draw_commit(
193210
prevCircle, m.RIGHT if settings.reverse else m.LEFT, buff=1.5
194211
)
195212

196-
start = (
197-
prevCircle.get_center()
198-
if prevCircle
199-
else (m.LEFT if settings.reverse else m.RIGHT)
200-
)
201-
end = circle.get_center()
213+
while any((circle.get_center() == c).all() for c in self.get_centers()):
214+
circle.next_to(circle, m.DOWN, buff=3.5)
215+
216+
isNewCommit = commit.hexsha not in self.drawnCommits
217+
218+
if isNewCommit:
219+
start = (
220+
prevCircle.get_center()
221+
if prevCircle
222+
else (m.LEFT if settings.reverse else m.RIGHT)
223+
)
224+
end = circle.get_center()
225+
else:
226+
circle.move_to(self.drawnCommits[commit.hexsha].get_center())
227+
start = (
228+
prevCircle.get_center()
229+
if prevCircle
230+
else (m.LEFT if settings.reverse else m.RIGHT)
231+
)
232+
end = self.drawnCommits[commit.hexsha].get_center()
233+
234+
arrow = m.Arrow(start, end, color=self.fontColor)
202235

203236
if commit == "dark":
204237
arrow = m.Arrow(
205238
start, end, color=m.WHITE if settings.light_mode else m.BLACK
206239
)
207-
elif commit.hexsha in self.drawnCommits:
208-
end = self.drawnCommits[commit.hexsha].get_center()
209-
arrow = m.Arrow(start, end, color=self.fontColor)
210-
self.stop = True
211-
else:
212-
arrow = m.Arrow(start, end, color=self.fontColor)
213240

214241
length = numpy.linalg.norm(start - end) - (1.5 if start[1] == end[1] else 3)
215242
arrow.set_length(length)
243+
angle = arrow.get_angle()
244+
lineRect = (
245+
m.Rectangle(height=0.1, width=length, color="#123456")
246+
.move_to(arrow.get_center())
247+
.rotate(angle)
248+
)
249+
250+
for commitCircle in self.drawnCommits.values():
251+
inter = m.Intersection(lineRect, commitCircle)
252+
if inter.has_points():
253+
arrow = m.CurvedArrow(start, end, color=self.fontColor)
254+
if start[1] == end[1]:
255+
arrow.shift(m.UP * 1.25)
256+
if start[0] < end[0] and start[1] == end[1]:
257+
arrow.flip(m.RIGHT).shift(m.UP)
216258

217259
commitId, commitMessage, commit, hide_refs = self.build_commit_id_and_message(
218-
commit, dots
260+
commit, i
219261
)
220262
commitId.next_to(circle, m.UP)
221263

@@ -231,15 +273,15 @@ def draw_commit(
231273
color=self.fontColor,
232274
).next_to(circle, m.DOWN)
233275

234-
if settings.animate and commit != "dark" and not self.stop:
276+
if settings.animate and commit != "dark" and isNewCommit:
235277
self.play(
236278
self.camera.frame.animate.move_to(circle.get_center()),
237279
m.Create(circle),
238280
m.AddTextLetterByLetter(commitId),
239281
m.AddTextLetterByLetter(message),
240282
run_time=1 / settings.speed,
241283
)
242-
elif not self.stop:
284+
elif isNewCommit:
243285
self.add(circle, commitId, message)
244286
else:
245287
return commitId, circle, arrow, hide_refs
@@ -252,7 +294,17 @@ def draw_commit(
252294

253295
return commitId, circle, arrow, hide_refs
254296

255-
def build_commit_id_and_message(self, commit, dots=False):
297+
def get_nonparent_branch_names(self):
298+
branches = [b for b in self.repo.heads if not b.name.startswith("remotes/")]
299+
exclude = []
300+
for b1 in branches:
301+
for b2 in branches:
302+
if b1.name != b2.name:
303+
if self.repo.is_ancestor(b1.commit, b2.commit):
304+
exclude.append(b1.name)
305+
return [b for b in branches if b.name not in exclude]
306+
307+
def build_commit_id_and_message(self, commit, i, dots=False):
256308
hide_refs = False
257309
if commit == "dark":
258310
commitId = m.Text("", font="Monospace", font_size=20, color=self.fontColor)
@@ -276,7 +328,7 @@ def build_commit_id_and_message(self, commit, dots=False):
276328
commitMessage = commit.message.split("\n")[0][:40].replace("\n", " ")
277329
return commitId, commitMessage, commit, hide_refs
278330

279-
def draw_head(self, commit, commitId):
331+
def draw_head(self, commit, i, commitId):
280332
if commit.hexsha == self.repo.head.commit.hexsha:
281333
headbox = m.Rectangle(color=m.BLUE, fill_color=m.BLUE, fill_opacity=0.25)
282334
headbox.width = 1
@@ -297,10 +349,10 @@ def draw_head(self, commit, commitId):
297349
self.drawnRefs["HEAD"] = head
298350
self.prevRef = head
299351

300-
if self.i == 0:
352+
if i == 0:
301353
self.topref = self.prevRef
302354

303-
def draw_branch(self, commit):
355+
def draw_branch(self, commit, i):
304356
x = 0
305357

306358
remote_tracking_branches = self.get_remote_tracking_branches()
@@ -348,17 +400,17 @@ def draw_branch(self, commit):
348400
self.toFadeOut.add(branchRec, branchText)
349401
self.drawnRefs[branch] = fullbranch
350402

351-
if self.i == 0:
403+
if i == 0:
352404
self.topref = self.prevRef
353405

354406
x += 1
355407
if x >= settings.max_branches_per_commit:
356408
return
357409

358-
def draw_tag(self, commit):
410+
def draw_tag(self, commit, i):
359411
x = 0
360412

361-
if settings.hide_first_tag and self.i == 0:
413+
if settings.hide_first_tag and i == 0:
362414
return
363415

364416
for tag in self.repo.tags:
@@ -394,7 +446,7 @@ def draw_tag(self, commit):
394446

395447
self.toFadeOut.add(tagRec, tagText)
396448

397-
if self.i == 0:
449+
if i == 0:
398450
self.topref = self.prevRef
399451

400452
x += 1
@@ -878,7 +930,7 @@ def get_nondark_commits(self):
878930
nondark_commits.append(commit)
879931
return nondark_commits
880932

881-
def draw_ref(self, commit, top, text="HEAD", color=m.BLUE):
933+
def draw_ref(self, commit, i, top, text="HEAD", color=m.BLUE):
882934
refText = m.Text(text, font="Monospace", font_size=20, color=self.fontColor)
883935
refbox = m.Rectangle(
884936
color=color,
@@ -901,7 +953,7 @@ def draw_ref(self, commit, top, text="HEAD", color=m.BLUE):
901953
self.drawnRefs[text] = ref
902954
self.prevRef = ref
903955

904-
if self.i == 0:
956+
if i == 0:
905957
self.topref = self.prevRef
906958

907959
def draw_dark_ref(self):

0 commit comments

Comments
 (0)