I store all my git repositories under the same directory, unsurprisingly called ~/git. I needed a way to have a quick list of what I have done in all of them in a given time, so I wrote a script named (probably incorrectly) my-git-metachangelog.sh. This script iterates all subdirectories, finds all that are git repositories, takes a shortlog for all of them, and sorts by date. The fields shown are: date, time, project and the first line of the commit message.
By default, shows the short log for the last 6 months. It accepts an optional unique argument with the number of months to summarize.
This is an example of its output:
2008-12-11 18:25:29 gruta: Changed all POD docum. in templates to head2. 2008-12-11 17:04:37 gruta: New templates 'main_top' and 'main_bottom'. 2008-12-11 10:57:19 grutatxt: The option 'no-pure-verbatim' has been docum. 2008-12-11 10:25:26 grutatxt: Don't move to 'blockquote' if in 'pre' mode. 2008-12-11 10:19:44 grutatxt: Strip bold form head2 documentation. 2008-12-11 10:17:11 grutatxt: 'pod2grutatxt' creates 'NAME' (Closes: #1016). 2008-12-11 10:08:07 grutatxt: Improved header generation in pod2grutatxt. 2008-12-11 09:49:30 grutatxt: New '--no-pure-verbatim' mode (Closes: #1015). 2008-12-10 14:24:06 mp-5.x: Updated TODO. 2008-12-10 07:25:44 gruta: New field 'description' (Closes: #1050). 2008-12-09 20:20:52 mp-5.x: Small documentation tweaks. 2008-12-09 13:47:48 gruta: More comments in templates. 2008-12-07 19:58:33 mp-5.x: New syntax color for special doc. blocks. 2008-12-07 08:42:38 mp-5.x: Version 5.1.1 RELEASED. ...
And the script:
#!/bin/sh
# my-git-metachangelog.sh
# Angel Ortega <angel@triptico.com> - public domain
MONTHS=$1
[ -z "$MONTHS" ] && MONTHS=6
for r in *
do [ -d ${r}/.git ] &&
(cd $r ; git-log --no-merges \
--since="$MONTHS months ago" \
--pretty="format:%ai $r: %s%n")
done | \
grep -v '^$' | sed -e 's/+[0-9][0-9][0-9][0-9] //' | \
sort -r | less
Sometimes is useful to have columns that are automatically created using operations with other ones. Certainly this violates the Relational Model, but sometimes you don't have a choice if the database schema was given to you by a legacy system.
In my case, I found a living system with a table like this:
CREATE TABLE users ( first_name VARCHAR, family_name VARCHAR, full_name VARCHAR PRIMARY KEY );
It's certainly aberrant; the full_name column is just a concatenation of the other two. For additional fun, it's the primary key.
PostgreSQL makes maintaining this monster easier by using triggers.
First, create the following function (this is in plpgsql, but it could be done in any programming language linked to the PostgreSQL engine):
CREATE FUNCTION build_user_full_name_func () RETURNS trigger AS ' BEGIN NEW.full_name = NEW.first_name || '' '' || NEW.family_name; RETURN NEW; END; ' LANGUAGE plpgsql;
What this function does should be obvious: update full_name concatenating the other two columns with a space in between.
The magic is done creating this trigger:
CREATE TRIGGER build_user_full_name_trg BEFORE INSERT OR UPDATE
ON users FOR EACH ROW
EXECUTE PROCEDURE build_user_full_name_func ();
Whenever users is affected by an INSERT or UPDATE, the trigger is called, and full_name (re)built.
If you are having an attack from an IP and want to ban it right now, use this ban_ip script:
ban_ip() { iptables -A INPUT -s $1 -j DROP; }
Just set the following environment variable:
export SDL_VIDEO_X11_DGAMOUSE=0
nif() { echo $1$(expr substr TRWAGMYFPDXBNJZSQVHLCKET $(($1 % 23 + 1)) 1) ; }
Acepta como primer argumento el número de NIF (sin ceros por delante, si los llevara). Útil para añadir a ~/.bashrc.
http://hardware.slashdot.org/article.pl?sid=08/11/06/1549256
The following two interesting tools are referred there:
"par2 is a program for creating and using PAR2 files to detect damage in data files and repair them if necessary. It can be used with any kind of file."
"dvdisaster provides a margin of safety against data loss on CD and DVD media caused by scratches or aging media. It creates error correction data which is used to recover unreadable sectors if the disc becomes damaged at a later time."
Dvdisaster approach is specially interesting, as it can append its error correction information to an existing .iso file, using as much space as available to fill the smallest medium size (CD, DVD or DVD9). That information seems to be invisible, so it does not interfere with the media content.
dvdisaster -i cd.iso -mRS02 -c
Links:
What I use here to emulate static pages:
RewriteEngine On RewriteRule /(img|download)/.* - [L] RewriteRule ^/(.+)/index\.html$ /?t=TOPIC&topic=$1 [PT] RewriteRule ^/(.+)/(.+)\.html$ /?t=STORY&topic=$1&id=$2 [PT] RewriteRule ^/(.+)/$ /?t=TOPIC&topic=$1 [PT] RewriteRule ^/rss\.xml$ /?t=RSS [PT] RewriteRule ^/sitemap\.xml$ /?t=SITEMAP [PT]
In a clone of a remote repository, start a branch to hold your code:
git-checkout -b my-changes
Do your work and commit changes as you like.
When you are happy with your work, create a temporary directory:
mkdir /tmp/patches
Then change back to the master branch and build a set of patches from your branch with git-format-patch:
git-checkout master git-format-patch -n master..my-changes -o /tmp/patches
A bunch of files, one per changeset, have been created in /tmp/patches. Now, use the git-send-email to send them, one per email, to the original author.
git-send-email --no-thread --from me@here --to author@remote /tmp/patches
If author@remote acknowledges your changes, you can just merge your changes to the current master head and delete your temporary branch:
git-merge my-changes git-branch -d my-changes
If author@remote uses mutt, he can move to his working copy, call it and type |git-am on each message.
Git-svn is a useful tool to communicate with a Subversion repository from git. You usually clone a repository with a command like:
git-svn clone svn+ssh://angel@svn.example.com/path/to/prj/trunk prj
And a prj directory is created with a full git repository. Then, you get another people changes with git-svn rebase and commit yours with git-svn dcommit.
It has one drawback, though; authors are mangled to something like
Author: angel <angel@2e99d34b-3c1d-0410-9ca7-923d03b5684e>
which is not only ugly but completely useless.
To map this monstrosity to real user email addresses and names, use the following steps:
First, create the file ~/.gitusers with content like this:
angel = Ángel Ortega <angel@triptico.com> otheruser = Other User <ouser@example.net>
If you converted your SVN repository from CVS with something like cvs2svn you'll also find entries like this:
Author: (no author) <(no author)@2e99d34b-3c1d-0410-9ca7-923d03b5684e>
Those ones can be converted with another line in ~/.gitusers.
(no author) = Really Me <email@example.org>
And now, instead of the usual git-svn clone command, use the following ones:
mkdir prj cd prj git-svn init svn+ssh://angel@svn.example.com/path/to/prj/trunk git config svn.authorsfile ~/.gitusers git-svn fetch
Add this to your ~/.bashrc:
[ -z "$DISPLAY" ] || wmctrl -r :ACTIVE: -b add,maximized_vert,maximized_horz
git config --global user.name "Angel Ortega" git config --global user.email angel@triptico.com
pppd noauth 192.168.33.1:192.168.33.2 \
pty 'ssh root@REMOTE_HOST pppd notty noauth'
The remote host needs a passwordless authorized key.