Friday, April 29, 2011

Commits and merges on SVN subdirectories considered harmful?

We have several large subprojects inside our main SVN project root.
I commit and merge only my subproject when working with our release branches, mainly because it's faster.

However, a colleague pointed out this reference to merging subdirectories in Version Control with Subversion (a.k.a "The SVN Book"):

Unfortunately, this is the extent of the warning. The linked section does not give an explanation either.

Is committing and merging SVN subdirectories harmful for release branches?
What about short-lived feature branches?

From stackoverflow
  • One possible explanation is that you could forget parts of a change set.

    If the change sets that you are merging cover files that are outside the subdirectory that you have checked out, then there is always the possibility that you will forget to merge those files.

    For example, if you have a commit like this on trunk:

    r5 | rich | 2009-04-16 22:22:46 +0200 (Thu, 16 Apr 2009) | 2 lines
    Changed paths:
       M /trunk/subdir1/main.c
       M /trunk/subdir2/main.c
    
    Change some stuff
    

    And you then have a checkout of subdir1 from your branch "stable", then you could merge the change set r5 like this:

    $ svn co http://example.com/svn/branches/stable/subdir1
    $ cd subdir1
    $ svn merge -c 5 http://example.com/svn/trunk/subdir1 .
    --- Merging r5 into '.':
    U    main.c
    $ svn ci -m"Merged r5 from trunk"
    

    But this will only merge half of revision 5. Worse still, if you go back and look at the log, it will now show this:

    $ svn log -g http://example.com/svn/
    ...
    ------------------------------------------------------------------------
    r5 | rich | 2009-04-16 22:22:46 +0200 (Thu, 16 Apr 2009) | 2 lines
    Changed paths:
       M /trunk/subdir1/main.c
       M /trunk/subdir2/main.c
    Merged via: r6
    
    Change some stuff
    

    So it looks like you've merged the whole commit, when in fact you have only merged some of it. Of course r6 does show that only 1 file has changed on the stable branch.

    ------------------------------------------------------------------------
    r6 | rich | 2009-04-16 22:28:16 +0200 (Thu, 16 Apr 2009) | 1 line
    Changed paths:
       M /branches/stable/subdir2
       M /branches/stable/subdir2/main.c
    
    Merge revision 5 from trunk
    

    Someone has to remember, or notice, that only part of the change set got merged and the rest needs doing. Not using subdirectory merges avoids this problem.

    There are times when you really don't want to merge all of a previous commit, and the above scenario is exactly what you intended to do. In that case, it is probably best to add a good commit message describing your intentions.

    Gary.Ray : +1 - Great answer and example
  • Committing should not have a problem, but in merges SVN tracks what is and is not merged.

    Therefore I assume you want to merge at the root to simplify future merges (in respect to the data set size being compared by SVN).

  • For subversion versions prior to 1.5, merging subdirectories made later merges of the rest of the directory tree really complicated. If you merged a directory, svn simply applied all the changes made in that directory to the other branch. If you had already merged a subdirectory and then tried to merge the main directory, all the changes in the subdirectory were already in the target branch (since you merged them before). Svn now didn't know that these changes were from a previous merge, it just saw that there were things "in the way" when it tried to merge the subdirectory, resulting in lots of conflicts.

    To avoid this you would have had to take care to only merge the directories that you hadn't merged before, making the whole process much more complicated. You had to remember exactly which revisions of which subdirectories you already had merged and only apply the remaining changes of the remaining directories/revisions. This can get confusing. Always merging the whole branch made this much easier. Current versions of subversion keep track of previous merges internally, so that these problems can be avoided.

    Committing subdirectories is no problem. For svn this is just a normal, global revision of the repository. In that revision there will be only changes in one subdirectory, but for svn it's still a new version of the whole repository, just like any other commit.

    rq : In svn 1.5+ this is not actually the case. Merging a subdirectory, then merging the rest of the same commit from the root does not "re-merge" the stuff already merged in the subdirectory causing a conflict. The svn:mergeinfo property prevents that from happening.
    sth : Glad to hear that. It really made subversions merging unnecessarily and annoyingly complex, to the point of uselessness.
  • Another reason for this could be that merging only to the root limits the number of svn:mergeinfo properties that are going to be set on the folders/files in your repository.

    mskfisher : Your answer is more in the spirit of my question, thanks. My gut feel is that since our subprojects are only one level deep, setting mergeinfo on one of those would still be reasonable.

Creating anonymous types based on lambda expression

Hi,

I'm trying to create a Fluent Interface to the Winforms Datagrid. This should allow me to use a typed datasource and easy use of properties of properties (Order.Custom.FullName)

I'm adding the columns on initialization and trying to set the property to use there:

dgv.With<Order>().Column("Client Name").On(x => x.Client.FullName);

The original question then poses itself when setting the Datasource:

dgv.SetTypedDatasource<T>(IList<Order> orders)

A big problem here is that Generic Controls are not possible (I guess), so that T cannot be specified for the class, but has to be specified per method...

I want to create a list of anonymous types, based on a given property in a lambda expression:

something like:

ProcessList<Client>(clientList, x => x.FullName);

Is it possible to do something like this:

[Edit] Note that in practice, the expressions will be set earlier, and will be fetched elsewhere...

public void ProcessList<T>(IList<T> sourceList, Expression<Func<T, object>> expression)
{
    var list =
        (from T x
         in sourceList
         select new { expression })
         .ToList();

    // process list ....  grid.DataSource = list;
}

So, I would like to create anonymous types based on the given expression. I know I can evaluate that expression to retrieve the correct properties.

I'm kinda stuck, is something like this possible?

Any ideas?

From stackoverflow
  • Well, with a simple call to Select you can come very close:

    ProcessList(clientList.Select(x => new { x.FullName }));
    
    ...
    
    public void ProcessList<T>(IEnumerable<T> list)
    {
        // process list ... T will be an anonymous type by now
        grid.DataSource = list;
    }
    

    (That assumes you don't need the original list in ProcessList as well. If you do, move the select into there.)

    Bertvan : so true, I was getting it all wrong...
    Marc Gravell : Note that if that is a winform grid, it will need a ToList() - webform grids are happy with IEnumerable, though.
    Bertvan : Still, not quite what I need, I'll explain a bit more in the question.
    Bertvan : @Marc, yes I forgot that line :)
  • isn't that just grid.DataSource = sourceList.AsQueryable().Select(expression).ToList();

    Note that it would be better to introduce a second generic, such that the list is typed:

        public static void ProcessList<TSource, TValue>(
            IList<TSource> sourceList,
            Func<TSource, TValue> expression)
        {
            grid.DataSource = sourceList.Select(expression).ToList();
        }
    

    Note I switched from Expression<...> to just Func<...>, as it seemed to serve no purpose.

Possible to export FireFox extensions and settings?

Want my FireFox at work to be in sync with my FireFox at my home. Is there a way to simply export all extensions and settings?

From stackoverflow
  • Try MozBackup

  • Just copy the files from your FireFox/Profiles folder to get the settings/saved passwords etc.

    That contains settngs and passwords. I believe you can do a similar process for extensions as well

  • Take a look at Mozilla Weave. An alternative is Foxmarks although I think that's limited to just bookmarks.

  • Since extensions are stored in your profile, you could just make a copy of it to a Flash drive or something.

  • FEBE / CLEO for plugin export/import

filter for many to many field

so I have this model:

class Message(models.Model):
    creator = models.ForeignKey(User, unique=True)
    note = models.CharField(max_length=200, blank=True)
    recipients = models.ManyToManyField(User, related_name="shared_to")
    read = models.ManyToManyField(User, related_name="read", blank=True)

I want to filter on people who are in both recipients and read, currently I'm doing this.

messages = user.shared_to.all()

for message in messages:
    if user not in message.read:
        do something

I'm sure there is a way to filter this but I can't figure out how.

From stackoverflow
  • I think that I originally misread your question. Try the following query.

    for message in user.shared_to.exclude(read__id__in=[user.id]):
      do_something()
    
  • If you use the Django development version, or wait until version 1.1 is released, then your filters can reference other fields in the model. So, your query would look like this:

    >>> Message.objects.filter(reciepients=F('read'))
    

    (Note: I spelled reciepients the same as you had in your model, although the correct spelling would be "recipients")

    Edit:

    Ok, your question is confusing. When I gave the above answer I was reading your statement that you wanted all users who were in both "recipients" and "read"). But then reading your code snippet it looks like you want a list of users who are recipients, but not yet in the "read" list.

    This is probably what you want, but I'm not completely sure because of the vague requirements and I can't quickly test it:

    # Get list of recipients
    shared_to = Message.shared_to.all().values('id')
    
    # Now list of recipients who are not in the read field
    unread = Message.objects.exclude(recipients__in=shared_to)
    

    This will make a single query, but if you are using MySQL it could still be more efficient to do two queries (read the Performance considerations warning).

Odd Bibtex behaviour in a Latex document

I added a line "\cite{test}" as a test to my working Latex document. When I compiled the bibtex "!bibtex name_of_my_file, I got the expected error:

Warning--I didn't find a database entry for "test"

Then, I removed the line and compiled the bibtex again, hoping to have a working Latex file again. However, the same error occurs, even with a fresh shell. I cannot understand the behaviour. What is the logic? How can I get my Latex document working again?

[Updated Info] The problem dissapeared as unexpectedly as it emerged. I have no idea why but it works now. Do you know the reason for the odd behaviour?

From stackoverflow
  • Rerun latex to regenerate the aux file.

    Have a look at this discussion for pointers to a bit more information. Basically, you may have taken your citation out of the .tex file, but it still exists in one of the derived files (aux, bbl, whatever...)

  • I think you are tripping over the multi-pass nature of LaTex plus Bibtex. If you look at Step 3 in this discussion, you'll see the following:

    The first run (through latex) generates an auxiliary file, paper.aux, containing information about citations (and other types of references), the bibliography style used, and the name of the bibtex database. The second run (through bibtex) uses the information in the auxiliary file, along with the data contained in the bibtex database, to create a file paper.bbl. This file contains a thebibliography environment with \bibitem entries formatted according to the bibliography style specified.

    So, what I think is happening is that your name_of_my_file.aux file still contains your placeholder \cite{test}. If you remove the auxiliary file, you should be able to start over with:

    latex name_of_my_file
    bibtex name_of_my_file
    latex name_of_my_file
    latex name_of_my_file
    

    [Update based on additional info]: The problem was that you had a .aux file with your \cite{} still embedded. The second time that you ran latex, you overrode the old file with the new. That's why the complete set of steps includes an initial latex call, a bibtex call and two follow-up latex calls. Think of it as a multi-pass compiler and it might be more intuitive.

    Jouni K. Seppänen : It is even possible to get the aux file into a sufficiently bad state that LaTeX quits before writing a new aux file (this has happened to me), and probably also to a state that is propagated into the new aux file even though the TeX file no longer produces it (this is just speculation and might make a fun research problem). To be sure that your document is reproducible, you need to remove the aux file before the command sequence.
    Bob Cross : Very true - if you're really panicked, the one file that you must keep is name_of_my_file.tex.
    Masi : "The second time that you ran latex, you overrode the old file with the new." I did more than two times. I run the command "!bibtex the_file" at least 50 times, and the command "pdflatex %" about 30 times. It may well be some other reason. Perhaps, it is due to the Mac OS, or something like that. Dunno.
  • You could have a look at latexmk, which will take care of the fix point compilation for you.

    Anyway, you should be able to build the document (pdflatex blah.tex), even if you're missing a bibliography item. The corresponding references will just appear as question marks in the PDF.

actionscript + javascript

Hello all. I'd like to call a javascript function from an embedded .swf file. Specifically, I'd like to call a function in one of my externally linked javascript files from within:

function loadTrack(){



//Radio Mode feature by nosferathoo, more info in: https://sourceforge.net/tracker/index.php?func=detail&aid=1341940&group_id=128363&atid=711474

if (radio_mode && track_index==playlist_size-1) {

 playlist_url=playlist_array[track_index].location;

 for (i=0;i<playlist_mc.track_count;++i) {

  removeMovieClip(playlist_mc.tracks_mc["track_"+i+"_mc"]);

 }

 playlist_mc.track_count=0;

 playlist_size=0;

 track_index=0;

 autoload=true;

 autoplay=true;

 loadPlaylist();

 return(0);

}



start_btn_mc.start_btn._visible = false;

track_display_mc.display_txt.text = playlist_array[track_index].label;

if(track_display_mc.display_txt._width>track_display_mc.mask_mc._width){

 track_display_mc.onEnterFrame = scrollTitle;

}else{

 track_display_mc.onEnterFrame = null;

 track_display_mc.display_txt._x = 0;

}

mysound.loadSound(playlist_array[track_index].location,true);

play_mc.gotoAndStop(2)



//info button

if(playlist_array[track_index].info!=undefined){

 info_mc._visible = true;

 info_mc.info_btn.onPress = function(){

  getURL(playlist_array[track_index].info,"_blank")

 }

 info_mc.info_btn.onRollOver = function(){

  track_display_mc.display_txt.text = info_button_text;

 }

 info_mc.info_btn.onRollOut = function(){

  track_display_mc.display_txt.text = playlist_array[track_index].label;

 }

}else{

 info_mc._visible = false;

}

resizeUI();

_root.onEnterFrame=function(){

 //HACK doesnt need to set the volume at every enterframe

 mysound.setVolume(this.volume_level)

 var load_percent = (mysound.getBytesLoaded()/mysound.getBytesTotal())*100

 track_display_mc.loader_mc.load_bar_mc._xscale = load_percent;

 if(mysound.getBytesLoaded()==mysound.getBytesTotal()){

  //_root.onEnterFrame = null;

 }

}

}

which is in an .as file which I assume somehow becomes the swf file. How would I go about this and 're-compile' the .as file?

From stackoverflow
  •   getURL("javascript:displayPost(" + postId + "," + feedId +")");
    

    From:

    You can also look into the following:

    http://osflash.org/projects/flashjs/tutorials/jstoas

    danwoods : Whoa! Super fast response! I can't test it right now but that looks like it should work. Thanks!
    danwoods : I'm assuming postId and feedId are parameters of displayPost?
  • Also incase anyone in the future is looking at this question the Actionscript 3 version of altCognito's answer is like this:

    ExternalInterface.call("displayPost",postId,feedId);
    
  • Let's compile those answers together for AS2 and AS3 using JS injection AND the ExternalInterface (both ways work in BOTH languages)

    AS2:

    
    // to use javascript injection in a url request
    getURL("javascript:displayPost(" + postId + "," + feedId +");", "_self");
    
    // to use the external interface
    import flash.external.ExternalInterface;
    ExternalInterface.call("displayPost",postId,feedId);
    

    AS3:

    
    // to use javascript injection in a url request
    navigateToURL(new URLRequest("javascript:displayPost(" + postId + "," + feedId +");"), "_self");
    
    // to use the external interface
    import flash.external.ExternalInterface;
    ExternalInterface.call("displayPost",postId,feedId);
    

    Notice that in AS2 and AS3 the ExternalInterface method is the exact same (ExternalInterface was introduced in Flash 8 for AS2). And in AS2 and AS3 the javascript injection method are the same except that it's navigateToURL instead of getURL, and the url string is wrapped in new URLRequest(), because it needs a URLRequest object. Also when using javascript injection, it's a good practice to set the target window to "_self" to avoid a new tab or window from opening.

How to validate compliant XML sitemap?

For the following header I get the same two errors on all my sitemaps. It's confusing because, if Google can't read my sitemap, then how can they say that each URL has the same priority? The header counts as line 2, after the XML declaration. Google claims only to have indexed about 2% of the URLs from the maps. Please help.

UPDATE: I think the problem is that I don't know how to validate against a schema. How to do that?

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

==Parsing error
We were unable to read your Sitemap. It may contain an entry we are 
unable to recognize. Please validate your Sitemap before resubmitting.

==Notice
All the URLs in your Sitemap have the same priority...

UPDATE: Please be patient, first time validating XML. I don't understand the errors.

Errors in the XML document:
    4: 80 SchemaLocation: schemaLocation value = 'http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd' must have even number of URI's.
    4: 80 cvc-elt.1: Cannot find the declaration of element 'urlset'.

XML document:
1   <?xml version="1.0" encoding="UTF-8"?>
2   <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4     xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
5     <url>
6       <loc>http://nutrograph.com/1-butter-salted</loc>
7       <changefreq>monthly</changefreq>
8       <priority>0.8</priority>
9     </url>
10    <url>
11      <loc>http://nutrograph.com/2-butter-whipped-with-salt</loc>
12      <changefreq>monthly</changefreq>
13      <priority>0.8</priority>
14    </url>
15  </urlset>
From stackoverflow
  • It's real hard to diagnose what could be wrong without the sitemap itself. Or did I miss something obvious?

    Jesse : The sitemap is well-formed. I think the header is wrong.
  • Have you validated your XML against the schema given here: http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd

    If yes, what was the result?

    If not, what is the URL of your sitemap?

    If you don't know how to validate the XML against the schema, use http://www.xmlvalidation.com/

    Paste the sitemap-XML there, click on "Validate against external XML schema" and paste the schema after clicking the Validate-button.

    This will tell you what's wrong with your XML. If you don't know how to interpret the result, please amend your original question accordingly.

    Edit: The error was a missing namesapce-URL in the schemaLocation. The first tag has to look like this:

    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
    
    Jesse : I'm not sure how to do that..
  • Strike the above. Looking at Googles site, their sitemap header seems to be a little longer than yours.

    It's on this page: https://www.google.com/webmasters/tools/docs/en/protocol.html

    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
    http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
    
    Jesse : I think the problem is that I don't know how to validate against a schema.
    Jesse : That was the format I tried first. It didn't seem to work. I'll try it again.
  • Nottice that the schemaLocation has 2 URi's... (must have even number of URI's)

    It should look like this: **

    xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"

    **