From 9413cf8499e16c50520edc4392408f16185bd168 Mon Sep 17 00:00:00 2001
From: Steve Francia <steve.francia@gmail.com>
Date: Mon, 25 Jan 2016 14:40:44 -0500
Subject: [PATCH] Handle self rename operations gracefully

---
 commands/hugo.go | 10 +++++++---
 hugolib/site.go  | 16 +++++++++++++++-
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/commands/hugo.go b/commands/hugo.go
index b186057c..89a2f7ed 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -483,6 +483,7 @@ func copyStatic() error {
 		publishDir = helpers.FilePathSeparator
 	}
 
+	// Includes both theme/static & /static
 	staticSourceFs := getStaticSourceFs()
 
 	if staticSourceFs == nil {
@@ -499,8 +500,12 @@ func copyStatic() error {
 	syncer.Delete = true
 	jww.INFO.Println("syncing static files to", publishDir)
 
-	// because we are using a baseFs (to get the union right). Sync from the root
-	syncer.Sync(publishDir, helpers.FilePathSeparator)
+	// because we are using a baseFs (to get the union right).
+	// set sync src to root
+	err := syncer.Sync(publishDir, helpers.FilePathSeparator)
+	if err != nil {
+		return err
+	}
 	return nil
 //
 //	themeDir, err := helpers.GetThemeStaticDirPath()
@@ -718,7 +723,6 @@ func NewWatcher(port int) error {
 						jww.FEEDBACK.Printf("Syncing all static files\n")
 						err := copyStatic()
 						if err != nil {
-							fmt.Println(err)
 							utils.StopOnErr(err, fmt.Sprintf("Error copying static files to %s", helpers.AbsPathify(viper.GetString("PublishDir"))))
 						}
 					} else {
diff --git a/hugolib/site.go b/hugolib/site.go
index 1d1f1cc1..6c66aa83 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -44,6 +44,7 @@ import (
 	"github.com/spf13/nitro"
 	"github.com/spf13/viper"
 	"gopkg.in/fsnotify.v1"
+	"github.com/spf13/afero"
 )
 
 var _ = transform.AbsURL
@@ -500,13 +501,26 @@ func (s *Site) ReBuild(events []fsnotify.Event) error {
 		go converterCollator(s, convertResults, errs)
 
 		for _, ev := range sourceChanged {
-			if ev.Op&fsnotify.Rename == fsnotify.Rename || ev.Op&fsnotify.Remove == fsnotify.Remove {
+
+			if  ev.Op&fsnotify.Remove == fsnotify.Remove {
 				//remove the file & a create will follow
 				path, _ := helpers.GetRelativePath(ev.Name, s.absContentDir())
 				s.RemovePageByPath(path)
 				continue
 			}
 
+			// Some editors (Vim) sometimes issue only a Rename operation when writing an existing file
+			// Sometimes a rename operation means that file has been renamed other times it means
+			// it's been updated
+			if ev.Op&fsnotify.Rename == fsnotify.Rename {
+				// If the file is still on disk, it's only been updated, if it's not, it's been moved
+				if ex, err := afero.Exists(hugofs.SourceFs, ev.Name); !ex || err != nil {
+					path, _ := helpers.GetRelativePath(ev.Name, s.absContentDir())
+					s.RemovePageByPath(path)
+					continue
+				}
+			}
+
 			file, err := s.ReReadFile(ev.Name)
 			if err != nil {
 				errs <- err
-- 
2.30.2