4d237f715cc1d628ebb5e2348d9e6702a90148dc
[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 os
21 import sys
22 from getopt import getopt
23
24 from dulwich.client import get_transport_and_path
25 from dulwich.errors import ApplyDeltaError
26 from dulwich.index import Index
27 from dulwich.pack import Pack, sha_to_hex
28 from dulwich.repo import Repo
29
30
31 def cmd_fetch_pack(args):
32     opts, args = getopt(args, "", ["all"])
33     opts = dict(opts)
34     client, path = get_transport_and_path(args.pop(0))
35     r = Repo(".")
36     if "--all" in opts:
37         determine_wants = r.object_store.determine_wants_all
38     else:
39         determine_wants = lambda x: [y for y in args if not y in r.object_store]
40     graphwalker = r.get_graph_walker()
41     client.fetch(path, r.object_store, determine_wants)
42
43
44 def cmd_log(args):
45     opts, args = getopt(args, "", [])
46     if len(args) > 0:
47         path = args.pop(0)
48     else:
49         path = "."
50     r = Repo(path)
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[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
74     opts, args = getopt(args, "", [])
75
76     if args == []:
77         print "Usage: dulwich dump-pack FILENAME"
78         sys.exit(1)
79
80     basename, _ = os.path.splitext(args[0])
81     x = Pack(basename)
82     print "Object names checksum: %s" % x.name()
83     print "Checksum: %s" % sha_to_hex(x.get_stored_checksum())
84     if not x.check():
85         print "CHECKSUM DOES NOT MATCH"
86     print "Length: %d" % len(x)
87     for name in x:
88         try:
89             print "\t%s" % x[name]
90         except KeyError, k:
91             print "\t%s: Unable to resolve base %s" % (name, k)
92         except ApplyDeltaError, e:
93             print "\t%s: Unable to apply delta: %r" % (name, e)
94
95
96 def cmd_dump_index(args):
97
98     opts, args = getopt(args, "", [])
99
100     if args == []:
101         print "Usage: dulwich dump-index FILENAME"
102         sys.exit(1)
103
104     filename = args[0]
105     idx = Index(filename)
106
107     for o in idx:
108         print o, idx[o]
109
110
111 def cmd_init(args):
112     opts, args = getopt(args, "", ["--bare"])
113     opts = dict(opts)
114
115     if args == []:
116         path = os.getcwd()
117     else:
118         path = args[0]
119
120     if not os.path.exists(path):
121         os.mkdir(path)
122
123     if "--bare" in opts:
124         Repo.init_bare(path)
125     else:
126         Repo.init(path)
127
128
129 def cmd_clone(args):
130     opts, args = getopt(args, "", [])
131     opts = dict(opts)
132
133     if args == []:
134         print "usage: dulwich clone host:path [PATH]"
135         sys.exit(1)
136     client, host_path = get_transport_and_path(args.pop(0))
137
138     if len(args) > 0:
139         path = args.pop(0)
140     else:
141         path = host_path.split("/")[-1]
142
143     if not os.path.exists(path):
144         os.mkdir(path)
145     r = Repo.init(path)
146     remote_refs = client.fetch(host_path, r,
147         determine_wants=r.object_store.determine_wants_all,
148         progress=sys.stdout.write)
149     r["HEAD"] = remote_refs["HEAD"]
150
151
152 def cmd_commit(args):
153     opts, args = getopt(args, "", ["message"])
154     opts = dict(opts)
155     r = Repo(".")
156     committer = "%s <%s>" % (os.getenv("GIT_COMMITTER_NAME"), 
157                              os.getenv("GIT_COMMITTER_EMAIL"))
158     author = "%s <%s>" % (os.getenv("GIT_AUTHOR_NAME"), 
159                           os.getenv("GIT_AUTHOR_EMAIL"))
160     r.do_commit(committer=committer, author=author, message=opts["--message"])
161
162 commands = {
163     "commit": cmd_commit,
164     "fetch-pack": cmd_fetch_pack,
165     "dump-pack": cmd_dump_pack,
166     "dump-index": cmd_dump_index,
167     "init": cmd_init,
168     "log": cmd_log,
169     "clone": cmd_clone,
170     }
171
172 if len(sys.argv) < 2:
173     print "Usage: %s <%s> [OPTIONS...]" % (sys.argv[0], "|".join(commands.keys()))
174     sys.exit(1)
175
176 cmd = sys.argv[1]
177 if not cmd in commands:
178     print "No such subcommand: %s" % cmd
179     sys.exit(1)
180 commands[cmd](sys.argv[2:])