On Tue, Jun 24, 2014 at 5:46 AM, Jeff King <peff@xxxxxxxx> wrote: > One of the purposes of "git replace --edit" is to help a > user repair objects which are malformed or corrupted. > Usually we pretty-print trees with "ls-tree", which is much > easier to work with than the raw binary data. However, some > forms of corruption break the tree-walker, in which case our > pretty-printing fails, rendering "--edit" useless for the > user. > > This patch introduces a "--raw" option, which lets you edit > the binary data in these instances. Is there a possibility that any of the other git-replace modes will grow a need for "raw"? If not, would it make sense to make this specific to "edit" as --edit=raw? > Signed-off-by: Jeff King <peff@xxxxxxxx> > --- > Documentation/git-replace.txt | 8 ++++++++ > builtin/replace.c | 31 +++++++++++++++++++++---------- > 2 files changed, 29 insertions(+), 10 deletions(-) > > diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt > index 61461b9..089dcac 100644 > --- a/Documentation/git-replace.txt > +++ b/Documentation/git-replace.txt > @@ -73,6 +73,14 @@ OPTIONS > newly created object. See linkgit:git-var[1] for details about > how the editor will be chosen. > > +--raw:: > + When editing, provide the raw object contents rather than > + pretty-printed ones. Currently this only affects trees, which > + will be shown in their binary form. This is harder to work with, > + but can help when repairing a tree that is so corrupted it > + cannot be pretty-printed. Note that you may need to configure > + your editor to cleanly read and write binary data. > + > -l <pattern>:: > --list <pattern>:: > List replace refs for objects that match the given pattern (or > diff --git a/builtin/replace.c b/builtin/replace.c > index 2584170..d1ea2c2 100644 > --- a/builtin/replace.c > +++ b/builtin/replace.c > @@ -188,10 +188,12 @@ static int replace_object(const char *object_ref, const char *replace_ref, int f > } > > /* > - * Write the contents of the object named by "sha1" to the file "filename", > - * pretty-printed for human editing based on its type. > + * Write the contents of the object named by "sha1" to the file "filename". > + * If "raw" is true, then the object's raw contents are printed according to > + * "type". Otherwise, we pretty-print the contents for human editing. > */ > -static void export_object(const unsigned char *sha1, const char *filename) > +static void export_object(const unsigned char *sha1, enum object_type type, > + int raw, const char *filename) > { > struct child_process cmd = { NULL }; > int fd; > @@ -202,7 +204,10 @@ static void export_object(const unsigned char *sha1, const char *filename) > > argv_array_push(&cmd.args, "--no-replace-objects"); > argv_array_push(&cmd.args, "cat-file"); > - argv_array_push(&cmd.args, "-p"); > + if (raw) > + argv_array_push(&cmd.args, typename(type)); > + else > + argv_array_push(&cmd.args, "-p"); > argv_array_push(&cmd.args, sha1_to_hex(sha1)); > cmd.git_cmd = 1; > cmd.out = fd; > @@ -217,7 +222,7 @@ static void export_object(const unsigned char *sha1, const char *filename) > * The sha1 of the written object is returned via sha1. > */ > static void import_object(unsigned char *sha1, enum object_type type, > - const char *filename) > + int raw, const char *filename) > { > int fd; > > @@ -225,7 +230,7 @@ static void import_object(unsigned char *sha1, enum object_type type, > if (fd < 0) > die_errno("unable to open %s for reading", filename); > > - if (type == OBJ_TREE) { > + if (!raw && type == OBJ_TREE) { > const char *argv[] = { "mktree", NULL }; > struct child_process cmd = { argv }; > struct strbuf result = STRBUF_INIT; > @@ -265,7 +270,7 @@ static void import_object(unsigned char *sha1, enum object_type type, > */ > } > > -static int edit_and_replace(const char *object_ref, int force) > +static int edit_and_replace(const char *object_ref, int force, int raw) > { > char *tmpfile = git_pathdup("REPLACE_EDITOBJ"); > enum object_type type; > @@ -281,10 +286,10 @@ static int edit_and_replace(const char *object_ref, int force) > > check_ref_valid(old, prev, ref, sizeof(ref), force); > > - export_object(old, tmpfile); > + export_object(old, type, raw, tmpfile); > if (launch_editor(tmpfile, NULL, NULL) < 0) > die("editing object file failed"); > - import_object(new, type, tmpfile); > + import_object(new, type, raw, tmpfile); > > free(tmpfile); > > @@ -297,6 +302,7 @@ static int edit_and_replace(const char *object_ref, int force) > int cmd_replace(int argc, const char **argv, const char *prefix) > { > int force = 0; > + int raw = 0; > const char *format = NULL; > enum { > MODE_UNSPECIFIED = 0, > @@ -310,6 +316,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix) > OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE), > OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT), > OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")), > + OPT_BOOL(0, "raw", &raw, N_("do not pretty-print contents for --edit")), > OPT_STRING(0, "format", &format, N_("format"), N_("use this format")), > OPT_END() > }; > @@ -329,6 +336,10 @@ int cmd_replace(int argc, const char **argv, const char *prefix) > usage_msg_opt("-f only makes sense when writing a replacement", > git_replace_usage, options); > > + if (raw && cmdmode != MODE_EDIT) > + usage_msg_opt("--raw only makes sense with --edit", > + git_replace_usage, options); > + > switch (cmdmode) { > case MODE_DELETE: > if (argc < 1) > @@ -346,7 +357,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix) > if (argc != 1) > usage_msg_opt("-e needs exactly one argument", > git_replace_usage, options); > - return edit_and_replace(argv[0], force); > + return edit_and_replace(argv[0], force, raw); > > case MODE_LIST: > if (argc > 1) > -- > 2.0.0.566.gfe3e6b2 > -- > To unsubscribe from this list: send the line "unsubscribe git" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html