Skip to content

Commit e766919

Browse files
authored
Update head.py
1 parent eaaa546 commit e766919

File tree

1 file changed

+1
-263
lines changed

1 file changed

+1
-263
lines changed

git/refs/head.py

+1-263
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,4 @@
1-
from git.config import SectionConstraint
2-
from git.util import join_path
3-
from git.exc import GitCommandError
4-
5-
from .symbolic import SymbolicReference
6-
from .reference import Reference
7-
8-
# typinng ---------------------------------------------------
9-
10-
from typing import Any, Sequence, Union, TYPE_CHECKING
11-
12-
from git.types import PathLike, Commit_ish
13-
14-
if TYPE_CHECKING:
15-
from git.repo import Repo
16-
from git.objects import Commitfrom git.config import GitConfigParser, SectionConstraint
1+
from git.config import GitConfigParser, SectionConstraint
172
from git.util import join_path
183
from git.exc import GitCommandError
194

@@ -276,250 +261,3 @@ def config_writer(self) -> SectionConstraint[GitConfigParser]:
276261
return self._config_parser(read_only=False)
277262

278263
#} END configuration
279-
280-
from git.refs import RemoteReference
281-
282-
# -------------------------------------------------------------------
283-
284-
__all__ = ["HEAD", "Head"]
285-
286-
287-
def strip_quotes(string):
288-
if string.startswith('"') and string.endswith('"'):
289-
return string[1:-1]
290-
return string
291-
292-
293-
class HEAD(SymbolicReference):
294-
295-
"""Special case of a Symbolic Reference as it represents the repository's
296-
HEAD reference."""
297-
_HEAD_NAME = 'HEAD'
298-
_ORIG_HEAD_NAME = 'ORIG_HEAD'
299-
__slots__ = ()
300-
301-
def __init__(self, repo: 'Repo', path: PathLike = _HEAD_NAME):
302-
if path != self._HEAD_NAME:
303-
raise ValueError("HEAD instance must point to %r, got %r" % (self._HEAD_NAME, path))
304-
super(HEAD, self).__init__(repo, path)
305-
self.commit: 'Commit'
306-
307-
def orig_head(self) -> SymbolicReference:
308-
"""
309-
:return: SymbolicReference pointing at the ORIG_HEAD, which is maintained
310-
to contain the previous value of HEAD"""
311-
return SymbolicReference(self.repo, self._ORIG_HEAD_NAME)
312-
313-
def reset(self, commit: Union[Commit_ish, SymbolicReference, str] = 'HEAD',
314-
index: bool = True, working_tree: bool = False,
315-
paths: Union[PathLike, Sequence[PathLike], None] = None, **kwargs: Any) -> 'HEAD':
316-
"""Reset our HEAD to the given commit optionally synchronizing
317-
the index and working tree. The reference we refer to will be set to
318-
commit as well.
319-
320-
:param commit:
321-
Commit object, Reference Object or string identifying a revision we
322-
should reset HEAD to.
323-
324-
:param index:
325-
If True, the index will be set to match the given commit. Otherwise
326-
it will not be touched.
327-
328-
:param working_tree:
329-
If True, the working tree will be forcefully adjusted to match the given
330-
commit, possibly overwriting uncommitted changes without warning.
331-
If working_tree is True, index must be true as well
332-
333-
:param paths:
334-
Single path or list of paths relative to the git root directory
335-
that are to be reset. This allows to partially reset individual files.
336-
337-
:param kwargs:
338-
Additional arguments passed to git-reset.
339-
340-
:return: self"""
341-
mode: Union[str, None]
342-
mode = "--soft"
343-
if index:
344-
mode = "--mixed"
345-
346-
# it appears, some git-versions declare mixed and paths deprecated
347-
# see http://github.com/Byron/GitPython/issues#issue/2
348-
if paths:
349-
mode = None
350-
# END special case
351-
# END handle index
352-
353-
if working_tree:
354-
mode = "--hard"
355-
if not index:
356-
raise ValueError("Cannot reset the working tree if the index is not reset as well")
357-
358-
# END working tree handling
359-
360-
try:
361-
self.repo.git.reset(mode, commit, '--', paths, **kwargs)
362-
except GitCommandError as e:
363-
# git nowadays may use 1 as status to indicate there are still unstaged
364-
# modifications after the reset
365-
if e.status != 1:
366-
raise
367-
# END handle exception
368-
369-
return self
370-
371-
372-
class Head(Reference):
373-
374-
"""A Head is a named reference to a Commit. Every Head instance contains a name
375-
and a Commit object.
376-
377-
Examples::
378-
379-
>>> repo = Repo("/path/to/repo")
380-
>>> head = repo.heads[0]
381-
382-
>>> head.name
383-
'master'
384-
385-
>>> head.commit
386-
<git.Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
387-
388-
>>> head.commit.hexsha
389-
'1c09f116cbc2cb4100fb6935bb162daa4723f455'"""
390-
_common_path_default = "refs/heads"
391-
k_config_remote = "remote"
392-
k_config_remote_ref = "merge" # branch to merge from remote
393-
394-
@classmethod
395-
def delete(cls, repo: 'Repo', *heads: 'Head', **kwargs: Any):
396-
"""Delete the given heads
397-
398-
:param force:
399-
If True, the heads will be deleted even if they are not yet merged into
400-
the main development stream.
401-
Default False"""
402-
force = kwargs.get("force", False)
403-
flag = "-d"
404-
if force:
405-
flag = "-D"
406-
repo.git.branch(flag, *heads)
407-
408-
def set_tracking_branch(self, remote_reference: 'RemoteReference') -> 'Head':
409-
"""
410-
Configure this branch to track the given remote reference. This will alter
411-
this branch's configuration accordingly.
412-
413-
:param remote_reference: The remote reference to track or None to untrack
414-
any references
415-
:return: self"""
416-
from .remote import RemoteReference
417-
if remote_reference is not None and not isinstance(remote_reference, RemoteReference):
418-
raise ValueError("Incorrect parameter type: %r" % remote_reference)
419-
# END handle type
420-
421-
with self.config_writer() as writer:
422-
if remote_reference is None:
423-
writer.remove_option(self.k_config_remote)
424-
writer.remove_option(self.k_config_remote_ref)
425-
if len(writer.options()) == 0:
426-
writer.remove_section()
427-
else:
428-
writer.set_value(self.k_config_remote, remote_reference.remote_name)
429-
writer.set_value(self.k_config_remote_ref, Head.to_full_path(remote_reference.remote_head))
430-
431-
return self
432-
433-
def tracking_branch(self) -> Union['RemoteReference', None]:
434-
"""
435-
:return: The remote_reference we are tracking, or None if we are
436-
not a tracking branch"""
437-
from .remote import RemoteReference
438-
reader = self.config_reader()
439-
if reader.has_option(self.k_config_remote) and reader.has_option(self.k_config_remote_ref):
440-
ref = Head(self.repo, Head.to_full_path(strip_quotes(reader.get_value(self.k_config_remote_ref))))
441-
remote_refpath = RemoteReference.to_full_path(join_path(reader.get_value(self.k_config_remote), ref.name))
442-
return RemoteReference(self.repo, remote_refpath)
443-
# END handle have tracking branch
444-
445-
# we are not a tracking branch
446-
return None
447-
448-
def rename(self, new_path: PathLike, force: bool = False) -> 'Head':
449-
"""Rename self to a new path
450-
451-
:param new_path:
452-
Either a simple name or a path, i.e. new_name or features/new_name.
453-
The prefix refs/heads is implied
454-
455-
:param force:
456-
If True, the rename will succeed even if a head with the target name
457-
already exists.
458-
459-
:return: self
460-
:note: respects the ref log as git commands are used"""
461-
flag = "-m"
462-
if force:
463-
flag = "-M"
464-
465-
self.repo.git.branch(flag, self, new_path)
466-
self.path = "%s/%s" % (self._common_path_default, new_path)
467-
return self
468-
469-
def checkout(self, force: bool = False, **kwargs: Any):
470-
"""Checkout this head by setting the HEAD to this reference, by updating the index
471-
to reflect the tree we point to and by updating the working tree to reflect
472-
the latest index.
473-
474-
The command will fail if changed working tree files would be overwritten.
475-
476-
:param force:
477-
If True, changes to the index and the working tree will be discarded.
478-
If False, GitCommandError will be raised in that situation.
479-
480-
:param kwargs:
481-
Additional keyword arguments to be passed to git checkout, i.e.
482-
b='new_branch' to create a new branch at the given spot.
483-
484-
:return:
485-
The active branch after the checkout operation, usually self unless
486-
a new branch has been created.
487-
If there is no active branch, as the HEAD is now detached, the HEAD
488-
reference will be returned instead.
489-
490-
:note:
491-
By default it is only allowed to checkout heads - everything else
492-
will leave the HEAD detached which is allowed and possible, but remains
493-
a special state that some tools might not be able to handle."""
494-
kwargs['f'] = force
495-
if kwargs['f'] is False:
496-
kwargs.pop('f')
497-
498-
self.repo.git.checkout(self, **kwargs)
499-
if self.repo.head.is_detached:
500-
return self.repo.head
501-
return self.repo.active_branch
502-
503-
#{ Configuration
504-
def _config_parser(self, read_only: bool) -> SectionConstraint:
505-
if read_only:
506-
parser = self.repo.config_reader()
507-
else:
508-
parser = self.repo.config_writer()
509-
# END handle parser instance
510-
511-
return SectionConstraint(parser, 'branch "%s"' % self.name)
512-
513-
def config_reader(self) -> SectionConstraint:
514-
"""
515-
:return: A configuration parser instance constrained to only read
516-
this instance's values"""
517-
return self._config_parser(read_only=True)
518-
519-
def config_writer(self) -> SectionConstraint:
520-
"""
521-
:return: A configuration writer instance with read-and write access
522-
to options of this head"""
523-
return self._config_parser(read_only=False)
524-
525-
#} END configuration

0 commit comments

Comments
 (0)