Re: [PATCH v4 1/4] rebase: start implementing it as a builtin

2018-07-22 Thread Duy Nguyen
On Sun, Jul 8, 2018 at 8:03 PM Pratik Karki  wrote:
> +int cmd_rebase(int argc, const char **argv, const char *prefix)
> +{
> +   /*
> +* NEEDSWORK: Once the builtin rebase has been tested enough
> +* and git-legacy-rebase.sh is retired to contrib/, this preamble
> +* can be removed.
> +*/
> +
> +   if (!use_builtin_rebase()) {
> +   const char *path = mkpath("%s/git-legacy-rebase",
> + git_exec_path());
> +
> +   if (sane_execvp(path, (char **)argv) < 0)
> +   die_errno("could not exec %s", path);

Please wrap all user visible strings in thi series in _().

> +   else
> +   die("sane_execvp() returned???");

or if it's definitely a bug in the code, go with BUG()
-- 
Duy


Re: [PATCH v4 1/4] rebase: start implementing it as a builtin

2018-07-09 Thread Pratik Karki
Hi,

On Mon, Jul 9, 2018 at 2:21 PM Eric Sunshine  wrote:
>
> On Mon, Jul 9, 2018 at 3:59 AM Andrei Rybak  wrote:
> > On 2018-07-08 20:01, Pratik Karki wrote:
> > > +static int use_builtin_rebase(void)
> > > +{
> > > + struct child_process cp = CHILD_PROCESS_INIT;
> > > + struct strbuf out = STRBUF_INIT;
> > > + int ret;
> > > +
> > > + argv_array_pushl(,
> > > +  "config", "--bool", "rebase.usebuiltin", NULL);
> > > + cp.git_cmd = 1;
> > > + if (capture_command(, , 6))
> > > + return 0;
> >
> > Does strbuf out leak on return here?
>
> Good catch. This _is_ a potential leak. Here is an excerpt from the
> documentation of pipe_command(), which is called by capture_command():
>
> Any output collected in the buffers is kept even if the
> command returns a non-zero exit.
>
> So, yes, this needs a strbuf_release() before returning.

Hmm. This seems to be a problem. Thanks for reviewing.


Re: [PATCH v4 1/4] rebase: start implementing it as a builtin

2018-07-09 Thread Eric Sunshine
On Mon, Jul 9, 2018 at 3:59 AM Andrei Rybak  wrote:
> On 2018-07-08 20:01, Pratik Karki wrote:
> > +static int use_builtin_rebase(void)
> > +{
> > + struct child_process cp = CHILD_PROCESS_INIT;
> > + struct strbuf out = STRBUF_INIT;
> > + int ret;
> > +
> > + argv_array_pushl(,
> > +  "config", "--bool", "rebase.usebuiltin", NULL);
> > + cp.git_cmd = 1;
> > + if (capture_command(, , 6))
> > + return 0;
>
> Does strbuf out leak on return here?

Good catch. This _is_ a potential leak. Here is an excerpt from the
documentation of pipe_command(), which is called by capture_command():

Any output collected in the buffers is kept even if the
command returns a non-zero exit.

So, yes, this needs a strbuf_release() before returning.

> > + strbuf_trim();
> > + ret = !strcmp("true", out.buf);
> > + strbuf_release();
> > + return ret;
> > +}


Re: [PATCH v4 1/4] rebase: start implementing it as a builtin

2018-07-09 Thread Andrei Rybak
On 2018-07-08 20:01, Pratik Karki wrote:
> +
> +static int use_builtin_rebase(void)
> +{
> + struct child_process cp = CHILD_PROCESS_INIT;
> + struct strbuf out = STRBUF_INIT;
> + int ret;
> +
> + argv_array_pushl(,
> +  "config", "--bool", "rebase.usebuiltin", NULL);
> + cp.git_cmd = 1;
> + if (capture_command(, , 6))
> + return 0;

Does strbuf out leak on return here?

> +
> + strbuf_trim();
> + ret = !strcmp("true", out.buf);
> + strbuf_release();
> + return ret;
> +}




[PATCH v4 1/4] rebase: start implementing it as a builtin

2018-07-08 Thread Pratik Karki
This commit imitates the strategy that was used to convert the
difftool to a builtin. We start by renaming the shell script
`git-rebase.sh` to `git-legacy-rebase.sh` and introduce a
`builtin/rebase.c` that simply executes the shell script version,
unless the config setting `rebase.useBuiltin` is set to `true`.

The motivation behind this is to rewrite all the functionality of the
shell script version in the aforementioned `rebase.c`, one by one and
be able to conveniently test new features by configuring
`rebase.useBuiltin`.

In the original difftool conversion, if sane_execvp() that attempts to
run the legacy scripted version returned with non-negative status, the
command silently exited without doing anything with success, but
sane_execvp() should not retun with non-negative status in the first
place, so we use die() to notice such an abnormal case.

We intentionally avoid reading the config directly to avoid
messing up the GIT_* environment variables when we need to fall back to
exec()ing the shell script. The test of builtin rebase can be done by
`git -c rebase.useBuiltin=true rebase ...`

Signed-off-by: Pratik Karki 
---
 .gitignore|  1 +
 Makefile  |  3 +-
 builtin.h |  1 +
 builtin/rebase.c  | 56 +++
 git-rebase.sh => git-legacy-rebase.sh |  0
 git.c |  6 +++
 6 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 builtin/rebase.c
 rename git-rebase.sh => git-legacy-rebase.sh (100%)

diff --git a/.gitignore b/.gitignore
index 3284a1e9b1..ec23959014 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,6 +78,7 @@
 /git-init-db
 /git-interpret-trailers
 /git-instaweb
+/git-legacy-rebase
 /git-log
 /git-ls-files
 /git-ls-remote
diff --git a/Makefile b/Makefile
index 0cb6590f24..e88fe2e5fb 100644
--- a/Makefile
+++ b/Makefile
@@ -609,7 +609,7 @@ SCRIPT_SH += git-merge-one-file.sh
 SCRIPT_SH += git-merge-resolve.sh
 SCRIPT_SH += git-mergetool.sh
 SCRIPT_SH += git-quiltimport.sh
-SCRIPT_SH += git-rebase.sh
+SCRIPT_SH += git-legacy-rebase.sh
 SCRIPT_SH += git-remote-testgit.sh
 SCRIPT_SH += git-request-pull.sh
 SCRIPT_SH += git-stash.sh
@@ -1059,6 +1059,7 @@ BUILTIN_OBJS += builtin/prune.o
 BUILTIN_OBJS += builtin/pull.o
 BUILTIN_OBJS += builtin/push.o
 BUILTIN_OBJS += builtin/read-tree.o
+BUILTIN_OBJS += builtin/rebase.o
 BUILTIN_OBJS += builtin/rebase--helper.o
 BUILTIN_OBJS += builtin/receive-pack.o
 BUILTIN_OBJS += builtin/reflog.o
diff --git a/builtin.h b/builtin.h
index 0362f1ce25..44651a447f 100644
--- a/builtin.h
+++ b/builtin.h
@@ -202,6 +202,7 @@ extern int cmd_prune_packed(int argc, const char **argv, 
const char *prefix);
 extern int cmd_pull(int argc, const char **argv, const char *prefix);
 extern int cmd_push(int argc, const char **argv, const char *prefix);
 extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_rebase(int argc, const char **argv, const char *prefix);
 extern int cmd_rebase__helper(int argc, const char **argv, const char *prefix);
 extern int cmd_receive_pack(int argc, const char **argv, const char *prefix);
 extern int cmd_reflog(int argc, const char **argv, const char *prefix);
diff --git a/builtin/rebase.c b/builtin/rebase.c
new file mode 100644
index 00..fab7fca37e
--- /dev/null
+++ b/builtin/rebase.c
@@ -0,0 +1,56 @@
+/*
+ * "git rebase" builtin command
+ *
+ * Copyright (c) 2018 Pratik Karki
+ */
+
+#include "builtin.h"
+#include "run-command.h"
+#include "exec-cmd.h"
+#include "argv-array.h"
+#include "dir.h"
+
+static int use_builtin_rebase(void)
+{
+   struct child_process cp = CHILD_PROCESS_INIT;
+   struct strbuf out = STRBUF_INIT;
+   int ret;
+
+   argv_array_pushl(,
+"config", "--bool", "rebase.usebuiltin", NULL);
+   cp.git_cmd = 1;
+   if (capture_command(, , 6))
+   return 0;
+
+   strbuf_trim();
+   ret = !strcmp("true", out.buf);
+   strbuf_release();
+   return ret;
+}
+
+int cmd_rebase(int argc, const char **argv, const char *prefix)
+{
+   /*
+* NEEDSWORK: Once the builtin rebase has been tested enough
+* and git-legacy-rebase.sh is retired to contrib/, this preamble
+* can be removed.
+*/
+
+   if (!use_builtin_rebase()) {
+   const char *path = mkpath("%s/git-legacy-rebase",
+ git_exec_path());
+
+   if (sane_execvp(path, (char **)argv) < 0)
+   die_errno("could not exec %s", path);
+   else
+   die("sane_execvp() returned???");
+   }
+
+   if (argc != 2)
+   die("Usage: %s ", argv[0]);
+   prefix = setup_git_directory();
+   trace_repo_setup(prefix);
+   setup_work_tree();
+
+   die("TODO");
+}
diff --git a/git-rebase.sh b/git-legacy-rebase.sh
similarity index 100%
rename from