for git v1.5.2 (and below): chdir to the directory of the target file before executin...
[translate_toolkit.git] / storage / versioncontrol / git_old.py
blob283e1227fdf2c9e7a4be3e0ad6420d3436ada274
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright 2004-2007 Zuza Software Foundation
5 #
6 # This file is part of translate.
8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 # Requires: git v1.5.2 or below
24 # For git v1.5.3 (or higher) use "git.py" instead
26 # this module for git support is supposed to be removed as soon as no major
27 # distribution contains git before v1.5.3 anymore
31 from translate.storage.versioncontrol import run_command
32 from translate.storage.versioncontrol import GenericRevisionControlSystem
33 import re
34 import os
37 def is_available():
38 """check if git v1.5.2 (or below) is installed"""
39 exitcode, output, error = run_command(["git", "--version"])
40 if exitcode != 0:
41 # no client available
42 return False
43 # check if the version number is below 1.5.3
44 # synchronize any changes below with "is_available" in "git.py"
45 if re.search(r'\s0\.', output) or \
46 re.search(r'\s1\.[0-4]$', output) or \
47 re.search(r'\s1\.[0-4]\.', output) or \
48 re.search(r'\s1\.5$', output) or \
49 re.search(r'\s1\.5\.[0-2]', output):
50 # git seems to be below v1.5.3
51 return True
52 # git seems to be at v1.5.3 or higher
53 return False
56 class git_old(GenericRevisionControlSystem):
57 """Class to manage items under revision control of git."""
59 RCS_METADIR = ".git"
60 SCAN_PARENTS = True
62 def _get_git_dir(self):
63 """git requires the git metadata directory for every operation
64 """
65 return os.path.join(self.root_dir, self.RCS_METADIR)
67 def _get_git_command(self, args):
68 """prepends generic git arguments to default ones
70 This function was only useful for "git.py", but we keep it here for
71 simplicity.
72 """
73 command = ["git"]
74 command.extend(args)
75 return command
77 def update(self, revision=None):
78 """Does a clean update of the given path"""
79 working_dir = os.path.dirname(self.location_abs)
80 original_dir = os.getcwd()
81 if working_dir:
82 try:
83 # first: check if we are allowed to _change_ to the current dir
84 # (of course, we are already here, but that does not mean so much)
85 os.chdir(original_dir)
86 except OSError, error:
87 raise IOError("[GIT] could not change to directory (%s): %s" \
88 % (original_dir, error))
89 try:
90 # change to the parent directory of the CVS managed file
91 os.chdir(working_dir)
92 except OSError, error:
93 raise IOError("[GIT] could not change to directory (%s): %s" \
94 % (working_dir, error))
95 # git checkout
96 command = self._get_git_command(["checkout", self.location_rel])
97 exitcode, output_checkout, error = run_command(command)
98 if exitcode != 0:
99 # something went wrong - go back to the original directory
100 try:
101 os.chdir(original_dir)
102 except OSError:
103 pass
104 raise IOError("[GIT] checkout failed (%s): %s" % (command, error))
105 # pull changes
106 command = self._get_git_command(["pull"])
107 exitcode, output_pull, error = run_command(command)
108 # always go back to the original directory
109 try:
110 os.chdir(original_dir)
111 except OSError:
112 pass
113 if exitcode != 0:
114 raise IOError("[GIT] pull failed (%s): %s" % (command, error))
115 return output_checkout + output_pull
117 def commit(self, message=None):
118 """Commits the file and supplies the given commit message if present"""
119 working_dir = os.path.dirname(self.location_abs)
120 original_dir = os.getcwd()
121 if working_dir:
122 try:
123 # first: check if we are allowed to _change_ to the current dir
124 # (of course, we are already here, but that does not mean so much)
125 os.chdir(original_dir)
126 except OSError, error:
127 raise IOError("[GIT] could not change to directory (%s): %s" \
128 % (original_dir, error))
129 try:
130 # change to the parent directory of the CVS managed file
131 os.chdir(working_dir)
132 except OSError, error:
133 raise IOError("[GIT] could not change to directory (%s): %s" \
134 % (working_dir, error))
135 # add the file
136 command = self._get_git_command(["add", self.location_rel])
137 exitcode, output_add, error = run_command(command)
138 if exitcode != 0:
139 # something went wrong - go back to the original directory
140 try:
141 os.chdir(original_dir)
142 except OSError:
143 pass
144 raise IOError("[GIT] add of ('%s', '%s') failed: %s" \
145 % (self.root_dir, self.location_rel, error))
146 # commit file
147 command = self._get_git_command(["commit"])
148 if message:
149 command.extend(["-m", message])
150 exitcode, output_commit, error = run_command(command)
151 if exitcode != 0:
152 # something went wrong - go back to the original directory
153 try:
154 os.chdir(original_dir)
155 except OSError:
156 pass
157 if len(error):
158 msg = error
159 else:
160 msg = output_commit
161 raise IOError("[GIT] commit of ('%s', '%s') failed: %s" \
162 % (self.root_dir, self.location_rel, msg))
163 # push changes
164 command = self._get_git_command(["push"])
165 exitcode, output_push, error = run_command(command)
166 # always go back to the original directory
167 try:
168 os.chdir(original_dir)
169 except OSError:
170 pass
171 if exitcode != 0:
172 raise IOError("[GIT] push of ('%s', '%s') failed: %s" \
173 % (self.root_dir, self.location_rel, error))
174 return output_add + output_commit + output_push
176 def getcleanfile(self, revision=None):
177 """Get a clean version of a file from the git repository"""
178 working_dir = os.path.dirname(self.location_abs)
179 original_dir = os.getcwd()
180 if working_dir:
181 try:
182 # first: check if we are allowed to _change_ to the current dir
183 # (of course, we are already here, but that does not mean so much)
184 os.chdir(original_dir)
185 except OSError, error:
186 raise IOError("[GIT] could not change to directory (%s): %s" \
187 % (original_dir, error))
188 try:
189 # change to the parent directory of the CVS managed file
190 os.chdir(working_dir)
191 except OSError, error:
192 raise IOError("[GIT] could not change to directory (%s): %s" \
193 % (working_dir, error))
194 # run git-show
195 command = self._get_git_command(["cat-file", "blob",
196 "HEAD:%s" % self.location_rel])
197 exitcode, output, error = run_command(command)
198 # always go back to the original directory
199 try:
200 os.chdir(original_dir)
201 except OSError:
202 pass
203 if exitcode != 0:
204 raise IOError("[GIT] 'cat-file' failed for ('%s', %s): %s" \
205 % (self.root_dir, self.location_rel, error))
206 return output