From: Johannes Schindelin <johannes.schindelin@gmx.de>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
Eric Sunshine <sunshine@sunshineco.com>
Subject: [PATCH v2 0/4] Teach `git fsck` a new option: `--name-objects`
Date: Sun, 17 Jul 2016 12:59:38 +0200 (CEST) [thread overview]
Message-ID: <cover.1468752290.git.johannes.schindelin@gmx.de> (raw)
In-Reply-To: <cover.1468510191.git.johannes.schindelin@gmx.de>
When using experimental features (such as worktrees), it is quite
possible to end up with a repository that is a little bit corrupted. In
this developer's case, the auto gc run during interactive rebases in
worktrees completely messed up the reflogs.
The symptoms are broken links between commits/trees/blobs.
Trying to work around such problems can be a real challenge: while
several tools will report when objects are missing, all of them simply
state the SHA-1. This is not useful when the user has to kiss the
offending reflog good-bye, but does not even know which one.
This patch series introduces a new option to `git fsck`: --name-objects.
With this option, the fsck command will report not only the SHA-1 of
missing objects, but also a name by which this object is supposed to be
reachable.
Example output:
...
broken link from tree b5eb6ff... (refs/stash@{<date>}~37:)
to blob ec5cf80...
Relative to v1, a tyop was fixed, Junio's suggestions about an early
return from {get,put}_object_name() and about avoiding parsing of
objects were addressed, and I found a couple more places in fsck.c that
could benefit from object names.
Johannes Schindelin (4):
fsck: refactor how to describe objects
fsck_walk(): optionally name objects on the go
fsck: give the error function a chance to see the fsck_options
fsck: optionally show more helpful info for broken links
Documentation/git-fsck.txt | 9 +++-
builtin/fsck.c | 80 ++++++++++++++++++++++++--------
fsck.c | 113 +++++++++++++++++++++++++++++++++++++++++----
fsck.h | 7 ++-
t/t1450-fsck.sh | 22 +++++++++
5 files changed, 200 insertions(+), 31 deletions(-)
Published-As: https://github.com/dscho/git/releases/tag/fsck-name-objects-v2
Interdiff vs v1:
diff --git a/builtin/fsck.c b/builtin/fsck.c
index e2173b6..49680e9 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -93,7 +93,8 @@ static int objerror(struct object *obj, const char *err)
return -1;
}
-static int fsck_error_func(struct object *obj, int type, const char *message)
+static int fsck_error_func(struct fsck_options *o,
+ struct object *obj, int type, const char *message)
{
objreport(obj, (type == FSCK_WARN) ? "warning" : "error", message);
return (type == FSCK_WARN) ? 0 : 1;
@@ -598,7 +599,7 @@ static struct option fsck_opts[] = {
OPT_BOOL(0, "lost-found", &write_lost_and_found,
N_("write dangling objects in .git/lost-found")),
OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
- OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for rechable objects")),
+ OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for reachable objects")),
OPT_END(),
};
diff --git a/fsck.c b/fsck.c
index fe6a28a..c9cf3de 100644
--- a/fsck.c
+++ b/fsck.c
@@ -291,7 +291,7 @@ static int report(struct fsck_options *options, struct object *object,
va_start(ap, fmt);
strbuf_vaddf(&sb, fmt, ap);
- result = options->error_func(object, msg_type, sb.buf);
+ result = options->error_func(options, object, msg_type, sb.buf);
strbuf_release(&sb);
va_end(ap);
@@ -300,17 +300,21 @@ static int report(struct fsck_options *options, struct object *object,
static char *get_object_name(struct fsck_options *options, struct object *obj)
{
- return options->object_names ?
- lookup_decoration(options->object_names, obj) : NULL;
+ if (!options->object_names)
+ return NULL;
+ return lookup_decoration(options->object_names, obj);
}
static void put_object_name(struct fsck_options *options, struct object *obj,
const char *fmt, ...)
{
va_list ap;
- char *existing = lookup_decoration(options->object_names, obj);
struct strbuf buf = STRBUF_INIT;
+ char *existing;
+ if (!options->object_names)
+ return;
+ existing = lookup_decoration(options->object_names, obj);
if (existing)
return;
va_start(ap, fmt);
@@ -319,6 +323,19 @@ static void put_object_name(struct fsck_options *options, struct object *obj,
va_end(ap);
}
+static const char *describe_object(struct fsck_options *o, struct object *obj)
+{
+ static struct strbuf buf = STRBUF_INIT;
+ char *name;
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, oid_to_hex(&obj->oid));
+ if (o->object_names && (name = lookup_decoration(o->object_names, obj)))
+ strbuf_addf(&buf, " (%s)", name);
+
+ return buf.buf;
+}
+
static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *options)
{
struct tree_desc desc;
@@ -332,26 +349,29 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
name = get_object_name(options, &tree->object);
init_tree_desc(&desc, tree->buffer, tree->size);
while (tree_entry(&desc, &entry)) {
+ struct object *obj;
int result;
- if (name) {
- struct object *obj = parse_object(entry.oid->hash);
-
- if (obj)
- put_object_name(options, obj, "%s%s%s", name,
- entry.path,
- S_ISDIR(entry.mode) ? "/" : "");
- }
-
if (S_ISGITLINK(entry.mode))
continue;
- if (S_ISDIR(entry.mode))
- result = options->walk(&lookup_tree(entry.oid->hash)->object, OBJ_TREE, data, options);
- else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode))
- result = options->walk(&lookup_blob(entry.oid->hash)->object, OBJ_BLOB, data, options);
+
+ if (S_ISDIR(entry.mode)) {
+ obj = &lookup_tree(entry.oid->hash)->object;
+ if (name)
+ put_object_name(options, obj, "%s%s/", name,
+ entry.path);
+ result = options->walk(obj, OBJ_TREE, data, options);
+ }
+ else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) {
+ obj = &lookup_blob(entry.oid->hash)->object;
+ if (name)
+ put_object_name(options, obj, "%s%s", name,
+ entry.path);
+ result = options->walk(obj, OBJ_BLOB, data, options);
+ }
else {
result = error("in tree %s: entry %s has bad mode %.6o",
- oid_to_hex(&tree->object.oid), entry.path, entry.mode);
+ describe_object(options, &tree->object), entry.path, entry.mode);
}
if (result < 0)
return result;
@@ -447,7 +467,7 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
case OBJ_TAG:
return fsck_walk_tag((struct tag *)obj, data, options);
default:
- error("Unknown object type for %s", oid_to_hex(&obj->oid));
+ error("Unknown object type for %s", describe_object(options, obj));
return -1;
}
}
@@ -890,12 +910,13 @@ int fsck_object(struct object *obj, void *data, unsigned long size,
obj->type);
}
-int fsck_error_function(struct object *obj, int msg_type, const char *message)
+int fsck_error_function(struct fsck_options *o,
+ struct object *obj, int msg_type, const char *message)
{
if (msg_type == FSCK_WARN) {
- warning("object %s: %s", oid_to_hex(&obj->oid), message);
+ warning("object %s: %s", describe_object(o, obj), message);
return 0;
}
- error("object %s: %s", oid_to_hex(&obj->oid), message);
+ error("object %s: %s", describe_object(o, obj), message);
return 1;
}
diff --git a/fsck.h b/fsck.h
index 26c0d41..1891c18 100644
--- a/fsck.h
+++ b/fsck.h
@@ -23,9 +23,11 @@ int is_valid_msg_type(const char *msg_id, const char *msg_type);
typedef int (*fsck_walk_func)(struct object *obj, int type, void *data, struct fsck_options *options);
/* callback for fsck_object, type is FSCK_ERROR or FSCK_WARN */
-typedef int (*fsck_error)(struct object *obj, int type, const char *message);
+typedef int (*fsck_error)(struct fsck_options *o,
+ struct object *obj, int type, const char *message);
-int fsck_error_function(struct object *obj, int type, const char *message);
+int fsck_error_function(struct fsck_options *o,
+ struct object *obj, int type, const char *message);
struct fsck_options {
fsck_walk_func walk;
--
2.9.0.281.g286a8d9
base-commit: 29493589e97a2de0c4c1c314f61ccafaee3b5caf
next prev parent reply other threads:[~2016-07-17 11:00 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-14 15:30 [PATCH 0/3] Teach `git fsck` a new option: `--name-objects` Johannes Schindelin
2016-07-14 15:30 ` [PATCH 1/3] fsck: refactor how to describe objects Johannes Schindelin
2016-07-14 16:33 ` Junio C Hamano
2016-07-14 15:30 ` [PATCH 2/3] fsck_walk(): optionally name objects on the go Johannes Schindelin
2016-07-14 17:03 ` Junio C Hamano
2016-07-17 8:44 ` Johannes Schindelin
2016-07-14 15:30 ` [PATCH 3/3] fsck: optionally show more helpful info for broken links Johannes Schindelin
2016-07-15 6:20 ` Eric Sunshine
2016-07-17 8:22 ` Johannes Schindelin
2016-07-14 16:32 ` [PATCH 0/3] Teach `git fsck` a new option: `--name-objects` Junio C Hamano
2016-07-17 10:59 ` Johannes Schindelin [this message]
2016-07-17 10:59 ` [PATCH v2 1/4] fsck: refactor how to describe objects Johannes Schindelin
2016-07-17 10:59 ` [PATCH v2 2/4] fsck_walk(): optionally name objects on the go Johannes Schindelin
2016-07-17 10:59 ` [PATCH v2 3/4] fsck: give the error function a chance to see the fsck_options Johannes Schindelin
2016-07-17 11:00 ` [PATCH v2 4/4] fsck: optionally show more helpful info for broken links Johannes Schindelin
2016-07-18 18:42 ` [PATCH v2 0/4] Teach `git fsck` a new option: `--name-objects` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1468752290.git.johannes.schindelin@gmx.de \
--to=johannes.schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).