summaryrefslogtreecommitdiff
path: root/git/index
diff options
context:
space:
mode:
Diffstat (limited to 'git/index')
-rw-r--r--git/index/__init__.py2
-rw-r--r--git/index/base.py63
-rw-r--r--git/index/fun.py44
-rw-r--r--git/index/typ.py14
-rw-r--r--git/index/util.py2
5 files changed, 61 insertions, 64 deletions
diff --git a/git/index/__init__.py b/git/index/__init__.py
index fe4a7f59..4a495c33 100644
--- a/git/index/__init__.py
+++ b/git/index/__init__.py
@@ -1,4 +1,4 @@
"""Initialize the index package"""
from base import *
-from typ import * \ No newline at end of file
+from typ import *
diff --git a/git/index/base.py b/git/index/base.py
index 3bd8634c..9a3e80ea 100644
--- a/git/index/base.py
+++ b/git/index/base.py
@@ -74,21 +74,21 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
"""
Implements an Index that can be manipulated using a native implementation in
order to save git command function calls wherever possible.
-
+
It provides custom merging facilities allowing to merge without actually changing
your index or your working tree. This way you can perform own test-merges based
on the index only without having to deal with the working copy. This is useful
in case of partial working trees.
``Entries``
-
+
The index contains an entries dict whose keys are tuples of type IndexEntry
to facilitate access.
You may read the entries dict or manipulate it using IndexEntry instance, i.e.::
-
+
index.entries[index.entry_key(index_entry_instance)] = index_entry_instance
-
+
Make sure you use index.write() once you are done manipulating the index directly
before operating on it using the git command"""
__slots__ = ("repo", "version", "entries", "_extension_data", "_file_path")
@@ -127,7 +127,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# Its insanely bad ... I am disappointed !
allow_mmap = (os.name != 'nt' or sys.version_info[1] > 5)
stream = file_contents_ro(fd, stream=True, allow_mmap=allow_mmap)
-
+
try:
self._deserialize(stream)
finally:
@@ -160,21 +160,21 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
"""Initialize this instance with index values read from the given stream"""
self.version, self.entries, self._extension_data, conten_sha = read_cache(stream)
return self
-
+
def _entries_sorted(self):
""":return: list of entries, in a sorted fashion, first by path, then by stage"""
entries_sorted = self.entries.values()
entries_sorted.sort(key=lambda e: (e.path, e.stage)) # use path/stage as sort key
return entries_sorted
-
+
def _serialize(self, stream, ignore_tree_extension_data=False):
entries = self._entries_sorted()
write_cache(entries,
stream,
(ignore_tree_extension_data and None) or self._extension_data)
return self
-
-
+
+
#} END serializable interface
def write(self, file_path = None, ignore_tree_extension_data=False):
@@ -203,9 +203,9 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
self.entries
lfd = LockedFD(file_path or self._file_path)
stream = lfd.open(write=True, stream=True)
-
+
self._serialize(stream, ignore_tree_extension_data)
-
+
lfd.commit()
# make sure we represent what we have written
@@ -264,12 +264,12 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
If you intend to write such a merged Index, supply an alternate file_path
to its 'write' method."""
base_entries = aggressive_tree_merge(repo.odb, [to_bin_sha(str(t)) for t in tree_sha])
-
+
inst = cls(repo)
# convert to entries dict
entries = dict(izip(((e.path, e.stage) for e in base_entries),
(IndexEntry.from_base(e) for e in base_entries)))
-
+
inst.entries = entries
return inst
@@ -314,7 +314,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
arg_list = list()
# ignore that working tree and index possibly are out of date
- if len(treeish)>1:
+ if len(treeish) > 1:
# drop unmerged entries when reading our index and merging
arg_list.append("--reset")
# handle non-trivial cases the way a real merge does
@@ -503,7 +503,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
def write_tree(self):
"""Writes this index to a corresponding Tree object into the repository's
object database and return it.
-
+
:return: Tree object representing this index
:note: The tree will be written even if one or more objects the tree refers to
does not yet exist in the object database. This could happen if you added
@@ -515,17 +515,17 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
mdb = MemoryDB()
entries = self._entries_sorted()
binsha, tree_items = write_tree_from_cache(entries, mdb, slice(0, len(entries)))
-
+
# copy changed trees only
mdb.stream_copy(mdb.sha_iter(), self.repo.odb)
-
-
+
+
# note: additional deserialization could be saved if write_tree_from_cache
# would return sorted tree entries
root_tree = Tree(self.repo, binsha, path='')
root_tree._cache = tree_items
return root_tree
-
+
def _process_diff_args(self, args):
try:
args.pop(args.index(self))
@@ -638,7 +638,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
:param write:
If True, the index will be written once it was altered. Otherwise
the changes only exist in memory and are not available to git commands.
-
+
:return:
List(BaseIndexEntries) representing the entries just actually added.
@@ -706,7 +706,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
for ei in null_entries_indices:
null_entry = entries[ei]
new_entry = store_path(null_entry.path)
-
+
# update null entry
entries[ei] = BaseIndexEntry((null_entry.mode, new_entry.binsha, null_entry.stage, null_entry.path))
# END for each entry index
@@ -736,11 +736,11 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# add the new entries to this instance
for entry in entries_added:
self.entries[(entry.path, 0)] = IndexEntry.from_base(entry)
-
+
if write:
self.write()
# END handle write
-
+
return entries_added
def _items_to_rela_paths(self, items):
@@ -901,7 +901,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
def checkout(self, paths=None, force=False, fprogress=lambda *args: None, **kwargs):
"""Checkout the given paths or all files from the version known to the index into
the working tree.
-
+
:note: Be sure you have written pending changes using the ``write`` method
in case you have altered the enties dictionary directly
@@ -934,7 +934,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
( as opposed to the original git command who ignores them ).
Raise GitCommandError if error lines could not be parsed - this truly is
an exceptional state
-
+
.. note:: The checkout is limited to checking out the files in the
index. Files which are not in the index anymore and exist in
the working tree will not be deleted. This behaviour is fundamentally
@@ -1008,7 +1008,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# which will hold a lock on it. We try to get the lock as well during
# our entries initialization
self.entries
-
+
args.append("--stdin")
kwargs['as_process'] = True
kwargs['istream'] = subprocess.PIPE
@@ -1066,11 +1066,11 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
If False, the working tree will not be touched
Please note that changes to the working copy will be discarded without
warning !
-
+
:param head:
If True, the head will be set to the given commit. This is False by default,
but if True, this method behaves like HEAD.reset.
-
+
:param paths: if given as an iterable of absolute or repository-relative paths,
only these will be reset to their state at the given commit'ish.
The paths need to exist at the commit, otherwise an exception will be
@@ -1078,7 +1078,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
:param kwargs:
Additional keyword arguments passed to git-reset
-
+
.. note:: IndexFile.reset, as opposed to HEAD.reset, will not delete anyfiles
in order to maintain a consistent working tree. Instead, it will just
checkout the files according to their state in the index.
@@ -1108,11 +1108,11 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# END for each path
# END handle paths
self.write()
-
+
if working_tree:
self.checkout(paths=paths, force=True)
# END handle working tree
-
+
if head:
self.repo.head.set_commit(self.repo.commit(commit), logmsg="%s: Updating HEAD" % commit)
# END handle head change
@@ -1154,4 +1154,3 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# diff against working copy - can be handled by superclass natively
return super(IndexFile, self).diff(other, paths, create_patch, **kwargs)
-
diff --git a/git/index/fun.py b/git/index/fun.py
index e39b09d6..ede7e43f 100644
--- a/git/index/fun.py
+++ b/git/index/fun.py
@@ -31,7 +31,7 @@ from typ import (
)
CE_NAMEMASK_INV = ~CE_NAMEMASK
-from util import (
+from util import (
pack,
unpack
)
@@ -55,19 +55,19 @@ def stat_mode_to_index_mode(mode):
def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1Writer):
"""Write the cache represented by entries to a stream
-
+
:param entries: **sorted** list of entries
:param stream: stream to wrap into the AdapterStreamCls - it is used for
final output.
-
+
:param ShaStreamCls: Type to use when writing to the stream. It produces a sha
while writing to it, before the data is passed on to the wrapped stream
-
+
:param extension_data: any kind of data to write as a trailer, it must begin
a 4 byte identifier, followed by its size ( 4 bytes )"""
# wrap the stream into a compatible writer
stream = ShaStreamCls(stream)
-
+
tell = stream.tell
write = stream.write
@@ -98,14 +98,14 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1
# write the sha over the content
stream.write_sha()
-
+
def read_header(stream):
"""Return tuple(version_long, num_entries) from the given stream"""
type_id = stream.read(4)
if type_id != "DIRC":
raise AssertionError("Invalid index file header: %r" % type_id)
version, num_entries = unpack(">LL", stream.read(4 * 2))
-
+
# TODO: handle version 3: extended data, see read-cache.c
assert version in (1, 2)
return version, num_entries
@@ -130,7 +130,7 @@ def read_cache(stream):
version, num_entries = read_header(stream)
count = 0
entries = dict()
-
+
read = stream.read
tell = stream.tell
while count < num_entries:
@@ -141,7 +141,7 @@ def read_cache(stream):
unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
path_size = flags & CE_NAMEMASK
path = read(path_size)
-
+
real_size = ((tell() - beginoffset + 8) & ~7)
data = read((beginoffset + real_size) - tell())
entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
@@ -163,13 +163,13 @@ def read_cache(stream):
# truncate the sha in the end as we will dynamically create it anyway
extension_data = extension_data[:-20]
-
+
return (version, entries, extension_data, content_sha)
-
+
def write_tree_from_cache(entries, odb, sl, si=0):
"""Create a tree from the given sorted list of entries and put the respective
trees into the given object database
-
+
:param entries: **sorted** list of IndexEntries
:param odb: object database to store the trees in
:param si: start index at which we should start creating subtrees
@@ -202,28 +202,28 @@ def write_tree_from_cache(entries, odb, sl, si=0):
# END abort on base mismatch
xi += 1
# END find common base
-
+
# enter recursion
# ci - 1 as we want to count our current item as well
sha, tree_entry_list = write_tree_from_cache(entries, odb, slice(ci-1, xi), rbound+1)
tree_items_append((sha, S_IFDIR, base))
-
+
# skip ahead
ci = xi
# END handle bounds
# END for each entry
-
+
# finally create the tree
sio = StringIO()
tree_to_stream(tree_items, sio.write)
sio.seek(0)
-
+
istream = odb.store(IStream(str_tree_type, len(sio.getvalue()), sio))
return (istream.binsha, tree_items)
-
+
def _tree_entry_to_baseindexentry(tree_entry, stage):
- return BaseIndexEntry((tree_entry[1], tree_entry[0], stage <<CE_STAGESHIFT, tree_entry[2]))
-
+ return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))
+
def aggressive_tree_merge(odb, tree_shas):
"""
:return: list of BaseIndexEntries representing the aggressive merge of the given
@@ -235,7 +235,7 @@ def aggressive_tree_merge(odb, tree_shas):
If 3 are given, a 3 way merge is performed"""
out = list()
out_append = out.append
-
+
# one and two way is the same for us, as we don't have to handle an existing
# index, instrea
if len(tree_shas) in (1,2):
@@ -244,7 +244,7 @@ def aggressive_tree_merge(odb, tree_shas):
# END for each entry
return out
# END handle single tree
-
+
if len(tree_shas) > 3:
raise ValueError("Cannot handle %i trees at once" % len(tree_shas))
@@ -273,7 +273,7 @@ def aggressive_tree_merge(odb, tree_shas):
out_append(_tree_entry_to_baseindexentry(theirs, 0))
# END handle modification
else:
-
+
if ours[0] != base[0] or ours[1] != base[1]:
# they deleted it, we changed it, conflict
out_append(_tree_entry_to_baseindexentry(base, 1))
diff --git a/git/index/typ.py b/git/index/typ.py
index 7f27d869..97dff59e 100644
--- a/git/index/typ.py
+++ b/git/index/typ.py
@@ -56,7 +56,7 @@ class BaseIndexEntry(tuple):
def __str__(self):
return "%o %s %i\t%s" % (self.mode, self.hexsha, self.stage, self.path)
-
+
def __repr__(self):
return "(%o, %s, %i, %s)" % (self.mode, self.hexsha, self.stage, self.path)
@@ -69,7 +69,7 @@ class BaseIndexEntry(tuple):
def binsha(self):
"""binary sha of the blob """
return self[1]
-
+
@property
def hexsha(self):
"""hex version of our sha"""
@@ -78,12 +78,12 @@ class BaseIndexEntry(tuple):
@property
def stage(self):
"""Stage of the entry, either:
-
+
* 0 = default stage
* 1 = stage before a merge or common ancestor entry in case of a 3 way merge
* 2 = stage of entries from the 'left' side of the merge
* 3 = stage of entries from the right side of the merge
-
+
:note: For more information, see http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html
"""
return (self[2] & CE_STAGEMASK) >> CE_STAGESHIFT
@@ -102,7 +102,7 @@ class BaseIndexEntry(tuple):
def from_blob(cls, blob, stage = 0):
""":return: Fully equipped BaseIndexEntry at the given stage"""
return cls((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path))
-
+
def to_blob(self, repo):
""":return: Blob using the information of this index entry"""
return Blob(repo, self.binsha, self.mode, self.path)
@@ -152,7 +152,7 @@ class IndexEntry(BaseIndexEntry):
def size(self):
""":return: Uncompressed size of the blob """
return self[10]
-
+
@classmethod
def from_base(cls, base):
"""
@@ -169,5 +169,3 @@ class IndexEntry(BaseIndexEntry):
""":return: Minimal entry resembling the given blob object"""
time = pack(">LL", 0, 0)
return IndexEntry((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path, time, time, 0, 0, 0, 0, blob.size))
-
-
diff --git a/git/index/util.py b/git/index/util.py
index 59f8d591..7211b4fc 100644
--- a/git/index/util.py
+++ b/git/index/util.py
@@ -79,7 +79,7 @@ def git_working_dir(func):
os.chdir(cur_wd)
# END handle working dir
# END wrapper
-
+
set_git_working_dir.__name__ = func.__name__
return set_git_working_dir