annotate git_handler.py @ 54:f6e11b9d7562

not adding HG extra info if commits were on the default branch have successfully tested an hg -> git -> hg lossless conversion of several commits. boom.
author Scott Chacon <schacon@gmail.com>
date Wed, 29 Apr 2009 13:26:13 -0700
parents 5deb5cbd86aa
children 5185af4e649a
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
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
5 from hgext import bookmarks
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
6 from mercurial.i18n import _
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
7 from mercurial.node import bin, hex, nullid
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
8 from mercurial import hg, util, context, error
38
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
9 from dulwich.objects import (
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
10 Blob,
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
11 Commit,
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
12 ShaFile,
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
13 Tag,
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
14 Tree,
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
15 hex_to_sha
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
16 )
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
17
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
18 import math
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
19
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
20 def seconds_to_offset(time):
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
21 hours = (float(time) / 60 / 60)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
22 hour_diff = math.fmod(time, 60)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
23 minutes = int(hour_diff)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
24 hours = int(math.floor(hours))
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
25 if hours > 12:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
26 sign = '+'
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
27 hours = 12 - (hours - 12)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
28 else:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
29 sign = '-'
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
30 return sign + str(hours).rjust(2, '0') + str(minutes).rjust(2, '0')
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
31
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
32 def offset_to_seconds(offset):
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
33 if len(offset) == 5:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
34 sign = offset[0:1]
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
35 hours = int(offset[1:3])
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
36 minutes = int(offset[3:5])
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
37 if sign == '+':
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
38 hours = 12 + (12 - hours)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
39 return (hours * 60 * 60) + (minutes) * 60
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
40 else:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
41 return 0
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
42
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
43 class GitHandler(object):
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
44
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
45 def __init__(self, dest_repo, ui):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
46 self.repo = dest_repo
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
47 self.ui = ui
16
58cd05129119 moved init into git_handler
Scott Chacon <schacon@gmail.com>
parents: 14
diff changeset
48 self.init_if_missing()
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
49 self.load_git()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
50 self.load_map()
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
51 self.load_config()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
52
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
53 # make the git data directory
16
58cd05129119 moved init into git_handler
Scott Chacon <schacon@gmail.com>
parents: 14
diff changeset
54 def init_if_missing(self):
58cd05129119 moved init into git_handler
Scott Chacon <schacon@gmail.com>
parents: 14
diff changeset
55 git_hg_path = os.path.join(self.repo.path, 'git')
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
56 if not os.path.exists(git_hg_path):
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
57 os.mkdir(git_hg_path)
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
58 dulwich.repo.Repo.init_bare(git_hg_path)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
59
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
60 def load_git(self):
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
61 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
62 self.git = Repo(git_dir)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
63
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
64 ## FILE LOAD AND SAVE METHODS
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
65
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
66 def map_set(self, gitsha, hgsha):
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
67 self._map_git[gitsha] = hgsha
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
68 self._map_hg[hgsha] = gitsha
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
69
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
70 def map_hg_get(self, gitsha):
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
71 if gitsha in self._map_git:
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
72 return self._map_git[gitsha]
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
73 else:
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
74 return None
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
75
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
76 def map_git_get(self, hgsha):
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
77 if hgsha in self._map_hg:
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
78 return self._map_hg[hgsha]
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
79 else:
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
80 return None
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
81
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
82 def load_map(self):
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
83 self._map_git = {}
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
84 self._map_hg = {}
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
85 if os.path.exists(self.repo.join('git-mapfile')):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
86 for line in self.repo.opener('git-mapfile'):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
87 gitsha, hgsha = line.strip().split(' ', 1)
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
88 self._map_git[gitsha] = hgsha
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
89 self._map_hg[hgsha] = gitsha
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
90
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
91 def save_map(self):
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
92 file = self.repo.opener('git-mapfile', 'w+')
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
93 for gitsha, hgsha in self._map_git.iteritems():
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
94 file.write("%s %s\n" % (gitsha, hgsha))
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
95 file.close()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
96
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
97 def load_config(self):
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
98 self._config = {}
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
99 if os.path.exists(self.repo.join('git-config')):
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
100 for line in self.repo.opener('git-config'):
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
101 key, value = line.strip().split(' ', 1)
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
102 self._config[key] = value
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
103
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
104 def save_config(self):
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
105 file = self.repo.opener('git-config', 'w+')
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
106 for key, value in self._config.iteritems():
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
107 file.write("%s %s\n" % (key, value))
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
108 file.close()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
109
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
110
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
111 ## END FILE LOAD AND SAVE METHODS
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
112
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
113 def fetch(self, remote_name):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
114 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
115 self.export_git_objects()
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
116 self.fetch_pack(remote_name)
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
117 self.import_git_objects(remote_name)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
118 self.save_map()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
119
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
120 def push(self, remote_name):
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
121 self.ui.status(_("pushing to : " + remote_name + "\n"))
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
122 self.export_git_objects()
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
123 self.update_references()
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
124 self.upload_pack(remote_name)
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
125 self.save_map()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
126
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
127 def remote_add(self, remote_name, git_url):
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
128 self._config['remote.' + remote_name + '.url'] = git_url
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
129 self.save_config()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
130
39
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
131 def remote_remove(self, remote_name):
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
132 key = 'remote.' + remote_name + '.url'
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
133 if key in self._config:
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
134 del self._config[key]
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
135 self.save_config()
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
136
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
137 def remote_show(self, remote_name):
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
138 key = 'remote.' + remote_name + '.url'
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
139 if key in self._config:
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
140 name = self._config[key]
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
141 print "URL for " + remote_name + " : " + name
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
142 else:
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
143 print "No remote named : " + remote_name
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
144 return
39
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
145
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
146 def remote_list(self):
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
147 for key, value in self._config.iteritems():
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
148 if key[0:6] == 'remote':
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
149 print key + "\t" + value
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
150
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
151 def remote_name_to_url(self, remote_name):
14
36e94e805fa7 added basic config file for remembering remote urls
Scott Chacon <schacon@gmail.com>
parents: 13
diff changeset
152 return self._config['remote.' + remote_name + '.url']
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
153
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
154 def update_references(self):
25
88e9e9e1caf1 will now set the current tip() as your git 'master' branch for packfile upload
Scott Chacon <schacon@gmail.com>
parents: 24
diff changeset
155 # TODO : if bookmarks exist, add them as git branches
88e9e9e1caf1 will now set the current tip() as your git 'master' branch for packfile upload
Scott Chacon <schacon@gmail.com>
parents: 24
diff changeset
156 c = self.map_git_get(hex(self.repo.changelog.tip()))
88e9e9e1caf1 will now set the current tip() as your git 'master' branch for packfile upload
Scott Chacon <schacon@gmail.com>
parents: 24
diff changeset
157 self.git.set_ref('refs/heads/master', c)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
158
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
159 def export_git_objects(self):
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
160 print "exporting git objects"
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
161 for rev in self.repo.changelog:
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
162 self.export_hg_commit(rev)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
163
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
164 # convert this commit into git objects
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
165 # go through the manifest, convert all blobs/trees we don't have
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
166 # write the commit object (with metadata info)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
167 def export_hg_commit(self, rev):
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
168 # return if we've already processed this
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
169 node = self.repo.changelog.lookup(rev)
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
170 phgsha = hex(node)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
171 pgit_sha = self.map_git_get(phgsha)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
172 if pgit_sha:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
173 return pgit_sha
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
174
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
175 self.ui.status("converting revision " + str(rev) + "\n")
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
176
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
177 # make sure parents are converted first
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
178 parents = self.repo.parents(rev)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
179 for parent in parents:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
180 p_rev = parent.rev()
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
181 hgsha = hex(parent.node())
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
182 git_sha = self.map_git_get(hgsha)
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
183 if not p_rev == -1:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
184 if not git_sha:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
185 self.export_hg_commit(p_rev)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
186
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
187 ctx = self.repo.changectx(rev)
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
188 tree_sha = self.write_git_tree(ctx)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
189
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
190 # TODO : something with tags?
25
88e9e9e1caf1 will now set the current tip() as your git 'master' branch for packfile upload
Scott Chacon <schacon@gmail.com>
parents: 24
diff changeset
191 # TODO : explicit file renaming, copying?
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
192
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
193 commit = {}
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
194 commit['tree'] = tree_sha
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
195 (time, timezone) = ctx.date()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
196 commit['author'] = ctx.user() + ' ' + str(int(time)) + ' ' + seconds_to_offset(timezone)
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
197 message = ctx.description()
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
198 commit['message'] = ctx.description()
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
199
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
200 # HG EXTRA INFORMATION
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
201 add_extras = False
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
202 if not ctx.branch() == 'default':
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
203 add_extras = True
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
204
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
205 if add_extras:
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
206 commit['message'] += "\n\n--HG--\n"
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
207 commit['message'] += "branch : " + ctx.branch() + "\n"
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
208
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
209 commit['parents'] = []
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
210 for parent in parents:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
211 hgsha = hex(parent.node())
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
212 git_sha = self.map_git_get(hgsha)
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
213 if git_sha:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
214 commit['parents'].append(git_sha)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
215
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
216 commit_sha = self.git.write_commit_hash(commit) # writing new blobs to git
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
217 self.map_set(commit_sha, phgsha)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
218 return commit_sha
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
219
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
220 def write_git_tree(self, ctx):
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
221 trees = {}
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
222 man = ctx.manifest()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
223 for filenm in man.keys():
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
224 # write blob if not in our git database
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
225 fctx = ctx.filectx(filenm)
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
226 is_exec = 'x' in fctx.flags()
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
227 is_link = 'l' in fctx.flags()
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
228 file_id = hex(fctx.filenode())
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
229 blob_sha = self.map_git_get(file_id)
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
230 if not blob_sha:
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
231 blob_sha = self.git.write_blob(fctx.data()) # writing new blobs to git
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
232 self.map_set(blob_sha, file_id)
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
233
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
234 parts = filenm.split('/')
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
235 if len(parts) > 1:
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
236 # get filename and path for leading subdir
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
237 filepath = parts[-1:][0]
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
238 dirpath = "/".join([v for v in parts[0:-1]]) + '/'
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
239
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
240 # get subdir name and path for parent dir
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
241 parpath = '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
242 nparpath = '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
243 for part in parts[0:-1]:
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
244 if nparpath == '/':
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
245 nparpath = part + '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
246 else:
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
247 nparpath += part + '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
248
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
249 treeentry = ['tree', part + '/', nparpath]
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
250
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
251 if parpath not in trees:
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
252 trees[parpath] = []
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
253 if treeentry not in trees[parpath]:
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
254 trees[parpath].append( treeentry )
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
255
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
256 parpath = nparpath
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
257
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
258 # set file entry
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
259 fileentry = ['blob', filepath, blob_sha, is_exec, is_link]
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
260 if dirpath not in trees:
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
261 trees[dirpath] = []
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
262 trees[dirpath].append(fileentry)
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
263
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
264 else:
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
265 fileentry = ['blob', parts[0], blob_sha, is_exec, is_link]
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
266 if '/' not in trees:
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
267 trees['/'] = []
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
268 trees['/'].append(fileentry)
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
269
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
270 # sort by tree depth, so we write the deepest trees first
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
271 dirs = trees.keys()
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
272 dirs.sort(lambda a, b: len(b.split('/'))-len(a.split('/')))
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
273 dirs.remove('/')
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
274 dirs.append('/')
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
275
23
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
276 # write all the trees
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
277 tree_sha = None
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
278 tree_shas = {}
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
279 for dirnm in dirs:
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
280 tree_data = []
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
281 for entry in trees[dirnm]:
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
282 # replace tree path with tree SHA
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
283 if entry[0] == 'tree':
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
284 sha = tree_shas[entry[2]]
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
285 entry[2] = sha
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
286 tree_data.append(entry)
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
287 tree_sha = self.git.write_tree_array(tree_data) # writing new trees to git
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
288 tree_shas[dirnm] = tree_sha
ee217d3c6363 will now write all trees and blobs needed. all thats left is commits for basic data conversion
Scott Chacon <schacon@gmail.com>
parents: 22
diff changeset
289 return tree_sha # should be the last root tree sha
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
290
13
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
291 def remote_head(self, remote_name):
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
292 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
293 if head == 'HEAD':
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
294 return self.map_hg_get(sha)
13
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
295 return None
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
296
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
297 def upload_pack(self, remote_name):
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
298 git_url = self.remote_name_to_url(remote_name)
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
299 client, path = self.get_transport_and_path(git_url)
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
300 changed = self.get_changed_refs
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
301 genpack = self.generate_pack_contents
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
302 try:
52
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
303 self.ui.status("creating and sending data\n")
47
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
304 changed_refs = client.send_pack(path, changed, genpack)
52
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
305 if changed_refs:
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
306 new_refs = {}
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
307 for old, new, ref in changed_refs:
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
308 self.ui.status(" "+ remote_name + "::" + ref + " : GIT:" + old[0:8] + " => GIT:" + new[0:8] + "\n")
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
309 new_refs[ref] = new
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
310 self.git.set_remote_refs(new_refs, remote_name)
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
311 self.update_hg_bookmarks(remote_name)
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
312 except:
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
313 raise
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
314
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
315 # TODO : for now, we'll just push all heads that match remote heads
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
316 # * we should have specified push, tracking branches and --all
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
317 # takes a dict of refs:shas from the server and returns what should be
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
318 # pushed up
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
319 def get_changed_refs(self, refs):
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
320 keys = refs.keys()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
321
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
322 changed = []
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
323 if not keys:
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
324 return None
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
325
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
326 # TODO : this is a huge hack
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
327 if keys[0] == 'capabilities^{}': # nothing on the server yet - first push
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
328 changed.append(("0"*40, self.git.ref('master'), 'refs/heads/master'))
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
329
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
330 for ref_name in keys:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
331 parts = ref_name.split('/')
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
332 if parts[0] == 'refs': # strip off 'refs/heads'
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
333 if parts[1] == 'heads':
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
334 head = "/".join([v for v in parts[2:]])
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
335 local_ref = self.git.ref(ref_name)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
336 if local_ref:
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
337 if not local_ref == refs[ref_name]:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
338 changed.append((refs[ref_name], local_ref, ref_name))
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
339 return changed
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
340
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
341 # takes a list of shas the server wants and shas the server has
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
342 # and generates a list of commit shas we need to push up
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
343 def generate_pack_contents(self, want, have):
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
344 graph_walker = SimpleFetchGraphWalker(want, self.git.get_parents)
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
345 next = graph_walker.next()
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
346 shas = []
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
347 while next:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
348 if next in have:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
349 graph_walker.ack(next)
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
350 else:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
351 shas.append(next)
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
352 next = graph_walker.next()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
353
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
354 # so now i have the shas, need to turn them into a list of
38
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
355 # tuples (sha, path) for ALL the objects i'm sending
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
356 # TODO : don't send blobs or trees they already have
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
357 def get_objects(tree, path):
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
358 changes = list()
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
359 changes.append((tree, path))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
360 for (mode, name, sha) in tree.entries():
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
361 if mode == 57344: # TODO : properly handle submodules
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
362 continue
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
363 obj = self.git.get_object(sha)
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
364 if isinstance (obj, Blob):
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
365 changes.append((obj, path + name))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
366 elif isinstance(obj, Tree):
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
367 changes.extend (get_objects (obj, path + name + '/'))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
368 return changes
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
369
38
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
370 objects = []
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
371 for commit_sha in shas:
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
372 commit = self.git.commit(commit_sha)
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
373 objects.append((commit, 'commit'))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
374 tree = self.git.get_object(commit.tree)
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
375 objects.extend( get_objects(tree, '/') )
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
376
38
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
377 return objects
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
378
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
379 def fetch_pack(self, remote_name):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
380 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
381 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
382 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
383 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
384 try:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
385 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
386 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
387 f.close()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
388 commit()
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
389 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
390 except:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
391 f.close()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
392 raise
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
393
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
394 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
395 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
396 # import heads as remote references
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
397 todo = []
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
398 done = set()
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
399 convert_list = {}
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
400
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
401 # 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
402 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
403 todo.append(sha)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
404
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
405 # 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
406 # 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
407 while todo:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
408 sha = todo.pop()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
409 assert isinstance(sha, str)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
410 if sha in done:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
411 continue
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
412 done.add(sha)
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
413 try:
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
414 commit = self.git.commit(sha)
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
415 convert_list[sha] = commit
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
416 todo.extend([p for p in commit.parents if p not in done])
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
417 except:
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
418 print "Cannot import tags yet" # TODO
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
419
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
420 # sort the commits
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
421 commits = TopoSort(convert_list).items()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
422
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
423 # import each of the commits, oldest first
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
424 for csha in commits:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
425 commit = convert_list[csha]
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
426 self.import_git_commit(commit)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
427
47
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
428 self.update_hg_bookmarks(remote_name)
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
429
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
430 def update_hg_bookmarks(self, remote_name):
29
2a5c0bf0fef5 Another way of fixing no-bookmark issue, along with updated test.
Augie Fackler <durin42@gmail.com>
parents: 28
diff changeset
431 try:
47
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
432 bms = bookmarks.parse(self.repo)
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
433 for head, sha in self.git.remote_refs(remote_name).iteritems():
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
434 hgsha = hex_to_sha(self.map_hg_get(sha))
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
435 if not head == 'HEAD':
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
436 bms[remote_name + '/' + head] = hgsha
29
2a5c0bf0fef5 Another way of fixing no-bookmark issue, along with updated test.
Augie Fackler <durin42@gmail.com>
parents: 28
diff changeset
437 bookmarks.write(self.repo, bms)
2a5c0bf0fef5 Another way of fixing no-bookmark issue, along with updated test.
Augie Fackler <durin42@gmail.com>
parents: 28
diff changeset
438 except AttributeError:
2a5c0bf0fef5 Another way of fixing no-bookmark issue, along with updated test.
Augie Fackler <durin42@gmail.com>
parents: 28
diff changeset
439 self.repo.ui.warn('creating bookmarks failed, do you have'
2a5c0bf0fef5 Another way of fixing no-bookmark issue, along with updated test.
Augie Fackler <durin42@gmail.com>
parents: 28
diff changeset
440 ' bookmarks enabled?\n')
53
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
441
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
442 def convert_git_int_mode(self, mode):
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
443 convert = {
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
444 33188: '',
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
445 40960: 'l',
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
446 33261: 'e'}
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
447 if mode in convert:
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
448 return convert[mode]
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
449 return ''
47
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
450
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
451 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
452 print "importing: " + commit.id
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
453 # TODO : look for HG metadata in the message and use it
35
562fc51b991e we did the same thing, not sure why it conflicted
Scott Chacon <schacon@gmail.com>
parents: 29
diff changeset
454 # TODO : add extra Git data (committer info) as extras to changeset
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
455
10
66860f141788 update todo file and removed outdated TODO comments
Scott Chacon <schacon@gmail.com>
parents: 9
diff changeset
456 # TODO : (?) have to handle merge contexts at some point (two parent files, etc)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
457 # TODO : Do something less coarse-grained than try/except on the
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
458 # get_file call for removed files
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
459 def getfilectx(repo, memctx, f):
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
460 try:
53
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
461 (mode, sha, data) = self.git.get_file(commit, f)
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
462 e = self.convert_git_int_mode(mode)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
463 except TypeError:
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
464 raise IOError()
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
465 return context.memfilectx(f, data, 'l' in e, 'x' in e, None)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
466
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
467 p1 = "0" * 40
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
468 p2 = "0" * 40
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
469 if len(commit.parents) > 0:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
470 sha = commit.parents[0]
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
471 p1 = self.map_hg_get(sha)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
472 if len(commit.parents) > 1:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
473 sha = commit.parents[1]
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
474 p2 = self.map_hg_get(sha)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
475 if len(commit.parents) > 2:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
476 # TODO : map extra parents to the extras file
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
477 pass
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
478
8
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
479 files = self.git.get_files_changed(commit)
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
480 #print files
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
481
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
482 # get a list of the changed, added, removed files
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
483 extra = {}
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
484 text = commit.message
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
485 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
486 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
487 commit.author, date, extra)
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
488 a = self.repo.commitctx(ctx)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
489
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
490 # get changeset id
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
491 p2 = hex(self.repo.changelog.tip())
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
492 # save changeset to mapping file
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
493 gitsha = commit.id
21
13b9a020e382 gpush coming along. will now write blobs it doesn't have yet to git repo.
Scott Chacon <schacon@gmail.com>
parents: 19
diff changeset
494 self.map_set(gitsha, p2)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
495
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
496 def check_bookmarks(self):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
497 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
498 print "YOU NEED TO SETUP BOOKMARKS"
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
499
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
500 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
501 from dulwich.client import TCPGitClient, SSHGitClient, SubprocessGitClient
35
562fc51b991e we did the same thing, not sure why it conflicted
Scott Chacon <schacon@gmail.com>
parents: 29
diff changeset
502 for handler, transport in (("git://", TCPGitClient), ("git@", SSHGitClient), ("git+ssh://", SSHGitClient)):
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
503 if uri.startswith(handler):
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
504 if handler == 'git@':
28
b258ef16ae37 Fix non-ssh URI parsing.
Augie Fackler <durin42@gmail.com>
parents: 26
diff changeset
505 host, path = uri[len(handler):].split(":", 1)
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
506 host = 'git@' + host
28
b258ef16ae37 Fix non-ssh URI parsing.
Augie Fackler <durin42@gmail.com>
parents: 26
diff changeset
507 else:
35
562fc51b991e we did the same thing, not sure why it conflicted
Scott Chacon <schacon@gmail.com>
parents: 29
diff changeset
508 host, path = uri[len(handler):].split("/", 1)
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
509 return transport(host), '/' + path
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
510 # 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
511 return SubprocessGitClient(), uri
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
512
40
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
513 def clear(self):
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
514 git_dir = self.repo.join('git')
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
515 mapfile = self.repo.join('git-mapfile')
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
516 if os.path.exists(git_dir):
40
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
517 for root, dirs, files in os.walk(git_dir, topdown=False):
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
518 for name in files:
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
519 os.remove(os.path.join(root, name))
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
520 for name in dirs:
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
521 os.rmdir(os.path.join(root, name))
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
522 os.rmdir(git_dir)
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
523 if os.path.exists(mapfile):
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
524 os.remove(mapfile)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
525
40
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
526
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
527 ''
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
528 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
529 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
530 by Paul Harrison
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
531 Public domain, do with it as you will
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
532 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
533 class TopoSort(object):
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
534
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
535 def __init__(self, commitdict):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
536 self._sorted = self.robust_topological_sort(commitdict)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
537 self._shas = []
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
538 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
539 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
540 self._shas.append(sha)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
541
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
542 def items(self):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
543 self._shas.reverse()
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
544 return self._shas
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
545
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
546 def strongly_connected_components(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
547 """ 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
548 Tarjan's algorithm.
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
549
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
550 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
551 lists of successor nodes.
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
552 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
553
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
554 result = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
555 stack = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
556 low = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
557
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
558 def visit(node):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
559 if node in low: return
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
560
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
561 num = len(low)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
562 low[node] = num
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
563 stack_pos = len(stack)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
564 stack.append(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
565
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
566 for successor in graph[node].parents:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
567 visit(successor)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
568 low[node] = min(low[node], low[successor])
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
569
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
570 if num == low[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
571 component = tuple(stack[stack_pos:])
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
572 del stack[stack_pos:]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
573 result.append(component)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
574 for item in component:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
575 low[item] = len(graph)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
576
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
577 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
578 visit(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
579
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
580 return result
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
581
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
582
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
583 def topological_sort(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
584 count = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
585 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
586 count[node] = 0
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
587 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
588 for successor in graph[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
589 count[successor] += 1
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
590
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
591 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
592
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
593 result = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
594 while ready:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
595 node = ready.pop(-1)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
596 result.append(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
597
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
598 for successor in graph[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
599 count[successor] -= 1
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
600 if count[successor] == 0:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
601 ready.append(successor)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
602
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
603 return result
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
604
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
605
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
606 def robust_topological_sort(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
607 """ First identify strongly connected components,
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
608 then perform a topological sort on these components. """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
609
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
610 components = self.strongly_connected_components(graph)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
611
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
612 node_component = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
613 for component in components:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
614 for node in component:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
615 node_component[node] = component
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
616
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
617 component_graph = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
618 for component in components:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
619 component_graph[component] = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
620
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
621 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
622 node_c = node_component[node]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
623 for successor in graph[node].parents:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
624 successor_c = node_component[successor]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
625 if node_c != successor_c:
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
626 component_graph[node_c].append(successor_c)
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
627
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
628 return self.topological_sort(component_graph)