Merge branch 'jk/replace-edit-raw'
Teach "git replace --edit" mode a "--raw" option to allow editing the bare-metal representation data of objects. * jk/replace-edit-raw: replace: add a --raw mode for --edit
This commit is contained in:
commit
5418212191
@ -73,6 +73,14 @@ OPTIONS
|
|||||||
newly created object. See linkgit:git-var[1] for details about
|
newly created object. See linkgit:git-var[1] for details about
|
||||||
how the editor will be chosen.
|
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>::
|
-l <pattern>::
|
||||||
--list <pattern>::
|
--list <pattern>::
|
||||||
List replace refs for objects that match the given pattern (or
|
List replace refs for objects that match the given pattern (or
|
||||||
|
@ -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",
|
* Write the contents of the object named by "sha1" to the file "filename".
|
||||||
* pretty-printed for human editing based on its type.
|
* 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 };
|
struct child_process cmd = { NULL };
|
||||||
int fd;
|
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, "--no-replace-objects");
|
||||||
argv_array_push(&cmd.args, "cat-file");
|
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));
|
argv_array_push(&cmd.args, sha1_to_hex(sha1));
|
||||||
cmd.git_cmd = 1;
|
cmd.git_cmd = 1;
|
||||||
cmd.out = fd;
|
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.
|
* The sha1 of the written object is returned via sha1.
|
||||||
*/
|
*/
|
||||||
static void import_object(unsigned char *sha1, enum object_type type,
|
static void import_object(unsigned char *sha1, enum object_type type,
|
||||||
const char *filename)
|
int raw, const char *filename)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -225,7 +230,7 @@ static void import_object(unsigned char *sha1, enum object_type type,
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
die_errno("unable to open %s for reading", filename);
|
die_errno("unable to open %s for reading", filename);
|
||||||
|
|
||||||
if (type == OBJ_TREE) {
|
if (!raw && type == OBJ_TREE) {
|
||||||
const char *argv[] = { "mktree", NULL };
|
const char *argv[] = { "mktree", NULL };
|
||||||
struct child_process cmd = { argv };
|
struct child_process cmd = { argv };
|
||||||
struct strbuf result = STRBUF_INIT;
|
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");
|
char *tmpfile = git_pathdup("REPLACE_EDITOBJ");
|
||||||
enum object_type type;
|
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);
|
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)
|
if (launch_editor(tmpfile, NULL, NULL) < 0)
|
||||||
die("editing object file failed");
|
die("editing object file failed");
|
||||||
import_object(new, type, tmpfile);
|
import_object(new, type, raw, tmpfile);
|
||||||
|
|
||||||
free(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 cmd_replace(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int force = 0;
|
int force = 0;
|
||||||
|
int raw = 0;
|
||||||
const char *format = NULL;
|
const char *format = NULL;
|
||||||
enum {
|
enum {
|
||||||
MODE_UNSPECIFIED = 0,
|
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('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
|
||||||
OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
|
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('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_STRING(0, "format", &format, N_("format"), N_("use this format")),
|
||||||
OPT_END()
|
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",
|
usage_msg_opt("-f only makes sense when writing a replacement",
|
||||||
git_replace_usage, options);
|
git_replace_usage, options);
|
||||||
|
|
||||||
|
if (raw && cmdmode != MODE_EDIT)
|
||||||
|
usage_msg_opt("--raw only makes sense with --edit",
|
||||||
|
git_replace_usage, options);
|
||||||
|
|
||||||
switch (cmdmode) {
|
switch (cmdmode) {
|
||||||
case MODE_DELETE:
|
case MODE_DELETE:
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
@ -346,7 +357,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
|
|||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
usage_msg_opt("-e needs exactly one argument",
|
usage_msg_opt("-e needs exactly one argument",
|
||||||
git_replace_usage, options);
|
git_replace_usage, options);
|
||||||
return edit_and_replace(argv[0], force);
|
return edit_and_replace(argv[0], force, raw);
|
||||||
|
|
||||||
case MODE_LIST:
|
case MODE_LIST:
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user