mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-29 14:17:30 +02:00
eeshow/: option -H path_into_repo to list branched history of repository
This commit is contained in:
parent
9564707f83
commit
e18c146323
@ -13,7 +13,7 @@
|
|||||||
NAME = eeshow
|
NAME = eeshow
|
||||||
OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \
|
OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \
|
||||||
gui.o gui-over.o gui-aoi.o \
|
gui.o gui-over.o gui-aoi.o \
|
||||||
file.o git-file.o \
|
file.o git-file.o git-hist.o \
|
||||||
style.o fig.o record.o cro.o diff.o gfx.o dwg.o text.o misc.o
|
style.o fig.o record.o cro.o diff.o gfx.o dwg.o text.o misc.o
|
||||||
|
|
||||||
CFLAGS = -g -Wall -Wextra -Wno-unused-parameter -Wshadow \
|
CFLAGS = -g -Wall -Wextra -Wno-unused-parameter -Wshadow \
|
||||||
|
196
eeshow/git-hist.c
Normal file
196
eeshow/git-hist.c
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* git-hist.c - Retrieve revision history from GIT repo
|
||||||
|
*
|
||||||
|
* Written 2016 by Werner Almesberger
|
||||||
|
* Copyright 2016 by Werner Almesberger
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "git-hist.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @@@ we assume to have a single head. That isn't necessarily true, since
|
||||||
|
* each open branch has its own head. Getting this right is for further study.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static struct hist *new_commit(unsigned branch)
|
||||||
|
{
|
||||||
|
struct hist *h;
|
||||||
|
|
||||||
|
h = alloc_type(struct hist);
|
||||||
|
h->commit = NULL;
|
||||||
|
h->branch = branch;
|
||||||
|
h->newer = NULL;
|
||||||
|
h->n_newer = 0;
|
||||||
|
h->older = NULL;
|
||||||
|
h->n_older = 0;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void uplink(struct hist *down, struct hist *up)
|
||||||
|
{
|
||||||
|
down->newer = realloc(down->newer,
|
||||||
|
sizeof(struct hist *) * (down->n_newer + 1));
|
||||||
|
if (!down->newer) {
|
||||||
|
perror("realloc");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
down->newer[down->n_newer++] = up;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct hist *find_commit(struct hist *h, const git_commit *commit)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
struct hist *found;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @@@ should probably use
|
||||||
|
* git_oid_equal(git_object_id(a), git_object_id(b))
|
||||||
|
*/
|
||||||
|
if (h->commit == commit)
|
||||||
|
return h;
|
||||||
|
for (i = 0; i != h->n_older; i++) {
|
||||||
|
if (h->older[i]->newer[0] != h)
|
||||||
|
continue;
|
||||||
|
found = find_commit(h->older[i], commit);
|
||||||
|
if (found)
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void recurse(struct hist *h,
|
||||||
|
unsigned n_branches, struct hist **branches)
|
||||||
|
{
|
||||||
|
unsigned n, i, j;
|
||||||
|
struct hist **b;
|
||||||
|
const git_error *e;
|
||||||
|
|
||||||
|
n = git_commit_parentcount(h->commit);
|
||||||
|
if (verbose > 2)
|
||||||
|
fprintf(stderr, "commit %p: %u + %u\n",
|
||||||
|
h->commit, n_branches, n);
|
||||||
|
|
||||||
|
b = alloca(sizeof(struct hist) * (n_branches - 1 + n));
|
||||||
|
n_branches--;
|
||||||
|
memcpy(b, branches, sizeof(struct hist *) * n_branches);
|
||||||
|
|
||||||
|
h->older = alloc_size(sizeof(struct hist *) * n);
|
||||||
|
h->n_older = n;
|
||||||
|
|
||||||
|
for (i = 0; i != n; i++) {
|
||||||
|
git_commit *commit;
|
||||||
|
struct hist *found = NULL;
|
||||||
|
|
||||||
|
if (git_commit_parent(&commit, h->commit, i)) {
|
||||||
|
e = giterr_last();
|
||||||
|
fprintf(stderr, "git_commit_parent: %s\n", e->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for (j = 0; j != n_branches; j++) {
|
||||||
|
found = find_commit(b[j], commit);
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
uplink(found, h);
|
||||||
|
h->older[i] = found;
|
||||||
|
} else {
|
||||||
|
struct hist *new;
|
||||||
|
|
||||||
|
new = new_commit(n_branches);
|
||||||
|
new->commit = commit;
|
||||||
|
h->older[i] = new;
|
||||||
|
b[n_branches++] = new;
|
||||||
|
uplink(new, h);
|
||||||
|
recurse(new, n_branches, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct hist *vcs_git_hist(const char *path)
|
||||||
|
{
|
||||||
|
struct hist *head;
|
||||||
|
git_repository *repo;
|
||||||
|
git_oid oid;
|
||||||
|
const git_error *e;
|
||||||
|
|
||||||
|
head = new_commit(0);
|
||||||
|
|
||||||
|
git_libgit2_init(); /* @@@ */
|
||||||
|
if (git_repository_open_ext(&repo, path,
|
||||||
|
GIT_REPOSITORY_OPEN_CROSS_FS, NULL)) {
|
||||||
|
e = giterr_last();
|
||||||
|
fprintf(stderr, "%s: %s\n", path, e->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (git_reference_name_to_id(&oid, repo, "HEAD")) {
|
||||||
|
e = giterr_last();
|
||||||
|
fprintf(stderr, "%s: %s\n",
|
||||||
|
git_repository_path(repo), e->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (git_commit_lookup(&head->commit, repo, &oid)) {
|
||||||
|
e = giterr_last();
|
||||||
|
fprintf(stderr, "%s: %s\n",
|
||||||
|
git_repository_path(repo), e->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
recurse(head, 1, &head);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *vcs_git_summary(struct hist *h)
|
||||||
|
{
|
||||||
|
const char *summary;
|
||||||
|
const git_error *e;
|
||||||
|
|
||||||
|
summary = git_commit_summary(h->commit);
|
||||||
|
if (summary)
|
||||||
|
return summary;
|
||||||
|
|
||||||
|
e = giterr_last();
|
||||||
|
fprintf(stderr, "git_commit_summary: %s\n", e->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dump_hist(struct hist *h)
|
||||||
|
{
|
||||||
|
git_buf buf = { 0 };
|
||||||
|
const git_error *e;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (git_object_short_id(&buf, (git_object *) h->commit)) {
|
||||||
|
e = giterr_last();
|
||||||
|
fprintf(stderr, "git_object_short_id: %s\n", e->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("%*s%s %s\n", 2 * h->branch, "", buf.ptr, vcs_git_summary(h));
|
||||||
|
git_buf_free(&buf);
|
||||||
|
|
||||||
|
for (i = 0; i != h->n_older; i++)
|
||||||
|
if (h->older[i]->newer[h->older[i]->n_newer - 1] == h)
|
||||||
|
dump_hist(h->older[i]);
|
||||||
|
}
|
36
eeshow/git-hist.h
Normal file
36
eeshow/git-hist.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* git-hist.h - Retrieve revision history from GIT repo
|
||||||
|
*
|
||||||
|
* Written 2016 by Werner Almesberger
|
||||||
|
* Copyright 2016 by Werner Almesberger
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GIT_HIST_H
|
||||||
|
#define GIT_HIST_H
|
||||||
|
|
||||||
|
#include <git2.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct hist {
|
||||||
|
struct git_commit *commit;
|
||||||
|
|
||||||
|
unsigned branch; /* branch index */
|
||||||
|
|
||||||
|
struct hist **newer;
|
||||||
|
unsigned n_newer;
|
||||||
|
|
||||||
|
struct hist **older;
|
||||||
|
unsigned n_older;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct hist *vcs_git_hist(const char *path);
|
||||||
|
const char *vcs_git_summary(struct hist *hist);
|
||||||
|
void dump_hist(struct hist *h);
|
||||||
|
|
||||||
|
#endif /* !GIT_HIST_H */
|
@ -27,6 +27,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
#include "sch.h"
|
#include "sch.h"
|
||||||
|
#include "git-hist.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
@ -48,11 +49,13 @@ void usage(const char *name)
|
|||||||
"usage: %s [-r] [-v ...] [[rev:]file.lib ...] [rev:]file.sch\n"
|
"usage: %s [-r] [-v ...] [[rev:]file.lib ...] [rev:]file.sch\n"
|
||||||
" %*s[-- driver_spec]\n"
|
" %*s[-- driver_spec]\n"
|
||||||
" %s [-v ...] -C [rev:]file\n"
|
" %s [-v ...] -C [rev:]file\n"
|
||||||
|
" %s [-v ...] -H path_into_repo\n"
|
||||||
"\n"
|
"\n"
|
||||||
" rev git revision\n"
|
" rev git revision\n"
|
||||||
" -r recurse into sub-sheets\n"
|
" -r recurse into sub-sheets\n"
|
||||||
" -v increase verbosity of diagnostic output\n"
|
" -v increase verbosity of diagnostic output\n"
|
||||||
" -C 'cat' the file to standard output\n"
|
" -C 'cat' the file to standard output\n"
|
||||||
|
" -H show history of repository on standard output\n"
|
||||||
"\n"
|
"\n"
|
||||||
"FIG driver spec:\n"
|
"FIG driver spec:\n"
|
||||||
" fig [-t template.fig] [var=value ...]\n"
|
" fig [-t template.fig] [var=value ...]\n"
|
||||||
@ -75,7 +78,7 @@ void usage(const char *name)
|
|||||||
" diff [-o output.pdf] [-s scale] [file.lib ...] file.sch\n"
|
" diff [-o output.pdf] [-s scale] [file.lib ...] file.sch\n"
|
||||||
"\n"
|
"\n"
|
||||||
" see PNG\n"
|
" see PNG\n"
|
||||||
, name, (int) strlen(name) + 1, "", name);
|
, name, (int) strlen(name) + 1, "", name, name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +90,7 @@ int main(int argc, char **argv)
|
|||||||
struct file sch_file;
|
struct file sch_file;
|
||||||
bool recurse = 0;
|
bool recurse = 0;
|
||||||
const char *cat = NULL;
|
const char *cat = NULL;
|
||||||
|
const char *history = NULL;
|
||||||
char c;
|
char c;
|
||||||
int arg, dashdash;
|
int arg, dashdash;
|
||||||
bool have_dashdash = 0;
|
bool have_dashdash = 0;
|
||||||
@ -102,7 +106,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((c = getopt(dashdash, argv, "rvC:")) != EOF)
|
while ((c = getopt(dashdash, argv, "rvC:H:")) != EOF)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'r':
|
case 'r':
|
||||||
recurse = 1;
|
recurse = 1;
|
||||||
@ -113,6 +117,9 @@ int main(int argc, char **argv)
|
|||||||
case 'C':
|
case 'C':
|
||||||
cat = optarg;
|
cat = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'H':
|
||||||
|
history = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(*argv);
|
usage(*argv);
|
||||||
}
|
}
|
||||||
@ -128,6 +135,14 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (history) {
|
||||||
|
struct hist *h;
|
||||||
|
|
||||||
|
h = vcs_git_hist(history);
|
||||||
|
dump_hist(h);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (dashdash - optind < 1)
|
if (dashdash - optind < 1)
|
||||||
usage(*argv);
|
usage(*argv);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user