123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // Copyright (c) 2025 TerraByte Inc.
- //
- // This script creates a custom Unity Editor window called "Arbitrator" to compare
- // local Git changes with the tracked remote branch using the LibGit2Sharp library.
- //
- // HOW TO USE:
- // 1. Ensure you have manually installed the LibGit2Sharp v0.27.0 package.
- // 2. Create an "Editor" folder in your Assets directory if you don't have one.
- // 3. Save this script as "Arbitrator.cs" inside the "Editor" folder.
- // 4. In Unity, open the window from the top menu: Terra > Arbitrator.
- // 5. Click the "Compare with Cloud" button. Results will appear in the console.
- using System;
- using System.IO;
- using UnityEngine;
- using UnityEditor;
- using LibGit2Sharp;
- namespace Terra.Arbitrator
- {
- public class Arbitrator : EditorWindow
- {
- // Creates a menu item in the Unity Editor to open this window.
- [MenuItem("Terra/Arbitrator")]
- public static void ShowWindow()
- {
- // Get an existing open window or if none, make a new one.
- GetWindow<Arbitrator>("Arbitrator");
- }
- // This method is called to draw the contents of the editor window.
- private void OnGUI()
- {
- // Add some descriptive text to the window.
- EditorGUILayout.LabelField("Compare local changes against the cloud.", EditorStyles.boldLabel);
- EditorGUILayout.HelpBox("This tool will fetch the latest state from the remote repository and show you which files have been added, modified, or deleted locally.", MessageType.Info);
- // Render a button. If the user clicks it, call our main logic function.
- if (GUILayout.Button("Compare with Cloud", GUILayout.Height(40)))
- {
- CompareLocalToRemote();
- }
- }
- /// <summary>
- /// The core function that performs the fetch and diff operations.
- /// </summary>
- private static void CompareLocalToRemote()
- {
- // The project root is one level above the "Assets" directory.
- var projectRoot = Directory.GetParent(Application.dataPath)?.FullName;
- try
- {
- // Use a 'using' statement to ensure the repository object is properly disposed of.
- // This opens the repository at the root of your Unity project.
- using var repo = new Repository(projectRoot);
- Debug.Log("Repository opened successfully.");
- // --- Step 1: Fetch the latest state from the remote ---
- // Get the primary remote, which is typically named "origin".
- var remote = repo.Network.Remotes["origin"];
- if (remote == null)
- {
- Debug.LogError("No remote named 'origin' was found. Please configure a remote for your repository.");
- return;
- }
- // IMPORTANT: For private repositories, you'll need to provide credentials.
- // This is a more advanced topic involving Personal Access Tokens (PATs).
- var fetchOptions = new FetchOptions();
-
- Debug.Log($"Fetching latest changes from '{remote.Name}' at {remote.Url}...");
- Commands.Fetch(repo, remote.Name, Array.Empty<string>(), fetchOptions, null);
- Debug.Log("Fetch complete.");
- // --- Step 2: Identify branches to compare ---
- var currentBranch = repo.Head;
- var remoteBranch = currentBranch.TrackedBranch;
- if (remoteBranch == null || !remoteBranch.IsRemote)
- {
- Debug.LogError($"The current branch '{currentBranch.FriendlyName}' is not tracking a remote branch. Set the upstream branch using 'git branch --set-upstream-to=origin/{currentBranch.FriendlyName}'.");
- return;
- }
-
- Debug.Log($"Comparing local '{currentBranch.FriendlyName}' against remote '{remoteBranch.FriendlyName}'.");
- // --- Step 3: Perform the Diff ---
- // We compare the tree from the latest commit on the remote branch
- // against the files currently in your working directory.
- var remoteTree = remoteBranch.Tip.Tree;
- var changes = repo.Diff.Compare<TreeChanges>(remoteTree, DiffTargets.Index | DiffTargets.WorkingDirectory);
- // --- Step 4: Log the Results ---
- if (changes.Count == 0)
- {
- Debug.Log("--- STATUS: You are up to date! No differences found with the remote branch. ---");
- }
- else
- {
- Debug.Log($"--- STATUS: Found {changes.Count} changes. ---");
- foreach (var change in changes)
- {
- // Log the status (Added, Deleted, Modified) and the file path.
- // The color-coding helps to quickly see the status.
- switch (change.Status)
- {
- case ChangeKind.Added:
- Debug.Log($"<color=green>ADDED: {change.Path}</color>");
- break;
- case ChangeKind.Deleted:
- Debug.Log($"<color=red>DELETED: {change.Path}</color>");
- break;
- case ChangeKind.Modified:
- Debug.Log($"<color=orange>MODIFIED: {change.Path}</color>");
- break;
- case ChangeKind.Unmodified:
- case ChangeKind.Renamed:
- case ChangeKind.Copied:
- case ChangeKind.Ignored:
- case ChangeKind.Untracked:
- case ChangeKind.TypeChanged:
- case ChangeKind.Unreadable:
- case ChangeKind.Conflicted:
- default:
- Debug.Log($"{change.Status.ToString().ToUpper()}: {change.Path}");
- break;
- }
- }
- Debug.Log("--- End of Report ---");
- }
- }
- catch (RepositoryNotFoundException)
- {
- Debug.LogError("Error: This project is not a Git repository or the .git folder is missing. Please initialize a repository first.");
- }
- catch (Exception ex)
- {
- // Catch any other exceptions that might occur (e.g., network issues during fetch).
- Debug.LogError($"An unexpected error occurred: {ex.Message}");
- Debug.LogException(ex);
- }
- }
- }
- }
|