Commands

A piggy bank of commands and fixes.

Can't connect to London underground WiFi after changing device

Problem:

You just changed your phone/tablet/device. Now you can't connect to the free Virgin Media wifi at London underground stations.

Solution:

  • Call your phone company's tech support (For EE it's 150, the 1, 3, 4)
  • Tell the level 1 support person that you've already tried all the troubleshooting steps including a network refresh
  • Ask to be put through to level 2
  • Ask the level 2 tech to un-register you from London underground wifi, wait 24 hours and re-register.
  • After that, follow the process for a new WiFi password (for EE it's texting EEWIFI to 9527).

Many different ways to resolve an IP to a hostname in Perl

Some different ways to look up hostnames.

Notes:

  • getnameinfo() gets a hostname and a service name, so it's not exactly the same as gethostbyaddr()
  • although the docs imply you need to enter a port, that's just to get the local service name. If you set it as undef then you can ignore any service

# 1, old deprecated way

use Socket; # gethostbyaddr, inet_aton, AF_INET

sub ip_address_to_host {
    my ( $self, $ip_address ) = @_;
    my ($hostname) = gethostbyaddr(
        inet_aton($ip_address),
        AF_INET,
    );
    return $hostname;
}

# 2, newer better way

use Socket qw(AF_INET inet_pton getnameinfo sockaddr_in);

sub ip_address_to_host {

     my ( $self, $ip_address ) = @_;

    my $port = undef;
    my $socket_address = sockaddr_in($port, inet_pton(AF_INET, $ip_address));

    my $flags = 0;
    my $xflags = 0;
    my ($error, $hostname, $servicename) = getnameinfo($socket_address, $flags, $xflags);

    return $hostname;
}

# 3, best way - that only uses DNS and not /etc/hosts first

use Net::DNS;

sub ip_address_to_host {

     my ( $self, $ip_address ) = @_;

    my $res = Net::DNS::Resolver->new;
    my $target_ip = join('.', reverse split(/\./, $ip_address)).".in-addr.arpa";
    my $query = $res->query("$target_ip", "PTR") // return;
    my $answer = ($query->answer)[0] // return;
    my $hostname = $answer->rdatastr;

    return $hostname;
}

# 4, the code golf way (no validation) - by Mark B

 perl -le 'use Net::DNS::Resolver; print ((Net::DNS::Resolver->new()->query("10.232.32.158","PTR")->answer)[0]->ptrdname);'


Run only one subtest with Test::More

Apply this patch to Test/More.pm, version 1.302075:

807d806
<     return if exists $ENV{SUBTEST} && $ENV{SUBTEST} ne $_[0];

Here's that patch again, in unified format:

$ diff -u Test/More.pm{,.orig}
--- Test/More.pm      2017-07-27 13:23:56.000000000 +0100
+++ Test/More.pm.orig 2017-07-27 13:19:00.000000000 +0100
@@ -804,7 +804,6 @@

 sub subtest {
     my $tb = Test::More->builder;
+    return if exists $ENV{SUBTEST} && $ENV{SUBTEST} ne $_[0];
     return $tb->subtest(@_);
 }

Run the test like this:

SUBTEST="put name of subtest here" /usr/bin/prove -v test_file.t

Why it's important to merge upstream at the end of every sprint

The whole idea of agile/scrum is to provide some value to the business every two weeks.

If you can tag your feature branch and deploy it to a Testing or Production environment for users or other stakeholders to see then that's great, you probably don't need to merge to master or trunk.

But say your release cycle is every two months so the new feature won't actually reach production for some time. If you don't merge the sprint's work to master, then it weakens all the good habits of agile working. Every sprint the developers will feel slightly less motivated to complete the work on time because it won't really matter, nothing is being done with the work. In this case, merging to master is a proxy for deploying to production.

If master/trunk doesn't work for you, designate a common feature branch, release branch or any other kind of special branch to merge each set of changes to. The point is that branch should not be under control of the developers anymore. Any new changes require a new issue/branch to be created, reviewed and merged separately.

There are many benefits to keeping branches small and merging upstream frequently:
  • The whole team gets to review the code, even (especially) people who haven't seen it yet
  • Smaller branches are easier for the team to review
  • Mistakes are caught earlier so less work is needed to rectify them
  • The new code can be more easily tested in continuous integration, which probably already runs off master
  • Reduces conflicts with the rest of the codebase
  • Makes it easier to work on new features in parallel (the alternative is using a common feature branch and sub-branches)
  • Keeps you honest by "publishing" your work, prevents feature creep, makes iterations clear, etc.
  • Makes it more efficient to work on and think about, you keep fewer things in your head because it's not all "up in the air"

General API design principles

API principles

Status: Draft
Working notes:
  • Read the Heroku HTTP API design guide
  • And the The twelve-factor app methodology for building SaaS
  • Use jsonapi.org
  • Consider JSON PATCH
  • Endpoints are all nouns, use the HTTP actions as verbs.
  • All endpoint nouns must always be singular, to match with database tables. Or plural (explanation). The point is they should remain consistent with other APIs from the same team, organisation or whatever.
  • Article: Your API versioning is wrong. Conclusions:
    • Use the headers for versioning.
    • Provide a special "override" URL path for humans, that sets the header appropriately. This will make development easier
      • i.e. /api/v2/nodes --> redirects to --> /api/nodes and automatically sets header: api-version: 2
      • or /api/nodes?version=2 --> redirects the same as above
    • Don't overload the content type.
  • Also provide a similar parameter for the Accept headers. This is to make it easy to send a URL to someone that works without any special software like curl or browser plugins: /api/nodes?accept=application/json
  • Return 2xx status code to indicate the success of the HTTP request
  • Return a status field in the content body to indicate the progress of the business domain request
    • Use a "status" field, not a "state" field. Status refers to a progression.
APIs should conform to previously created APIs where that doesn't contradict the principles above.
Where legacy APIs don't follow the principles above, they should be updated to conform as a pre-requisite to any changes.

Examples

Success response:
{
    "data" : [{
    "type" : "xyz",
    "id": "dw12345",
    "attributes" : {
        "status": "requested",
        },
    "links": {
        "self": "http://endpoint.example.com/webservice/dw12345" 
        }
    }]
}
Failure response:
{
  "errors": [{
      "status": "400",
      "source": { "pointer": "/data/attributes/environment" },
      "title":  "Invalid Attribute",
      "detail": "Environment must be int, uat or prod."
    }]
}

Questions

  • The response should be valid JSON API. But must the request be JSON API too?

References

More stuff

https://www.youtube.com/watch?v=aAb7hSCtvGw

Some of the key takeaways:
  • An api should be easy to learn, easy to use, hard to misuse
  • Continue to write to the API early and often
  • Example programs should be exemplary - this code will end up being copied everywhere
  • When in doubt, leave it out
  • Be consistent - same word means the same thing across the api 
  • Documentation matters - reuse is something is easier to say than to do - doing it requires both good design and good documentation
  • Do what is customary - obey standard naming conventions - it should feel like one of the core APIs, know the common pitfalls for the language and avoid them

Perl one-liner to serve a directory over HTTP

plackup -e 'use Plack::App::Directory; Plack::App::Directory->new({ root => "/opt/dweb/packages" })->to_app;'

(source)

Git show untracked stash files

Git stash can save untracked files like this:

git stash --all

But to see untracked files in the stash you need this special ^3 syntax:

git show stash@{1}^3
git show stash@{2}^3
git show stash@{99}^3

This shows stash numbers, 1, 2 and 99 respectively. The number 3 always remains 3.

(source)

Jenkins email notifications

The default Jenkins email notifications are almost unusable, they contain a complete output of the build log. Custom notifications are not trivial to set up and the official documentation is poor.

How to do it:

  • Install this plugin: https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin
  • Get an example HTML template (list of all default templates)
  • Put it at /var/jenkins_home/email-templates/foo1.groovy
  • Test
    • Enter the base filename of the template at http://jenkins_host/view/foo/job/bar/templateTest/
      • (this link to "Email Template Testing" should be underneath "Configure")
    • Does this require installing https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+Template+Plugin ?
  • ...?
  • profit!

Elasticsearch basics

Warning: Your Elasticsearch / ELK stack based logging solution may take a huge amount of disk space, and indexing of large amounts of data may also take so long that it can't keep up with the logs being generated.

Search:

curl '{endpoint}/_search?q=title:jones&size=5&pretty=true'

List indexes:

curl -s '{endpoint}/_cat/indices?v' | sort

Git: diff branch against master

Compare feature branch changes with upstream:

git diff $( git merge-base master HEAD )

Thanks Bill!

Surprising behaviour of the perl debugger for wantarray()

When you are running a perl script in the debugger, do not expect wantarray() to return the same thing it would if not running in the debugger.

If you break execution at a breakpoint, wantarray() seems to return 1 when it wouldn't otherwise.

Show the full patch for a git merge commit

Use the undocumented -m and -p options to show the main commit ID.
Why are these not in the help!?

git show -m -p 25172c1

Specify git config temporarily for one command

Use -c after the git call, before any other options:

e.g. to override your core.pager="less -r" setting:

    git -c 'core.pager=cat' log -n 3 --abbrev-commit

(source)

How to apply a named stash in git

git stash apply stash^{/foo1}

where foo1 is the full name of your stash (keep names short, with no spaces).

(source)

How to find who/what is changing a file in linux

A list:
  • inotifywait - simple, attended
  • auditctl - powerful, old school
  • file system monitoring - more involved, more complete

See https://pinboard.in/u:random/t:audit

Reasons to use "git pull --rebase" by default

Rebase is a really sharp knife. Sometimes a really sharp knife is what you need, but it's also possible to accidentally injure yourself.

(thanks to Bill Blunn for the imagery).

Reasons to use "git pull --rebase" and not "git pull" (which merges by default):
  • Prevents massive weird conflicting-with-yourself problems if anyone rebases that branch later, e.g. just before merging to master
  • Keeps all the commits together in a bunch at the top of the tree so you can easily identify them visually
  • Allows "git diff master..HEAD" to work without including unrelated changes
Reasons not to use "git pull --rebase" and stick with "git pull" (using merges):

  • It's the default, so most people will use it, and their merges will clash with your rebases


Comparison table:

issue git pull (default: merge) git pull --rebase
git log, in a feature branch pro: you always see when master was merged
con: your commits will be interleaved with others commits
(less of a problem for short-lived branches)
pro: root of feature branch is transparently moved to head of master
pro: all your commits are kept bunched together
con: you don't know when master was merged
con: you have to notify everyone downstream
diff feature branch against master con: it's more difficult to diff against master pro: "git diff master" just works
mixing rebase and merge con: you can't rebase without weird conflicts con: you can't merge downstream without weird conflicts
(not sure about this one)

(thank you tablesgenerator.com)

ssh debug3: Incorrect RSA1 identifier debug3: Could not load ".ssh/id_rsa" as a RSA1 public key

When testing ssh with -vvv, you see this in the log:

    debug3: Incorrect RSA1 identifier
    debug3: Could not load ".ssh/id_rsa" as a RSA1 public key

This is not an error.
This is not the problem you're looking for.
Your problem is something else.

(source)

See also another ssh non-error.

debug2: key_type_from_name: unknown key type '-----BEGIN'

SSH debug output can be quite misleading.
When you see the following output, it does NOT indicate a problem.

debug2: key_type_from_name: unknown key type '-----BEGIN'
debug3: key_read: missing keytype
debug3: key_read: missing whitespace
...
debug2: key_type_from_name: unknown key type '-----END'
debug3: key_read: missing keytype
debug1: identity file /home/foo/.ssh/id_rsa type 1

The final line tells you that the key was read successfully.

(source)

See also another ssh non-error.

Whitespace woes

One very annoying aspect of software development in a team is whitespace. Many people use it differently. In a way it's unimportant, not least because it's literally invisible and so often overlooked. Yet it continues to cause problems which repeatedly waste time, and is especially distracting and troublesome for the many detail-oriented developers among us.

Clearly the only sane way to use whitespace in Perl is:

  • 4 character indent
  • only use spaces, never use tabs
  • never allow any trailing whitespace

One of the worst violations of these rules is an indent composed of mixed tabs and spaces. This is a list of reasons why that's very wrong:

  • When someone gets fed up and changes that whitespace to make it conform, it introduces noise into the code diff (they don't create a separate branch due to the overhead costs in a bureaucratic, audited environment).
  • Different text editors and web interfaces all display the indent differently, making the code hard to follow.

So, you're thinking of switching to git...

I've written a few things I learnt about using git:

I've also gathered a few links over the years, many relating to the philosophy and strategy of git. Some highlights are:

The git features I like best are:
  • git stash
    • Quickly store a copy of all your unsaved changes, so you can work on them later
    • You can use it like: git stash save "halfway through debugging issue foo"
  • git branch
    • Unlike other version control systems, git makes it incredibly easy, fast and fun to create a new branch for some changes you've made
    • Everything is stored locally until you decide to "push" it to the main repo
    • To get the most out of git, frequently commit all your work to some branch or other (at least once a day)
  • git reflog
    • See a history of (almost) all the git commands you issued
    • In case you badly mess up you can save your life here
  • git rebase -i
    • Interactively squash together several commits
    • Change commit messages
    • Even split out a large commit into several different commits
  • git log --color --stat=200,200 --decorate --abbrev-commit --relative
    • Improved log

I publish my git config.

Git cache password over https

error: cannot run git-credential-cache--daemon: No such file or directory
fatal: unable to start cache daemon: No such file or directory

# fix:
wget http://example.com/git-daemon-1.7.12.4-0.7.1.x86_64.rpm
sudo rpm -i git-daemon-1.7.12.4-0.7.1.x86_64.rpm
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=28800' # 8 hours

Oracle clients

A short list:
  • dbVisualizer
  • Toad
  • Oracle SQL Developer

Jenkins admin notes

Some things to help on your Continuous Integration journey with Jenkins:

  • Use  docker pull jenkins  for a quick start
  • Security can be a bit fiddly to set up. Try these easy settings:
    • Jenkins’ own user database
    • Allow users to sign up
    • Logged-in users can do anything
  • There is a Role-Based Strategy plugin for more advanced use
  • If you accidentally lock yourself out, edit  $JENKINS_HOME/config.xml  to say false and restart Jenkins
  • To see a list of failing tests, configure a Post-build action for  "Publish JUnit test result report"

-- Jenkins ver. 1.642.2

Simplest easiest quickest web server script

cd ~
python -m SimpleHTTPServer 8080

(source)

PHP, pecl, phpize PDO, mysqli for Perl devs

"pecl" is the same as "cpan"
"phpize" is the equivalent of "perl Makefile.pl"
"PDO" is PHP's DBI equivalent (i.e. general purpose RDBMS connector)
"mysqli" is the more modern version of the mysql-specific connector

Simple perl webserver

HTTP::Server::Simple

(contrast with python one-liner)

#!/usr/bin/perl

# https://metacpan.org/pod/HTTP::Server::Simple
# /versions/perl-5.8.7/bin/perl -MHTTP::Server::Simple test2.pl

use strict;
use warnings;

{
package MyWebServer;

use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);

my %dispatch = (
    '/hello' => \&resp_hello,
    '/' => \&resp_index,
);

sub handle_request {
    my $self = shift;
    my $cgi  = shift;

    my $path = $cgi->path_info();
    my $handler = $dispatch{$path};

    if (ref($handler) eq "CODE") {
        print "HTTP/1.0 200 OK\r\n";
        $handler->($cgi);

    } else {
        print "HTTP/1.0 404 Not found\r\n";
        print $cgi->header,
              $cgi->start_html('Not found'),
              $cgi->h1('Not found'),
              $cgi->end_html;
    }
}

sub resp_hello {
    my $cgi  = shift;   # CGI.pm object
    return if !ref $cgi;

    my $who = $cgi->param('name');

    print $cgi->header,
          $cgi->start_html("Hello"),
          $cgi->h1("Hello $who!"),
          $cgi->end_html;
}

sub resp_index {
    my $cgi = shift;
    print $cgi->header;
    open(my $fh,'<','index.html') or die "can't open index.html";
    local $/ = undef;
    my $out = <$fh>;
    close($fh);
    print $out;
}

}

# start the server on port 8080
my $pid = MyWebServer->new(8085)->background();
print "Use 'kill $pid' to stop server.\n";

(source)

Change quoting level in Outlook 2007

When replying to an HTML email, the original message has a blue bar to the left (which replaces the traditional > symbol). I've seen in previous versions of Outlook that pressing enter on this line takes you to a new line without the blue line ("paragraph unindent") and allows you to write a reply inline. That's fine and what I'd expect.

But currently that doesn't work and I can't easily get rid of the blue line, meaning all my inline replies look like they're part of the original message! Quite odd. Here's how to work around the problem:

  • Change the message format from HTML to Rich-text
  • Type Ctrl-Q where you want to add a reply
  • Type your reply
Voila


Why not to use a pop-up window

If you're using a pop-up window on your website, you're doing it wrong.
It's akin to using nested tables for display, fer chrissakes!

Reasons why it's wrong:

  • It's a poor user experience because the user doesn't get any of the usual browser functionality in the pop-up window, like the back button or the icon that tells you the page is loading.
  • I'm sure I'll think of some more later

Testing Catalyst

Notes:

Catalyst::Test - you get a context object back

Test::WWW::Mechanize::Catalyst - you don't have to run a separate server

Change timezone in Linux

Change this link:

$ ls -l /etc/localtime

lrwxrwxrwx    1 root     dwebadm        34 Dec  2 01:12 /etc/localtime -> /usr/share/zoneinfo/Asia/Singapore*

Cannot install Java JDK: semicolon found in selected path

There's no semi colon in the install path. But you still get the error:

        semicolon found in selected path

Solution is to move the install .exe to c:\ and run it again.

Possibly with command line switches: /v"/L c:\install.log"

(Search results show that this same issue has existed for 11 years!)

Why not to require javascript

Reasons not to require javascript for critical features of your website:
  • It can slow down the user experience.
  • Standard HTML form and browser controls are the way they are for a reason: They work. Subvert or reinvent them at your peril.
  • It's much more likely Javascript code won't work as expected in all browsers, than HTML.
  • When some part of it breaks, forcing the user to disable it, they won't be able to use the rest of the website
  • Not all browsers have javascript, for example Lynx (text only) and JAWS (i.e. screen readers which blind people use).
  • It often makes automated testing harder
  • When the user gets logged out due to inactivity, the AJAX calls may behave unexpectedly

Disclaimer: This is my opinion only, based on personal experience.

Select sub-section of putty buffer only

Are you sick and tired of waiting for your terminal to scroll down when dragging to select a large portion of the scrollback buffer in putty?

The putty developers already thought of that!


  1. Go to Putty Configuration window
  2. Choose "Selection" from category on the left of the window.
  3. Under 'Control use of mouse', choose 'Compromise (Middle extends, Right pastes)' if not already chosen.

(source)

Use Data::Compare to compare data outside a test

Need to compare data outside of a test, without generating "ok" / "not ok" TAP output? Use Data::Compare.

Perltidy docs / example config

Docs

Reference for all the possible perltidy options
More detailed explanation of some the options

Team perltidy options

ruleexplanationnotes
-i=4
4 column indentA lot of the legacy code has 2 column indent.
-pt=2
"horizontal tightness" 2 - no space for parenthesis tokens
 if ( ( my $len_tab = length( $tabstr ) ) > 0 ) {  # -pt=0
 if ( ( my $len_tab = length($tabstr) ) > 0 ) {    # -pt=1 (default)
 if ((my $len_tab = length($tabstr)) > 0) {        # -pt=2
(docs)
-wls='=>'
ensure there's always space to the left of =>
-wrs='=>'
...and always to the right of =>
-vtc=0
always break before a closing token (default)i.e. non-block curly braces, parentheses, and square brackets docs
-l=79
Lines should be no more than 79 characters wide
-nolc
no "outdenting" for long comments - indent them properlyBy default, full-line (block) comments longer than the value maximum-line-length will have their indentation removed ("outdented"). This rule prevents that. docs
-nolq
no "outdenting" for long quotes/stringsdocs
-sot
stack opening tokens - same as -sop -sohb -sosbPut opening parentheses, braces, etc. on the same line docs
-sct
stack closing tokensPut closing parentheses, braces, etc. on the same line docs

Options that were removed

ruleexplanationnotes
-lp
line up parenthesesSee docs
-vt=2
define opening vertical tightnessPut opening parentheses, braces, etc. on the same line. Related to -lp docs
-vt=0
always break a line after opening tokendocs
-st -se
use as a filterInstructions to the parser docs
-nsfs
'for' loop semicolon spaces
The default is to place a space before a semicolon in a for statement, like this:
    for ( @a = @$ap, $u = shift @a ; @a ; $u = $v ) {  # -sfs (default)
If you prefer no such space, like this:
    for ( @a = @$ap, $u = shift @a; @a; $u = $v ) {    # -nsfs
then use nsfs.
-nbbc
No blanks before commentsBy default, a blank line will be introduced before a full-line comment. This rule prevents that.

SSH tunnel

ssh -N -R 5555:1.2.3.4:666 user@hostname
  • 5555 is the port you make up
  • 666 is the port to which you are forwarding
  • 1.2.3.4 is the IP of the target host to which you are fowarding
  • hostname is the host where port 5555 will be available
  • you run this command on a third machine, which can connect to 1.2.3.4 on port 666

This results in  hostname:5555  getting forwarded to  1.2.3.4:666

Useful bash flags for scripts verbose trace expand error exit

Useful flags:
set -v # "verbose" - echo commands
set -x # "xtrace" - like verbose but expands commands
set -e # "errexit" - abort script at first error
set -u # "nounset" - strict mode: undefined variable causes an exit

Long format:
set -o verbose

Bash "strict mode":
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

Windows: folder or file open in another program

When you try to move a folder:

    "The action can't be completed because the folder or a file in it is open in another program"

This stunningly unhelpful error message has persisted through many versions of Windows.

The way I work around it is:

  • Rename an unrelated file or folder nearby, then rename it back again.
  • The original folder or file should now be "unlocked"
You can always reboot to fix it, too.

Ctrl-C doesn't interrupt loop in Bash script

If you want Ctrl-C to be able to stop your loop in Bash, put this inside the loop:

trap "echo Exited!; exit;" SIGINT SIGTERM

(source)

SSH warning: authenticity of host can't be established

Problem

The authenticity of host 'example.com (1.2.3.4)' can't be established.
RSA key fingerprint is ab:cd:ef:12:34:56:78:90:ab:cd:ef:12:34:56:78:90
Are you sure you want to continue connecting (yes/no)?

Solution

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no

Make sure you understand the security implications of doing this (Hint: they're not good).

(source)

Advanced subversion usage

Rebase branch on trunk

cd /working/dir/path/to/branch

svn log --stop-on-copy | tail -4 | grep ^r | cut -d' ' -f1 | sed 's/r//'
1111

svn propget db:::dweb::trunk:last_merge_from /working/dir/path/to/branch
2222

svn merge -r 1110:2222 https://remote/path/to/trunk /working/dir/path/to/branch

# check for conflicts and test

svn commit -m'Pull from trunk'

Diff branch against trunk

svn propget db:::dweb::trunk:last_merge_from /working/dir/path/to/branch
1111

svn diff https://remote/path/to/trunk@1111 https://remote/path/to/branch

When to use "or" and when to use || (double pipe) in Perl

Use || for assigning to a variable:

$a = $b || $c

Use "or" to control program flow:

$a = $b or die 'error: $b is unexpectedly false'

Mnemonic: || is a symbol like variables and numbers are, while "or" and "die" are both english words.

(source, source)

Terminal does not wrap properly in linux

Sometimes lines don't wrap correctly in a bash terminal in linux - long lines overlap and overwrite the beginning of the line instead of continuing onto the next line.

To fix it:
shopt -s checkwinsize

To check it:
shopt  | grep checkwinsize
You should see:
checkwinsize    on

If it still isn't working, try:
reset

(source)

Create a lot of random data files on linux

# Create 10Mb random data

dd bs=1024 count=10240 < /dev/urandom > data

# Split into files of 10K each

split -a 5 -b 10240 data 'split.'

Client-side web design frameworks

A short list:

  • Foundation - doesn't work in IE8, and doesn't even degrade gracefully
  • Bootstrap - from Twitter. Works in IE8
  • Alternatives are available

See all commit messages in svn log

After merging a branch to trunk, subversion does not include commit logs from branches in the trunk log. With a little work it can be persuaded to display the log in a more useful way, see "svnlogg" perl script below.

When viewing this log output you may want to see the diff of one of the changes and naively type:

    svn diff -c 69271

...this may produce no output. However, if you type this intead:

    svn diff -c 69271 https://www.example.com/repo/branches/feature_xyz

...then you will see the expected output.

How to determine the branch name from the commit message is left as an exercise for the reader.


"svnlogg" perl script:

#!/usr/bin/env perl

# First, get all the commits.
# -v shows the filenames of changed files,
# -g shows commits from all merged branches.

my $LOG_TEMP = "/tmp/log.txt";

system("svn log -v -g > $LOG_TEMP");

# Then split the list into individual commits, filter out ones we don't want to see, and sort by date:

open(my $fh,"<",$LOG_TEMP) or die "cannot open file $LOG_TEMP";
local $/="------------------------------------------------------------------------"; # define the record separator
my @a = <$fh>; # populate an array with the commit messages
foreach my $aa (
    sort {
        # sort the commits by date (descending)
        my ($c) = $a =~ /\s\|\s(\d\d\d\d\-\d\d\-\d\d)\s/; # extract date field
        my ($d) = $b =~ /\s\|\s(\d\d\d\d\-\d\d\-\d\d)\s/; #
        $d cmp $c
    } @a
) {
    # exclude unwanted messages, especially the hundreds of "remove svn:mergeinfo"
    # also exclude the commit messages we use by convention in our organisation
    # to refer to branches and merges
    if ($aa !~ /(remove svn:mergeinfo|branching|final pull)/i) {
        print "$aa\n";
    }
}

Depending on your hardware it may be unusably slow, so pipe it into a file for viewing later.

Outlook 2007 autocomplete doesn't work

It really doesn't.

I tried these things:
  • Adding the name to my contacts list
  • Composing and sending an email to the contact (source)
  • Tools | Address Book | Tools | Options | Check names using these address lists | Contacts
Some names are auto-completed, but some aren't.
Note: I 

:-(

Does you know how to make it work? Leave a comment

Git: Change author name in all previous commits

On any branch, or trunk:

git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Josh Lee" ];
  then export GIT_AUTHOR_NAME="Hobo Bob"; export GIT_AUTHOR_EMAIL=hobo@example.com;
       export GIT_COMMITTER_NAME="Hobo Bob"; export GIT_COMMITTER_EMAIL=hobo@example.com;
fi; git commit-tree "$@"'