From: Felipe Contreras Date: Thu, 29 Aug 2013 18:09:04 GMT Subject: [PATCH 2/2] stage: add edit command Message-ID: <1377799744-5201-3-git-send-email-felipe.contreras@gmail.com> In-Reply-To: <1377799744-5201-1-git-send-email-felipe.contreras@gmail.com> Signed-off-by: Felipe Contreras --- Documentation/git-stage.txt | 5 +++ builtin/stage.c | 74 ++++++++++++++++++++++++++++++++++ contrib/completion/git-completion.bash | 4 +- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/Documentation/git-stage.txt b/Documentation/git-stage.txt index 318bf45..3e52a66 100644 --- a/Documentation/git-stage.txt +++ b/Documentation/git-stage.txt @@ -15,6 +15,7 @@ SYNOPSIS 'git stage diff' [options] [] [--] [...] 'git stage rm' [options] [--] [...] 'git stage apply' [options] [--] [...] +'git stage edit' DESCRIPTION ----------- @@ -45,6 +46,10 @@ Remove files from the staging area only. See linkgit:git-rm[1] --staged. Apply a patch to the staging area. See linkgit:git-rm[1] --staged. +'edit':: + +Manually edit the staging area (as a diff). + SEE ALSO -------- linkgit:git-add[1] diff --git a/builtin/stage.c b/builtin/stage.c index 3023d17..d3c58d5 100644 --- a/builtin/stage.c +++ b/builtin/stage.c @@ -6,6 +6,9 @@ #include "builtin.h" #include "parse-options.h" +#include "diff.h" +#include "diffcore.h" +#include "revision.h" static const char *const stage_usage[] = { N_("git stage [options] [--] ..."), @@ -16,6 +19,74 @@ static const char *const stage_usage[] = { NULL }; +static int do_reset(const char *prefix) +{ + const char *argv[] = { "reset", "--quiet", NULL }; + return cmd_reset(2, argv, prefix); +} + +static int do_apply(const char *file, const char *prefix) +{ + const char *argv[] = { "apply", "--recount", "--cached", file, NULL }; + return cmd_apply(4, argv, prefix); +} + +static int edit(int argc, const char **argv, const char *prefix) +{ + char *file = git_pathdup("STAGE_EDIT.patch"); + int out; + struct rev_info rev; + int ret = 0; + struct stat st; + + read_cache(); + + init_revisions(&rev, prefix); + rev.diffopt.context = 7; + + argc = setup_revisions(argc, argv, &rev, NULL); + add_head_to_pending(&rev); + if (!rev.pending.nr) { + struct tree *tree; + tree = lookup_tree(EMPTY_TREE_SHA1_BIN); + add_pending_object(&rev, &tree->object, "HEAD"); + } + + rev.diffopt.output_format = DIFF_FORMAT_PATCH; + rev.diffopt.use_color = 0; + DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES); + + out = open(file, O_CREAT | O_WRONLY, 0666); + if (out < 0) + die(_("Could not open '%s' for writing."), file); + rev.diffopt.file = xfdopen(out, "w"); + rev.diffopt.close_file = 1; + + if (run_diff_index(&rev, 1)) + die(_("Could not write patch")); + if (launch_editor(file, NULL, NULL)) + exit(1); + + if (stat(file, &st)) + die_errno(_("Could not stat '%s'"), file); + + ret = do_reset(prefix); + if (ret) + goto leave; + + if (!st.st_size) + goto leave; + + ret = do_apply(file, prefix); + if (ret) + goto leave; + +leave: + unlink(file); + free(file); + return ret; +} + int cmd_stage(int argc, const char **argv, const char *prefix) { struct option options[] = { OPT_END() }; @@ -46,6 +117,9 @@ int cmd_stage(int argc, const char **argv, const char *prefix) return cmd_apply(argc, argv, prefix); } + if (!strcmp(argv[1], "edit")) { + return edit(argc - 1, argv + 1, prefix); + } } return cmd_add(argc, argv, prefix); diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 8cf26e2..2b81e78 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1693,7 +1693,7 @@ _git_stage () { __git_has_doubledash && return - local subcommands="add reset diff rm apply" + local subcommands="add reset diff rm apply edit" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" @@ -1711,6 +1711,8 @@ _git_stage () _git_rm;; apply) _git_apply;; + edit) + ;; *) _git_add; esac -- 1.8.4-fc