Do a humble attempt to implement something along the lines of bug #229033
authorFabian Groffen <grobian@gentoo.org>
Sun, 27 Jul 2008 11:28:26 +0000 (11:28 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 27 Jul 2008 11:28:26 +0000 (11:28 -0000)
Big problem with SVN is that retrieving the known files is slow and
expensive (it goes over the network), hence should be avoided.

Imlemented Manifest commit in the first batch, if no headers change.
This implementation is a (hopefully) 90% coverage one.  First, not all
keywords are recognised (they never were), second we do not check in
SVN's case if the used keyword is the one that SVN expands.  What we
just try to achieve is to avoid the single Manifest commit on SVN repos
which by default do not use header expansion.  This objective seems to
be made with this commit.

svn path=/main/branches/prefix/; revision=11211

bin/repoman

index 9c0f6b3f94ba6d7b4b3f578db2291bd94f219183..018eb36fc27841d0a562a1c9961289ba00f234fc 100755 (executable)
@@ -1737,19 +1737,22 @@ else:
                mynew=portage.cvstree.findnew(mycvstree,recursive=1,basedir="./")
                myremoved=portage.cvstree.findremoved(mycvstree,recursive=1,basedir="./")
                bin_blob_pattern = re.compile("^-kb$")
-               bin_blobs = set(portage.cvstree.findoption(mycvstree, bin_blob_pattern,
+               expansion = set(portage.cvstree.findoption(mycvstree, bin_blob_pattern,
                        recursive=1, basedir="./"))
 
 
        if vcs == "svn":
                svnstatus = os.popen("svn status").readlines()
                mychanged = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("M") ]
-               for manifest in [ file for file in mychanged if '/Manifest' in file ]:
-                       mychanged.remove(manifest)
-               mynew = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("A") ]
+               mynew     = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("A") ]
                myremoved = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("D") ]
-               # no idea how to detect binaries in SVN
-               bin_blobs = []
+               # in contrast to CVS, SVN expands nothing by default, but of
+               # course proplist's output is horrible.  bin_blobs historically
+               # were just there to see what files need to be checked for
+               # keyword expansion, which is exactly what we do here, so
+               # slightly change the semantic meaning of "bin_blob"...
+               props = os.popen("svn proplist -R").readlines()
+               expansion = [ prop[15:-2] for prop in props if prop.startswith("Properties on '") ]
 
        if vcs:
                if not (mychanged or mynew or myremoved):
@@ -1769,7 +1772,11 @@ else:
        headerstring = "'\$(Header|Id)"
        headerstring += ".*\$'"
        for myfile in myupdates:
-               if myfile in bin_blobs:
+               # for CVS, expansion contains files that are excluded from expansion
+               if vcs == "cvs" and myfile in expansion:
+                       continue
+               # for SVN, expansion contains files that are included in expansion
+               if vcs == "svn" and myfile not in expansion:
                        continue
                myout = commands.getstatusoutput("egrep -q "+headerstring+" "+myfile)
                if myout[0] == 0:
@@ -1825,6 +1832,8 @@ else:
 
        if myupdates or myremoved:
                myfiles = myupdates + myremoved
+               if not myheaders and "sign" not in repoman_settings.features:
+                       myfiles += mymanifests
                fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
                mymsg = os.fdopen(fd, "w")
                mymsg.write(commitmessage)
@@ -1911,8 +1920,8 @@ else:
                        write_atomic(x, "".join(mylines))
 
        manifest_commit_required = True
-       if myheaders or myupdates or myremoved or mynew:
-               myfiles=myheaders+myupdates+myremoved+mynew
+       if myupdates or myremoved or mynew:
+               myfiles=myupdates+myremoved+mynew
                for x in range(len(myfiles)-1, -1, -1):
                        if myfiles[x].count("/") < 4-repolevel:
                                del myfiles[x]