@@ -30,21 +30,21 @@ def __init__(
3030 Instantiate a local clone of a git repo.
3131
3232 If specifying a `clone_from`:
33- will clone an existing remote repository
33+ will clone an existing remote repository, for instance one
3434 that was previously created using ``HfApi().create_repo(token=huggingface_token, name=repo_name)``.
3535 ``Repository`` uses the local git credentials by default, but if required, the ``huggingface_token``
36- as well as the git ``user`` and the ``email`` can be specified.
37- ``Repository`` will then override them.
36+ as well as the git ``user`` and the ``email`` can be explicitly specified.
3837 If `clone_from` is used, and the repository is being instantiated into a non-empty directory,
3938 e.g. a directory with your trained model files, it will automatically merge them.
4039
4140 Args:
4241 local_dir (``str``):
43- path (e.g. ``'my_trained_model/'``) to the local directory, where the ``Repository`` will be either initalized.
42+ path (e.g. ``'my_trained_model/'``) to the local directory, where the ``Repository`` will be initalized.
4443 clone_from (``str``, optional):
4544 repository url (e.g. ``'https://huggingface.co/philschmid/playground-tests'``).
4645 use_auth_token (``str`` or ``bool``, `optional`, defaults ``None``):
47- huggingface_token can be extract from ``HfApi().login(username, password)`` and is used to authenticate against the hub.
46+ huggingface_token can be extract from ``HfApi().login(username, password)`` and is used to authenticate against the hub
47+ (useful from Google Colab for instance).
4848 git_user (``str``, `optional`, defaults ``None``):
4949 will override the ``git config user.name`` for committing and pushing files to the hub.
5050 git_email (``str``, `optional`, defaults ``None``):
@@ -59,15 +59,9 @@ def __init__(
5959 if clone_from is not None :
6060 self .clone_from (repo_url = clone_from , use_auth_token = use_auth_token )
6161 else :
62- try :
63- remotes = subprocess .check_output (
64- ["git" , "remote" , "-v" ],
65- encoding = "utf-8" ,
66- cwd = self .local_dir ,
67- )
68- logger .debug ("[Repository] has remotes" )
69- logger .debug (remotes )
70- except subprocess .CalledProcessError :
62+ if os .path .isdir (os .path .join (self .local_dir , ".git" )):
63+ logger .debug ("[Repository] is a valid git repo" )
64+ else :
7165 logger .error (
7266 "If not specifying `clone_from`, you need to pass Repository a valid git clone."
7367 )
@@ -84,19 +78,26 @@ def check_git_versions(self):
8478 print git and git-lfs versions, raises if they aren't installed.
8579 """
8680 try :
87- git_version = subprocess .check_output (
88- ["git" , "--version" ], encoding = "utf-8"
89- ).strip ()
81+ git_version = subprocess .run (
82+ ["git" , "--version" ],
83+ stderr = subprocess .PIPE ,
84+ stdout = subprocess .PIPE ,
85+ check = True ,
86+ encoding = "utf-8" ,
87+ ).stdout .strip ()
9088 except FileNotFoundError :
9189 raise EnvironmentError (
9290 "Looks like you do not have git installed, please install."
9391 )
9492
9593 try :
96- lfs_version = subprocess .check_output (
94+ lfs_version = subprocess .run (
9795 ["git-lfs" , "--version" ],
9896 encoding = "utf-8" ,
99- ).strip ()
97+ check = True ,
98+ stderr = subprocess .PIPE ,
99+ stdout = subprocess .PIPE ,
100+ ).stdout .strip ()
100101 except FileNotFoundError :
101102 raise EnvironmentError (
102103 "Looks like you do not have git-lfs installed, please install."
@@ -126,77 +127,143 @@ def clone_from(self, repo_url: str, use_auth_token: Union[bool, str, None] = Non
126127 repo_url = repo_url .replace (
127128 "https://" , f"https://user:{ huggingface_token } @"
128129 )
129-
130- subprocess .run ("git lfs install" .split (), check = True )
131-
132- # checks if repository is initialized in a empty repository or in one with files
133- if len (os .listdir (self .local_dir )) == 0 :
134- subprocess .run (
135- ["git" , "clone" , repo_url , "." ], check = True , cwd = self .local_dir
136- )
137- else :
138- logger .warning (
139- "[Repository] local_dir is not empty, so let's try to pull the remote over a non-empty folder."
140- )
141- subprocess .run ("git init" .split (), check = True , cwd = self .local_dir )
130+ try :
142131 subprocess .run (
143- ["git" , "remote" , "add" , "origin" , repo_url ],
132+ "git lfs install" .split (),
133+ stderr = subprocess .PIPE ,
134+ stdout = subprocess .PIPE ,
144135 check = True ,
145- cwd = self .local_dir ,
146- )
147- subprocess .run ("git fetch" .split (), check = True , cwd = self .local_dir )
148- subprocess .run (
149- "git reset origin/main" .split (), check = True , cwd = self .local_dir
150- )
151- # TODO(check if we really want the --force flag)
152- subprocess .run (
153- "git checkout origin/main -ft" .split (), check = True , cwd = self .local_dir
136+ encoding = "utf-8" ,
154137 )
155138
139+ # checks if repository is initialized in a empty repository or in one with files
140+ if len (os .listdir (self .local_dir )) == 0 :
141+ subprocess .run (
142+ ["git" , "clone" , repo_url , "." ],
143+ stderr = subprocess .PIPE ,
144+ stdout = subprocess .PIPE ,
145+ check = True ,
146+ encoding = "utf-8" ,
147+ cwd = self .local_dir ,
148+ )
149+ else :
150+ logger .warning (
151+ "[Repository] local_dir is not empty, so let's try to pull the remote over a non-empty folder."
152+ )
153+ subprocess .run (
154+ "git init" .split (),
155+ stderr = subprocess .PIPE ,
156+ stdout = subprocess .PIPE ,
157+ check = True ,
158+ encoding = "utf-8" ,
159+ cwd = self .local_dir ,
160+ )
161+ subprocess .run (
162+ ["git" , "remote" , "add" , "origin" , repo_url ],
163+ stderr = subprocess .PIPE ,
164+ stdout = subprocess .PIPE ,
165+ check = True ,
166+ encoding = "utf-8" ,
167+ cwd = self .local_dir ,
168+ )
169+ subprocess .run (
170+ "git fetch" .split (),
171+ stderr = subprocess .PIPE ,
172+ stdout = subprocess .PIPE ,
173+ check = True ,
174+ encoding = "utf-8" ,
175+ cwd = self .local_dir ,
176+ )
177+ subprocess .run (
178+ "git reset origin/main" .split (),
179+ stderr = subprocess .PIPE ,
180+ stdout = subprocess .PIPE ,
181+ encoding = "utf-8" ,
182+ check = True ,
183+ cwd = self .local_dir ,
184+ )
185+ # TODO(check if we really want the --force flag)
186+ subprocess .run (
187+ "git checkout origin/main -ft" .split (),
188+ stderr = subprocess .PIPE ,
189+ stdout = subprocess .PIPE ,
190+ encoding = "utf-8" ,
191+ check = True ,
192+ cwd = self .local_dir ,
193+ )
194+ except subprocess .CalledProcessError as exc :
195+ raise EnvironmentError (exc .stderr )
196+
156197 def git_config_username_and_email (
157198 self , git_user : Optional [str ] = None , git_email : Optional [str ] = None
158199 ):
159200 """
160201 sets git user name and email (only in the current repo)
161202 """
162- if git_user is not None :
163- subprocess .run (
164- f"git config user.name { git_user } " .split (),
165- check = True ,
166- cwd = self .local_dir ,
167- )
168- if git_email is not None :
169- subprocess .run (
170- f"git config user.email { git_email } " .split (),
171- check = True ,
172- cwd = self .local_dir ,
173- )
203+ try :
204+ if git_user is not None :
205+ subprocess .run (
206+ ["git" , "config" , "user.name" , git_user ],
207+ stderr = subprocess .PIPE ,
208+ stdout = subprocess .PIPE ,
209+ check = True ,
210+ encoding = "utf-8" ,
211+ cwd = self .local_dir ,
212+ )
213+ if git_email is not None :
214+ subprocess .run (
215+ ["git" , "config" , "user.email" , git_email ],
216+ stderr = subprocess .PIPE ,
217+ stdout = subprocess .PIPE ,
218+ check = True ,
219+ encoding = "utf-8" ,
220+ cwd = self .local_dir ,
221+ )
222+ except subprocess .CalledProcessError as exc :
223+ raise EnvironmentError (exc .stderr )
174224
175225 def lfs_track (self , patterns : Union [str , List [str ]]):
176226 """
177227 Tell git-lfs to track those files.
178228 """
179229 if isinstance (patterns , str ):
180230 patterns = [patterns ]
181- for pattern in patterns :
182- subprocess .run (
183- ["git" , "lfs" , "track" , pattern ], check = True , cwd = self .local_dir
184- )
231+ try :
232+ for pattern in patterns :
233+ subprocess .run (
234+ ["git" , "lfs" , "track" , pattern ],
235+ stderr = subprocess .PIPE ,
236+ stdout = subprocess .PIPE ,
237+ check = True ,
238+ encoding = "utf-8" ,
239+ cwd = self .local_dir ,
240+ )
241+ except subprocess .CalledProcessError as exc :
242+ raise EnvironmentError (exc .stderr )
185243
186244 def lfs_enable_largefiles (self ):
187245 """
188246 HF-specific. This enables upload support of files >5GB.
189247 """
190- subprocess .run (
191- "git config lfs.customtransfer.multipart.path huggingface-cli" .split (),
192- check = True ,
193- cwd = self .local_dir ,
194- )
195- subprocess .run (
196- f"git config lfs.customtransfer.multipart.args { LFS_MULTIPART_UPLOAD_COMMAND } " .split (),
197- check = True ,
198- cwd = self .local_dir ,
199- )
248+ try :
249+ subprocess .run (
250+ "git config lfs.customtransfer.multipart.path huggingface-cli" .split (),
251+ stderr = subprocess .PIPE ,
252+ stdout = subprocess .PIPE ,
253+ check = True ,
254+ encoding = "utf-8" ,
255+ cwd = self .local_dir ,
256+ )
257+ subprocess .run (
258+ f"git config lfs.customtransfer.multipart.args { LFS_MULTIPART_UPLOAD_COMMAND } " .split (),
259+ stderr = subprocess .PIPE ,
260+ stdout = subprocess .PIPE ,
261+ check = True ,
262+ encoding = "utf-8" ,
263+ cwd = self .local_dir ,
264+ )
265+ except subprocess .CalledProcessError as exc :
266+ raise EnvironmentError (exc .stderr )
200267
201268 def git_pull (self , rebase : Optional [bool ] = False ):
202269 """
@@ -205,27 +272,69 @@ def git_pull(self, rebase: Optional[bool] = False):
205272 args = "git pull" .split ()
206273 if rebase :
207274 args .append ("--rebase" )
208- subprocess .run (args , check = True , cwd = self .local_dir )
275+ try :
276+ subprocess .run (
277+ args ,
278+ stderr = subprocess .PIPE ,
279+ stdout = subprocess .PIPE ,
280+ check = True ,
281+ encoding = "utf-8" ,
282+ cwd = self .local_dir ,
283+ )
284+ except subprocess .CalledProcessError as exc :
285+ raise EnvironmentError (exc .stderr )
209286
210287 def git_add (self , pattern = "." ):
211288 """
212289 git add
213290 """
214- subprocess .run ("git add ." .split (), check = True , cwd = self .local_dir )
291+ try :
292+ subprocess .run (
293+ ["git" , "add" , pattern ],
294+ stderr = subprocess .PIPE ,
295+ stdout = subprocess .PIPE ,
296+ check = True ,
297+ encoding = "utf-8" ,
298+ cwd = self .local_dir ,
299+ )
300+ except subprocess .CalledProcessError as exc :
301+ raise EnvironmentError (exc .stderr )
215302
216303 def git_commit (self , commit_message = "commit files to HF hub" ):
217304 """
218305 git commit
219306 """
220- subprocess .run (
221- ["git" , "commit" , "-m" , commit_message ], check = True , cwd = self .local_dir
222- )
307+ try :
308+ subprocess .run (
309+ ["git" , "commit" , "-m" , commit_message ],
310+ stderr = subprocess .PIPE ,
311+ stdout = subprocess .PIPE ,
312+ check = True ,
313+ encoding = "utf-8" ,
314+ cwd = self .local_dir ,
315+ )
316+ except subprocess .CalledProcessError as exc :
317+ if len (exc .stderr ) > 0 :
318+ raise EnvironmentError (exc .stderr )
319+ else :
320+ raise EnvironmentError (exc .stdout )
223321
224322 def git_push (self ):
225323 """
226324 git push
227325 """
228- subprocess .run ("git push" .split (), check = True , cwd = self .local_dir )
326+ try :
327+ result = subprocess .run (
328+ "git push" .split (),
329+ stderr = subprocess .PIPE ,
330+ stdout = subprocess .PIPE ,
331+ check = True ,
332+ encoding = "utf-8" ,
333+ cwd = self .local_dir ,
334+ )
335+ logger .info (result .stdout )
336+ except subprocess .CalledProcessError as exc :
337+ raise EnvironmentError (exc .stderr )
229338
230339 def push_to_hub (self , commit_message = "commit files to HF hub" ):
231340 """
0 commit comments