mirror of
https://github.com/openSUSE/osc.git
synced 2024-12-27 18:26:15 +01:00
- reimplement 'osc pull' so that iw works like intended, i.e. still works if the link is broken
This commit is contained in:
parent
60c3b45194
commit
0cb7afbfdf
@ -4389,16 +4389,102 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
raise oscerr.WrongArgs('osc pull only works on linked packages.')
|
raise oscerr.WrongArgs('osc pull only works on linked packages.')
|
||||||
elif not p.isexpanded():
|
elif not p.isexpanded():
|
||||||
raise oscerr.WrongArgs('osc pull only works on expanded links.')
|
raise oscerr.WrongArgs('osc pull only works on expanded links.')
|
||||||
|
linkinfo = p.linkinfo
|
||||||
|
baserev = linkinfo.baserev
|
||||||
|
if baserev == None:
|
||||||
|
raise oscerr.WrongArgs('osc pull only works on links containing a base revision.')
|
||||||
|
|
||||||
# hack
|
# get revisions we need
|
||||||
conf.config['linkcontrol'] = 0
|
query = { 'expand': 1, 'emptylink': 1 }
|
||||||
# do the update
|
u = makeurl(p.apiurl, ['source', p.prjname, p.name], query=query)
|
||||||
pulledrev=p.latest_rev()
|
f = http_GET(u)
|
||||||
if pulledrev == p.rev:
|
meta = f.readlines()
|
||||||
raise oscerr.WrongArgs('Already up-to-date.')
|
root_new = ET.fromstring(''.join(meta))
|
||||||
p.update(rev=pulledrev)
|
linkinfo_new = root_new.find('linkinfo')
|
||||||
store_write_string(p.absdir, '_pulled', '')
|
if linkinfo_new == None:
|
||||||
|
raise oscerr.APIError('link is not a really a link?')
|
||||||
|
if linkinfo_new.get('error') != None:
|
||||||
|
raise oscerr.APIError('link target is broken')
|
||||||
|
if linkinfo_new.get('srcmd5') == baserev:
|
||||||
|
print "Already up-to-date."
|
||||||
|
return
|
||||||
|
dir_new = { 'apiurl': p.apiurl, 'project': p.prjname, 'package': p.name }
|
||||||
|
dir_new['srcmd5'] = root_new.get('srcmd5')
|
||||||
|
dir_new['entries'] = [[n.get('name'), n.get('md5')] for n in root_new.findall('entry')]
|
||||||
|
|
||||||
|
dir_oldpatched = { 'apiurl': p.apiurl, 'project': p.prjname, 'package': p.name, 'srcmd5': p.srcmd5 }
|
||||||
|
dir_oldpatched['entries'] = map(lambda f: [f.name, f.md5], p.filelist)
|
||||||
|
|
||||||
|
query = { 'rev': linkinfo.srcmd5 }
|
||||||
|
u = makeurl(p.apiurl, ['source', linkinfo.project, linkinfo.package], query=query)
|
||||||
|
f = http_GET(u)
|
||||||
|
root_old = ET.parse(f).getroot()
|
||||||
|
dir_old = { 'apiurl': p.apiurl, 'project': linkinfo.project, 'package': linkinfo.package, 'srcmd5': linkinfo.srcmd5 }
|
||||||
|
dir_old['entries'] = [[n.get('name'), n.get('md5')] for n in root_old.findall('entry')]
|
||||||
|
|
||||||
|
# now do 3-way merge
|
||||||
|
entries_old = dict(dir_old['entries'])
|
||||||
|
entries_oldpatched = dict(dir_oldpatched['entries'])
|
||||||
|
entries_new = dict(dir_new['entries'])
|
||||||
|
entries = {}
|
||||||
|
entries.update(entries_old)
|
||||||
|
entries.update(entries_oldpatched)
|
||||||
|
entries.update(entries_new)
|
||||||
|
for name in sorted(entries.keys()):
|
||||||
|
md5_old = entries_old.get(name, '')
|
||||||
|
md5_new = entries_new.get(name, '')
|
||||||
|
md5_oldpatched = entries_oldpatched.get(name, '')
|
||||||
|
if md5_old == md5_new or md5_oldpatched == md5_new:
|
||||||
|
continue
|
||||||
|
if md5_old == md5_oldpatched:
|
||||||
|
if md5_new == '':
|
||||||
|
print statfrmt('D', name)
|
||||||
|
p.put_on_deletelist(name)
|
||||||
|
os.unlink(name)
|
||||||
|
else:
|
||||||
|
print statfrmt('U', name)
|
||||||
|
self.download(name, md5_new, dir_new, name)
|
||||||
|
continue
|
||||||
|
# need diff3 to resolve issue
|
||||||
|
if md5_oldpatched == '':
|
||||||
|
open(name, 'w').write('')
|
||||||
|
os.rename(name, name + '.mine')
|
||||||
|
self.download(name, md5_new, dir_new, name + '.new')
|
||||||
|
self.download(name, md5_old, dir_old, name + '.old')
|
||||||
|
if binary_file(name + '.mine') or binary_file(name + '.old') or binary_file(name + '.new'):
|
||||||
|
shutil.copy2(name + '.new', name)
|
||||||
|
print statfrmt('C', name)
|
||||||
|
p.put_on_conflictlist(name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
o = open(name, 'wb')
|
||||||
|
code = subprocess.call(['diff3', '-m',
|
||||||
|
'-L', '.mine', name + '.mine',
|
||||||
|
'-L', '.old', name + '.old',
|
||||||
|
'-L', '.new', name + '.new',
|
||||||
|
], stdout=o)
|
||||||
|
if code == 0:
|
||||||
|
print statfrmt('G', name)
|
||||||
|
os.unlink(name + '.mine')
|
||||||
|
os.unlink(name + '.old')
|
||||||
|
os.unlink(name + '.new')
|
||||||
|
elif code == 1:
|
||||||
|
print statfrmt('C', name)
|
||||||
|
p.put_on_conflictlist(name)
|
||||||
|
else:
|
||||||
|
print statfrmt('?', name)
|
||||||
|
p.put_on_conflictlist(name)
|
||||||
|
p.write_deletelist()
|
||||||
|
p.write_conflictlist()
|
||||||
|
# store new linkrev
|
||||||
|
store_write_string(p.absdir, '_pulled', linkinfo_new.get('srcmd5'))
|
||||||
|
print
|
||||||
|
if len(p.in_conflict):
|
||||||
|
print 'Please fix the conflicts (files marked with \'C\' above),'
|
||||||
|
print 'run \'osc resolved ...\', and commit the changes'
|
||||||
|
print 'to update the link information.'
|
||||||
|
else:
|
||||||
|
print 'Please commit the changes to update the link information.'
|
||||||
|
|
||||||
@cmdln.option('--create', action='store_true', default=False,
|
@cmdln.option('--create', action='store_true', default=False,
|
||||||
help='create new gpg signing key for this project')
|
help='create new gpg signing key for this project')
|
||||||
|
12
osc/core.py
12
osc/core.py
@ -276,6 +276,7 @@ class Linkinfo:
|
|||||||
self.srcmd5 = None
|
self.srcmd5 = None
|
||||||
self.error = None
|
self.error = None
|
||||||
self.rev = None
|
self.rev = None
|
||||||
|
self.baserev = None
|
||||||
|
|
||||||
def read(self, linkinfo_node):
|
def read(self, linkinfo_node):
|
||||||
"""read in the linkinfo metadata from the <linkinfo> element passed as
|
"""read in the linkinfo metadata from the <linkinfo> element passed as
|
||||||
@ -291,6 +292,7 @@ class Linkinfo:
|
|||||||
self.srcmd5 = linkinfo_node.get('srcmd5')
|
self.srcmd5 = linkinfo_node.get('srcmd5')
|
||||||
self.error = linkinfo_node.get('error')
|
self.error = linkinfo_node.get('error')
|
||||||
self.rev = linkinfo_node.get('rev')
|
self.rev = linkinfo_node.get('rev')
|
||||||
|
self.baserev = linkinfo_node.get('baserev')
|
||||||
|
|
||||||
def islink(self):
|
def islink(self):
|
||||||
"""returns True if the linkinfo is not empty, otherwise False"""
|
"""returns True if the linkinfo is not empty, otherwise False"""
|
||||||
@ -745,7 +747,7 @@ class Package:
|
|||||||
filename = os.path.join(self.dir, n)
|
filename = os.path.join(self.dir, n)
|
||||||
storefilename = os.path.join(self.storedir, n)
|
storefilename = os.path.join(self.storedir, n)
|
||||||
myfilename = os.path.join(self.dir, n + '.mine')
|
myfilename = os.path.join(self.dir, n + '.mine')
|
||||||
if self.islinkrepair():
|
if self.islinkrepair() or self.ispulled():
|
||||||
upfilename = os.path.join(self.dir, n + '.new')
|
upfilename = os.path.join(self.dir, n + '.new')
|
||||||
else:
|
else:
|
||||||
upfilename = os.path.join(self.dir, n + '.r' + self.rev)
|
upfilename = os.path.join(self.dir, n + '.r' + self.rev)
|
||||||
@ -755,7 +757,7 @@ class Package:
|
|||||||
# the working copy may be updated, so the .r* ending may be obsolete...
|
# the working copy may be updated, so the .r* ending may be obsolete...
|
||||||
# then we don't care
|
# then we don't care
|
||||||
os.unlink(upfilename)
|
os.unlink(upfilename)
|
||||||
if self.islinkrepair():
|
if self.islinkrepair() or self.ispulled():
|
||||||
os.unlink(os.path.join(self.dir, n + '.old'))
|
os.unlink(os.path.join(self.dir, n + '.old'))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@ -858,6 +860,12 @@ class Package:
|
|||||||
query['keeplink'] = '1'
|
query['keeplink'] = '1'
|
||||||
if conf.config['linkcontrol']:
|
if conf.config['linkcontrol']:
|
||||||
query['linkrev'] = self.linkinfo.srcmd5
|
query['linkrev'] = self.linkinfo.srcmd5
|
||||||
|
if self.ispulled():
|
||||||
|
for line in open(os.path.join(self.storedir, '_pulled'), 'r'):
|
||||||
|
pulledrev = line.strip()
|
||||||
|
if pulledrev:
|
||||||
|
query['repairlink'] = '1'
|
||||||
|
query['linkrev'] = pulledrev
|
||||||
if self.islinkrepair():
|
if self.islinkrepair():
|
||||||
query['repairlink'] = '1'
|
query['repairlink'] = '1'
|
||||||
u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
|
u = makeurl(self.apiurl, ['source', self.prjname, self.name], query=query)
|
||||||
|
Loading…
Reference in New Issue
Block a user