]> rtime.felk.cvut.cz Git - git-ftp-sync.git/blobdiff - git-ftp-sync
Fixed typos in doccumentation, removed empty README
[git-ftp-sync.git] / git-ftp-sync
index 921c1c7e8163d1287580cd667275597119f3dc8b..d3d3e26625bfb2b50fad037dc29e0eb117250782 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Script for mirroring (a part of) git repository to a FTP site. Only
+# Script for mirroring (a part of) git repository to an FTP site. Only
 # changed files are copied to FTP. Works with bare repositories.
 #
 # Author: Michal Sojka <sojkam1@fel.cvut.cz>
@@ -13,7 +13,7 @@
 # or
 #     /usr/local/bin/git-ftp-sync -d /var/www/projectweb -r www
 
-# The first comamnd line mirrors the content og www directory in
+# The first comamnd line mirrors the content of www directory in
 # repository to FTP site at ftp.example.com as user "username" with
 # password "secret".
 
@@ -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, path
+            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, 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,6 +247,10 @@ def selftest():
     print
     print "Selftest succeeded!"
 
+def perror(str):    
+    print >>sys.stderr, "git-ftp-sync: %s"%str
+
+
 def update_ref(hash):
     remote = "ftp"
     branch = "master"
@@ -240,9 +258,9 @@ def update_ref(hash):
         os.makedirs("refs/remotes/"+remote)
     file("refs/remotes/"+remote+"/"+branch, "w").write(newrev+"\n")
 
-def build_change_list(changes, oldrev, newrev):
+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:
@@ -253,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()
 
@@ -273,11 +289,15 @@ for line in sys.stdin:
     if refname == "refs/heads/master":
         try:
             oldrev=file("refs/remotes/ftp/master").readline().strip();
+            git_command = "/usr/bin/git diff --name-status %s %s"%(oldrev, newrev)
         except IOError:
-            pass
-        build_change_list(changes, oldrev, newrev)
+            # 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
@@ -294,8 +314,8 @@ try:
     syncer.close()
 
 except ftplib.all_errors, detail:
-    print >> sys.stderr, "FTP synchronization error: ", detail
-    print >> sys.stderr, "I will try it next time again"
+    perror("FTP synchronization error: %s" % detail);
+    perror("I will try it next time again");
     sys.exit(1)
 
 # If succeessfull, update remote ref