summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--refs/head.py17
-rw-r--r--refs/log.py14
-rw-r--r--refs/symbolic.py25
-rw-r--r--test/test_index.py1
-rw-r--r--test/test_refs.py61
5 files changed, 47 insertions, 71 deletions
diff --git a/refs/head.py b/refs/head.py
index 278cecc7..08ad581d 100644
--- a/refs/head.py
+++ b/refs/head.py
@@ -29,23 +29,6 @@ class HEAD(SymbolicReference):
to contain the previous value of HEAD"""
return SymbolicReference(self.repo, self._ORIG_HEAD_NAME)
- def _set_reference(self, ref):
- """If someone changes the reference through us, we must manually update
- the ORIG_HEAD if we are detached. The underlying implementation can only
- handle un-detached heads as it has to check whether the current head
- is the checked-out one"""
- if self.is_detached:
- prev_commit = self.commit
- super(HEAD, self)._set_reference(ref)
- SymbolicReference.create(self.repo, self._ORIG_HEAD_NAME, prev_commit, force=True)
- else:
- super(HEAD, self)._set_reference(ref)
- # END handle detached mode
-
- # aliased reference
- reference = property(SymbolicReference._get_reference, _set_reference, doc="Returns the Reference we point to")
- ref = reference
-
def reset(self, commit='HEAD', index=True, working_tree = False,
paths=None, **kwargs):
"""Reset our HEAD to the given commit optionally synchronizing
diff --git a/refs/log.py b/refs/log.py
index 8cb0a5ab..c2799f79 100644
--- a/refs/log.py
+++ b/refs/log.py
@@ -1,6 +1,7 @@
from git.util import (
join_path,
Actor,
+ LockedFD,
)
from gitdb.util import (
@@ -173,13 +174,16 @@ class RefLog(list, Serializable):
def to_file(self, filepath):
"""Write the contents of the reflog instance to a file at the given filepath.
:param filepath: path to file, parent directories are assumed to exist"""
- # TODO: Use locked fd
- fp = open(filepath, 'wb')
+ lfd = LockedFD(filepath)
+ fp = lfd.open(write=True, stream=True)
try:
self._serialize(fp)
- finally:
- fp.close()
- #END handle file streams
+ lfd.commit()
+ except:
+ # on failure it rolls back automatically, but we make it clear
+ lfd.rollback()
+ raise
+ #END handle change
def append_entry(self, oldbinsha, newbinsha, message, write=True):
"""Append a new log entry to the revlog, changing it in place.
diff --git a/refs/symbolic.py b/refs/symbolic.py
index b978e484..94e8d726 100644
--- a/refs/symbolic.py
+++ b/refs/symbolic.py
@@ -13,7 +13,8 @@ from gitdb.util import (
exists,
isfile,
rename,
- hex_to_bin
+ hex_to_bin,
+ LockedFD
)
from log import RefLog
@@ -181,11 +182,13 @@ class SymbolicReference(object):
raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, sha))
return self.from_path(self.repo, target_ref_path)
- def _set_reference(self, ref):
+ def _set_reference(self, ref, msg = None):
"""Set ourselves to the given ref. It will stay a symbol if the ref is a Reference.
Otherwise we try to get a commit from it using our interface.
- Strings are allowed but will be checked to be sure we have a commit"""
+ Strings are allowed but will be checked to be sure we have a commit
+ :param msg: If set to a string, the message will be used in the reflog.
+ Otherwise, a reflog entry is not written for the changed reference"""
write_value = None
if isinstance(ref, SymbolicReference):
write_value = "ref: %s" % ref.path
@@ -205,22 +208,6 @@ class SymbolicReference(object):
# END end try string
# END try commit attribute
- # maintain the orig-head if we are currently checked-out
- head = HEAD(self.repo)
- try:
- if head.ref == self:
- try:
- # TODO: implement this atomically, if we fail below, orig_head is at an incorrect spot
- # Enforce the creation of ORIG_HEAD
- SymbolicReference.create(self.repo, head.orig_head().name, self.commit, force=True)
- except ValueError:
- pass
- #END exception handling
- # END if we are checked-out
- except TypeError:
- pass
- # END handle detached heads
-
# if we are writing a ref, use symbolic ref to get the reflog and more
# checking
# Otherwise we detach it and have to do it manually. Besides, this works
diff --git a/test/test_index.py b/test/test_index.py
index 78a868c7..5d227897 100644
--- a/test/test_index.py
+++ b/test/test_index.py
@@ -422,7 +422,6 @@ class TestIndex(TestBase):
# same index, no parents
commit_message = "index without parents"
commit_no_parents = index.commit(commit_message, parent_commits=list(), head=True)
- assert SymbolicReference(rw_repo, 'ORIG_HEAD').commit == cur_commit
assert commit_no_parents.message == commit_message
assert len(commit_no_parents.parents) == 0
assert cur_head.commit == commit_no_parents
diff --git a/test/test_refs.py b/test/test_refs.py
index c7764d92..0c0caaf2 100644
--- a/test/test_refs.py
+++ b/test/test_refs.py
@@ -95,35 +95,38 @@ class TestRefs(TestBase):
assert head.tracking_branch() is None
# END for each head
- # verify ORIG_HEAD gets set for detached heads
- head = rwrepo.head
- orig_head = head.orig_head()
- cur_head = head.ref
- cur_commit = cur_head.commit
- pcommit = cur_head.commit.parents[0].parents[0]
- head.ref = pcommit # detach head
- assert orig_head.commit == cur_commit
-
- # even if we set it through its reference - chaning the ref
- # will adjust the orig_head, which still points to cur_commit
- head.ref = cur_head
- assert orig_head.commit == pcommit
- assert head.commit == cur_commit == cur_head.commit
-
- cur_head.commit = pcommit
- assert head.commit == pcommit
- assert orig_head.commit == cur_commit
-
- # with automatic dereferencing
- head.commit = cur_commit
- assert orig_head.commit == pcommit
-
- # changing branches which are not checked out doesn't affect the ORIG_HEAD
- other_head = Head.create(rwrepo, 'mynewhead', pcommit)
- assert other_head.commit == pcommit
- assert orig_head.commit == pcommit
- other_head.commit = pcommit.parents[0]
- assert orig_head.commit == pcommit
+ # verify REFLOG gets altered
+ if False:
+ head = rwrepo.head
+ orig_head = head.orig_head()
+ cur_head = head.ref
+ cur_commit = cur_head.commit
+ pcommit = cur_head.commit.parents[0].parents[0]
+ head.ref = pcommit # detach head
+ assert orig_head.commit == cur_commit
+
+ # even if we set it through its reference - chaning the ref
+ # will adjust the orig_head, which still points to cur_commit
+ head.ref = cur_head
+ assert orig_head.commit == pcommit
+ assert head.commit == cur_commit == cur_head.commit
+
+ cur_head.commit = pcommit
+ assert head.commit == pcommit
+ assert orig_head.commit == cur_commit
+
+ # with automatic dereferencing
+ head.commit = cur_commit
+ assert orig_head.commit == pcommit
+
+ # changing branches which are not checked out doesn't affect the ORIG_HEAD
+ other_head = Head.create(rwrepo, 'mynewhead', pcommit)
+ assert other_head.commit == pcommit
+ assert orig_head.commit == pcommit
+ other_head.commit = pcommit.parents[0]
+ assert orig_head.commit == pcommit
+
+ # TODO: Need changing a ref changes HEAD reflog as well if it pointed to it
def test_refs(self):