From: Alessandro Di Marco <dmr@ethzero.com>
To: git@vger.kernel.org
Subject: [PATCH] Geolocation support
Date: Wed, 22 May 2013 15:25:02 +0200 [thread overview]
Message-ID: <87mwrncfkh.fsf@ethzero.com> (raw)
Hi all,
this is a hack I made a couple of years ago in order to store my current
location in git commits (I travel a lot and being able to associate a
place with the commit date helps me to quickly recover what were doing
at that time). Long story short, the screeenshot at
http://tinypic.com/r/wars40/5 shows the new gitk interface once this
patch has been integrated. Geolocation is controlled by two envvars
GIT_AUTHOR_PLACE and COMMITTER_PLACE, respectively. You can set them via
something like this:
function gitenv {
DATA="`tail -n1 /etc/geotags.dat`"
CITY="`echo \"$DATA\" | cut -d ',' -f 6 | sed -r 's/^\s+//'`"
COUNTRY="`echo \"$DATA\" | cut -d ',' -f 5 | sed -r 's/^\s+//'`"
LAT="`echo \"$DATA\" | cut -d ',' -f 2 | sed -r 's/^\s+//'`"
LON="`echo \"$DATA\" | cut -d ',' -f 3 | sed -r 's/^\s+//'`"
if [ -n "$CITY" ] ; then
export GIT_AUTHOR_PLACE="$CITY, $COUNTRY ($LAT, $LON)"
export GIT_COMMITTER_PLACE="$CITY, $COUNTRY ($LAT, $LON)"
else
export GIT_AUTHOR_PLACE="$COUNTRY ($LAT, $LON)"
export GIT_COMMITTER_PLACE="$COUNTRY ($LAT, $LON)"
fi
}
alias git='gitenv ; git'
Finally, here it is a sample of my geotags data (produced by a bash
script appending a line per wlan gateway change).
Mon Mar 4 19:18:00 CET 2013, 44.4167, 8.95, Europe, Italy, Genoa, Europe/Rome, 2.230.XXX.XX, Fastweb, Fastweb SpA
Wed Mar 6 01:14:43 CET 2013, 25.7743, -80.1937, North America, United States, Miami, America/New_York, 96.47.XXX.XXX, IPTelligent LLC, IPTelligent LLC
Mon May 6 22:29:01 UTC 2013, 35.685, 139.7514, Asia, Japan, Tokyo, Asia/Tokyo, 183.77.XXX.XXX, Asahi Net, Asahi Net
Thu May 16 21:55:20 UTC 2013, 44.4167, 8.95, Europe, Italy, Genoa, Europe/Rome, 2.230.XXX.XXX, Fastweb, Fastweb SpA
That's all folks.
Regards,
Alessandro
Signed-off-by: Alessandro Di Marco <dmr@ethzero.com>
---
builtin/blame.c | 2 +-
builtin/commit.c | 32 ++--
cache.h | 3 +-
fsck.c | 13 +-
gitk-git/gitk | 571 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
ident.c | 30 ++-
6 files changed, 619 insertions(+), 32 deletions(-)
diff --git a/builtin/blame.c b/builtin/blame.c
index 57a487e..6ed145c 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2136,7 +2136,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
origin = make_origin(commit, path);
- ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, 0);
+ ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, NULL, 0);
strbuf_addstr(&msg, "tree 0000000000000000000000000000000000000000\n");
for (parent = commit->parents; parent; parent = parent->next)
strbuf_addf(&msg, "parent %s\n",
diff --git a/builtin/commit.c b/builtin/commit.c
index d2f30d9..a19ae23 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -497,40 +497,46 @@ static int sane_ident_split(struct ident_split *person)
static void determine_author_info(struct strbuf *author_ident)
{
- char *name, *email, *date;
+ char *name, *email, *date, *place;
struct ident_split author;
name = getenv("GIT_AUTHOR_NAME");
email = getenv("GIT_AUTHOR_EMAIL");
date = getenv("GIT_AUTHOR_DATE");
+ place = getenv("GIT_AUTHOR_PLACE");
if (author_message) {
- const char *a, *lb, *rb, *eol;
+ const char *a, *lb1, *rb1, *lb2, *rb2, *eol;
size_t len;
a = strstr(author_message_buffer, "\nauthor ");
if (!a)
die(_("invalid commit: %s"), author_message);
- lb = strchrnul(a + strlen("\nauthor "), '<');
- rb = strchrnul(lb, '>');
- eol = strchrnul(rb, '\n');
- if (!*lb || !*rb || !*eol)
+ lb1 = strchrnul(a + strlen("\nauthor "), '<');
+ rb1 = strchrnul(lb1, '>');
+
+ lb2 = strchrnul(rb1, '(');
+ rb2 = strchrnul(lb2, ')');
+
+ eol = strchrnul(rb1, '\n');
+ if (!*lb1 || !*rb1 || !*lb2 || !*rb2 || !*eol)
die(_("invalid commit: %s"), author_message);
- if (lb == a + strlen("\nauthor "))
+ if (lb1 == a + strlen("\nauthor "))
/* \nauthor <foo@example.com> */
name = xcalloc(1, 1);
else
name = xmemdupz(a + strlen("\nauthor "),
- (lb - strlen(" ") -
+ (lb1 - strlen(" ") -
(a + strlen("\nauthor "))));
- email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
- date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
- len = eol - (rb + strlen("> "));
+ email = xmemdupz(lb1 + strlen("<"), rb1 - (lb1 + strlen("<")));
+ date = xmemdupz(rb1 + strlen("> "), lb2 - (rb1 + strlen("> ")));
+ place = xmemdupz(lb2 + strlen("("), eol - (lb2 + strlen(") ")));
+ len = lb2 - (rb1 + strlen("> "));
date = xmalloc(len + 2);
*date = '@';
- memcpy(date + 1, rb + strlen("> "), len);
+ memcpy(date + 1, rb1 + strlen("> "), len);
date[len + 1] = '\0';
}
@@ -546,7 +552,7 @@ static void determine_author_info(struct strbuf *author_ident)
if (force_date)
date = force_date;
- strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));
+ strbuf_addstr(author_ident, fmt_ident(name, email, date, place, IDENT_STRICT));
if (!split_ident_line(&author, author_ident->buf, author_ident->len) &&
sane_ident_split(&author)) {
export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0);
diff --git a/cache.h b/cache.h
index 94ca1ac..c40d596 100644
--- a/cache.h
+++ b/cache.h
@@ -919,9 +919,10 @@ enum date_mode parse_date_format(const char *format);
#define IDENT_STRICT 1
#define IDENT_NO_DATE 2
#define IDENT_NO_NAME 4
+#define IDENT_NO_PLACE 8
extern const char *git_author_info(int);
extern const char *git_committer_info(int);
-extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);
+extern const char *fmt_ident(const char *name, const char *email, const char *date_str, const char *place, int);
extern const char *fmt_name(const char *name, const char *email);
extern const char *ident_default_email(void);
extern const char *git_editor(void);
diff --git a/fsck.c b/fsck.c
index 99c0497..a8ff1d3 100644
--- a/fsck.c
+++ b/fsck.c
@@ -273,9 +273,20 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
!isdigit((*ident)[2]) ||
!isdigit((*ident)[3]) ||
!isdigit((*ident)[4]) ||
- ((*ident)[5] != '\n'))
+ ((*ident)[5] != '\n' && (*ident)[5] != ' '))
return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad time zone");
(*ident) += 6;
+ if (**ident == '(') {
+ (*ident)++;
+ *ident += strcspn(*ident, "( \n");
+ if (**ident != '(')
+ return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad place");
+ (*ident)++;
+ *ident += strspn(*ident, "-0123456789.,_");
+ if ((*ident)[0] != ')' || (*ident)[1] != ')')
+ return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad coordinates");
+ (*ident) += 3;
+ }
return 0;
}
diff --git a/gitk-git/gitk b/gitk-git/gitk
index 5cd00d8..efd7ea9 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -8,6 +8,7 @@ exec wish "$0" -- "$@"
# either version 2, or (at your option) any later version.
package require Tk
+package require Img
proc hasworktree {} {
return [expr {[exec git rev-parse --is-bare-repository] == "false" &&
@@ -1672,12 +1673,33 @@ proc parsecommit {id contents listed} {
foreach line [split $header "\n"] {
set line [split $line " "]
set tag [lindex $line 0]
+
+ set match ""
+
if {$tag == "author"} {
- set audate [lrange $line end-1 end]
- set auname [join [lrange $line 1 end-2] " "]
+ regexp {\(.*\)} [lindex $line end] match
+
+ set auplace $match
+
+ if {$match == ""} {
+ set audate [lrange $line end-1 end]
+ set auname [join [lrange $line 1 end-2] " "]
+ } else {
+ set audate [lrange $line end-2 end]
+ set auname [join [lrange $line 1 end-3] " "]
+ }
} elseif {$tag == "committer"} {
- set comdate [lrange $line end-1 end]
- set comname [join [lrange $line 1 end-2] " "]
+ regexp {\(.*\)} [lindex $line end] match
+
+ set complace $match
+
+ if {$match == ""} {
+ set comdate [lrange $line end-1 end]
+ set comname [join [lrange $line 1 end-2] " "]
+ } else {
+ set comdate [lrange $line end-2 end]
+ set comname [join [lrange $line 1 end-3] " "]
+ }
}
}
set headline {}
@@ -1705,7 +1727,7 @@ proc parsecommit {id contents listed} {
}
set hasnote [string first "\nNotes:\n" $contents]
set commitinfo($id) [list $headline $auname $audate \
- $comname $comdate $comment $hasnote]
+ $comname $comdate $comment $auplace $complace $hasnote]
}
proc getcommit {id} {
@@ -2020,7 +2042,8 @@ proc makedroplist {w varname args} {
}
proc makewindow {} {
- global canv canv2 canv3 linespc charspc ctext cflist cscroll
+ global canv canv2 canv3 canv4 linespc charspc ctext cflist cscroll
+ global wwidth wheight
global tabstop
global findtype findtypemenu findloc findstring fstring geometry
global entries sha1entry sha1string sha1but
@@ -2107,6 +2130,7 @@ proc makewindow {} {
set geometry(botwidth) [expr {50 * $charspc}]
set geometry(pwsash0) [list [expr {40 * $charspc}] 2]
set geometry(pwsash1) [list [expr {60 * $charspc}] 2]
+ set geometry(pwsash2) [list [expr {80 * $charspc}] 2]
}
# the upper half will have a paned window, a scroll bar to the right, and some stuff below
@@ -2117,6 +2141,489 @@ proc makewindow {} {
.tf.histframe.pwclist configure -sashpad 0 -handlesize 4
}
+ set world {
+ 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
+ iVoUKFJJf//Z
+ }
+
# create three canvases
set cscroll .tf.histframe.csb
set canv .tf.histframe.pwclist.canv
@@ -2135,15 +2642,26 @@ proc makewindow {} {
-selectbackground $selectbgcolor \
-background $bgcolor -bd 0 -yscrollincr $linespc
.tf.histframe.pwclist add $canv3
+ set canv4 .tf.histframe.pwclist.canv4
+ canvas $canv4
+ .tf.histframe.pwclist add $canv4
+ image create photo world -data $world
+ $canv4 create image 0 0 -anchor nw -image world
+
+ set wheight [image height world]
+ set wwidth [image width world]
+
if {$use_ttk} {
bind .tf.histframe.pwclist <Map> {
bind %W <Map> {}
+ .tf.histframe.pwclist sashpos 2 [lindex $::geometry(pwsash2) 0]
.tf.histframe.pwclist sashpos 1 [lindex $::geometry(pwsash1) 0]
.tf.histframe.pwclist sashpos 0 [lindex $::geometry(pwsash0) 0]
}
} else {
eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
+ eval .tf.histframe.pwclist sash place 2 $geometry(pwsash2)
}
# a scroll bar to rule them
@@ -2810,9 +3328,11 @@ proc savestuff {w} {
if {$use_ttk} {
puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sashpos 0] 1\""
puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\""
+ puts $f "set geometry(pwsash2) \"[.tf.histframe.pwclist sashpos 2] 1\""
} else {
puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
+ puts $f "set geometry(pwsash2) \"[.tf.histframe.pwclist sash coord 2]\""
}
puts $f "set geometry(botwidth) [winfo width .bleft]"
puts $f "set geometry(botheight) [winfo height .bleft]"
@@ -7072,7 +7592,8 @@ proc make_idmark {id} {
}
proc selectline {l isnew {desired_loc {}}} {
- global canv ctext commitinfo selectedline
+ global canv canv4 ctext commitinfo selectedline
+ global wwidth wheight
global canvy0 linespc parents children curview
global currentid sha1entry
global commentend idtags linknum
@@ -7153,9 +7674,41 @@ proc selectline {l isnew {desired_loc {}}} {
}
set info $commitinfo($id)
set date [formatdate [lindex $info 2]]
- $ctext insert end "[mc "Author"]: [lindex $info 1] $date\n"
+
+ # comment me for spot persistence
+ $canv4 delete "spot"
+
+ set place ""
+ regexp {\((.*)\)} [lindex $info 6] -> place
+
+ if {$place != ""} {
+ set place "[string map { _ \ } $place] "
+
+ set sub1 ""
+ set sub2 ""
+ regexp {[^\(]+\((-?[0-9\.]+), (-?[0-9\.]+)\)} $place -> sub1 sub2
+
+ if {$sub1 != "" && $sub2 != ""} {
+ set wx [expr {round(($sub2 + 180) * $wwidth / 360)} ]
+ set wy [expr {round((90 - $sub1) * $wheight / 180)} ]
+
+ $canv4 create oval [expr {$wx - 2}] [expr {$wy - 2}] [expr {$wx + 2}] [expr {$wy + 2}] -tags "spot" -outline #F00
+ }
+ }
+
+ $ctext insert end "[mc "Author"]: [lindex $info 1] $place$date\n"
+
set date [formatdate [lindex $info 4]]
- $ctext insert end "[mc "Committer"]: [lindex $info 3] $date\n"
+
+ set place ""
+ regexp {\((.*)\)} [lindex $info 7] -> place
+
+ if {$place != ""} {
+ set place "[string map { _ \ } $place] "
+ }
+
+ $ctext insert end "[mc "Committer"]: [lindex $info 3] $place$date\n"
+
if {[info exists idtags($id)]} {
$ctext insert end [mc "Tags:"]
foreach tag $idtags($id) {
diff --git a/ident.c b/ident.c
index 1c123e6..e31717f 100644
--- a/ident.c
+++ b/ident.c
@@ -1,7 +1,7 @@
/*
* ident.c
*
- * create git identifier lines of the form "name <email> date"
+ * create git identifier lines of the form "name <email> date place"
*
* Copyright (C) 2005 Linus Torvalds
*/
@@ -152,7 +152,7 @@ static int crud(unsigned char c)
* Copy over a string to the destination, but avoid special
* characters ('\n', '<' and '>') and remove crud at the end
*/
-static void strbuf_addstr_without_crud(struct strbuf *sb, const char *src)
+static void strbuf_addstr_without_crud(struct strbuf *sb, const char *src, int nospace)
{
size_t i, len;
unsigned char c;
@@ -185,6 +185,8 @@ static void strbuf_addstr_without_crud(struct strbuf *sb, const char *src)
switch (c) {
case '\n': case '<': case '>':
continue;
+ case ' ': if (nospace) c = '_';
+ break;
}
sb->buf[sb->len++] = c;
}
@@ -275,13 +277,14 @@ static const char *env_hint =
"\n";
const char *fmt_ident(const char *name, const char *email,
- const char *date_str, int flag)
+ const char *date_str, const char *place, int flag)
{
static struct strbuf ident = STRBUF_INIT;
char date[50];
int strict = (flag & IDENT_STRICT);
int want_date = !(flag & IDENT_NO_DATE);
int want_name = !(flag & IDENT_NO_NAME);
+ int want_place = !(flag & IDENT_NO_PLACE);
if (want_name && !name)
name = ident_default_name();
@@ -317,22 +320,33 @@ const char *fmt_ident(const char *name, const char *email,
strbuf_reset(&ident);
if (want_name) {
- strbuf_addstr_without_crud(&ident, name);
+ strbuf_addstr_without_crud(&ident, name, 0);
strbuf_addstr(&ident, " <");
}
- strbuf_addstr_without_crud(&ident, email);
+ strbuf_addstr_without_crud(&ident, email, 0);
if (want_name)
strbuf_addch(&ident, '>');
if (want_date) {
strbuf_addch(&ident, ' ');
- strbuf_addstr_without_crud(&ident, date);
+ strbuf_addstr_without_crud(&ident, date, 0);
}
+
+ if (want_place) {
+ strbuf_addstr(&ident, " (");
+
+ if (place) {
+ strbuf_addstr_without_crud(&ident, place, 1);
+ }
+
+ strbuf_addch(&ident, ')');
+ }
+
return ident.buf;
}
const char *fmt_name(const char *name, const char *email)
{
- return fmt_ident(name, email, NULL, IDENT_STRICT | IDENT_NO_DATE);
+ return fmt_ident(name, email, NULL, NULL, IDENT_STRICT | IDENT_NO_DATE | IDENT_NO_PLACE);
}
const char *git_author_info(int flag)
@@ -344,6 +358,7 @@ const char *git_author_info(int flag)
return fmt_ident(getenv("GIT_AUTHOR_NAME"),
getenv("GIT_AUTHOR_EMAIL"),
getenv("GIT_AUTHOR_DATE"),
+ getenv("GIT_AUTHOR_PLACE"),
flag);
}
@@ -356,6 +371,7 @@ const char *git_committer_info(int flag)
return fmt_ident(getenv("GIT_COMMITTER_NAME"),
getenv("GIT_COMMITTER_EMAIL"),
getenv("GIT_COMMITTER_DATE"),
+ getenv("GIT_COMMITTER_PLACE"),
flag);
}
--
1.8.1.5
next reply other threads:[~2013-05-22 13:25 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-22 13:25 Alessandro Di Marco [this message]
2013-05-23 8:45 ` [PATCH] Geolocation support Ramkumar Ramachandra
2013-05-23 9:52 ` Antoine Pelisse
2013-05-23 11:58 ` Alessandro Di Marco
2013-05-23 17:48 ` Junio C Hamano
2015-02-09 0:03 ` Alessandro Di Marco
2015-02-09 1:24 ` Junio C Hamano
2015-02-09 13:57 ` Ævar Arnfjörð Bjarmason
2015-02-09 19:13 ` Junio C Hamano
2015-02-12 20:50 ` Alessandro Di Marco
2015-02-12 20:57 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mwrncfkh.fsf@ethzero.com \
--to=dmr@ethzero.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.