annotate git_handler.py @ 51:1421d04f1ad2

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