Skip to content

Commit

Permalink
Add support for SHA-256 repositories
Browse files Browse the repository at this point in the history
Use variable extensions.objectformat to determine the length of the hash
id in the current repository.
  • Loading branch information
koutcher committed Nov 2, 2023
1 parent e543cfe commit fc1a0cb
Show file tree
Hide file tree
Showing 20 changed files with 53 additions and 27 deletions.
2 changes: 2 additions & 0 deletions doc/manual.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ following variables.
|%(repo:is-inside-work-tree)
|Whether Tig is running inside a work tree,
either `true` or `false`.
|%(repo:hash_len) |The hash algorithm used for the repository, e.g. `sha1`
or `sha256`.
|=============================================================================

Example user-defined commands:
Expand Down
2 changes: 1 addition & 1 deletion include/tig/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "tig/util.h"

struct commit {
char id[SIZEOF_REV]; /* SHA1 ID. */
char id[SIZEOF_REV]; /* Hash ID. */
const struct ident *author; /* Author of the commit. */
struct time time; /* Date from the author ident. */
struct graph_canvas graph; /* Ancestry chain graphics. */
Expand Down
6 changes: 3 additions & 3 deletions include/tig/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ bool parse_chunk_header(struct chunk_header *header, const char *line);
bool parse_chunk_lineno(unsigned long *lineno, const char *chunk, int marker);

struct blame_commit {
char id[SIZEOF_REV]; /* SHA1 ID. */
char id[SIZEOF_REV]; /* Hash ID. */
char title[128]; /* First line of the commit message. */
const struct ident *author; /* Author of the commit. */
struct time time; /* Date from the author ident. */
const char *filename; /* Name of file. */
char parent_id[SIZEOF_REV]; /* Parent/previous SHA1 ID. */
char parent_id[SIZEOF_REV]; /* Parent/previous hash ID. */
const char *parent_filename; /* Parent/previous name of file. */
};

struct blame_header {
char id[SIZEOF_REV]; /* SHA1 ID. */
char id[SIZEOF_REV]; /* Hash ID. */
size_t orig_lineno;
size_t lineno;
size_t group;
Expand Down
4 changes: 2 additions & 2 deletions include/tig/refdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ struct argv_env;
struct ref {
struct ref *next;
enum reference_type type;
char id[SIZEOF_REV]; /* Commit SHA1 ID */
char id[SIZEOF_REV]; /* Commit hash ID */
unsigned int valid:1; /* Is the ref still valid? */
char name[1]; /* Ref name; tag or head names are shortened. */
};

#define is_initial_commit() (!get_ref_head())
#define is_head_commit(rev) (!strcmp((rev), "HEAD") || (get_ref_head() && !strncmp(rev, get_ref_head()->id, SIZEOF_REV - 1)))
#define is_head_commit(rev) (!strcmp((rev), "HEAD") || (get_ref_head() && !strncmp(rev, get_ref_head()->id, repo.hash_len)))
#define ref_is_tag(ref) ((ref)->type == REFERENCE_TAG || (ref)->type == REFERENCE_LOCAL_TAG)
#define ref_is_remote(ref) ((ref)->type == REFERENCE_REMOTE || (ref)->type == REFERENCE_TRACKED_REMOTE)

Expand Down
2 changes: 2 additions & 0 deletions include/tig/repo.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@

#include "tig/tig.h"

typedef int repo_hash_len;
typedef char repo_ref[SIZEOF_REF];
typedef char repo_rev[SIZEOF_REV];
typedef char repo_str[SIZEOF_STR];

#define REPO_INFO(_) \
_(repo_hash_len, hash_len) \
_(repo_ref, head) \
_(repo_rev, head_id) \
_(repo_ref, remote) \
Expand Down
4 changes: 2 additions & 2 deletions include/tig/tig.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@

#define SIZEOF_STR 1024 /* Default string size. */
#define SIZEOF_MED_STR 8192 /* Medium string size. */
#define SIZEOF_REF 256 /* Size of symbolic or SHA1 ID. */
#define SIZEOF_REV 41 /* Holds a SHA-1 and an ending NUL. */
#define SIZEOF_REF 256 /* Size of symbolic or hash ID. */
#define SIZEOF_REV 65 /* Holds a SHA-1 or SHA-256 and an ending NUL. */

/* This color name can be used to refer to the default term colors. */
#define COLOR_DEFAULT (-1)
Expand Down
8 changes: 8 additions & 0 deletions src/argv.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,14 @@ bool_formatter(struct format_context *format, struct format_var *var)
return string_format_from(format->buf, &format->bufpos, "%s", value ? "true" : "false");
}

static bool
repo_hash_len_formatter(struct format_context *format, struct format_var *var)
{
int value = *(int *)var->value_ref;

return string_format_from(format->buf, &format->bufpos, "%s", value == 64 ? "sha256" : "sha1");
}

static bool
repo_str_formatter(struct format_context *format, struct format_var *var)
{
Expand Down
6 changes: 3 additions & 3 deletions src/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
*/

struct blame_history_state {
char id[SIZEOF_REV]; /* SHA1 ID. */
char id[SIZEOF_REV]; /* Hash ID. */
const char *filename; /* Name of file. */
};

Expand Down Expand Up @@ -187,15 +187,15 @@ get_blame_commit(struct view *view, const char *id)
if (!blame->commit)
continue;

if (!strncmp(blame->commit->id, id, SIZEOF_REV - 1))
if (!strncmp(blame->commit->id, id, repo.hash_len))
return blame->commit;
}

{
struct blame_commit *commit = calloc(1, sizeof(*commit));

if (commit)
string_ncopy(commit->id, id, SIZEOF_REV);
string_ncopy(commit->id, id, repo.hash_len + 1);
return commit;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "tig/graph.h"
#include "tig/draw.h"
#include "tig/options.h"
#include "tig/repo.h"
#include "compat/hashtab.h"

static const enum line_type palette_colors[] = {
Expand Down Expand Up @@ -267,7 +268,7 @@ draw_id(struct view *view, struct view_column *column, const char *id)
return false;

if (column->opt.id.color && id) {
hashval_t color = iterative_hash(id, SIZEOF_REV - 1, 0);
hashval_t color = iterative_hash(id, repo.hash_len, 0);

type = palette_colors[color % ARRAY_SIZE(palette_colors)];
}
Expand Down
2 changes: 1 addition & 1 deletion src/graph-v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct graph_symbol {

struct graph_column {
struct graph_symbol symbol;
char id[SIZEOF_REV]; /* Parent SHA1 ID. */
char id[SIZEOF_REV]; /* Parent hash ID. */
};

struct graph_row {
Expand Down
2 changes: 1 addition & 1 deletion src/graph-v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct graph_symbol {

struct graph_column {
struct graph_symbol symbol;
const char *id; /* Parent SHA1 ID. */
const char *id; /* Parent hash ID. */
};

struct graph_row {
Expand Down
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ main_add_commit(struct view *view, enum line_type type, struct commit *template,
view_column_info_update(view, line);

if ((opt_start_on_head && is_head_commit(commit->id)) ||
(view->env->goto_id[0] && !strncmp(view->env->goto_id, commit->id, SIZEOF_REV - 1)))
(view->env->goto_id[0] && !strncmp(view->env->goto_id, commit->id, repo.hash_len)))
select_view_line(view, line->lineno + 1);

return commit;
Expand Down
3 changes: 3 additions & 0 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,9 @@ read_repo_config_option(char *name, size_t namelen, char *value, size_t valuelen
else if (!strcmp(name, "core.abbrev"))
parse_int(&opt_id_width, value, 0, SIZEOF_REV - 1);

else if (!strcmp(name, "extensions.objectformat"))
repo.hash_len = !strcmp(value, "sha256") ? 64 : 40;

else if (!strcmp(name, "diff.noprefix"))
parse_bool(&opt_diff_noprefix, value);

Expand Down
11 changes: 6 additions & 5 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "tig/tig.h"
#include "tig/parse.h"
#include "tig/map.h"
#include "tig/repo.h"

size_t
parse_size(const char *text)
Expand Down Expand Up @@ -109,12 +110,12 @@ parse_number(const char **posref, size_t *number)
bool
parse_blame_header(struct blame_header *header, const char *text)
{
const char *pos = text + SIZEOF_REV - 2;
const char *pos = text + repo.hash_len - 1;

if (strlen(text) <= SIZEOF_REV || pos[1] != ' ')
if (strlen(text) < repo.hash_len || pos[1] != ' ')
return false;

string_ncopy(header->id, text, SIZEOF_REV);
string_copy_rev(header->id, text);

if (!parse_number(&pos, &header->orig_lineno) ||
!parse_number(&pos, &header->lineno))
Expand Down Expand Up @@ -163,10 +164,10 @@ parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *lin
string_ncopy(commit->title, line, strlen(line));

} else if (match_blame_header("previous ", &line)) {
if (strlen(line) <= SIZEOF_REV)
if (strlen(line) < repo.hash_len)
return false;
string_copy_rev(commit->parent_id, line);
line += SIZEOF_REV;
line += repo.hash_len + 1;
commit->parent_filename = get_path(line);
if (!commit->parent_filename)
return true;
Expand Down
4 changes: 2 additions & 2 deletions src/refdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref
}

/* If we are reloading or it's an annotated tag, replace the
* previous SHA1 with the resolved commit id; relies on the fact
* previous hash with the resolved commit id; relies on the fact
* git-ls-remote lists the commit id of an annotated tag right
* before the commit id it points to. */
if (type == REFERENCE_REPLACE) {
Expand Down Expand Up @@ -269,7 +269,7 @@ add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref

ref->valid = true;
ref->type = type;
string_ncopy_do(ref->id, SIZEOF_REV, id, idlen);
string_ncopy_do(ref->id, repo.hash_len + 1, id, idlen);

if (type == REFERENCE_HEAD) {
if (!refs_head ||
Expand Down
4 changes: 3 additions & 1 deletion src/repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ read_repo_info(char *name, size_t namelen, char *value, size_t valuelen, void *d
* this special case by looking at the emitted value. If it looks
* like a commit ID and there's no cdup path assume that no value
* was emitted. */
if (!*repo.cdup && namelen == 40 && iscommit(name))
if (!*repo.cdup && namelen == repo.hash_len && iscommit(name))
return read_repo_info(name, namelen, value, valuelen, data);

string_ncopy(repo.prefix, name, namelen);
Expand Down Expand Up @@ -102,6 +102,8 @@ load_repo_info(void)
};

memset(&repo, 0, sizeof(repo));
/* defaults to SHA-1 as older Git versions don't have extensions.objectformat */
repo.hash_len = 40;
return reload_repo_info(rev_parse_argv);
}

Expand Down
7 changes: 4 additions & 3 deletions src/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include "tig/tig.h"
#include "tig/repo.h"
#include "tig/string.h"
#include "compat/utf8proc.h"

Expand Down Expand Up @@ -42,7 +43,7 @@ iscommit(const char *str)
return false;
}

return 7 <= pos && pos < SIZEOF_REV;
return 7 <= pos && pos <= repo.hash_len;
}

int
Expand Down Expand Up @@ -72,11 +73,11 @@ string_copy_rev(char *dst, const char *src)
if (!*src)
return;

for (srclen = 0; srclen < SIZEOF_REV; srclen++)
for (srclen = 0; srclen <= repo.hash_len; srclen++)
if (!src[srclen] || isspace((unsigned char)src[srclen]))
break;

string_ncopy_do(dst, SIZEOF_REV, src, srclen);
string_ncopy_do(dst, repo.hash_len + 1, src, srclen);
}

void
Expand Down
2 changes: 1 addition & 1 deletion src/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ push_tree_stack_entry(struct view *view, const char *name, struct position *posi
*/

#define SIZEOF_TREE_ATTR \
STRING_SIZE("100644 blob f931e1d229c3e185caad4449bf5b66ed72462657\t")
STRING_SIZE("100644 blob ") + repo.hash_len + 1

#define SIZEOF_TREE_MODE \
STRING_SIZE("100644 ")
Expand Down
3 changes: 3 additions & 0 deletions test/tools/test-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "tig/util.h"
#include "tig/io.h"
#include "tig/graph.h"
#include "tig/repo.h"

#define USAGE \
"test-graph [--ascii]\n" \
Expand All @@ -23,6 +24,8 @@
" # git log --pretty=raw --parents | ./test-graph\n" \
" # git log --pretty=raw --parents | ./test-graph --ascii"

struct repo_info repo = {40};

struct commit {
char id[SIZEOF_REV];
struct graph_canvas canvas;
Expand Down
3 changes: 3 additions & 0 deletions tools/doc-gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include "tig/tig.h"
#include "tig/request.h"
#include "tig/util.h"
#include "tig/repo.h"

struct repo_info repo = {40};

struct doc_action_iterator {
bool end_group;
Expand Down

0 comments on commit fc1a0cb

Please sign in to comment.