first commit
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
var path: String = ProjectSettings.globalize_path("res://")
|
||||
var dock: EditorDock
|
||||
|
||||
func _enter_tree() -> void:
|
||||
dock = EditorDock.new()
|
||||
dock.name = "Git"
|
||||
dock.default_slot = EditorDock.DOCK_SLOT_LEFT_UR
|
||||
var dock_content = preload("uid://ivjdq3iu1k6r").instantiate()
|
||||
dock.add_child(dock_content)
|
||||
add_dock(dock)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if dock != null:
|
||||
remove_dock(dock)
|
||||
dock.queue_free()
|
||||
dock = null
|
||||
@@ -0,0 +1 @@
|
||||
uid://dqyx882kpwyxf
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dfkhd4xwkws2s"
|
||||
path="res://.godot/imported/fgi_logo.png-34ef447b1e00e7e9cfc01045347acd2c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/fgi/fgi_logo.png"
|
||||
dest_files=["res://.godot/imported/fgi_logo.png-34ef447b1e00e7e9cfc01045347acd2c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://buyihhm48peqh"
|
||||
path="res://.godot/imported/fgi_logo_transparent.png-3d30218d834c938bec7d9a8688fa7272.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/fgi/fgi_logo_transparent.png"
|
||||
dest_files=["res://.godot/imported/fgi_logo_transparent.png-3d30218d834c938bec7d9a8688fa7272.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -0,0 +1,94 @@
|
||||
[gd_scene format=3 uid="uid://ivjdq3iu1k6r"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b7lkke108s0j0" path="res://addons/fgi/git_ui.gd" id="1_kprvy"]
|
||||
|
||||
[node name="Git" type="Control" unique_id=1162410415]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_kprvy")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=2080877151]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer" unique_id=797029245]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FetchChanges" type="Button" parent="VBoxContainer/HBoxContainer" unique_id=159460668]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Fetch Changes"
|
||||
|
||||
[node name="Pull" type="Button" parent="VBoxContainer/HBoxContainer" unique_id=399363292]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Pull"
|
||||
|
||||
[node name="Push" type="Button" parent="VBoxContainer/HBoxContainer" unique_id=1683292935]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Push"
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="VBoxContainer" unique_id=876855756]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
current_tab = 0
|
||||
|
||||
[node name="Changes" type="MarginContainer" parent="VBoxContainer/TabContainer" unique_id=782888386]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 12
|
||||
theme_override_constants/margin_top = 12
|
||||
theme_override_constants/margin_right = 12
|
||||
theme_override_constants/margin_bottom = 12
|
||||
metadata/_tab_index = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/Changes" unique_id=2111121496]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FileList" type="Tree" parent="VBoxContainer/TabContainer/Changes/VBoxContainer" unique_id=154612544]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(300, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
allow_search = false
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/TabContainer/Changes/VBoxContainer" unique_id=1268697564]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="CommitMessage" type="TextEdit" parent="VBoxContainer/TabContainer/Changes/VBoxContainer/HBoxContainer" unique_id=289463898]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 40)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
placeholder_text = "Enter Commit Message"
|
||||
|
||||
[node name="Commit" type="Button" parent="VBoxContainer/TabContainer/Changes/VBoxContainer/HBoxContainer" unique_id=1863054490]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
text = "Commit"
|
||||
|
||||
[node name="Status" type="RichTextLabel" parent="VBoxContainer/TabContainer/Changes/VBoxContainer" unique_id=1087869543]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 120)
|
||||
layout_mode = 2
|
||||
bbcode_enabled = true
|
||||
text = "Branch: main"
|
||||
|
||||
[node name="Credit" type="RichTextLabel" parent="VBoxContainer/TabContainer/Changes/VBoxContainer" unique_id=1665117723]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 60)
|
||||
layout_mode = 2
|
||||
bbcode_enabled = true
|
||||
text = "Made by: [url=\"https://godotengine.org/asset-library/asset?user=Fxll3n\"]Fxll3n[/url]"
|
||||
fit_content = true
|
||||
scroll_active = false
|
||||
@@ -0,0 +1,152 @@
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
@onready var file_tree: Tree = %FileList
|
||||
@onready var commit_message: TextEdit = %CommitMessage
|
||||
@onready var status_log: RichTextLabel = %Status
|
||||
@onready var refresh_timer: Timer = Timer.new()
|
||||
|
||||
var git_executable = "git"
|
||||
var repo_path = ""
|
||||
|
||||
func _ready():
|
||||
repo_path = ProjectSettings.globalize_path("res://")
|
||||
refresh_status()
|
||||
|
||||
%FetchChanges.pressed.connect(refresh_status)
|
||||
%Commit.pressed.connect(_on_commit_pressed)
|
||||
%Pull.pressed.connect(_on_pull_pressed)
|
||||
%Push.pressed.connect(_on_push_pressed)
|
||||
%Credit.meta_clicked.connect(
|
||||
func(meta):
|
||||
OS.shell_open(str(meta))
|
||||
)
|
||||
|
||||
# Update periodicly.
|
||||
add_child(refresh_timer)
|
||||
refresh_timer.one_shot = true
|
||||
refresh_timer.start(10)
|
||||
refresh_timer.timeout.connect(
|
||||
func():
|
||||
refresh_status()
|
||||
refresh_timer.start(10)
|
||||
)
|
||||
|
||||
|
||||
func execute_git_command_sync(args: Array) -> Dictionary:
|
||||
var output = []
|
||||
|
||||
var exit_code = OS.execute(git_executable, args, output, true, false)
|
||||
|
||||
return {
|
||||
"exit_code": exit_code,
|
||||
"output": "\n".join(output)
|
||||
}
|
||||
|
||||
func execute_git_command_async(args: Array, callback: Callable):
|
||||
var script_path = "res://.godot/git_temp_command.sh" if OS.get_name() != "Windows" else "res://.godot/git_temp_command.bat"
|
||||
var file = FileAccess.open(script_path, FileAccess.WRITE)
|
||||
|
||||
if OS.get_name() == "Windows":
|
||||
file.store_string("@echo off\ncd /d \"" + repo_path + "\"\ngit " + " ".join(args))
|
||||
else:
|
||||
file.store_string("#!/bin/bash\ncd \"" + repo_path + "\"\ngit " + " ".join(args))
|
||||
file.close()
|
||||
|
||||
if OS.get_name() != "Windows":
|
||||
OS.execute("chmod", ["+x", ProjectSettings.globalize_path(script_path)])
|
||||
|
||||
# New thread so that Editor doesn't freeze when awaiting command results
|
||||
var thread = Thread.new()
|
||||
thread.start(_run_git_async.bind(script_path, callback))
|
||||
#thread.wait_to_finish()
|
||||
#thread.free()
|
||||
|
||||
func _run_git_async(script_path: String, callback: Callable):
|
||||
var output = []
|
||||
var exec_path = ProjectSettings.globalize_path(script_path)
|
||||
var exit_code = OS.execute(exec_path if OS.get_name() != "Windows" else "cmd.exe",
|
||||
[] if OS.get_name() != "Windows" else ["/c", exec_path],
|
||||
output, true, false)
|
||||
|
||||
var result = {
|
||||
"exit_code": exit_code,
|
||||
"output": "\n".join(output)
|
||||
}
|
||||
|
||||
# Call the callback on the main thread
|
||||
callback.call_deferred(result)
|
||||
|
||||
func refresh_status():
|
||||
var result = execute_git_command_sync(["status", "--porcelain"])
|
||||
|
||||
if result.exit_code != 0:
|
||||
status_log.text = "[color=red][b]Error[/b][/color]: Not a git repository or git not found"
|
||||
return
|
||||
|
||||
# Parse and display changes
|
||||
file_tree.clear()
|
||||
var root = file_tree.create_item()
|
||||
|
||||
for line in result.output.split("\n"):
|
||||
if line.strip_edges() == "":
|
||||
continue
|
||||
|
||||
var status = line.substr(0, 2)
|
||||
var file_path = line.substr(3)
|
||||
|
||||
var item = file_tree.create_item(root)
|
||||
item.set_text(0, get_status_icon(status) + " " + file_path)
|
||||
item.set_metadata(0, {"file": file_path, "status": status})
|
||||
|
||||
# Update status log
|
||||
var branch_result = execute_git_command_sync(["branch", "--show-current"])
|
||||
status_log.text = "[b]Branch[/b]: " + branch_result.output.strip_edges()
|
||||
|
||||
func get_status_icon(status: String) -> String:
|
||||
match status.strip_edges():
|
||||
"M", " M": return "[M]"
|
||||
"A", " A": return "[A]"
|
||||
"D", " D": return "[D]"
|
||||
"??": return "[?]"
|
||||
_: return "[*]"
|
||||
|
||||
func _on_commit_pressed():
|
||||
var message = commit_message.text.strip_edges()
|
||||
commit_message.text = ""
|
||||
if message == "":
|
||||
status_log.text = "[color=red][b]Error[/b][/color]: Commit message cannot be empty"
|
||||
return
|
||||
|
||||
# Stage all changes
|
||||
var stage_result = execute_git_command_sync(["add", "-A"])
|
||||
if stage_result.exit_code != 0:
|
||||
status_log.text = "[color=red][b]Error[/b][/color] staging files:\n" + stage_result.output
|
||||
return
|
||||
|
||||
# Commit
|
||||
var commit_result = execute_git_command_sync(["commit", "-m", message])
|
||||
status_log.text = commit_result.output
|
||||
|
||||
if commit_result.exit_code == 0:
|
||||
refresh_status()
|
||||
|
||||
func _on_pull_pressed():
|
||||
status_log.text = "Pulling... (this may take a moment)"
|
||||
%Pull.disabled = true
|
||||
|
||||
execute_git_command_async(["pull"], func(result):
|
||||
status_log.text = result.output if result.output != "" else "Pull completed"
|
||||
%Pull.disabled = false
|
||||
refresh_status()
|
||||
)
|
||||
|
||||
func _on_push_pressed():
|
||||
status_log.text = "Pushing... (this may take a moment)"
|
||||
%Push.disabled = true
|
||||
|
||||
execute_git_command_async(["push"], func(result):
|
||||
status_log.text = result.output if result.output != "" else "Push completed"
|
||||
%Push.disabled = false
|
||||
refresh_status()
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
uid://b7lkke108s0j0
|
||||
@@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="Fxll3n's Git Interface Plugin (FGIP)"
|
||||
description="A Godot 4.6+ GDScript plugin that adds a Git Interface in your editor dock."
|
||||
author="Fxll3n"
|
||||
version="v0.01-Alpha"
|
||||
script="fgi.gd"
|
||||
Reference in New Issue
Block a user