Пример #1
0
        public override bool CheckForRemoteChanges()
        {
            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Checking for remote changes...");
            SparkleGit git = new SparkleGit(LocalPath, "ls-remote origin master");

            git.Start();
            git.WaitForExit();

            if (git.ExitCode != 0)
            {
                return(false);
            }

            string remote_revision = git.StandardOutput.ReadToEnd().TrimEnd();

            if (!remote_revision.StartsWith(CurrentRevision))
            {
                SparkleHelpers.DebugInfo("Git", "[" + Name + "] Remote changes found. (" + remote_revision + ")");
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
        private void CheckForRemoteChanges()
        {
            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Checking for remote changes...");
            SparkleGit git = new SparkleGit(LocalPath, "ls-remote origin master");

            git.Exited += delegate {
                if (git.ExitCode != 0)
                {
                    return;
                }

                string remote_hash = git.StandardOutput.ReadToEnd();

                if (!remote_hash.StartsWith(_CurrentHash))
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Remote changes found. (" + remote_hash + ")");
                    Fetch();

                    Watcher.EnableRaisingEvents = false;
                    Rebase();
                    Watcher.EnableRaisingEvents = true;
                }
            };

            git.Start();
            git.WaitForExit();
        }
Пример #3
0
        // Clones the remote repository
        public void Start()
        {
            SparkleHelpers.DebugInfo ("Git", "[" + TargetFolder + "] Cloning Repository");

            if (Directory.Exists (TargetFolder))
                Directory.Delete (TargetFolder, true);

            if (CloningStarted != null)
                CloningStarted (this, new SparkleEventArgs ("CloningStarted"));

            SparkleGit git = new SparkleGit (SparklePaths.SparkleTmpPath,
                "clone \"" + RemoteOriginUrl + "\" " + "\"" + TargetFolder + "\"");

            git.Exited += delegate {
                SparkleHelpers.DebugInfo ("Git", "Exit code " + git.ExitCode.ToString ());

                if (git.ExitCode != 0) {
                    SparkleHelpers.DebugInfo ("Git", "[" + TargetFolder + "] Cloning failed");

                    if (CloningFailed != null)
                        CloningFailed (this, new SparkleEventArgs ("CloningFailed"));
                } else {
                    InstallConfiguration ();
                    InstallExcludeRules ();

                    SparkleHelpers.DebugInfo ("Git", "[" + TargetFolder + "] Repository cloned");

                    if (CloningFinished != null)
                        CloningFinished (this, new SparkleEventArgs ("CloningFinished"));
                }
            };

            git.Start ();
        }
Пример #4
0
        // Commits the made changes
        public void Commit(string message)
        {
            if (!AnyDifferences)
            {
                return;
            }

            SparkleGit git = new SparkleGit(LocalPath, "commit -m '" + message + "'");

            git.Start();
            git.WaitForExit();

            _CurrentHash = GetCurrentHash();
            SparkleHelpers.DebugInfo("Commit", "[" + Name + "] " + message + " (" + _CurrentHash + ")");

            SparkleEventArgs args = new SparkleEventArgs("Commited")
            {
                Message = message
            };

            if (Commited != null)
            {
                Commited(this, args);
            }

            // Collect garbage pseudo-randomly
            if (DateTime.Now.Second % 10 == 0)
            {
                CollectGarbage();
            }
        }
Пример #5
0
        // Merges the fetched changes
        private void Rebase()
        {
            DisableWatching();

            if (AnyDifferences)
            {
                Add();

                string commit_message = FormatCommitMessage();
                Commit(commit_message);
            }

            SparkleGit git = new SparkleGit(LocalPath, "rebase -v FETCH_HEAD");

            git.Start();
            git.WaitForExit();

            if (git.ExitCode != 0)
            {
                SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict detected. Trying to get out...");

                while (AnyDifferences)
                {
                    ResolveConflict();
                }

                SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict resolved.");
                OnConflictResolved();
            }

            EnableWatching();
        }
Пример #6
0
        public override bool SyncUp()
        {
            if (AnyDifferences)
            {
                Add();

                string message = FormatCommitMessage();
                Commit(message);
            }

            SparkleGit git = new SparkleGit(LocalPath, "push origin master");

            git.Start();
            git.StandardOutput.ReadToEnd();
            git.WaitForExit();

            if (git.ExitCode == 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #7
0
        // Fetches changes from the remote repository
        public void Fetch()
        {
            _IsSyncing  = true;
            _IsFetching = true;

            RemoteTimer.Stop();

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Fetching changes...");

            SparkleGit git = new SparkleGit(LocalPath, "fetch -v origin master");

            SparkleEventArgs args;

            args = new SparkleEventArgs("FetchingStarted");

            if (FetchingStarted != null)
            {
                FetchingStarted(this, args);
            }


            git.Exited += delegate {
                SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes fetched.");

                _IsSyncing  = false;
                _IsFetching = false;

                _CurrentHash = Head.CurrentCommit.Hash;

                if (git.ExitCode != 0)
                {
                    _ServerOnline = false;

                    args = new SparkleEventArgs("FetchingFailed");

                    if (FetchingFailed != null)
                    {
                        FetchingFailed(this, args);
                    }
                }
                else
                {
                    _ServerOnline = true;

                    args = new SparkleEventArgs("FetchingFinished");

                    if (FetchingFinished != null)
                    {
                        FetchingFinished(this, args);
                    }
                }

                RemoteTimer.Start();
            };


            git.Start();
            git.WaitForExit();
        }
Пример #8
0
        // Stages the made changes
        private void Add()
        {
            SparkleGit git = new SparkleGit(LocalPath, "add --all");

            git.Start();
            git.WaitForExit();

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes staged");
        }
Пример #9
0
        // Removes unneeded objects
        private void CollectGarbage()
        {
            SparkleGit git = new SparkleGit(LocalPath, "gc");

            git.Start();
            git.WaitForExit();

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Garbage collected.");
        }
Пример #10
0
        private string GetCurrentHash()
        {
            SparkleGit git = new SparkleGit(LocalPath, "log -1 --format=%H");

            git.Start();
            git.WaitForExit();

            string output = git.StandardOutput.ReadToEnd();
            string hash   = output.Trim();

            return(hash);
        }
Пример #11
0
        private string GetUserName()
        {
            SparkleGit git = new SparkleGit(LocalPath, "config --get user.name");

            git.Start();
            git.WaitForExit();

            string output    = git.StandardOutput.ReadToEnd();
            string user_name = output.Trim();

            return(user_name);
        }
Пример #12
0
        private string GetRemoteOriginUrl()
        {
            SparkleGit git = new SparkleGit(LocalPath, "config --get remote.origin.url");

            git.Start();
            git.WaitForExit();

            string output = git.StandardOutput.ReadToEnd();
            string url    = output.Trim();

            return(url);
        }
Пример #13
0
        private string GetUserEmail()
        {
            SparkleGit git = new SparkleGit(LocalPath, "config --get user.email");

            git.Start();
            git.WaitForExit();

            string output     = git.StandardOutput.ReadToEnd();
            string user_email = output.Trim();

            return(user_email);
        }
Пример #14
0
        // Merges the fetched changes
        public void Rebase()
        {
            if (AnyDifferences)
            {
                Add();

                string commit_message = FormatCommitMessage();
                Commit(commit_message);
            }

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Rebasing changes...");
            SparkleGit git = new SparkleGit(LocalPath, "rebase -v FETCH_HEAD");

            git.Exited += delegate {
                if (git.ExitCode != 0)
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict detected. Trying to get out...");
                    Watcher.EnableRaisingEvents = false;

                    while (AnyDifferences)
                    {
                        ResolveConflict();
                    }

                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict resolved.");
                    Watcher.EnableRaisingEvents = true;

                    SparkleEventArgs args = new SparkleEventArgs("ConflictDetected");
                    if (ConflictDetected != null)
                    {
                        ConflictDetected(this, args);
                    }
                }

                _CurrentHash = GetCurrentHash();
            };

            git.Start();
            git.WaitForExit();

            _CurrentHash = GetCurrentHash();

            if (NewCommit != null)
            {
                NewCommit(GetCommits(1) [0], LocalPath);
            }

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes rebased.");
        }
Пример #15
0
        public override bool SyncDown()
        {
            SparkleGit git = new SparkleGit(LocalPath, "fetch -v");

            git.Start();
            git.WaitForExit();

            if (git.ExitCode == 0)
            {
                Rebase();
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #16
0
        // Stages the made changes
        private void Add()
        {
            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Staging changes...");

            SparkleGit git = new SparkleGit(LocalPath, "add --all");

            git.Start();
            git.WaitForExit();

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes staged.");
            SparkleEventArgs args = new SparkleEventArgs("Added");

            if (Added != null)
            {
                Added(this, args);
            }
        }
Пример #17
0
        // Clones the remote repository
        public void Start()
        {
            SparkleHelpers.DebugInfo("Git", "[" + TargetFolder + "] Cloning Repository");

            if (Directory.Exists(TargetFolder))
            {
                Directory.Delete(TargetFolder, true);
            }


            if (CloningStarted != null)
            {
                CloningStarted(this, new SparkleEventArgs("CloningStarted"));
            }

            SparkleGit git = new SparkleGit(SparklePaths.SparkleTmpPath,
                                            "clone \"" + RemoteOriginUrl + "\" " + "\"" + TargetFolder + "\"");

            git.Exited += delegate {
                SparkleHelpers.DebugInfo("Git", "Exit code " + git.ExitCode.ToString());

                if (git.ExitCode != 0)
                {
                    SparkleHelpers.DebugInfo("Git", "[" + TargetFolder + "] Cloning failed");

                    if (CloningFailed != null)
                    {
                        CloningFailed(this, new SparkleEventArgs("CloningFailed"));
                    }
                }
                else
                {
                    InstallConfiguration();
                    InstallExcludeRules();

                    SparkleHelpers.DebugInfo("Git", "[" + TargetFolder + "] Repository cloned");

                    if (CloningFinished != null)
                    {
                        CloningFinished(this, new SparkleEventArgs("CloningFinished"));
                    }
                }
            };

            git.Start();
        }
Пример #18
0
        // Removes unneeded objects

/*        private void CollectGarbage ()
 *      {
 *          SparkleGit git = new SparkleGit (LocalPath, "gc");
 *          git.Start ();
 *          git.WaitForExit ();
 *
 *          SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Garbage collected.");
 *      } */


        // Commits the made changes
        private void Commit(string message)
        {
            SparkleGit git = new SparkleGit(LocalPath,
                                            "commit -m \"" + message + "\" " +
                                            "--author=\"" + SparkleConfig.DefaultConfig.User.Name +
                                            " <" + SparkleConfig.DefaultConfig.User.Email + ">\"");

            git.Start();
            git.StandardOutput.ReadToEnd();
            git.WaitForExit();

            SparkleHelpers.DebugInfo("Commit", "[" + Name + "] " + message);

            // Collect garbage pseudo-randomly. Turn off for
            // now: too resource heavy.
            // if (DateTime.Now.Second % 10 == 0)
            //     CollectGarbage ();
        }
Пример #19
0
        public override bool Fetch()
        {
            SparkleGit git = new SparkleGit (SparklePaths.SparkleTmpPath,
                "clone \"" + base.remote_url + "\" " + "\"" + base.target_folder + "\"");

            git.Start ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Git", "Exit code " + git.ExitCode.ToString ());

            if (git.ExitCode != 0) {
                return false;
            } else {
                InstallConfiguration ();
                InstallExcludeRules ();
                return true;
            }
        }
Пример #20
0
        // Stages the made changes
        private void Add()
        {
            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Staging changes...");

            // FIXME: this GitSharp method seems to block...
            // Index.AddAll ();

            SparkleGit git = new SparkleGit(LocalPath, "add --all");

            git.Start();
            git.WaitForExit();

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes staged.");

            SparkleEventArgs args = new SparkleEventArgs("Added");

            if (Added != null)
            {
                Added(this, args);
            }
        }
Пример #21
0
        private string GetCurrentHash()
        {
            // Remove stale rebase-apply files because it
            // makes the method return the wrong hashes.
            string rebase_apply_file = SparkleHelpers.CombineMore(LocalPath, ".git", "rebase-apply");

            if (File.Exists(rebase_apply_file))
            {
                File.Delete(rebase_apply_file);
            }

            SparkleGit git = new SparkleGit(LocalPath, "log -1 --format=%H");

            git.Start();
            git.WaitForExit();

            string output = git.StandardOutput.ReadToEnd();
            string hash   = output.Trim();

            return(hash);
        }
Пример #22
0
        // Merges the fetched changes
        private void Rebase()
        {
            DisableWatching ();

            if (AnyDifferences) {
                Add ();

                string commit_message = FormatCommitMessage ();
                Commit (commit_message);
            }

            SparkleGit git = new SparkleGit (LocalPath, "rebase -v FETCH_HEAD");

            git.Start ();
            git.WaitForExit ();

            if (git.ExitCode != 0) {
                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict detected. Trying to get out...");

                while (AnyDifferences)
                    ResolveConflict ();

                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict resolved.");
                OnConflictResolved ();
            }

            EnableWatching ();
        }
Пример #23
0
        // Creates a pretty commit message based on what has changed
        private string FormatCommitMessage()
        {
            List<string> Added    = new List<string> ();
            List<string> Modified = new List<string> ();
            List<string> Removed  = new List<string> ();
            string file_name      = "";
            string message        = "";

            SparkleGit git_status = new SparkleGit (LocalPath, "status --porcelain");
            git_status.Start ();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_status.StandardOutput.ReadToEnd ().Trim ("\n".ToCharArray ());
            git_status.WaitForExit ();

            string [] lines = output.Split ("\n".ToCharArray ());
            foreach (string line in lines) {
                if (line.StartsWith ("A"))
                    Added.Add (line.Substring (3));
                else if (line.StartsWith ("M"))
                    Modified.Add (line.Substring (3));
                else if (line.StartsWith ("D"))
                    Removed.Add (line.Substring (3));
                else if (line.StartsWith ("R")) {
                    Removed.Add (line.Substring (3, (line.IndexOf (" -> ") - 3)));
                    Added.Add (line.Substring (line.IndexOf (" -> ") + 4));
                }
            }

            int count     = 0;
            int max_count = 20;

            string n = Environment.NewLine;

            foreach (string added in Added) {
                file_name = added.Trim ("\"".ToCharArray ());

                if (file_name.EndsWith (".empty"))
                    file_name = file_name.Substring (0, file_name.Length - 6);

                message += "+ ‘" + file_name + "’" + n;

                count++;
                if (count == max_count)
                    return message + "...";
            }

            foreach (string modified in Modified) {
                file_name = modified.Trim ("\"".ToCharArray ());

                if (file_name.EndsWith (".empty"))
                    file_name = file_name.Substring (0, file_name.Length - 6);

                message += "/ ‘" + file_name + "’" + n;

                count++;
                if (count == max_count)
                    return message + "...";
            }

            foreach (string removed in Removed) {
                file_name = removed.Trim ("\"".ToCharArray ());

                if (file_name.EndsWith (".empty"))
                    file_name = file_name.Substring (0, file_name.Length - 6);

                message += "- ‘" + file_name + "’" + n;

                count++;
                if (count == max_count)
                    return message + "..." + n;
            }

            message = message.Replace ("\"", "");
            return message.TrimEnd ();
        }
Пример #24
0
        // Removes unneeded objects
        /*        private void CollectGarbage ()
        {
            SparkleGit git = new SparkleGit (LocalPath, "gc");
            git.Start ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Garbage collected.");
        } */
        // Commits the made changes
        private void Commit(string message)
        {
            SparkleGit git = new SparkleGit (LocalPath,
                "commit -m \"" + message + "\" " +
                "--author=\"" + SparkleConfig.DefaultConfig.User.Name +
                " <" + SparkleConfig.DefaultConfig.User.Email + ">\"");

            git.Start ();
            git.StandardOutput.ReadToEnd ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message);

            // Collect garbage pseudo-randomly. Turn off for
            // now: too resource heavy.
            // if (DateTime.Now.Second % 10 == 0)
            //     CollectGarbage ();
        }
Пример #25
0
        // Creates a pretty commit message based on what has changed
        private string FormatCommitMessage()
        {
            List <string> Added     = new List <string> ();
            List <string> Modified  = new List <string> ();
            List <string> Removed   = new List <string> ();
            string        file_name = "";
            string        message   = "";

            SparkleGit git_status = new SparkleGit(LocalPath, "status --porcelain");

            git_status.Start();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_status.StandardOutput.ReadToEnd().Trim("\n".ToCharArray());

            git_status.WaitForExit();

            string [] lines = output.Split("\n".ToCharArray());
            foreach (string line in lines)
            {
                if (line.StartsWith("A"))
                {
                    Added.Add(line.Substring(3));
                }
                else if (line.StartsWith("M"))
                {
                    Modified.Add(line.Substring(3));
                }
                else if (line.StartsWith("D"))
                {
                    Removed.Add(line.Substring(3));
                }
                else if (line.StartsWith("R"))
                {
                    Removed.Add(line.Substring(3, (line.IndexOf(" -> ") - 3)));
                    Added.Add(line.Substring(line.IndexOf(" -> ") + 4));
                }
            }

            int count     = 0;
            int max_count = 20;

            string n = Environment.NewLine;

            foreach (string added in Added)
            {
                file_name = added.Trim("\"".ToCharArray());

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

                message += "+ ‘" + file_name + "’" + n;

                count++;
                if (count == max_count)
                {
                    return(message + "...");
                }
            }

            foreach (string modified in Modified)
            {
                file_name = modified.Trim("\"".ToCharArray());

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

                message += "/ ‘" + file_name + "’" + n;

                count++;
                if (count == max_count)
                {
                    return(message + "...");
                }
            }

            foreach (string removed in Removed)
            {
                file_name = removed.Trim("\"".ToCharArray());

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

                message += "- ‘" + file_name + "’" + n;

                count++;
                if (count == max_count)
                {
                    return(message + "..." + n);
                }
            }

            message = message.Replace("\"", "");
            return(message.TrimEnd());
        }
Пример #26
0
        // Creates a pretty commit message based on what has changed
        private string FormatCommitMessage()
        {
            List <string> Added     = new List <string> ();
            List <string> Modified  = new List <string> ();
            List <string> Removed   = new List <string> ();
            string        file_name = "";
            string        message   = null;

            SparkleGit git_status = new SparkleGit(LocalPath, "status --porcelain");

            git_status.Start();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_status.StandardOutput.ReadToEnd().Trim("\n".ToCharArray());

            git_status.WaitForExit();

            string [] lines = output.Split("\n".ToCharArray());
            foreach (string line in lines)
            {
                if (line.StartsWith("A"))
                {
                    Added.Add(line.Substring(2));
                }
                else if (line.StartsWith("M"))
                {
                    Modified.Add(line.Substring(2));
                }
                else if (line.StartsWith("D"))
                {
                    Removed.Add(line.Substring(2));
                }
                else if (line.StartsWith("R"))
                {
                    Removed.Add(line.Substring(3, (line.IndexOf(" -> ") - 3)));
                    Added.Add(line.Substring(line.IndexOf(" -> ") + 4));
                }
            }

            if (Added.Count > 0)
            {
                foreach (string added in Added)
                {
                    file_name = added.Trim("\"".ToCharArray());
                    break;
                }

                message = "+ ‘" + file_name + "’";
            }

            if (Modified.Count > 0)
            {
                foreach (string modified in Modified)
                {
                    file_name = modified.Trim("\"".ToCharArray());
                    break;
                }

                message = "/ ‘" + file_name + "’";
            }

            if (Removed.Count > 0)
            {
                foreach (string removed in Removed)
                {
                    file_name = removed.Trim("\"".ToCharArray());
                    break;
                }

                message = "- ‘" + file_name + "’";
            }

            int changes_count = (Added.Count +
                                 Modified.Count +
                                 Removed.Count);

            if (changes_count > 1)
            {
                message += " + " + (changes_count - 1);
            }

            return(message);
        }
Пример #27
0
        private void ResolveConflict()
        {
            // This is al 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 theirs, save ours as a timestamped copy
            // UD    unmerged, deleted by them -> Use ours
            // UA    unmerged, added by them   -> Use theirs, save ours as a timestamped copy
            // DU    unmerged, deleted by us   -> Use theirs
            // AA    unmerged, both added      -> Use theirs, save ours as a timestamped copy
            // UU    unmerged, both modified   -> Use theirs, save ours as a timestamped copy
            //
            // 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'

            SparkleGit git_status = new SparkleGit(LocalPath, "status --porcelain");

            git_status.Start();
            git_status.WaitForExit();

            string output = git_status.StandardOutput.ReadToEnd().TrimEnd();

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

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

                // 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.Start();
                    git_theirs.WaitForExit();

                    // Append a timestamp to local version
                    string timestamp            = DateTime.Now.ToString("HH:mm MMM d");
                    string their_path           = conflicting_path + " (" + UserName + ", " + timestamp + ")";
                    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.Start();
                    git_ours.WaitForExit();

                    Add();

                    SparkleGit git_rebase_continue = new SparkleGit(LocalPath, "rebase --continue");
                    git_rebase_continue.Start();
                    git_rebase_continue.WaitForExit();
                }

                // The local version has been modified, but the server version was removed
                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.Start();
                    git_add.WaitForExit();

                    SparkleGit git_rebase_continue = new SparkleGit(LocalPath, "rebase --continue");
                    git_rebase_continue.Start();
                    git_rebase_continue.WaitForExit();
                }

                // The server version has been modified, but the local version was removed
                if (line.StartsWith("UD"))
                {
                    // We can just skip here, the server version is
                    // already in the checkout
                    SparkleGit git_rebase_skip = new SparkleGit(LocalPath, "rebase --skip");
                    git_rebase_skip.Start();
                    git_rebase_skip.WaitForExit();
                }
            }
        }
Пример #28
0
        // Pushes the changes to the remote repo
        public void Push()
        {
            _IsSyncing = true;
            _IsPushing = true;

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing changes...");
            SparkleGit git = new SparkleGit (LocalPath, "push origin master");

            SparkleEventArgs args = new SparkleEventArgs ("PushingStarted");

            if (PushingStarted != null)
                PushingStarted (this, args);

            git.Exited += delegate {
                _IsSyncing = false;
                _IsPushing = false;

                if (git.ExitCode != 0) {
                    SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing failed.");

                    string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath ,
                        ".git", "has_unsynced_changes");

                    if (!File.Exists (unsynced_file_path))
                        File.Create (unsynced_file_path);

                    _HasUnsyncedChanges = true;

                    args = new SparkleEventArgs ("PushingFailed");

                    if (PushingFailed != null)
                        PushingFailed (this, args);

                    FetchRebaseAndPush ();
                } else {
                    SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes pushed.");
                    args = new SparkleEventArgs ("PushingFinished");

                    string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath ,
                        ".git", "has_unsynced_changes");

                    if (File.Exists (unsynced_file_path))
                        File.Delete (unsynced_file_path);

                    _HasUnsyncedChanges = false;

                    if (PushingFinished != null)
                        PushingFinished (this, args);

                    if (Listener.Client.IsConnected) {
                        Listener.Announce (_CurrentHash);
                    } else {
                        AnnounceQueue++;
                        SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Could not deliver notification, added it to the queue");
                     }
                }

            };

            git.Start ();
            git.WaitForExit ();
        }
Пример #29
0
        // Fetches changes from the remote repository
        public void Fetch()
        {
            _IsSyncing  = true;
            _IsFetching = true;

            RemoteTimer.Stop ();

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Fetching changes...");
            SparkleGit git = new SparkleGit (LocalPath, "fetch -v origin master");

            SparkleEventArgs args = new SparkleEventArgs ("FetchingStarted");

            if (FetchingStarted != null)
                FetchingStarted (this, args);

            git.Exited += delegate {
                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes fetched.");

                _IsSyncing   = false;
                _IsFetching  = false;
                _CurrentHash = GetCurrentHash ();

                if (git.ExitCode != 0) {
                    _ServerOnline = false;

                    args = new SparkleEventArgs ("FetchingFailed");

                    if (FetchingFailed != null)
                        FetchingFailed (this, args);
                } else {
                    _ServerOnline = true;

                    args = new SparkleEventArgs ("FetchingFinished");

                    if (FetchingFinished != null)
                        FetchingFinished (this, args);
                }

                RemoteTimer.Start ();
            };

            git.Start ();
            git.WaitForExit ();
        }
Пример #30
0
        // Pushes the changes to the remote repo
        public void Push()
        {
            _IsSyncing = true;
            _IsPushing = true;

            SparkleGit git = new SparkleGit(LocalPath, "push origin master");

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Pushing changes...");

            SparkleEventArgs args = new SparkleEventArgs("PushingStarted");

            if (PushingStarted != null)
            {
                PushingStarted(this, args);
            }


            git.Exited += delegate {
                _IsSyncing = false;
                _IsPushing = false;

                if (git.ExitCode != 0)
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Pushing failed.");

                    string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath,
                                                                           ".git", "has_unsynced_changes");

                    if (!File.Exists(unsynced_file_path))
                    {
                        File.Create(unsynced_file_path);
                    }

                    _HasUnsyncedChanges = true;

                    args = new SparkleEventArgs("PushingFailed");

                    if (PushingFailed != null)
                    {
                        PushingFailed(this, args);
                    }

                    CheckForRemoteChanges();
                    Push();
                }
                else
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes pushed.");

                    args = new SparkleEventArgs("PushingFinished");

                    string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath,
                                                                           ".git", "has_unsynced_changes");

                    if (File.Exists(unsynced_file_path))
                    {
                        File.Delete(unsynced_file_path);
                    }

                    _HasUnsyncedChanges = false;

                    if (PushingFinished != null)
                    {
                        PushingFinished(this, args);
                    }

                    if (!_IsPolling)
                    {
                        Listener.Announce(_CurrentHash);
                    }
                }
            };


            git.Start();
            git.WaitForExit();
        }
Пример #31
0
        public override void SyncUpNotes()
        {
            while (Status != SyncStatus.Idle) {
                System.Threading.Thread.Sleep (5 * 20);
            }

            SparkleGit git_push = new SparkleGit (LocalPath, "push origin refs/notes/*");
            git_push.Start ();
            git_push.WaitForExit ();

            if (git_push.ExitCode == 0) {
                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Notes pushed");

            } else {
                HasUnsyncedChanges = true;
                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing notes failed, trying again later");
            }

            SparkleAnnouncement announcement = new SparkleAnnouncement (Identifier, SHA1 (DateTime.Now.ToString ()));
            base.listener.Announce (announcement);
        }
Пример #32
0
        // Returns a list of the latest change sets
        public override List<SparkleChangeSet> GetChangeSets(int count)
        {
            if (count < 1)
                count = 30;

            List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();

            SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso --show-notes=*");
            Console.OutputEncoding = System.Text.Encoding.Unicode;
            git_log.Start ();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_log.StandardOutput.ReadToEnd ();
            git_log.WaitForExit ();

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

            int j = 0;
            string entry = "", last_entry = "";
            foreach (string line in lines) {
                if (line.StartsWith ("commit") && j > 0) {
                    entries.Add (entry);
                    entry = "";
                }

                entry += line + "\n";
                j++;

                last_entry = entry;
            }

            entries.Add (last_entry);

            Regex merge_regex = new Regex (@"commit ([a-z0-9]{40})\n" +
                                "Merge: .+ .+\n" +
                                "Author: (.+) <(.+)>\n" +
                                "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                "*", RegexOptions.Compiled);

            Regex non_merge_regex = new Regex (@"commit ([a-z0-9]{40})\n" +
                                "Author: (.+) <(.+)>\n" +
                                "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" +
                                "*", RegexOptions.Compiled);

            foreach (string log_entry in entries) {
                Regex regex;
                bool is_merge_commit = false;

                if (log_entry.Contains ("\nMerge: ")) {
                    regex = merge_regex;
                    is_merge_commit = true;
                } else {
                    regex = non_merge_regex;
                }

                Match match = regex.Match (log_entry);

                if (match.Success) {
                    SparkleChangeSet change_set = new SparkleChangeSet ();

                    change_set.Folder        = Name;
                    change_set.Revision      = match.Groups [1].Value;
                    change_set.UserName      = match.Groups [2].Value;
                    change_set.UserEmail     = match.Groups [3].Value;
                    change_set.IsMerge       = is_merge_commit;
                    change_set.SupportsNotes = true;

                    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 ());

                    foreach (string entry_line in entry_lines) {
                        if (entry_line.StartsWith (":")) {

                            string change_type = entry_line [37].ToString ();
                            string file_path   = entry_line.Substring (39);
                            string to_file_path;

                            if (change_type.Equals ("A")) {
                                change_set.Added.Add (file_path);

                            } else if (change_type.Equals ("M")) {
                                change_set.Edited.Add (file_path);

                            } else if (change_type.Equals ("D")) {
                                change_set.Deleted.Add (file_path);

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

                                change_set.MovedFrom.Add (file_path);
                                change_set.MovedTo.Add (to_file_path);
                            }

                        } else if (entry_line.StartsWith ("    <note>")) {

                            Regex regex_notes = new Regex (@"<name>(.+)</name>.*" +
                                                            "<email>(.+)</email>.*" +
                                                            "<timestamp>([0-9]+)</timestamp>.*" +
                                                            "<body>(.+)</body>", RegexOptions.Compiled);

                            Match match_notes = regex_notes.Match (entry_line);

                            if (match_notes.Success) {
                                SparkleNote note = new SparkleNote () {
                                    UserName  = match_notes.Groups [1].Value,
                                    UserEmail = match_notes.Groups [2].Value,
                                    Timestamp = new DateTime (1970, 1, 1).AddSeconds (int.Parse (match_notes.Groups [3].Value)),
                                    Body      = match_notes.Groups [4].Value
                                };

                                change_set.Notes.Add (note);
                            }
                        }
                    }

                    change_sets.Add (change_set);
                }
            }

            return change_sets;
        }
Пример #33
0
        public override void AddNote(string revision, string note)
        {
            string url = SparkleConfig.DefaultConfig.GetUrlForFolder (Name);

            if (url.StartsWith ("git") || url.StartsWith ("http"))
                return;

            int timestamp = (int) (DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;

            // Create the note in one line for easier merging
            note = "<note>" +
                   "  <user>" +
                   "    <name>" + SparkleConfig.DefaultConfig.UserName + "</name>" +
                   "    <email>" + SparkleConfig.DefaultConfig.UserEmail + "</email>" +
                   "  </user>" +
                   "  <timestamp>" + timestamp + "</timestamp>" +
                   "  <body>" + note + "</body>" +
                   "</note>";

            string note_namespace = SHA1 (timestamp.ToString () + note);
            SparkleGit git_notes = new SparkleGit (LocalPath,
                "notes --ref=" + note_namespace + " append -m \"" + note + "\" " + revision);
            git_notes.Start ();
            git_notes.WaitForExit ();

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Added note to " + revision);
            SyncUpNotes ();
        }
Пример #34
0
        private void ResolveConflict()
        {
            // This is al 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 theirs, save ours as a timestamped copy
            // UD    unmerged, deleted by them -> Use ours
            // UA    unmerged, added by them   -> Use theirs, save ours as a timestamped copy
            // DU    unmerged, deleted by us   -> Use theirs
            // AA    unmerged, both added      -> Use theirs, save ours as a timestamped copy
            // UU    unmerged, both modified   -> Use theirs, 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'

            SparkleGit git_status = new SparkleGit (LocalPath, "status --porcelain");
            git_status.Start ();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_status.StandardOutput.ReadToEnd ().TrimEnd ();
            git_status.WaitForExit ();

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

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

                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict type: " + line);

                // 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.Start ();
                    git_theirs.WaitForExit ();

                    // 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 ("HH\\hmm MMM d");
                    string their_path           = conflicting_path + " (" + SparkleConfig.DefaultConfig.User.Name + ", " + timestamp + ")";
                    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.Start ();
                    git_ours.WaitForExit ();

                    Add ();

                    SparkleGit git_rebase_continue = new SparkleGit (LocalPath, "rebase --continue");
                    git_rebase_continue.Start ();
                    git_rebase_continue.WaitForExit ();
                }

                // The local version has been modified, but the server version was removed
                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.Start ();
                    git_add.WaitForExit ();

                    SparkleGit git_rebase_continue = new SparkleGit (LocalPath, "rebase --continue");
                    git_rebase_continue.Start ();
                    git_rebase_continue.WaitForExit ();
                }

                // The server version has been modified, but the local version was removed
                if (line.StartsWith ("UD")) {

                    // We can just skip here, the server version is
                    // already in the checkout
                    SparkleGit git_rebase_skip = new SparkleGit (LocalPath, "rebase --skip");
                    git_rebase_skip.Start ();
                    git_rebase_skip.WaitForExit ();
                }

                // New local files
                if (line.StartsWith ("??")) {

                    Add ();

                    SparkleGit git_rebase_continue = new SparkleGit (LocalPath, "rebase --continue");
                    git_rebase_continue.Start ();
                    git_rebase_continue.WaitForExit ();
                }
            }
        }
Пример #35
0
        // Returns a list of latest commits
        // TODO: Method needs to be made a lot faster
        public List <SparkleCommit> GetCommits(int count)
        {
            if (count < 1)
            {
                count = 30;
            }

            List <SparkleCommit> commits = new List <SparkleCommit> ();

            SparkleGit git_log = new SparkleGit(LocalPath, "log -" + count + " --raw -M --date=iso");

            Console.OutputEncoding = System.Text.Encoding.Unicode;
            git_log.Start();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_log.StandardOutput.ReadToEnd();

            git_log.WaitForExit();

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

            int    j = 0;
            string entry = "", last_entry = "";

            foreach (string line in lines)
            {
                if (line.StartsWith("commit") && j > 0)
                {
                    entries.Add(entry);
                    entry = "";
                }

                entry += line + "\n";
                j++;

                last_entry = entry;
            }

            entries.Add(last_entry);

            // TODO: Need to optimise for speed
            foreach (string log_entry in entries)
            {
                Regex regex;
                bool  is_merge_commit = false;

                if (log_entry.Contains("\nMerge: "))
                {
                    regex = new Regex(@"commit ([a-z0-9]{40})\n" +
                                      "Merge: .+ .+\n" +
                                      "Author: (.+) <(.+)>\n" +
                                      "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                      "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                      "*");

                    is_merge_commit = true;
                }
                else
                {
                    regex = new Regex(@"commit ([a-z0-9]{40})\n" +
                                      "Author: (.+) <(.+)>\n" +
                                      "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                      "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                      "*");
                }

                Match match = regex.Match(log_entry);

                if (match.Success)
                {
                    SparkleCommit commit = new SparkleCommit();

                    commit.Hash      = match.Groups [1].Value;
                    commit.UserName  = match.Groups [2].Value;
                    commit.UserEmail = match.Groups [3].Value;
                    commit.IsMerge   = is_merge_commit;

                    commit.DateTime = 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 [] entry_lines = log_entry.Split("\n".ToCharArray());

                    foreach (string entry_line in entry_lines)
                    {
                        if (entry_line.StartsWith(":"))
                        {
                            string change_type = entry_line [37].ToString();
                            string file_path   = entry_line.Substring(39);
                            string to_file_path;

                            if (change_type.Equals("A"))
                            {
                                commit.Added.Add(file_path);
                            }
                            else if (change_type.Equals("M"))
                            {
                                commit.Edited.Add(file_path);
                            }
                            else if (change_type.Equals("D"))
                            {
                                commit.Deleted.Add(file_path);
                            }
                            else if (change_type.Equals("R"))
                            {
                                int tab_pos = entry_line.LastIndexOf("\t");
                                file_path    = entry_line.Substring(42, tab_pos - 42);
                                to_file_path = entry_line.Substring(tab_pos + 1);

                                commit.MovedFrom.Add(file_path);
                                commit.MovedTo.Add(to_file_path);
                            }
                        }
                    }

                    commits.Add(commit);
                }
            }

            return(commits);
        }
Пример #36
0
        // Merges the fetched changes
        public void Rebase()
        {
            if (AnyDifferences)
            {
                Add();

                string commit_message = FormatCommitMessage();
                Commit(commit_message);
            }

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Rebasing changes...");
            SparkleGit git = new SparkleGit(LocalPath, "rebase -v FETCH_HEAD");

            git.Exited += delegate {
                if (Status.MergeConflict.Count > 0)
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict detected...");

                    foreach (string problem_file_name in Status.MergeConflict)
                    {
                        SparkleGit git_ours = new SparkleGit(LocalPath,
                                                             "checkout --ours " + problem_file_name);
                        git_ours.Start();
                        git_ours.WaitForExit();

                        string timestamp = DateTime.Now.ToString("H:mm d MMM");

                        string new_file_name = problem_file_name + " (" + UserName + ", " + timestamp + ")";
                        File.Move(problem_file_name, new_file_name);

                        SparkleGit git_theirs = new SparkleGit(LocalPath,
                                                               "checkout --theirs " + problem_file_name);
                        git_theirs.Start();
                        git_theirs.WaitForExit();

                        SparkleEventArgs args = new SparkleEventArgs("ConflictDetected");

                        if (ConflictDetected != null)
                        {
                            ConflictDetected(this, args);
                        }
                    }

                    Add();

                    SparkleGit git_continue = new SparkleGit(LocalPath, "rebase --continue");
                    git_continue.Start();
                    git_continue.WaitForExit();

                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict resolved.");

                    Push();
                }
            };


            git.Start();
            git.WaitForExit();

            _CurrentHash = Head.CurrentCommit.Hash;

            if (NewCommit != null)
            {
                NewCommit(GetCommits(1) [0], LocalPath);
            }

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes rebased.");
        }
Пример #37
0
        public override bool Fetch()
        {
            this.git = new SparkleGit(base.target_folder,
                                      "clone " +
                                      "--progress " + // Redirects progress stats to standarderror
                                      "\"" + base.remote_url + "\" " + "\"" + base.target_folder + "\"");

            this.git.StartInfo.RedirectStandardError = true;
            this.git.Start();

            double percentage     = 1.0;
            Regex  progress_regex = new Regex(@"([0-9]+)%", RegexOptions.Compiled);

            while (!this.git.StandardError.EndOfStream)
            {
                string line  = this.git.StandardError.ReadLine();
                Match  match = progress_regex.Match(line);

                double number = 0.0;
                if (match.Success)
                {
                    number = double.Parse(match.Groups [1].Value);

                    // The cloning progress consists of two stages: the "Compressing
                    // objects" stage which we count as 20% of the total progress, and
                    // the "Receiving objects" stage which we count as the last 80%
                    if (line.Contains("|"))
                    {
                        // "Receiving objects" stage
                        number = (number / 100 * 75 + 20);
                    }
                    else
                    {
                        // "Compressing objects" stage
                        number = (number / 100 * 20);
                    }
                }

                if (number >= percentage)
                {
                    percentage = number;

                    // FIXME: for some reason it doesn't go above 95%
                    base.OnProgressChanged(percentage);
                }

                System.Threading.Thread.Sleep(100);
            }

            this.git.WaitForExit();

            SparkleHelpers.DebugInfo("Git", "Exit code " + this.git.ExitCode.ToString());

            if (this.git.ExitCode != 0)
            {
                return(false);
            }
            else
            {
                InstallConfiguration();
                InstallExcludeRules();
                return(true);
            }
        }
Пример #38
0
        // Returns a list of the latest change sets
        public override List <SparkleChangeSet> GetChangeSets(int count)
        {
            if (count < 1)
            {
                count = 30;
            }

            List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();

            // Console.InputEncoding  = System.Text.Encoding.Unicode;
            Console.OutputEncoding = System.Text.Encoding.Unicode;

            SparkleGit git_log = new SparkleGit(LocalPath, "log -" + count + " --raw -M --date=iso");

            git_log.Start();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_log.StandardOutput.ReadToEnd();

            git_log.WaitForExit();

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

            int    j = 0;
            string entry = "", last_entry = "";

            foreach (string line in lines)
            {
                if (line.StartsWith("commit") && j > 0)
                {
                    entries.Add(entry);
                    entry = "";
                }

                entry += line + "\n";
                j++;

                last_entry = entry;
            }

            entries.Add(last_entry);

            Regex merge_regex = new Regex(@"commit ([a-z0-9]{40})\n" +
                                          "Merge: .+ .+\n" +
                                          "Author: (.+) <(.+)>\n" +
                                          "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                          "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                          "*", RegexOptions.Compiled);

            Regex non_merge_regex = new Regex(@"commit ([a-z0-9]{40})\n" +
                                              "Author: (.+) <(.+)>\n" +
                                              "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                              "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" +
                                              "*", RegexOptions.Compiled);

            foreach (string log_entry in entries)
            {
                Regex regex;
                bool  is_merge_commit = false;

                if (log_entry.Contains("\nMerge: "))
                {
                    regex           = merge_regex;
                    is_merge_commit = true;
                }
                else
                {
                    regex = non_merge_regex;
                }

                Match match = regex.Match(log_entry);

                if (match.Success)
                {
                    SparkleChangeSet change_set = new SparkleChangeSet();

                    change_set.Folder     = Name;
                    change_set.Revision   = match.Groups [1].Value;
                    change_set.User.Name  = match.Groups [2].Value;
                    change_set.User.Email = match.Groups [3].Value;
                    change_set.IsMagical  = is_merge_commit;

                    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());

                    foreach (string entry_line in entry_lines)
                    {
                        if (entry_line.StartsWith(":"))
                        {
                            string change_type = entry_line [37].ToString();
                            string file_path   = entry_line.Substring(39);
                            string to_file_path;

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

                            if (change_type.Equals("A") && !file_path.Contains(".notes"))
                            {
                                change_set.Added.Add(file_path);
                            }
                            else if (change_type.Equals("M"))
                            {
                                change_set.Edited.Add(file_path);
                            }
                            else if (change_type.Equals("D"))
                            {
                                change_set.Deleted.Add(file_path);
                            }
                            else if (change_type.Equals("R"))
                            {
                                int tab_pos = entry_line.LastIndexOf("\t");
                                file_path    = entry_line.Substring(42, tab_pos - 42);
                                to_file_path = entry_line.Substring(tab_pos + 1);

                                change_set.MovedFrom.Add(file_path);
                                change_set.MovedTo.Add(to_file_path);
                            }
                        }
                    }

                    if ((change_set.Added.Count +
                         change_set.Edited.Count +
                         change_set.Deleted.Count +
                         change_set.MovedFrom.Count) > 0)
                    {
                        change_set.Notes.AddRange(GetNotes(change_set.Revision));
                        change_sets.Add(change_set);
                    }
                }
            }

            return(change_sets);
        }
Пример #39
0
        private string GetUserEmail()
        {
            SparkleGit git = new SparkleGit (LocalPath, "config --get user.email");
            git.Start ();
            git.WaitForExit ();

            string output = git.StandardOutput.ReadToEnd ();
            string user_email   = output.Trim ();

            return user_email;
        }
Пример #40
0
        public override bool SyncDown()
        {
            SparkleGit git = new SparkleGit(LocalPath, "fetch --progress");

            git.StartInfo.RedirectStandardError = true;
            git.Start();

            double percentage     = 1.0;
            Regex  progress_regex = new Regex(@"([0-9]+)%", RegexOptions.Compiled);

            DateTime last_change     = DateTime.Now;
            TimeSpan change_interval = new TimeSpan(0, 0, 0, 1);

            while (!git.StandardError.EndOfStream)
            {
                string line   = git.StandardError.ReadLine();
                Match  match  = progress_regex.Match(line);
                string speed  = "";
                double number = 0.0;

                if (match.Success)
                {
                    number = double.Parse(match.Groups [1].Value);

                    // The fetching progress consists of two stages: the "Compressing
                    // objects" stage which we count as 20% of the total progress, and
                    // the "Receiving objects" stage which we count as the last 80%
                    if (line.StartsWith("Compressing"))
                    {
                        // "Compressing objects" stage
                        number = (number / 100 * 20);
                    }
                    else
                    {
                        // "Writing objects" stage
                        number = (number / 100 * 80 + 20);

                        if (line.Contains("|"))
                        {
                            speed = line.Substring(line.IndexOf("|") + 1).Trim();
                            speed = speed.Replace(", done.", "").Trim();
                            speed = speed.Replace("i", "");
                            speed = speed.Replace("KB/s", "ᴋʙ/s");
                            speed = speed.Replace("MB/s", "ᴍʙ/s");
                        }
                    }
                }

                if (number >= percentage)
                {
                    percentage = number;

                    if (percentage == 100.0)
                    {
                        percentage = 99.0;
                    }

                    if (DateTime.Compare(last_change, DateTime.Now.Subtract(change_interval)) < 0)
                    {
                        base.OnSyncProgressChanged(percentage, speed);
                        last_change = DateTime.Now;
                    }
                }
            }

            git.WaitForExit();


            if (git.ExitCode == 0)
            {
                Rebase();
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #41
0
        // Stages the made changes
        private void Add()
        {
            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Staging changes...");

            SparkleGit git = new SparkleGit (LocalPath, "add --all");
            git.Start ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes staged.");
            SparkleEventArgs args = new SparkleEventArgs ("Added");

            if (Added != null)
                Added (this, args);
        }
Пример #42
0
        private string GetCurrentHash()
        {
            // Remove stale rebase-apply files because it
            // makes the method return the wrong hashes.
            string rebase_apply_file = SparkleHelpers.CombineMore (LocalPath, ".git", "rebase-apply");
            if (File.Exists (rebase_apply_file))
                File.Delete (rebase_apply_file);

            SparkleGit git = new SparkleGit (LocalPath, "log -1 --format=%H");
            git.Start ();
            git.WaitForExit ();

            string output = git.StandardOutput.ReadToEnd ();
            string hash   = output.Trim ();

            return hash;
        }
Пример #43
0
        // Pushes the changes to the remote repo
        public void Push()
        {
            _IsSyncing = true;
            _IsPushing = true;

            SparkleHelpers.DebugInfo("Git", "[" + Name + "] Pushing changes...");
            SparkleGit git = new SparkleGit(LocalPath, "push origin master");

            SparkleEventArgs args = new SparkleEventArgs("PushingStarted");

            if (PushingStarted != null)
            {
                PushingStarted(this, args);
            }

            git.Exited += delegate {
                _IsSyncing = false;
                _IsPushing = false;

                if (git.ExitCode != 0)
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Pushing failed.");

                    string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath,
                                                                           ".git", "has_unsynced_changes");

                    if (!File.Exists(unsynced_file_path))
                    {
                        File.Create(unsynced_file_path);
                    }

                    _HasUnsyncedChanges = true;

                    args = new SparkleEventArgs("PushingFailed");

                    if (PushingFailed != null)
                    {
                        PushingFailed(this, args);
                    }

                    FetchRebaseAndPush();
                }
                else
                {
                    SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes pushed.");
                    args = new SparkleEventArgs("PushingFinished");

                    string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath,
                                                                           ".git", "has_unsynced_changes");

                    if (File.Exists(unsynced_file_path))
                    {
                        File.Delete(unsynced_file_path);
                    }

                    _HasUnsyncedChanges = false;

                    if (PushingFinished != null)
                    {
                        PushingFinished(this, args);
                    }

                    if (Listener.Client.IsConnected)
                    {
                        Listener.Announce(_CurrentHash);
                    }
                    else
                    {
                        AnnounceQueue++;
                        SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Could not deliver notification, added it to the queue");
                    }
                }
            };

            git.Start();
            git.WaitForExit();
        }
Пример #44
0
        // Removes unneeded objects
        private void CollectGarbage()
        {
            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Collecting garbage...");

            SparkleGit git = new SparkleGit (LocalPath, "gc");
            git.Start ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Garbage collected.");
        }
Пример #45
0
        public override bool SyncDown()
        {
            SparkleGit git = new SparkleGit (LocalPath, "fetch -v origin master");

            git.Start ();
            git.WaitForExit ();

            if (git.ExitCode == 0) {
                Rebase ();
                return true;
            } else {
                return false;
            }
        }
Пример #46
0
        private string GetCurrentHash()
        {
            SparkleGit git = new SparkleGit (LocalPath, "log -1 --format=%H");
            git.Start ();
            git.WaitForExit ();

            string output = git.StandardOutput.ReadToEnd ();
            string hash   = output.Trim ();

            return hash;
        }
Пример #47
0
        // Commits the made changes
        public void Commit(string message)
        {
            if (!AnyDifferences)
                return;

            SparkleGit git = new SparkleGit (LocalPath, "commit -m '" + message + "'");
            git.Start ();
            git.WaitForExit ();

            _CurrentHash = GetCurrentHash ();
            SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message + " (" + _CurrentHash + ")");

            SparkleEventArgs args = new SparkleEventArgs ("Commited") {
                Message = message
            };

            if (Commited != null)
                Commited (this, args);

            // Collect garbage pseudo-randomly
            if (DateTime.Now.Second % 10 == 0)
                CollectGarbage ();
        }
Пример #48
0
        public override bool SyncUp()
        {
            Add ();

            string message = FormatCommitMessage ();
            Commit (message);

            SparkleGit git = new SparkleGit (LocalPath, "push origin master");

            git.Start ();
            git.WaitForExit ();

            if (git.ExitCode == 0)
                return true;
            else
                return false;
        }
Пример #49
0
        // Returns a list of latest commits
        // TODO: Method needs to be made a lot faster
        public List<SparkleCommit> GetCommits(int count)
        {
            if (count < 1)
                count = 30;

            List <SparkleCommit> commits = new List <SparkleCommit> ();

            SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso");
            Console.OutputEncoding = System.Text.Encoding.Unicode;
            git_log.Start ();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_log.StandardOutput.ReadToEnd ();
            git_log.WaitForExit ();

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

            int j = 0;
            string entry = "", last_entry = "";
            foreach (string line in lines) {
                if (line.StartsWith ("commit") && j > 0) {
                    entries.Add (entry);
                    entry = "";
                }

                entry += line + "\n";
                j++;

                last_entry = entry;
            }

            entries.Add (last_entry);

            // TODO: Need to optimise for speed
            foreach (string log_entry in entries) {
                Regex regex;
                bool is_merge_commit = false;

                if (log_entry.Contains ("\nMerge: ")) {
                    regex = new Regex (@"commit ([a-z0-9]{40})\n" +
                                        "Merge: .+ .+\n" +
                                        "Author: (.+) <(.+)>\n" +
                                        "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                        "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                        "*");

                    is_merge_commit = true;
                } else {
                    regex = new Regex (@"commit ([a-z0-9]{40})\n" +
                                        "Author: (.+) <(.+)>\n" +
                                        "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                        "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                        "*");
                }

                Match match = regex.Match (log_entry);

                if (match.Success) {
                    SparkleCommit commit = new SparkleCommit ();

                    commit.Hash      = match.Groups [1].Value;
                    commit.UserName  = match.Groups [2].Value;
                    commit.UserEmail = match.Groups [3].Value;
                    commit.IsMerge   = is_merge_commit;

                    commit.DateTime = 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 [] entry_lines = log_entry.Split ("\n".ToCharArray ());

                    foreach (string entry_line in entry_lines) {
                        if (entry_line.StartsWith (":")) {

                            string change_type = entry_line [37].ToString ();
                            string file_path   = entry_line.Substring (39);
                            string to_file_path;

                            if (change_type.Equals ("A")) {
                                commit.Added.Add (file_path);
                            } else if (change_type.Equals ("M")) {
                                commit.Edited.Add (file_path);
                            } else if (change_type.Equals ("D")) {
                                commit.Deleted.Add (file_path);
                            } else if (change_type.Equals ("R")) {
                                int tab_pos  = entry_line.LastIndexOf ("\t");
                                file_path    = entry_line.Substring (42, tab_pos - 42);
                                to_file_path = entry_line.Substring (tab_pos + 1);

                                commit.MovedFrom.Add (file_path);
                                commit.MovedTo.Add (to_file_path);
                            }
                        }
                    }

                    commits.Add (commit);
                }
            }

            return commits;
        }
Пример #50
0
        // Commits the made changes
        private void Commit(string message)
        {
            if (!AnyDifferences)
                return;

            SparkleGit git = new SparkleGit (LocalPath, "commit -m \"" + message + "\"");
            git.Start ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message);

            // Collect garbage pseudo-randomly. Turn off for
            // now: too resource heavy.
            // if (DateTime.Now.Second % 10 == 0)
            //     CollectGarbage ();
        }
Пример #51
0
        // Merges the fetched changes
        public void Rebase()
        {
            if (AnyDifferences) {
                Add ();

                string commit_message = FormatCommitMessage ();
                Commit (commit_message);
            }

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Rebasing changes...");
            SparkleGit git = new SparkleGit (LocalPath, "rebase -v FETCH_HEAD");

            git.Exited += delegate {
            /*                if (Status.MergeConflict.Count > 0) {
                    SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict detected...");

                    foreach (string problem_file_name in Status.MergeConflict) {
                        SparkleGit git_ours = new SparkleGit (LocalPath,
                            "checkout --ours " + problem_file_name);
                        git_ours.Start ();
                        git_ours.WaitForExit ();

                        string timestamp     = DateTime.Now.ToString ("H:mm d MMM");
                        string new_file_name = problem_file_name + " (" + UserName  + ", " + timestamp + ")";

                        File.Move (problem_file_name, new_file_name);

                        SparkleGit git_theirs = new SparkleGit (LocalPath,
                            "checkout --theirs " + problem_file_name);
                        git_theirs.Start ();
                        git_theirs.WaitForExit ();

                        SparkleEventArgs args = new SparkleEventArgs ("ConflictDetected");

                        if (ConflictDetected != null)
                            ConflictDetected (this, args);
                    }

                    Add ();

                    SparkleGit git_continue = new SparkleGit (LocalPath, "rebase --continue");
                    git_continue.Start ();
                    git_continue.WaitForExit ();

                    SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict resolved.");
            */
                    _CurrentHash = GetCurrentHash ();
            //                    Push ();
            //                }
            };

            git.Start ();
            git.WaitForExit ();

            _CurrentHash = GetCurrentHash ();

            if (NewCommit != null)
                NewCommit (GetCommits (1) [0], LocalPath);

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes rebased.");
        }
Пример #52
0
        public override bool Fetch()
        {
            this.git = new SparkleGit(SparkleConfig.DefaultConfig.TmpPath,
                                      "clone " +
                                      "--progress " + // Redirects progress stats to standarderror
                                      "\"" + base.remote_url + "\" " + "\"" + base.target_folder + "\"");

            this.git.StartInfo.RedirectStandardError = true;
            this.git.Start();

            double percentage     = 1.0;
            Regex  progress_regex = new Regex(@"([0-9]+)%", RegexOptions.Compiled);

            DateTime last_change     = DateTime.Now;
            TimeSpan change_interval = new TimeSpan(0, 0, 0, 1);

            while (!this.git.StandardError.EndOfStream)
            {
                string line  = this.git.StandardError.ReadLine();
                Match  match = progress_regex.Match(line);

                double number = 0.0;
                if (match.Success)
                {
                    number = double.Parse(match.Groups [1].Value);

                    // The cloning progress consists of two stages: the "Compressing
                    // objects" stage which we count as 20% of the total progress, and
                    // the "Receiving objects" stage which we count as the last 80%
                    if (line.Contains("|"))
                    {
                        // "Receiving objects" stage
                        number = (number / 100 * 80 + 20);
                    }
                    else
                    {
                        // "Compressing objects" stage
                        number = (number / 100 * 20);
                    }
                }

                if (number >= percentage)
                {
                    percentage = number;

                    if (DateTime.Compare(last_change, DateTime.Now.Subtract(change_interval)) < 0)
                    {
                        base.OnProgressChanged(percentage);
                        last_change = DateTime.Now;
                    }
                }
            }

            this.git.WaitForExit();
            SparkleHelpers.DebugInfo("Git", "Exit code " + this.git.ExitCode.ToString());


            if (this.git.ExitCode != 0)
            {
                return(false);
            }
            else
            {
                InstallConfiguration();
                InstallExcludeRules();
                return(true);
            }
        }
Пример #53
0
        private void CheckForRemoteChanges()
        {
            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
            SparkleGit git = new SparkleGit (LocalPath, "ls-remote origin master");

            git.Exited += delegate {
                if (git.ExitCode != 0)
                    return;

                string remote_hash = git.StandardOutput.ReadToEnd ();

                if (!remote_hash.StartsWith (_CurrentHash)) {
                    SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found.");
                    Fetch ();

                    Watcher.EnableRaisingEvents = false;
                    Rebase ();
                    Watcher.EnableRaisingEvents = true;
                }
            };

            git.Start ();
            git.WaitForExit ();
        }
Пример #54
0
        public override bool CheckForRemoteChanges()
        {
            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
            SparkleGit git = new SparkleGit (LocalPath, "ls-remote origin master");

            git.Start ();
            git.WaitForExit ();

            if (git.ExitCode != 0)
                return false;

            string remote_revision = git.StandardOutput.ReadToEnd ().TrimEnd ();

            if (!remote_revision.StartsWith (CurrentRevision)) {
                SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found. (" + remote_revision + ")");
                return true;

            } else {
                return false;
            }
        }
Пример #55
0
        // Creates a pretty commit message based on what has changed
        private string FormatCommitMessage()
        {
            List<string> Added    = new List<string> ();
            List<string> Modified = new List<string> ();
            List<string> Removed  = new List<string> ();
            string file_name      = "";
            string message        = null;

            SparkleGit git_status = new SparkleGit (LocalPath, "status --porcelain");
            git_status.Start ();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_status.StandardOutput.ReadToEnd ().Trim ("\n".ToCharArray ());
            git_status.WaitForExit ();

            string [] lines = output.Split ("\n".ToCharArray ());
            foreach (string line in lines) {
                if (line.StartsWith ("A"))
                    Added.Add (line.Substring (2));
                else if (line.StartsWith ("M"))
                    Modified.Add (line.Substring (2));
                else if (line.StartsWith ("D"))
                    Removed.Add (line.Substring (2));
                else if (line.StartsWith ("R")) {
                    Removed.Add (line.Substring (3, (line.IndexOf (" -> ") - 3)));
                    Added.Add (line.Substring (line.IndexOf (" -> ") + 4));
                }
            }

            if (Added.Count > 0) {
                foreach (string added in Added) {
                    file_name = added.Trim ("\"".ToCharArray ());
                    break;
                }

                message = "+ ‘" + file_name + "’";
            }

            if (Modified.Count > 0) {
                foreach (string modified in Modified) {
                    file_name = modified.Trim ("\"".ToCharArray ());
                    break;
                }

                message = "/ ‘" + file_name + "’";
            }

            if (Removed.Count > 0) {
                foreach (string removed in Removed) {
                    file_name = removed.Trim ("\"".ToCharArray ());
                    break;
                }

                message = "- ‘" + file_name + "’";
            }

            int changes_count = (Added.Count +
                                 Modified.Count +
                                 Removed.Count);

            if (changes_count > 1)
                message += " + " + (changes_count - 1);

            return message;
        }
Пример #56
0
        // Returns a list of the latest change sets
        public override List<SparkleChangeSet> GetChangeSets(int count)
        {
            if (count < 1)
                count = 30;

            List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();

            // Console.InputEncoding  = System.Text.Encoding.Unicode;
            Console.OutputEncoding = System.Text.Encoding.Unicode;

            SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso");
            git_log.Start ();

            // Reading the standard output HAS to go before
            // WaitForExit, or it will hang forever on output > 4096 bytes
            string output = git_log.StandardOutput.ReadToEnd ();
            git_log.WaitForExit ();

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

            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 250 files to prevent memory issues
                if (line_number < 254) {
                    entry += line + "\n";
                    line_number++;
                }

                last_entry = entry;
            }

            entries.Add (last_entry);

            Regex merge_regex = new Regex (@"commit ([a-z0-9]{40})\n" +
                                "Merge: .+ .+\n" +
                                "Author: (.+) <(.+)>\n" +
                                "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                "([0-9]{2}):([0-9]{2}):([0-9]{2}) .([0-9]{4})\n" +
                                "*", RegexOptions.Compiled);

            Regex non_merge_regex = new Regex (@"commit ([a-z0-9]{40})\n" +
                                "Author: (.+) <(.+)>\n" +
                                "Date:   ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
                                "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" +
                                "*", RegexOptions.Compiled);

            foreach (string log_entry in entries) {
                Regex regex;
                bool is_merge_commit = false;

                if (log_entry.Contains ("\nMerge: ")) {
                    regex = merge_regex;
                    is_merge_commit = true;
                } else {
                    regex = non_merge_regex;
                }

                Match match = regex.Match (log_entry);

                if (match.Success) {
                    SparkleChangeSet change_set = new SparkleChangeSet ();

                    change_set.Folder        = Name;
                    change_set.Revision      = match.Groups [1].Value;
                    change_set.User.Name     = match.Groups [2].Value;
                    change_set.User.Email    = match.Groups [3].Value;
                    change_set.IsMagical     = is_merge_commit;

                    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 ());

                    foreach (string entry_line in entry_lines) {
                        if (entry_line.StartsWith (":")) {

                            string change_type = entry_line [37].ToString ();
                            string file_path   = entry_line.Substring (39);
                            string to_file_path;

                            if (file_path.EndsWith (".empty"))
                                file_path = file_path.Substring (0, file_path.Length - ".empty".Length);

                            if (change_type.Equals ("A") && !file_path.Contains (".notes")) {
                                change_set.Added.Add (file_path);

                            } else if (change_type.Equals ("M")) {
                                change_set.Edited.Add (file_path);

                            } else if (change_type.Equals ("D")) {
                                change_set.Deleted.Add (file_path);

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

                                change_set.MovedFrom.Add (file_path);
                                change_set.MovedTo.Add (to_file_path);
                            }
                        }
                    }

                    if ((change_set.Added.Count +
                         change_set.Edited.Count +
                         change_set.Deleted.Count +
                         change_set.MovedFrom.Count) > 0) {

                        change_set.Notes.AddRange (GetNotes (change_set.Revision));
                        change_sets.Add (change_set);
                    }
                }
            }

            return change_sets;
        }
Пример #57
0
        private string GetRemoteOriginUrl()
        {
            SparkleGit git = new SparkleGit (LocalPath, "config --get remote.origin.url");
            git.Start ();
            git.WaitForExit ();

            string output = git.StandardOutput.ReadToEnd ();
            string url    = output.Trim ();

            return url;
        }
Пример #58
0
        public override bool SyncUp()
        {
            if (AnyDifferences) {
                Add ();

                string message = FormatCommitMessage ();
                Commit (message);
            }

            SparkleGit git = new SparkleGit (LocalPath,
                "push --progress " + // Redirects progress stats to standarderror
                "origin master");

            git.StartInfo.RedirectStandardError = true;
            git.Start ();

            double percentage = 1.0;
            Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);

            while (!git.StandardError.EndOfStream) {
                string line   = git.StandardError.ReadLine ();
                Match match   = progress_regex.Match (line);
                string speed  = "";
                double number = 0.0;

                if (match.Success) {
                    number = double.Parse (match.Groups [1].Value);

                    // The pushing progress consists of two stages: the "Compressing
                    // objects" stage which we count as 20% of the total progress, and
                    // the "Writing objects" stage which we count as the last 80%
                    if (line.StartsWith ("Compressing")) {
                        // "Compressing objects" stage
                        number = (number / 100 * 20);

                    } else {
                        // "Writing objects" stage
                        number = (number / 100 * 80 + 20);

                        if (line.Contains ("|")) {
                            speed = line.Substring (line.IndexOf ("|") + 1).Trim ();
                            speed = speed.Replace (", done.", "").Trim ();
                            speed = speed.Replace ("i", "");
                            speed = speed.Replace ("KB/s", "ᴋʙ/s");
                            speed = speed.Replace ("MB/s", "ᴍʙ/s");
                        }
                    }
                }

                if (number >= percentage) {
                    percentage = number;
                    base.OnSyncProgressChanged (percentage, speed);
                }
            }

            git.WaitForExit ();

            CalculateSizes ();

            if (git.ExitCode == 0)
                return true;
            else
                return false;
        }
Пример #59
0
        private string GetUserName()
        {
            SparkleGit git = new SparkleGit (LocalPath, "config --get user.name");
            git.Start ();
            git.WaitForExit ();

            string output = git.StandardOutput.ReadToEnd ();
            string user_name   = output.Trim ();

            return user_name;
        }
Пример #60
0
        // Stages the made changes
        private void Add()
        {
            SparkleGit git = new SparkleGit (LocalPath, "add --all");
            git.Start ();
            git.WaitForExit ();

            SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes staged");
        }