annotate git_handler.py @ 13:01f28d40cb6a

checks out the HEAD node from a clone
author Scott Chacon <schacon@gmail.com>
date Sun, 26 Apr 2009 15:51:05 -0700
parents 227b11d75844
children 36e94e805fa7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
1 import os, errno, sys, time, datetime, pickle, copy
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
2 import dulwich
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
3 from dulwich.repo import Repo
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
4 from dulwich.client import SimpleFetchGraphWalker
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
5 from dulwich.objects import hex_to_sha
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
6 from hgext import bookmarks
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
7 from mercurial.i18n import _
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
8 from mercurial.node import bin, hex, nullid
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
9 from mercurial import hg, util, context, error
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
10
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
11 class GitHandler(object):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
12
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
13 def __init__(self, dest_repo, ui):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
14 self.repo = dest_repo
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
15 self.ui = ui
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
16 self.load_git()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
17 self.load_map()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
18
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
19 def load_git(self):
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
20 git_dir = os.path.join(self.repo.path, 'git')
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
21 self.git = Repo(git_dir)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
22
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
23 def load_map(self):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
24 self._map = {}
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
25 if os.path.exists(self.repo.join('git-mapfile')):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
26 for line in self.repo.opener('git-mapfile'):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
27 gitsha, hgsha = line.strip().split(' ', 1)
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
28 self._map[gitsha] = hgsha
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
29
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
30 def save_map(self):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
31 file = self.repo.opener('git-mapfile', 'w+')
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
32 for gitsha, hgsha in self._map.iteritems():
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
33 file.write("%s %s\n" % (gitsha, hgsha))
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
34 file.close()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
35
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
36 def fetch(self, remote_name):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
37 self.ui.status(_("fetching from : " + remote_name + "\n"))
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
38 self.export_git_objects()
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
39 self.fetch_pack(remote_name)
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
40 self.import_git_objects(remote_name)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
41 self.save_map()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
42
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
43 # TODO: make these actually save and recall
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
44 def remote_add(self, remote_name, git_url):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
45 self._git_url = git_url
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
46
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
47 def remote_name_to_url(self, remote_name):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
48 return self._git_url
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
49
13
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
50 def remote_head(self, remote_name):
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
51 for head, sha in self.git.remote_refs(remote_name).iteritems():
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
52 if head == 'HEAD':
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
53 return self._map[sha]
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
54 return None
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
55
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
56 def fetch_pack(self, remote_name):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
57 git_url = self.remote_name_to_url(remote_name)
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
58 client, path = self.get_transport_and_path(git_url)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
59 graphwalker = SimpleFetchGraphWalker(self.git.heads().values(), self.git.get_parents)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
60 f, commit = self.git.object_store.add_pack()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
61 try:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
62 determine_wants = self.git.object_store.determine_wants_all
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
63 refs = client.fetch_pack(path, determine_wants, graphwalker, f.write, sys.stdout.write)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
64 f.close()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
65 commit()
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
66 self.git.set_remote_refs(refs, remote_name)
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
67 except:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
68 f.close()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
69 raise
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
70
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
71 def import_git_objects(self, remote_name):
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
72 self.ui.status(_("importing Git objects into Hg\n"))
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
73 # import heads as remote references
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
74 todo = []
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
75 done = set()
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
76 convert_list = {}
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
77
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
78 # get a list of all the head shas
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
79 for head, sha in self.git.remote_refs(remote_name).iteritems():
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
80 todo.append(sha)
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
81
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
82 # traverse the heads getting a list of all the unique commits
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
83 # TODO : stop when we hit a SHA we've already imported
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
84 while todo:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
85 sha = todo.pop()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
86 assert isinstance(sha, str)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
87 if sha in done:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
88 continue
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
89 done.add(sha)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
90 commit = self.git.commit(sha)
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
91 convert_list[sha] = commit
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
92 todo.extend([p for p in commit.parents if p not in done])
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
93
10
66860f141788 update todo file and removed outdated TODO comments
Scott Chacon <schacon@gmail.com>
parents: 9
diff changeset
94 # sort the commits
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
95 commits = TopoSort(convert_list).items()
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
96
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
97 # import each of the commits, oldest first
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
98 for csha in commits:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
99 commit = convert_list[csha]
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
100 self.import_git_commit(commit)
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
101
13
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
102 # update Hg bookmarks
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
103 bms = {}
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
104 for head, sha in self.git.remote_refs(remote_name).iteritems():
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
105 hgsha = hex_to_sha(self._map[sha])
13
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
106 if not head == 'HEAD':
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
107 bms[remote_name + '/' + head] = hgsha
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
108 bookmarks.write(self.repo, bms)
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
109
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
110 def import_git_commit(self, commit):
8
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
111 print "importing: " + commit.id
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
112
10
66860f141788 update todo file and removed outdated TODO comments
Scott Chacon <schacon@gmail.com>
parents: 9
diff changeset
113 # TODO : (?) have to handle merge contexts at some point (two parent files, etc)
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
114 def getfilectx(repo, memctx, f):
8
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
115 (e, sha, data) = self.git.get_file(commit, f)
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
116 e = '' # TODO : make this a real mode
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
117 return context.memfilectx(f, data, 'l' in e, 'x' in e, None)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
118
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
119 p1 = "0" * 40
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
120 p2 = "0" * 40
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
121 if len(commit.parents) > 0:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
122 sha = commit.parents[0]
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
123 p1 = self._map[sha]
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
124 if len(commit.parents) > 1:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
125 sha = commit.parents[1]
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
126 p2 = self._map[sha]
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
127 if len(commit.parents) > 2:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
128 # TODO : map extra parents to the extras file
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
129 pass
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
130
8
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
131 files = self.git.get_files_changed(commit)
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
132 #print files
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
133
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
134 # get a list of the changed, added, removed files
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
135 extra = {}
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
136 text = commit.message
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
137 date = datetime.datetime.fromtimestamp(commit.author_time).strftime("%Y-%m-%d %H:%M:%S")
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
138 ctx = context.memctx(self.repo, (p1, p2), text, files, getfilectx,
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
139 commit.author, date, extra)
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
140 a = self.repo.commitctx(ctx)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
141
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
142 # get changeset id
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
143 p2 = hex(self.repo.changelog.tip())
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
144 # save changeset to mapping file
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
145 gitsha = commit.id
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
146 self._map[gitsha] = p2
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
147
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
148 def getfilectx(self, source, repo, memctx, f):
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
149 v = files[f]
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
150 data = source.getfile(f, v)
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
151 e = source.getmode(f, v)
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
152 return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
153
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
154 def export_git_objects(self):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
155 pass
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
156
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
157 def check_bookmarks(self):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
158 if self.ui.config('extensions', 'hgext.bookmarks') is not None:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
159 print "YOU NEED TO SETUP BOOKMARKS"
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
160
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
161 def get_transport_and_path(self, uri):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
162 from dulwich.client import TCPGitClient, SSHGitClient, SubprocessGitClient
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
163 for handler, transport in (("git://", TCPGitClient), ("git+ssh://", SSHGitClient)):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
164 if uri.startswith(handler):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
165 host, path = uri[len(handler):].split("/", 1)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
166 return transport(host), "/"+path
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
167 # if its not git or git+ssh, try a local url..
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
168 return SubprocessGitClient(), uri
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
169
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
170
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
171 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
172 Tarjan's algorithm and topological sorting implementation in Python
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
173 by Paul Harrison
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
174 Public domain, do with it as you will
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
175 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
176 class TopoSort(object):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
177
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
178 def __init__(self, commitdict):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
179 self._sorted = self.robust_topological_sort(commitdict)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
180 self._shas = []
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
181 for level in self._sorted:
11
f2826f7b1ae5 sped up large imports significantly by caching parsed trees and sha_to_hexes
Scott Chacon <schacon@gmail.com>
parents: 10
diff changeset
182 for sha in level:
f2826f7b1ae5 sped up large imports significantly by caching parsed trees and sha_to_hexes
Scott Chacon <schacon@gmail.com>
parents: 10
diff changeset
183 self._shas.append(sha)
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
184
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
185 def items(self):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
186 self._shas.reverse()
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
187 return self._shas
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
188
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
189 def strongly_connected_components(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
190 """ Find the strongly connected components in a graph using
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
191 Tarjan's algorithm.
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
192
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
193 graph should be a dictionary mapping node names to
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
194 lists of successor nodes.
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
195 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
196
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
197 result = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
198 stack = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
199 low = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
200
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
201 def visit(node):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
202 if node in low: return
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
203
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
204 num = len(low)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
205 low[node] = num
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
206 stack_pos = len(stack)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
207 stack.append(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
208
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
209 for successor in graph[node].parents:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
210 visit(successor)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
211 low[node] = min(low[node], low[successor])
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
212
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
213 if num == low[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
214 component = tuple(stack[stack_pos:])
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
215 del stack[stack_pos:]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
216 result.append(component)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
217 for item in component:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
218 low[item] = len(graph)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
219
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
220 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
221 visit(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
222
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
223 return result
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
224
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
225
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
226 def topological_sort(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
227 count = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
228 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
229 count[node] = 0
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
230 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
231 for successor in graph[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
232 count[successor] += 1
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
233
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
234 ready = [ node for node in graph if count[node] == 0 ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
235
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
236 result = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
237 while ready:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
238 node = ready.pop(-1)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
239 result.append(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
240
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
241 for successor in graph[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
242 count[successor] -= 1
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
243 if count[successor] == 0:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
244 ready.append(successor)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
245
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
246 return result
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
247
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
248
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
249 def robust_topological_sort(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
250 """ First identify strongly connected components,
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
251 then perform a topological sort on these components. """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
252
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
253 components = self.strongly_connected_components(graph)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
254
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
255 node_component = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
256 for component in components:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
257 for node in component:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
258 node_component[node] = component
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
259
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
260 component_graph = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
261 for component in components:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
262 component_graph[component] = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
263
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
264 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
265 node_c = node_component[node]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
266 for successor in graph[node].parents:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
267 successor_c = node_component[successor]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
268 if node_c != successor_c:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
269 component_graph[node_c].append(successor_c)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
270
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
271 return self.topological_sort(component_graph)