def info(self, url=None, revno=None): if getattr(revno, 'kind', None): r = revno else: r = revno and pysvn.Revision( pysvn.opt_revision_kind.number, revno ) or \ pysvn.Revision( pysvn.opt_revision_kind.head ) data = self.client.info2(url, revision=r, recurse=False)[0][1].data auth = data.get('last_changed_author', '') rev = getattr(data.get('last_changed_rev', None), 'number', 0) mt = data.get('kind', None) and mime_type[data['kind']] or '' date = data.get('last_changed_date', None) and \ dt.datetime.strptime( time.ctime( data['last_changed_date'] ), '%a %b %d %H:%M:%S %Y' ) \ or None # Fetch the size by listing the file if mt == 'text/directory': # ldata = self.client.list( url, revision=r, recurse=False )[0][0].data size = 0 repos_path = '' elif mt == 'text/file': size = len(self.client.cat(url, revision=r)) repos_path = url.split(self.rooturl)[1] return { 'l_revision': rev, 'l_author': auth, 'l_date': date, 'mime_type': mt, 'size': size, 'repos_path': repos_path }
def getDiffsArray(self): if self.diffIsReallyBig: return [] alldiffs = [] differ = gdiff.diff_match_patch() client = pysvn.Client() for f in self.files: loc = self.repo.url + f loc = loc.replace("trunk//trunk", "trunk/") #Try/Catches are easier than seeing if the diff is an addition/deletion try: left = client.cat(url_or_path=loc, revision=pysvn.Revision( pysvn.opt_revision_kind.number, int(self.uniqueid) - 1)) except: left = '' try: right = client.cat(url_or_path=loc, revision=pysvn.Revision( pysvn.opt_revision_kind.number, int(self.uniqueid))) except: right = '' alldiffs.append(differ.diff_main(left, right)) return alldiffs
def checkout(self, dest, revnum=None, directory=None, verbose=False): revnum_s = str(revnum) if revnum == None: revnum_s = 'head' url = self._svn_url if directory: url += '/' + directory dest = os.path.join(dest, url2pathname(directory)) if verbose: logger.info('checking out "{}@{}" to "{}"'.format(url, revnum_s, dest)) if os.path.exists(dest): logger.warning('already exist: "{}", removing..'.format(dest)) shutil.rmtree(dest) rev = None if revnum: rev = pysvn.Revision(pysvn.opt_revision_kind.number, revnum) else: rev = pysvn.Revision(pysvn.opt_revision_kind.head) self.svn_cli.checkout(url, dest, recurse=True, revision=rev, ignore_externals=False)
def run_log(self, path=None, start_rev=0, end_rev=None, limit=0): self.logger.debug('%s, %s, %d' % (path, self.wc_root, start_rev)) revision_start = pysvn.Revision(opt_revision_kind.head) if end_rev: end_rev = int(end_rev) revision_start = pysvn.Revision(opt_revision_kind.number, end_rev) revision_end = pysvn.Revision(opt_revision_kind.number, start_rev) if not path: path = self.wc_root path = convert_curr_locale_to_unicode_str(path) logs = self.client.log(path, revision_start=revision_start, revision_end=revision_end, discover_changed_paths=True, limit=limit) logs = sorted(logs, key=lambda log: log.revision.number) for log in logs: log['message'] = convert_utf8_to_curr_locale(log.get( 'message', '')) for cp in log.changed_paths: cp['path'] = convert_utf8_to_curr_locale(cp['path']) return logs
def svnDiffSummarize(self, path1, revision1, path2, revision2): head = pysvn.Revision(pysvn.opt_revision_kind.number, revision1) end = pysvn.Revision(pysvn.opt_revision_kind.number, revision2) added = [] deleted = [] modified = [] prop_changed = [] nothing = [] files = self.client.diff_summarize(path1, head, path2, end) for info in files: path = info.path if info.node_kind == pysvn.node_kind.dir: path += '/' if info.summarize_kind == pysvn.diff_summarize_kind.normal: nothing.append(path) elif info.summarize_kind == pysvn.diff_summarize_kind.modified: modified.append(path) elif info.summarize_kind == pysvn.diff_summarize_kind.delete: deleted.append(path) elif info.summarize_kind == pysvn.diff_summarize_kind.added: added.append(path) elif info.prop_changed: prop_changed.append(path) dictionary_changes = {} dictionary_changes['added'] = added dictionary_changes['deleted'] = deleted dictionary_changes['modified'] = modified dictionary_changes['nothing'] = nothing dictionary_changes['prop_changed'] = prop_changed return dictionary_changes
def getBlame(self, filepath): ''' run the blame command on file. Read the blame for SVN or from cache. ''' if filepath not in self.blame_cache: logging.debug('trying to extract annotations for %s' % filepath) revision_start = pysvn.Revision( pysvn.opt_revision_kind.number, 0 ) revision_end = pysvn.Revision( pysvn.opt_revision_kind.head ) #call 'log' and query the last 100 revisions of given file. For large repositories #annotate can put lot of stress on the server. Hence limit it to 100 revisions revlogs = self.svnclient.log(filepath, discover_changed_paths=False, limit=self.MAX_REVISIONS_FOR_BLAME, include_merged_revisions=True, revprops = ['revision']) revision_start = revlogs[-1].revision revision_end = revlogs[0].revision output = self.svnclient.annotate(filepath,revision_start=revision_start, revision_end=revision_end) logging.debug('extracted annotations for %s' % filepath) blameout = list() for lineno, blamedict in enumerate(output): blameinfo = BlameInfo(blamedict['author'], blamedict['revision'].number) assert lineno == int(blamedict['number']) blameout.append(blameinfo) self.blame_cache[filepath] = blameout return self.blame_cache[filepath]
def get_diff(): # Here we go back through history, 5 commits at a time, searching # for the first point at which there is a change along our path. oldrev_log = None i = 1 # the start of our search is always at the previous commit while oldrev_log is None: i += 5 diff_rev_start = pysvn.Revision( pysvn.opt_revision_kind.number, log['revision'].number - (i - 5)) diff_rev_end = pysvn.Revision(pysvn.opt_revision_kind.number, log['revision'].number - i) log_list = self._repo.log(self.path, revision_start=diff_rev_start, revision_end=diff_rev_end, discover_changed_paths=True) try: oldrev_log = log_list.pop(0) except IndexError: # If we've gone back through the entirety of history and # still not found anything, bail out, this commit doesn't # exist along our path (or perhaps at all) if i >= log['revision'].number: raise CommitDoesNotExist diff = self._repo.diff( NamedTemporaryFile().name, url_or_path=self.path, revision1=oldrev_log['revision'], revision2=log['revision'], ) return diff
def commits_by_authors(self): """ :return: dict(author=dict(revision=message)) """ def ssl_server_trust_prompt(trust_dict): return True, trust_dict['failures'], True result = {} svn = pysvn.Client() if self.svn_root.startswith('https'): svn.callback_ssl_server_trust_prompt = ssl_server_trust_prompt start_revision = svn.log( self.svn_root, limit=1, discover_changed_paths=False)[0].revision.number end_revision = start_revision - self.commits draft_log = svn.log( self.svn_root, revision_start=pysvn.Revision(pysvn.opt_revision_kind.number, start_revision), revision_end=pysvn.Revision(pysvn.opt_revision_kind.number, end_revision)) log = [ commit for commit in draft_log if commit.author in self.developers and datetime.datetime.fromtimestamp(commit.date) > self.start_day ] for commit in log: author = commit.author revision = str(commit.revision.number) message = self.task_to_link(commit.message) if author not in result: result.update({author: {revision: message}}) else: result[author].update({revision: message}) return result
def cmdCommitLogForFile(self, filename, limit=None, since=None, until=None, rev=None): if limit is None: limit = 0 if until is not None: rev_start = pysvn.Revision(pysvn.opt_revision_kind.date, until) else: rev_start = self.svn_rev_head if since is not None: rev_end = pysvn.Revision(pysvn.opt_revision_kind.date, since) elif rev is not None: rev_end = rev else: rev_end = self.svn_rev_r0 all_logs = self.client().log(self.pathForSvn(filename), revision_start=rev_start, revision_end=rev_end, limit=limit, discover_changed_paths=True) return all_logs
def doSVNAnnotate(client, path, revStart=None, revEnd=None, revPeg=None): " Performs the SVN annotate for the given path " if revStart is None: revStart = pysvn.Revision(pysvn.opt_revision_kind.number, 0) if revEnd is None: revEnd = pysvn.Revision(pysvn.opt_revision_kind.head) if revPeg is None: revPeg = pysvn.Revision(pysvn.opt_revision_kind.unspecified) progressDialog = SVNAnnotateProgress(client, path, revStart, revEnd, revPeg) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) res = progressDialog.exec_() QApplication.restoreOverrideCursor() if res == QDialog.Accepted: fullText = "\n".join( [lineInfo['line'] for lineInfo in progressDialog.annotation]) revisions = deepcopy(progressDialog.revisionsInfo.keys()) revisionPerLine = [] for lineInfo in progressDialog.annotation: revNumber = lineInfo['revision'].number revisionPerLine.append(revNumber) if revNumber in revisions: progressDialog.revisionsInfo[revNumber]['date'] = lineInfo[ 'date'] progressDialog.revisionsInfo[revNumber]['author'] = lineInfo[ 'author'] revisions.remove(revNumber) return fullText, revisionPerLine, progressDialog.revisionsInfo return None, None, None
def getTody_log(): global g_LogList g_LogList = [] client = pysvn.Client() revision_start = pysvn.Revision(pysvn.opt_revision_kind.head) bContinue = True while bContinue: LogList = client.log(SVNURL, revision_start, limit=10) print "LogList: %s" % (TodayTime) Number = LogList[len(LogList) - 1].revision.number revision_start = pysvn.Revision(pysvn.opt_revision_kind.number, Number) for LogInfo in LogList: LogTime = time.strftime("%Y-%m-%d", time.localtime(LogInfo.date)) print LogTime if LogTime == TodayTime: print LogInfo g_LogList.append(LogInfo) else: bContinue = False if len(g_LogList) == 0: break
def __collectRevisionInfo(self): " Collects information about revision messages " self.__infoLabel.setText("Collecting revision messages...") QApplication.processEvents() revisions = set() for item in self.annotation: if item['revision'].kind == pysvn.opt_revision_kind.number: revisions.add(item['revision'].number) self.revisionsInfo = {} minRevision = min(revisions) maxRevision = max(revisions) revStart = pysvn.Revision(pysvn.opt_revision_kind.number, minRevision) revEnd = pysvn.Revision(pysvn.opt_revision_kind.number, maxRevision) revs = self.__client.log(self.__path, revision_start=revStart, revision_end=revEnd) for rev in revs: if rev['revision'].kind == pysvn.opt_revision_kind.number: number = rev['revision'].number if number in revisions: self.revisionsInfo[number] = {'message': rev['message']} return
def getRevFileDiff(self, path, revno,prev_path=None,prev_rev_no=None): if( prev_path == None): prev_path = path if( prev_rev_no == None): prev_rev_no = revno-1 cur_url = self.getUrl(path) cur_rev = pysvn.Revision(pysvn.opt_revision_kind.number, revno) prev_url = self.getUrl(prev_path) prev_rev = pysvn.Revision(pysvn.opt_revision_kind.number, prev_rev_no) diff_log = None logging.debug("Getting filelevel revision diffs") logging.debug("revision : %d, url=%s" % (revno, cur_url)) logging.debug("prev url=%s" % prev_url) try: diff_log = self.svnclient.diff(self.tmppath, url_or_path=prev_url, revision1=prev_rev, url_or_path2=cur_url , revision2=cur_rev, recurse=True, ignore_ancestry=False,ignore_content_type=False, header_encoding=SVN_HEADER_ENCODING, diff_deleted=True) except pysvn.ClientError, exp: logging.exception("Error in getting file level revision diff") logging.debug("url : %s" % cur_url) logging.debug("previous url : %s" % prev_url) logging.debug("revno =%d", revno) logging.debug("prev renvo = %d", prev_rev_no) raise
def svnLog(path, start, end): ret = pysvn.Client().log( path, revision_start=pysvn.Revision(pysvn.opt_revision_kind.number, start), revision_end=pysvn.Revision(pysvn.opt_revision_kind.number, end)) for k in ret: print(k.message)
def get_diff_file(self, min, max): targetPath = self.release_svn_dir + self.date_file client = pysvn.Client() revision_max = pysvn.Revision(pysvn.pysvn.opt_revision_kind.number, max) revision_min = pysvn.Revision(pysvn.pysvn.opt_revision_kind.number, min) self.change = client.diff_summarize(self.url, revision_min, self.url, revision_max) for changed in self.change: try: if pysvn.diff_summarize_kind.added == changed['summarize_kind'] or pysvn.diff_summarize_kind.modified == \ changed['summarize_kind']: self.logger.info("从SVN下载:" + changed['path']) file_text = client.cat( self.url + parse.quote(changed['path'].encode('utf8')), revision_max) fullpath = targetPath + "/" + changed["path"] dirpath = fullpath[0:fullpath.rfind("/")] if not os.path.exists(dirpath): os.makedirs(dirpath) with open(fullpath, "wb") as f: f.write(file_text) except: print("error:" + parse.quote(changed['path'].encode('utf8'))) continue return targetPath
def getlogs(newrev, startrev): import pysvn logs = [] log_messages = [] loglimit = 200 def get_login(realm, username, may_save): return True, newrev.project.repo_user, newrev.project.repo_pass, False client = pysvn.Client() if newrev.project.repo_user != "": client.callback_get_login = get_login try: log_messages = \ client.log( newrev.project.repo_path, revision_start=pysvn.Revision( pysvn.opt_revision_kind.number, startrev.commitid ), revision_end=pysvn.Revision( pysvn.opt_revision_kind.number, newrev.commitid ) ) except pysvn.ClientError: return [{ 'error': True, 'message': "Could not resolve '" + newrev.project.repo_path + "'" }] except ValueError: return [{ 'error': True, 'message': "'%s' is an invalid subversion revision number" % newrev.commitid }] log_messages.reverse() s = len(log_messages) while s > loglimit: log_messages = log_messages[:s] s = len(log_messages) - 1 for log in log_messages: try: author = log.author except AttributeError: author = "" date = datetime.fromtimestamp(log.date).strftime("%Y-%m-%d %H:%M:%S") message = log.message # Add log unless it is the last commit log, which has already been tested logs.append({ 'date': date, 'author': author, 'message': message, 'commitid': log.revision.number }) return logs
def get_svn_log_style2(svn_path, start_timestamp, end_timestamp): revision_start = pysvn.Revision(pysvn.opt_revision_kind.date, start_timestamp) revision_end = pysvn.Revision(pysvn.opt_revision_kind.date, end_timestamp) log_list = client.log(svn_path, revision_start, revision_end) dic = {} for LogInfo in log_list: LogInfo.message = LogInfo.message.replace("\n", "") if LogInfo.message != "": if is_repeat(LogInfo.message) == True: if dic.has_key(LogInfo.author) == False: dic[LogInfo.author] = { "msg": "", "name": LogInfo.author, "date": "", "showmsg": "" } # else: if rep(dic[LogInfo.author]["msg"], LogInfo.message) == False: dic[LogInfo.author]["msg"] += LogInfo.message + "\&" dic[LogInfo.author]["date"] += fmtDateTime(LogInfo.date) # dic[LogInfo.author]["showmsg"]+=LogInfo.message+","+LogInfo.author+", tm="+fmtDateTime(LogInfo.date)+"\n" dic[LogInfo.author]["showmsg"] += "tm=" + fmtDateTime( LogInfo.date ) + "," + LogInfo.message + "," + LogInfo.author + "\n" s1 = "start log content\n" for key, value in dic.items(): s1 += value["showmsg"] + "\n" f = open("svnLog_style2.csv", "w") f.write(s1) f.close()
def SvnUpdateList(self, old_rev, new_rev): head = pysvn.Revision(pysvn.opt_revision_kind.number, old_rev) end = pysvn.Revision(pysvn.opt_revision_kind.number, new_rev) FILE_CHANGE_INFO = { pysvn.diff_summarize_kind.normal: ' ', pysvn.diff_summarize_kind.modified: u'修改', pysvn.diff_summarize_kind.delete: u'删除', pysvn.diff_summarize_kind.added: u'添加', } summary = self.client.diff_summarize(self.svnDir, head, self.svnDir, end) UpdateAllList = [] for info in summary: path = info.path if info.node_kind == pysvn.node_kind.dir: path += '/' file_changed = FILE_CHANGE_INFO[info.summarize_kind] prop_changed = ' ' if info.prop_changed: prop_changed = 'M' UpdateAllList.append([file_changed + prop_changed, path]) #print UpdateAllList return UpdateAllList
def list_directory(self, path, revision=None): if revision: rev = pysvn.Revision(pysvn.opt_revision_kind.number, revision) else: rev = pysvn.Revision(pysvn.opt_revision_kind.head) dir_path = os.path.join(self.path, path) try: entries = self._repo.list(dir_path, revision=rev, recurse=False) except pysvn.ClientError: raise FolderDoesNotExist files, folders = [], [] for file_info, file_pops in entries: if file_info['kind'] == pysvn.node_kind.dir: # TODO: Path is not always present, only repos_path # is guaranteed, in case of looking at a remote # repository (with no local working copy) we should # check against repos_path. if not dir_path.startswith(file_info['path']): folders.append(os.path.basename(file_info['repos_path'])) else: files.append(os.path.basename(file_info['repos_path'])) return files, folders
def revision_info(self, revision): rev = int(revision) rev_obj = pysvn.Revision(pysvn.opt_revision_kind.number, rev) info = self._client.log(self._base, revision_start=rev_obj, revision_end=rev_obj) rev_summ = self._client.diff_summarize( self._base, pysvn.Revision(pysvn.opt_revision_kind.number, rev - 1), self._base, pysvn.Revision(pysvn.opt_revision_kind.number, rev), ) tmpdir = tempfile.mkdtemp() try: diff_text = self._client.diff( tmpdir, self._base, pysvn.Revision(pysvn.opt_revision_kind.number, rev - 1), self._base, pysvn.Revision(pysvn.opt_revision_kind.number, rev), header_encoding="UTF-8") except: logger.exception('could not calculate diff') diff_text = "impossible de calculer les différences" shutil.rmtree(tmpdir) return [dict(item) for item in rev_summ], info[0], diff_text
def run_copy(self, src_url_or_path, dest_url_or_path, rev=None): if rev: rev = pysvn.Revision(opt_revision_kind.number, rev) else: rev = pysvn.Revision(opt_revision_kind.head) return self.client.copy(src_url_or_path, dest_url_or_path, rev)
def getLog(self): try: client = pysvn.Client() client.callback_ssl_server_trust_prompt = self.ssl_server_trust_prompt client.callback_get_login = self.get_login mid = time.mktime( datetime.datetime.combine(datetime.date.today(), datetime.time.min).timetuple()) start = pysvn.Revision(pysvn.opt_revision_kind.date, time.time()) end = pysvn.Revision(pysvn.opt_revision_kind.date, mid) num = pysvn.Revision(pysvn.opt_revision_kind.number, 41975) # log = client.log(self._url, revision_start=start, # revision_end=end, limit=self._logLimitNum) log = client.log(self._url, peg_revision=num) for info in log: logAuthor = info.author logTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(info.date)) logMessage = info.message logRevision = info.revision.number logChange_list = info.changed_paths one = { 'Author': logAuthor, 'Time': logTime, 'Message': logMessage, 'Revision': logRevision, 'Change_list': logChange_list } self._result.append(one) print "提交人:", logAuthor, "提交时间:", logTime, "提交信息:", logMessage, "svn版本号:", logRevision return True except Exception as e: print '获取日志失败,错误信息:', e return False
def run_list(self, path, rev_num=None, peg_rev=None, depth=None): revision = pysvn.Revision(pysvn.opt_revision_kind.head) if rev_num: revision = pysvn.Revision(pysvn.opt_revision_kind.number, rev_num) if peg_rev: peg_rev = pysvn.Revision(pysvn.opt_revision_kind.number, peg_rev) else: peg_rev = revision if depth: properties = self.client.list(path, revision=revision, peg_revision=peg_rev, depth=depth) else: properties = self.client.list(path, revision=revision, peg_revision=peg_rev) for fi in properties: fi[0]['repos_path'] = convert_unicode_to_current_locale( fi[0]['repos_path']) return properties
def update(self, path, rev=None): if rev: pyrev = pysvn.Revision(pysvn.opt_revision_kind.number, int(rev)) else: pyrev = pysvn.Revision(pysvn.opt_revision_kind.head) ret = self.client.update(path, revision=pyrev, ignore_externals=True) return self.check_rev_result(ret)
def getChangedTexts(self, metadata): if self.changedTexts != None: return self.changedTexts elif self.changedTexts_data != None: return self._loadChangedTextFromBackingVar() elif metadata == None: raise Exception( "NULL passed to getChangedTexts when local changedTexts was not set" ) uniqueid, repo = metadata if int(uniqueid) == 1: diff = '' else: client = pysvn.Client() diff = client.diff( tmp_path='./', url_or_path=repo.url, revision1=pysvn.Revision(pysvn.opt_revision_kind.number, int(uniqueid) - 1), revision2=pysvn.Revision(pysvn.opt_revision_kind.number, int(uniqueid))) diff = svn_diff_header.sub('', diff) diff = svn_diff_newline.sub('', diff) diff = svn_diff_property.sub('', diff) diff = svn_diff_deletions.sub('', diff) diff = diff.lower() self.changedTexts = [diff] return self.changedTexts
def switch(self, path, uri, rev=None): if rev: pyrev = pysvn.Revision(pysvn.opt_revision_kind.number, int(rev)) else: pyrev = pysvn.Revision(pysvn.opt_revision_kind.head) ret = self.client.switch(path, uri, revision=pyrev) return self.check_rev_result(ret)
def main(repos, revision): """ Main function. """ import pysvn import os.path client = pysvn.Client() diff = client.diff_summarize( repos, revision1=pysvn.Revision(pysvn.opt_revision_kind.number, revision - 1), revision2=pysvn.Revision(pysvn.opt_revision_kind.number, revision)) conn = sqlobject.connectionForURI(DATABASE_URI) sqlobject.sqlhub.processConnection = conn #PythonScore.createTable() func = lambda f: os.path.splitext(f.path)[-1] == ".py" for entry in filter(func, diff): path = os.path.join(repos, entry.path) score, old_score, credit = process_file(path) info = client.info(path) PythonScore(username=info['commit_author'], pathname=path, revision="1", score=score, old_score=old_score, credit=credit)
def diff(self): diff_text = self.client.diff( '/tmp/svn', '/data/svn/a', pysvn.Revision(pysvn.opt_revision_kind.number, 20825), '/data/svn/a', pysvn.Revision(pysvn.opt_revision_kind.number, 20826)) return diff_text
def checkout_source(self, path, revnum=None, verbose=False): revnum_s = str(revnum) if revnum == None: revnum_s = 'head' url = self._svn_url if verbose: logger.info('checking out "{}@{}" as {}'.format(url, revnum_s, path)) if os.path.exists(path): logger.warning('already exist: "{}"'.format(path)) else: if revnum: rev = pysvn.Revision(pysvn.opt_revision_kind.number, revnum) else: rev = pysvn.Revision(pysvn.opt_revision_kind.head) text = self.svn_cli.cat(url, revision=rev) f = None d = os.path.dirname(path) try: if not os.path.exists(d): self.mkdir(d) f = open(path, 'w') f.write(text) finally: if f: f.close()
def poll(self): """Looks for updates to this repository since the last poll. Submits CIA messages for any commits that have occurred since then. """ if not self.model.root_url: self.probe() self.model.save() # Have there been any new revisions? Get the last revision for # the whole repository. Note that this may be later than the # revision of the last commit we retrieve. last_revision = self._pollLatestRev() if last_revision <= self.model.last_revision: return changes = self.client.log( self.model.location, revision_start=pysvn.Revision(pysvn.opt_revision_kind.number, self.model.last_revision + 1), revision_end=pysvn.Revision(pysvn.opt_revision_kind.number, last_revision), discover_changed_paths=True, limit=REVISION_FETCH_LIMIT) for change in changes: self._deliverCommit(change) self.model.last_revision = last_revision self.model.last_update_time = datetime.datetime.now() self.model.save()