Skip ^{} tags.
[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.client import SimpleFetchGraphWalker
35         from dulwich.repo import Repo
36         opts, args = getopt(args, "", ["all"])
37         opts = dict(opts)
38         client, path = get_transport_and_path(args.pop(0))
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         r = Repo(".")
44         graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
45         f, commit = r.object_store.add_pack()
46         try:
47                 client.fetch_pack(path, determine_wants, graphwalker, f.write, sys.stdout.write)
48                 f.close()
49                 commit()
50         except:
51                 f.close()
52                 raise
53
54
55 def cmd_log(args):
56         from dulwich.repo import Repo
57         opts, args = getopt(args, "", [])
58         r = Repo(".")
59         todo = [r.head()]
60         done = set()
61         while todo:
62                 sha = todo.pop()
63                 assert isinstance(sha, str)
64                 if sha in done:
65                         continue
66                 done.add(sha)
67                 commit = r.commit(sha)
68                 print "-" * 50
69                 print "commit: %s" % sha
70                 if len(commit.parents) > 1:
71                         print "merge: %s" % "...".join(commit.parents[1:])
72                 print "author: %s" % commit.author
73                 print "committer: %s" % commit.committer
74                 print ""
75                 print commit.message
76                 print ""
77                 todo.extend([p for p in commit.parents if p not in done])
78
79
80 def cmd_dump_pack(args):
81         from dulwich.errors import ApplyDeltaError
82         from dulwich.pack import Pack, sha_to_hex
83         import os
84         import sys
85
86         opts, args = getopt(args, "", [])
87
88         if args == []:
89                 print "Usage: dulwich dump-pack FILENAME"
90                 sys.exit(1)
91
92         basename, _ = os.path.splitext(args[0])
93         x = Pack(basename)
94         print "Object names checksum: %s" % x.name()
95         print "Checksum: %s" % sha_to_hex(x.get_stored_checksum())
96         if not x.check():
97                 print "CHECKSUM DOES NOT MATCH"
98         print "Length: %d" % len(x)
99         for name in x:
100                 try:
101                         print "\t%s" % x[name]
102                 except KeyError, k:
103                         print "\t%s: Unable to resolve base %s" % (name, k)
104                 except ApplyDeltaError, e:
105                         print "\t%s: Unable to apply delta: %r" % (name, e)
106
107
108 def cmd_dump_index(args):
109         from dulwich.index import Index
110
111         opts, args = getopt(args, "", [])
112
113         if args == []:
114                 print "Usage: dulwich dump-pack FILENAME"
115                 sys.exit(1)
116
117         filename = args[0]
118         idx = Index(filename)
119
120         for o in idx:
121                 print o[0]
122
123
124 def cmd_init(args):
125         from dulwich.repo import Repo
126         import os
127         import sys
128         opts, args = getopt(args, "", ["--bare"])
129         opts = dict(opts)
130
131         if args == []:
132                 path = os.getcwd()
133         else:
134                 path = args[0]
135
136         if not os.path.exists(path):
137                 os.mkdir(path)
138
139         if "--bare" in opts:
140                 Repo.init_bare(path)
141         else:
142                 Repo.init(path)
143
144
145 def cmd_clone(args):
146         from dulwich.client import SimpleFetchGraphWalker
147         from dulwich.repo import Repo
148         import os
149         import sys
150         opts, args = getopt(args, "", [])
151         opts = dict(opts)
152
153         if args == []:
154                 print "usage: dulwich clone host:path [PATH]"
155                 sys.exit(1)
156         client, host_path = get_transport_and_path(args.pop(0))
157
158         if len(args) > 0:
159                 path = args.pop(0)
160         else:
161                 path = host_path.split("/")[-1]
162
163         if not os.path.exists(path):
164                 os.mkdir(path)
165         Repo.init(path)
166         r = Repo(path)
167         graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
168         f, commit = r.object_store.add_pack()
169         try:
170                 client.fetch_pack(host_path, r.object_store.determine_wants_all, graphwalker, f.write, 
171                                           sys.stdout.write)
172                 f.close()
173                 commit()
174         except:
175                 f.close()
176                 raise
177
178
179 commands = {
180         "fetch-pack": cmd_fetch_pack,
181         "dump-pack": cmd_dump_pack,
182         "dump-index": cmd_dump_index,
183         "init": cmd_init,
184         "log": cmd_log,
185         "clone": cmd_clone,
186         }
187
188 if len(sys.argv) < 2:
189         print "Usage: %s <%s> [OPTIONS...]" % (sys.argv[0], "|".join(commands.keys()))
190         sys.exit(1)
191
192 cmd = sys.argv[1]
193 if not cmd in commands:
194         print "No such subcommand: %s" % cmd
195         sys.exit(1)
196 commands[cmd](sys.argv[2:])