gui.py 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672
  1. import time
  2. import threading
  3. import tkinter
  4. import os
  5. import tkinter.messagebox
  6. from tkinter import ttk
  7. from newtkinter import asksaveasfilename, askdirectory, askopenfilenames
  8. from tkinter.scrolledtext import ScrolledText
  9. import gitrepo.template
  10. from gitrepo import controller
  11. def git_main():
  12. global SCREEN, git, PATH, bg_color, buttom_color, word_color, repo_list, last_name, file_list, FONT
  13. SCREEN.mainloop()
  14. def branch_new(): # 克隆仓库
  15. global branch_name, branch_new_name
  16. new_name = branch_new_name.get()
  17. old_name = branch_name.get()
  18. cli(git.rename_branch, (get_repo_name(), old_name, new_name), show_screen=False)
  19. update_repo_box()
  20. def clone_git(): # 克隆仓库
  21. global clone_repo
  22. new_dir = askdirectory(title="选择仓库地址")
  23. if new_dir == "":
  24. return False
  25. name = git.clone_repo(new_dir)
  26. clone_core(name, clone_repo.get())
  27. update_repo_box()
  28. def clone_core(name, url):
  29. cli(
  30. git.clone,
  31. (name, url),
  32. break_time=0,
  33. tip_text=f"{url}:正在执行克隆操作",
  34. is_threaded_refresh=True,
  35. is_asynchronous_display=True,
  36. )
  37. git.after_clone(name)
  38. update_git_file_last()
  39. def customize():
  40. global git, customize_input, threaded_refresh, asynchronous_display
  41. command = customize_input.get()
  42. cli(
  43. git.customize_command,
  44. (get_repo_name(), command),
  45. break_time=0,
  46. tip_text=f"{command}:操作进行中",
  47. is_threaded_refresh=bool(threaded_refresh.get()),
  48. is_asynchronous_display=bool(asynchronous_display.get()),
  49. )
  50. update_git_file_last()
  51. def fetch_remote():
  52. global remote_branch, local_branch, git, remote_name
  53. branch = remote_branch.get()
  54. remote = remote_name.get()
  55. local = local_branch.get()
  56. cli(
  57. git.fetch,
  58. (get_repo_name(), local, remote, branch),
  59. break_time=0,
  60. tip_text=f"此操作需要连接远程仓库,请稍等...",
  61. is_threaded_refresh=True,
  62. is_asynchronous_display=True,
  63. )
  64. update_git_file_last()
  65. def del_tag():
  66. global git, remote_name, tag_name
  67. tag = tag_name.get()
  68. cli(git.del_tag, (get_repo_name(), tag))
  69. update_git_file_last()
  70. def del_remote_branch():
  71. global git, remote_name, tag_name
  72. remote = remote_name.get()
  73. branch = remote_branch.get()
  74. cli(
  75. git.del_branch_remote,
  76. (get_repo_name(), remote, branch),
  77. break_time=0,
  78. tip_text=f"此操作需要连接远程仓库,请稍等...",
  79. is_threaded_refresh=True,
  80. is_asynchronous_display=True,
  81. )
  82. update_git_file_last()
  83. def del_remote_tag():
  84. global git, remote_name, tag_name
  85. remoto = remote_name.get()
  86. tag = tag_name.get()
  87. cli(
  88. git.del_tag_remote,
  89. (get_repo_name(), remoto, tag),
  90. break_time=0,
  91. tip_text=f"此操作需要连接远程仓库,请稍等...",
  92. is_threaded_refresh=True,
  93. is_asynchronous_display=True,
  94. )
  95. update_git_file_last()
  96. def push_all_tag():
  97. global git, remote_name
  98. remoto = remote_name.get()
  99. cli(
  100. git.push_all_tag,
  101. (get_repo_name(), remoto),
  102. break_time=0,
  103. tip_text=f"此操作需要连接远程仓库,请稍等...",
  104. is_threaded_refresh=True,
  105. is_asynchronous_display=True,
  106. )
  107. update_git_file_last()
  108. def push_tag():
  109. global tag_name, git, remote_name
  110. tag_name = tag_name.get()
  111. remoto = remote_name.get()
  112. cli(
  113. git.push_tag,
  114. (get_repo_name(), tag_name, remoto),
  115. break_time=0,
  116. tip_text=f"此操作需要连接远程仓库,请稍等...",
  117. is_threaded_refresh=True,
  118. is_asynchronous_display=True,
  119. )
  120. update_git_file_last()
  121. def add_tag():
  122. global tag_name, git, commit, tag_message
  123. tag_name = tag_name.get()
  124. commit = tag_commit.get()
  125. tag_message = tag_message.get()
  126. cli(
  127. git.add_tag, (get_repo_name(), tag_name, commit, tag_message), show_screen=False
  128. )
  129. update_git_file_last()
  130. def show_tag(type_):
  131. global show_search_key, git
  132. key = show_search_key.get()
  133. cli(
  134. {1: git.get_tag_list, 0: git.search_commit}.get(type_, git.search_commit),
  135. (get_repo_name(), key),
  136. )
  137. update_git_file_last()
  138. def pull_push_remote(type_):
  139. global remote_branch, local_branch, git, allow_history, remote_name
  140. branch = remote_branch.get()
  141. remote = remote_name.get()
  142. local = local_branch.get()
  143. allow = bool(allow_history.get())
  144. parameters_u = bool(push_bind.get())
  145. parameters_f = tkinter.messagebox.askokcancel("提示", f"是否需要强制推送?(强制推送不被建议)")
  146. cli(
  147. {0: git.pull_from_remote, 1: git.push_to_remote}.get(
  148. type_, git.pull_from_remote
  149. ),
  150. (get_repo_name(), local, remote, branch, allow, parameters_u, parameters_f),
  151. break_time=0,
  152. tip_text=f"此操作需要连接远程仓库,请稍等...",
  153. is_threaded_refresh=True,
  154. is_asynchronous_display=True,
  155. )
  156. update_git_file_last()
  157. def bind_remote_branch():
  158. global remote_branch, local_branch, git
  159. remote = remote_branch.get()
  160. local = local_branch.get()
  161. cli(git.bind_branch, (get_repo_name(), local, remote))
  162. update_git_file_last()
  163. def del_remote():
  164. global remote_ssh, remote_name, git
  165. name = remote_name.get()
  166. cli(git.del_remote, (get_repo_name(), name))
  167. update_git_file_last()
  168. def add_remote():
  169. global remote_ssh, remote_name, git
  170. ssh = remote_ssh.get()
  171. name = remote_name.get()
  172. cli(git.remote_add, (get_repo_name(), ssh, name))
  173. update_git_file_last()
  174. def cherry_pick():
  175. global commit, git
  176. commit = commit.get()
  177. cli(git.cherry_pick, (get_repo_name(), commit))
  178. update_git_file_last()
  179. def open_stash(type_):
  180. global stash_name, git
  181. stash_num = stash_name.get()
  182. if stash_num == "":
  183. stash_num = "0"
  184. cli([git.drop_stash, git.apply_stash][type_], (get_repo_name(), stash_num))
  185. update_git_file_last()
  186. def branch_merge():
  187. global branch_name, git, no_fast_forward, commit_message
  188. message = commit_message.get()
  189. parameters_no_ff = not bool(no_fast_forward.get()) # 对于no_ff来说,True - 使用快速合并,所以要翻转
  190. if message.replace(" ", "") == "" and parameters_no_ff:
  191. tkinter.messagebox.showinfo(
  192. "警告!", "非常遗憾,我不同意你commit而不添加任何描述!\n描述是很重要的!" "(如果你不想添加描述,请使用快速合并,但我并不建议!)"
  193. )
  194. return False
  195. name = branch_name.get()
  196. cli(git.merge_branch, (get_repo_name(), name, parameters_no_ff, message))
  197. update_git_file_last()
  198. def del_branch(type_):
  199. global branch_name, git
  200. name = branch_name.get()
  201. cli(git.del_branch, (get_repo_name(), name, type_))
  202. update_git_file_last()
  203. def switch_branch():
  204. global branch_name, git
  205. name = branch_name.get()
  206. cli(git.switch_branch, (get_repo_name(), name), break_time=1, show_screen=False)
  207. update_git_file_last()
  208. def add_new_branch():
  209. global branch_name, git, origin_branch
  210. name = branch_name.get()
  211. origin = origin_branch.get()
  212. cli(
  213. git.new_branch, (get_repo_name(), name, origin), break_time=1, show_screen=False
  214. )
  215. update_git_file_last()
  216. def remove_file():
  217. global git, head, file_list
  218. if file_list == []:
  219. return False
  220. cli(git.rm, (get_repo_name(), file_list))
  221. update_git_file_last()
  222. def checkout_file(): # 从暂存区、仓库返回文件
  223. global git, head, file_list
  224. if file_list == []:
  225. return False
  226. cli(git.checkout_version, (get_repo_name(), file_list))
  227. update_git_file_last()
  228. def reset_file(): # 使用reset回退文件
  229. global git, head, reset_type, file_list
  230. repo_head = head.get()
  231. if repo_head == "":
  232. repo_head = "HEAD~1"
  233. cli(git.back_version_file, (get_repo_name(), repo_head, file_list))
  234. update_git_file_last()
  235. def reset_head():
  236. global git, head, reset_type
  237. repo_head = head.get()
  238. if repo_head == "":
  239. repo_head = "HEAD~1"
  240. the_reset_type = reset_type.get()
  241. cli(git.back_version, (get_repo_name(), repo_head, the_reset_type))
  242. update_git_file_last()
  243. def cli(
  244. func,
  245. args,
  246. name="CoTan Git",
  247. break_time=0,
  248. show_screen=True,
  249. tip_text="",
  250. is_threaded_refresh=False,
  251. is_asynchronous_display=False,
  252. ):
  253. command_thread = func(*args)
  254. format_flat = True
  255. stop_key = gitrepo.template.stop_key
  256. def save_to_txt():
  257. nonlocal data
  258. dic = asksaveasfilename(title="选择文件保存位置", filetypes=[("TXT", ".txt")])
  259. try:
  260. if dic == "":
  261. return False
  262. if dic[-4] == ".txt":
  263. pass
  264. else:
  265. raise Exception
  266. except BaseException:
  267. dic += ".txt"
  268. with open(dic, "w", encoding="utf-8") as f:
  269. f.write(data)
  270. keep_button = True
  271. stop_button = True
  272. def update_button():
  273. if not keep_button:
  274. button_list[1].config(state=tkinter.DISABLED)
  275. if not stop_button:
  276. button_list[0].config(state=tkinter.DISABLED)
  277. def stop():
  278. nonlocal start, keep_button, stop_button
  279. start = 0
  280. stop_button = False
  281. keep_button = False
  282. update_button()
  283. def keep():
  284. nonlocal start, keep_button
  285. start = float("inf")
  286. keep_button = False
  287. update_button()
  288. def pipe():
  289. pass
  290. def format():
  291. nonlocal text, out_data, data, format_flat
  292. text.clear()
  293. if format_flat:
  294. text.insert(tkinter.END, data)
  295. else:
  296. text.insert(tkinter.END, out_data)
  297. format_flat = not format_flat
  298. start = time.time()
  299. data = ""
  300. out_data = "" # 包含out的data
  301. if show_screen:
  302. text, cli_screen, button_list = show_cli(
  303. save_to_txt, stop, keep, format, pipe, name=name
  304. ) # [close,keep]
  305. update_button()
  306. if tip_text != "":
  307. text.insert("0.0", f"载入前提示>>> {tip_text}\n")
  308. out_data += f"载入前提示>>> {tip_text}\n"
  309. data += f"{tip_text}\n"
  310. cli_screen.update()
  311. else:
  312. u = threading.Thread(target=progress_bar)
  313. u.start()
  314. SCREEN.update()
  315. def update_screen():
  316. nonlocal start
  317. while True:
  318. try:
  319. SCREEN.update()
  320. if show_screen:
  321. try:
  322. cli_screen.update()
  323. except BaseException:
  324. pass
  325. if time.time() - start >= break_time and break_time != 0:
  326. raise Exception
  327. elif break_time == 0 and start == 0:
  328. raise Exception
  329. except BaseException:
  330. start = 0
  331. break
  332. if is_threaded_refresh or not is_asynchronous_display:
  333. # 如果没有启动到多进程的效果,请检查Update是不是加了(),这里需要回调
  334. threaded_update = threading.Thread(target=update_screen)
  335. threaded_update.start()
  336. if is_asynchronous_display: # 等待后显示
  337. if break_time == 0:
  338. break_ti = None # 此处break_ti是为了别面覆盖break_time,因为Update进程需要用
  339. else:
  340. break_ti = break_time
  341. def wait_command_thread():
  342. nonlocal start
  343. command_thread.wait(break_ti)
  344. start = 0
  345. threaded_update = threading.Thread(
  346. target=wait_command_thread
  347. ) # 这么做不是多此一举,如果没有wait,进程并不会退出
  348. threaded_update.start()
  349. update_screen() # 遇到sleep等主线程阻塞,top.update等会阻塞子线程,因此,必须保证主线程不会被wait所阻塞
  350. out = command_thread.stdout.read().split("\n")
  351. for i in out:
  352. if show_screen:
  353. try: # 如果界面被关掉了,会报错
  354. cli_screen.title(f"{name} : 运行中")
  355. except BaseException:
  356. text, cli_screen, button_list = show_cli(
  357. save_to_txt, stop, keep, format, pipe, name=f"{name} : 运行中"
  358. )
  359. update_button()
  360. text.insert(tkinter.END, out_data)
  361. if stop and i.replace(" ", "").replace("\n", "") != stop_key:
  362. text.insert(tkinter.END, f"[out]> {i}\n")
  363. data += i + "\n"
  364. out_data += f"[out]> {i}\n"
  365. else:
  366. break
  367. else:
  368. text.insert(tkinter.END, "[END]")
  369. out_data += f"[END]"
  370. data += f"[END]"
  371. start = 0
  372. else: # 即时显示
  373. while True:
  374. # 界面设置
  375. try: # 如果界面被关掉了,会报错
  376. if show_screen:
  377. cli_screen.title(f"{name} : 运行中")
  378. except BaseException:
  379. text, cli_screen, button_list = show_cli(
  380. save_to_txt, stop, keep, format, pipe, name=f"{name} : 运行中"
  381. )
  382. update_button()
  383. text.insert(tkinter.END, out_data)
  384. # 界面刷新
  385. try:
  386. if not is_threaded_refresh:
  387. SCREEN.update()
  388. if show_screen:
  389. cli_screen.update()
  390. except BaseException:
  391. break
  392. # 输出字符
  393. try:
  394. # .decode(str_code)#不需要decode,因为Popen已经设置了universal_newlines=True
  395. i = command_thread.stdout.readline()
  396. bool_text = i.replace(" ", "").replace("\n", "")
  397. if bool_text != "":
  398. if stop and bool_text == stop_key:
  399. start = 0
  400. else:
  401. if show_screen:
  402. text.insert(tkinter.END, f"[out]> {i}")
  403. data += i
  404. out_data += f"[out]> {i}"
  405. if (
  406. command_thread.returncode == 0
  407. or (time.time() - start >= break_time and break_time != 0)
  408. or (break_time == 0 and start == 0)
  409. ):
  410. if show_screen:
  411. text.insert(tkinter.END, "[END]")
  412. out_data += f"[END]"
  413. data += f"[END]"
  414. break
  415. elif command_thread.returncode is not None:
  416. raise Exception
  417. except BaseException:
  418. try:
  419. if show_screen:
  420. text.insert(tkinter.END, "[ERROR]")
  421. out_data += f"[ERROR]"
  422. data += f"[ERROR]"
  423. raise Exception
  424. except BaseException:
  425. break
  426. try: # 如果界面被关掉了,会报错
  427. if show_screen:
  428. cli_screen.title(f"{name} : 运行完毕")
  429. except BaseException:
  430. pass
  431. command_thread.kill()
  432. try:
  433. if show_screen:
  434. button_list[0].config(state=tkinter.DISABLED)
  435. button_list[1].config(state=tkinter.DISABLED)
  436. except BaseException:
  437. pass
  438. return data
  439. def log():
  440. global git, log_type
  441. name = get_repo_name()
  442. graph = bool(log_type[0].get())
  443. abbrev = bool(log_type[1].get())
  444. pretty = bool(log_type[2].get())
  445. cli(git.log, (name, graph, pretty, abbrev))
  446. update_git_file_last()
  447. def not_parameters_call(func):
  448. global git
  449. name = get_repo_name()
  450. cli(func, (name,))
  451. update_git_file_last()
  452. def commit_file():
  453. global git, commit_message
  454. m = commit_message.get()
  455. if m.replace(" ", "") == "":
  456. tkinter.messagebox.showinfo("警告!", "非常遗憾,我不同意你commit而不添加任何描述!\n描述是很重要的!")
  457. return False
  458. name = get_repo_name()
  459. cli(git.commit_file, (name, m))
  460. update_git_file_last()
  461. def diff():
  462. global git, master
  463. branch = master.get()
  464. if branch == "":
  465. branch = "HEAD"
  466. cli(git.diff_file, (get_repo_name(), branch))
  467. update_git_file_last()
  468. def remove_the_staging():
  469. global git, last_name, file_list
  470. dic = file_list
  471. if dic == []:
  472. dic = "."
  473. cli(git.reset_file, (get_repo_name(), dic))
  474. update_git_file_last()
  475. def add():
  476. global git, last_name, file_list
  477. dic = file_list
  478. if dic == []:
  479. dic = "." # 查一下取消的dic
  480. cli(git.add_file, (get_repo_name(), dic))
  481. update_git_file_last()
  482. def add_file_list():
  483. global file_list, file_box
  484. new_file = set(askopenfilenames(title=f"选择文件"))
  485. have_file = set(file_list)
  486. file_list += list(new_file - (new_file & have_file)) # 筛选出重复
  487. update_file_box()
  488. def add_file_input():
  489. global file_dir
  490. new_dir = file_dir.get()
  491. if new_dir.replace(" ", "") != "" and new_dir not in file_list:
  492. file_list.append(new_dir)
  493. update_file_box()
  494. def add_file_by_git():
  495. global file_dir
  496. new_dir = file_dir.get()
  497. if new_dir.replace(" ", "") != "":
  498. name = get_repo_name()
  499. new_dir = git.make_dir(name, new_dir)
  500. if new_dir not in file_list:
  501. file_list.append(new_dir)
  502. update_file_box()
  503. def del_file():
  504. global file_list, file_box
  505. try:
  506. del file_list[file_box.curselection()]
  507. update_file_box()
  508. except BaseException:
  509. pass
  510. def clean_file():
  511. global file_list
  512. file_list = []
  513. update_file_box()
  514. def update_file_box():
  515. global file_list, file_box
  516. file_box.delete(0, tkinter.END)
  517. file_box.insert(tkinter.END, *file_list)
  518. def update_git_file_last():
  519. global last_name
  520. if last_name is None:
  521. return False
  522. update_git_file_core(last_name)
  523. def update_git_file_select():
  524. name = get_repo_name()
  525. update_git_file_core(name)
  526. def update_git_file_core(name):
  527. global git, repo_dir, last_name
  528. dir_list = git.get_dir(name)
  529. try: # 窗口可能已经关闭
  530. repo_dir.delete(0, tkinter.END)
  531. repo_dir.insert(tkinter.END, *dir_list)
  532. except BaseException:
  533. pass
  534. last_name = name
  535. def repo_init(): # 创建仓库
  536. global git
  537. new_dir = askdirectory(title="选择仓库地址")
  538. if new_dir == "":
  539. return False
  540. git.open_repo(new_dir)
  541. update_repo_box()
  542. def get_repo_name(): # 获得名字统一接口
  543. global git, repo_list, repo_box
  544. try:
  545. return repo_list[repo_box.curselection()[0]]
  546. except BaseException:
  547. try:
  548. return repo_list[0]
  549. except BaseException:
  550. return None
  551. def update_repo_box():
  552. global git, repo_list, repo_box
  553. repo_list = list(git.get_git_dict().keys())
  554. repo_box.delete(0, tkinter.END)
  555. repo_box.insert(tkinter.END, *repo_list)
  556. def show_cli(
  557. out_func, close_func, keep_func, not_out, pipe_func, name="CoTan_Git >>> 命令行"
  558. ):
  559. global bg_color
  560. cli_screen = tkinter.Toplevel(bg=bg_color)
  561. cli_screen.title(name)
  562. cli_screen.geometry("+10+10") # 设置所在位置
  563. cli_screen.resizable(width=False, height=False)
  564. class ScrolledCli(ScrolledText):
  565. def __init__(self, *args, **kwargs):
  566. super(ScrolledCli, self).__init__(*args, **kwargs)
  567. def insert(self, index, chars, *args):
  568. text.config(state=tkinter.NORMAL)
  569. super(ScrolledCli, self).insert(index, chars, *args)
  570. text.config(state=tkinter.DISABLED)
  571. def clear(self):
  572. text.config(state=tkinter.NORMAL)
  573. self.delete("0.0", tkinter.END)
  574. text.config(state=tkinter.DISABLED)
  575. text = ScrolledCli(cli_screen, font=("黑体", 11), height=30, width=100)
  576. text.grid(column=0, row=0, columnspan=5, sticky=tkinter.E + tkinter.W)
  577. text.config(state=tkinter.DISABLED)
  578. tkinter.Button(
  579. cli_screen,
  580. bg=bg_color,
  581. fg=word_color,
  582. text="输出文档",
  583. font=("黑体", 11),
  584. width=20,
  585. height=2,
  586. command=out_func,
  587. ).grid(column=4, row=1, sticky=tkinter.E + tkinter.W)
  588. close = tkinter.Button(
  589. cli_screen,
  590. bg=bg_color,
  591. fg=word_color,
  592. text="关闭子线程连接",
  593. font=("黑体", 11),
  594. width=20,
  595. height=2,
  596. command=close_func,
  597. )
  598. close.grid(column=0, row=1, sticky=tkinter.E + tkinter.W)
  599. keep = tkinter.Button(
  600. cli_screen,
  601. bg=bg_color,
  602. fg=word_color,
  603. text="保持线程连接",
  604. font=("黑体", 11),
  605. width=20,
  606. height=2,
  607. command=keep_func,
  608. )
  609. keep.grid(column=1, row=1, sticky=tkinter.E + tkinter.W)
  610. tkinter.Button(
  611. cli_screen,
  612. bg=bg_color,
  613. fg=word_color,
  614. text="格式化输出",
  615. font=("黑体", 11),
  616. width=20,
  617. height=2,
  618. command=not_out,
  619. ).grid(column=2, row=1, sticky=tkinter.E + tkinter.W)
  620. tkinter.Button(
  621. cli_screen,
  622. bg=bg_color,
  623. fg=word_color,
  624. text="启动CoTan命令行",
  625. font=("黑体", 11),
  626. width=20,
  627. height=2,
  628. command=pipe_func,
  629. state=tkinter.DISABLED,
  630. ).grid(column=3, row=1, sticky=tkinter.E + tkinter.W)
  631. cli_screen.update()
  632. return text, cli_screen, [close, keep]
  633. def progress_bar(*args, name="CoTan_Git >>> 运行中...", **kwargs):
  634. progress_screen = tkinter.Toplevel(bg=bg_color)
  635. progress_screen.title(name)
  636. progress_screen.geometry("+10+10") # 设置所在位置
  637. mpb = ttk.Progressbar(
  638. progress_screen, orient="horizontal", length=300, mode="determinate"
  639. )
  640. mpb.pack()
  641. progress_screen.resizable(width=False, height=False)
  642. mpb["maximum"] = 50
  643. mpb["value"] = 0
  644. for i in range(50):
  645. mpb["value"] = i + 1
  646. progress_screen.update()
  647. SCREEN.update()
  648. time.sleep(0.001)
  649. progress_screen.destroy()
  650. file_list = []
  651. PATH = os.getcwd()
  652. git = controller.GitCtrol()
  653. repo_list = []
  654. SCREEN = tkinter.Tk()
  655. last_name = None
  656. bg_color = "#FFFAFA" # 主颜色
  657. buttom_color = "#FFFAFA" # 按钮颜色
  658. word_color = "#000000" # 文字颜色
  659. SCREEN["bg"] = bg_color
  660. FONT = ("黑体", 11) # 设置字体
  661. SCREEN.title("CoTan仓库管理器")
  662. SCREEN.resizable(width=False, height=False)
  663. SCREEN.geometry("+10+10") # 设置所在位置
  664. gui_width = 13 # 标准宽度
  665. gui_height = 2
  666. row = 0
  667. column = 0
  668. tkinter.Button(
  669. SCREEN,
  670. bg=buttom_color,
  671. fg=word_color,
  672. text="克隆仓库",
  673. command=clone_git,
  674. font=FONT,
  675. width=gui_width,
  676. height=gui_height,
  677. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  678. tkinter.Button(
  679. SCREEN,
  680. bg=buttom_color,
  681. fg=word_color,
  682. text="打开仓库",
  683. command=repo_init,
  684. font=FONT,
  685. width=gui_width,
  686. height=gui_height,
  687. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  688. tkinter.Button(
  689. SCREEN,
  690. bg=buttom_color,
  691. fg=word_color,
  692. text="查看文件",
  693. command=update_git_file_select,
  694. font=FONT,
  695. width=gui_width,
  696. height=gui_height,
  697. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  698. row += 1
  699. tkinter.Label(
  700. SCREEN,
  701. text="克隆URL:",
  702. bg=bg_color,
  703. fg=word_color,
  704. font=FONT,
  705. width=gui_width,
  706. height=gui_height,
  707. ).grid(column=column, row=row)
  708. clone_repo = tkinter.Entry(SCREEN, width=gui_width * 2)
  709. clone_repo.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  710. row += 1
  711. repo_box = tkinter.Listbox(SCREEN, width=gui_width * 3, height=gui_height * 4)
  712. repo_box.grid(
  713. column=column,
  714. row=row,
  715. columnspan=3,
  716. rowspan=4,
  717. sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N,
  718. )
  719. row += 4
  720. tkinter.Label(
  721. SCREEN,
  722. text="【仓库文件列表】",
  723. bg=bg_color,
  724. fg=word_color,
  725. font=FONT,
  726. width=gui_width * 3,
  727. height=gui_height,
  728. ).grid(
  729. column=column,
  730. columnspan=3,
  731. row=row,
  732. sticky=tkinter.E + tkinter.W + tkinter.W + tkinter.S + tkinter.N,
  733. ) # 设置说明
  734. row += 1
  735. repo_dir = tkinter.Listbox(SCREEN, width=gui_width * 3, height=gui_height * 4)
  736. repo_dir.grid(
  737. column=column,
  738. row=row,
  739. columnspan=3,
  740. rowspan=4,
  741. sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N,
  742. )
  743. row += 4
  744. tkinter.Label(
  745. SCREEN,
  746. text="【添加文件列表】",
  747. bg=bg_color,
  748. fg=word_color,
  749. font=FONT,
  750. width=gui_width * 3,
  751. height=gui_height,
  752. ).grid(
  753. column=column,
  754. columnspan=3,
  755. row=row,
  756. sticky=tkinter.E + tkinter.W + tkinter.W + tkinter.S + tkinter.N,
  757. ) # 设置说明
  758. row += 1
  759. file_dir = tkinter.Entry(SCREEN, width=gui_width * 2)
  760. file_dir.grid(
  761. column=column,
  762. row=row,
  763. columnspan=3,
  764. sticky=tkinter.E + tkinter.W + tkinter.N + tkinter.S,
  765. )
  766. row += 1
  767. tkinter.Button(
  768. SCREEN,
  769. bg=buttom_color,
  770. fg=word_color,
  771. text="填充路径并添加",
  772. command=add_file_by_git,
  773. font=FONT,
  774. width=gui_width,
  775. height=gui_height,
  776. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  777. tkinter.Button(
  778. SCREEN,
  779. bg=buttom_color,
  780. fg=word_color,
  781. text="直接添加",
  782. command=add_file_input,
  783. font=FONT,
  784. width=gui_width,
  785. height=gui_height,
  786. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  787. tkinter.Button(
  788. SCREEN,
  789. bg=buttom_color,
  790. fg=word_color,
  791. text="选择文件",
  792. command=add_file_list,
  793. font=FONT,
  794. width=gui_width,
  795. height=gui_height,
  796. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  797. row += 1
  798. tkinter.Button(
  799. SCREEN,
  800. bg=buttom_color,
  801. fg=word_color,
  802. text="把文件移除出列表",
  803. command=del_file,
  804. font=FONT,
  805. width=gui_width,
  806. height=gui_height,
  807. ).grid(column=column, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  808. tkinter.Button(
  809. SCREEN,
  810. bg=buttom_color,
  811. fg=word_color,
  812. text="清空列表",
  813. command=clean_file,
  814. font=FONT,
  815. width=gui_width,
  816. height=gui_height,
  817. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  818. row += 1
  819. file_box = tkinter.Listbox(SCREEN, width=gui_width * 3, height=gui_height * 4)
  820. file_box.grid(
  821. column=column,
  822. row=row,
  823. columnspan=3,
  824. rowspan=4,
  825. sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N,
  826. )
  827. row += 4
  828. tkinter.Button(
  829. SCREEN,
  830. bg=buttom_color,
  831. fg=word_color,
  832. text="添加暂存区文件",
  833. command=add,
  834. font=FONT,
  835. width=gui_width,
  836. height=gui_height,
  837. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  838. tkinter.Button(
  839. SCREEN,
  840. bg=buttom_color,
  841. fg=word_color,
  842. text="移除暂存区文件",
  843. command=remove_the_staging,
  844. font=FONT,
  845. width=gui_width,
  846. height=gui_height,
  847. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  848. tkinter.Button(
  849. SCREEN,
  850. bg=buttom_color,
  851. fg=word_color,
  852. text="提交到git",
  853. command=commit_file,
  854. font=FONT,
  855. width=gui_width,
  856. height=gui_height,
  857. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  858. row += 1
  859. tkinter.Button(
  860. SCREEN,
  861. bg=buttom_color,
  862. fg=word_color,
  863. text="查看执行日志",
  864. command=lambda: not_parameters_call(git.do_log),
  865. font=FONT,
  866. width=gui_width,
  867. height=gui_height,
  868. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  869. tkinter.Button(
  870. SCREEN,
  871. bg=buttom_color,
  872. fg=word_color,
  873. text="查看文件日志",
  874. command=log,
  875. font=FONT,
  876. width=gui_width,
  877. height=gui_height,
  878. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  879. tkinter.Button(
  880. SCREEN,
  881. bg=buttom_color,
  882. fg=word_color,
  883. text="查看状态",
  884. command=lambda: not_parameters_call(git.status),
  885. font=FONT,
  886. width=gui_width,
  887. height=gui_height,
  888. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  889. row += 1
  890. log_type = []
  891. lable = ["显示轴", "commit完全显示", "简化显示"] # 复选框
  892. for i in range(3):
  893. log_type.append(tkinter.IntVar())
  894. tkinter.Checkbutton(
  895. SCREEN,
  896. bg=bg_color,
  897. fg=word_color,
  898. activebackground=bg_color,
  899. activeforeground=word_color,
  900. selectcolor=bg_color,
  901. text=lable[i],
  902. variable=log_type[-1],
  903. ).grid(column=column + i, row=row, sticky=tkinter.W)
  904. log_type[-1].set(1)
  905. row += 1
  906. tkinter.Button(
  907. SCREEN,
  908. bg=buttom_color,
  909. fg=word_color,
  910. text="版本回退",
  911. command=reset_head,
  912. font=FONT,
  913. width=gui_width,
  914. height=gui_height,
  915. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  916. tkinter.Button(
  917. SCREEN,
  918. bg=buttom_color,
  919. fg=word_color,
  920. text="放弃修改",
  921. command=checkout_file,
  922. font=FONT,
  923. width=gui_width,
  924. height=gui_height,
  925. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  926. tkinter.Button(
  927. SCREEN,
  928. bg=buttom_color,
  929. fg=word_color,
  930. text="删除文件",
  931. command=remove_file,
  932. font=FONT,
  933. width=gui_width,
  934. height=gui_height,
  935. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  936. row += 1
  937. reset_type = tkinter.IntVar() # 正,负,0
  938. lable = ["回退到工作区", "回退到暂存区", "无痕回退"] # 复选框
  939. for i in range(3):
  940. tkinter.Radiobutton(
  941. SCREEN,
  942. bg=bg_color,
  943. fg=word_color,
  944. activebackground=bg_color,
  945. activeforeground=word_color,
  946. selectcolor=bg_color,
  947. text=lable[i],
  948. variable=reset_type,
  949. value=i,
  950. ).grid(column=column + i, row=row, sticky=tkinter.W)
  951. column += 3
  952. tkinter.Label(SCREEN, text="", bg=bg_color, fg=word_color, font=FONT, width=1).grid(
  953. column=column, row=row
  954. ) # 设置说明
  955. column += 1
  956. row = 0
  957. tkinter.Label(
  958. SCREEN,
  959. text="【参数操作】",
  960. bg=bg_color,
  961. fg=word_color,
  962. font=FONT,
  963. width=gui_width * 3,
  964. height=gui_height,
  965. ).grid(
  966. column=column,
  967. columnspan=3,
  968. row=row,
  969. sticky=tkinter.E + tkinter.W + tkinter.W + tkinter.S + tkinter.N,
  970. ) # 设置说明
  971. row += 1
  972. tkinter.Label(
  973. SCREEN,
  974. text="提交描述:",
  975. bg=bg_color,
  976. fg=word_color,
  977. font=FONT,
  978. width=gui_width,
  979. height=gui_height,
  980. ).grid(column=column, row=row)
  981. commit_message = tkinter.Entry(SCREEN, width=gui_width * 2)
  982. commit_message.grid(
  983. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  984. )
  985. row += 1
  986. tkinter.Label(
  987. SCREEN,
  988. text="diff分支:",
  989. bg=bg_color,
  990. fg=word_color,
  991. font=FONT,
  992. width=gui_width,
  993. height=gui_height,
  994. ).grid(column=column, row=row)
  995. master = tkinter.Entry(SCREEN, width=gui_width * 2)
  996. master.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  997. row += 1
  998. tkinter.Label(
  999. SCREEN,
  1000. text="回退版本号:",
  1001. bg=bg_color,
  1002. fg=word_color,
  1003. font=FONT,
  1004. width=gui_width,
  1005. height=gui_height,
  1006. ).grid(column=column, row=row)
  1007. head = tkinter.Entry(SCREEN, width=gui_width * 2)
  1008. head.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1009. row += 1
  1010. tkinter.Label(
  1011. SCREEN,
  1012. text="本地分支:",
  1013. bg=bg_color,
  1014. fg=word_color,
  1015. font=FONT,
  1016. width=gui_width,
  1017. height=gui_height,
  1018. ).grid(column=column, row=row)
  1019. branch_name = tkinter.Entry(SCREEN, width=gui_width * 2)
  1020. branch_name.grid(
  1021. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1022. )
  1023. row += 1
  1024. tkinter.Label(
  1025. SCREEN,
  1026. text="远程分支:",
  1027. bg=bg_color,
  1028. fg=word_color,
  1029. font=FONT,
  1030. width=gui_width,
  1031. height=gui_height,
  1032. ).grid(column=column, row=row)
  1033. origin_branch = tkinter.Entry(SCREEN, width=gui_width * 2)
  1034. origin_branch.grid(
  1035. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1036. )
  1037. row += 1
  1038. tkinter.Label(
  1039. SCREEN,
  1040. text="远程仓库链接:",
  1041. bg=bg_color,
  1042. fg=word_color,
  1043. font=FONT,
  1044. width=gui_width,
  1045. height=gui_height,
  1046. ).grid(column=column, row=row)
  1047. remote_ssh = tkinter.Entry(SCREEN, width=gui_width)
  1048. remote_ssh.grid(column=column + 1, columnspan=2, row=row, sticky=tkinter.E + tkinter.W)
  1049. row += 1
  1050. tkinter.Label(
  1051. SCREEN,
  1052. text="远程仓库名:",
  1053. bg=bg_color,
  1054. fg=word_color,
  1055. font=FONT,
  1056. width=gui_width,
  1057. height=gui_height,
  1058. ).grid(column=column, row=row)
  1059. remote_name = tkinter.Entry(SCREEN, width=gui_width)
  1060. remote_name.grid(
  1061. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1062. )
  1063. row += 1
  1064. tkinter.Label(
  1065. SCREEN,
  1066. text="commit:",
  1067. bg=bg_color,
  1068. fg=word_color,
  1069. font=FONT,
  1070. width=gui_width,
  1071. height=gui_height,
  1072. ).grid(column=column, row=row)
  1073. commit = tkinter.Entry(SCREEN, width=gui_width)
  1074. commit.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1075. row += 1
  1076. tkinter.Label(
  1077. SCREEN,
  1078. text="标签名字:",
  1079. bg=bg_color,
  1080. fg=word_color,
  1081. font=FONT,
  1082. width=gui_width,
  1083. height=gui_height,
  1084. ).grid(column=column, row=row)
  1085. tag_name = tkinter.Entry(SCREEN, width=gui_width)
  1086. tag_name.grid(column=column + 1, columnspan=2, row=row, sticky=tkinter.E + tkinter.W)
  1087. row += 1
  1088. tkinter.Label(
  1089. SCREEN,
  1090. text="查询关键字:",
  1091. bg=bg_color,
  1092. fg=word_color,
  1093. font=FONT,
  1094. width=gui_width,
  1095. height=gui_height,
  1096. ).grid(column=column, row=row)
  1097. show_search_key = tkinter.Entry(SCREEN, width=gui_width)
  1098. show_search_key.grid(
  1099. column=column + 1, columnspan=2, row=row, sticky=tkinter.E + tkinter.W
  1100. )
  1101. row += 1
  1102. tkinter.Label(
  1103. SCREEN,
  1104. text="工作区序号:",
  1105. bg=bg_color,
  1106. fg=word_color,
  1107. font=FONT,
  1108. width=gui_width,
  1109. height=gui_height,
  1110. ).grid(column=column, row=row)
  1111. stash_name = tkinter.Entry(SCREEN, width=gui_width)
  1112. stash_name.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1113. row += 1
  1114. tkinter.Label(
  1115. SCREEN,
  1116. text="【高级操作】",
  1117. bg=bg_color,
  1118. fg=word_color,
  1119. font=FONT,
  1120. width=gui_width * 3,
  1121. height=gui_height,
  1122. ).grid(
  1123. column=column,
  1124. columnspan=3,
  1125. row=row,
  1126. sticky=tkinter.E + tkinter.W + tkinter.W + tkinter.S + tkinter.N,
  1127. ) # 设置说明
  1128. row += 1
  1129. tkinter.Button(
  1130. SCREEN,
  1131. bg=buttom_color,
  1132. fg=word_color,
  1133. text="查看分支",
  1134. command=lambda: not_parameters_call(git.branch_view),
  1135. font=FONT,
  1136. width=gui_width,
  1137. height=gui_height,
  1138. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1139. tkinter.Button(
  1140. SCREEN,
  1141. bg=buttom_color,
  1142. fg=word_color,
  1143. text="新建分支",
  1144. command=add_new_branch,
  1145. font=FONT,
  1146. width=gui_width,
  1147. height=gui_height,
  1148. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1149. tkinter.Button(
  1150. SCREEN,
  1151. bg=buttom_color,
  1152. fg=word_color,
  1153. text="切换分支",
  1154. command=switch_branch,
  1155. font=FONT,
  1156. width=gui_width,
  1157. height=gui_height,
  1158. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1159. row += 1
  1160. tkinter.Button(
  1161. SCREEN,
  1162. bg=buttom_color,
  1163. fg=word_color,
  1164. text="删除分支",
  1165. command=lambda: del_branch(1),
  1166. font=FONT,
  1167. width=gui_width,
  1168. height=gui_height,
  1169. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1170. tkinter.Button(
  1171. SCREEN,
  1172. bg=buttom_color,
  1173. fg=word_color,
  1174. text="丢弃分支",
  1175. command=lambda: del_branch(0),
  1176. font=FONT,
  1177. width=gui_width,
  1178. height=gui_height,
  1179. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1180. tkinter.Button(
  1181. SCREEN,
  1182. bg=buttom_color,
  1183. fg=word_color,
  1184. text="合并分支",
  1185. command=switch_branch,
  1186. font=FONT,
  1187. width=gui_width,
  1188. height=gui_height,
  1189. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1190. no_fast_forward = tkinter.IntVar()
  1191. row += 1
  1192. tkinter.Button(
  1193. SCREEN,
  1194. bg=buttom_color,
  1195. fg=word_color,
  1196. text="合并分支",
  1197. command=branch_merge,
  1198. font=FONT,
  1199. width=gui_width,
  1200. height=gui_height,
  1201. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1202. tkinter.Button(
  1203. SCREEN,
  1204. bg=buttom_color,
  1205. fg=word_color,
  1206. text="退出冲突处理",
  1207. command=lambda: not_parameters_call(git.merge_abort),
  1208. font=FONT,
  1209. width=gui_width,
  1210. height=gui_height,
  1211. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1212. tkinter.Checkbutton(
  1213. SCREEN,
  1214. bg=bg_color,
  1215. fg=word_color,
  1216. activebackground=bg_color,
  1217. activeforeground=word_color,
  1218. selectcolor=bg_color,
  1219. text="使用快速合并",
  1220. variable=no_fast_forward,
  1221. ).grid(column=column + 1, row=row, sticky=tkinter.W)
  1222. no_fast_forward.set(0)
  1223. row += 1
  1224. tkinter.Button(
  1225. SCREEN,
  1226. bg=buttom_color,
  1227. fg=word_color,
  1228. text="连接远程仓库",
  1229. command=add_remote,
  1230. font=FONT,
  1231. width=gui_width,
  1232. height=gui_height,
  1233. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1234. tkinter.Button(
  1235. SCREEN,
  1236. bg=buttom_color,
  1237. fg=word_color,
  1238. text="推送到远程仓库",
  1239. command=lambda: pull_push_remote(1),
  1240. font=FONT,
  1241. width=gui_width,
  1242. height=gui_height,
  1243. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1244. tkinter.Button(
  1245. SCREEN,
  1246. bg=buttom_color,
  1247. fg=word_color,
  1248. text="从远程仓库抓取",
  1249. command=lambda: pull_push_remote(0),
  1250. font=FONT,
  1251. width=gui_width,
  1252. height=gui_height,
  1253. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1254. push_bind = tkinter.IntVar()
  1255. allow_history = tkinter.IntVar()
  1256. row += 1
  1257. tkinter.Button(
  1258. SCREEN,
  1259. bg=buttom_color,
  1260. fg=word_color,
  1261. text="分支绑定",
  1262. command=bind_remote_branch,
  1263. font=FONT,
  1264. width=gui_width,
  1265. height=gui_height,
  1266. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1267. tkinter.Checkbutton(
  1268. SCREEN,
  1269. bg=bg_color,
  1270. fg=word_color,
  1271. activebackground=bg_color,
  1272. activeforeground=word_color,
  1273. selectcolor=bg_color,
  1274. text="无视历史记录",
  1275. variable=allow_history,
  1276. ).grid(column=column + 1, row=row, sticky=tkinter.W)
  1277. tkinter.Checkbutton(
  1278. SCREEN,
  1279. bg=bg_color,
  1280. fg=word_color,
  1281. activebackground=bg_color,
  1282. activeforeground=word_color,
  1283. selectcolor=bg_color,
  1284. text="推送时绑定",
  1285. variable=push_bind,
  1286. ).grid(column=column + 2, row=row, sticky=tkinter.W)
  1287. allow_history.set(0)
  1288. push_bind.set(0)
  1289. row += 1
  1290. tkinter.Button(
  1291. SCREEN,
  1292. bg=buttom_color,
  1293. fg=word_color,
  1294. text="应用标签",
  1295. command=add_tag,
  1296. font=FONT,
  1297. width=gui_width,
  1298. height=gui_height,
  1299. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1300. tkinter.Button(
  1301. SCREEN,
  1302. bg=buttom_color,
  1303. fg=word_color,
  1304. text="查看已有标签",
  1305. command=lambda: show_tag(1),
  1306. font=FONT,
  1307. width=gui_width,
  1308. height=gui_height,
  1309. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1310. tkinter.Button(
  1311. SCREEN,
  1312. bg=buttom_color,
  1313. fg=word_color,
  1314. text="查询commit记录",
  1315. command=lambda: show_tag(0),
  1316. font=FONT,
  1317. width=gui_width,
  1318. height=gui_height,
  1319. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1320. row += 1
  1321. tkinter.Button(
  1322. SCREEN,
  1323. bg=buttom_color,
  1324. fg=word_color,
  1325. text="推送标签",
  1326. command=push_tag,
  1327. font=FONT,
  1328. width=gui_width,
  1329. height=gui_height,
  1330. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1331. tkinter.Button(
  1332. SCREEN,
  1333. bg=buttom_color,
  1334. fg=word_color,
  1335. text="推送所有标签",
  1336. command=push_all_tag,
  1337. font=FONT,
  1338. width=gui_width,
  1339. height=gui_height,
  1340. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1341. tkinter.Button(
  1342. SCREEN,
  1343. bg=buttom_color,
  1344. fg=word_color,
  1345. text="删除本地标签",
  1346. command=del_tag,
  1347. font=FONT,
  1348. width=gui_width,
  1349. height=gui_height,
  1350. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1351. row += 1
  1352. tkinter.Button(
  1353. SCREEN,
  1354. bg=buttom_color,
  1355. fg=word_color,
  1356. text="删除远程标签",
  1357. command=del_remote_tag,
  1358. font=FONT,
  1359. width=gui_width,
  1360. height=gui_height,
  1361. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1362. tkinter.Button(
  1363. SCREEN,
  1364. bg=buttom_color,
  1365. fg=word_color,
  1366. text="删除远程分支",
  1367. command=del_remote_branch,
  1368. font=FONT,
  1369. width=gui_width,
  1370. height=gui_height,
  1371. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1372. tkinter.Button(
  1373. SCREEN,
  1374. bg=buttom_color,
  1375. fg=word_color,
  1376. text="刷新远程分支",
  1377. command=fetch_remote,
  1378. font=FONT,
  1379. width=gui_width,
  1380. height=gui_height,
  1381. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1382. row += 1
  1383. tkinter.Button(
  1384. SCREEN,
  1385. bg=buttom_color,
  1386. fg=word_color,
  1387. text="commit补丁",
  1388. command=cherry_pick,
  1389. font=FONT,
  1390. width=gui_width,
  1391. height=gui_height,
  1392. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1393. tkinter.Button(
  1394. SCREEN,
  1395. bg=buttom_color,
  1396. fg=word_color,
  1397. text="删除远程仓库",
  1398. command=del_remote,
  1399. font=FONT,
  1400. width=gui_width,
  1401. height=gui_height,
  1402. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1403. tkinter.Button(
  1404. SCREEN,
  1405. bg=buttom_color,
  1406. fg=word_color,
  1407. text="工作区列表",
  1408. command=lambda: not_parameters_call(git.stash_list),
  1409. font=FONT,
  1410. width=gui_width,
  1411. height=gui_height,
  1412. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1413. row += 1
  1414. tkinter.Button(
  1415. SCREEN,
  1416. bg=buttom_color,
  1417. fg=word_color,
  1418. text="文件回退",
  1419. command=reset_file,
  1420. font=FONT,
  1421. width=gui_width,
  1422. height=gui_height,
  1423. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1424. tkinter.Button(
  1425. SCREEN,
  1426. bg=buttom_color,
  1427. fg=word_color,
  1428. text="分支重命名",
  1429. command=branch_new,
  1430. font=FONT,
  1431. width=gui_width,
  1432. height=gui_height,
  1433. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1434. branch_new_name = tkinter.Entry(SCREEN, width=gui_width)
  1435. branch_new_name.grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1436. row += 1
  1437. tkinter.Button(
  1438. SCREEN,
  1439. bg=buttom_color,
  1440. fg=word_color,
  1441. text="保存工作区",
  1442. command=lambda: not_parameters_call(git.save_stash),
  1443. font=FONT,
  1444. width=gui_width,
  1445. height=gui_height,
  1446. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1447. tkinter.Button(
  1448. SCREEN,
  1449. bg=buttom_color,
  1450. fg=word_color,
  1451. text="恢复工作区",
  1452. command=lambda: open_stash(1),
  1453. font=FONT,
  1454. width=gui_width,
  1455. height=gui_height,
  1456. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1457. tkinter.Button(
  1458. SCREEN,
  1459. bg=buttom_color,
  1460. fg=word_color,
  1461. text="删除工作区",
  1462. command=lambda: open_stash(0),
  1463. font=FONT,
  1464. width=gui_width,
  1465. height=gui_height,
  1466. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1467. row += 1
  1468. threaded_refresh = tkinter.IntVar()
  1469. asynchronous_display = tkinter.IntVar()
  1470. tkinter.Checkbutton(
  1471. SCREEN,
  1472. bg=bg_color,
  1473. fg=word_color,
  1474. activebackground=bg_color,
  1475. activeforeground=word_color,
  1476. selectcolor=bg_color,
  1477. text="多进程刷新",
  1478. variable=threaded_refresh,
  1479. ).grid(column=0, row=row, sticky=tkinter.W)
  1480. tkinter.Checkbutton(
  1481. SCREEN,
  1482. bg=bg_color,
  1483. fg=word_color,
  1484. activebackground=bg_color,
  1485. activeforeground=word_color,
  1486. selectcolor=bg_color,
  1487. text="异步显示",
  1488. variable=asynchronous_display,
  1489. ).grid(column=1, row=row, sticky=tkinter.W)
  1490. customize_input = tkinter.Entry(SCREEN, width=gui_width * 3)
  1491. customize_input.grid(
  1492. column=2,
  1493. row=row,
  1494. columnspan=4,
  1495. sticky=tkinter.E + tkinter.W + tkinter.N + tkinter.S,
  1496. )
  1497. tkinter.Button(
  1498. SCREEN,
  1499. bg=buttom_color,
  1500. fg=word_color,
  1501. text="执行操作",
  1502. command=customize,
  1503. font=FONT,
  1504. width=gui_width,
  1505. height=gui_height,
  1506. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1507. threaded_refresh.set(0)
  1508. asynchronous_display.set(1)
  1509. tag_message = commit_message
  1510. tag_commit = commit
  1511. remote_branch = origin_branch
  1512. local_branch = branch_name