private void ClearCache()
        {
            if (!this.use_git_bin)
                return;

            PryanetGitBin git_bin = new PryanetGitBin (LocalPath, "clear -f");
            git_bin.StartAndWaitForExit ();
        }
        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;
            }
        }