Signed-off-by: Felipe Contreras <felipe.contreras@xxxxxxxxx> --- 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 5b42b29..13a01c8 100644 --- a/Documentation/git-stage.txt +++ b/Documentation/git-stage.txt @@ -15,6 +15,7 @@ SYNOPSIS 'git stage diff' [options] [<commit>] [--] [<paths>...] 'git stage rm' [options] [--] [<paths>...] 'git stage apply' [options] [--] [<paths>...] +'git stage edit' DESCRIPTION ----------- @@ -46,6 +47,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 7c4d442..f537c1d 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] [--] <paths>..."), @@ -17,6 +20,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() }; @@ -47,6 +118,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 0521d52..2ec7b1a 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1707,7 +1707,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" @@ -1725,6 +1725,8 @@ _git_stage () _git_rm;; apply) _git_apply;; + edit) + ;; *) _git_add; esac -- 1.9.2+fc1.2.gfbaae8c -- 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