Codebase list python-git / 95fa14a
Imported Upstream version 0.1.5 SVN-Git Migration 8 years ago
28 changed file(s) with 330 addition(s) and 213 deletion(s). Raw diff Collapse all Expand all
._AUTHORS less more
Binary diff not shown
._CHANGES less more
Binary diff not shown
._LICENSE less more
Binary diff not shown
._MANIFEST.in less more
Binary diff not shown
._README less more
Binary diff not shown
._VERSION less more
Binary diff not shown
11 Alan Briolat
22 Florian Apolloner <florian _at_ apolloner.eu>
33 David Aguilar <davvid _at_ gmail.com>
4 Jelmer Vernooij <jelmer _at_ samba.org>
5 Steve Frécinaux <code _at_ istique.net>
6 Kai Lautaportti <kai _at_ lautaportti.fi>
44 0.1.5
55 =====
66
7 * removed ``method_missing`` stuff and replaced with a ``__getattr__``
7 General
8 -------
9 * upgraded to Mock 0.4 dependency.
10
11 * Replace GitPython with git in repr() outputs.
12
13 * Fixed packaging issue caused by ez_setup.py.
14
15 Blob
16 ----
17 * No longer strip newlines from Blob data.
18
19 Commit
20 ------
21 * Corrected problem with git-rev-list --bisect-all. See
22 http://groups.google.com/group/git-python/browse_thread/thread/aed1d5c4b31d5027
23
24 Repo
25 ----
26 * Corrected problems with creating bare repositories.
27
28 * Repo.tree no longer accepts a path argument. Use:
29
30 >>> dict(k, o for k, o in tree.items() if k in paths)
31
32 * Made daemon export a property of Repo. Now you can do this:
33
34 >>> exported = repo.daemon_export
35 >>> repo.daemon_export = True
36
37 * Allows modifying the project description. Do this:
38
39 >>> repo.description = "Foo Bar"
40 >>> repo.description
41 'Foo Bar'
42
43 * Added a read-only property Repo.is_dirty which reflects the status of the
44 working directory.
45
46 * Added a read-only Repo.active_branch property which returns the name of the
47 currently active branch.
48
49
50 Tree
51 ----
52 * Switched to using a dictionary for Tree contents since you will usually want
53 to access them by name and order is unimportant.
54
55 * Implemented a dictionary protocol for Tree objects. The following:
56
57 child = tree.contents['grit']
58
59 becomes:
60
61 child = tree['grit']
62
63 * Made Tree.content_from_string a static method.
64
65 0.1.4.1
66 =======
67
68 * removed ``method_missing`` stuff and replaced with a ``__getattr__``
869 override in ``Git``.
970
1071 0.1.4
00 Metadata-Version: 1.0
11 Name: GitPython
2 Version: 0.1.4.1
2 Version: 0.1.5
33 Summary: Python Git Library
44 Home-page: http://gitorious.org/projects/git-python/
55 Author: Michael Trier
1212 ============
1313
1414 * Git_ tested with 1.5.3.7
15 * `Python Nose`_ - used for running the tests
16 * `Mock by Michael Foord`_ used for tests
15 * `Python Nose`_ - used for running the tests
16 * `Mock by Michael Foord`_ used for tests. Requires 0.4
1717
1818 .. _Git: http://git.or.cz/
1919 .. _Python Nose: http://code.google.com/p/python-nose/
3838 LICENSE
3939 =======
4040
41 New BSD License. See the LICENSE file.
41 New BSD License. See the LICENSE file.
0 0.1.4.1
0 0.1.5
doc/._tutorial.txt less more
Binary diff not shown
2626 objects.
2727
2828 >>> repo.commits()
29 [<GitPython.Commit "207c0c4418115df0d30820ab1a9acd2ea4bf4431">,
30 <GitPython.Commit "a91c45eee0b41bf3cdaad3418ca3850664c4a4b4">,
31 <GitPython.Commit "e17c7e11aed9e94d2159e549a99b966912ce1091">,
32 <GitPython.Commit "bd795df2d0e07d10e0298670005c0e9d9a5ed867">]
29 [<git.Commit "207c0c4418115df0d30820ab1a9acd2ea4bf4431">,
30 <git.Commit "a91c45eee0b41bf3cdaad3418ca3850664c4a4b4">,
31 <git.Commit "e17c7e11aed9e94d2159e549a99b966912ce1091">,
32 <git.Commit "bd795df2d0e07d10e0298670005c0e9d9a5ed867">]
3333
3434 Called without arguments, ``Repo.commits`` returns a list of up to ten commits
3535 reachable by the master branch (starting at the latest commit). You can ask
6060 '207c0c4418115df0d30820ab1a9acd2ea4bf4431'
6161
6262 >>> head.parents
63 [<GitPython.Commit "a91c45eee0b41bf3cdaad3418ca3850664c4a4b4">]
63 [<git.Commit "a91c45eee0b41bf3cdaad3418ca3850664c4a4b4">]
6464
6565 >>> head.tree
66 <GitPython.Tree "563413aedbeda425d8d9dcbb744247d0c3e8a0ac">
66 <git.Tree "563413aedbeda425d8d9dcbb744247d0c3e8a0ac">
6767
6868 >>> head.author
69 <GitPython.Actor "Michael Trier <mtrier@gmail.com>">
69 <git.Actor "Michael Trier <mtrier@gmail.com>">
7070
7171 >>> head.authored_date
7272 (2008, 5, 7, 5, 0, 56, 2, 128, 0)
7373
7474 >>> head.committer
75 <GitPython.Actor "Michael Trier <mtrier@gmail.com>">
75 <git.Actor "Michael Trier <mtrier@gmail.com>">
7676
7777 >>> head.committed_date
7878 (2008, 5, 7, 5, 0, 56, 2, 128, 0)
106106 the root tree of the latest commit on the master branch.
107107
108108 >>> tree = repo.commits()[0].tree
109 <GitPython.Tree "a006b5b1a8115185a228b7514cdcd46fed90dc92">
109 <git.Tree "a006b5b1a8115185a228b7514cdcd46fed90dc92">
110110
111111 >>> tree.id
112112 'a006b5b1a8115185a228b7514cdcd46fed90dc92'
114114 Once you have a tree, you can get the contents.
115115
116116 >>> contents = tree.contents
117 [<GitPython.Blob "6a91a439ea968bf2f5ce8bb1cd8ddf5bf2cad6c7">,
118 <GitPython.Blob "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391">,
119 <GitPython.Tree "eaa0090ec96b054e425603480519e7cf587adfc3">,
120 <GitPython.Blob "980e72ae16b5378009ba5dfd6772b59fe7ccd2df">]
117 [<git.Blob "6a91a439ea968bf2f5ce8bb1cd8ddf5bf2cad6c7">,
118 <git.Blob "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391">,
119 <git.Tree "eaa0090ec96b054e425603480519e7cf587adfc3">,
120 <git.Blob "980e72ae16b5378009ba5dfd6772b59fe7ccd2df">]
121121
122122 This tree contains three ``Blob`` objects and one ``Tree`` object. The trees
123123 are subdirectories and the blobs are files. Trees below the root have
124124 additional attributes.
125125
126 >>> contents = tree.contents[-2]
127 <GitPython.Tree "e5445b9db4a9f08d5b4de4e29e61dffda2f386ba">
126 >>> contents = tree["lib"]
127 <git.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a3">
128128
129129 >>> contents.name
130130 'test'
133133 '040000'
134134
135135 There is a convenience method that allows you to get a named sub-object
136 from a tree.
136 from a tree with a syntax similar to how paths are written in an unix
137 system.
137138
138139 >>> tree/"lib"
139 <GitPython.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
140 <git.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
140141
141142 You can also get a tree directly from the repository if you know its name.
142143
143144 >>> repo.tree()
144 <GitPython.Tree "master">
145 <git.Tree "master">
145146
146147 >>> repo.tree("c1c7214dde86f76bc3e18806ac1f47c38b2b7a30")
147 <GitPython.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
148 <git.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
148149
149150 The Blob object
150151 ***************
152153 A blob represents a file. Trees often contain blobs.
153154
154155 >>> blob = tree.contents[-1]
155 <GitPython.Blob "b19574431a073333ea09346eafd64e7b1908ef49">
156 <git.Blob "b19574431a073333ea09346eafd64e7b1908ef49">
156157
157158 A blob has certain attributes.
158159
176177 You can also get a blob directly from the repo if you know its name.
177178
178179 >>> repo.blob("b19574431a073333ea09346eafd64e7b1908ef49")
179 <GitPython.Blob "b19574431a073333ea09346eafd64e7b1908ef49">
180 <git.Blob "b19574431a073333ea09346eafd64e7b1908ef49">
180181
181182 What Else?
182183 **********
00 Metadata-Version: 1.0
11 Name: GitPython
2 Version: 0.1.4.1
2 Version: 0.1.5
33 Summary: Python Git Library
44 Home-page: http://gitorious.org/projects/git-python/
55 Author: Michael Trier
2222 lib/git/stats.py
2323 lib/git/tag.py
2424 lib/git/tree.py
25 lib/git/utils.py
25 lib/git/utils.py
lib/git/._cmd.py less more
Binary diff not shown
lib/git/._commit.py less more
Binary diff not shown
66 import os
77 import inspect
88
9 __version__ = '0.1.4.1'
9 __version__ = '0.1.5'
1010
1111 from git.actor import Actor
1212 from git.blob import Blob
1414 return self.name
1515
1616 def __repr__(self):
17 return '<GitPython.Actor "%s <%s>">' % (self.name, self.email)
17 return '<git.Actor "%s <%s>">' % (self.name, self.email)
1818
1919 @classmethod
2020 def from_string(cls, string):
1313 class Blob(object):
1414 DEFAULT_MIME_TYPE = "text/plain"
1515
16 def __init__(self, repo, **kwargs):
16 def __init__(self, repo, id, mode=None, name=None):
1717 """
1818 Create an unbaked Blob containing just the specified attributes
1919
2020 ``repo``
2121 is the Repo
2222
23 ``atts``
24 is a dict of instance variable data
23 ``id``
24 is the git object id
25
26 ``mode``
27 is the file mode
28
29 ``name``
30 is the file name
2531
2632 Returns
27 GitPython.Blob
33 git.Blob
2834 """
29 self.id = None
30 self.mode = None
31 self.name = None
35 self.repo = repo
36 self.id = id
37 self.mode = mode
38 self.name = name
39
3240 self._size = None
3341 self.data_stored = None
34
35 self.repo = repo
36 for k, v in kwargs.items():
37 setattr(self, k, v)
3842
3943 @property
4044 def size(self):
4549 int
4650 """
4751 if self._size is None:
48 self._size = int(self.repo.git.cat_file(self.id, **{'s': True}).rstrip())
52 self._size = int(self.repo.git.cat_file(self.id, s=True).rstrip())
4953 return self._size
5054
5155 @property
5660 Returns
5761 str
5862 """
59 self.data_stored = self.data_stored or self.repo.git.cat_file(self.id, **{'p': True})
63 self.data_stored = self.data_stored or self.repo.git.cat_file(self.id, p=True, with_raw_output=True)
6064 return self.data_stored
6165
6266 @property
8286 The blame information for the given file at the given commit
8387
8488 Returns
85 list: [GitPython.Commit, list: [<line>]]
89 list: [git.Commit, list: [<line>]]
8690 """
87 data = repo.git.blame(commit, '--', file, **{'p': True})
91 data = repo.git.blame(commit, '--', file, p=True)
8892 commits = {}
8993 blames = []
9094 info = None
119123 if info:
120124 c = commits.has_key(info['id']) and commits[info['id']]
121125 if not c:
122 c = Commit(repo, **{'id': info['id'],
123 'author': Actor.from_string(info['author'] + ' ' + info['author_email']),
124 'authored_date': info['author_date'],
125 'committer': Actor.from_string(info['committer'] + ' ' + info['committer_email']),
126 'committed_date': info['committer_date'],
127 'message': info['summary']})
126 c = Commit(repo, id=info['id'],
127 author=Actor.from_string(info['author'] + ' ' + info['author_email']),
128 authored_date=info['author_date'],
129 committer=Actor.from_string(info['committer'] + ' ' + info['committer_email']),
130 committed_date=info['committer_date'],
131 message=info['summary'])
128132 commits[info['id']] = c
129133
130134 m = re.search(r'^\t(.*)$', line)
136140 return blames
137141
138142 def __repr__(self):
139 return '<GitPython.Blob "%s">' % self.id
143 return '<git.Blob "%s">' % self.id
0 # cmd.py
0 # cmd.py
11 # Copyright (C) 2008 Michael Trier (mtrier@gmail.com) and contributors
22 #
33 # This module is part of GitPython and is released under
44 # the BSD License: http://www.opensource.org/licenses/bsd-license.php
55
6 import os
6 import os, sys
77 import subprocess
88 import re
99 from utils import *
1414
1515 execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
1616 'with_exceptions', 'with_raw_output')
17
18 extra = {}
19 if sys.platform == 'win32':
20 extra = {'shell': True}
1721
1822 class Git(object):
1923 """
8286 cwd=cwd,
8387 stdin=istream,
8488 stderr=subprocess.PIPE,
85 stdout=subprocess.PIPE
89 stdout=subprocess.PIPE,
90 **extra
8691 )
8792
8893 # Wait for the process to return
88
99 from actor import Actor
1010 from lazy import LazyMixin
11 import tree
11 from tree import Tree
1212 import diff
1313 import stats
1414
1515 class Commit(LazyMixin):
16 def __init__(self, repo, **kwargs):
16 def __init__(self, repo, id, tree=None, author=None, authored_date=None,
17 committer=None, committed_date=None, message=None, parents=None):
1718 """
1819 Instantiate a new Commit
1920
4142 ``message``
4243 is the first line of the commit message
4344
44 Returns
45 GitPython.Commit
45 ``parents``
46 is the list of the parents of the commit
47
48 Returns
49 git.Commit
4650 """
4751 LazyMixin.__init__(self)
4852
4953 self.repo = repo
50 self.id = None
54 self.id = id
55 self.parents = None
5156 self.tree = None
52 self.author = None
53 self.authored_date = None
54 self.committer = None
55 self.committed_date = None
56 self.message = None
57 self.parents = None
58
59 for k, v in kwargs.items():
60 setattr(self, k, v)
57 self.author = author
58 self.authored_date = authored_date
59 self.committer = committer
60 self.committed_date = committed_date
61 self.message = message
6162
6263 if self.id:
63 if 'parents' in kwargs:
64 self.parents = map(lambda p: Commit(repo, **{'id': p}), kwargs['parents'])
65 if 'tree' in kwargs:
66 self.tree = tree.Tree(repo, **{'id': kwargs['tree']})
64 if parents is not None:
65 self.parents = [Commit(repo, p) for p in parents]
66 if tree is not None:
67 self.tree = Tree(repo, id=tree)
6768
6869 def __bake__(self):
69 temp = Commit.find_all(self.repo, self.id, **{'max_count': 1})[0]
70 temp = Commit.find_all(self.repo, self.id, max_count=1)[0]
7071 self.parents = temp.parents
7172 self.tree = temp.tree
7273 self.author = temp.author
111112 ``skip`` is the number of commits to skip
112113
113114 Returns
114 GitPython.Commit[]
115 git.Commit[]
115116 """
116117 options = {'pretty': 'raw'}
117118 options.update(kwargs)
131132 is the text output from the git command (raw format)
132133
133134 Returns
134 GitPython.Commit[]
135 git.Commit[]
135136 """
136137 lines = [l for l in text.splitlines() if l.strip()]
137138
138139 commits = []
139140
140141 while lines:
141 id = lines.pop(0).split()[-1]
142 tree = lines.pop(0).split()[-1]
142 id = lines.pop(0).split()[1]
143 tree = lines.pop(0).split()[1]
143144
144145 parents = []
145 while lines and re.search(r'^parent', lines[0]):
146 while lines and lines[0].startswith('parent'):
146147 parents.append(lines.pop(0).split()[-1])
147148 author, authored_date = cls.actor(lines.pop(0))
148149 committer, committed_date = cls.actor(lines.pop(0))
149150
150151 messages = []
151 while lines and re.search(r'^ {4}', lines[0]):
152 while lines and lines[0].startswith(' '):
152153 messages.append(lines.pop(0).strip())
153154
154155 message = messages and messages[0] or ''
178179 is a list of paths to limit the diff.
179180
180181 Returns
181 GitPython.Diff[]
182 git.Diff[]
182183 """
183184 paths = paths or []
184185
192193 if b:
193194 paths.insert(0, b)
194195 paths.insert(0, a)
195 text = repo.git.diff(*paths, **{'full_index': True})
196 text = repo.git.diff(full_index=True, *paths)
196197 return diff.Diff.list_from_string(repo, text)
197198
198199 @property
199200 def diffs(self):
200201 if not self.parents:
201 d = self.repo.git.show(self.id, **{'full_index': True, 'pretty': 'raw'})
202 d = self.repo.git.show(self.id, full_index=True, pretty='raw')
202203 if re.search(r'diff --git a', d):
203204 if not re.search(r'^diff --git a', d):
204205 p = re.compile(r'.+?(diff --git a)', re.MULTILINE | re.DOTALL)
212213 @property
213214 def stats(self):
214215 if not self.parents:
215 text = self.repo.git.diff(self.id, **{'numstat': True})
216 text = self.repo.git.diff(self.id, numstat=True)
216217 text2 = ""
217218 for line in text.splitlines():
218219 (insertions, deletions, filename) = line.split("\t")
219220 text2 += "%s\t%s\t%s\n" % (deletions, insertions, filename)
220221 text = text2
221222 else:
222 text = self.repo.git.diff(self.parents[0].id, self.id, **{'numstat': True})
223 text = self.repo.git.diff(self.parents[0].id, self.id, numstat=True)
223224 return stats.Stats.list_from_string(self.repo, text)
224225
225226 def __str__(self):
227228 return self.id
228229
229230 def __repr__(self):
230 return '<GitPython.Commit "%s">' % self.id
231 return '<git.Commit "%s">' % self.id
231232
232233 @classmethod
233234 def actor(cls, line):
1919 if not a_commit or re.search(r'^0{40}$', a_commit):
2020 self.a_commit = None
2121 else:
22 self.a_commit = commit.Commit(repo, **{'id': a_commit})
22 self.a_commit = commit.Commit(repo, id=a_commit)
2323 if not b_commit or re.search(r'^0{40}$', b_commit):
2424 self.b_commit = None
2525 else:
26 self.b_commit = commit.Commit(repo, **{'id': b_commit})
26 self.b_commit = commit.Commit(repo, id=b_commit)
2727
2828 self.a_mode = a_mode
2929 self.b_mode = b_mode
1919 'master'
2020
2121 >>> head.commit
22 <GitPython.Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
22 <git.Commit "1c09f116cbc2cb4100fb6935bb162daa4723f455">
2323
2424 >>> head.commit.id
2525 '1c09f116cbc2cb4100fb6935bb162daa4723f455'
3636 is the Commit that the head points to
3737
3838 Returns
39 GitPython.Head
39 git.Head
4040 """
4141 self.name = name
4242 self.commit = commit
5353 is a dict of options
5454
5555 Returns
56 GitPython.Head[]
56 git.Head[]
5757 """
5858
5959 options = {'sort': "committerdate",
7474 is the text output from the git command
7575
7676 Returns
77 GitPython.Head[]
77 git.Head[]
7878 """
7979 heads = []
8080
100100 id: [0-9A-Fa-f]{40}
101101
102102 Returns
103 GitPython.Head
103 git.Head
104104 """
105 print line
106105 full_name, ids = line.split("\x00")
107106 name = full_name.split("/")[-1]
108 c = commit.Commit(repo, **{'id': ids})
107 c = commit.Commit(repo, id=ids)
109108 return Head(name, c)
110109
111110 def __repr__(self):
112 return '<GitPython.Head "%s">' % self.name
111 return '<git.Head "%s">' % self.name
3030 repo = Repo("/Users/mtrier/Development/git-python.git")
3131
3232 Returns
33 ``GitPython.Repo``
33 ``git.Repo``
3434 """
3535
3636 epath = os.path.abspath(os.path.expanduser(path or os.getcwd()))
4343 while curpath:
4444 if is_git_dir(curpath):
4545 self.bare = True
46 self.path, self.wd = curpath
46 self.path = curpath
47 self.wd = curpath
4748 break
4849 gitpath = os.path.join(curpath, '.git')
4950 if is_git_dir(gitpath):
6061
6162 self.git = Git(self.wd)
6263
63 @property
64 def description(self):
65 """
66 The project's description. Taken verbatim from GIT_REPO/description
67
68 Returns
69 str
70 """
71 try:
72 f = open(os.path.join(self.path, 'description'))
73 result = f.read()
74 return result.rstrip()
75 finally:
76 f.close()
64 # Description property
65 def _get_description(self):
66 filename = os.path.join(self.path, 'description')
67 return file(filename).read().rstrip()
68
69 def _set_description(self, descr):
70 filename = os.path.join(self.path, 'description')
71 file(filename, 'w').write(descr+'\n')
72
73 description = property(_get_description, _set_description,
74 doc="the project's description")
75 del _get_description
76 del _set_description
7777
7878 @property
7979 def heads(self):
8282 this repo
8383
8484 Returns
85 ``GitPython.Head[]``
85 ``git.Head[]``
8686 """
8787 return Head.find_all(self)
8888
9595 A list of ``Tag`` objects that are available in this repo
9696
9797 Returns
98 ``GitPython.Tag[]``
98 ``git.Tag[]``
9999 """
100100 return Tag.find_all(self)
101101
113113 is the number of commits to skip (default 0)
114114
115115 Returns
116 ``GitPython.Commit[]``
116 ``git.Commit[]``
117117 """
118118 options = {'max_count': max_count,
119119 'skip': skip}
132132 is the branch/commit name of the older item
133133
134134 Returns
135 ``GitPython.Commit[]``
135 ``git.Commit[]``
136136 """
137137 return Commit.find_all(self, "%s..%s" % (frm, to)).reverse()
138138
148148 is a string represeting a date/time
149149
150150 Returns
151 ``GitPython.Commit[]``
151 ``git.Commit[]``
152152 """
153153 options = {'since': since}
154154
174174 is the SHA1 identifier of the commit
175175
176176 Returns
177 GitPython.Commit
177 git.Commit
178178 """
179179 options = {'max_count': 1}
180180
189189 Returns a list of commits that is in ``other_repo`` but not in self
190190
191191 Returns
192 ``GitPython.Commit[]``
192 ``git.Commit[]``
193193 """
194194 repo_refs = self.git.rev_list(ref).strip().splitlines()
195195 other_repo_refs = other_repo.git.rev_list(other_ref).strip().splitlines()
196196
197197 diff_refs = list(set(other_repo_refs) - set(repo_refs))
198 return map(lambda ref: Commit.find_all(other_repo, ref, **{'max_count': 1}[0]), diff_refs)
199
200 def tree(self, treeish = 'master', paths = []):
198 return map(lambda ref: Commit.find_all(other_repo, ref, max_count=1)[0], diff_refs)
199
200 def tree(self, treeish = 'master'):
201201 """
202202 The Tree object for the given treeish reference
203203
204204 ``treeish``
205205 is the reference (default 'master')
206 ``paths``
207 is an optional Array of directory paths to restrict the tree (default [])
208206
209207 Examples::
210208
211 repo.tree('master', ['lib/'])
212
213
214 Returns
215 ``GitPython.Tree``
216 """
217 return Tree.construct(self, treeish, paths)
209 repo.tree('master')
210
211
212 Returns
213 ``git.Tree``
214 """
215 return Tree(self, id=treeish)
218216
219217 def blob(self, id):
220218 """
224222 is the SHA1 id of the blob
225223
226224 Returns
227 ``GitPython.Blob``
228 """
229 return Blob(self, **{'id': id})
225 ``git.Blob``
226 """
227 return Blob(self, id=id)
230228
231229 def log(self, commit = 'master', path = None, **kwargs):
232230 """
233231 The commit log for a treeish
234232
235233 Returns
236 ``GitPython.Commit[]``
234 ``git.Commit[]``
237235 """
238236 options = {'pretty': 'raw'}
239237 options.update(kwargs)
264262 ``commit`` is the commit name/id
265263
266264 Returns
267 ``GitPython.Diff[]``
265 ``git.Diff[]``
268266 """
269267 return Commit.diff(self, commit)
270268
285283
286284 Examples::
287285
288 GitPython.Repo.init_bare('/var/git/myrepo.git')
289
290 Returns
291 ``GitPython.Repo`` (the newly created repo)
286 git.Repo.init_bare('/var/git/myrepo.git')
287
288 Returns
289 ``git.Repo`` (the newly created repo)
292290 """
293291
294292 if mkdir and not os.path.exists(path):
295293 os.makedirs(path, 0755)
296294
297295 git = Git(path)
298 output = git.init(**kwargs)
296 output = git.init('--bare', **kwargs)
299297 return Repo(path)
300298 create = init_bare
301299
310308 is any additional options to the git clone command
311309
312310 Returns
313 ``GitPython.Repo`` (the newly forked repo)
311 ``git.Repo`` (the newly forked repo)
314312 """
315313 options = {'bare': True}
316314 options.update(kwargs)
375373 kwargs['prefix'] = prefix
376374 self.git.archive(treeish, "| gzip", **kwargs)
377375
378 def enable_daemon_serve(self):
379 """
380 Enable git-daemon serving of this repository by writing the
381 git-daemon-export-ok file to its git directory
382
383 Returns
384 None
385 """
386 touch(os.path.join(self.path, DAEMON_EXPORT_FILE))
387
388 def disable_daemon_serve(self):
389 """
390 Disable git-daemon serving of this repository by ensuring there is no
391 git-daemon-export-ok file in its git directory
392
393 Returns
394 None
395 """
396 return os.remove(os.path.join(self.path, DAEMON_EXPORT_FILE))
376 def _get_daemon_export(self):
377 filename = os.path.join(self.path, self.DAEMON_EXPORT_FILE)
378 return os.path.exists(filename)
379
380 def _set_daemon_export(self, value):
381 filename = os.path.join(self.path, self.DAEMON_EXPORT_FILE)
382 fileexists = os.path.exists(filename)
383 if value and not fileexists:
384 touch(filename)
385 elif not value and fileexists:
386 os.unlink(filename)
387
388 daemon_export = property(_get_daemon_export, _set_daemon_export,
389 doc="git-daemon export of this repository")
390 del _get_daemon_export
391 del _set_daemon_export
397392
398393 def _get_alternates(self):
399394 """
402397 Returns
403398 list[str] (pathnames of alternates)
404399 """
405 alternates_path = os.path.join(self.path, *['objects', 'info', 'alternates'])
400 alternates_path = os.path.join(self.path, 'objects', 'info', 'alternates')
406401
407402 if os.path.exists(alternates_path):
408403 try:
429424 raise NoSuchPathError("Could not set alternates. Alternate path %s must exist" % alt)
430425
431426 if not alts:
432 os.remove(os.path.join(self.path, *['objects', 'info', 'alternates']))
427 os.remove(os.path.join(self.path, 'objects', 'info', 'alternates'))
433428 else:
434429 try:
435 f = open(os.path.join(self.path, *['objects', 'info', 'alternates']), 'w')
430 f = open(os.path.join(self.path, 'objects', 'info', 'alternates'), 'w')
436431 f.write("\n".join(alts))
437432 finally:
438433 f.close()
439434
440435 alternates = property(_get_alternates, _set_alternates)
441436
437 @property
438 def is_dirty(self):
439 """
440 Return the status of the working directory.
441
442 Returns
443 ``True``, if the working directory has any uncommitted changes,
444 otherwise ``False``
445
446 """
447 if self.bare:
448 # Bare repositories with no associated working directory are
449 # always consired to be clean.
450 return False
451
452 return len(self.git.diff('HEAD').strip()) > 0
453
454 @property
455 def active_branch(self):
456 """
457 The name of the currently active branch.
458
459 Returns
460 str (the branch name)
461 """
462 branch = self.git.symbolic_ref('HEAD').strip()
463 if branch.startswith('refs/heads/'):
464 branch = branch[len('refs/heads/'):]
465
466 return branch
467
442468 def __repr__(self):
443 return '<GitPython.Repo "%s">' % self.path
469 return '<git.Repo "%s">' % self.path
1717 is the Commit that the head points to
1818
1919 Returns
20 ``GitPython.Tag``
20 ``git.Tag``
2121 """
2222 self.name = name
2323 self.commit = commit
3434 is a dict of options
3535
3636 Returns
37 ``GitPython.Tag[]``
37 ``git.Tag[]``
3838 """
3939 options = {'sort': "committerdate",
4040 'format': "%(refname)%00%(objectname)"}
5555 is the text output from the git command
5656
5757 Returns
58 ``GitPython.Tag[]``
58 ``git.Tag[]``
5959 """
6060 tags = []
6161 for line in text.splitlines():
7979 id: [0-9A-Fa-f]{40}
8080
8181 Returns
82 ``GitPython.Tag``
82 ``git.Tag``
8383 """
8484 full_name, ids = line.split("\x00")
8585 name = full_name.split("/")[-1]
86 commit = Commit(repo, **{'id': ids})
86 commit = Commit(repo, id=ids)
8787 return Tag(name, commit)
8888
8989 def __repr__(self):
90 return '<GitPython.Tag "%s">' % self.name
90 return '<git.Tag "%s">' % self.name
88 import blob
99
1010 class Tree(LazyMixin):
11 def __init__(self, repo, **kwargs):
11 def __init__(self, repo, id, mode=None, name=None):
1212 LazyMixin.__init__(self)
1313 self.repo = repo
14 self.id = None
15 self.mode = None
16 self.name = None
17 self.contents = None
18
19 for k, v in kwargs.items():
20 setattr(self, k, v)
14 self.id = id
15 self.mode = mode
16 self.name = name
17 self._contents = None
2118
2219 def __bake__(self):
23 temp = Tree.construct(self.repo, self.id)
24 self.contents = temp.contents
20 # Ensure the treeish references directly a tree
21 treeish = self.id
22 if not treeish.endswith(':'):
23 treeish = treeish + ':'
2524
26 @classmethod
27 def construct(cls, repo, treeish, paths = []):
28 output = repo.git.ls_tree(treeish, *paths)
29 return Tree(repo, **{'id': treeish}).construct_initialize(repo, treeish, output)
25 # Read the tree contents.
26 self._contents = {}
27 for line in self.repo.git.ls_tree(self.id).splitlines():
28 obj = self.content_from_string(self.repo, line)
29 if obj is not None:
30 self._contents[obj.name] = obj
3031
31 def construct_initialize(self, repo, id, text):
32 self.repo = repo
33 self.id = id
34 self.contents = []
35 self.__baked__ = False
36
37 for line in text.splitlines():
38 self.contents.append(self.content_from_string(self.repo, line))
39
40 self.contents = [c for c in self.contents if c is not None]
41
42 self.__bake_it__()
43 return self
44
45 def content_from_string(self, repo, text):
32 @staticmethod
33 def content_from_string(repo, text):
4634 """
4735 Parse a content item and create the appropriate object
4836
5341 is the single line containing the items data in `git ls-tree` format
5442
5543 Returns
56 ``GitPython.Blob`` or ``GitPython.Tree``
44 ``git.Blob`` or ``git.Tree``
5745 """
5846 try:
5947 mode, typ, id, name = text.expandtabs(1).split(" ", 4)
6149 return None
6250
6351 if typ == "tree":
64 return Tree(repo, **{'id': id, 'mode': mode, 'name': name})
52 return Tree(repo, id=id, mode=mode, name=name)
6553 elif typ == "blob":
66 return blob.Blob(repo, **{'id': id, 'mode': mode, 'name': name})
54 return blob.Blob(repo, id=id, mode=mode, name=name)
6755 elif typ == "commit":
6856 return None
6957 else:
7664 Examples::
7765
7866 >>> Repo('/path/to/python-git').tree/'lib'
79 <GitPython.Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
67 <git.Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
8068 >>> Repo('/path/to/python-git').tree/'README.txt'
81 <GitPython.Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
69 <git.Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
8270
8371 Returns
84 ``GitPython.Blob`` or ``GitPython.Tree`` or ``None`` if not found
72 ``git.Blob`` or ``git.Tree`` or ``None`` if not found
8573 """
86 contents = [c for c in self.contents if c.name == file]
87 return contents and contents[0] or None
74 return self.get(file)
8875
8976 @property
9077 def basename(self):
9178 os.path.basename(self.name)
9279
9380 def __repr__(self):
94 return '<GitPython.Tree "%s">' % self.id
81 return '<git.Tree "%s">' % self.id
82
83 # Implement the basics of the dict protocol:
84 # directories/trees can be seen as object dicts.
85 def __getitem__(self, key):
86 return self._contents[key]
87
88 def __iter__(self):
89 return iter(self._contents)
90
91 def __len__(self):
92 return len(self._contents)
93
94 def __contains__(self, key):
95 return key in self._contents
96
97 def get(self, key):
98 return self._contents.get(key)
99
100 def items(self):
101 return self._contents.items()
102
103 def keys(self):
104 return self._contents.keys()
105
106 def values(self):
107 return self._contents.values()
0 from ez_setup import use_setuptools
1 use_setuptools()
2 from setuptools import setup, find_packages
0 try:
1 from setuptools import setup, find_packages
2 except ImportError:
3 from ez_setup import use_setuptools
4 use_setuptools()
5 from setuptools import setup, find_packages
6
37 from distutils.command.build_py import build_py as _build_py
48 from setuptools.command.sdist import sdist as _sdist
59 import os