Description
Seen on
OS
: Windows 7
git.__version__
: 1.0.1
python --version
: Python 3.4.3
Description
If an object file becomes read-only, trying to add the corresponding working directory file to an index causes a File Access Error:
Running the program below following with the object file for 'test.txt' set to read-only triggers the error (see Traceback at bottom).
This appears to be because the store() function of the underlying loose DB tries to remove the file before renaming a temp file onto it. However, on windows, read-only files cannot be removed with os.remove - one must remove the read only attribute first.
Although this might seem like a farfetched scenario, in reality I've hit this in several real usage scenarios (though I have not been able to characterize exactly why an object file becomes read-only). So, I think this is generally valid (and indeed this would work fine on *nix due to the fact that read-only files can still be deleted with os.remove)
I do not know enough about the way GIT stores objects to say what the best solution would be here, but one option would be to check for this case and explicilty remove the read-only attribute before attempting to remove.
Program
import git
repo_path = r"C:\Users\ach\Documents\code\odds_ends\gptest"
broken_path = r"C:\Users\ach\Documents\code\odds_ends\gptest\test.txt"
repo = git.Repo(repo_path)
idx = repo.index
idx.add(items=[broken_path])
Traceback
Traceback (most recent call last):
File "C:/Users/ach/Documents/code/odds_ends/gitpy_broken.py", line 7, in <module>
idx.add(items=[broken_path])
File "C:\Python34\lib\site-packages\git\index\base.py", line 726, in add
entries_added.extend(self._entries_for_paths(paths, path_rewriter, fprogress, entries))
File "C:\Python34\lib\site-packages\git\util.py", line 54, in wrapper
return func(self, *args, **kwargs)
File "C:\Python34\lib\site-packages\git\index\util.py", line 84, in set_git_working_dir
return func(self, *args, **kwargs)
File "C:\Python34\lib\site-packages\git\index\base.py", line 612, in _entries_for_paths
entries_added.append(self._store_path(filepath, fprogress))
File "C:\Python34\lib\site-packages\git\index\base.py", line 580, in _store_path
istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream))
File "C:\Python34\lib\site-packages\gitdb\db\git.py", line 73, in store
return self._loose_db.store(istream)
File "C:\Python34\lib\site-packages\gitdb\db\loose.py", line 230, in store
remove(obj_path)
PermissionError: [WinError 5] Access is denied: 'C:\\Users\\ach\\Documents\\code\\odds_ends\\gptest\\.git\\objects\\e6\\9de29bb2d1d6434b8b29ae775ad8c2e48c5391'