Skip to content

Commit ca4c1b8

Browse files
committed
Merge branch 'master' of https://github.com/moshevds/GitPython into moshevds-master
Fixed an issue with path_rewriter code branch, but there is more to do Conflicts: git/index/base.py git/test/test_index.py
2 parents cebda2d + 4d4138c commit ca4c1b8

File tree

2 files changed

+90
-49
lines changed

2 files changed

+90
-49
lines changed

‎git/index/base.py

+56-49
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070

7171

7272
class IndexFile(LazyMixin, diff.Diffable, Serializable):
73-
7473
"""
7574
Implements an Index that can be manipulated using a native implementation in
7675
order to save git command function calls wherever possible.
@@ -561,8 +560,48 @@ def _preprocess_add_items(self, items):
561560
return (paths, entries)
562561

563562
@git_working_dir
564-
def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=None,
565-
write=True):
563+
def _store_path(self, filepath, fprogress):
564+
"""Store file at filepath in the database and return the base index entry"""
565+
st = os.lstat(filepath) # handles non-symlinks as well
566+
stream = None
567+
if S_ISLNK(st.st_mode):
568+
stream = StringIO(os.readlink(filepath))
569+
else:
570+
stream = open(filepath, 'rb')
571+
# END handle stream
572+
fprogress(filepath, False, filepath)
573+
istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream))
574+
fprogress(filepath, True, filepath)
575+
return BaseIndexEntry((stat_mode_to_index_mode(st.st_mode),
576+
istream.binsha, 0, to_native_path_linux(filepath)))
577+
578+
@git_working_dir
579+
def _entries_for_paths(self, paths, path_rewriter, fprogress, entries):
580+
entries_added = list()
581+
if path_rewriter:
582+
for path in paths:
583+
abspath = os.path.abspath(path)
584+
gitrelative_path = abspath[len(self.repo.working_tree_dir)+1:]
585+
blob = Blob(self.repo, Blob.NULL_BIN_SHA,
586+
stat_mode_to_index_mode(os.stat(abspath).st_mode),
587+
to_native_path_linux(gitrelative_path))
588+
# TODO: variable undefined
589+
entries.append(BaseIndexEntry.from_blob(blob))
590+
# END for each path
591+
del(paths[:])
592+
# END rewrite paths
593+
594+
# HANDLE PATHS
595+
assert len(entries_added) == 0
596+
for filepath in self._iter_expand_paths(paths):
597+
entries_added.append(self._store_path(filepath, fprogress))
598+
# END for each filepath
599+
# END path handling
600+
return entries_added
601+
602+
603+
def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=None,
604+
write=True):
566605
"""Add files from the working tree, specific blobs or BaseIndexEntries
567606
to the index.
568607
@@ -637,7 +676,7 @@ def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=Non
637676
:param write:
638677
If True, the index will be written once it was altered. Otherwise
639678
the changes only exist in memory and are not available to git commands.
640-
679+
641680
:return:
642681
List(BaseIndexEntries) representing the entries just actually added.
643682
@@ -649,61 +688,29 @@ def add(self, items, force=True, fprogress=lambda *args: None, path_rewriter=Non
649688
# sort the entries into strings and Entries, Blobs are converted to entries
650689
# automatically
651690
# paths can be git-added, for everything else we use git-update-index
652-
entries_added = list()
653691
paths, entries = self._preprocess_add_items(items)
654-
if paths and path_rewriter:
655-
for path in paths:
656-
abspath = os.path.abspath(path)
657-
gitrelative_path = abspath[len(self.repo.working_tree_dir) + 1:]
658-
blob = Blob(self.repo, Blob.NULL_BIN_SHA,
659-
stat_mode_to_index_mode(os.stat(abspath).st_mode),
660-
to_native_path_linux(gitrelative_path))
661-
entries.append(BaseIndexEntry.from_blob(blob))
662-
# END for each path
663-
del(paths[:])
664-
# END rewrite paths
665-
666-
def store_path(filepath):
667-
"""Store file at filepath in the database and return the base index entry"""
668-
st = os.lstat(filepath) # handles non-symlinks as well
669-
stream = None
670-
if S_ISLNK(st.st_mode):
671-
stream = StringIO(os.readlink(filepath))
672-
else:
673-
stream = open(filepath, 'rb')
674-
# END handle stream
675-
fprogress(filepath, False, filepath)
676-
istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream))
677-
fprogress(filepath, True, filepath)
678-
return BaseIndexEntry((stat_mode_to_index_mode(st.st_mode),
679-
istream.binsha, 0, to_native_path_linux(filepath)))
680-
# END utility method
681-
682-
# HANDLE PATHS
692+
entries_added = list()
693+
# This code needs a working tree, therefore we try not to run it unless required.
694+
# That way, we are OK on a bare repository as well.
695+
# If there are no paths, the rewriter has nothing to do either
683696
if paths:
684-
assert len(entries_added) == 0
685-
added_files = list()
686-
for filepath in self._iter_expand_paths(paths):
687-
entries_added.append(store_path(filepath))
688-
# END for each filepath
689-
# END path handling
697+
entries_added.extend(self._entries_for_paths(paths, path_rewriter, fprogress, entries))
690698

691699
# HANDLE ENTRIES
692700
if entries:
693-
null_mode_entries = [e for e in entries if e.mode == 0]
701+
null_mode_entries = [ e for e in entries if e.mode == 0 ]
694702
if null_mode_entries:
695-
raise ValueError(
696-
"At least one Entry has a null-mode - please use index.remove to remove files for clarity")
703+
raise ValueError("At least one Entry has a null-mode - please use index.remove to remove files for clarity")
697704
# END null mode should be remove
698705

699706
# HANLDE ENTRY OBJECT CREATION
700707
# create objects if required, otherwise go with the existing shas
701-
null_entries_indices = [i for i, e in enumerate(entries) if e.binsha == Object.NULL_BIN_SHA]
708+
null_entries_indices = [ i for i,e in enumerate(entries) if e.binsha == Object.NULL_BIN_SHA ]
702709
if null_entries_indices:
703710
for ei in null_entries_indices:
704711
null_entry = entries[ei]
705-
new_entry = store_path(null_entry.path)
706-
712+
new_entry = self._store_path(null_entry.path, fprogress)
713+
707714
# update null entry
708715
entries[ei] = BaseIndexEntry((null_entry.mode, new_entry.binsha, null_entry.stage, null_entry.path))
709716
# END for each entry index
@@ -713,7 +720,7 @@ def store_path(filepath):
713720
# If we have to rewrite the entries, do so now, after we have generated
714721
# all object sha's
715722
if path_rewriter:
716-
for i, e in enumerate(entries):
723+
for i,e in enumerate(entries):
717724
entries[i] = BaseIndexEntry((e.mode, e.binsha, e.stage, path_rewriter(e)))
718725
# END for each entry
719726
# END handle path rewriting
@@ -733,11 +740,11 @@ def store_path(filepath):
733740
# add the new entries to this instance
734741
for entry in entries_added:
735742
self.entries[(entry.path, 0)] = IndexEntry.from_base(entry)
736-
743+
737744
if write:
738745
self.write()
739746
# END handle write
740-
747+
741748
return entries_added
742749

743750
def _items_to_rela_paths(self, items):

‎git/test/test_index.py

+34
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
import time
2121
from stat import *
2222

23+
from StringIO import StringIO
24+
from gitdb.base import IStream
25+
from git.objects import Blob
26+
from git.index.typ import BaseIndexEntry
27+
2328

2429
class TestIndex(TestBase):
2530

@@ -671,3 +676,32 @@ def test_index_new(self):
671676
index = IndexFile.new(self.rorepo, *args)
672677
assert isinstance(index, IndexFile)
673678
# END for each arg tuple
679+
680+
@with_rw_repo('HEAD', bare=True)
681+
def test_index_bare_add(self, rw_bare_repo):
682+
# Something is wrong after cloning to a bare repo, reading the
683+
# property rw_bare_repo.working_tree_dir will return '/tmp'
684+
# instead of throwing the Exception we are expecting. This is
685+
# a quick hack to make this test fail when expected.
686+
rw_bare_repo._working_tree_dir = None
687+
contents = 'This is a StringIO file'
688+
filesize = len(contents)
689+
fileobj = StringIO(contents)
690+
filename = 'my-imaginary-file'
691+
istream = rw_bare_repo.odb.store(
692+
IStream(Blob.type, filesize, fileobj))
693+
entry = BaseIndexEntry((100644, istream.binsha, 0, filename))
694+
try:
695+
rw_bare_repo.index.add([entry])
696+
except AssertionError, e:
697+
self.fail("Adding to the index of a bare repo is not allowed.")
698+
699+
# Adding using a path should still require a non-bare repository.
700+
asserted = False
701+
path = os.path.join('git', 'test', 'test_index.py')
702+
try:
703+
rw_bare_repo.index.add([path])
704+
except Exception, e:
705+
asserted = "does not have a working tree" in e.message
706+
assert asserted, "Adding using a filename is not correctly asserted."
707+

0 commit comments

Comments
 (0)