Skip to content

Instantly share code, notes, and snippets.

@5263
Last active October 26, 2020 19:28
Show Gist options
  • Save 5263/0f1554decb1cd329f4ee to your computer and use it in GitHub Desktop.
Save 5263/0f1554decb1cd329f4ee to your computer and use it in GitHub Desktop.
FreeCAD files git repo
#!/usr/bin/env python
import zip2git
from PySide import QtGui
# 1. Choose repository (directiory)
repodir = QtGui.QFileDialog.getExistingDirectory(QtGui.qApp.activeWindow())
if repodir:
# ToDO: 2. List branches in a list and let the user choose one
# ToDo: 3. List commits in a list and let the user choose one
# ToDo: 4. Check if it would overwrite a file. And if the file is
# part of the repo. Ask the user for cofirmation
zip2git.checkoutandload(ref=None,repopath=repodir)
#!/usr/bin/env python
from PySide import QtGui
from PySide import QtCore
class GitRepoForm(QtGui.QDialog):
def __init__(self,parent=None):
super(GitRepoForm,self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
self.setLayout(layout)
hsplitter = QtGui.QSplitter(self)
self.lv1 = QtGui.QListWidget(self)
self.lv1.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.lv2 = QtGui.QTableWidget(self)
hsplitter.addWidget(self.lv1)
hsplitter.addWidget(self.lv2)
h1layout = QtGui.QHBoxLayout()
self.repopathle=QtGui.QLineEdit(u".",parent=self)
h1layout.addWidget(self.repopathle)
self.dirdialogbutton=QtGui.QPushButton('...')
h1layout.addWidget(self.dirdialogbutton)
layout.addLayout(h1layout)
layout.addWidget(hsplitter)
self.buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok\
|QtGui.QDialogButtonBox.Cancel)
layout.addWidget(self.buttons)
self.buttons.accepted.connect(self.onOkButtonClicked)
self.buttons.rejected.connect(self.reject)
self.dirdialogbutton.clicked.connect(self.onDirDialogButtonClicked)
self.repopathle.textChanged.connect(self.updateReflist)
self.lv1.itemSelectionChanged.connect(self.updateCommitlist)
self.refs={}
self.updateReflist()
@QtCore.Slot()
def onDirDialogButtonClicked(self):
repodir = QtGui.QFileDialog.getExistingDirectory(\
QtGui.qApp.activeWindow())
if repodir:
self.repopathle.setText(repodir)
@QtCore.Slot()
def updateReflist(self):
def sortkey(val):
nohyphen=val[-36:].replace('-','')
return (len(val.rsplit('/',1)[-1]) == 36 and len(nohyphen) ==\
32 and all(c in '0123456789abcdef' for c in nohyphen),val)
import dulwich #zip2git
import dulwich.repo
try:
repo=dulwich.repo.Repo(self.repopathle.text())
self.refs=repo.get_refs()
self.keys=sorted(self.refs.keys(),key=sortkey)
self.lv1.clear()
self.lv1.addItems(self.keys)
except dulwich.repo.NotGitRepository:
self.lv1.clear()
@QtCore.Slot(int)
def updateCommitlist(self,index=None):
self.lv2.clear()
commits=set()
for listitem in self.lv1.selectedItems():
refname=listitem.text()
if refname in self.refs:
commits.add(self.refs[refname])
#print commits
import dulwich
import zip2git
repo=dulwich.repo.Repo(self.repopathle.text())
walker=repo.get_walker(include=list(commits))
self.lv2.clear()
self.lv2.setColumnCount(13)
self.lv2.setRowCount(0)
self.lv2.setHorizontalHeaderLabels(("Label",'Last Modified',\
"Modified by","Comment","License","tree", "commit","UUID",\
"Program Version","Created","Created by","Company","Id"))
for row,we in enumerate(walker):
c=we.commit
twiauthortime=QtGui.QTableWidgetItem(zip2git.git2datetime(\
c.author_time,c.author_timezone).strftime('%F %T %z'))
twiauthor=QtGui.QTableWidgetItem(c.author)
twitreeid=QtGui.QTableWidgetItem(c.tree)
twicommitid=QtGui.QTableWidgetItem(c.id)
self.lv2.insertRow(row)
self.lv2.setItem(row, 1, twiauthortime)
self.lv2.setItem(row, 2, twiauthor)
self.lv2.setItem(row, 5, twitreeid)
self.lv2.setItem(row, 6, twicommitid)
propertiesdict=zip2git.tree2propertiesdict(c.tree,repo)
if propertiesdict is not None:
uuid=zip2git.extractuidpropertiesdict(propertiesdict)
twiuuid = QtGui.QTableWidgetItem(uuid)
self.lv2.setItem(row, 7, twiuuid)
for key,listindex in (('Label',0),('License',4),\
('Comment',3),('Company',11),('CreationDate',9),\
('CreatedBy',10),("Id",12),("ProgramVersion",8)):
value=propertiesdict.get(key)
if value:
tableitem=QtGui.QTableWidgetItem(value)
self.lv2.setItem(row, listindex, tableitem)
@QtCore.Slot()
def onOkButtonClicked(self):
commits=set()
for srange in self.lv2.selectedRanges():
for rowindex in range(srange.topRow(),srange.bottomRow()+1):
#print rowindex
commits.add(self.lv2.item(rowindex,6).text()) #commitid
if len(commits) == 1:
commitid=tuple(commits)[0]
repopath=self.repopathle.text()
import zip2git
zipfilepath=zip2git.checkoutfile(commitid,True,repopath=repopath)
if zipfilepath:
import FreeCAD
doc=FreeCAD.openDocument(zipfilepath)
if not hasattr(FreeCAD,'_doc2git'):
FreeCAD._doc2git={}
FreeCAD._doc2git[doc]={'repopath':repopath,'parents':\
[commitid]} #'branch': ?
if len(self.lv1.selectedItems()) == 1:
FreeCAD._doc2git[doc]['branch'] = self.lv1.selectedItems()\
[0].text()
self.accept()
if __name__ == '__main__':
qApp = QtGui.qApp
if qApp is not None:
parent = QtGui.qApp.activeWindow()
else:
import sys
app = QtGui.QApplication(sys.argv)
parent = None
form = GitRepoForm(parent)
form.show()
# if parent is None:
# import sys
# sys.exit(qApp.exec_())
import FreeCAD,zip2git
reload(zip2git)
doc=FreeCAD.activeDocument()
if doc is None:
raise ValueError('No Document')
if not doc.FileName:
import FreeCADGui
Gui.SendMsgToActiveView("SaveAs")
if doc.FileName:
#file was saved from the gui allready
commitid=zip2git.saveandcommit(save=False)
else:
raise ValueError('No Filename set')
else:
commitid=zip2git.saveandcommit()
if commitid:
FreeCAD.Console.PrintLog('commit id %s\n' % commitid)
#!/usr/bin/env python
#***************************************************************************
#* *
#* Copyright (c) 2014 Sebastian Hoogen <github@sebastianhoogen.de> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="FreeCAD Git resource backend"
import zipfile
import dulwich
import dulwich.repo
import dulwich.objects
import xml.sax
import xml.sax.handler
import xml.sax.xmlreader
defaultcommiter = 'unknown <>'
class DocumentHandler(xml.sax.handler.ContentHandler):
"""adaped form DlgProjectUtility.cpp (c) wmayer 2011 LGPL2+"""
def __init__(self):
self.files = []
def startElement(self, name, attributes):
item=attributes.get("file")
if item != None:
self.files.append(str(item))
def characters(self, data):
return
def endElement(self, name):
return
def parsedocument(docstr1):
import re, xml.etree.ElementTree
mo=re.search('(<Properties Count="\d+">.*?</Properties>)',\
docstr1, re.DOTALL)
if mo is not None:
propertiestree = xml.etree.ElementTree.fromstring(mo.group(1))
d1=dict((p.attrib['name'],p[0].attrib['value']) \
for p in propertiestree.getchildren() \
if 'value' in p[0].attrib)
moversion=re.search('<Document SchemaVersion="(\d+)" ProgramVersion="(.*?)" FileVersion="(\d+)">',docstr1)
#re.search('<Document SchemaVersion="(\d+)"ProgramVersion="(.*?)" FileVersion="(\d+)">', docstr1,re.DOTALL)
if moversion is not None:
d1['ProgramVersion'] = moversion.group(2)
d1['SchemaFileVersion'] = \
(moversion.group(1),moversion.group(3))
return d1
else:
return {}
def extractuidpropertiesdict(d1):
return d1.get('Uid') or d1.get('Id')
def extractuidstring(str1):
return extractuidpropertiesdict(parsedocument(str1))
def extractuid(filename):
z=zipfile.ZipFile(filename)
uuid=extractuidstring(z.read('Document.xml'))
z.close()
return uuid
def git2datetime(ts,offset):
import datetime,dateutil.tz
utc=dateutil.tz.tzoffset(None,0)
local=dateutil.tz.tzoffset(None,offset)
dtutc=datetime.datetime.fromtimestamp(ts,utc)
return dtutc.astimezone(local)
def parsedatetime(datetimestr):
import calendar,dateutil.parser
dt=dateutil.parser.parse(datetimestr)
timestamp=calendar.timegm(dt.utctimetuple())
utcoffset=dt.utcoffset()
if utcoffset is None:
return timestamp,0
else:
return timestamp,utcoffset.total_seconds()
def uuidfilelist(filenames):
"""extract the UUID, LastModidiedDate and git tree hash form given
FCStd files"""
uuiddict={}
filelist=[]
for filepath in filenames:
if filepath.lower().endswith('.fcstd') or\
filepath.lower().endswith('.fcstd1'):
treeid,propertiesdict=buildtree(filepath,object_store=None)
uuidstr = propertiesdict.get('Uid') or propertiesdict.get('Id')
doctimestamp=parsedatetime(\
propertiesdict['LastModifiedDate'].strip())
list1=uuiddict.get(uuidstr,[])
list1.append((filepath,doctimestamp[0],treeid))
uuiddict[uuidstr]=sorted(list1,key=lambda k:k[1])
filelist.append((filepath, treeid, uuidstr, doctimestamp[0]))
return filelist,uuiddict
def uuiddir(paths=('.',)):
"""extract the UUID, LastModidiedDate and git tree hash form all
FCStd files in the given directories"""
import os
uuiddict={}
for path in paths:
for filename in os.listdir(path):
if filename.lower().endswith('.fcstd') or\
filename.lower().endswith('.fcstd1'):
filepath=os.path.join(path,filename)
#listentry=extractuid(filepath,True)
treeid,propertiesdict=buildtree(filepath,object_store=None)
uuidstr = propertiesdict.get('Uid') or propertiesdict.get('Id')
doctimestamp=parsedatetime(\
propertiesdict['LastModifiedDate'].strip())
list1=uuiddict.get(uuidstr,[])
list1.append((filepath,doctimestamp[0],treeid))
uuiddict[uuidstr]=sorted(list1,key=lambda k:k[1])
return uuiddict
def getFilesList(documentstr):
"""parse the FreeCAD xml document and extract the names of referenced
external files, in the order of apperanche. The FCStd file format expects
relies on the correct oder of the files inside the ZIP structure."""
import xml.sax
handler=DocumentHandler()
xml.sax.parseString(documentstr,handler)
return tuple(iter(handler.files))
def buildtree(filename,object_store=None):
"""Calculate the tree hash for a FCStd file
if an object_store is specified the blobs and tree will be added
the properties are returned as a dictionary"""
propertiesdict={}
z=zipfile.ZipFile(filename)
tree=dulwich.objects.Tree()
for i in z.infolist():
if i.filename == 'Document.xml':
propertiesdict=parsedocument(z.open(i).read())
elif i.filename.startswith('thumbnails/'):
continue # discard the thumbnailis.
#It's easier than handling tree objects
blob = dulwich.objects.Blob.from_string(z.open(i).read())
if object_store is not None:
object_store.add_object(blob)
tree.add(i.filename, 0100644, blob.id)
z.close()
if object_store is not None:
object_store.add_object(tree)
return tree.id,propertiesdict
def walkrefs(repo,unknown=()):
unknown=set(unknown)
known=set()
while len(unknown) > 0:
#unknown=unknown-known
commit=unknown.pop()
try:
parents=repo.get_parents(commit)
known.add(commit)
unknown.update(frozenset(parents)-known)
except ValueError:
print "skipped invalid commit %s" % commit
#raise
return known
def treeids(repo):
def addtodictset(d,k,v):
s=d.get(k,set())
s.add(v)
d[k]=s
ref2tree={}
tree2currentref={}
tree2parentref={}
for refname, commit in repo.get_refs().iteritems():
try:
currenttree=repo.get_object(commit).tree
addtodictset(tree2currentref,currenttree,refname)
commits=walkrefs(repo,(commit,)) #walks parents!
trees=[repo.get_object(commitid).tree for commitid in commits-\
frozenset(commit)]
ref2tree[refname]=[currenttree]+trees
for tree in trees:
addtodictset(tree2parentref,tree,'parent_of_%s' %refname)
except ValueError:
raise
print "skipped invalid commit %s" % commit
return ref2tree,tree2currentref,tree2parentref
def tree2propertiesdict(treeid,repo):
tree = repo.get_object(treeid)
if 'Document.xml' in tree:
perms,blobid = tree['Document.xml']
documentobj=repo.get_object(blobid)
return parsedocument(documentobj.data)
def checkoutfilecommitid(refid,zipfilepath=None,repopath='.',repo=None):
repo = repo or dulwich.repo.Repo(repopath)
commit=repo.get_object(refid)
tree=repo.get_object(commit.tree)
documentblob=None
guidocumentblob=None
for tentry in tree.items():#._entries:#tree.entries():
#for attr,name,blobhash in tree.entries():
name = tentry.path
blobhash = tentry.sha
if name == 'Document.xml' : documentblob = blobhash
elif name == 'GuiDocument.xml' : guidocumentblob = blobhash
namelist=['Document.xml']
documentobj=repo.get_object(documentblob)
documentstr=documentobj.data
namelist.extend(getFilesList(documentstr))
if guidocumentblob is not None:
guidocumentobj=repo.get_object(guidocumentblob)
namelist.append('GuiDocument.xml')
namelist.extend(getFilesList(guidocumentobj.data))
namelist2=[]
for filename in namelist:
for treeentry in tree.items():
if treeentry.path == filename:
namelist2.append((filename,treeentry.sha))
#write the zipfile
if zipfilepath is None or zipfilepath is True:
if repopath.lower().endswith('.fcstd.git'):
zipfilepath=repopath[:-4]
elif zipfilepath is True:
import os.path #extract name
filename=parsedocument(documentstr).get('FileName')
zipfilepath=os.path.join(repopath,os.path.split(filename)[1])
else:
import os
import os.path
zipfilepath=os.path.join(repopath,'%s.FCStd' % \
(ref.replace('/','_')))
#if os.path.exists(zipfilepath):
# zipfilepath='gitcheckout-%s' % zipfilepath
zf=zipfile.ZipFile(zipfilepath,'w',zipfile.ZIP_DEFLATED)
for filename,blobhash in namelist2:
zf.writestr(filename,repo.get_object(blobhash).data)
zf.close()
return zipfilepath
def checkoutfile(ref='HEAD',zipfilepath=None,repopath='.',\
returncommitid=False):
repo=dulwich.repo.Repo(repopath)
refid = repo.refs.read_ref(ref)
if refid is None:
refid = repo.refs.read_ref('refs/heads/%s' % ref)
if refid is None and len(ref) == 40:
refid=ref
if refid is None:
raise ValueError('Neither refs nor full hash given. Use git rev-parse to get the full hash')
filename = checkoutfilecommitid(refid,zipfilepath=zipfilepath,\
repopath=repopath,repo=repo)
if returncommitid:
return filename,commit #to save as parent for next commit
else:
return filename #backward compatible
def commitfile(filename,refname=None,repopath='.',overrideparents=None\
,defaultauthor=None,committimestamp=None,checkforduplicatetree=\
True):
"""decompress a FreeCAD file and check it into the repo"""
import os.path
filename2=os.path.split(filename)[1].rsplit('.',1)[0]
if refname is None:
refname = filename2.replace(' ','_')
repo=dulwich.repo.Repo(repopath)
object_store = repo.object_store
treeid,propertiesdict = buildtree(filename,object_store=object_store)
datetimestr=propertiesdict['LastModifiedDate'].strip()
uuidstr=propertiesdict.get('Uid') or \
propertiesdict.get('Id')
if 'Uid' in propertiesdict:
del propertiesdict['Uid']
if 'Id' in propertiesdict:
del propertiesdict['Id']
if 'SchemaFileVersion' in propertiesdict:
del propertiesdict['SchemaFileVersion']
author=propertiesdict['LastModifiedBy'].strip()
keys=sorted(propertiesdict.keys())
propertiesstr='\n'.join(('%s: %s' % (key,\
propertiesdict[key].strip()) \
for key in keys if propertiesdict[key].strip()))
doctimestamp=parsedatetime(datetimestr)
#doctimestamp=calendar.timegm(time.struct_time(i.date_time+(0,0,0)))
author = author or defaultauthor or 'unknown'
if not author.endswith('>'):
author = '%s <>' % author
commit = dulwich.objects.Commit()
commit.tree=treeid
commit.author = author
commit.committer = defaultcommiter
import time
commit.author_time = int(doctimestamp[0])
commit.author_timezone = doctimestamp[1]
if committimestamp is None:
commit.commit_time = int(time.time())
commit.commit_timezone = -1 * time.timezone # use the current timezone
else:
commit.commit_time = int(committimestamp[0])
commit.commit_timezone = committimestamp[1]
#unix timestamp parse form from xml
#tz = dulwhich.parse_timezone('+0100')[0] # ???
#commit.author_timezone = 0 #tz
#commit.encoding = "UTF-8"
ref= 'refs/heads/%s'%refname#.\
# decode('utf-8').encode('ascii',errors='replace').replace('?','_')
uuidrefname = 'refs/heads/%s'%uuidstr
olduuidrefid = repo.refs.read_ref(uuidrefname)
oldnamerefid = repo.refs.read_ref(ref)
if overrideparents is not None:
parents = set(overrideparents)
else:
parents = set()
if olduuidrefid is not None:
parents.add(olduuidrefid)
if oldnamerefid is not None:
parents.add(oldnamerefid)
if len(parents) ==1 and checkforduplicatetree:
parentcommit=repo.get_object(tuple(parents)[0])
parenttree=parentcommit.tree
if parenttree == treeid:
print "Warning: skipped duplicate tree"
return False #commit would be empty
if len(parents) > 0:
commit.parents=list(parents)
neworupdate='Updated'
else:
neworupdate='New'
commit.message = ('%s FreeCAD Document %s\n\n'\
'UUID: %s\n\n%s\n' % ( neworupdate, filename2, uuidstr,propertiesstr))\
.encode('utf-8')
object_store.add_object(commit)
repo.refs[ref]= commit.id
if repo.bare:
repo.refs['refs/heads/master']=commit.id
if olduuidrefid is None or olduuidrefid in parents:
repo.refs[uuidrefname] = commit.id
else:
print "Warning: updating the UUID-ref would create orphan commits"
if oldnamerefid is not None and oldnamerefid not in parents:
print "Probably orphaned commit: %s" % oldnamerefid
return commit.id
def saveandcommit(doc=None,repodir=None,save=True):
import FreeCAD,os
if doc is None:
doc=FreeCAD.activeDocument()
if doc is None or not doc.FileName:
raise ValueError('No Document or no Filename set')
if save:
doc.save()
filename=doc.FileName
if hasattr(FreeCAD,'_doc2git'):
repodir = repodir or FreeCAD._doc2git.get('repopath')
branch = FreeCAD._doc2git.get('branch')
parents = FreeCAD._doc2git.get('parents')
path,name=os.path.split(filename)
if repodir is None:
try: #test if path is a also a git repo
repo=dulwich.repo.Repo(path)
repodir=path
except dulwich.repo.NotGitRepository:
repodir='%s.git' % filename
if not os.path.isdir(repodir):
os.mkdir(repodir)
try:
repo=dulwich.repo.Repo(repodir)
except dulwich.repo.NotGitRepository:
repo=dulwich.repo.Repo.init_bare(repodir)
#commitfile(filename,refname=None,repopath='.',overrideparents=None\
# ,defaultauthor=None,committimestamp=None):
commitid = commitfile(filename,repopath=repodir,refname=branch,
overrideparents=parents)
if not hasattr(FreeCAD,'_doc2git'):
FreeCAD._doc2git={doc:{'repopath':repodir,'branch':branch}}
FreeCAD._doc2git[doc]['parents']=[commitid]
return commitid
def checkoutandload(ref='master',repopath='.'):
try: #test if path is a also a git repo
repo=dulwich.repo.Repo(repopath)
if ref is None: #check if all branches point to the same commit/tree
ref2tree,tree2currentref,tree2parentref = treeids(repo)
if len(tree2currentref) ==1: #all refs contain the same root tree
ref=ref2tree.keys()[0]
else:
raise ValueError('multiple branches in repo')
import FreeCAD
filename,commitid=checkoutfile(ref=ref,zipfilepath=None,\
repopath=repopath,returncommitid=True)
doc=FreeCAD.openDocument(filename)
if not hasattr(FreeCAD,'_doc2git'):
FreeCAD._doc2git={}
FreeCAD._doc2git[doc]={'repopath':repopath,'branch':ref,\
parents:[commitid]}
except dulwich.repo.NotGitRepository:
raise
def _example_check_for_existing_tree():
repo=dulwich.repo.Repo('.')
ref2tree,tree2currentref,tree2parentref = treeids(repo)
#print tree2ref
uuiddict=uuiddir(('.','../Downloads'))
for key,value in uuiddict.iteritems():
#print 'UUID %s' % key
for filename,timestamp,treeid in value:
if treeid in tree2currentref:
print key,filename,'CURRENT',tree2currentref[treeid]
if treeid in tree2parentref:
print key,filename,'parrent',tree2parentref[treeid]
#print treeid[:7],timestamp,filename,tree2ref.get(treeid)
def _example_check_in_all_files_with_given_UUID():
"""checkin all versions of given UUID from a directory"""
uuiddict=uuiddir(('.','../Downloads'))
for uuidstr,refname in (\
("83f098be-a2a6-4527-8ef1-1d2a3a379f19",'hydrophonics'),
("0c776e1b-8dca-49a5-b7f6-8f0484798e2a","gal")):
for filename, timestamp,treeid in uuiddict[uuidstr]:
print treeid[:7],timestamp,refname, filename
commitfile(filename,refname=refname)
if __name__ == '__main__':
import argparse
parser =argparse.ArgumentParser()
parser.add_argument("--no-parents", action='store_true', help =\
"for the commti to have no parents, this might orphan existing"
"commits")
parser.add_argument("-a", "--author", help =\
"set default author for files that Last Modified By Property")
parser.add_argument("-b", "--branch", help =\
"branch name")
parser.add_argument("-c", "--checkout", action='store_true', help =\
"checkout ")
parser.add_argument("-r", "--repo-path", default='.', help =\
"path to the git repo")
parser.add_argument("-s", "--store", action='store_true', help =\
"stores the file in the repo")
parser.add_argument("--tree-in-repo", action='store_true', help =\
"checks if the files given are allready present in the repo")
parser.add_argument("--info", action='store_true', help =\
"show properties of the FCStd files")
parser.add_argument("--test1", action='store_true', help =\
"run test1 ")
parser.add_argument("files", nargs=argparse.REMAINDER)
args = parser.parse_args()
print args
if args.store:
for filename in args.files:
print filename
if args.no_parents:
overrideparents=()
else:
overrideparents=None
commitfile(filename,refname=args.branch,repopath=args.repo_path\
,overrideparents=overrideparents,defaultauthor=\
args.author)
elif args.checkout:
refname = args.branch or 'master'
checkoutfile(ref=refname,zipfilepath=None,repopath=args.repo_path)
elif args.tree_in_repo:
repo=dulwich.repo.Repo(args.repo_path)
ref2tree,tree2currentref,tree2parentref = treeids(repo)
filelist,uuiddict= uuidfilelist(args.files)
import time
for filepath, treeid, uuidstr, ts in filelist:
if treeid in tree2currentref or treeid in tree2parentref:
print '%s %s %s is present' % (treeid[:7],time.strftime("%F",\
time.gmtime(ts)), filepath)
if treeid in tree2currentref:
print 'as current head of refs:',tree2currentref[treeid]
if treeid in tree2parentref:
print 'as parents in refs:',tree2parentref[treeid]
elif args.info:
for filename in args.files:
z=zipfile.ZipFile(filename)
docstr=z.open('Document.xml').read()
propertiesdict=parsedocument(docstr)
print propertiesdict
elif args.test1:
_example_check_for_existing_tree()
else: #list branches
repo=dulwich.repo.Repo(args.repo_path)
ref2tree,tree2currentref,tree2parentref = treeids(repo)
#print ref2tree
for key,value in tree2currentref.iteritems():
print key[:7], ','.join(value)
Copy link

ghost commented Mar 29, 2016

How does one actually use it?
I copied all 4 files to my user macros dir.
I installed dulwich from git.
Then when it still wasn't found I copied /opt/brew/bin/dulwich to dulwitch.py in my macros dir. It's only a tiny py file that loads something else, but I can't tell where it looks, so it was no surprise that it still failed.
So when it failed with a message that it couldn't find dulwich--0.12.1... , I poked around my system at random and in the dulwich source tree I took a wild undocumented stab in that dark that the only thing that looked like it even might be, or contain, the missing suff is this "*.egg" in a build directory. Having no idea what I was really doing, I copied the .egg file to the freecad user macros dir.

I tried to execute "checkoutgui", but it just said can not load porcelain.

I have a few freecad files in a git repo already, whole freecad files with compression level 0, not unzipped freecad files.
So I tried to execute "checkoutandload" and select that git directory, but it just said "repo contains multiple branches" which yes, it does.

So I tried going the other way, I loaded a freecad file, and then tried to execute "saveandcommit", but it just said "variable branch used before assignment".

Ok so I guess I have to somehow tell the script what branch to use. I guess with a config file or some other way to set that variable?

It seems like a lot of cool work, but for lack of the teeniest bit of explanation, I can't actually make use of any of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment