Skip to content

[Windows] Unable to add files to index if corresponding object file is read-only #353

Closed
@achermes

Description

@achermes

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'

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions