Search Results: "will"

18 February 2012

Dirk Eddelbuettel: Using Rcout with Rcpp / RcppArmadillo to coordinate output with R

The new RcppArmadillo release 0.2.35 now supports the Rcpp::Rcout output stream device. Based on a contributed Rcpp patch by Jelper Ypma, the Rcpp::Rcout output stream gets redirected to R's buffered output. In other words, R's own output and that eminating from C++ code using Rcpp::Rcout are now both in sync. This avoids a stern warning from Section 5.6 in the Writing R Extensions manual:
Using C++ iostreams, as in this example, is best avoided. There is no guarantee that the output will appear in the R console, and indeed it will not on the R for Windows console. Use R code or the C entry points (*note Printing) for all I/O if at all possible.
and does in fact provide exactly what is recommended: the same entry points R itself uses. Below is a sample program, once again using the wonderful inline package to compile, load and link C++ code into R from a simple text variable submitted to the cxxfunction. What is shown in R code to load the package, the definition of the C++ code as assigned to a variable src and the creation of the dynamically-loadaded R function called fun which contains the code from we compiled, link and load via a single call to cxxfunction() given src.
library
library(inline)
src <- '
  Rcpp::Rcout << "Armadillo version: " << arma::arma_version::as_string() << std::endl;
  // directly specify the matrix size (elements are uninitialised)
  arma::mat A(2,3);
  // .n_rows = number of rows    (read only)
  // .n_cols = number of columns (read only)
  Rcpp::Rcout << "A.n_rows = " << A.n_rows << std::endl;
  Rcpp::Rcout << "A.n_cols = " << A.n_cols << std::endl;
  // directly access an element (indexing starts at 0)
  A(1,2) = 456.0;
  A.print("A:");
  // scalars are treated as a 1x1 matrix,
  // hence the code below will set A to have a size of 1x1
  A = 5.0;
  A.print("A:");
  // if you want a matrix with all elements set to a particular value
  // the .fill() member function can be used
  A.set_size(3,3);
  A.fill(5.0);
  A.print("A:");
  arma::mat B;
  // endr indicates "end of row"
  B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr
    << 0.108929 << 0.830123 << 0.891726 << 0.895283 << arma::endr
    << 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr
    << 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr;
  // print to the cout stream
  // with an optional string before the contents of the matrix
  B.print("B:");
  // the << operator can also be used to print the matrix
  // to an arbitrary stream (cout in this case)
  Rcpp::Rcout << "B:" << std::endl << B << std::endl;
  // save to disk
  B.save("B.txt", arma::raw_ascii);
  // load from disk
  arma::mat C;
  C.load("B.txt");
  C += 2.0 * B;
  C.print("C:");
  // submatrix types:
  //
  // .submat(first_row, first_column, last_row, last_column)
  // .row(row_number)
  // .col(column_number)
  // .cols(first_column, last_column)
  // .rows(first_row, last_row)
  Rcpp::Rcout << "C.submat(0,0,3,1) =" << std::endl;
  Rcpp::Rcout << C.submat(0,0,3,1) << std::endl;
  // generate the identity matrix
  arma::mat D = arma::eye<arma::mat>(4,4);
  D.submat(0,0,3,1) = C.cols(1,2);
  D.print("D:");
  // transpose
  Rcpp::Rcout << "trans(B) =" << std::endl;
  Rcpp::Rcout << trans(B) << std::endl;
  // maximum from each column (traverse along rows)
  Rcpp::Rcout << "max(B) =" << std::endl;
  Rcpp::Rcout << max(B) << std::endl;
  // maximum from each row (traverse along columns)
  Rcpp::Rcout << "max(B,1) =" << std::endl;
  Rcpp::Rcout << max(B,1) << std::endl;
  // maximum value in B
  Rcpp::Rcout << "max(max(B)) = " << max(max(B)) << std::endl;
  // sum of each column (traverse along rows)
  Rcpp::Rcout << "sum(B) =" << std::endl;
  Rcpp::Rcout << sum(B) << std::endl;
  // sum of each row (traverse along columns)
  Rcpp::Rcout << "sum(B,1) =" << std::endl;
  Rcpp::Rcout << sum(B,1) << std::endl;
  // sum of all elements
  Rcpp::Rcout << "sum(sum(B)) = " << sum(sum(B)) << std::endl;
  Rcpp::Rcout << "accu(B)     = " << accu(B) << std::endl;
  // trace = sum along diagonal
  Rcpp::Rcout << "trace(B)    = " << trace(B) << std::endl;
  Rcpp::Rcout << std::endl;
'
fun <- cxxfunction(signature(), body=src, plugin="RcppArmadillo")
setwd("/tmp")                           # adjust on other OSs
fun()                                   # output to stdout
sink("rcpparma.log.txt")                # start 'sink' to output to file
fun()                                   # no output to screen
sink()                                  # stop 'sink'
We then switch to a temporary directory (as the example code, taken from one of the two examples in Conrad's Armadillo sources, creates a temporary file) and run the new function. To demontrate how it does in fact now mesh perfectly with R, we create an output 'sink' (which catches all output) and re-run. This simple example demonstrated how we can use the new Rcout output stream from Rcpp to have dynamically-loaded C++ code cooperate more cleanly with the (buffered) R output. It also demontrated some of the nice features in Armadillo which we bring to R via RcppArmadillo.

Neil Williams: Introducing ladder

We needed a new package at work and once I'd written it, I realised that it could well be useful for others, so I did the ITP and the package is now in Debian unstable.

Ladder - Stepwise repository upgrade tool

Ladder creates a local repository of packages required
to upgrade a tarball of a chroot to a new milestone or
software release.
.
The repository can be signed and includes all specified
target packages and dependencies. The repository can then
be distributed and used to upgrade multiple devices in
sequence without needing network access.


The only dependencies are some simple perl modules, reprepro for the repository, apt and gnupg for the signing. None of those need to be particularly recent versions, so once ladder has had a little time in testing, I will be doing a backport to Squeeze. Lenny is a little less likely but eminently possible if someone specifically asks for it. Not that it particularly needs a backport mind, if you want to run ladder on some other Debian-based system, it's simply a case of installing the version in unstable. reprepro was in Lenny at a suitable version for what ladder requires, so any system remotely recent should be able to run ladder without changes.

Normally, whenever you need to upgrade a device, you need to get that device onto a network, get access over the serial port or some form of pre-configured network connection, run the commands and clean up afterwards. OK, now do that again... oh and here are another 40 or 100 devices which all need precisely the same thing done and they all have to be shipped to paying customers today. What does any geek do? Script it.

Ladder is part of that process. There would need to be some scripting / programming support on the devices concerned but ladder makes it easier to put that support in place at the design stage and then automate the actual update without the device needing to get onto a network and, potentially, allowing you to decide how to offer the upgrade (automatic, user involvement, engineers only etc.) Once that is implemented, the device is simply pointed at a locally mounted filesystem which contains the ladder step for the migration. Each step is a SecureApt signed repository which is available at a deterministic location which can be easily scripted and which contains only the packages necessary (with dependencies) to upgrade any device installed at Milestone A to Milestone B. Nice and small, only the stuff you need, whatever architecture you like and if you need to migrate from Milestone A to Milestone D, then you create a few steps on the ladder and automate the migration from A to B to C to D. All you need is enough space on whatever local media you need to use to plug into the devices. Then copy the media enough times, start the interface on each device and do something useful whilst the upgrade happens. Then, when the next lot need to be upgraded, you already have the media... Oh and ladder does not need to run on the same architecture as the devices - all package handling is entirely architecture-neutral. So create the ladder steps and media on your fast x86 machines and then let the slower SSD devices take their own sweet time via automation. Simple - maybe, hopefully.

I'm expressly talking about devices here because this is where the original requirement arose - embedded devices which don't have direct / automatic / accessible network ports or even a working network configuration preset. These aren't new images to flash onto the device either, these are apt repositories, so only the stuff which needs to be changed is changed which saves a lot of time writing to slow SSD storage.

If the mechanism sounds familiar, yes, it's using the same principles as xapt, multistrap and emdebian-grip but I thought it could be useful, so I generalised the interface (a bit) and uploaded.

Let me know via the BTS if you need tweaks to the support. Ladder isn't particularly about getting desktop machines from Debian Potato to Debian Wheezy because you need to identify a target package to be the top point of the dependency chain which gets into the step repository and all devices should start with the same packages at the same versions. Normally, the kind of devices I use at work have a single top level application which is the sole user interface and which directly or indirectly depends on all the other software required for that device. Whilst the target package value could take a few carefully selected packages instead of just one and there is support for an extra packages field, it's not intended / expected to be useful for desktops. This is for use with multiple devices which all have the same package selection, are at the same milestone at the start and which all need to migrate smoothly to whatever milestone is intended - one step at a time. Ladder could be used to migrate between Debian releases and I've included example config files to support that, but the principle usage is with internal / proprietary repositories based on a common Debian stable platform where the user interface software is managed via identifiable milestones and where users have no direct control over installing packages. It's a production / manufacturing support tool more than a user / admin support tool. If you want to manage servers and desktops which allow users to install (or request to be installed) arbitrary packages, there are plenty of tools which already support this and are used by DSA in Debian for exactly these tasks. Ladder is not puppet but Linp didn't sound like a good name...

Ladder step repositories only include the binary packages, not sources - so if the migration is not going to be done in-house and you're expecting to distribute these steps to users somehow, ensure that the original source repository is available online for the Debian / free software packages concerned. If you can't do that (because the source is proprietary), you possibly shouldn't be distributing the binaries as a user update mechanism in the first place because each step will include packages from the core Debian system which need to have the sources available when distributed.

Inevitably, the ladder source package already contains two POT files for translations of the runtime messages and the POD based manpage. I expect to need to expand / clarify the manpage in due course, so don't rush to translate it yet as it's likely to change.

Mike Hommey: How to waste a lot of space without knowing

const char *foo = "foo";
This was recently mentioned on bugzilla, and the problem is usually underestimated, so I thought I would give some details about what is wrong with the code above. The first common mistake here is to believe foo is a constant. It is a pointer to a constant. In practical ELF terms, this means the pointer lives in the .data section, and the string constant in .rodata. The following code defines a constant pointer to a constant:
const char * const foo = "foo";
The above code will put both the pointer and the string constant in .rodata. But keeping a constant pointer to a constant string is pointless. In the above examples, the string itself is 4 bytes (3 characters and a zero termination). On 32-bits architectures, a pointer is 4 bytes, so storing the pointer and the string takes 8 bytes. A 100% overhead. On 64-bits architectures, a pointer is 8 bytes, putting the total weight at 12 bytes, a 200% overhead. The overhead is always the same size, though, so the longer the string, the smaller the overhead, relatively to the string size. But there is another, not well known, hidden overhead: relocations. When loading a library in memory, its base address varies depending on how many other libraries were loaded beforehand, or depending on the use of address space layout randomization (ASLR). This also applies to programs built as position independent executables (PIE). For pointers embedded in the library or program image to point to the appropriate place, they need to be adjusted to the base address where the program or library is loaded. This process is called relocation. The relocation process requires information which is stored in .rel.* or .rela.* ELF sections. Each pointer needs one relocation. The relocation overhead varies depending on the relocation type and the architecture. REL relocations use 2 words, and RELA relocations use 3 words, where a word is 4 bytes on 32-bits architectures and 8 bytes on 64-bits architectures. On x86 and ARM, to mention the most popular 32-bits architectures nowadays, REL relocations are used, which makes a relocation weigh 8 bytes. This puts the pointer overhead for our example string to 12 bytes, or 300% of the string size. On x86-64, RELA relocations are used, making a relocation weigh 24 bytes! This puts the pointer overhead for our example string to 32 bytes, or 800% of the string size! Another hidden cost of using a pointer to a constant is that every time it is used in the code, there will be pointer dereference. A function as simple as
int bar() return foo;
weighs one instruction more when foo is defined const char *. On x86, that instruction weighs 2 bytes. On x86-64, 3 bytes. On ARM, 4 bytes (or 2 in Thumb). That weight can vary depending on the additional instructions required, but you get the idea: using a pointer to a constant also adds overhead to the code, both in time and space. Also, if the string is defined as a constant instead of being used as a literal in the code, chances are it s used several times, multiplying the number of such instructions. Update: Note that in the case of const char * const, the compiler will optimize these instruction and avoid reading the pointer, since it s never going to change. The symbol for foo is also exported, making it available from other libraries or programs, which might not be required, but also adds its own overhead: an entry in the symbols table (5 words), an entry in the string table for the symbol name (strlen("foo") + 1) and an entry in the symbols hash chain table (4 bytes if only one type of hash table (sysv or GNU) is present, 8 if both are present), and possibly an entry in the symbols hash bucket table, depending on the other exported symbols (4 or 8 bytes, as chain table). It can also affect the size of the bloom filter table in the GNU symbol hash table. So here we are, with a seemingly tiny 3 character string possibly taking 64 bytes or more! Now imagine what happens when you have an array of such tiny strings. This also doesn t only apply to strings, it applies to any kind of global pointer to constants. In conclusion, using a definition like
const char *foo = "foo";
is almost never what you want. Instead, you want to use one of the following forms:

Craig Small: VMware Player on Debian

For various reasons, having vmware running on my desktop would be kind of useful. VMware provide a Free (as in beer) version of their software called VMware Player. I downloaded the file VMware-Player-4.0.2-591240.x86_64.bundle off their website and tried to build it. It failed to build. Given my previous lack of success with VMware server, I wasn t too surprised. What was surprising was it wasn t too hard to fix it. The problem was that the vmnet module would not compile and that was due to three things: The patch is only a few lines and means I can compile vmware on my Debian sid computer running kernel 3.2.0-1 vmnet.patch To use it, you will need to find where the modules are built, for me it is /usr/lib/vmware/modules/source
  1. mv vmnet.tar vmnet2.tar
  2. tar xf vmnet2.tar
  3. patch -p1 < vmnet.patch
  4. tar cf vmnet.tar vmnet-only
With that you can run the player which will try to build the modules and you re done!

Benjamin Mako Hill: Advice for Prospective Doctoral Students

There is tons of advice on the Internet (e.g., on the academic blogs I read) for prospective doctoral students. I am very happy with my own graduate school choices but I feel that I basically got lucky. Few people are saying the two things I really wish someone had told me before I made the decision to get a PhD: Most People Getting Doctorates Probably Shouldn't In most fields, the only thing you need a PhD for is to become a professor -- and even this requirement can be flexible. You can have almost any job in any company or non-profit without a PhD. You can teach without a PhD. You can write books without a PhD. You can do research and work in thinktanks without a PhD. You don't even always need a PhD to grant PhDs to other people: two of my advisors at the Media Lab supervised PhD work but did not have doctorates themselves! Becoming a tenured professor is more difficult without a doctorate, but it is not impossible. There are grants and jobs outside of universities that require doctorates, but not nearly as many as most people applying for PhDs programs think. Getting a doctorate can even hurt: If you want to work in a company or non-profit, you are usually better off with 4-6 years of experience doing the kind of work you want to do than with the doctorate and the less relevant experience of getting one. Starting salaries for people with doctorates are often higher than for people with masters degrees. But salaries for people with masters degrees and 5 years of experience are even higher -- and that's before you take into account the opportunity costs of working for relatively low graduate student wages for half a decade. PhD take an enormous amount of time and, in most programs, you spend a huge amount of this time doing academic busy work, teaching, applying for grants or fellowships, and writing academic papers that very few people read. These are skills you'll need to be a successful professor. They are useful skills for other jobs too, but not as useful as the experience of actually doing those other jobs for the time it takes to get the degree. Evaluating Graduate Programs If you are still convinced you need a doctorate, or any graduate degree for that matter, you will need to pick a program. Plenty of people will offer advice on how to pick the right program and trying to balance all the complicated and contradictory advice can be difficult. Although I love my program and advisors, I've known many less happy students. Toward that end, there are two pieces of meta-advice that I wish everybody was told before they applied:
  1. Find recent graduates of the program you are considering, and the faculty advisor(s) you are planning on working with, and look at where they are now. Are these ex-students doing the kind of work that you want to do? Are they at great programs at great universities? Chances are good that a PhD program and its faculty will prepare future students to be like, and do work like, the students they have trained in the past. Programs that consistently make good placements are preparing their students well, supporting them, making sure they have the resources necessary to do good work, and helping their students when they are on the job market. A program whose students do poorly, or just end doing work that isn't like the kind you want to do, will probably fail you too.

  2. If recent graduates seem to be generally successful and doing the kind of work you want to do, find one who looks most like the kind of academic you want to become and talk to them about their experience. Chances are, your faculty advisors will overlap with theirs and your experience will be similar. Ex-students can tell you the strengths of weaknesses of the program you are considering and what to watch out for. If they had a horrible experience, there's a decent chance you will too, and they will tell you so.

Doing these two things means you don't have to worry about trying to think of all the axes on which you want to evaluate a program or pour through admissions material which is only tangentially connected to the reality you'll live for a long time. What matters most is the outcomes, of course, because you're be living the rest of your life for a lot longer than you'll be in the PhD program.

17 February 2012

Dirk Eddelbuettel: Rcpp 0.9.10

A new release 0.9.10 of Rcpp is now on CRAN and in Debian. This is mostly internal release with a little bit of code reorgination (some of which will be used by a forthcoming RcppArmadillo release), some changes to make R CMD check happy, and one or two new features. The complete NEWS entry for 0.9.10 is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
0.9.10  2012-02-16
    o   Rearrange headers so that Rcpp::Rcout can be used by RcppArmadillo et al
    o   New Rcpp sugar function mapply (for limited to two or three input vectors)
    o   Added custom version of the Rcpp sugar diff function for numeric vectors
        skipping unncesserry checks for NA
    o   Some internal code changes to reflect changes and stricter requirements
        in R CMD check in the current R-devel versions
    
    o   Corrected fixed-value initialization for IntegerVector (with thanks to
        Gregor Kastner for spotting this)
    o   New Rcpp-FAQ entry on simple way to a set compiler option for cxxfunction
Thanks to CRANberries, you can also look at a diff to the previous release 0.9.9. As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page

16 February 2012

Tanguy Ortolo: OpenSSH tip: connection sharing

The last versions of OpenSSH brought an interesting feature: sharing multiple sessions over a single connection. When enabled, this is how it works:
  1. The first time you open an SSH connection to a server (including anything that works on top of SSH, like SCP, SFTP, rsync or Git), it opens a network connection as usual. It also opens a local Unix socket and listens to it for later use.
  2. The next times you open an SSH connection to that server while the first one is still open, instead of opening a new network connection, it connects to that local Unix socket and lets the first SSH client carry its new session.
Advantages Disadvantages Just like SSH agents, there is one major side-effect to take into account: new remote sessions can be opened without a password. Never use such a feature on a public computer if you are used to temporarily leave running sessions: here, locking them would not protect other people to get a shell access to your remote account! Configuration In ~/.ssh/config or /etc/ssh/ssh_config:
ControlPath ~/.ssh/control-%r@%h:%p
ControlMaster auto
ControlPersist 1
ControlPath
The name template for the session sharing Unix sockets. See the ssh_config(5) manpage for the syntax.
ControlMaster
Lets the SSH client use the session sharing socket if it exists or create it and listen otherwise.
ControlPersist
Usually, the first client to a given server is in charge of the connection sharing. It will then stay in foreground even if you terminate the session it is used for, until every other clients using its socket has finished, and forcefully terminating it will have the effect of terminating these clients! With that option, the master connection is put in background and will only terminate when no client needs it any more (one second after that, in fact), and you will be able to terminate the first session without kicking the other ones.
Try it! Apply this configuration and connect several times to a single host, to see the difference

Eddy Petri&#537;or: HOWTO: Git - reauthor/fix author and committer email and author name after a git cvsimport

You might find yourself at some moment when your git repository imported from CVS does not contain all the correct names and email addresses of the commits which were once in CVS but are now part of your project history in your git repo. Or you might do a cvsimport which missed a few authors.

Let's suppose you first import the cvs repo into git, but then you realise you missed some authors.

Before being able to do a git cvsimport, you need a checkout of the module or cvs subdir that you want to turn into its own git repo.

For ease of use I defined CVSCMD as
cvs -z9 -d :pserver:my_cvs_id@cvs.server.com:/root_dir
You will need to replace the items written in italics according to you situation, more exactly, you need to define 'my_cvs_id', 'cvs.server.com' and 'root_dir'. If your acces method to the server is not pserver, you should change that accordingly. This information should be available from your project admin or pages.


Check out the desired module or even subdir of a module

$CVSCMD checkout -d localdirname MODULE/path/to/subdir

git cvsimport -A ../authors -m -z 600 -C ../new-git-repo -R

How to find out the commits which do need rewriting

The way to limit yourself only to the commits that had no cvs-git author and commit information on git-cvsimport time is to use a filter like this:
git log -E --author='^[^@]*$' --pretty=format:%h
This tells git log to print only the abbreviated hashes (%h) for the commits that have NO '@' sign in the 'Author:', which happens if no cvs user id to git author and email was provided in the authors file and git cvsimport time.

We will use this command's output to tell later git filter-branch which commits need rewriting. *

But before that...

How do we find if our authors file is complete?

For this task we'll use a slighly modified form of the previous command and some shell script magic.
git log -E --author='^[^@]*$' --pretty=format:%an sort -u > all-leftout-cvs-authors
And now in all-leftout-cvs-authors we'll have a sorted list of all cvs id's which were not handled in the original git-cvsimport. In my case there are only 19 such ids:
$ wc -l all-leftout-cvs-authors
19 all-leftout-cvs-authors

Nice, that will be easy to fix. Now edit your all-leftout-cvs-authors file to add the relevant information in a format similar to this:
john = John van Code <john@code.temple.tld>
jimmy = Jimmy O'Document <jimmy@documenting.com>
In case you can't make a complete cvs-user-to-name-and-email map, you might want to use stubs of the following form in order to be able to easily identify later such commits, if you prefer (or you could let them unaltered at al ;-):
cvsid=cvsid <cvsid@cvs.server.com>

How to actually do the filtering to fix history (using git-filter-branch and a script)

After this is done, we'll need just one more piece, the command to do the altering itself which reads as follow (note that my final authors file is called new-authors and that I placed this in a script in order to be able to easily run it without trying to escape all spaces and such madness):

[ "$authors_file" ]   export authors_file=$HOME/new-authors

#git filter-branch -f --remap-cvs --env-filter '
git filter-branch -f --env-filter '

get_name ()
grep "^$1=" "$authors_file" sed "s/^.*=\(.*\)\ .*$/\1/"


get_email ()
grep "^$1=" "$authors_file" sed "s/^.*\ <\(.*\)>$/\1/"


if grep -q "^$GIT_COMMITTER_NAME" "$authors_file" ; then
GIT_AUTHOR_NAME=$(get_name "$GIT_COMMITTER_NAME") &&
GIT_AUTHOR_EMAIL=$(get_email "$GIT_COMMITTER_NAME") &&
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" &&
GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" &&
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
fi
' -- --all
You might wonder what's up with the commented git filter-branch line with the --remap-cvs option. This script will NOT work for you as long as you have the stock git-filter-branch script and keep the option --remap-cvs while not patching your git-filter-branch script (/usr/lib/git-core/git-filter-branch), but that option will provide a file with the mappings from the old to the new commit ids. If you want that function, too, you'll want to apply this patch to git-filter-branch:

diff --git a/git-filter-branch b/git-filter-branch
old mode 100644
new mode 100755
index ae602e3..d1f7ef6
--- a/git-filter-branch
+++ b/git-filter-branch
@@ -149,6 +149,11 @@ do
prune_empty=t
continue
;;
+ --remap-cvs)
+ shift
+ remap_cvs=t
+ continue
+ ;;
-*)
;;
*)
@@ -368,6 +373,33 @@ while read commit parents; do
die "could not write rewritten commit"
done <../revs

+# Rewrite the cvs-revisions file, if requested and the file exists
+
+ORIG_CVS_REVS_FILE="$ GIT_DIR /cvs-revisions"
+if [ -f "$ORIG_CVS_REVS_FILE" ]; then
+ if [ "$remap_cvs" ]; then
+ printf "CVS remapping requested\n"
+
+ CVS_REVS_FILE="$tempdir/cvs-revisions"
+ cp "$ORIG_CVS_REVS_FILE" "$CVS_REVS_FILE"
+ printf "\nFound $ORIG_CVS_REVS_FILE; will copy and alter it as $CVS_REVS_FILE\n"
+ cvs_remap__commit_count=0
+ newcommits="$(ls ../map/ wc -l)"
+ for commit in ../map/* ; do
+ cvs_remap__commit_count=$(($cvs_remap__commit_count+1))
+ printf "\rRemap CVS commit $commit ($cvs_remap__commit_count/$newcommits)"
+
+ oldsha1="$(basename $commit)"
+ read newsha1 < $commit
+ sed -i "s@$oldsha1\$@$newsha1@" "$CVS_REVS_FILE"
+ done
+ else
+ warn "\nNo CVS remapping requested, but cvs-revisions file found. All CVS mappings will be lost.\n"
+ fi
+elif [ "$remap_cvs" ]; then
+ warn "\nWARNING: CVS remap was ignored, since no original cvs-revisions file was found\n"
+fi
+
# If we are filtering for paths, as in the case of a subdirectory
# filter, it is possible that a specified head is not in the set of
# rewritten commits, because it was pruned by the revision walker.
@@ -491,6 +523,11 @@ if [ "$filter_tag_name" ]; then
done
fi

+if [ "$remap_cvs" -a -f "$CVS_REVS_FILE" ]; then
+ mv "$ORIG_CVS_REVS_FILE" "$ORIG_CVS_REVS_FILE.original"
+ cp "$CVS_REVS_FILE" "$ORIG_CVS_REVS_FILE"
+fi
+
cd ../..
rm -rf "$tempdir"


Then, after running this script, let's call it filter, you should have a brand new git repo with the appropriate authors and their emails set.


P.S.: I have started writing this post some time ago but stopped just before the last part, the one with the filter script. I realise I might be missing something in the explanation, but if you have problems, please comment so I can help you fixing them.

P.P.S.: * I realised in the filter script at some point I wanted to do something like:
for R in $(git log -E --author='^[^@]*$' --pretty=format:%H   head -n 2) ; do
[the same git filter branch command above but ending in ...]
' $R
done
But I think I remember that $R didn't work on the whole history, but only on that revision, or some other weird of that sort. I know I ended up not filtering explicitly those revisions, but the entire history. I hope this helps.

Christian Perrier: Bug #660000

Beatrice Torracca reported the Debian bug #660000 on Wednesday February 15th, against wide-dhcpv6. That one makes me happy, because it is occurring during one of my numerous l10n "NMU" proposals and it is likely that I'll be the one who closes it (unless J r mie Corbier reacts to my l10n NMU proposal). It also makes me happy because Beatrice is participating to the great localization work of the Italian team where she is one of the most active contributors along with Francesca Ciceri. Hats off to italian ladies! Bug #650000 was reported as of November 25th. 2 months and 20 days for 10,000 bugs. The rate didn't really change and I expect it to increase a little bit as quality work related to release preparation will be increasing in the upcoming months. As usual, see you about 2.5 months for bug #670000 but, in the meantime, I might be "celebrating" Debian bug #666666. We all like nice numbers, isn't it?

15 February 2012

Christian Perrier: Bug #650000

Beatrice Torracca reported the Debian bug #660000 on Wednesday February 15th, against wide-dhcpv6. That one makes me happy, because it is occurring during one of my numerous l10n "NMU" proposals and it is likely that I'll be the one who closes it (unless J r mie Corbier reacts to my l10n NMU proposal). It also makes me happy because Beatrice is participating to the great localization work of the Italian team where she is one of the most active contributors along with Francesca Ciceri. Hats off to italian ladies! Bug #650000 was reported as of November 25th. 2 months and 20 days for 10,000 bugs. The rate didn't really change and I expect it to increase a little bit as quality work related to release preparation will be increasing in the upcoming months. As usual, see you about 2.5 months for bug #670000 but, in the meantime, I might be "celebrating" Debian bug #666666. We all like nice numbers, isn't it?

Dirk Eddelbuettel: Kurt Elling, Regina Carter and Anat Cohen at the CSO

Yesterday was Valentine's Day, and Kurt Elling came back to Chicago for a show at Symphony Center. He brought along guest stars Regina Carter (violin) and Anat Cohen (clarinet), as well as a small band led by Elling's long-time collaborator Laurence Hobgood on piano. The program was titled Passion World and featured songs from around the world. Quite impressively, Elling actually sang in French, Spanish, Portuguese, German and of cause English. The program lacked a little bit of cohesion at times, but it was still a most enjoyable and solid two-hour set. A similar concert will take place in Minneapolis on Saturday, so for those near the Twin Cities I would recommended looking for tickets.

Russell Coker: Links February 2012

Sociological Images has an interesting article about the attempts to apply the word Camping to OWS and framing the issues [1]. Lester Macgurdy wrote an insightful article about the snake , a new technique for OWS protesters to beat riot police [2]. Ron Barassi suggests that Australia Day be celebrated on the 27th of May to commemorate the day in 1967 when the Australian constitution was amended to not be racist [3]. The current Australia Day is often referred to as Invasion Day . IMHO Ron deserves another Best and Fairest award. Stefon Harris gave an entertaining TED talk about improv Jazz music titled There Are No Mistakes on the Bandstand [4]. It seems that his concepts can apply to some extent to many collaborative projects. John Robb wrote an interesting article about the future of drone (UAV) warfare [5]. He suggests that having one person control each drone is a temporary thing and that the future is to have a cloud of cheap autonomous drones taking strategic control from one person. His comparison of Starcraft players to future drone fighters is interesting. The OWS movement is branching out into other related areas, OccupyYourHomes.org is one of the latest ones [6]. When banks try to forclose on homes without good cause the OWS people are protesting. Cory Doctorow wrote an important article for The Guardian about corporations using the Youtube ContentID system to pirate works that other people have uploaded [7]. Matt Taibbi s description of Goldman Sachs as a great vampire squid wrapped around the face of humanity, relentlessly jamming its blood funnel into anything that smells like money will never die [8]. It has spawned many other creative descriptions of the evil and greed of Goldman Sachs and even Lloyd Blankfein of Goldman Sachs describes his company as having burned down the Reichstag, shot the Archduke Ferdinand and fired on Fort Sumter he was trying to use satire, but I don t think that Goldman Sachs people would act differently to Fritz Thyssen. Keith Packard wrote an interesting article about the Calypso CalDAV system which he uses with Android [9]. He makes lots of good points about how to improve calendaring and contacts on Android, unfortunately I lack time to fiddle with such things at the moment so I ll stick with Google in spite of the risks. Asheesh Laroia wrote a great article about the problems with short (32bit) GPG keys [10]. It seems that creating keys with matching ID numbers isn t particularly difficult and that GPG doesn t handle them as well as we would like giving the possibility of at best annoying DoS attacks and at worse security problems due to using the wrong key. Sociological Images has an interesting article about when game show audiences are trustworthy [11]. It seems that French people don t want an undeserving person to win so they will intentionally advocate the wrong answer if the contestant should know it. Paul Wayper gave a great lecture titled SE Linux for Everyone [12]. He covers the basics of SE Linux in a user-friendly way and explains some simple solutions to common problems which don t involve compromising system security. Paul Tassi wrote an insightful article for Forbes about piracy [13]. His conclusion is that the media companies should make it cheaper and easier to be a customer and not spend insane amounts of money on low quality products. The Reid Report has an interesting article about Ron Paul s racism [14]. Ron Paul is generally well regarded outside the US because he wants the US government to stop meddling in the affairs of other countries, but while he s less bad than other US politicians in terms of foreign policy that doesn t make him a good person. Anonymous hacked some mailboxes belonging to a neo-Nazi group and found links to Ron Paul [15]. I ve always been suspicious of the way Ron Paul wanted to avoid anti-racism legislation on supposed Libertarian principles. The Reid Report has an interesting summary of Ron Paul news plus some criticism of Glenn Greenwald and others who associate with him [16]. Related posts:
  1. Links February 2011 Australia s Department of Finance has mandated that the MS-Office document...
  2. Links January 2012 Cops in Tennessee routinely steal cash from citizens [1]. They...
  3. Links February 2009 Michael Anissimov writes about the theft of computers from the...

14 February 2012

Petter Reinholdtsen: How to figure out which RAID disk to replace when it fail

Once in a while my home server have disk problems. Thanks to Linux Software RAID, I have not lost data yet (but I was close this summer :). But once a disk is starting to behave funny, a practical problem present itself. How to get from the Linux device name (like /dev/sdd) to something that can be used to identify the disk when the computer is turned off? In my case I have SATA disks with a unique ID printed on the label. All I need is a way to figure out how to query the disk to get the ID out. After fumbling a bit, I found that hdparm -I will report the disk serial number, which is printed on the disk label. The following (almost) one-liner can be used to look up the ID of all the failed disks:
for d in $(cat /proc/mdstat  grep '(F)' tr ' ' "\n" grep '(F)' cut -d\[ -f1 sort -u);
do
    printf "Failed disk $d: "
    hdparm -I /dev/$d  grep 'Serial Num'
done
Putting it here to make sure I do not have to search for it the next time, and in case other find it useful. At the moment I have two failing disk. :(
Failed disk sdd1:       Serial Number:      WD-WCASJ1860823
Failed disk sdd2:       Serial Number:      WD-WCASJ1860823
Failed disk sde2:       Serial Number:      WD-WCASJ1840589
The last time I had failing disks, I added the serial number on labels I printed and stuck on the short sides of each disk, to be able to figure out which disk to take out of the box without having to remove each disk to look at the physical vendor label. The vendor label is at the top of the disk, which is hidden when the disks are mounted inside my box. I really wish the check_linux_raid Nagios plugin for checking Linux Software RAID in the nagios-plugins-standard debian package would look up this value automatically, as it would make the plugin a lot more useful when my disks fail. At the moment it only report a failure when there are no more spares left (it really should warn as soon as a disk is failing), and it do not tell me which disk(s) is failing when the RAID is running short on disks.

Martin-&#201;ric Racine: Adopted: ispell-et, myspell-lv, rus-ispell.

Over recent months, I have been pondering the relevance of my Free Software involvement a lot: More than anything, it constantly feels more and more like several important distributions and projects are moving in directions that break with the old ways far too radically, by breaking software usability rules such as "least surprise", "works out of the box", and "if it ain't broken, don't fix it" either to try new approaches to addressing existing needs or simply for change's sake. Another aspect lies in my usual motivation for packaging or adopting software: because I need it and nobody else bothered doing it. Further reflection made me ponder what, correspondingly, are my usual reasons for dropping software: because what exists already works and because everybody and their grand-mother already invented a million of ways to handle the same issue. Which brings us to today's news. What prompted me to hand the dictionary packages I maintained over to someone else was a combination of "no longer need it" and "it already works fine as it is." For instance, the Estonian dictionaries haven't seen any upstream release since the initial one in 2003. While I still use Estonian daily in my online communications, the last 9 years have mostly been spent making minor changes to the dependencies and maintainer scripts, just to keep the package compliant with current Debian packaging policies and with ongoing improvements to the dictionary-common maintainer tools. This is not the sort of work that requires any knowledge of the Estonian language, so I felt that having dictionary-common developers handle those technical transitions in a clean and across-the-board way for as many dictionary packages as possible would be more productive than me trying to keep track of those changes by myself. A similar case applies to the Latvian dictionaries. While there have been occasional upstream releases, some of which required patching the source code, maintaining the package has mostly been about tracking Debian policy changes and dictionary-common functional changes. Additionally, my interest for learning Latvian has dramatically dropped over the years, so I no longer saw any point in remaining involved in maintaining the package. Ditto for the Russian dictionaries: occasional upstream releases, occasional patches, regular packaging upgrades to keep up with the Debian policy and with dictionary-common functionality, but no longer much of anything than a passive interest in practicing my Russian. One of the developers behind dictionary-common, Agustin Martin Domingo, frequently helped me make sense of the changes I needed to track in the past, so he gladly accepted taking over the technical maintenance of all 3 packages. The Estonian dictionaries, while extremely skim in the breadth of vocabulary they cover, remain useful, but are essentially deprecated, as the upstream author is working on a spell checking engine similar to what Voikko does for Finnish, which is why maintaining them will be a rather easy task for Agustin. Meanwhile, Aigars Mahinovs passively remains on board for the Latvian dictionaries, while the Russian dictionaries have been adopted by Mikhail Gusarov, in both cases with Agustin assisting on technical matters. Basically, I feel that passing the maintenance over to people whose motivation remains high is a better way to guarantee those packages' future than leaving them in my unmotivated hands and I'm glad that I found someone to keep on packaging them. PS: happy Valentine's day to everyone!

13 February 2012

Petter Reinholdtsen: Automatic proxy configuration with Debian Edu / Skolelinux

New in the Squeeze version of Debian Edu / Skolelinux is the ability for clients to automatically configure their proxy settings based on their environment. We want all systems on the client to use the WPAD based proxy definition fetched from http://wpad/wpad.dat, to allow sites to control the proxy setting from a central place and make sure clients do not have hard coded proxy settings. The schools can change the global proxy setting by editing tjener:/etc/debian-edu/www/wpad.dat and the change propagate to all Debian Edu clients in the network. The problem is that some systems do not understand the WPAD system. In other words, how do one get from a WPAD file like this (this is a simple one, they can run arbitrary code):
function FindProxyForURL(url, host)
 
   if (!isResolvable(host)  
       isPlainHostName(host)  
       dnsDomainIs(host, ".intern"))
      return "DIRECT";
   else
      return "PROXY webcache:3128; DIRECT";
 
to a proxy setting in the process environment looking like this:
http_proxy=http://webcache:3128/
ftp_proxy=http://webcache:3128/
To do this conversion I developed a perl script that will execute the javascript fragment in the WPAD file and return the proxy that would be used for http://www.debian.org/, and insert this extracted proxy URL in /etc/environment and /etc/apt/apt.conf. The perl script wpad-extract work just fine in Squeeze, but in Wheezy the library it need to run the javascript code is no longer able to build because the C library it depended on is now a C++ library. I hope someone find a solution to that problem before Wheezy is frozen. An alternative would be for us to rewrite wpad-extract to use some other javascript library currently working in Wheezy, but no known alternative is known at the moment. This automatic proxy system allow the roaming workstation (aka laptop) setup in Debian Edu/Squeeze to use the proxy when the laptop is connected to the backbone network in a Debian Edu setup, and to automatically use any proxy present and announced using the WPAD feature when it is connected to other networks. And if no proxy is announced, direct connections will be used instead. Silently using a proxy announced on the network might be a privacy or security problem. But those controlling DHCP and DNS on a network could just as easily set up a transparent proxy, and force all HTTP and FTP connections to use a proxy anyway, so I consider that distinction to be academic. If you are afraid of using the wrong proxy, you should avoid connecting to the network in question in the first place. In Debian Edu, the proxy setup is updated using dhcp and ifupdown hooks, to make sure the configuration is updated every time the network setup changes. The WPAD system is documented in a IETF draft and a Wikipedia page for those that want to learn more.

Benjamin Mako Hill: Quasi-Private Resources

Public Resource republishes many court documents. Although these documents are all part of the public record and PR will not take them down because someone finds their publication uncomfortable, PR will evaluate and honor some requests to remove documents from search engine results. Public Resources does so using a robots.txt file or "robot exclusion protocol" which websites use to, among other things, tell search engine's web crawling "robots" which pages they do not want to be indexed and included in search results. Originally, the files were mostly used to keep robots from abusing server resources by walking through infinite lists of automatically generated pages or to block search engines from including user-contributed content that might include spam. The result for Public Resource, however, is that PR is now publishing, in the form of its robots.txt, a list of all of the cases that people have successfully requested to be made less visible! In Public Resource's case, this is is the result of a careful decision; PR makes the arrangement clear in on their website. The robots.txt home page also explains the situation saying, "the /robots.txt file is a publicly available file. Anyone can see what sections of your server you don't want robots to use,", and "don't try to use /robots.txt to hide information." That said, I've looked at a bunch of robots.txt files on websites I have visited recently and, sadly, I've found many sites that use robots.txt as a form of weak security. This is very dangerous. Some poorly designed robots simply ignore the robots.txt file. But one can also imagine an evil search engine that uses a web-crawler that does the opposite of what it's told and only indexes these "hidden" pages. This evil crawler might look for particular keywords or use existing search engine data to check for incoming links in order to construct a list of pages whose existence is only made public through a file meant to keep people away. Check your own robots.txt and ask yourself what it might reveal. By advertising the existence and locations of your secrets, the act of "hiding" might make your data even less private.

Michal &#268;iha&#345;: phpMyAdmin translations status

As phpMyAdmin is approaching to 3.5 release, it has come time to share about translations status. Here comes third round of translation status update. Since last update we have one new translation at 100%, but one has dropped from the list: There are few which are really close to 100% and I hope they will get there soon: As you can see, traveling around FOSDEM was really useful for Czech translation, which I've managed to complete during that weekend (+ Monday when I traveled to Nuremberg). There was great amount of work done on Polish translation, so hopefully it will be on 100% in next report. Also Rouslan is progressing quite well on Italian, but there is still fair amount of work to be done. Was your language not mentioned? It's now perfect time to contribute to it.

Filed under: English Phpmyadmin 0 comments Flattr this!

James Bromberger: Debian Wheezy: US$19 Billion. Your price FREE!

As many would know, Debian GNU/Linux is one of the oldest, and the largest Linux distributions that is available for free. Since it was first released in 1993, several people have analysed the size and produced cost estimates for the project. In 2001, Jes s M. Gonz lez-Barahona et al produced an article entitled Counting Potatoes , an analysis of Debian 2.2 (code named Potato). When Potato was released in June 2003, it contained 2,800 source packages of software, totalling around 55 million lines of source code. When using David A. Wheeler s sloccount tool to apply the COCOMO model of development, and an average developer salary of US$56,000, the projected development cost that Gonz lez-Barahona calculated to start-from-scratch and build Debian 2.2 in 2003 was US$1.9 billion. In 2007 an analysis entitled Macro-level software evolution: a case study of a large software compilation by Jes s M. Gonz lez-Barahona, Gregorio Robles, Martin Michlmayr, Juan Jos Amor and Daniel M. German was released. It found that Debian 4.0 (codename Etch released April 2007) had just over 10,000 source packages of software and 288 million lines of source code. This analysis also delved into the dependencies of software packages, and the update flow between Debian release (not all packages are updated with each release). Today (February 2012) the current development version of Debian, codenamed Wheezy, contains some 17,141 source packages of software, but as it s still in development this number may change over the coming months. I analysied the source code in Wheezy, looking at the content from the original software that Debian distributes from its upstream authors without including the additional patches that Debian Developers apply to this software, or the package management scripts (used to install, configure and de-install packages). One might argue that these patches and configuration scripts are the added value of Debian, however the in my analysis I only examined the pristine upstream source code. By using David A Wheeler s sloccount tool and average wage of a developer of US$72,533 (using median estimates from Salary.com and PayScale.com for 2011) I summed the individual results to find a total of 419,776,604 source lines of code for the pristine upstream sources, in 31 programming languages including 429 lines of Cobol and 1933 lines of Modula3! In my analysis the projected cost of producing Debian Wheezy in February 2012 is US$19,070,177,727 (AU$17.7B, EUR 14.4B, GBP 12.11B), making each package s upstream source code wrth an average of US$1,112,547.56 (AU$837K) to produce. Impressively, this is all free (of cost). Zooming in on the Linux Kernel In 2004 David A. Wheeler did a cost analysis of the Linux Kernel project by itself. He found 4,000,000 source lines of code (SLOC), and a projected cost between US$175M and US$611M depending on the complexity rating of the software. Within my analysis above, I used the standard (default) complexity with the adjusted salary for 2011 (US$72K), and deducted that Kernel version 3.1.8 with almost 10,000,000 lines of source code would be worth US$540M at standard complexity, or US$1,877M when rated as complex . Another Kernel Costing in 2011 put this figure at US$3 billion, so perhaps there s some more variance in here to play with. Individual Projects Other highlights by project included:
Project Version Thousands
of SLOC
Projected cost
at US$72,533/developer/year
Samba 3.6.1 2,000 US$101 (AU$93M)
Apache 2.2.9 693 US$33.5M (AU$31M)
MySQL 5.5.17 1,200 US$64.2M (AU$59.7M)
Perl 5.14.2 669 US$32.3M (AU$30M)
PHP 5.3.9 693 US$33.5M (AU$31.1M)
Bind 9.7.3 319 US$14.8M (AU$13.8M)
Moodle 1.9.9 396 US$18.6M (AU$17.3M)
Dasher 4.11 109 US$4.8M (AU$4.4M)
DVSwitch 0.8.3.6 6 US$250K (AU$232K)
Debian Wheezy by Programming Language The upstream code that Debian distributes is written in many different languages. ANSI C with 168,536,758 is the dominant language (40% of all lines), followed by C++ at 83,187,329 (20%) and Java with 34,698,990 (8%).
Line chart

Break down of Wheezy by Language

If you are intersted in finding the line count and cost projections for any of the 17,000+ projects, you will find them in the raw data CSV. Other Tools and Comparisons Ohcount is another source code cost analysis tool. In March 2011 Ohcount was run across Debian Sid: its results are here. In comparison, its results appear much lower than the sloccount tool. There s also the Ohloh.net Debian Estimate which only finds 55 Million source lines of code and a projected cost of US$1B. However Ohloh uses Ohcount for its estimates, and seems to be to be around 370 million SLOC missing compared to my recent analysis. Summary Over the last 10 years the cost to develop Debian has increased ten-fold. It s intersting to know that US$19 billion of software is available to use, review, extend, and share, for the bargain price of $0. If we were to add in Debian patches and install scripts then this projected figure would increase. If only more organisations would realise the potential they have before them. Need help with Linux (including Debian), Perl, or AWS? See www.jamesbromberger.com.

Gunnar Wolf: Mexico City Metro project

Some days ago, reading my local Couchsurfing groups, I stumbled across an announcement by Australian Peter Davies to go to each of the 148 stations in the Mexico City Metro system, take some photos of the environment, and document on his impressions. I have followed and enjoyed the Mexico City Metro blog since I learnt of it, and have grown used to looking forward to the daily post-or-two. Peter writes each of his entries both in English and Spanish (you can tell it's not a native Spanish, but it's a good effort). He has been doing the stations in a very well distributed order (I cannot say it's completely random, but it's surely not lineal or methodical). I connected wiht his project as I love discovering the city more or less the same way, but with a different system: I try to have at least one long bike ride every two weeks (being "long" something over 40Km). I usually go either to the North or to downtown and to the East by the good old route I always take, and on my way back, at some point I decide just to turn right or left and discover yet another village slurped by the city. I don't usually take pictures, as I'm too much into the cycling thrill, left-right-left-right... But cycling has led me to appropriate my city (I don't know if that's proper English), to make my city really mine, to get to know parts of it I'd never otherwise go to. Anyway, Peter's is a great way to document urban life. I'm in love with my city, and with expressions of urban appropriation. I loved his project, and if you are interested by what I say, go take a look at his wanderings in the city. I have suggested him two bits to check, but the work is very much an artist's He accepts my input, but quite probably he will do whatever he pleases ;-) In case any of you is interested in contacting him, I can tell you for a fact he replies :-) [*] And what is CouchSurfing? Oh, a great community where you can offer a space to crash at your house for unknown people from all around the world. I have never requested a couch, as the Free Software community is much more tightly knit, but I have offered it to several interesting people.

12 February 2012

Sylvain Beucler: Branching FreeGLUT SVN with Git

I'm working on porting FreeGLUT to Android! Since I don't have access so the repository (I'm not a regular contributor), and since it will be a BIG patch, I thought I'd try a git-svn branch. So this won't be a post on OpenGL for once ;) I'm not an expert at managing Git branch but here's how I set it up. In this case, let's forget about importing tags: they don't have the same directory branch point in the hierarchy (sometimes the freeglut/ module, sometimes the parent directory), and git-svn only correctly supports set of sane tags that track the same initial directory. SVN is SLOW, especially remotely. I suggest you make a rsync copy of the repository first, it will greatly speed up the import :
rsync -avHSP freeglut.svn.sourceforge.net::svn/freeglut/ freeglut.svn/
Then start the import with git-svn :
git svn clone --trunk=trunk/freeglut/freeglut file://$(pwd)/freeglut.svn/ freeglut-git/
And edit .git/config to point to https://freeglut.svn.sourceforge.net/svnroot/freeglut :
[svn-remote "svn"]
    url = https://freeglut.svn.sourceforge.net/svnroot/freeglut
    fetch = trunk/freeglut/freeglut:refs/remotes/trunk
I work with 2 branches: Here's how I synchronize the upstream repository and merge it regularly with my feature branch:
git svn fetch
git checkout master
git merge remotes/trunk
git checkout android  # my feature branch
git merge master
# if conflict
git add .../sthing.c
git commit -m "Merge master"
git push
Any better way? The ongoing work is available at https://gitorious.org/freeglut/android :)

Next.

Previous.