git skew: a tool to find how big a clock skew exists in the history

> As you probably guessed from the specificity of the number, I wrote a > short program to actually traverse and find the worst skew. It takes > about 5 seconds to run (unsurprisingly, since it is doing the same full > traversal that we end up doing in the above numbers). So we could > "autoskew" by setting up the configuration on clone, and then > periodically updating it as part of "git gc". This patch doesn't implement auto-detection of skew, but is the program I used to calculate, and would provide the basis for such auto-detection. It would be interesting to see average skew numbers for popular repositories. You can run it as "git skew --all". Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jun 11, 2011 at 19:04 UTC 188c35e36d22c39074a8b0ee411483a405065a9a
5 files changed +54
.gitignore
+1
@@ -132,6 +132,7 @@
132 /git-show-branch
133 /git-show-index
134 /git-show-ref
135 +/git-skew
136 /git-stage
137 /git-stash
138 /git-status
Makefile
+1
@@ -725,6 +725,7 @@ BUILTIN_OBJS += builtin/send-pack.o
725 BUILTIN_OBJS += builtin/shortlog.o
726 BUILTIN_OBJS += builtin/show-branch.o
727 BUILTIN_OBJS += builtin/show-ref.o
728 +BUILTIN_OBJS += builtin/skew.o
729 BUILTIN_OBJS += builtin/stripspace.o
730 BUILTIN_OBJS += builtin/symbolic-ref.o
731 BUILTIN_OBJS += builtin/tag.o
builtin.h
+1
@@ -141,5 +141,6 @@ extern int cmd_verify_pack(int argc, const char **argv, const char *prefix);
141 extern int cmd_show_ref(int argc, const char **argv, const char *prefix);
142 extern int cmd_pack_refs(int argc, const char **argv, const char *prefix);
143 extern int cmd_replace(int argc, const char **argv, const char *prefix);
144 +extern int cmd_skew(int argc, const char **argv, const char *prefix);
145
146 #endif
builtin/skew.c new
+50
@@ -0,0 +1,50 @@
1 +#include "cache.h"
2 +#include "commit.h"
3 +#include "diff.h"
4 +#include "revision.h"
5 +
6 +unsigned long worst_skew = 0;
7 +
8 +static void check_skew_recurse(struct commit *c, unsigned long when)
9 +{
10 + struct commit_list *p;
11 +
12 + if (c->object.flags & SEEN)
13 + return;
14 + c->object.flags |= SEEN;
15 +
16 + if (parse_commit(c) < 0)
17 + return;
18 +
19 + if (c->date > when) {
20 + unsigned long skew = c->date - when;
21 + if (skew > worst_skew)
22 + worst_skew = skew;
23 + }
24 +
25 + for (p = c->parents; p; p = p->next)
26 + check_skew_recurse(p->item, c->date < when ? c->date : when);
27 +}
28 +
29 +static void check_skew(struct commit *c)
30 +{
31 + check_skew_recurse(c, time(NULL));
32 +}
33 +
34 +int cmd_skew(int argc, const char **argv, const char *prefix) {
35 + struct rev_info revs;
36 + int i;
37 +
38 + git_config(git_default_config, NULL);
39 + init_revisions(&revs, prefix);
40 + argc = setup_revisions(argc, argv, &revs, NULL);
41 +
42 + for (i = 0; i < revs.pending.nr; i++) {
43 + struct object *o = revs.pending.objects[i].item;
44 + if (o->type == OBJ_COMMIT)
45 + check_skew((struct commit *)o);
46 + }
47 +
48 + printf("%lu\n", worst_skew);
49 + return 0;
50 +}
git.c
+1
@@ -399,6 +399,7 @@ static void handle_internal_command(int argc, const char **argv)
399 { "verify-pack", cmd_verify_pack },
400 { "show-ref", cmd_show_ref, RUN_SETUP },
401 { "pack-refs", cmd_pack_refs, RUN_SETUP },
402 + { "skew", cmd_skew, RUN_SETUP },
403 };
404 int i;
405 static const char ext[] = STRIP_EXTENSION;