]> rtime.felk.cvut.cz Git - git-ftp-sync.git/blobdiff - git-ftp-sync
First run uploads the whole current tree, not only the changes in the last commit
[git-ftp-sync.git] / git-ftp-sync
index 5d40c9da5d2ca3e3ac86c2fcb199a5f524b6220d..73fd7ab4aa424ee475329349196d99d90216ea45 100755 (executable)
@@ -89,7 +89,7 @@ class Syncer:
                 print "%s: DEL   "%self.__class__.__name__, change.dest_path
                 self._delete(change.dest_path)
         else:
-            print >> sys.stderr, "Unknown change:", change.type, change.dest_path
+            perror("Unknown change: %s %s" % (change.type, change.dest_path))
             sys.exit(1)
 
     def mkd(self, path):
@@ -124,7 +124,7 @@ class FTPSync(Syncer):
         try:
             self.ftp.mkd(path)
         except ftplib.error_perm, detail:
-            print >> sys.stderr, "FTP warning:", detail, path
+            perror("FTP warning: %s %s" % (detail, path))
 
     def _storbinary(self, string, path):
         #print >> sys.stderr, self.dest_path
@@ -135,14 +135,14 @@ class FTPSync(Syncer):
             # FIXME: this should be recursive deletion
             self.ftp.rmd(path)
         except ftplib.error_perm, detail:
-            print >> sys.stderr, "FTP warning:", detail
+            perror("FTP warning: %s %s" % (detail, path))
 
     def _delete(self, path):
         try:
             #print >> sys.stderr, path
             self.ftp.delete(path)
         except ftplib.error_perm, detail:
-            print >> sys.stderr, "FTP warning:", detail, self.dest_path
+            perror("FTP warning: %s %s" % (detail, path))
 
 
 class LocalSync(Syncer):
@@ -180,18 +180,30 @@ def selftest():
     mkdir repo.git
     cd repo.git
     git --bare init
-    echo -e "%s" > hooks/pre-receive
-    chmod +x hooks/pre-receive
     REPO=$PWD
     cd ..
     mkdir www
     mkdir working
     cd working
     git init
+    mkdir www
+
+    # Commit something to www directory in repo without the activated hook
+    echo 'Bye' > www/first.html
+    git add www/first.html
+    commit_push 'Added first.html'
+    
+    # Activate the hook and commit a non-mirrored file
+    echo "%s" > $REPO/hooks/post-receive
+    chmod +x $REPO/hooks/post-receive
     echo 'abc' > non-mirrored-file
     git add non-mirrored-file
     commit_push 'Added non-mirrored-file'
-    mkdir www
+
+    # Check that the first commit appears in www even if the hook was
+    # activated later (only for local sync)
+    grep -q PASSWORD $REPO/hooks/post-receive || test -f ../www/first.html
+    
     cd www
     echo 'Hello' > index.html
     git add index.html
@@ -214,6 +226,8 @@ def selftest():
     cd ..
     git rm www/index2.html
     commit_push 'Removed index2'
+    git rm www/first.html
+    commit_push 'Removed first.html'
     cd $REPO/..
     rm -rf working repo.git www    
     """
@@ -233,9 +247,20 @@ def selftest():
     print
     print "Selftest succeeded!"
 
-def build_change_list(changes, oldrev, newrev):
+def perror(str):    
+    print >>sys.stderr, "git-ftp-sync: %s"%str
+
+
+def update_ref(hash):
+    remote = "ftp"
+    branch = "master"
+    if (not os.path.exists("refs/remotes/"+remote)):
+        os.makedirs("refs/remotes/"+remote)
+    file("refs/remotes/"+remote+"/"+branch, "w").write(newrev+"\n")
+
+def add_to_change_list(changes, git_command):
     # Read changes
-    gitdiff = Popen("/usr/bin/git diff --name-status %s %s"%(oldrev, newrev),
+    gitdiff = Popen(git_command,
                     stdout=PIPE, stderr=PIPE, close_fds=True, shell=True)
     change_re = re.compile("(\S+)\s+(.*)$");
     for line in gitdiff.stdout:
@@ -246,8 +271,6 @@ def build_change_list(changes, oldrev, newrev):
             if change.inDir(options.repodir):
                 changes.append(change)
 
-
-
 # Parse command line options
 (options, args) = opt_parser.parse_args()
 
@@ -264,9 +287,17 @@ changes = list()
 for line in sys.stdin:
     (oldrev, newrev, refname) = line.split()
     if refname == "refs/heads/master":
-        build_change_list(changes, oldrev, newrev)
+        try:
+            oldrev=file("refs/remotes/ftp/master").readline().strip();
+            git_command = "/usr/bin/git diff --name-status %s %s"%(oldrev, newrev)
+        except IOError:
+            # We are run for the first time, so (A)dd all files in the repo.
+            git_command = r"git ls-tree -r --name-only %s | sed -e 's/\(.*\)/A \1/'"%(newrev);
+
+        add_to_change_list(changes, git_command)
 
 if not changes:
+    perror("No changes to sync")
     sys.exit(0)
 
 # Apply changes
@@ -283,7 +314,9 @@ try:
     syncer.close()
 
 except ftplib.all_errors, detail:
-    print >> sys.stderr, "FTP error: ", detail
+    perror("FTP synchronization error: %s" % detail);
+    perror("I will try it next time again");
     sys.exit(1)
-    
-    
+
+# If succeessfull, update remote ref
+update_ref(newrev)