Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita17c43d

Browse files
committed
Made previously protected methods public to introduce a method with reflog support which cannot be exposed using the respective property. Ref-Creation is now fully implemented in python. For details, see doc/source/changes.rst
1 parent8dd51f1 commita17c43d

File tree

6 files changed

+118
-111
lines changed

6 files changed

+118
-111
lines changed

‎doc/source/changes.rst‎

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,44 @@
22
Changelog
33
=========
44

5-
0.3.2 Beta 2
5+
0.3.1 Beta 2
66
============
7-
* Added reflog support ( reading and writing )
7+
* Added **reflog support** ( reading and writing )
8+
9+
* New types: ``RefLog`` and ``RefLogEntry``
10+
* Reflog is maintained automatically when creating references and deleting them
11+
* Non-intrusive changes to ``SymbolicReference``, these don't require your code to change. They allow to append messages to the reflog.
12+
13+
* ``abspath`` property added, similar to ``abspath`` of Object instances
14+
* ``log()`` method added
15+
* ``log_append(...)`` method added
16+
* ``set_reference(...)`` method added (reflog support)
17+
* ``set_commit(...)`` method added (reflog support)
18+
19+
* Intrusive Changes to ``Head`` type
20+
21+
* ``create(...)`` method now supports the reflog, but will not raise ``GitCommandError`` anymore as it is a pure python implementation now. Instead, it raises ``OSError``.
22+
823
* Repo.rev_parse now supports the [ref]@{n} syntax, where n is the number of steps to look into the reference's past
924

10-
0.3.2 Beta 1
11-
============
12-
* Flattened directory structure to make development more convenient.
25+
* **BugFixes**
26+
27+
* Removed incorrect ORIG_HEAD handling
28+
29+
* **Flattened directory** structure to make development more convenient.
1330

1431
* .. note:: This alters the way projects using git-python as a submodule have to adjust their sys.path to be able to import git-python successfully.
32+
* Misc smaller changes and bugfixes
1533

1634
0.3.1 Beta 1
1735
============
1836
* Full Submodule-Support
1937
* Added unicode support for author names. Commit.author.name is now unicode instead of string.
38+
* Head Type changes
39+
40+
* config_reader() & config_writer() methods added for access to head specific options.
41+
* tracking_branch() & set_tracking_branch() methods addded for easy configuration of tracking branches.
42+
2043

2144
0.3.0 Beta 2
2245
============

‎refs/head.py‎

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -112,38 +112,6 @@ class Head(Reference):
112112
k_config_remote="remote"
113113
k_config_remote_ref="merge"# branch to merge from remote
114114

115-
@classmethod
116-
defcreate(cls,repo,path,commit='HEAD',force=False,**kwargs):
117-
"""Create a new head.
118-
:param repo: Repository to create the head in
119-
:param path:
120-
The name or path of the head, i.e. 'new_branch' or
121-
feature/feature1. The prefix refs/heads is implied.
122-
123-
:param commit:
124-
Commit to which the new head should point, defaults to the
125-
current HEAD
126-
127-
:param force:
128-
if True, force creation even if branch with that name already exists.
129-
130-
:param kwargs:
131-
Additional keyword arguments to be passed to git-branch, i.e.
132-
track, no-track, l
133-
134-
:return: Newly created Head
135-
:note: This does not alter the current HEAD, index or Working Tree"""
136-
ifclsisnotHead:
137-
raiseTypeError("Only Heads can be created explicitly, not objects of type %s"%cls.__name__)
138-
139-
args= (path,commit )
140-
ifforce:
141-
kwargs['f']=True
142-
143-
repo.git.branch(*args,**kwargs)
144-
returncls(repo,"%s/%s"% (cls._common_path_default,path))
145-
146-
147115
@classmethod
148116
defdelete(cls,repo,*heads,**kwargs):
149117
"""Delete the given heads
@@ -157,7 +125,6 @@ def delete(cls, repo, *heads, **kwargs):
157125
flag="-D"
158126
repo.git.branch(flag,*heads)
159127

160-
161128
defset_tracking_branch(self,remote_reference):
162129
"""
163130
Configure this branch to track the given remote reference. This will alter

‎refs/reference.py‎

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
1818
"""Represents a named reference to any object. Subclasses may apply restrictions though,
1919
i.e. Heads can only point to commits."""
2020
__slots__=tuple()
21+
_resolve_ref_on_create=True
2122
_common_path_default="refs"
2223

2324
def__init__(self,repo,path):
@@ -52,7 +53,7 @@ def _set_object(self, ref):
5253
5354
:note:
5455
TypeChecking is done by the git command"""
55-
abs_path=self._abs_path()
56+
abs_path=self.abspath
5657
existed=True
5758
ifnotisfile(abs_path):
5859
existed=False
@@ -81,31 +82,7 @@ def name(self):
8182
returnself.path# could be refs/HEAD
8283
return'/'.join(tokens[2:])
8384

84-
8585
@classmethod
86-
defcreate(cls,repo,path,commit='HEAD',force=False ):
87-
"""Create a new reference.
88-
89-
:param repo: Repository to create the reference in
90-
:param path:
91-
The relative path of the reference, i.e. 'new_branch' or
92-
feature/feature1. The path prefix 'refs/' is implied if not
93-
given explicitly
94-
95-
:param commit:
96-
Commit to which the new reference should point, defaults to the
97-
current HEAD
98-
99-
:param force:
100-
if True, force creation even if a reference with that name already exists.
101-
Raise OSError otherwise
102-
103-
:return: Newly created Reference
104-
105-
:note: This does not alter the current HEAD, index or Working Tree"""
106-
returncls._create(repo,path,True,commit,force)
107-
108-
@classmethod
10986
defiter_items(cls,repo,common_path=None):
11087
"""Equivalent to SymbolicReference.iter_items, but will return non-detached
11188
references as well."""

‎refs/remote.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,8 @@ def delete(cls, repo, *refs, **kwargs):
5656
exceptOSError:
5757
pass
5858
# END for each ref
59+
60+
@classmethod
61+
defcreate(cls,*args,**kwargs):
62+
"""Used to disable this method"""
63+
raiseTypeError("Cannot explicitly create remote references")

‎refs/symbolic.py‎

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
fromgit.utilimport (
44
join_path,
55
join_path_native,
6-
to_native_path_linux
6+
to_native_path_linux,
7+
assure_directory_exists
78
)
89

910
fromgitdb.utilimport (
@@ -28,6 +29,7 @@ class SymbolicReference(object):
2829
2930
A typical example for a symbolic reference is HEAD."""
3031
__slots__= ("repo","path")
32+
_resolve_ref_on_create=False
3133
_common_path_default=""
3234
_id_attribute_="name"
3335

@@ -58,7 +60,8 @@ def name(self):
5860
is the path itself."""
5961
returnself.path
6062

61-
def_abs_path(self):
63+
@property
64+
defabspath(self):
6265
returnjoin_path_native(self.repo.git_dir,self.path)
6366

6467
@classmethod
@@ -116,7 +119,7 @@ def _get_ref_info(self):
116119
point to, or None"""
117120
tokens=None
118121
try:
119-
fp=open(self._abs_path(),'r')
122+
fp=open(self.abspath,'r')
120123
value=fp.read().rstrip()
121124
fp.close()
122125
tokens=value.split(" ")
@@ -158,37 +161,48 @@ def _get_commit(self):
158161

159162
returnself.from_path(self.repo,target_ref_path).commit
160163

161-
def_set_commit(self,commit):
164+
defset_commit(self,commit,msg=None):
162165
"""Set our commit, possibly dereference our symbolic reference first.
163-
If the reference does not exist, it will be created"""
166+
If the reference does not exist, it will be created
167+
168+
:param msg: If not None, the message will be used in the reflog entry to be
169+
written. Otherwise the reflog is not altered"""
164170
is_detached=True
165171
try:
166172
is_detached=self.is_detached
167173
exceptValueError:
168174
pass
169175
# END handle non-existing ones
176+
170177
ifis_detached:
171-
returnself._set_reference(commit)
178+
returnself.set_reference(commit,msg)
172179

173180
# set the commit on our reference
174-
self._get_reference().commit=commit
181+
self._get_reference().set_commit(commit,msg)
175182

176-
commit=property(_get_commit,_set_commit,doc="Query or set commits directly")
183+
commit=property(_get_commit,set_commit,doc="Query or set commits directly")
177184

178185
def_get_reference(self):
179-
""":return: Reference Object we point to"""
186+
""":return: Reference Object we point to
187+
:raise TypeError: If this symbolic reference is detached, hence it doesn't point
188+
to a reference, but to a commit"""
180189
sha,target_ref_path=self._get_ref_info()
181190
iftarget_ref_pathisNone:
182191
raiseTypeError("%s is a detached symbolic reference as it points to %r"% (self,sha))
183192
returnself.from_path(self.repo,target_ref_path)
184193

185-
def_set_reference(self,ref,msg=None):
194+
defset_reference(self,ref,msg=None):
186195
"""Set ourselves to the given ref. It will stay a symbol if the ref is a Reference.
187-
Otherwise we try to get a commit from it using our interface.
196+
Otherwise a commmit, given as Commit object or refspec, is assumed and if valid,
197+
will be set which effectively detaches the refererence if it was a purely
198+
symbolic one.
188199
189-
Strings are allowed but will be checked to be sure we have a commit
200+
:param ref: SymbolicReference instance, Commit instance or refspec string
190201
:param msg: If set to a string, the message will be used in the reflog.
191-
Otherwise, a reflog entry is not written for the changed reference"""
202+
Otherwise, a reflog entry is not written for the changed reference.
203+
The previous commit of the entry will be the commit we point to now.
204+
205+
See also: log_append()"""
192206
write_value=None
193207
ifisinstance(ref,SymbolicReference):
194208
write_value="ref: %s"%ref.path
@@ -207,33 +221,31 @@ def _set_reference(self, ref, msg = None):
207221
raiseValueError("Could not extract object from %s"%ref)
208222
# END end try string
209223
# END try commit attribute
224+
oldbinsha=None
225+
ifmsgisnotNone:
226+
try:
227+
oldhexsha=self.commit.binsha
228+
exceptValueError:
229+
oldbinsha=Commit.NULL_BIN_SHA
230+
#END handle non-existing
231+
#END retrieve old hexsha
232+
233+
fpath=self.abspath
234+
assure_directory_exists(fpath,is_file=True)
235+
236+
lfd=LockedFD(fpath)
237+
fd=lfd.open(write=True,stream=True)
238+
fd.write(write_value)
239+
lfd.commit()
240+
241+
# Adjust the reflog
242+
ifmsgisnotNone:
243+
self.log_append(oldbinsha,msg)
244+
#END handle reflog
210245

211-
# if we are writing a ref, use symbolic ref to get the reflog and more
212-
# checking
213-
# Otherwise we detach it and have to do it manually. Besides, this works
214-
# recursively automaitcally, but should be replaced with a python implementation
215-
# soon
216-
ifwrite_value.startswith('ref:'):
217-
self.repo.git.symbolic_ref(self.path,write_value[5:])
218-
return
219-
# END non-detached handling
220-
221-
path=self._abs_path()
222-
directory=dirname(path)
223-
ifnotisdir(directory):
224-
os.makedirs(directory)
225-
226-
# TODO: Write using LockedFD
227-
fp=open(path,"wb")
228-
try:
229-
fp.write(write_value)
230-
finally:
231-
fp.close()
232-
# END writing
233-
234246

235247
# aliased reference
236-
reference=property(_get_reference,_set_reference,doc="Returns the Reference we point to")
248+
reference=property(_get_reference,set_reference,doc="Returns the Reference we point to")
237249
ref=reference
238250

239251
defis_valid(self):
@@ -255,7 +267,7 @@ def is_detached(self):
255267
True if we are a detached reference, hence we point to a specific commit
256268
instead to another reference"""
257269
try:
258-
self.reference
270+
self.ref
259271
returnFalse
260272
exceptTypeError:
261273
returnTrue
@@ -343,11 +355,18 @@ def delete(cls, repo, path):
343355
open(pack_file_path,'w').writelines(new_lines)
344356
# END open exception handling
345357
# END handle deletion
358+
359+
# delete the reflog
360+
reflog_path=RefLog.path(cls(repo,full_ref_path))
361+
ifos.path.isfile(reflog_path):
362+
os.remove(reflog_path)
363+
#END remove reflog
364+
346365

347366
@classmethod
348-
def_create(cls,repo,path,resolve,reference,force):
367+
def_create(cls,repo,path,resolve,reference,force,msg=None):
349368
"""internal method used to create a new symbolic reference.
350-
If resolve is False,, the reference will be taken as is, creating
369+
If resolve is False, the reference will be taken as is, creating
351370
a proper symbolic reference. Otherwise it will be resolved to the
352371
corresponding object and a detached symbolic reference will be created
353372
instead"""
@@ -365,16 +384,17 @@ def _create(cls, repo, path, resolve, reference, force):
365384
target_data=target.path
366385
ifnotresolve:
367386
target_data="ref: "+target_data
368-
ifopen(abs_ref_path,'rb').read().strip()!=target_data:
369-
raiseOSError("Reference at %s does already exist"%full_ref_path)
387+
existing_data=open(abs_ref_path,'rb').read().strip()
388+
ifexisting_data!=target_data:
389+
raiseOSError("Reference at %r does already exist, pointing to %r, requested was %r"% (full_ref_path,existing_data,target_data))
370390
# END no force handling
371391

372392
ref=cls(repo,full_ref_path)
373-
ref.reference=target
393+
ref.set_reference(target,msg)
374394
returnref
375395

376396
@classmethod
377-
defcreate(cls,repo,path,reference='HEAD',force=False):
397+
defcreate(cls,repo,path,reference='HEAD',force=False,msg=None):
378398
"""Create a new symbolic reference, hence a reference pointing to another reference.
379399
380400
:param repo:
@@ -391,14 +411,18 @@ def create(cls, repo, path, reference='HEAD', force=False ):
391411
if True, force creation even if a symbolic reference with that name already exists.
392412
Raise OSError otherwise
393413
414+
:param msg:
415+
If not None, the message to append to the reflog. Otherwise no reflog
416+
entry is written.
417+
394418
:return: Newly created symbolic Reference
395419
396420
:raise OSError:
397421
If a (Symbolic)Reference with the same name but different contents
398422
already exists.
399423
400424
:note: This does not alter the current HEAD, index or Working Tree"""
401-
returncls._create(repo,path,False,reference,force)
425+
returncls._create(repo,path,cls._resolve_ref_on_create,reference,force,msg)
402426

403427
defrename(self,new_path,force=False):
404428
"""Rename self to a new path

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp