Exemple #1
0
        public override bool IsFetchedRepoPasswordCorrect(string password)
        {
            string password_check_file_path = Path.Combine(TargetFolder, ".sparkleshare");

            if (!File.Exists(password_check_file_path))
            {
                SparkleGit git    = new SparkleGit(TargetFolder, "show HEAD:.sparkleshare");
                string     output = git.StartAndReadStandardOutput();

                if (git.ExitCode == 0)
                {
                    File.WriteAllText(password_check_file_path, output);
                }
                else
                {
                    return(false);
                }
            }

            Process process = new Process();

            process.EnableRaisingEvents              = true;
            process.StartInfo.WorkingDirectory       = TargetFolder;
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardInput  = true;
            process.StartInfo.CreateNoWindow         = true;

            process.StartInfo.FileName  = "openssl";
            process.StartInfo.Arguments = "enc -d -aes-256-cbc -base64 -pass stdin " +
                                          "-in \"" + password_check_file_path + "\"";

            SparkleLogger.LogInfo("Cmd | " + System.IO.Path.GetFileName(process.StartInfo.WorkingDirectory),
                                  System.IO.Path.GetFileName(process.StartInfo.FileName) + " " + process.StartInfo.Arguments);

            process.Start();
            process.StandardInput.WriteLine(password);
            process.WaitForExit();

            if (process.ExitCode == 0)
            {
                File.Delete(password_check_file_path);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #2
0
        private void AddWarnings()
        {
            if (this.warnings.Count > 0)
            {
                return;
            }

            SparkleGit git    = new SparkleGit(TargetFolder, "config --global core.excludesfile");
            string     output = git.StartAndReadStandardOutput();

            if (string.IsNullOrEmpty(output))
            {
                return;
            }
            else
            {
                this.warnings.Add("You seem to have a system wide ‘gitignore’ file, this may affect SparkleShare files.");
            }
        }
        // Commits the made changes
        private void Commit(string message)
        {
            SparkleGit git;

            if (!this.user_is_set)
            {
                git = new SparkleGit(LocalPath, "config user.name \"" + base.local_config.User.Name + "\"");
                git.StartAndWaitForExit();

                git = new SparkleGit(LocalPath, "config user.email \"" + base.local_config.User.Email + "\"");
                git.StartAndWaitForExit();

                this.user_is_set = true;
            }

            git = new SparkleGit(LocalPath, "commit --all --message=\"" + message + "\" " +
                                 "--author=\"" + base.local_config.User.Name + " <" + base.local_config.User.Email + ">\"");

            git.StartAndReadStandardOutput();
        }
        private void ResolveConflict()
        {
            // This is a list of conflict status codes that Git uses, their
            // meaning, and how SparkleShare should handle them.
            //
            // DD    unmerged, both deleted    -> Do nothing
            // AU    unmerged, added by us     -> Use server's, save ours as a timestamped copy
            // UD    unmerged, deleted by them -> Use ours
            // UA    unmerged, added by them   -> Use server's, save ours as a timestamped copy
            // DU    unmerged, deleted by us   -> Use server's
            // AA    unmerged, both added      -> Use server's, save ours as a timestamped copy
            // UU    unmerged, both modified   -> Use server's, save ours as a timestamped copy
            // ??    unmerged, new files       -> Stage the new files
            //
            // Note that a rebase merge works by replaying each commit from the working branch on
            // top of the upstream branch. Because of this, when a merge conflict happens the
            // side reported as 'ours' is the so-far rebased series, starting with upstream,
            // and 'theirs' is the working branch. In other words, the sides are swapped.
            //
            // So: 'ours' means the 'server's version' and 'theirs' means the 'local version' after this comment

            SparkleGit git_status = new SparkleGit(LocalPath, "status --porcelain");
            string     output     = git_status.StartAndReadStandardOutput();

            string [] lines         = output.Split("\n".ToCharArray());
            bool      changes_added = false;

            foreach (string line in lines)
            {
                string conflicting_path = line.Substring(3);
                conflicting_path = EnsureSpecialCharacters(conflicting_path);
                conflicting_path = conflicting_path.Replace("\"", "\\\"");

                SparkleLogger.LogInfo("Git", Name + " | Conflict type: " + line);

                // Ignore conflicts in the .sparkleshare file and use the local version
                if (conflicting_path.EndsWith(".sparkleshare") || conflicting_path.EndsWith(".empty"))
                {
                    // Recover local version
                    SparkleGit git_theirs = new SparkleGit(LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
                    git_theirs.StartAndWaitForExit();

                    File.SetAttributes(Path.Combine(LocalPath, conflicting_path), FileAttributes.Hidden);
                    changes_added = true;

                    continue;
                }

                // Both the local and server version have been modified
                if (line.StartsWith("UU") || line.StartsWith("AA") ||
                    line.StartsWith("AU") || line.StartsWith("UA"))
                {
                    // Recover local version
                    SparkleGit git_theirs = new SparkleGit(LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
                    git_theirs.StartAndWaitForExit();

                    // Append a timestamp to local version.
                    // Windows doesn't allow colons in the file name, so
                    // we use "h" between the hours and minutes instead.
                    string timestamp  = DateTime.Now.ToString("MMM d H\\hmm");
                    string their_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_their_path       = Path.Combine(LocalPath, their_path);

                    File.Move(abs_conflicting_path, abs_their_path);

                    // Recover server version
                    SparkleGit git_ours = new SparkleGit(LocalPath, "checkout --ours \"" + conflicting_path + "\"");
                    git_ours.StartAndWaitForExit();

                    changes_added = true;

                    // The local version has been modified, but the server version was removed
                }
                else if (line.StartsWith("DU"))
                {
                    // 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
                    SparkleGit git_add = new SparkleGit(LocalPath, "add \"" + conflicting_path + "\"");
                    git_add.StartAndWaitForExit();

                    changes_added = true;
                }
            }

            Add();
            SparkleGit git;

            if (changes_added)
            {
                git = new SparkleGit(LocalPath, "rebase --continue");
            }
            else
            {
                git = new SparkleGit(LocalPath, "rebase --skip");
            }

            git.StartInfo.RedirectStandardOutput = false;
            git.StartAndWaitForExit();
        }
Exemple #5
0
        private List <SparkleChangeSet> GetChangeSetsInternal(string path)
        {
            List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();
            SparkleGit git;

            if (path == null)
            {
                git = new SparkleGit(LocalPath, "log --since=1.month --raw --find-renames --date=iso " +
                                     "--format=medium --no-color --no-merges");
            }
            else
            {
                path = path.Replace("\\", "/");

                git = new SparkleGit(LocalPath, "log --raw --find-renames --date=iso " +
                                     "--format=medium --no-color --no-merges -- \"" + path + "\"");
            }

            string output = git.StartAndReadStandardOutput();

            if (path == null && string.IsNullOrWhiteSpace(output))
            {
                git = new SparkleGit(LocalPath, "log -n 75 --raw --find-renames --date=iso " +
                                     "--format=medium --no-color --no-merges");

                output = git.StartAndReadStandardOutput();
            }

            string []     lines   = output.Split("\n".ToCharArray());
            List <string> entries = new List <string> ();

            // Split up commit entries
            int    line_number = 0;
            bool   first_pass = true;
            string entry = "", last_entry = "";

            foreach (string line in lines)
            {
                if (line.StartsWith("commit") && !first_pass)
                {
                    entries.Add(entry);
                    entry       = "";
                    line_number = 0;
                }
                else
                {
                    first_pass = false;
                }

                // Only parse first 250 files to prevent memory issues
                if (line_number < 250)
                {
                    entry += line + "\n";
                    line_number++;
                }

                last_entry = entry;
            }

            entries.Add(last_entry);

            // Parse commit entries
            foreach (string log_entry in entries)
            {
                Match match = this.log_regex.Match(log_entry);

                if (!match.Success)
                {
                    match = this.merge_regex.Match(log_entry);

                    if (!match.Success)
                    {
                        continue;
                    }
                }

                SparkleChangeSet change_set = new SparkleChangeSet();

                change_set.Folder    = new SparkleFolder(Name);
                change_set.Revision  = match.Groups [1].Value;
                change_set.User      = new SparkleUser(match.Groups [2].Value, match.Groups [3].Value);
                change_set.RemoteUrl = RemoteUrl;

                change_set.Timestamp = new DateTime(int.Parse(match.Groups [4].Value),
                                                    int.Parse(match.Groups [5].Value), int.Parse(match.Groups [6].Value),
                                                    int.Parse(match.Groups [7].Value), int.Parse(match.Groups [8].Value),
                                                    int.Parse(match.Groups [9].Value));

                string time_zone    = match.Groups [10].Value;
                int    our_offset   = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Hours;
                int    their_offset = int.Parse(time_zone.Substring(0, 3));
                change_set.Timestamp = change_set.Timestamp.AddHours(their_offset * -1);
                change_set.Timestamp = change_set.Timestamp.AddHours(our_offset);

                string [] entry_lines = log_entry.Split("\n".ToCharArray());

                // Parse file list. Lines containing file changes start with ":"
                foreach (string entry_line in entry_lines)
                {
                    // Skip lines containing backspace characters
                    if (!entry_line.StartsWith(":") || entry_line.Contains("\\177"))
                    {
                        continue;
                    }

                    string file_path = entry_line.Substring(39);

                    if (file_path.Equals(".sparkleshare"))
                    {
                        continue;
                    }

                    string type_letter      = entry_line [37].ToString();
                    bool   change_is_folder = false;

                    if (file_path.EndsWith(".empty"))
                    {
                        file_path        = file_path.Substring(0, file_path.Length - ".empty".Length);
                        change_is_folder = true;
                    }

                    try {
                        file_path = EnsureSpecialCharacters(file_path);
                    } catch (Exception e) {
                        SparkleLogger.LogInfo("Local", "Error parsing file name '" + file_path + "'", e);
                        continue;
                    }

                    file_path = file_path.Replace("\\\"", "\"");

                    SparkleChange change = new SparkleChange()
                    {
                        Path      = file_path,
                        IsFolder  = change_is_folder,
                        Timestamp = change_set.Timestamp,
                        Type      = SparkleChangeType.Added
                    };

                    if (type_letter.Equals("R"))
                    {
                        int tab_pos = entry_line.LastIndexOf("\t");
                        file_path = entry_line.Substring(42, tab_pos - 42);
                        string to_file_path = entry_line.Substring(tab_pos + 1);

                        try {
                            file_path = EnsureSpecialCharacters(file_path);
                        } catch (Exception e) {
                            SparkleLogger.LogInfo("Local", "Error parsing file name '" + file_path + "'", e);
                            continue;
                        }

                        try {
                            to_file_path = EnsureSpecialCharacters(to_file_path);
                        } catch (Exception e) {
                            SparkleLogger.LogInfo("Local", "Error parsing file name '" + to_file_path + "'", e);
                            continue;
                        }

                        file_path    = file_path.Replace("\\\"", "\"");
                        to_file_path = to_file_path.Replace("\\\"", "\"");

                        if (file_path.EndsWith(".empty"))
                        {
                            file_path        = file_path.Substring(0, file_path.Length - 6);
                            change_is_folder = true;
                        }

                        if (to_file_path.EndsWith(".empty"))
                        {
                            to_file_path     = to_file_path.Substring(0, to_file_path.Length - 6);
                            change_is_folder = true;
                        }

                        change.Path        = file_path;
                        change.MovedToPath = to_file_path;
                        change.Type        = SparkleChangeType.Moved;
                    }
                    else if (type_letter.Equals("M"))
                    {
                        change.Type = SparkleChangeType.Edited;
                    }
                    else if (type_letter.Equals("D"))
                    {
                        change.Type = SparkleChangeType.Deleted;
                    }

                    change_set.Changes.Add(change);
                }

                // Group commits per user, per day
                if (change_sets.Count > 0 && path == null)
                {
                    SparkleChangeSet last_change_set = change_sets [change_sets.Count - 1];

                    if (change_set.Timestamp.Year == last_change_set.Timestamp.Year &&
                        change_set.Timestamp.Month == last_change_set.Timestamp.Month &&
                        change_set.Timestamp.Day == last_change_set.Timestamp.Day &&
                        change_set.User.Name.Equals(last_change_set.User.Name))
                    {
                        last_change_set.Changes.AddRange(change_set.Changes);

                        if (DateTime.Compare(last_change_set.Timestamp, change_set.Timestamp) < 1)
                        {
                            last_change_set.FirstTimestamp = last_change_set.Timestamp;
                            last_change_set.Timestamp      = change_set.Timestamp;
                            last_change_set.Revision       = change_set.Revision;
                        }
                        else
                        {
                            last_change_set.FirstTimestamp = change_set.Timestamp;
                        }
                    }
                    else
                    {
                        change_sets.Add(change_set);
                    }
                }
                else
                {
                    // Don't show removals or moves in the revision list of a file
                    if (path != null)
                    {
                        List <SparkleChange> changes_to_skip = new List <SparkleChange> ();

                        foreach (SparkleChange change in change_set.Changes)
                        {
                            if ((change.Type == SparkleChangeType.Deleted || change.Type == SparkleChangeType.Moved) &&
                                change.Path.Equals(path))
                            {
                                changes_to_skip.Add(change);
                            }
                        }

                        foreach (SparkleChange change_to_skip in changes_to_skip)
                        {
                            change_set.Changes.Remove(change_to_skip);
                        }
                    }

                    change_sets.Add(change_set);
                }
            }

            return(change_sets);
        }
Exemple #6
0
        private void ResolveConflict()
        {
            // This is a list of conflict status codes that Git uses, their
            // meaning, and how SparkleShare should handle them.
            //
            // DD    unmerged, both deleted    -> Do nothing
            // AU    unmerged, added by us     -> Use server's, save ours as a timestamped copy
            // UD    unmerged, deleted by them -> Use ours
            // UA    unmerged, added by them   -> Use server's, save ours as a timestamped copy
            // DU    unmerged, deleted by us   -> Use server's
            // AA    unmerged, both added      -> Use server's, save ours as a timestamped copy
            // UU    unmerged, both modified   -> Use server's, save ours as a timestamped copy
            // ??    unmerged, new files       -> Stage the new files

            SparkleGit git_status = new SparkleGit(LocalPath, "status --porcelain");
            string     output     = git_status.StartAndReadStandardOutput();

            string [] lines = output.Split("\n".ToCharArray());
            bool      trigger_conflict_event = false;

            foreach (string line in lines)
            {
                string conflicting_path = line.Substring(3);
                conflicting_path = EnsureSpecialCharacters(conflicting_path);
                conflicting_path = conflicting_path.Trim("\"".ToCharArray());

                // Remove possible rename indicators
                string [] separators = { " -> \"", " -> " };
                foreach (string separator in separators)
                {
                    if (conflicting_path.Contains(separator))
                    {
                        conflicting_path = conflicting_path.Substring(
                            conflicting_path.IndexOf(separator) + separator.Length);
                    }
                }

                SparkleLogger.LogInfo("Git", Name + " | Conflict type: " + line);

                // Ignore conflicts in hidden files and use the local versions
                if (conflicting_path.EndsWith(".sparkleshare") || conflicting_path.EndsWith(".empty"))
                {
                    SparkleLogger.LogInfo("Git", Name + " | Ignoring conflict in special file: " + conflicting_path);

                    // Recover local version
                    SparkleGit git_ours = new SparkleGit(LocalPath, "checkout --ours \"" + conflicting_path + "\"");
                    git_ours.StartAndWaitForExit();

                    string abs_conflicting_path = Path.Combine(LocalPath, conflicting_path);

                    if (File.Exists(abs_conflicting_path))
                    {
                        File.SetAttributes(abs_conflicting_path, FileAttributes.Hidden);
                    }

                    continue;
                }

                SparkleLogger.LogInfo("Git", Name + " | Resolving: " + conflicting_path);

                // Both the local and server version have been modified
                if (line.StartsWith("UU") || line.StartsWith("AA") ||
                    line.StartsWith("AU") || line.StartsWith("UA"))
                {
                    // Recover local version
                    SparkleGit git_ours = new SparkleGit(LocalPath, "checkout --ours \"" + conflicting_path + "\"");
                    git_ours.StartAndWaitForExit();

                    // Append a timestamp to local version.
                    // Windows doesn't allow colons in the file name, so
                    // 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(LocalPath, our_path);

                    if (File.Exists(abs_conflicting_path) && !File.Exists(abs_our_path))
                    {
                        File.Move(abs_conflicting_path, abs_our_path);
                    }

                    // Recover server version
                    SparkleGit git_theirs = new SparkleGit(LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
                    git_theirs.StartAndWaitForExit();

                    trigger_conflict_event = true;


                    // The server version has been modified, but the local version was removed
                }
                else if (line.StartsWith("DU"))
                {
                    // 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
                    SparkleGit git_add = new SparkleGit(LocalPath, "add \"" + conflicting_path + "\"");
                    git_add.StartAndWaitForExit();


                    // The local version has been modified, but the server version was removed
                }
                else if (line.StartsWith("UD"))
                {
                    // Recover server version
                    SparkleGit git_theirs = new SparkleGit(LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
                    git_theirs.StartAndWaitForExit();


                    // Server and local versions were removed
                }
                else if (line.StartsWith("DD"))
                {
                    SparkleLogger.LogInfo("Git", Name + " | No need to resolve: " + line);

                    // New local files
                }
                else if (line.StartsWith("??"))
                {
                    SparkleLogger.LogInfo("Git", Name + " | Found new file, no need to resolve: " + line);
                }
                else
                {
                    SparkleLogger.LogInfo("Git", Name + " | Don't know what to do with: " + line);
                }
            }

            Add();

            SparkleGit git = new SparkleGit(LocalPath, "commit --message \"Conflict resolution by SparkleShare\"");

            git.StartInfo.RedirectStandardOutput = false;
            git.StartAndWaitForExit();

            if (trigger_conflict_event)
            {
                OnConflictResolved();
            }
        }