Skip to content

Commit 192472f

Browse files
committed
BaseIndexEntry: Added to_blob method, refactored functionality sligthly
repo.clone: assured backslashes won't reach the remote configuration, as it can cause trouble when re-reading the file later on. Some git commands don't appear to be able to properly deal with backslashes, other's do
1 parent 8942284 commit 192472f

File tree

4 files changed

+50
-27
lines changed

4 files changed

+50
-27
lines changed

lib/git/index/base.py

+9-24
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,7 @@
1212
import glob
1313
from cStringIO import StringIO
1414

15-
from stat import (
16-
S_ISLNK,
17-
S_ISDIR,
18-
S_IFMT,
19-
S_IFDIR,
20-
S_IFLNK,
21-
S_IFREG
22-
)
15+
from stat import S_ISLNK
2316

2417
from typ import (
2518
BaseIndexEntry,
@@ -65,7 +58,9 @@
6558
write_cache,
6659
read_cache,
6760
aggressive_tree_merge,
68-
write_tree_from_cache
61+
write_tree_from_cache,
62+
stat_mode_to_index_mode,
63+
S_IFGITLINK
6964
)
7065

7166
from gitdb.base import IStream
@@ -99,7 +94,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
9994
before operating on it using the git command"""
10095
__slots__ = ("repo", "version", "entries", "_extension_data", "_file_path")
10196
_VERSION = 2 # latest version we support
102-
S_IFGITLINK = 0160000 # a submodule
97+
S_IFGITLINK = S_IFGITLINK # a submodule
10398

10499
def __init__(self, repo, file_path=None):
105100
"""Initialize this Index instance, optionally from the given ``file_path``.
@@ -350,16 +345,6 @@ def from_tree(cls, repo, *treeish, **kwargs):
350345

351346
return index
352347

353-
@classmethod
354-
def _stat_mode_to_index_mode(cls, mode):
355-
"""Convert the given mode from a stat call to the corresponding index mode
356-
and return it"""
357-
if S_ISLNK(mode): # symlinks
358-
return S_IFLNK
359-
if S_ISDIR(mode) or S_IFMT(mode) == cls.S_IFGITLINK: # submodules
360-
return cls.S_IFGITLINK
361-
return S_IFREG | 0644 | (mode & 0100) # blobs with or without executable bit
362-
363348
# UTILITIES
364349
def _iter_expand_paths(self, paths):
365350
"""Expand the directories in list of paths to the corresponding paths accordingly,
@@ -437,8 +422,8 @@ def iter_blobs(self, predicate = lambda t: True):
437422
for entry in self.entries.itervalues():
438423
# TODO: is it necessary to convert the mode ? We did that when adding
439424
# it to the index, right ?
440-
mode = self._stat_mode_to_index_mode(entry.mode)
441-
blob = Blob(self.repo, entry.binsha, mode, entry.path)
425+
mode = stat_mode_to_index_mode(entry.mode)
426+
blob = entry.to_blob(self.repo)
442427
blob.size = entry.size
443428
output = (entry.stage, blob)
444429
if predicate(output):
@@ -672,7 +657,7 @@ def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=Non
672657
abspath = os.path.abspath(path)
673658
gitrelative_path = abspath[len(self.repo.working_tree_dir)+1:]
674659
blob = Blob(self.repo, Blob.NULL_BIN_SHA,
675-
self._stat_mode_to_index_mode(os.stat(abspath).st_mode),
660+
stat_mode_to_index_mode(os.stat(abspath).st_mode),
676661
to_native_path_linux(gitrelative_path))
677662
entries.append(BaseIndexEntry.from_blob(blob))
678663
# END for each path
@@ -692,7 +677,7 @@ def store_path(filepath):
692677
fprogress(filepath, False, filepath)
693678
istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream))
694679
fprogress(filepath, True, filepath)
695-
return BaseIndexEntry((self._stat_mode_to_index_mode(st.st_mode),
680+
return BaseIndexEntry((stat_mode_to_index_mode(st.st_mode),
696681
istream.binsha, 0, to_native_path_linux(filepath)))
697682
# END utility method
698683

lib/git/index/fun.py

+25-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,18 @@
22
Contains standalone functions to accompany the index implementation and make it
33
more versatile
44
"""
5-
from stat import S_IFDIR
5+
from stat import (
6+
S_IFDIR,
7+
S_IFLNK,
8+
S_ISLNK,
9+
S_IFDIR,
10+
S_ISDIR,
11+
S_IFMT,
12+
S_IFREG,
13+
)
14+
15+
S_IFGITLINK = S_IFLNK | S_IFDIR # a submodule
16+
617
from cStringIO import StringIO
718

819
from git.util import IndexFileSHA1Writer
@@ -28,7 +39,19 @@
2839
from gitdb.base import IStream
2940
from gitdb.typ import str_tree_type
3041

31-
__all__ = ('write_cache', 'read_cache', 'write_tree_from_cache', 'entry_key' )
42+
__all__ = ('write_cache', 'read_cache', 'write_tree_from_cache', 'entry_key',
43+
'stat_mode_to_index_mode', 'S_IFGITLINK')
44+
45+
46+
def stat_mode_to_index_mode(mode):
47+
"""Convert the given mode from a stat call to the corresponding index mode
48+
and return it"""
49+
if S_ISLNK(mode): # symlinks
50+
return S_IFLNK
51+
if S_ISDIR(mode) or S_IFMT(mode) == S_IFGITLINK: # submodules
52+
return S_IFGITLINK
53+
return S_IFREG | 0644 | (mode & 0100) # blobs with or without executable bit
54+
3255

3356
def write_cache_entry(entry, stream):
3457
"""Write the given entry to the stream"""

lib/git/index/typ.py

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
b2a_hex,
1010
)
1111

12+
from git.objects import Blob
1213
__all__ = ('BlobFilter', 'BaseIndexEntry', 'IndexEntry')
1314

1415
#{ Invariants
@@ -101,6 +102,10 @@ def flags(self):
101102
def from_blob(cls, blob, stage = 0):
102103
""":return: Fully equipped BaseIndexEntry at the given stage"""
103104
return cls((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path))
105+
106+
def to_blob(self, repo):
107+
""":return: Blob using the information of this index entry"""
108+
return Blob(repo, self.binsha, self.mode, self.path)
104109

105110

106111
class IndexEntry(BaseIndexEntry):

lib/git/repo/base.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,17 @@ def _clone(cls, git, url, path, odb_default_type, **kwargs):
651651
# environment, hence we prepend its working dir if required
652652
if not os.path.isabs(path) and git.working_dir:
653653
path = join(git._working_dir, path)
654-
return cls(os.path.abspath(path), odbt = odbt)
654+
655+
# adjust remotes - there may be operating systems which use backslashes,
656+
# These might be given as initial paths, but when handling the config file
657+
# that contains the remote from which we were clones, git stops liking it
658+
# as it will escape the backslashes. Hence we undo the escaping just to be
659+
# sure
660+
repo = cls(os.path.abspath(path), odbt = odbt)
661+
if repo.remotes:
662+
repo.remotes[0].config_writer.set_value('url', repo.remotes[0].url.replace("\\\\", "\\").replace("\\", "/"))
663+
# END handle remote repo
664+
return repo
655665

656666
def clone(self, path, **kwargs):
657667
"""Create a clone from this repository.

0 commit comments

Comments
 (0)