diff options
author | Jo Shields <directhex@apebox.org> | 2015-12-21 22:01:14 +0000 |
---|---|---|
committer | Jo Shields <directhex@apebox.org> | 2015-12-21 22:01:14 +0000 |
commit | 89d5f75065cf2a7e2ca1c122c26a34d7433d120d (patch) | |
tree | 077dcd6b4a6b0aca6c8368c5da9a3ebe40137f48 /SparkleLib/Git | |
parent | e45ec00415203c0133be6d18a72326f3506f793b (diff) |
Imported Upstream version 1.2
Diffstat (limited to 'SparkleLib/Git')
-rw-r--r-- | SparkleLib/Git/Makefile.in | 166 | ||||
-rwxr-xr-x | SparkleLib/Git/SparkleFetcherGit.cs | 137 | ||||
-rw-r--r-- | SparkleLib/Git/SparkleGit.cs | 8 | ||||
-rw-r--r-- | SparkleLib/Git/SparkleRepoGit.cs | 311 |
4 files changed, 425 insertions, 197 deletions
diff --git a/SparkleLib/Git/Makefile.in b/SparkleLib/Git/Makefile.in index bcb72cd..3717490 100644 --- a/SparkleLib/Git/Makefile.in +++ b/SparkleLib/Git/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.13.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -32,10 +76,10 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ +DIST_COMMON = $(top_srcdir)/build/build.mk \ $(top_srcdir)/build/build.environment.mk \ - $(top_srcdir)/build/build.mk \ - $(top_srcdir)/build/build.rules.mk + $(top_srcdir)/build/build.rules.mk $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am subdir = SparkleLib/Git ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shave/shave.m4 \ @@ -80,11 +124,48 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(moduledir)" SCRIPTS = $(module_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_MAKEFLAGS = @AM_MAKEFLAGS@ APP_INDICATOR_CFLAGS = @APP_INDICATOR_CFLAGS@ APP_INDICATOR_LIBS = @APP_INDICATOR_LIBS@ @@ -216,7 +297,6 @@ DIR_BIN = $(top_builddir)/bin # External libraries to link against, generated from configure LINK_SYSTEM = -r:System -LINK_SYSTEM_WEB = -r:System.Web LINK_MONO_POSIX = -r:Mono.Posix LINK_GLIB = $(GLIBSHARP_LIBS) LINK_GTK = $(GTKSHARP_LIBS) @@ -230,7 +310,7 @@ LINK_NOTIFY_SHARP_DEPS = $(REF_NOTIFY_SHARP) $(LINK_NOTIFY_SHARP) REF_SPARKLELIB = $(LINK_SYSTEM) $(LINK_MONO_POSIX) LINK_SPARKLELIB = -r:$(DIR_BIN)/SparkleLib.dll LINK_SPARKLELIB_DEPS = $(REF_SPARKLELIB) $(LINK_SPARKLELIB) -REF_SPARKLESHARE = $(LINK_SYSTEM_WEB) $(LINK_DBUS) $(LINK_GTK) $(LINK_SPARKLELIB_DEPS) $(LINK_APP_INDICATOR) +REF_SPARKLESHARE = $(LINK_DBUS) $(LINK_GTK) $(LINK_SPARKLELIB_DEPS) $(LINK_APP_INDICATOR) # Cute hack to replace a space with something colon := : @@ -306,8 +386,11 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-moduleSCRIPTS: $(module_SCRIPTS) @$(NORMAL_INSTALL) - test -z "$(moduledir)" || $(MKDIR_P) "$(DESTDIR)$(moduledir)" @list='$(module_SCRIPTS)'; test -n "$(moduledir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ @@ -342,12 +425,58 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -tags: TAGS -TAGS: -ctags: CTAGS -CTAGS: +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -425,7 +554,7 @@ clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile -distclean-am: clean-am distclean-generic +distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am @@ -489,8 +618,9 @@ uninstall-am: uninstall-moduleSCRIPTS $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-data-am install-strip uninstall-am -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-hook install-dvi \ install-dvi-am install-exec install-exec-am install-html \ @@ -499,7 +629,7 @@ uninstall-am: uninstall-moduleSCRIPTS install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am uninstall uninstall-am uninstall-hook \ + ps ps-am tags tags-am uninstall uninstall-am uninstall-hook \ uninstall-moduleSCRIPTS diff --git a/SparkleLib/Git/SparkleFetcherGit.cs b/SparkleLib/Git/SparkleFetcherGit.cs index fc36646..a9a9b3e 100755 --- a/SparkleLib/Git/SparkleFetcherGit.cs +++ b/SparkleLib/Git/SparkleFetcherGit.cs @@ -29,9 +29,12 @@ namespace SparkleLib.Git { private SparkleGit git; private bool use_git_bin; - private string cached_salt; + private Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled); + private Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled); + + private string crypto_salt { get { if (!string.IsNullOrEmpty (this.cached_salt)) @@ -123,54 +126,82 @@ namespace SparkleLib.Git { 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, new CultureInfo ("en-US")); + try { + while (!this.git.StandardError.EndOfStream) { + string line = this.git.StandardError.ReadLine (); + Match match = this.progress_regex.Match (line); - // 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 ("|")) - number = (number / 100 * 80 + 20); // "Receiving objects" stage - else - number = (number / 100 * 20); // "Compressing objects" stage - - } else { - SparkleLogger.LogInfo ("Fetcher", line); - line = line.Trim (new char [] {' ', '@'}); - - if (line.StartsWith ("fatal:", StringComparison.InvariantCultureIgnoreCase) || - line.StartsWith ("error:", StringComparison.InvariantCultureIgnoreCase)) { - - base.errors.Add (line); - - } else if (line.StartsWith ("WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!")) { - base.errors.Add ("warning: Remote host identification has changed!"); - - } else if (line.StartsWith ("WARNING: POSSIBLE DNS SPOOFING DETECTED!")) { - base.errors.Add ("warning: Possible DNS spoofing detected!"); + double number = 0.0; + double speed = 0.0; + if (match.Success) { + try { + number = double.Parse (match.Groups [1].Value, new CultureInfo ("en-US")); + + } catch (FormatException) { + SparkleLogger.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.Contains ("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) { + SparkleLogger.LogInfo ("Git", "Error parsing speed: \"" + speed_match.Groups [1] + "\""); + } + + if (speed_match.Groups [2].Value.Equals ("M")) + speed = speed * 1024; + } + } + + } else { + SparkleLogger.LogInfo ("Fetcher", line); + line = line.Trim (new char [] {' ', '@'}); + + if (line.StartsWith ("fatal:", StringComparison.InvariantCultureIgnoreCase) || + line.StartsWith ("error:", StringComparison.InvariantCultureIgnoreCase)) { + + base.errors.Add (line); + + } else if (line.StartsWith ("WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!")) { + base.errors.Add ("warning: Remote host identification has changed!"); + + } else if (line.StartsWith ("WARNING: POSSIBLE DNS SPOOFING DETECTED!")) { + base.errors.Add ("warning: Possible DNS spoofing detected!"); + } } - } - if (number >= percentage) { - percentage = number; + if (number >= percentage) { + percentage = number; - if (DateTime.Compare (last_change, DateTime.Now.Subtract (change_interval)) < 0) { - base.OnProgressChanged (percentage); - last_change = DateTime.Now; + if (DateTime.Compare (last_change, DateTime.Now.Subtract (change_interval)) < 0) { + base.OnProgressChanged (percentage, speed); + last_change = DateTime.Now; + } } } - } + } catch (Exception) { + IsActive = false; + return false; + } + this.git.WaitForExit (); if (this.git.ExitCode == 0) { @@ -181,10 +212,10 @@ namespace SparkleLib.Git { break; Thread.Sleep (500); - base.OnProgressChanged (percentage); + base.OnProgressChanged (percentage, 0); } - base.OnProgressChanged (100); + base.OnProgressChanged (100, 0); InstallConfiguration (); InstallExcludeRules (); @@ -248,10 +279,8 @@ namespace SparkleLib.Git { return false; } - Process process = new Process () { - EnableRaisingEvents = true - }; - + Process process = new Process (); + process.EnableRaisingEvents = true; process.StartInfo.WorkingDirectory = TargetFolder; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; @@ -259,7 +288,10 @@ namespace SparkleLib.Git { process.StartInfo.FileName = "openssl"; process.StartInfo.Arguments = "enc -d -aes-256-cbc -base64 -S " + this.crypto_salt + - " -pass pass:\"" + password + "\" -in " + password_check_file_path; + " -pass pass:\"" + password + "\" -in \"" + password_check_file_path + "\""; + + SparkleLogger.LogInfo ("Cmd | " + System.IO.Path.GetFileName (process.StartInfo.WorkingDirectory), + System.IO.Path.GetFileName (process.StartInfo.FileName) + " " + process.StartInfo.Arguments); process.Start (); process.WaitForExit (); @@ -277,8 +309,7 @@ namespace SparkleLib.Git { public override void Stop () { try { - if (this.git != null) { - this.git.Close (); + if (this.git != null && !this.git.HasExited) { this.git.Kill (); this.git.Dispose (); } @@ -286,6 +317,16 @@ namespace SparkleLib.Git { } catch (Exception e) { SparkleLogger.LogInfo ("Fetcher", "Failed to dispose properly", e); } + + if (Directory.Exists (TargetFolder)) { + try { + Directory.Delete (TargetFolder, true /* Recursive */ ); + SparkleLogger.LogInfo ("Fetcher", "Deleted '" + TargetFolder + "'"); + + } catch (Exception e) { + SparkleLogger.LogInfo ("Fetcher", "Failed to delete '" + TargetFolder + "'", e); + } + } } @@ -309,7 +350,7 @@ namespace SparkleLib.Git { "core.autocrlf false", // Don't change file line endings "core.precomposeunicode true", // Use the same Unicode form on all filesystems "core.safecrlf false", - "core.exludesfile \"\"", + "core.excludesfile \"\"", "core.packedGitLimit 128m", // Some memory limiting options "core.packedGitWindowSize 128m", "pack.deltaCacheSize 128m", diff --git a/SparkleLib/Git/SparkleGit.cs b/SparkleLib/Git/SparkleGit.cs index 3ccde01..8dd6489 100644 --- a/SparkleLib/Git/SparkleGit.cs +++ b/SparkleLib/Git/SparkleGit.cs @@ -103,6 +103,7 @@ namespace SparkleLib.Git { public static string ExecPath; public static string GitPath; + public static string SSHPath; public SparkleGit (string path, string args) : base (path, args) @@ -121,6 +122,13 @@ namespace SparkleLib.Git { StartInfo.EnvironmentVariables ["LANG"] = "en_US"; else StartInfo.EnvironmentVariables.Add ("LANG", "en_US"); + + if (!string.IsNullOrEmpty (SSHPath)) { + if (StartInfo.EnvironmentVariables.ContainsKey ("GIT_SSH")) + StartInfo.EnvironmentVariables ["GIT_SSH"] = SSHPath; + else + StartInfo.EnvironmentVariables.Add ("GIT_SSH", SSHPath); + } if (string.IsNullOrEmpty (ExecPath)) StartInfo.Arguments = args; diff --git a/SparkleLib/Git/SparkleRepoGit.cs b/SparkleLib/Git/SparkleRepoGit.cs index 28d7ba7..100340a 100644 --- a/SparkleLib/Git/SparkleRepoGit.cs +++ b/SparkleLib/Git/SparkleRepoGit.cs @@ -51,6 +51,9 @@ namespace SparkleLib.Git { string rebase_apply_path = new string [] { LocalPath, ".git", "rebase-apply" }.Combine (); + SparkleGit git = new SparkleGit (LocalPath, "config core.ignorecase true"); + git.StartAndWaitForExit (); + while (Directory.Exists (rebase_apply_path) && HasLocalChanges) { try { ResolveConflict (); @@ -60,7 +63,10 @@ namespace SparkleLib.Git { } } - SparkleGit git = new SparkleGit (LocalPath, "rev-parse --abbrev-ref HEAD"); + git = new SparkleGit (LocalPath, "config core.ignorecase false"); + git.StartAndWaitForExit (); + + git = new SparkleGit (LocalPath, "rev-parse --abbrev-ref HEAD"); this.cached_branch = git.StartAndReadStandardOutput (); return this.cached_branch; @@ -507,6 +513,7 @@ namespace SparkleLib.Git { return false; } else { + SparkleLogger.LogInfo ("", error_output); SparkleLogger.LogInfo ("Git", Name + " | Conflict detected, trying to get out..."); while (Directory.Exists (rebase_apply_path) && HasLocalChanges) { @@ -560,12 +567,14 @@ namespace SparkleLib.Git { foreach (string line in lines) { string conflicting_path = line.Substring (3); conflicting_path = EnsureSpecialCharacters (conflicting_path); - conflicting_path = conflicting_path.Replace ("\"", "\\\""); + conflicting_path = conflicting_path.Trim ("\"".ToCharArray ()); SparkleLogger.LogInfo ("Git", Name + " | Conflict type: " + line); // Ignore conflicts in the .sparkleshare file and use the local version if (conflicting_path.EndsWith (".sparkleshare") || conflicting_path.EndsWith (".empty")) { + SparkleLogger.LogInfo ("Git", Name + " | Ignoring conflict in special file: " + conflicting_path); + // Recover local version SparkleGit git_theirs = new SparkleGit (LocalPath, "checkout --theirs \"" + conflicting_path + "\""); git_theirs.StartAndWaitForExit (); @@ -576,6 +585,8 @@ namespace SparkleLib.Git { continue; } + SparkleLogger.LogInfo ("Git", Name + " | Resolving: " + line); + // Both the local and server version have been modified if (line.StartsWith ("UU") || line.StartsWith ("AA") || line.StartsWith ("AU") || line.StartsWith ("UA")) { @@ -594,7 +605,8 @@ namespace SparkleLib.Git { 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); + if (File.Exists (abs_conflicting_path) && !File.Exists (abs_their_path)) + File.Move (abs_conflicting_path, abs_their_path); // Recover server version SparkleGit git_ours = new SparkleGit (LocalPath, "checkout --ours \"" + conflicting_path + "\""); @@ -604,12 +616,34 @@ namespace SparkleLib.Git { // The local version has been modified, but the server version was removed } else if (line.StartsWith ("DU")) { + // The modified local version is already in the checkout, so it just needs to be added. // We need to specifically mention the file, so we can't reuse the Add () method SparkleGit git_add = new SparkleGit (LocalPath, "add \"" + conflicting_path + "\""); git_add.StartAndWaitForExit (); changes_added = true; + + // The server version has been modified, but the local version was removed + } else if (line.StartsWith ("UD")) { + + // Recover server version + SparkleGit git_theirs = new SparkleGit (LocalPath, "checkout --ours \"" + conflicting_path + "\""); + git_theirs.StartAndWaitForExit (); + + changes_added = true; + + // Server and local versions were removed + } else if (line.StartsWith ("DD")) { + SparkleLogger.LogInfo ("Git", Name + " | No need to resolve: " + line); + + // New local files + } else if (line.StartsWith ("??")) { + SparkleLogger.LogInfo ("Git", Name + " | Found new file, no need to resolve: " + line); + changes_added = true; + + } else { + SparkleLogger.LogInfo ("Git", Name + " | Don't know what to do with: " + line); } } @@ -677,18 +711,6 @@ namespace SparkleLib.Git { } - public override List<SparkleChangeSet> GetChangeSets (string path) - { - return GetChangeSetsInternal (path); - } - - - public override List<SparkleChangeSet> GetChangeSets () - { - return GetChangeSetsInternal (null); - } - - private bool FindError (string line) { Error = ErrorStatus.None; @@ -702,14 +724,16 @@ namespace SparkleLib.Git { line.StartsWith ("ssh_exchange_identification: Connection closed by remote host")) { Error = ErrorStatus.AuthenticationFailed; + + } else if (line.EndsWith ("does not appear to be a git repository")) { + Error = ErrorStatus.NotFound; - } else if (line.StartsWith ("error: Disk space exceeded")) { + } else if (line.StartsWith ("error: Disk space exceeded") || + line.EndsWith ("No space left on device")) { + Error = ErrorStatus.DiskSpaceExceeded; - - } else if (line.EndsWith ("does not appear to be a git repository")) { - Error = ErrorStatus.NotFound; } - + if (Error != ErrorStatus.None) { SparkleLogger.LogInfo ("Git", Name + " | Error status changed to " + Error); return true; @@ -720,6 +744,16 @@ namespace SparkleLib.Git { } + public override List<SparkleChangeSet> GetChangeSets () + { + return GetChangeSetsInternal (null); + } + + public override List<SparkleChangeSet> GetChangeSets (string path) + { + return GetChangeSetsInternal (path); + } + private List<SparkleChangeSet> GetChangeSetsInternal (string path) { List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> (); @@ -748,6 +782,7 @@ namespace SparkleLib.Git { string [] lines = output.Split ("\n".ToCharArray ()); List<string> entries = new List <string> (); + // Split up commit entries int line_number = 0; bool first_pass = true; string entry = "", last_entry = ""; @@ -761,8 +796,8 @@ namespace SparkleLib.Git { first_pass = false; } - // Only parse 250 files to prevent memory issues - if (line_number < 254) { + // Only parse first 250 files to prevent memory issues + if (line_number < 250) { entry += line + "\n"; line_number++; } @@ -772,145 +807,159 @@ namespace SparkleLib.Git { entries.Add (last_entry); - + // Parse commit entries foreach (string log_entry in entries) { Match match = this.log_regex.Match (log_entry); - if (match.Success) { - SparkleChangeSet change_set = new SparkleChangeSet (); + if (!match.Success) + continue; - change_set.Folder = new SparkleFolder (Name); - change_set.Revision = match.Groups [1].Value; - change_set.User = new SparkleUser (match.Groups [2].Value, match.Groups [3].Value); - change_set.RemoteUrl = RemoteUrl; + SparkleChangeSet change_set = new SparkleChangeSet (); - 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)); + change_set.Folder = new SparkleFolder (Name); + change_set.Revision = match.Groups [1].Value; + change_set.User = new SparkleUser (match.Groups [2].Value, match.Groups [3].Value); + change_set.RemoteUrl = RemoteUrl; - 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); + 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 [] entry_lines = log_entry.Split ("\n".ToCharArray ()); + 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); - foreach (string entry_line in entry_lines) { - if (entry_line.StartsWith (":")) { - if (entry_line.Contains ("\\177")) - continue; + string [] entry_lines = log_entry.Split ("\n".ToCharArray ()); - string type_letter = entry_line [37].ToString (); - string file_path = entry_line.Substring (39); - bool change_is_folder = false; + // Parse file list. Lines containing file changes start with ":" + foreach (string entry_line in entry_lines) { + // Skip lines containing backspace characters + if (!entry_line.StartsWith (":") || entry_line.Contains ("\\177")) + continue; - if (file_path.Equals (".sparkleshare")) - continue; + string file_path = entry_line.Substring (39); - if (file_path.EndsWith (".empty")) { - file_path = file_path.Substring (0, file_path.Length - ".empty".Length); - change_is_folder = true; - } + if (file_path.Equals (".sparkleshare")) + continue; + + string type_letter = entry_line [37].ToString (); + bool change_is_folder = false; + + if (file_path.EndsWith (".empty")) { + file_path = file_path.Substring (0, file_path.Length - ".empty".Length); + change_is_folder = true; + } + try { + file_path = EnsureSpecialCharacters (file_path); + + } catch (Exception e) { + SparkleLogger.LogInfo ("Local", "Error parsing file name '" + file_path + "'", e); + continue; + } + + file_path = file_path.Replace ("\\\"", "\""); + + SparkleChange change = new SparkleChange () { + Path = file_path, + IsFolder = change_is_folder, + Timestamp = change_set.Timestamp, + Type = SparkleChangeType.Added + }; + + if (type_letter.Equals ("R")) { + int tab_pos = entry_line.LastIndexOf ("\t"); + file_path = entry_line.Substring (42, tab_pos - 42); + string to_file_path = entry_line.Substring (tab_pos + 1); + + try { file_path = EnsureSpecialCharacters (file_path); - file_path = file_path.Replace ("\\\"", "\""); - - if (type_letter.Equals ("R")) { - int tab_pos = entry_line.LastIndexOf ("\t"); - file_path = entry_line.Substring (42, tab_pos - 42); - string to_file_path = entry_line.Substring (tab_pos + 1); - - file_path = EnsureSpecialCharacters (file_path); - to_file_path = EnsureSpecialCharacters (to_file_path); - - file_path = file_path.Replace ("\\\"", "\""); - to_file_path = to_file_path.Replace ("\\\"", "\""); - - if (file_path.EndsWith (".empty")) { - file_path = file_path.Substring (0, file_path.Length - 6); - change_is_folder = true; - } - - if (to_file_path.EndsWith (".empty")) { - to_file_path = to_file_path.Substring (0, to_file_path.Length - 6); - change_is_folder = true; - } - - change_set.Changes.Add ( - new SparkleChange () { - Path = file_path, - IsFolder = change_is_folder, - MovedToPath = to_file_path, - Timestamp = change_set.Timestamp, - Type = SparkleChangeType.Moved - } - ); - - } else { - SparkleChangeType change_type = SparkleChangeType.Added; - - if (type_letter.Equals ("M")) { - change_type = SparkleChangeType.Edited; - - } else if (type_letter.Equals ("D")) { - change_type = SparkleChangeType.Deleted; - } - - change_set.Changes.Add ( - new SparkleChange () { - Path = file_path, - IsFolder = change_is_folder, - Timestamp = change_set.Timestamp, - Type = change_type - } - ); - } + + } catch (Exception e) { + SparkleLogger.LogInfo ("Local", "Error parsing file name '" + file_path + "'", e); + continue; + } + + try { + to_file_path = EnsureSpecialCharacters (to_file_path); + + } catch (Exception e) { + SparkleLogger.LogInfo ("Local", "Error parsing file name '" + to_file_path + "'", e); + continue; + } + + file_path = file_path.Replace ("\\\"", "\""); + to_file_path = to_file_path.Replace ("\\\"", "\""); + + if (file_path.EndsWith (".empty")) { + file_path = file_path.Substring (0, file_path.Length - 6); + change_is_folder = true; + } + + if (to_file_path.EndsWith (".empty")) { + to_file_path = to_file_path.Substring (0, to_file_path.Length - 6); + change_is_folder = true; } + + change.Path = file_path; + change.MovedToPath = to_file_path; + change.Type = SparkleChangeType.Moved; + + } else if (type_letter.Equals ("M")) { + change.Type = SparkleChangeType.Edited; + + } else if (type_letter.Equals ("D")) { + change.Type = SparkleChangeType.Deleted; } - if (change_sets.Count > 0 && path == null) { - SparkleChangeSet last_change_set = change_sets [change_sets.Count - 1]; + change_set.Changes.Add (change); + } - if (change_set.Timestamp.Year == last_change_set.Timestamp.Year && - change_set.Timestamp.Month == last_change_set.Timestamp.Month && - change_set.Timestamp.Day == last_change_set.Timestamp.Day && - change_set.User.Name.Equals (last_change_set.User.Name)) { + // Group commits per user, per day + if (change_sets.Count > 0 && path == null) { + SparkleChangeSet last_change_set = change_sets [change_sets.Count - 1]; - last_change_set.Changes.AddRange (change_set.Changes); + if (change_set.Timestamp.Year == last_change_set.Timestamp.Year && + change_set.Timestamp.Month == last_change_set.Timestamp.Month && + change_set.Timestamp.Day == last_change_set.Timestamp.Day && + change_set.User.Name.Equals (last_change_set.User.Name)) { - if (DateTime.Compare (last_change_set.Timestamp, change_set.Timestamp) < 1) { - last_change_set.FirstTimestamp = last_change_set.Timestamp; - last_change_set.Timestamp = change_set.Timestamp; - last_change_set.Revision = change_set.Revision; + last_change_set.Changes.AddRange (change_set.Changes); - } else { - last_change_set.FirstTimestamp = change_set.Timestamp; - } + if (DateTime.Compare (last_change_set.Timestamp, change_set.Timestamp) < 1) { + last_change_set.FirstTimestamp = last_change_set.Timestamp; + last_change_set.Timestamp = change_set.Timestamp; + last_change_set.Revision = change_set.Revision; } else { - change_sets.Add (change_set); + last_change_set.FirstTimestamp = change_set.Timestamp; } } else { - if (path != null) { - List<SparkleChange> changes_to_skip = new List<SparkleChange> (); + change_sets.Add (change_set); + } - foreach (SparkleChange change in change_set.Changes) { - if ((change.Type == SparkleChangeType.Deleted || change.Type == SparkleChangeType.Moved) - && change.Path.Equals (path)) { + } else { + // Don't show removals or moves in the revision list of a file + if (path != null) { + List<SparkleChange> changes_to_skip = new List<SparkleChange> (); - changes_to_skip.Add (change); - } - } + foreach (SparkleChange change in change_set.Changes) { + if ((change.Type == SparkleChangeType.Deleted || change.Type == SparkleChangeType.Moved) + && change.Path.Equals (path)) { - foreach (SparkleChange change_to_skip in changes_to_skip) - change_set.Changes.Remove (change_to_skip); + changes_to_skip.Add (change); + } } - - change_sets.Add (change_set); + + foreach (SparkleChange change_to_skip in changes_to_skip) + change_set.Changes.Remove (change_to_skip); } + + change_sets.Add (change_set); } } |