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@xxxxxxxxxxx> --- 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@xxxxxxxxxxx> */ 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html