/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
1
# repo.py -- For dealing wih git repositories.
0.211.2 by James Westby
Make it more like a real project.
2
# Copyright (C) 2007 James Westby <jw+debian@jameswestby.net>
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
3
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
0.211.2 by James Westby
Make it more like a real project.
4
# 
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; version 2
8
# of the License.
9
# 
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
# 
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
# MA  02110-1301, USA.
19
0.211.1 by James Westby
Start the python-git project.
20
import os
21
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
22
from commit import Commit
0.211.6 by James Westby
Error when a commit isn't found to avoid problems later.
23
from errors import MissingCommitError
0.211.4 by James Westby
Add methods to repo to get objects of a certain type.
24
from objects import (ShaFile,
25
                     Commit,
26
                     Tree,
27
                     Blob,
28
                     )
0.211.1 by James Westby
Start the python-git project.
29
30
objectdir = 'objects'
31
symref = 'ref: '
32
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
33
34
class Tag(object):
35
36
    def __init__(self, name, ref):
37
        self.name = name
38
        self.commit = Commit(ref)
39
40
41
class Repo(object):
0.211.1 by James Westby
Start the python-git project.
42
43
  ref_locs = ['', 'refs', 'refs/tags', 'refs/heads', 'refs/remotes']
44
45
  def __init__(self, root):
0.212.1 by Jelmer Vernooij
Support opening bare repositories.
46
    controldir = os.path.join(root, ".git")
47
    if os.path.exists(os.path.join(controldir, "objects")):
48
      self.bare = False
49
      self._basedir = controldir
50
    else:
51
      self.bare = True
52
      self._basedir = root
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
53
    self.path = controldir
54
    self.tags = [Tag(name, ref) for name, ref in self.get_tags().items()]
0.211.1 by James Westby
Start the python-git project.
55
56
  def basedir(self):
57
    return self._basedir
58
59
  def object_dir(self):
60
    return os.path.join(self.basedir(), objectdir)
61
62
  def _get_ref(self, file):
63
    f = open(file, 'rb')
64
    try:
65
      contents = f.read()
66
      if contents.startswith(symref):
67
        ref = contents[len(symref):]
68
        if ref[-1] == '\n':
69
          ref = ref[:-1]
70
        return self.ref(ref)
71
      assert len(contents) == 41, 'Invalid ref'
72
      return contents[:-1]
73
    finally:
74
      f.close()
75
76
  def ref(self, name):
77
    for dir in self.ref_locs:
78
      file = os.path.join(self.basedir(), dir, name)
79
      if os.path.exists(file):
80
        return self._get_ref(file)
81
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
82
  def get_tags(self):
83
    ret = {}
84
    for name in os.listdir(os.path.join(self.basedir(), 'refs', 'tags')):
85
      ret[name] = self._get_ref(os.path.join(self.basedir(), 'refs', 'tags', name))
86
    return ret
87
88
  def heads(self):
89
    ret = {}
90
    for name in os.listdir(os.path.join(self.basedir(), 'refs', 'heads')):
91
      ret[name] = self._get_ref(os.path.join(self.basedir(), 'refs', 'heads', name))
92
    return ret
93
0.211.1 by James Westby
Start the python-git project.
94
  def head(self):
95
    return self.ref('HEAD')
96
0.211.4 by James Westby
Add methods to repo to get objects of a certain type.
97
  def _get_object(self, sha, cls):
98
    assert len(sha) == 40, "Incorrect length sha: %s" % str(sha)
0.211.1 by James Westby
Start the python-git project.
99
    dir = sha[:2]
100
    file = sha[2:]
101
    path = os.path.join(self.object_dir(), dir, file)
102
    if not os.path.exists(path):
0.211.6 by James Westby
Error when a commit isn't found to avoid problems later.
103
      # Should this raise instead?
0.211.1 by James Westby
Start the python-git project.
104
      return None
0.211.4 by James Westby
Add methods to repo to get objects of a certain type.
105
    return cls.from_file(path)
106
107
  def get_object(self, sha):
108
    return self._get_object(sha, ShaFile)
109
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
110
  def commit(self, sha):
0.211.4 by James Westby
Add methods to repo to get objects of a certain type.
111
    return self._get_object(sha, Commit)
112
113
  def get_tree(self, sha):
114
    return self._get_object(sha, Tree)
115
116
  def get_blob(self, sha):
117
    return self._get_object(sha, Blob)
0.211.1 by James Westby
Start the python-git project.
118
0.211.5 by James Westby
Add support for getting the revision graph from a head.
119
  def revision_history(self, head):
120
    """Returns a list of the commits reachable from head.
121
122
    Returns a list of commit objects. the first of which will be the commit
123
    of head, then following theat will be the parents.
124
125
    Raises NotCommitError if any no commits are referenced, including if the
126
    head parameter isn't the sha of a commit.
127
128
    XXX: work out how to handle merges.
129
    """
0.211.8 by James Westby
Make the commit walker use a loop rather than recursion.
130
    # We build the list backwards, as parents are more likely to be older
131
    # than children
132
    pending_commits = [head]
133
    history = []
134
    while pending_commits != []:
135
      head = pending_commits.pop(0)
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
136
      commit = self.commit(head)
0.211.8 by James Westby
Make the commit walker use a loop rather than recursion.
137
      if commit is None:
138
        raise MissingCommitError(head)
139
      if commit in history:
140
        continue
141
      i = 0
142
      for known_commit in history:
143
        if known_commit.commit_time() > commit.commit_time():
144
          break
145
        i += 1
146
      history.insert(i, commit)
147
      parents = commit.parents()
148
      pending_commits += parents
149
    history.reverse()
0.211.5 by James Westby
Add support for getting the revision graph from a head.
150
    return history
151
0.211.14 by Jelmer Vernooij
Import changes from my bzr-git branch, to make dulwich before more like python-git.
152
  @classmethod
153
  def init_bare(cls, path, mkdir=True):
154
      for d in [["objects"], 
155
                ["objects", "info"], 
156
                ["objects", "pack"],
157
                ["branches"],
158
                ["refs"],
159
                ["refs", "tags"],
160
                ["refs", "heads"],
161
                ["hooks"],
162
                ["info"]]:
163
          os.mkdir(os.path.join(path, *d))
164
      open(os.path.join(path, 'HEAD'), 'w').write("ref: refs/heads/master\n")
165
      open(os.path.join(path, 'description'), 'w').write("Unnamed repository")
166
      open(os.path.join(path, 'info', 'excludes'), 'w').write("")
167
168
  create = init_bare
169