Delay checking size until it's actually used.
[jelmer/dulwich-libgit2.git] / bin / dulwich
1 #!/usr/bin/python
2 # dul-daemon - Simple git smart server client
3 # Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
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 # or (at your option) a later version 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
20 import sys
21 from getopt import getopt
22
23 def get_transport_and_path(uri):
24     from dulwich.client import TCPGitClient, SSHGitClient, SubprocessGitClient
25     for handler, transport in (("git://", TCPGitClient), ("git+ssh://", SSHGitClient)):
26         if uri.startswith(handler):
27             host, path = uri[len(handler):].split("/", 1)
28             return transport(host), "/"+path
29     # if its not git or git+ssh, try a local url..
30     return SubprocessGitClient(), uri
31
32
33 def cmd_fetch_pack(args):
34     from dulwich.repo import Repo
35     opts, args = getopt(args, "", ["all"])
36     opts = dict(opts)
37     client, path = get_transport_and_path(args.pop(0))
38     r = Repo(".")
39     if "--all" in opts:
40         determine_wants = r.object_store.determine_wants_all
41     else:
42         determine_wants = lambda x: [y for y in args if not y in r.object_store]
43     graphwalker = r.get_graph_walker()
44     client.fetch(path, r.object_store, determine_wants)
45
46
47 def cmd_log(args):
48     from dulwich.repo import Repo
49     opts, args = getopt(args, "", [])
50     r = Repo(".")
51     todo = [r.head()]
52     done = set()
53     while todo:
54         sha = todo.pop()
55         assert isinstance(sha, str)
56         if sha in done:
57             continue
58         done.add(sha)
59         commit = r.commit(sha)
60         print "-" * 50
61         print "commit: %s" % sha
62         if len(commit.parents) > 1:
63             print "merge: %s" % "...".join(commit.parents[1:])
64         print "author: %s" % commit.author
65         print "committer: %s" % commit.committer
66         print ""
67         print commit.message
68         print ""
69         todo.extend([p for p in commit.parents if p not in done])
70
71
72 def cmd_dump_pack(args):
73     from dulwich.errors import ApplyDeltaError
74     from dulwich.pack import Pack, sha_to_hex
75     import os
76     import sys
77
78     opts, args = getopt(args, "", [])
79
80     if args == []:
81         print "Usage: dulwich dump-pack FILENAME"
82         sys.exit(1)
83
84     basename, _ = os.path.splitext(args[0])
85     x = Pack(basename)
86     print "Object names checksum: %s" % x.name()
87     print "Checksum: %s" % sha_to_hex(x.get_stored_checksum())
88     if not x.check():
89         print "CHECKSUM DOES NOT MATCH"
90     print "Length: %d" % len(x)
91     for name in x:
92         try:
93             print "\t%s" % x[name]
94         except KeyError, k:
95             print "\t%s: Unable to resolve base %s" % (name, k)
96         except ApplyDeltaError, e:
97             print "\t%s: Unable to apply delta: %r" % (name, e)
98
99
100 def cmd_dump_index(args):
101     from dulwich.index import Index
102
103     opts, args = getopt(args, "", [])
104
105     if args == []:
106         print "Usage: dulwich dump-index FILENAME"
107         sys.exit(1)
108
109     filename = args[0]
110     idx = Index(filename)
111
112     for o in idx:
113         print o, idx[o]
114
115
116 def cmd_init(args):
117     from dulwich.repo import Repo
118     import os
119     opts, args = getopt(args, "", ["--bare"])
120     opts = dict(opts)
121
122     if args == []:
123         path = os.getcwd()
124     else:
125         path = args[0]
126
127     if not os.path.exists(path):
128         os.mkdir(path)
129
130     if "--bare" in opts:
131         Repo.init_bare(path)
132     else:
133         Repo.init(path)
134
135
136 def cmd_clone(args):
137     from dulwich.repo import Repo
138     import os
139     import sys
140     opts, args = getopt(args, "", [])
141     opts = dict(opts)
142
143     if args == []:
144         print "usage: dulwich clone host:path [PATH]"
145         sys.exit(1)
146         client, host_path = get_transport_and_path(args.pop(0))
147
148     if len(args) > 0:
149         path = args.pop(0)
150     else:
151         path = host_path.split("/")[-1]
152
153     if not os.path.exists(path):
154         os.mkdir(path)
155     Repo.init(path)
156     r = Repo(path)
157     graphwalker = r.get_graph_walker()
158     f, commit = r.object_store.add_pack()
159     client.fetch_pack(host_path, r.object_store.determine_wants_all, 
160                       graphwalker, f.write, sys.stdout.write)
161     commit()
162
163
164 def cmd_commit(args):
165     from dulwich.repo import Repo
166     import os
167     opts, args = getopt(args, "", ["message"])
168     opts = dict(opts)
169     r = Repo(".")
170     committer = "%s <%s>" % (os.getenv("GIT_COMMITTER_NAME"), 
171                              os.getenv("GIT_COMMITTER_EMAIL"))
172     author = "%s <%s>" % (os.getenv("GIT_AUTHOR_NAME"), 
173                           os.getenv("GIT_AUTHOR_EMAIL"))
174     r.do_commit(committer=committer, author=author, message=opts["--message"])
175
176 commands = {
177     "commit": cmd_commit,
178     "fetch-pack": cmd_fetch_pack,
179     "dump-pack": cmd_dump_pack,
180     "dump-index": cmd_dump_index,
181     "init": cmd_init,
182     "log": cmd_log,
183     "clone": cmd_clone,
184     }
185
186 if len(sys.argv) < 2:
187     print "Usage: %s <%s> [OPTIONS...]" % (sys.argv[0], "|".join(commands.keys()))
188     sys.exit(1)
189
190 cmd = sys.argv[1]
191 if not cmd in commands:
192     print "No such subcommand: %s" % cmd
193     sys.exit(1)
194 commands[cmd](sys.argv[2:])