Commit Diff


commit - 5489743fa2b652dc080c3ecb621f80a5de568ce5
commit + 788c352e1f3b00dfa5628e7ccfcfb056433c1948
blob - a8dad302445587afca3921aacfe506fb6b487b18
blob + a80083bfb47f68f00c32b5b01618c6fbc9aa66a7
--- got/got.c
+++ got/got.c
@@ -323,23 +323,29 @@ print_commit(struct got_commit_object *commit, struct 
 	const struct got_error *err = NULL;
 	char *id_str, *datestr, *logmsg, *line;
 	char datebuf[26];
+	time_t author_time, committer_time;
 
 	err = got_object_id_str(&id_str, id);
 	if (err)
 		return err;
+
+	author_time = mktime(&commit->tm_author);
+	committer_time = mktime(&commit->tm_committer);
+#if 0
+	/* This would express the date in committer's timezone. */
+	author_time += commit->tm_author.tm_gmtoff;
+	committer_time += commit->tm_committer.tm_gmtoff;
+#endif
 
 	printf("-----------------------------------------------\n");
 	printf("commit %s\n", id_str);
 	free(id_str);
-	datestr = get_datestr(&commit->author_time, datebuf);
-	printf("author: %s  %s %s\n", commit->author, datestr,
-	    commit->author_tzoff);
+	datestr = get_datestr(&author_time, datebuf);
+	printf("author: %s  %s UTC\n", commit->author, datestr);
 	if (strcmp(commit->author, commit->committer) != 0 ||
-	    commit->author_time != commit->committer_time ||
-	    strcmp(commit->author_tzoff, commit->committer_tzoff) != 0) {
-		datestr = get_datestr(&commit->committer_time, datebuf);
-		printf("committer: %s  %s %s\n", commit->committer,
-		    datestr, commit->committer_tzoff);
+	    author_time != committer_time) {
+		datestr = get_datestr(&committer_time, datebuf);
+		printf("committer: %s  %s UTC\n", commit->committer, datestr);
 	}
 	if (commit->nparents > 1) {
 		struct got_object_qid *qid;
blob - 1f6e4e055123872ec7e6b34a908765fe2bb1abdf
blob + ec5c5b134da4aac3b2260284f17374a481a813ca
--- include/got_object.h
+++ include/got_object.h
@@ -42,11 +42,9 @@ struct got_commit_object {
 	unsigned int nparents;
 	struct got_object_id_queue parent_ids;
 	char *author;
-	time_t author_time;	/* local time */
-	char *author_tzoff;	/* timezone offset description */
+	struct tm tm_author;	/* UTC */
 	char *committer;
-	time_t committer_time;	/* local time */
-	char *committer_tzoff;	/* timezone offset description */
+	struct tm tm_committer;	/* UTC */
 	char *logmsg;
 };
 
blob - 9e8852e024353a395aff616e5276a04585dd2240
blob + 958b66ec82b4dd7e18be4a27f9d081e78e7b6484
--- lib/commit_graph.c
+++ lib/commit_graph.c
@@ -281,7 +281,9 @@ add_node(struct got_commit_graph_node **new_node,
 			return err;
 		node->nparents++;
 	}
-	node->commit_timestamp = commit->committer_time; /* XXX not UTC! */
+	node->commit_timestamp = mktime(&commit->tm_committer); 
+	if (node->commit_timestamp == -1)
+		return got_error_from_errno();
 
 	err = got_object_idset_add((void **)(&existing_node),
 	    graph->node_ids, &node->id, node);
blob - af295fc40438bb0ead909df0299dc917f29ea676
blob + 5d81bff851248d53b410b6439315d28e2f467c7f
--- lib/delta.c
+++ lib/delta.c
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <zlib.h>
 #include <sha1.h>
+#include <time.h>
 
 #include "got_error.h"
 #include "got_repository.h"
blob - 0f2d7838f8a00ec112a1ba2bf0d7b3340e6c8808
blob + 67a687b619f5daf43ec02cb885bec570058db386
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -99,17 +99,14 @@ struct got_imsg_object {
 struct got_imsg_commit_object {
 	uint8_t tree_id[SHA1_DIGEST_LENGTH];
 	size_t author_len;
-	time_t author_time;
-	size_t author_tzoff_len;
+	struct tm tm_author;
 	size_t committer_len;
-	time_t committer_time;
-	size_t committer_tzoff_len;
+	struct tm tm_committer;
 	size_t logmsg_len;
 	int nparents;
 
 	/*
-	 * Followed by author_len + author_tzoff_len + committer_len +
-	 * committer_tzoff_len + logmsg_len data bytes
+	 * Followed by author_len + committer_len + logmsg_len data bytes
 	 */
 
 	/* Followed by 'nparents' SHA1_DIGEST_LENGTH length strings */
blob - 498d4c5d14364cf60575dcef5d969848dbb895a8
blob + 1765ec7c9ff3743ac32416d1a8baa920602a89c6
--- lib/object.c
+++ lib/object.c
@@ -32,6 +32,7 @@
 #include <ctype.h>
 #include <limits.h>
 #include <imsg.h>
+#include <time.h>
 
 #include "got_error.h"
 #include "got_object.h"
@@ -493,20 +494,52 @@ got_object_commit_add_parent(struct got_commit_object 
 }
 
 static const struct got_error *
-parse_commit_time(time_t *time, char **tzoff, char *committer)
+parse_gmtoff(time_t *gmtoff, const char *tzstr)
 {
-	const char *errstr;
-	char *space;
+	int sign = 1;
+	const char *p = tzstr;
+	time_t h, m;
 
-	*time = 0;
+	*gmtoff = 0;
 
-	/* Parse and then strip trailing timezone indicator. */
+	if (*p == '-')
+		sign = -1;
+	else if (*p != '+')
+		return got_error(GOT_ERR_BAD_OBJ_DATA);
+	p++;
+	if (!isdigit(*p) && !isdigit(*(p + 1)))
+		return got_error(GOT_ERR_BAD_OBJ_DATA);
+	h = (((*p - '0') * 10) + (*(p + 1) - '0'));
+
+	p += 2;
+	if (!isdigit(*p) && !isdigit(*(p + 1)))
+		return got_error(GOT_ERR_BAD_OBJ_DATA);
+	m = ((*p - '0') * 10) + (*(p + 1) - '0');
+
+	*gmtoff = (h * 60 * 60 + m * 60) * sign;
+	return NULL;
+}
+
+static const struct got_error *
+parse_commit_time(struct tm *tm, char *committer)
+{
+	const struct got_error *err = NULL;
+	const char *errstr;
+	char *space, *tzstr;
+	time_t gmtoff;
+	time_t time;
+
+	/* Parse and strip off trailing timezone indicator string. */
 	space = strrchr(committer, ' ');
 	if (space == NULL)
 		return got_error(GOT_ERR_BAD_OBJ_DATA);
-	*tzoff = strdup(space + 1);
-	if (*tzoff == NULL)
+	tzstr = strdup(space + 1);
+	if (tzstr == NULL)
 		return got_error_from_errno();
+	err = parse_gmtoff(&gmtoff, tzstr);
+	free(tzstr);
+	if (err)
+		return err;
 	*space = '\0';
 
 	/* Timestamp is separated from committer name + email by space. */
@@ -514,12 +547,21 @@ parse_commit_time(time_t *time, char **tzoff, char *co
 	if (space == NULL)
 		return got_error(GOT_ERR_BAD_OBJ_DATA);
 
-	*time = strtonum(space + 1, 0, INT64_MAX, &errstr);
+	/* Timestamp parsed here is expressed in comitter's local time. */
+	time = strtonum(space + 1, 0, INT64_MAX, &errstr);
 	if (errstr)
 		return got_error(GOT_ERR_BAD_OBJ_DATA);
 
+	/* Express the time stamp in UTC. */
+	memset(tm, 0, sizeof(*tm));
+	time -= gmtoff;
+	if (localtime_r(&time, tm) == NULL)
+		return got_error_from_errno();
+	tm->tm_gmtoff = gmtoff;
+
 	/* Strip off parsed time information, leaving just author and email. */
 	*space = '\0';
+
 	return NULL;
 }
 
@@ -588,8 +630,7 @@ parse_commit_object(struct got_commit_object **commit,
 		}
 		*p = '\0';
 		slen = strlen(s);
-		err = parse_commit_time(&(*commit)->author_time,
-		    &(*commit)->author_tzoff, s);
+		err = parse_commit_time(&(*commit)->tm_author, s);
 		if (err)
 			goto done;
 		(*commit)->author = strdup(s);
@@ -619,8 +660,7 @@ parse_commit_object(struct got_commit_object **commit,
 		}
 		*p = '\0';
 		slen = strlen(s);
-		err = parse_commit_time(&(*commit)->committer_time,
-		    &(*commit)->committer_tzoff, s);
+		err = parse_commit_time(&(*commit)->tm_committer, s);
 		if (err)
 			goto done;
 		(*commit)->committer = strdup(s);
@@ -949,9 +989,7 @@ got_object_commit_close(struct got_commit_object *comm
 
 	free(commit->tree_id);
 	free(commit->author);
-	free(commit->author_tzoff);
 	free(commit->committer);
-	free(commit->committer_tzoff);
 	free(commit->logmsg);
 	free(commit);
 }
blob - e7e8b1b918ce38fbbb00abcd2583937dcfabf32b
blob + ae64f9afe555ae449ffadfb4d39015675ba0b35b
--- lib/object_idset.c
+++ lib/object_idset.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <zlib.h>
 #include <limits.h>
+#include <time.h>
 
 #include "got_object.h"
 #include "got_error.h"
blob - 1c18f16672018cc1aea650967e5b3d848968f948
blob + 2fc13c0bc4f4adfde459767488c025425b5a05fe
--- lib/privsep.c
+++ lib/privsep.c
@@ -27,6 +27,7 @@
 #include <imsg.h>
 #include <sha1.h>
 #include <zlib.h>
+#include <time.h>
 
 #include "got_object.h"
 #include "got_error.h"
@@ -266,17 +267,16 @@ got_privsep_send_commit(struct imsgbuf *ibuf, struct g
 
 	memcpy(icommit.tree_id, commit->tree_id->sha1, sizeof(icommit.tree_id));
 	icommit.author_len = strlen(commit->author);
-	icommit.author_time = commit->author_time;
-	icommit.author_tzoff_len = strlen(commit->author_tzoff);
+	memcpy(&icommit.tm_author, &commit->tm_author,
+	    sizeof(icommit.tm_author));
 	icommit.committer_len = strlen(commit->committer);
-	icommit.committer_time = commit->committer_time;
-	icommit.committer_tzoff_len = strlen(commit->committer_tzoff);
+	memcpy(&icommit.tm_committer, &commit->tm_committer,
+	    sizeof(icommit.tm_committer));
 	icommit.logmsg_len = strlen(commit->logmsg);
 	icommit.nparents = commit->nparents;
 
 	total = sizeof(icommit) + icommit.author_len +
-	    icommit.author_tzoff_len + icommit.committer_len +
-	    icommit.committer_tzoff_len + icommit.logmsg_len +
+	    icommit.committer_len + icommit.logmsg_len +
 	    icommit.nparents * SHA1_DIGEST_LENGTH;
 	/* XXX TODO support very large log messages properly */
 	if (total > MAX_IMSGSIZE)
@@ -291,12 +291,8 @@ got_privsep_send_commit(struct imsgbuf *ibuf, struct g
 	len += sizeof(icommit);
 	memcpy(buf + len, commit->author, icommit.author_len);
 	len += icommit.author_len;
-	memcpy(buf + len, commit->author_tzoff, icommit.author_tzoff_len);
-	len += icommit.author_tzoff_len;
 	memcpy(buf + len, commit->committer, icommit.committer_len);
 	len += icommit.committer_len;
-	memcpy(buf + len, commit->committer_tzoff, icommit.committer_tzoff_len);
-	len += icommit.committer_tzoff_len;
 	memcpy(buf + len, commit->logmsg, icommit.logmsg_len);
 	len += icommit.logmsg_len;
 	SIMPLEQ_FOREACH(qid, &commit->parent_ids, entry) {
@@ -349,8 +345,7 @@ got_privsep_recv_commit(struct got_commit_object **com
 
 		memcpy(&icommit, data, sizeof(icommit));
 		if (datalen != sizeof(icommit) + icommit.author_len +
-		    icommit.author_tzoff_len + icommit.committer_len +
-		    icommit.committer_tzoff_len + icommit.logmsg_len +
+		    icommit.committer_len + icommit.logmsg_len +
 		    icommit.nparents * SHA1_DIGEST_LENGTH) {
 			err = got_error(GOT_ERR_PRIVSEP_LEN);
 			break;
@@ -369,6 +364,10 @@ got_privsep_recv_commit(struct got_commit_object **com
 
 		memcpy((*commit)->tree_id->sha1, icommit.tree_id,
 		    SHA1_DIGEST_LENGTH);
+		memcpy(&(*commit)->tm_author, &icommit.tm_author,
+		    sizeof((*commit)->tm_author));
+		memcpy(&(*commit)->tm_committer, &icommit.tm_committer,
+		    sizeof((*commit)->tm_committer));
 
 		if (icommit.author_len == 0) {
 			(*commit)->author = strdup("");
@@ -376,7 +375,6 @@ got_privsep_recv_commit(struct got_commit_object **com
 				err = got_error_from_errno();
 				break;
 			}
-			(*commit)->author_time = 0;
 		} else {
 			(*commit)->author = malloc(icommit.author_len + 1);
 			if ((*commit)->author == NULL) {
@@ -389,34 +387,12 @@ got_privsep_recv_commit(struct got_commit_object **com
 		}
 		len += icommit.author_len;
 
-		(*commit)->author_time = icommit.author_time;
-		if (icommit.author_tzoff_len == 0) {
-			(*commit)->author_tzoff = strdup("");
-			if ((*commit)->author_tzoff == NULL) {
-				err = got_error_from_errno();
-				break;
-			}
-		} else {
-			(*commit)->author_tzoff =
-			    malloc(icommit.author_tzoff_len + 1);
-			if ((*commit)->author_tzoff == NULL) {
-				err = got_error_from_errno();
-				break;
-			}
-			memcpy((*commit)->author_tzoff, data + len,
-			    icommit.author_tzoff_len);
-			(*commit)->author_tzoff[icommit.author_tzoff_len] =
-			    '\0';
-		}
-		len += icommit.author_tzoff_len;
-
 		if (icommit.committer_len == 0) {
 			(*commit)->committer = strdup("");
 			if ((*commit)->committer == NULL) {
 				err = got_error_from_errno();
 				break;
 			}
-			(*commit)->committer_time = 0;
 		} else {
 			(*commit)->committer =
 			    malloc(icommit.committer_len + 1);
@@ -430,27 +406,6 @@ got_privsep_recv_commit(struct got_commit_object **com
 		}
 		len += icommit.committer_len;
 
-		(*commit)->committer_time = icommit.committer_time;
-		if (icommit.committer_tzoff_len == 0) {
-			(*commit)->committer_tzoff = strdup("");
-			if ((*commit)->committer_tzoff == NULL) {
-				err = got_error_from_errno();
-				break;
-			}
-		} else {
-			(*commit)->committer_tzoff =
-			    malloc(icommit.committer_tzoff_len + 1);
-			if ((*commit)->committer_tzoff == NULL) {
-				err = got_error_from_errno();
-				break;
-			}
-			memcpy((*commit)->committer_tzoff, data + len,
-			    icommit.committer_tzoff_len);
-			(*commit)->committer_tzoff[icommit.committer_tzoff_len]
-			    = '\0';
-		}
-		len += icommit.committer_tzoff_len;
-
 		if (icommit.logmsg_len == 0) {
 			(*commit)->logmsg = strdup("");
 			if ((*commit)->logmsg == NULL) {
blob - 8336d486ab9d4e22fab6d158517d9809b5c84bbf
blob + 635623e6ce2338f4495a8e2021c539a29cf39b14
--- lib/reference.c
+++ lib/reference.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <util.h>
 #include <zlib.h>
+#include <time.h>
 
 #include "got_error.h"
 #include "got_object.h"
blob - 90a2cab8ef89165a7eec96bcb7f6dbf99119e75b
blob + cd8dc7d1925b20202d7dd0d3f89e37bcc75806da
--- lib/zbuf.c
+++ lib/zbuf.c
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <sha1.h>
 #include <zlib.h>
+#include <time.h>
 
 #include "got_error.h"
 #include "got_object.h"
blob - 3b6200000b3462fc4fa34348605f411fe70b4896
blob + 35a2c48dd780532592d387e60fde43f989958b1f
--- regress/idset/idset_test.c
+++ regress/idset/idset_test.c
@@ -23,6 +23,7 @@
 #include <err.h>
 #include <sha1.h>
 #include <zlib.h>
+#include <time.h>
 
 #include "got_error.h"
 #include "got_object.h"
blob - 96875062cb41b6f612b4a6972fde4cb283909042
blob + b4bebe2c83c1a2648a3c9a817ed26bcd7327542e
--- tog/tog.c
+++ tog/tog.c
@@ -31,6 +31,7 @@
 #include <util.h>
 #include <limits.h>
 #include <wchar.h>
+#include <time.h>
 
 #include "got_error.h"
 #include "got_object.h"