git repo: Keep original plus both diverging versions on conflicts. Closes #1716

This commit is contained in:
Hylke Bons 2017-12-16 17:56:13 +01:00
parent f737a5bcc3
commit 8c8a5a460e
2 changed files with 58 additions and 29 deletions

View file

@ -490,28 +490,28 @@ namespace Sparkles.Git {
bool trigger_conflict_event = false; bool trigger_conflict_event = false;
foreach (string line in lines) { foreach (string line in lines) {
string conflicting_path = line.Substring (3); string conflicting_file_path = line.Substring (3);
conflicting_path = EnsureSpecialCharacters (conflicting_path); conflicting_file_path = EnsureSpecialCharacters (conflicting_file_path);
conflicting_path = conflicting_path.Trim ("\"".ToCharArray ()); conflicting_file_path = conflicting_file_path.Trim ("\"".ToCharArray ());
// Remove possible rename indicators // Remove possible rename indicators
string [] separators = {" -> \"", " -> "}; string [] separators = {" -> \"", " -> "};
foreach (string separator in separators) { foreach (string separator in separators) {
if (conflicting_path.Contains (separator)) if (conflicting_file_path.Contains (separator))
conflicting_path = conflicting_path.Substring (conflicting_path.IndexOf (separator) + separator.Length); conflicting_file_path = conflicting_file_path.Substring (conflicting_file_path.IndexOf (separator) + separator.Length);
} }
Logger.LogInfo ("Git", Name + " | Conflict type: " + line); Logger.LogInfo ("Git", Name + " | Conflict type: " + line);
// Ignore conflicts in hidden files and use the local versions // Ignore conflicts in hidden files and use the local versions
if (conflicting_path.EndsWith (".sparkleshare") || conflicting_path.EndsWith (".empty")) { if (conflicting_file_path.EndsWith (".sparkleshare") || conflicting_file_path.EndsWith (".empty")) {
Logger.LogInfo ("Git", Name + " | Ignoring conflict in special file: " + conflicting_path); Logger.LogInfo ("Git", Name + " | Ignoring conflict in special file: " + conflicting_file_path);
// Recover local version // Recover local version
var git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_path + "\""); var git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_file_path + "\"");
git_ours.StartAndWaitForExit (); git_ours.StartAndWaitForExit ();
string abs_conflicting_path = Path.Combine (LocalPath, conflicting_path); string abs_conflicting_path = Path.Combine (LocalPath, conflicting_file_path);
if (File.Exists (abs_conflicting_path)) if (File.Exists (abs_conflicting_path))
File.SetAttributes (abs_conflicting_path, FileAttributes.Hidden); File.SetAttributes (abs_conflicting_path, FileAttributes.Hidden);
@ -519,43 +519,66 @@ namespace Sparkles.Git {
continue; continue;
} }
Logger.LogInfo ("Git", Name + " | Resolving: " + conflicting_path); Logger.LogInfo ("Git", Name + " | Resolving: " + conflicting_file_path);
// Both the local and server version have been modified // Both the local and server version have been modified
if (line.StartsWith ("UU") || line.StartsWith ("AA") || if (line.StartsWith ("UU") || line.StartsWith ("AA") ||
line.StartsWith ("AU") || line.StartsWith ("UA")) { line.StartsWith ("AU") || line.StartsWith ("UA")) {
// Get the author name of the conflicting version
var git_log = new GitCommand (LocalPath, "log -n 1 FETCH_HEAD --pretty=format:%an " + conflicting_file_path);
string other_author_name = git_log.StartAndReadStandardOutput ();
// Generate distinguishing names for both versions of the file
string clue_A = string.Format (" (by {0})", base.local_config.User.Name);
string clue_B = string.Format (" (by {0})", other_author_name);
if (base.local_config.User.Name == other_author_name) {
clue_A = " (A)";
clue_B = " (B)";
}
string file_name_A = Path.GetFileNameWithoutExtension (conflicting_file_path) + clue_A + Path.GetExtension (conflicting_file_path);
string file_name_B = Path.GetFileNameWithoutExtension (conflicting_file_path) + clue_B + Path.GetExtension (conflicting_file_path);
string abs_conflicting_file_path = Path.Combine (LocalPath, conflicting_file_path);
string abs_file_path_A = Path.Combine (Path.GetDirectoryName (abs_conflicting_file_path), file_name_A);
string abs_file_path_B = Path.Combine (Path.GetDirectoryName (abs_conflicting_file_path), file_name_B);
// Recover local version // Recover local version
var git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_path + "\""); var git_checkout_A = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_file_path + "\"");
git_ours.StartAndWaitForExit (); git_checkout_A.StartAndWaitForExit ();
// Append a timestamp to local version. if (File.Exists (abs_conflicting_file_path) && !File.Exists (abs_file_path_A))
// Windows doesn't allow colons in the file name, so File.Move (abs_conflicting_file_path, abs_file_path_A);
// we use "h" between the hours and minutes instead.
string timestamp = DateTime.Now.ToString ("MMM d H\\hmm");
string our_path = Path.GetFileNameWithoutExtension (conflicting_path) +
" (" + base.local_config.User.Name + ", " + timestamp + ")" + Path.GetExtension (conflicting_path);
string abs_conflicting_path = Path.Combine (LocalPath, conflicting_path);
string abs_our_path = Path.Combine (Path.GetDirectoryName (abs_conflicting_path), our_path);
if (File.Exists (abs_conflicting_path) && !File.Exists (abs_our_path))
File.Move (abs_conflicting_path, abs_our_path);
// Recover server version // Recover server version
var git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_path + "\""); var git_checkout_B = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_file_path + "\"");
git_theirs.StartAndWaitForExit (); git_checkout_B.StartAndWaitForExit ();
if (File.Exists (abs_conflicting_file_path) && !File.Exists (abs_file_path_B))
File.Move (abs_conflicting_file_path, abs_file_path_B);
// Recover original (before both versions diverged)
var git_checkout = new GitCommand (LocalPath, "checkout ORIG_HEAD^ \"" + conflicting_file_path + "\"");
git_checkout.StartAndWaitForExit ();
trigger_conflict_event = true; trigger_conflict_event = true;
// The server version has been modified, but the local version was removed // The server version has been modified, but the local version was removed
} else if (line.StartsWith ("DU")) { } else if (line.StartsWith ("DU")) {
// The modified local version is already in the checkout, so it just needs to be added. // The modified local version is already in the checkout, so it just needs to be added.
// We need to specifically mention the file, so we can't reuse the Add () method // We need to specifically mention the file, so we can't reuse the Add () method
var git_add = new GitCommand (LocalPath, "add \"" + conflicting_path + "\""); var git_add = new GitCommand (LocalPath, "add \"" + conflicting_file_path + "\"");
git_add.StartAndWaitForExit (); git_add.StartAndWaitForExit ();
@ -563,7 +586,7 @@ namespace Sparkles.Git {
} else if (line.StartsWith ("UD")) { } else if (line.StartsWith ("UD")) {
// Recover server version // Recover server version
var git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_path + "\""); var git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_file_path + "\"");
git_theirs.StartAndWaitForExit (); git_theirs.StartAndWaitForExit ();

View file

@ -1,3 +1,9 @@
2.0.1 (???):
- Fix files created by conflict resolution being moved to the root folder
- On conflicts, both diverging versions plus the original version are kept
2.0.0 for Linux, Mac and Windows (Sun Sep 10, 2017): 2.0.0 for Linux, Mac and Windows (Sun Sep 10, 2017):
SparkleShare 2.0 is a clean break and will be incompatible with SparkleShare 2.0 is a clean break and will be incompatible with