Skip to content

Commit 88bf60d

Browse files
Detect and display filenames in merge conflicts
Signed-off-by: Jacob Stopak <jacob@initialcommit.io>
1 parent eaac208 commit 88bf60d

File tree

1 file changed

+83
-18
lines changed

1 file changed

+83
-18
lines changed

git_sim/merge.py

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import sys
2-
from argparse import Namespace
2+
import os
33

44
import git
55
import manim as m
66
import numpy
7+
import tempfile
8+
import shutil
9+
import stat
710

811
from git_sim.git_sim_base_command import GitSimBaseCommand
912
from git_sim.settings import settings
@@ -105,23 +108,85 @@ def construct(self):
105108
self.color_by()
106109

107110
else:
108-
self.parse_commits(head_commit)
109-
self.parse_commits(branch_commit, shift=4 * m.DOWN)
110-
self.parse_all()
111-
self.center_frame_on_commit(head_commit)
112-
self.setup_and_draw_parent(
113-
head_commit,
114-
"Merge commit",
115-
shift=2 * m.DOWN,
116-
draw_arrow=False,
117-
color=m.GRAY,
118-
)
119-
self.draw_arrow_between_commits("abcdef", branch_commit.hexsha)
120-
self.draw_arrow_between_commits("abcdef", head_commit.hexsha)
121-
self.recenter_frame()
122-
self.scale_frame()
123-
self.reset_head_branch("abcdef")
124-
self.color_by(offset=2)
111+
merge_result, new_dir = self.check_merge_conflict(self.repo.active_branch.name, self.branch)
112+
if merge_result:
113+
self.parse_commits(head_commit)
114+
self.recenter_frame()
115+
self.scale_frame()
116+
117+
# Show the conflicted files names in the table/zones
118+
self.vsplit_frame()
119+
self.setup_and_draw_zones(
120+
first_column_name="----",
121+
second_column_name="Conflicted files",
122+
third_column_name="----",
123+
)
124+
self.color_by()
125+
else:
126+
self.parse_commits(head_commit)
127+
self.parse_commits(branch_commit, shift=4 * m.DOWN)
128+
self.parse_all()
129+
self.center_frame_on_commit(head_commit)
130+
self.setup_and_draw_parent(
131+
head_commit,
132+
"Merge commit",
133+
shift=2 * m.DOWN,
134+
draw_arrow=False,
135+
color=m.GRAY,
136+
)
137+
self.draw_arrow_between_commits("abcdef", branch_commit.hexsha)
138+
self.draw_arrow_between_commits("abcdef", head_commit.hexsha)
139+
self.recenter_frame()
140+
self.scale_frame()
141+
self.reset_head_branch("abcdef")
142+
self.color_by(offset=2)
125143

126144
self.fadeout()
127145
self.show_outro()
146+
147+
# Unlink the program from the filesystem
148+
self.repo.git.clear_cache()
149+
150+
# Delete the local clone
151+
shutil.rmtree(new_dir, onerror=del_rw)
152+
153+
154+
def check_merge_conflict(self, branch1, branch2):
155+
git_root = self.repo.git.rev_parse("--show-toplevel")
156+
repo_name = os.path.basename(self.repo.working_dir)
157+
new_dir = os.path.join(tempfile.gettempdir(), "git_sim", repo_name)
158+
159+
orig_remotes = self.repo.remotes
160+
self.repo = git.Repo.clone_from(git_root, new_dir, no_hardlinks=True)
161+
self.repo.git.checkout(branch2)
162+
self.repo.git.checkout(branch1)
163+
164+
try:
165+
self.repo.git.merge(branch2)
166+
except git.GitCommandError as e:
167+
if "CONFLICT" in e.stdout:
168+
self.conflicted_files = []
169+
self.n = 5
170+
for entry in self.repo.index.entries:
171+
if len(entry) == 2 and entry[1] > 0:
172+
self.conflicted_files.append(entry[0])
173+
return 1, new_dir
174+
return 0, new_dir
175+
176+
# Override to display conflicted filenames
177+
def populate_zones(
178+
self,
179+
firstColumnFileNames,
180+
secondColumnFileNames,
181+
thirdColumnFileNames,
182+
firstColumnArrowMap={},
183+
secondColumnArrowMap={},
184+
thirdColumnArrowMap={},
185+
):
186+
for filename in self.conflicted_files:
187+
secondColumnFileNames.add(filename)
188+
189+
190+
def del_rw(action, name, exc):
191+
os.chmod(name, stat.S_IWRITE)
192+
os.remove(name)

0 commit comments

Comments
 (0)