fix(Repository): separated git dir for submodules

This commit is contained in:
leo 2020-07-23 14:04:42 +08:00
parent 39e55a3f2d
commit 646a80a395
5 changed files with 93 additions and 77 deletions

View file

@ -28,22 +28,6 @@ namespace SourceGit {
}
}
/// <summary>
/// Interactive rebase sequence file.
/// </summary>
public static string InteractiveRebaseScript {
get;
private set;
}
/// <summary>
/// TODO file for interactive rebase.
/// </summary>
public static string InteractiveRebaseTodo {
get;
private set;
}
/// <summary>
/// Error handler.
/// </summary>
@ -66,6 +50,22 @@ namespace SourceGit {
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnAppStartup(object sender, StartupEventArgs e) {
// Use this app as a sequence editor?
var args = e.Args;
if (args.Length > 1) {
if (args[0] == "--interactive-rebase") {
if (args.Length < 3) {
Environment.Exit(1);
return;
}
File.WriteAllText(args[2], File.ReadAllText(args[1]));
}
Environment.Exit(0);
return;
}
// Try auto configure git via registry.
if (!IsGitConfigured) {
var root = RegistryKey.OpenBaseKey(
@ -81,23 +81,6 @@ namespace SourceGit {
}
}
// Files for interactive rebase.
InteractiveRebaseScript = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"SourceGit",
"rebase.bat");
InteractiveRebaseTodo = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"SourceGit",
"REBASE_TODO");
if (!File.Exists(InteractiveRebaseScript)) {
var folder = Path.GetDirectoryName(InteractiveRebaseScript);
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
File.WriteAllText(InteractiveRebaseScript, $"@echo off\ntype \"{InteractiveRebaseTodo}\" > .git\\rebase-merge\\git-rebase-todo");
File.WriteAllText(InteractiveRebaseTodo, "");
}
// Apply themes
if (Preference.UIUseLightTheme) {
foreach (var rs in Current.Resources.MergedDictionaries) {

View file

@ -59,11 +59,13 @@ namespace SourceGit.Git {
#region PROPERTIES_RUNTIME
[XmlIgnore] public Repository Parent = null;
[XmlIgnore] public string GitDir = null;
private List<Remote> cachedRemotes = new List<Remote>();
private List<Branch> cachedBranches = new List<Branch>();
private List<Tag> cachedTags = new List<Tag>();
private FileSystemWatcher watcher = null;
private FileSystemWatcher gitDirWatcher = null;
private FileSystemWatcher workingCopyWatcher = null;
private DispatcherTimer timer = null;
private bool isWatcherDisabled = false;
private long nextUpdateTags = 0;
@ -276,16 +278,41 @@ namespace SourceGit.Git {
LastOpenTime = DateTime.Now.ToFileTime();
isWatcherDisabled = false;
watcher = new FileSystemWatcher();
watcher.Path = Path;
watcher.Filter = "*";
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
watcher.IncludeSubdirectories = true;
watcher.Created += OnFSChanged;
watcher.Renamed += OnFSChanged;
watcher.Changed += OnFSChanged;
watcher.Deleted += OnFSChanged;
watcher.EnableRaisingEvents = true;
GitDir = ".git";
RunCommand("rev-parse --git-dir", line => {
GitDir = line;
});
if (!System.IO.Path.IsPathRooted(GitDir)) GitDir = System.IO.Path.Combine(Path, GitDir);
var checkGitDir = new DirectoryInfo(GitDir);
if (!checkGitDir.Exists) {
App.RaiseError("GIT_DIR for this repository NOT FOUND!");
return;
} else {
GitDir = checkGitDir.FullName;
}
gitDirWatcher = new FileSystemWatcher();
gitDirWatcher.Path = GitDir;
gitDirWatcher.Filter = "*";
gitDirWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
gitDirWatcher.IncludeSubdirectories = true;
gitDirWatcher.Created += OnGitDirFSChanged;
gitDirWatcher.Renamed += OnGitDirFSChanged;
gitDirWatcher.Changed += OnGitDirFSChanged;
gitDirWatcher.Deleted += OnGitDirFSChanged;
gitDirWatcher.EnableRaisingEvents = true;
workingCopyWatcher = new FileSystemWatcher();
workingCopyWatcher.Path = Path;
workingCopyWatcher.Filter = "*";
workingCopyWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
workingCopyWatcher.IncludeSubdirectories = true;
workingCopyWatcher.Created += OnWorkingCopyFSChanged;
workingCopyWatcher.Renamed += OnWorkingCopyFSChanged;
workingCopyWatcher.Changed += OnWorkingCopyFSChanged;
workingCopyWatcher.Deleted += OnWorkingCopyFSChanged;
workingCopyWatcher.EnableRaisingEvents = true;
timer = new DispatcherTimer();
timer.Tick += Tick;
@ -315,11 +342,14 @@ namespace SourceGit.Git {
cachedRemotes.Clear();
cachedTags.Clear();
watcher.EnableRaisingEvents = false;
watcher.Dispose();
gitDirWatcher.EnableRaisingEvents = false;
workingCopyWatcher.EnableRaisingEvents = false;
gitDirWatcher.Dispose();
workingCopyWatcher.Dispose();
timer.Stop();
watcher = null;
gitDirWatcher = null;
workingCopyWatcher = null;
timer = null;
featurePrefix = null;
releasePrefix = null;
@ -367,27 +397,27 @@ namespace SourceGit.Git {
}
}
private void OnFSChanged(object sender, FileSystemEventArgs e) {
private void OnGitDirFSChanged(object sender, FileSystemEventArgs e) {
if (string.IsNullOrEmpty(e.Name)) return;
if (e.Name.StartsWith("index")) return;
if (e.Name.StartsWith(".git", StringComparison.Ordinal)) {
if (e.Name.Equals(".git") || e.Name.StartsWith(".git\\index")) return;
if (e.Name.Equals(".gitignore") || e.Name.Equals(".gitattributes")) {
nextUpdateLocalChanges = DateTime.Now.AddSeconds(1.5).ToFileTime();
} else if (e.Name.StartsWith(".git\\refs\\tags", StringComparison.Ordinal)) {
nextUpdateTags = DateTime.Now.AddSeconds(.5).ToFileTime();
} else if (e.Name.StartsWith(".git\\refs\\stash", StringComparison.Ordinal)) {
nextUpdateStashes = DateTime.Now.AddSeconds(.5).ToFileTime();
} else if (e.Name.EndsWith("_HEAD", StringComparison.Ordinal) ||
e.Name.StartsWith(".git\\refs\\heads", StringComparison.Ordinal) ||
e.Name.StartsWith(".git\\refs\\remotes", StringComparison.Ordinal)) {
nextUpdateTree = DateTime.Now.AddSeconds(.5).ToFileTime();
}
} else {
nextUpdateLocalChanges = DateTime.Now.AddSeconds(1.5).ToFileTime();
if (e.Name.StartsWith("refs\\tags", StringComparison.Ordinal)) {
nextUpdateTags = DateTime.Now.AddSeconds(.5).ToFileTime();
} else if (e.Name.StartsWith("refs\\stash", StringComparison.Ordinal)) {
nextUpdateStashes = DateTime.Now.AddSeconds(.5).ToFileTime();
} else if (e.Name.EndsWith("_HEAD", StringComparison.Ordinal) ||
e.Name.StartsWith("refs\\heads", StringComparison.Ordinal) ||
e.Name.StartsWith("refs\\remotes", StringComparison.Ordinal)) {
nextUpdateTree = DateTime.Now.AddSeconds(.5).ToFileTime();
}
}
private void OnWorkingCopyFSChanged(object sender, FileSystemEventArgs e) {
if (string.IsNullOrEmpty(e.Name)) return;
if (e.Name == ".git" || e.Name.StartsWith(".git\\")) return;
nextUpdateLocalChanges = DateTime.Now.AddSeconds(1.5).ToFileTime();
}
#endregion
#region METHOD_GITCOMMANDS

View file

@ -383,11 +383,10 @@ namespace SourceGit.UI {
#region MERGE_ABORTS
public void DetectMergeState() {
var gitDir = Path.Combine(repo.Path, ".git");
var cherryPickMerge = Path.Combine(gitDir, "CHERRY_PICK_HEAD");
var rebaseMerge = Path.Combine(gitDir, "REBASE_HEAD");
var revertMerge = Path.Combine(gitDir, "REVERT_HEAD");
var otherMerge = Path.Combine(gitDir, "MERGE_HEAD");
var cherryPickMerge = Path.Combine(repo.GitDir, "CHERRY_PICK_HEAD");
var rebaseMerge = Path.Combine(repo.GitDir, "REBASE_HEAD");
var revertMerge = Path.Combine(repo.GitDir, "REVERT_HEAD");
var otherMerge = Path.Combine(repo.GitDir, "MERGE_HEAD");
if (File.Exists(cherryPickMerge)) {
abortCommand = "cherry-pick";

View file

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
@ -255,7 +257,8 @@ namespace SourceGit.UI {
}
private void Start(object sender, RoutedEventArgs e) {
var stream = new FileStream(App.InteractiveRebaseTodo, FileMode.Create);
var temp = Path.GetTempFileName();
var stream = new FileStream(temp, FileMode.Create);
var writer = new StreamWriter(stream);
for (int i = Items.Count - 1; i >= 0; i--) {
@ -263,19 +266,19 @@ namespace SourceGit.UI {
switch ((InteractiveRebaseMode)item.Mode) {
case InteractiveRebaseMode.Pick:
writer.WriteLine($"pick {item.Commit.ShortSHA} {item.Subject}");
writer.WriteLine($"p {item.Commit.ShortSHA} {item.Subject}");
break;
case InteractiveRebaseMode.Reword:
writer.WriteLine($"reword {item.Commit.ShortSHA} {item.Subject}");
writer.WriteLine($"r {item.Commit.ShortSHA} {item.Subject}");
break;
case InteractiveRebaseMode.Squash:
writer.WriteLine($"squash {item.Commit.ShortSHA} {item.Subject}");
writer.WriteLine($"s {item.Commit.ShortSHA} {item.Subject}");
break;
case InteractiveRebaseMode.Fixup:
writer.WriteLine($"fixup {item.Commit.ShortSHA} {item.Subject}");
writer.WriteLine($"f {item.Commit.ShortSHA} {item.Subject}");
break;
case InteractiveRebaseMode.Drop:
writer.WriteLine($"drop {item.Commit.ShortSHA} {item.Subject}");
writer.WriteLine($"d {item.Commit.ShortSHA} {item.Subject}");
break;
}
}
@ -286,7 +289,8 @@ namespace SourceGit.UI {
stream.Close();
repo.SetWatcherEnabled(false);
var errs = repo.RunCommand($"-c sequence.editor=\"\\\"{App.InteractiveRebaseScript}\\\"\" rebase -i {from}^", null);
var editor = Process.GetCurrentProcess().MainModule.FileName;
var errs = repo.RunCommand($"-c sequence.editor=\"\\\"{editor}\\\" --interactive-rebase \\\"{temp}\\\"\" rebase -i {from}^", null);
repo.AssertCommand(errs);
Close();

View file

@ -96,7 +96,7 @@ namespace SourceGit.UI {
/// </summary>
public void LoadMergeMessage() {
if (string.IsNullOrEmpty(txtCommitMsg.Text)) {
var mergeMsgFile = Path.Combine(Repo.Path, ".git", "MERGE_MSG");
var mergeMsgFile = Path.Combine(Repo.GitDir, "MERGE_MSG");
if (!File.Exists(mergeMsgFile)) return;
var content = File.ReadAllText(mergeMsgFile);