summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Tan <pyokagan@gmail.com>2015-08-04 21:51:24 +0800
committerJunio C Hamano <gitster@pobox.com>2015-08-04 22:02:11 -0700
commit73c2779f421fe1eaead6f1c07a0e134a9c17d6db (patch)
treed64784376e10ce1a71eec802d261a96b707a62c4
parent260eec292736388831958637eccdcf1a8f00e14d (diff)
downloadgit-73c2779f421fe1eaead6f1c07a0e134a9c17d6db.tar.gz
builtin-am: implement skeletal builtin am
For the purpose of rewriting git-am.sh into a C builtin, implement a skeletal builtin/am.c that redirects to $GIT_EXEC_PATH/git-am if the environment variable _GIT_USE_BUILTIN_AM is not defined. Since in the Makefile git-am.sh takes precedence over builtin/am.c, $GIT_EXEC_PATH/git-am will contain the shell script git-am.sh, and thus this allows us to fall back on the functional git-am.sh when running the test suite for tests that depend on a working git-am implementation. Since git-am.sh cannot handle any environment modifications by setup_git_directory(), "am" is declared with no setup flags in git.c. On the other hand, to re-implement git-am.sh in builtin/am.c, we need to run all the git dir and work tree setup logic that git.c typically does for us. As such, we work around this temporarily by copying the logic in git.c's run_builtin(), which is roughly: prefix = setup_git_directory(); trace_repo_setup(prefix); setup_work_tree(); This redirection should be removed when all the features of git-am.sh have been re-implemented in builtin/am.c. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Paul Tan <pyokagan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Makefile1
-rw-r--r--builtin.h1
-rw-r--r--builtin/am.c29
-rw-r--r--git.c6
4 files changed, 37 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 7efedbe834..da451f8bca 100644
--- a/Makefile
+++ b/Makefile
@@ -813,6 +813,7 @@ LIB_OBJS += xdiff-interface.o
LIB_OBJS += zlib.o
BUILTIN_OBJS += builtin/add.o
+BUILTIN_OBJS += builtin/am.o
BUILTIN_OBJS += builtin/annotate.o
BUILTIN_OBJS += builtin/apply.o
BUILTIN_OBJS += builtin/archive.o
diff --git a/builtin.h b/builtin.h
index 839483de6e..79aaf0afe8 100644
--- a/builtin.h
+++ b/builtin.h
@@ -30,6 +30,7 @@ extern int textconv_object(const char *path, unsigned mode, const unsigned char
extern int is_builtin(const char *s);
extern int cmd_add(int argc, const char **argv, const char *prefix);
+extern int cmd_am(int argc, const char **argv, const char *prefix);
extern int cmd_annotate(int argc, const char **argv, const char *prefix);
extern int cmd_apply(int argc, const char **argv, const char *prefix);
extern int cmd_archive(int argc, const char **argv, const char *prefix);
diff --git a/builtin/am.c b/builtin/am.c
new file mode 100644
index 0000000000..fd32caf107
--- /dev/null
+++ b/builtin/am.c
@@ -0,0 +1,29 @@
+/*
+ * Builtin "git am"
+ *
+ * Based on git-am.sh by Junio C Hamano.
+ */
+#include "cache.h"
+#include "builtin.h"
+#include "exec_cmd.h"
+
+int cmd_am(int argc, const char **argv, const char *prefix)
+{
+
+ /*
+ * NEEDSWORK: Once all the features of git-am.sh have been
+ * re-implemented in builtin/am.c, this preamble can be removed.
+ */
+ if (!getenv("_GIT_USE_BUILTIN_AM")) {
+ const char *path = mkpath("%s/git-am", git_exec_path());
+
+ if (sane_execvp(path, (char **)argv) < 0)
+ die_errno("could not exec %s", path);
+ } else {
+ prefix = setup_git_directory();
+ trace_repo_setup(prefix);
+ setup_work_tree();
+ }
+
+ return 0;
+}
diff --git a/git.c b/git.c
index 55c327c7b3..38d9ad531e 100644
--- a/git.c
+++ b/git.c
@@ -370,6 +370,12 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
static struct cmd_struct commands[] = {
{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
+ /*
+ * NEEDSWORK: Once the redirection to git-am.sh in builtin/am.c has
+ * been removed, this entry should be changed to
+ * RUN_SETUP | NEED_WORK_TREE
+ */
+ { "am", cmd_am },
{ "annotate", cmd_annotate, RUN_SETUP },
{ "apply", cmd_apply, RUN_SETUP_GENTLY },
{ "archive", cmd_archive },