Signed-off-by: Felipe Contreras <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html