3 # Author: Paul D. Eden <paul@benchline.org>
4 # Distributed under the terms of the GNU Public License version 2
12 subprocess
.check_call(cmd
, shell
=True)
15 if subprocess
.call(cmd
, shell
=True) == 0:
21 process
= subprocess
.Popen(cmd
, shell
=True, stdout
=subprocess
.PIPE
)
22 rval
= process
.communicate()[0]
23 if process
.returncode
!= 0:
24 raise Exception, "%s failed" % cmd
27 class NotRepoException(Exception): pass
31 Simple script to automate syncing a local git repository
34 The remote local git directory must have the same
35 name as the remote S3 directory
38 home
= os
.environ
["HOME"]
39 self
.git_repo_dir
= self
._get
_repo
()
40 self
.shadow_repo_dir
= self
._setup
_shadow
_repo
()
42 def _get_repo(self
, directory
=""):
44 Recursively tries to find the git repo we are in
48 directory
= os
.path
.realpath(os
.getcwd())
50 raise NotRepoException
, "This directory is not a git repository"
52 if self
._is
_git
_repo
(directory
):
55 return self
._get
_repo
(os
.path
.dirname(directory
))
57 def _setup_shadow_repo(self
):
59 Makes the repo a clone of shadow_dir
62 short_name
= os
.path
.basename(self
.git_repo_dir
)
63 parent_dir
= os
.path
.dirname(self
.git_repo_dir
)
64 shadow_dir
= os
.path
.join(parent_dir
, ".%s.s3" % short_name
)
65 if not os
.path
.exists(shadow_dir
):
66 self
._setup
_clone
(shadow_dir
)
69 def _setup_clone(self
, shadow_dir
):
70 # make sure this code is right. It can be destructive
73 run("cp -a %s %s" % (self
.git_repo_dir
, shadow_dir
))
74 run("rm -fr %s" % self
.git_repo_dir
)
75 run("git clone file://%s %s" % (shadow_dir
, self
.git_repo_dir
))
76 os
.chdir(self
.git_repo_dir
)
78 def _backup_repo(self
):
79 backup_dir
= self
.git_repo_dir
+ ".bak"
80 if os
.path
.exists(backup_dir
):
81 run("rm -fr %s" % backup_dir
)
82 run("cp -a %s %s" % (self
.git_repo_dir
, backup_dir
))
84 def _is_git_repo(self
, directory
):
85 return os
.path
.exists("%s/.git" % directory
)
87 def _commit_repo(self
):
89 ans
= raw_input("Commit the changes to git? ")
90 if ans
.lower() == "y":
91 print "Here's a shell with which to commit."
94 def _s3_to_shadow(self
):
95 run("s3cmd --force --delete-removed sync s3://git_repos/%s %s" % (os
.path
.basename(self
.git_repo_dir
), self
.shadow_repo_dir
))
97 def _shadow_to_s3(self
):
98 run("s3cmd --delete-removed sync %s s3://git_repos/%s" % (self
.shadow_repo_dir
,
99 os
.path
.basename(self
.git_repo_dir
)))
111 def main(self
, args
):
118 raise Exception, "%s is an invalid command" % cmd
120 if __name__
== "__main__":
121 from optparse
import OptionParser
122 parser
= OptionParser()
123 parser
.add_option("-v", "--verbose", action
="store_true",
124 help="run gregariously")
125 parser
.add_option("-q", "--quiet", action
="store_true",
127 (options
, args
) = parser
.parse_args()
128 if len(args
) < 1 or (args
[0] not in ("push", "pull")):
129 parser
.error("You must specify one of 'push' or 'pull'")