@@ -22,6 +22,7 @@ def __init__(self, remote: str = None, branch: str = None):
2222 self .remote = remote
2323 self .branch = branch
2424 settings .max_branches_per_commit = 2
25+ settings .color_by = "notlocal"
2526
2627 if self .remote and self .remote not in self .repo .remotes :
2728 print ("git-sim error: no remote with name '" + self .remote + "'" )
@@ -66,52 +67,76 @@ def construct(self):
6667 self .repo .remotes [0 ].set_url (new_dir2 )
6768
6869 # Push the local clone into the local clone of the remote repo
70+ push_result = 0
6971 try :
7072 self .repo .git .push (self .remote , self .branch )
71- head_commit = self .get_commit ()
72- self .parse_commits (head_commit )
73- self .recenter_frame ()
74- self .scale_frame ()
75-
76- # But if we get merge conflicts...
73+ # If push fails...
7774 except git .GitCommandError as e :
78- if "CONFLICT" in e .stdout :
79- # Restrict to default number of commits since we'll show the table/zones
80- self .n = self .n_default
81-
82- # Get list of conflicted filenames
83- self .conflicted_files = re .findall (r"Merge conflict in (.+)" , e .stdout )
84-
85- head_commit = self .get_commit ()
86- self .parse_commits (head_commit )
87- self .recenter_frame ()
88- self .scale_frame ()
89-
90- # Show the conflicted files names in the table/zones
91- self .vsplit_frame ()
92- self .setup_and_draw_zones (
93- first_column_name = "----" ,
94- second_column_name = "Conflicted files" ,
95- third_column_name = "----" ,
96- )
97- else :
98- print (f"git-sim error: git push failed: { e } " )
99- self .repo .git .clear_cache ()
100- shutil .rmtree (new_dir , onerror = del_rw )
101- shutil .rmtree (new_dir2 , onerror = del_rw )
102- sys .exit (1 )
103-
75+ print (f"git-sim error: git push failed: { e .stderr } " )
76+ if "rejected" in e .stderr and "fetch first" in e .stderr :
77+ push_result = 1
78+ self .orig_repo = self .repo
79+ self .repo = self .remote_repo
80+
81+ head_commit = self .get_commit ()
82+ self .parse_commits (head_commit , make_branches_remote = (self .remote if self .remote else self .repo .remotes [0 ].name ))
83+ self .recenter_frame ()
84+ self .scale_frame ()
85+ self .failed_push (push_result )
10486 self .color_by ()
10587 self .fadeout ()
10688 self .show_outro ()
10789
10890 # Unlink the program from the filesystem
10991 self .repo .git .clear_cache ()
92+ if self .orig_repo :
93+ self .orig_repo .git .clear_cache ()
11094
11195 # Delete the local clones
11296 shutil .rmtree (new_dir , onerror = del_rw )
11397 shutil .rmtree (new_dir2 , onerror = del_rw )
11498
99+ def failed_push (self , push_result ):
100+ if push_result == 1 :
101+ text1 = m .Text (
102+ f"'git push' failed since remote has commits that don't exist locally, run 'git pull' and try again" ,
103+ font = "Monospace" ,
104+ font_size = 20 ,
105+ color = self .fontColor ,
106+ weight = m .BOLD ,
107+ )
108+ text1 .move_to ([self .camera .frame .get_center ()[0 ], 4 , 0 ])
109+
110+ text2 = m .Text (
111+ f"Gold commits exist in remote repo, but not locally (need to be pulled)" ,
112+ font = "Monospace" ,
113+ font_size = 20 ,
114+ color = m .GOLD ,
115+ weight = m .BOLD ,
116+ )
117+ text2 .move_to (text1 .get_center ()).shift (m .DOWN / 2 )
118+
119+ text3 = m .Text (
120+ f"Red commits exist in both local and remote repos" ,
121+ font = "Monospace" ,
122+ font_size = 20 ,
123+ color = m .RED ,
124+ weight = m .BOLD ,
125+ )
126+ text3 .move_to (text2 .get_center ()).shift (m .DOWN / 2 )
127+
128+ self .toFadeOut .add (text1 )
129+ self .toFadeOut .add (text2 )
130+ self .toFadeOut .add (text3 )
131+ self .recenter_frame ()
132+ self .scale_frame ()
133+ if settings .animate :
134+ self .play (m .AddTextLetterByLetter (text1 ), m .AddTextLetterByLetter (text2 ), m .AddTextLetterByLetter (text3 ))
135+ else :
136+ self .add (text1 , text2 , text3 )
137+
138+
139+
115140def del_rw (action , name , exc ):
116141 os .chmod (name , stat .S_IWRITE )
117142 os .remove (name )
0 commit comments