Beispiel #1
0
        // Creates a pretty commit message based on what has changed
        private string FormatCommitMessage()
        {
            int count      = 0;
            string message = "";

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

            while (!git_status.StandardOutput.EndOfStream) {
                string line = git_status.StandardOutput.ReadLine ();
                line        = line.Trim ();

                if (line.EndsWith (".empty") || line.EndsWith (".empty\""))
                    line = line.Replace (".empty", "");

                if (line.StartsWith ("R")) {
                    string path = line.Substring (3, line.IndexOf (" -> ") - 3).Trim ("\"".ToCharArray ());
                    string moved_to_path = line.Substring (line.IndexOf (" -> ") + 4).Trim ("\"".ToCharArray ());

                    message +=  "< ‘" + EnsureSpecialCharacters (path) + "’\n";
                    message +=  "> ‘" + EnsureSpecialCharacters (moved_to_path) + "’\n";

                } else {
                    if (line.StartsWith ("M")) {
                        message += "/";

                    } else if (line.StartsWith ("D")) {
                        message += "-";

                    } else {
                        message += "+";
                    }

                    string path = line.Substring (3).Trim ("\"".ToCharArray ());
                    message += " ‘" + EnsureSpecialCharacters (path) + "’\n";
                }

                count++;
                if (count == 10) {
                    message += "...\n";
                    break;
                }
            }

            git_status.StandardOutput.ReadToEnd ();
            git_status.WaitForExit ();

            if (string.IsNullOrWhiteSpace (message))
                return null;
            else
                return message;
        }
Beispiel #2
0
        public override bool SyncDown()
        {
            PryanetGit git = new PryanetGit (LocalPath, "fetch --progress \"" + RemoteUrl + "\" " + this.branch);

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

            double percentage = 1.0;

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

                if (match.Success) {
                    try {
                        number = double.Parse (match.Groups [1].Value, new CultureInfo ("en-US"));

                    } catch (FormatException) {
                        PryanetLogger.LogInfo ("Git", "Error parsing progress: \"" + match.Groups [1] + "\"");
                    }

                    // 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);
                        Match speed_match = this.speed_regex.Match (line);

                        if (speed_match.Success) {
                            try {
                                speed = double.Parse (speed_match.Groups [1].Value, new CultureInfo ("en-US")) * 1024;

                            } catch (FormatException) {
                                PryanetLogger.LogInfo ("Git", "Error parsing speed: \"" + speed_match.Groups [1] + "\"");
                            }

                            if (speed_match.Groups [2].Value.Equals ("M"))
                                speed = speed * 1024;
                        }
                    }

                } else {
                    PryanetLogger.LogInfo ("Git", Name + " | " + line);

                    if (FindError (line))
                        return false;
                }

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

            git.WaitForExit ();
            UpdateSizes ();

            if (git.ExitCode == 0) {
                if (Rebase ()) {
                    ClearCache ();
                    return true;

                } else {
                    return false;
                }

            } else {
                Error = ErrorStatus.HostUnreachable;
                return false;
            }
        }
Beispiel #3
0
        public override bool SyncUp()
        {
            if (!Add ()) {
                Error = ErrorStatus.UnreadableFiles;
                return false;
            }

            string message = FormatCommitMessage ();

            if (message != null)
                Commit (message);

            if (this.use_git_bin) {
                PryanetGitBin git_bin = new PryanetGitBin (LocalPath, "push");
                git_bin.StartAndWaitForExit ();

                // TODO: Progress
            }

            PryanetGit git = new PryanetGit (LocalPath, "push --progress \"" + RemoteUrl + "\" " + this.branch);
            git.StartInfo.RedirectStandardError = true;
            git.Start ();

            double percentage = 1.0;

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

                if (match.Success) {
                    try {
                        number = double.Parse (match.Groups [1].Value, new CultureInfo ("en-US"));

                    } catch (FormatException) {
                        PryanetLogger.LogInfo ("Git", "Error parsing progress: \"" + match.Groups [1] + "\"");
                    }

                    // 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);
                        Match speed_match = this.speed_regex.Match (line);

                        if (speed_match.Success) {
                            try {
                                speed = double.Parse (speed_match.Groups [1].Value, new CultureInfo ("en-US")) * 1024;

                            } catch (FormatException) {
                                PryanetLogger.LogInfo ("Git", "Error parsing speed: \"" + speed_match.Groups [1] + "\"");
                            }

                            if (speed_match.Groups [2].Value.Equals ("M"))
                                speed = speed * 1024;
                        }
                    }

                } else {
                    PryanetLogger.LogInfo ("Git", Name + " | " + line);

                    if (FindError (line))
                        return false;
                }

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

            git.WaitForExit ();
            UpdateSizes ();

            if (git.ExitCode == 0) {
                ClearCache ();

                string salt_file_path = new string [] { LocalPath, ".git", "salt" }.Combine ();

                // If the repo is encrypted, create a branch to
                // store the salt in and push it to the host
                if (File.Exists (salt_file_path)) {
                    string salt = File.ReadAllText (salt_file_path).Trim ();

                    PryanetGit git_salt = new PryanetGit (LocalPath, "branch salt-" + salt);
                    git_salt.StartAndWaitForExit ();

                    git_salt = new PryanetGit (LocalPath, "push origin salt-" + salt);
                    git_salt.StartAndWaitForExit ();

                    File.Delete (salt_file_path);
                }

                return true;

            } else {
                Error = ErrorStatus.HostUnreachable;
                return false;
            }
        }
Beispiel #4
0
        public override void RestoreFile(string path, string revision, string target_file_path)
        {
            if (path == null)
                throw new ArgumentNullException ("path");

            if (revision == null)
                throw new ArgumentNullException ("revision");

            PryanetLogger.LogInfo ("Git", Name + " | Restoring \"" + path + "\" (revision " + revision + ")");

            // git-show doesn't decrypt objects, so we can't use it to retrieve
            // files from the index. This is a suboptimal workaround but it does the job
            if (this.is_encrypted) {
                // Restore the older file...
                PryanetGit git = new PryanetGit (LocalPath, "checkout " + revision + " \"" + path + "\"");
                git.StartAndWaitForExit ();

                string local_file_path = Path.Combine (LocalPath, path);

                // ...move it...
                try {
                    File.Move (local_file_path, target_file_path);

                } catch {
                    PryanetLogger.LogInfo ("Git",
                        Name + " | Could not move \"" + local_file_path + "\" to \"" + target_file_path + "\"");
                }

                // ...and restore the most recent revision
                git = new PryanetGit (LocalPath, "checkout " + CurrentRevision + " \"" + path + "\"");
                git.StartAndWaitForExit ();

            // The correct way
            } else {
                path = path.Replace ("\"", "\\\"");

                PryanetGit git = new PryanetGit (LocalPath, "show " + revision + ":\"" + path + "\"");
                git.Start ();

                FileStream stream = File.OpenWrite (target_file_path);
                git.StandardOutput.BaseStream.CopyTo (stream);
                stream.Close ();

                git.WaitForExit ();
            }

            if (target_file_path.StartsWith (LocalPath))
                new Thread (() => OnFileActivity (null)).Start ();
        }