annotate git_handler.py @ 68:d28d3763eda3

Deal with hg authors missing email attributes.
author Chris Wanstrath <chris@ozmm.org>
date Thu, 30 Apr 2009 12:46:54 -0700 (2009-04-30)
parents 5ed8316d3cfa
children 983c2792f8d8
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()
56
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
116 refs = self.fetch_pack(remote_name)
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
117 if refs:
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
118 self.import_git_objects(remote_name)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
119 self.save_map()
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
120
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
121 def push(self, remote_name):
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
122 self.ui.status(_("pushing to : " + remote_name + "\n"))
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
123 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
124 self.update_references()
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
125 self.upload_pack(remote_name)
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
126 self.save_map()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
127
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
128 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
129 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
130 self.save_config()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
131
39
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
132 def remote_remove(self, remote_name):
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
133 key = 'remote.' + remote_name + '.url'
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
134 if key in self._config:
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
135 del self._config[key]
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
136 self.save_config()
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
137
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
138 def remote_show(self, remote_name):
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
139 key = 'remote.' + remote_name + '.url'
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
140 if key in self._config:
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
141 name = self._config[key]
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
142 self.ui.status("URL for %s : %s\n" % (remote_name, name, ))
39
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
143 else:
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
144 self.ui.status("No remote named : %s\n" % remote_name)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
145 return
39
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
146
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
147 def remote_list(self):
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
148 for key, value in self._config.iteritems():
173e738d0da4 remote management tools
Scott Chacon <schacon@gmail.com>
parents: 38
diff changeset
149 if key[0:6] == 'remote':
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
150 self.ui.status('%s\t%s\n' % (key, value, ))
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
151
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
152 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
153 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
154
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
155 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
156 # 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
157 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
158 self.git.set_ref('refs/heads/master', c)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
159
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
160 def export_git_objects(self):
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
161 self.ui.status("exporting git objects\n")
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
162 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
163 self.export_hg_commit(rev)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
164
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
165 # 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
166 # 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
167 # 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
168 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
169 # return if we've already processed this
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
170 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
171 phgsha = hex(node)
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
172 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
173 if pgit_sha:
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
174 return pgit_sha
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
175
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
176 self.ui.status("converting revision " + str(rev) + "\n")
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
177
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
178 # 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
179 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
180 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
181 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
182 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
183 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
184 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
185 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
186 self.export_hg_commit(p_rev)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
187
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
188 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
189 tree_sha = self.write_git_tree(ctx)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
190
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
191 # 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
192 # TODO : explicit file renaming, copying?
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
193
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
194 commit = {}
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
195 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
196 (time, timezone) = ctx.date()
68
d28d3763eda3 Deal with hg authors missing email attributes.
Chris Wanstrath <chris@ozmm.org>
parents: 65
diff changeset
197
d28d3763eda3 Deal with hg authors missing email attributes.
Chris Wanstrath <chris@ozmm.org>
parents: 65
diff changeset
198 # hg authors might not have emails
d28d3763eda3 Deal with hg authors missing email attributes.
Chris Wanstrath <chris@ozmm.org>
parents: 65
diff changeset
199 author = ctx.user()
d28d3763eda3 Deal with hg authors missing email attributes.
Chris Wanstrath <chris@ozmm.org>
parents: 65
diff changeset
200 if not '>' in author:
d28d3763eda3 Deal with hg authors missing email attributes.
Chris Wanstrath <chris@ozmm.org>
parents: 65
diff changeset
201 author = author + ' <none@none>'
d28d3763eda3 Deal with hg authors missing email attributes.
Chris Wanstrath <chris@ozmm.org>
parents: 65
diff changeset
202 commit['author'] = author + ' ' + 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
203 message = ctx.description()
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
204 commit['message'] = ctx.description()
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
205
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
206 # 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
207 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
208 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
209 add_extras = True
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
210
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
211 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
212 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
213 commit['message'] += "branch : " + ctx.branch() + "\n"
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
214
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
215 commit['parents'] = []
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
216 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
217 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
218 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
219 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
220 commit['parents'].append(git_sha)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
221
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
222 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
223 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
224 return commit_sha
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
225
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
226 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
227 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
228 man = ctx.manifest()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
229 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
230 # 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
231 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
232 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
233 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
234 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
235 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
236 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
237 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
238 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
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 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
241 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
242 # 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
243 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
244 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
245
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
246 # 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
247 parpath = '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
248 nparpath = '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
249 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
250 if nparpath == '/':
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
251 nparpath = part + '/'
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
252 else:
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
253 nparpath += part + '/'
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
254
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
255 treeentry = ['tree', part + '/', nparpath]
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
256
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
257 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
258 trees[parpath] = []
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
259 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
260 trees[parpath].append( treeentry )
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
261
54
f6e11b9d7562 not adding HG extra info if commits were on the default branch
Scott Chacon <schacon@gmail.com>
parents: 53
diff changeset
262 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
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 # 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
265 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
266 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
267 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
268 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
269
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 else:
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
271 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
272 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
273 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
274 trees['/'].append(fileentry)
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
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 # 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
277 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
278 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
279 dirs.remove('/')
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
280 dirs.append('/')
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
281
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
282 # 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
283 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
284 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
285 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
286 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
287 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
288 # 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
289 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
290 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
291 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
292 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
293 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
294 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
295 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
296
13
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
297 def remote_head(self, remote_name):
01f28d40cb6a checks out the HEAD node from a clone
Scott Chacon <schacon@gmail.com>
parents: 12
diff changeset
298 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
299 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
300 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
301 return None
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
302
17
ace0f6ed65a1 setting up for upload-pack functionality
Scott Chacon <schacon@gmail.com>
parents: 16
diff changeset
303 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
304 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
305 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
306 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
307 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
308 try:
52
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
309 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
310 changed_refs = client.send_pack(path, changed, genpack)
52
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
311 if changed_refs:
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
312 new_refs = {}
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
313 for old, new, ref in changed_refs:
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
314 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
315 new_refs[ref] = new
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
316 self.git.set_remote_refs(new_refs, remote_name)
87d462a6b796 pushing nothing works better
Scott Chacon <schacon@gmail.com>
parents: 51
diff changeset
317 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
318 except:
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
319 raise
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
320
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
321 # 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
322 # * 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
323 # 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
324 # pushed up
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
325 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
326 keys = refs.keys()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
327
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
328 changed = []
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
329 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
330 return None
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
331
42
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
332 # TODO : this is a huge hack
fcfb4db848e1 added hack for pushing first branch
Scott Chacon <schacon@gmail.com>
parents: 40
diff changeset
333 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
334 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
335
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
336 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
337 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
338 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
339 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
340 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
341 local_ref = self.git.ref(ref_name)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
342 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
343 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
344 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
345 return changed
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
346
37
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
347 # 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
348 # 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
349 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
350 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
351 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
352 shas = []
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
353 while next:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
354 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
355 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
356 else:
7046d792dfcd fix bug where it was not writing the git object names properly
Scott Chacon <schacon@gmail.com>
parents: 35
diff changeset
357 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
358 next = graph_walker.next()
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
359
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
360 # 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
361 # 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
362 # 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
363 def get_objects(tree, path):
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
364 changes = list()
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
365 changes.append((tree, path))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
366 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
367 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
368 continue
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
369 obj = self.git.get_object(sha)
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
370 if isinstance (obj, Blob):
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
371 changes.append((obj, path + name))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
372 elif isinstance(obj, Tree):
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
373 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
374 return changes
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
375
38
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
376 objects = []
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
377 for commit_sha in shas:
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
378 commit = self.git.commit(commit_sha)
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
379 objects.append((commit, 'commit'))
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
380 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
381 objects.extend( get_objects(tree, '/') )
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
382
38
f0daee676e10 successful push to an upstream git server - BOOYAH!
Scott Chacon <schacon@gmail.com>
parents: 37
diff changeset
383 return objects
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
384
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
385 def fetch_pack(self, remote_name):
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
386 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
387 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
388 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
389 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
390 try:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
391 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
392 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
393 f.close()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
394 commit()
56
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
395 if refs:
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
396 self.git.set_remote_refs(refs, remote_name)
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
397 else:
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
398 self.ui.status(_("nothing new on the server\n"))
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
399 return refs
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
400 except:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
401 f.close()
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
402 raise
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
403
12
227b11d75844 updates bookmarks and beginnings of seperate remotes support
Scott Chacon <schacon@gmail.com>
parents: 11
diff changeset
404 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
405 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
406 # import heads as remote references
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
407 todo = []
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
408 done = set()
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
409 convert_list = {}
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
410
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
411 # 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
412 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
413 todo.append(sha)
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
414
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
415 # 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
416 # 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
417 while todo:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
418 sha = todo.pop()
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
419 assert isinstance(sha, str)
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
420 if sha in done:
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
421 continue
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
422 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
423 try:
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
424 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
425 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
426 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
427 except:
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
428 self.ui.warn("Cannot import tags yet\n") # TODO
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
429
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
430 # sort the commits
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
431 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
432
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
433 # import each of the commits, oldest first
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
434 for csha in commits:
56
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
435 if not self.map_hg_get(csha):
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
436 commit = convert_list[csha]
5185af4e649a hg gfetch now works
Scott Chacon <schacon@gmail.com>
parents: 54
diff changeset
437 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
438
47
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
439 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
440
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
441 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
442 try:
47
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
443 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
444 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
445 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
446 if not head == 'HEAD':
3b62270c1fad writing some status output after a push, updating local bookmarks
Scott Chacon <schacon@gmail.com>
parents: 42
diff changeset
447 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
448 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
449 except AttributeError:
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
450 self.ui.warn('creating bookmarks failed, do you have'
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
451 ' bookmarks enabled?\n')
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
452
53
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
453 def convert_git_int_mode(self, mode):
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
454 convert = {
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
455 33188: '',
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
456 40960: 'l',
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
457 33261: 'e'}
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
458 if mode in convert:
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
459 return convert[mode]
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
460 return ''
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
461
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
462 def import_git_commit(self, commit):
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
463 self.ui.debug("importing: %s\n" % commit.id)
24
41f4e0a85d15 fully converts hg changeset/manifest/files to git commits/trees/blobs
Scott Chacon <schacon@gmail.com>
parents: 23
diff changeset
464 # 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
465 # 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
466
10
66860f141788 update todo file and removed outdated TODO comments
Scott Chacon <schacon@gmail.com>
parents: 9
diff changeset
467 # 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
468 # 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
469 # get_file call for removed files
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
470 def getfilectx(repo, memctx, f):
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
471 try:
53
5deb5cbd86aa respecting file modes on git import
Scott Chacon <schacon@gmail.com>
parents: 52
diff changeset
472 (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
473 e = self.convert_git_int_mode(mode)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
474 except TypeError:
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
475 raise IOError()
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
476 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
477
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
478 p1 = "0" * 40
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
479 p2 = "0" * 40
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
480 if len(commit.parents) > 0:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
481 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
482 p1 = self.map_hg_get(sha)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
483 if len(commit.parents) > 1:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
484 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
485 p2 = self.map_hg_get(sha)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
486 if len(commit.parents) > 2:
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
487 # TODO : map extra parents to the extras file
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
488 pass
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
489
8
2548735d24ef will now more or less correctly determine a changelist from a git commit
Scott Chacon <schacon@gmail.com>
parents: 7
diff changeset
490 files = self.git.get_files_changed(commit)
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
491
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
492 # get a list of the changed, added, removed files
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
493 extra = {}
6
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
494 text = commit.message
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
495 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
496 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
497 commit.author, date, extra)
c77197123d95 importing basic, mostly stubbed changesets
Scott Chacon <schacon@gmail.com>
parents: 5
diff changeset
498 a = self.repo.commitctx(ctx)
7
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
499
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
500 # get changeset id
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
501 p2 = hex(self.repo.changelog.tip())
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
502 # save changeset to mapping file
89992b6d2eef mapping parents properly now
Scott Chacon <schacon@gmail.com>
parents: 6
diff changeset
503 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
504 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
505
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
506 def check_bookmarks(self):
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
507 if self.ui.config('extensions', 'hgext.bookmarks') is not None:
65
5ed8316d3cfa Start using reasonable ui.{status,debug,warn} calls instead of print.
Augie Fackler <durin42@gmail.com>
parents: 56
diff changeset
508 self.ui.warn("YOU NEED TO SETUP BOOKMARKS\n")
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
509
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
510 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
511 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
512 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
513 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
514 if handler == 'git@':
28
b258ef16ae37 Fix non-ssh URI parsing.
Augie Fackler <durin42@gmail.com>
parents: 26
diff changeset
515 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
516 host = 'git@' + host
28
b258ef16ae37 Fix non-ssh URI parsing.
Augie Fackler <durin42@gmail.com>
parents: 26
diff changeset
517 else:
35
562fc51b991e we did the same thing, not sure why it conflicted
Scott Chacon <schacon@gmail.com>
parents: 29
diff changeset
518 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
519 return transport(host), '/' + path
5
d6c443a91b18 refactored the git handling stuff out into another class
Scott Chacon <schacon@gmail.com>
parents:
diff changeset
520 # 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
521 return SubprocessGitClient(), uri
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
522
40
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
523 def clear(self):
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
524 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
525 mapfile = self.repo.join('git-mapfile')
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
526 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
527 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
528 for name in files:
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
529 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
530 for name in dirs:
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
531 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
532 os.rmdir(git_dir)
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
533 if os.path.exists(mapfile):
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
534 os.remove(mapfile)
50
d274092e3b24 Hacky implementation of file removals.
Augie Fackler <durin42@gmail.com>
parents: 42
diff changeset
535
40
f5b000ec7100 added gclear command to remove all the git data
Scott Chacon <schacon@gmail.com>
parents: 39
diff changeset
536
26
a1a5391bc3c3 edit ssh command to quote the path, also convert tags properly on fetch
Scott Chacon <schacon@gmail.com>
parents: 25
diff changeset
537 ''
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
538 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
539 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
540 by Paul Harrison
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
541 Public domain, do with it as you will
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
542 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
543 class TopoSort(object):
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
544
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
545 def __init__(self, commitdict):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
546 self._sorted = self.robust_topological_sort(commitdict)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
547 self._shas = []
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
548 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
549 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
550 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
551
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
552 def items(self):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
553 self._shas.reverse()
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
554 return self._shas
19
2be9c0bd88af Warn, but don't fail when bookmarks is not enabled.
Augie Fackler <durin42@gmail.com>
parents: 17
diff changeset
555
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
556 def strongly_connected_components(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
557 """ 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
558 Tarjan's algorithm.
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
559
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
560 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
561 lists of successor nodes.
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
562 """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
563
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
564 result = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
565 stack = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
566 low = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
567
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
568 def visit(node):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
569 if node in low: return
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
570
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
571 num = len(low)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
572 low[node] = num
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
573 stack_pos = len(stack)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
574 stack.append(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
575
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
576 for successor in graph[node].parents:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
577 visit(successor)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
578 low[node] = min(low[node], low[successor])
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 if num == low[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
581 component = tuple(stack[stack_pos:])
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
582 del stack[stack_pos:]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
583 result.append(component)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
584 for item in component:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
585 low[item] = len(graph)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
586
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 visit(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
589
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
590 return result
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
591
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 def topological_sort(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
594 count = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
595 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
596 count[node] = 0
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
597 for node in graph:
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
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
601 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
602
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
603 result = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
604 while ready:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
605 node = ready.pop(-1)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
606 result.append(node)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
607
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
608 for successor in graph[node]:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
609 count[successor] -= 1
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
610 if count[successor] == 0:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
611 ready.append(successor)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
612
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
613 return result
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
614
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
615
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
616 def robust_topological_sort(self, graph):
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
617 """ First identify strongly connected components,
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
618 then perform a topological sort on these components. """
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
619
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
620 components = self.strongly_connected_components(graph)
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
621
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
622 node_component = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
623 for component in components:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
624 for node in component:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
625 node_component[node] = component
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
626
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
627 component_graph = { }
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
628 for component in components:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
629 component_graph[component] = [ ]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
630
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
631 for node in graph:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
632 node_c = node_component[node]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
633 for successor in graph[node].parents:
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
634 successor_c = node_component[successor]
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
635 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
636 component_graph[node_c].append(successor_c)
9
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
637
7e776864b301 sorts the commits topologically before converting
Scott Chacon <schacon@gmail.com>
parents: 8
diff changeset
638 return self.topological_sort(component_graph)