Re: [GSoC][PATCH v2 04/13] submodule: port submodule subcommand 'status' from shell to C

2017-07-29 Thread Christian Couder
On Sun, Jul 30, 2017 at 12:23 AM, Prathamesh Chavan  wrote:

> +static void print_status(struct status_cb *info, char state, const char 
> *path,
> +const struct object_id *oid, const char *displaypath)
> +{
> +   if (info->quiet)
> +   return;
> +
> +   printf("%c%s %s", state, oid_to_hex(oid), displaypath);
> +
> +

Spurious new line.

> +   if (state == ' ' || state == '+') {
> +   struct argv_array name_rev_args = ARGV_ARRAY_INIT;
> +
> +   argv_array_pushl(_rev_args, "print-name-rev",
> +path, oid_to_hex(oid), NULL);
> +   print_name_rev(name_rev_args.argc, name_rev_args.argv,
> +  info->prefix);
> +   } else {
> +   printf("\n");
> +   }
> +}

> +static void status_submodule(const struct cache_entry *list_item, void 
> *cb_data)
> +{
> +   struct status_cb *info = cb_data;
> +   char *displaypath;
> +   struct argv_array diff_files_args = ARGV_ARRAY_INIT;
> +
> +   if (!submodule_from_path(null_sha1, list_item->name))
> +   die(_("no submodule mapping found in .gitmodules for path 
> '%s'"),
> + list_item->name);
> +
> +   displaypath = get_submodule_displaypath(list_item->name, 
> info->prefix);
> +
> +   trace_printf("the value of flag is %d\n", list_item->ce_flags);

Debugging left over.

> +   if (list_item->ce_flags) {
> +   trace_printf("for U the value of flag is %d\n", 
> list_item->ce_flags);
> +   print_status(info, 'U', list_item->name,
> +_oid, displaypath);
> +   goto cleanup;
> +   }


Re: [GSoC][PATCH v2 08/13] submodule: port submodule subcommand 'summary' from shell to C

2017-07-29 Thread Christian Couder
On Sun, Jul 30, 2017 at 12:23 AM, Prathamesh Chavan  wrote:

> +static int module_summary(int argc, const char **argv, const char *prefix)
> +{
> +   struct summary_cb info = SUMMARY_CB_INIT;
> +   int cached = 0;
> +   char *diff_cmd = "diff-index";
> +   int for_status = 0;
> +   int quiet = 0;
> +   int files = 0;
> +   int summary_limits = -1;
> +   struct child_process cp_rev = CHILD_PROCESS_INIT;
> +   char *head;
> +   struct strbuf sb = STRBUF_INIT;
> +   int ret;
> +
> +   struct option module_summary_options[] = {
> +   OPT__QUIET(, N_("Suppress output for initializing a 
> submodule")),
> +   OPT_BOOL(0, "cached", , N_("Use the commit stored in 
> the index instead of the submodule HEAD")),
> +   OPT_BOOL(0, "files", , N_("To compares the commit in 
> the index with that in the submodule HEAD")),
> +   OPT_BOOL(0, "for-status", _status, N_("Skip submodules 
> with 'all' ignore_config value")),
> +   OPT_INTEGER('n', "summary-limits", _limits, N_("Limit 
> the summary size")),
> +   OPT_END()
> +   };
> +
> +   const char *const git_submodule_helper_usage[] = {
> +   N_("git submodule--helper summary [] [--] []"),
> +   NULL
> +   };
> +
> +   argc = parse_options(argc, argv, prefix, module_summary_options,
> +git_submodule_helper_usage, 0);
> +
> +   if (!summary_limits)
> +   return 0;
> +
> +   cp_rev.git_cmd = 1;
> +   argv_array_pushl(_rev.args, "rev-parse", "-q", "--verify",
> +argc ? argv[0] : "HEAD", NULL);
> +
> +   if (!capture_command(_rev, , 0)) {
> +   strbuf_strip_suffix(, "\n");
> +   if (argc) {
> +   argv++;
> +   argc--;
> +   }
> +   } else if (!argc || !strcmp(argv[0], "HEAD")) {
> +   /* before the first commit: compare with an empty tree */
> +   struct stat st;
> +   struct object_id oid;
> +   if (fstat(0, ) < 0 || index_fd(oid.hash, 0, , 2, 
> prefix, 3))
> +   die("Unable to add %s to database", oid.hash);
> +   strbuf_addstr(, oid_to_hex());
> +   if (argc) {
> +   argv++;
> +   argc--;
> +   }
> +   } else {
> +   strbuf_addstr(, "HEAD");
> +   }
> +
> +   head = strbuf_detach(, NULL);

I am not sure this "head" variable is really needed.

> +   if (files) {
> +   if (cached)
> +   die(_("The --cached option cannot be used with the 
> --files option"));
> +   diff_cmd = "diff-files";
> +
> +   free(head);
> +
> +   head = NULL;

If "head" isn't used, "strbuf_reset()" could be used instead.
If "head" is still needed, "FREE_AND_NULL(head)" could be used.

> +   }
> +
> +   info.argc = argc;
> +   info.argv = argv;
> +   info.prefix = prefix;
> +   info.cached = !!cached;
> +   info.for_status = !!for_status;
> +   info.quiet = quiet;
> +   info.files = files;
> +   info.summary_limits = summary_limits;
> +   info.diff_cmd = diff_cmd;
> +
> +   ret = compute_summary_module_list(head, );
> +   if (head)
> +   free(head);

"sb.buf" could be passed to compute_summary_module_list() instead of
"head". In this case that function should check that head is not an
empty string before using it.

If "head" is not used then strbuf_release() can be used to free any
memory sb still holds.
If "head" is still used, "if (head)" can be removed before
"free(head)" as free() already checks if its argument is NULL.

> +   return ret;
> +

Spurious new line.

> +}


[GSoC][PATCH v2 12/13] submodule foreach: document variable '$displaypath'

2017-07-29 Thread Prathamesh Chavan
It was observed that the variable '$displaypath' was accessible but
undocumented. Hence, document it.

Discussed-with: Ramsay Jones 
Signed-off-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:

* Spelling mistake in the commit message was corrected.

 Documentation/git-submodule.txt |  6 --
 t/t7407-submodule-foreach.sh| 22 +++---
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 8e7930ebc..0cca702cb 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -183,10 +183,12 @@ information too.
 
 foreach [--recursive] ::
Evaluates an arbitrary shell command in each checked out submodule.
-   The command has access to the variables $name, $sm_path, $sha1 and
-   $toplevel:
+   The command has access to the variables $name, $sm_path, $displaypath,
+   $sha1 and $toplevel:
$name is the name of the relevant submodule section in `.gitmodules`,
$sm_path is the path of the submodule as recorded in the superproject,
+   $displaypath contains the relative path from the current working
+   directory to the submodules root directory,
$sha1 is the commit as recorded in the superproject, and
$toplevel is the absolute path to its superproject, such that
$toplevel/$sm_path is the absolute path of the submodule.
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 0663622a4..6ad57e061 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -82,16 +82,16 @@ test_expect_success 'test basic "submodule foreach" usage' '
 
 cat >expect <../../actual
+   git submodule foreach "echo 
\$toplevel-\$name-\$sm_path-\$displaypath-\$sha1" >../../actual
) &&
test_i18ncmp expect actual
 '
@@ -206,25 +206,25 @@ submodulesha1=$(cd 
clone2/nested1/nested2/nested3/submodule && git rev-parse HEA
 
 cat >expect <../../actual
+   git submodule foreach --recursive "echo 
\$toplevel-\$name-\$sm_path-\$displaypath-\$sha1" >../../actual
) &&
test_i18ncmp expect actual
 '
-- 
2.13.0



[GSoC][PATCH v2 13/13] submodule: port submodule subcommand 'foreach' from shell to C

2017-07-29 Thread Prathamesh Chavan
This aims to make git-submodule foreach a builtin. This is the very
first step taken in this direction. Hence, 'foreach' is ported to
submodule--helper, and submodule--helper is called from git-submodule.sh.
The code is split up to have one function to obtain all the list of
submodules. This function acts as the front-end of git-submodule foreach
subcommand. It calls the function for_each_submodule_list, which basically
loops through the list and calls function fn, which in this case is
runcommand_in_submodule. This third function is a calling function that
takes care of running the command in that submodule, and recursively
perform the same when --recursive is flagged.

The first function module_foreach first parses the options present in
argv, and then with the help of module_list_compute, generates the list of
submodules present in the current working tree.

The second function for_each_submodule_list traverses through the
list, and calls function fn (which in case of submodule subcommand
foreach is runcommand_in_submodule) is called for each entry.

The third function runcommand_in_submodule, generates a submodule struct sub
for $name, value and then later prepends name=sub->name; and other
value assignment to the env argv_array structure of a child_process.
Also the  of submodule-foreach is push to args argv_array
structure and finally, using run_command the commands are executed
using a shell.

The third function also takes care of the recursive flag, by creating
a separate child_process structure and prepending "--super-prefix displaypath",
to the args argv_array structure. Other required arguments and the
input  of submodule-foreach is also appended to this argv_array.

Helped-by: Brandon Williams 
Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:

* Comment style is improved in the function runcommand_in_submodule()

* Comment in added about why the variable "path" was exposed via args
  argv_array instead of exposing it via the env_array.

* This patch exposes the various variables when argc == 1 only, just
  for maintaining a faithful porting. You can also find discussion about
  the same at [1].

[1]: 
https://public-inbox.org/git/came+mvusgafbn5j-_hv7qpas57hq4wgh+yz7xjmpuyqn1ga...@mail.gmail.com/

 builtin/submodule--helper.c | 136 
 git-submodule.sh|  39 +
 2 files changed, 137 insertions(+), 38 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d8bf16f1d..d5527aa93 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -772,6 +772,141 @@ static int module_name(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+struct cb_foreach {
+   int argc;
+   const char **argv;
+   const char *prefix;
+   unsigned int quiet: 1;
+   unsigned int recursive: 1;
+};
+#define CB_FOREACH_INIT { 0, NULL, NULL, 0, 0 }
+
+static void runcommand_in_submodule(const struct cache_entry *list_item,
+   void *cb_data)
+{
+   struct cb_foreach *info = cb_data;
+   const struct submodule *sub;
+   struct child_process cp = CHILD_PROCESS_INIT;
+   char *displaypath;
+
+   displaypath = get_submodule_displaypath(list_item->name, info->prefix);
+
+   sub = submodule_from_path(null_sha1, list_item->name);
+
+   if (!sub)
+   die(_("No url found for submodule path '%s' in .gitmodules"),
+ displaypath);
+
+   if (!is_submodule_populated_gently(list_item->name, NULL))
+   goto cleanup;
+
+   prepare_submodule_repo_env(_array);
+
+   /*
+* For the purpose of executing  in the submodule,
+* separate shell is used for the purpose of running the
+* child process.
+*/
+   cp.use_shell = 1;
+   cp.dir = list_item->name;
+
+   if (info->argc == 1) {
+   char *toplevel = xgetcwd();
+
+   argv_array_pushf(_array, "name=%s", sub->name);
+   argv_array_pushf(_array, "sm_path=%s", list_item->name);
+   argv_array_pushf(_array, "displaypath=%s", displaypath);
+   argv_array_pushf(_array, "sha1=%s",
+oid_to_hex(_item->oid));
+   argv_array_pushf(_array, "toplevel=%s", toplevel);
+
+   /*
+* Since the path variable was accessible from the script
+* before porting, it is also made available after porting.
+* The environment variable "PATH" has a very special purpose
+* on windows. And since environment variables are
+* case-insensitive in windows, it interferes with the
+* existing PATH variable. Hence, to avoid that, 

[GSoC][PATCH v2 08/13] submodule: port submodule subcommand 'summary' from shell to C

2017-07-29 Thread Prathamesh Chavan
The submodule subcommand 'summary' is ported in the process of
making git-submodule a builtin. The function cmd_summary() from
git-submodule.sh is ported to functions module_summary(),
compute_summary_module_list(), prepare_submodule_summary() and
print_submodule_summary().

The first function module_summary() parses the options of submodule
subcommand and also acts as the front-end of this subcommand.
After parsing them, it calls the compute_summary_module_list()

The functions compute_summary_module_list() runs the diff_cmd,
and generates the modules list, as required by the subcommand.
The generation of this module list is done by the using the
callback function submodule_summary_callback(), and stored in the
structure module_cb.

Once the module list is generated, prepare_submodule_summary()
further goes through the list and filters the list, for
eventually calling the print_submodule_summary() function.

Finally, the print_submodule_summary() takes care of generating
and printing the summary for each submodule.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:

* Firstly, about the function compute_summary_module_list().
  This function is created to generate the list of modules, for which
  we will generate the summary further. Since the list is actually
  generated using the git-diff-files or git-diff-index command, but for
  porting this, we required to create a function similar to the builtin
  functions of the above commands. But we can't directly call cmd_diff_files()
  and cmd_diff_index() since we don't have to display the output and instead
  need to store it. Hence, this function is introduced.

* Also, the module_cb_list *list is not freed since it is a non-heap object.
  Hence, free() can't be using on the non-heap objects.

* In the function prepare_submodule_summary(), as suggested
  'git_config_get_string_const' was used instead of instead of '_value'

* Some variables which weren't modified throughout the function-call were
  passed as const.

* The '!!' trick, which wasn't used in the last patch, is now used in this
  new version .

* the variables sha1_dst and sha1_src are removed from the function
  print_submodule_summary(), and instead the p->oid_src and p->oid_dst are
  used.

* The variable sm_git_dir is freed at the end of the function.

 builtin/submodule--helper.c | 433 
 git-submodule.sh| 182 +--
 2 files changed, 434 insertions(+), 181 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 038be7ee2..d8bf16f1d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -13,6 +13,9 @@
 #include "remote.h"
 #include "refs.h"
 #include "connect.h"
+#include "revision.h"
+#include "diffcore.h"
+#include "diff.h"
 
 typedef void (*submodule_list_func_t)(const struct cache_entry *list_item,
  void *cb_data);
@@ -769,6 +772,435 @@ static int module_name(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+struct module_cb {
+   unsigned int mod_src;
+   unsigned int mod_dst;
+   struct object_id oid_src;
+   struct object_id oid_dst;
+   char status;
+   const char *sm_path;
+};
+#define MODULE_CB_INIT { 0, 0, NULL, NULL, '\0', NULL }
+
+struct module_cb_list {
+   struct module_cb **entries;
+   int alloc, nr;
+};
+#define MODULE_CB_LIST_INIT { NULL, 0, 0 }
+
+struct summary_cb {
+   int argc;
+   const char **argv;
+   const char *prefix;
+   char *diff_cmd;
+   unsigned int cached: 1;
+   unsigned int for_status: 1;
+   unsigned int quiet: 1;
+   unsigned int files: 1;
+   int summary_limits;
+};
+#define SUMMARY_CB_INIT { 0, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
+
+static int verify_submodule_object_name(const char *sm_path, const char *sha1)
+{
+   struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
+
+   cp_rev_parse.git_cmd = 1;
+   cp_rev_parse.no_stdout = 1;
+   cp_rev_parse.dir = sm_path;
+   prepare_submodule_repo_env(_rev_parse.env_array);
+
+   argv_array_pushl(_rev_parse.args, "rev-parse", "-q",
+"--verify", NULL);
+   argv_array_pushf(_rev_parse.args, "%s^0", sha1);
+
+   if (run_command(_rev_parse))
+   return 1;
+
+   return 0;
+}
+
+static void print_submodule_summary(struct summary_cb *info,
+   struct module_cb *p)
+{
+   int missing_src = 0;
+   int missing_dst = 0;
+   char *displaypath;
+   const char *sha1_abbr_src;
+   const char *sha1_abbr_dst;
+   int errmsg = 0;
+   int total_commits = -1;
+   char *sm_git_dir = xstrfmt("%s/.git", p->sm_path);
+   int is_sm_git_dir = 0;
+
+   if (!info->cached 

[GSoC][PATCH v2 10/13] submodule foreach: document '$sm_path' instead of '$path'

2017-07-29 Thread Prathamesh Chavan
As using a variable '$path' may be harmful to users due to
capitalization issues, see 64394e3ae9 (git-submodule.sh: Don't
use $path variable in eval_gettext string, 2012-04-17). Adjust
the documentation to advocate for using $sm_path,  which contains
the same value. We still make the 'path' variable available and
document it as a deprecated synonym of 'sm_path'.

Discussed-with: Ramsay Jones 
Signed-off-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
This patch is same as its previous version.
Although here I'll like to add a point that we aim to slowly drop the support
of the variable 'path'.

 Documentation/git-submodule.txt | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index ff612001d..a23baef62 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -183,12 +183,14 @@ information too.
 
 foreach [--recursive] ::
Evaluates an arbitrary shell command in each checked out submodule.
-   The command has access to the variables $name, $path, $sha1 and
+   The command has access to the variables $name, $sm_path, $sha1 and
$toplevel:
$name is the name of the relevant submodule section in `.gitmodules`,
-   $path is the name of the submodule directory relative to the
-   superproject, $sha1 is the commit as recorded in the superproject,
-   and $toplevel is the absolute path to the top-level of the superproject.
+   $sm_path is the path of the submodule as recorded in the superproject,
+   $sha1 is the commit as recorded in the superproject, and
+   $toplevel is the absolute path to the top-level of the superproject.
+   Note that to avoid conflicts with '$PATH' on Windows, the '$path'
+   variable is now a deprecated synonym of '$sm_path' variable.
Any submodules defined in the superproject but not checked out are
ignored by this command. Unless given `--quiet`, foreach prints the name
of each submodule before evaluating the command.
-- 
2.13.0



[GSoC][PATCH v2 11/13] submodule foreach: clarify the '$toplevel' variable documentation

2017-07-29 Thread Prathamesh Chavan
It does not contain the topmost superproject as the author assumed,
but the direct superproject, such that $toplevel/$sm_path is the
actual absolute path of the submodule.

Discussed-with: Ramsay Jones 
Signed-off-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
 Documentation/git-submodule.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index a23baef62..8e7930ebc 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -188,7 +188,8 @@ foreach [--recursive] ::
$name is the name of the relevant submodule section in `.gitmodules`,
$sm_path is the path of the submodule as recorded in the superproject,
$sha1 is the commit as recorded in the superproject, and
-   $toplevel is the absolute path to the top-level of the superproject.
+   $toplevel is the absolute path to its superproject, such that
+   $toplevel/$sm_path is the absolute path of the submodule.
Note that to avoid conflicts with '$PATH' on Windows, the '$path'
variable is now a deprecated synonym of '$sm_path' variable.
Any submodules defined in the superproject but not checked out are
-- 
2.13.0



[GSoC][PATCH v2 09/13] submodule foreach: correct '$path' in nested submodules from a subdirectory

2017-07-29 Thread Prathamesh Chavan
When running 'git submodule foreach' from a subdirectory of your
repository, nested submodules get a bogus value for $sm_path:
For a submodule 'sub' that contains a nested submodule 'nested',
running 'git -C dir submodule foreach echo $path' would report
path='../nested' for the nested submodule. The first part '../' is
derived from the logic computing the relative path from $pwd to the
root of the superproject. The second part is the submodule path inside
the submodule. This value is of little use and is hard to document.

There are two different possible solutions that have more value:
(a) The path value is documented as the path from the toplevel of the
superproject to the mount point of the submodule.
In this case we would want to have path='sub/nested'.

(b) As Ramsay noticed the documented value is wrong. For the non-nested
case the path is equal to the relative path from $pwd to the
submodules working directory. When following this model,
the expected value would be path='../sub/nested'.

The behavior for (b) was introduced in 091a6eb0fe (submodule: drop the
top-level requirement, 2013-06-16) the intent for $path seemed to be
relative to $cwd to the submodule worktree, but that did not work for
nested submodules, as the intermittent submodules were not included in
the path.

If we were to fix the meaning of the $path using (a) such that "path"
is "the path from the toplevel of the superproject to the mount point
of the submodule", we would break any existing submodule user that runs
foreach from non-root of the superproject as the non-nested submodule
'../sub' would change its path to 'sub'.

If we would fix the meaning of the $path using (b), such that "path"
is "the relative path from $pwd to the submodule", then we would break
any user that uses nested submodules (even from the root directory) as
the 'nested' would become 'sub/nested'.

Both groups can be found in the wild.  The author has no data if one group
outweighs the other by large margin, and offending each one seems equally
bad at first.  However in the authors imagination it is better to go with
(a) as running from a sub directory sounds like it is carried out
by a human rather than by some automation task.  With a human on
the keyboard the feedback loop is short and the changed behavior can be
adapted to quickly unlike some automation that can break silently.

Discussed-with: Ramsay Jones 
Signed-off-by: Prathamesh Chavan 
Signed-off-by: Stefan Beller 
---
 git-submodule.sh |  1 -
 t/t7407-submodule-foreach.sh | 36 ++--
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index a427ddafd..493a64372 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -320,7 +320,6 @@ cmd_foreach()
prefix="$prefix$sm_path/"
sanitize_submodule_env
cd "$sm_path" &&
-   sm_path=$(git submodule--helper relative-path 
"$sm_path" "$wt_prefix") &&
# we make $path available to scripts ...
path=$sm_path &&
if test $# -eq 1
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 6ba5daf42..0663622a4 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -82,9 +82,9 @@ test_expect_success 'test basic "submodule foreach" usage' '
 
 cat >expect  expect <

[GSoC][PATCH v2 06/13] submodule: port submodule subcommand 'deinit' from shell to C

2017-07-29 Thread Prathamesh Chavan
The same mechanism is used even for porting this submodule
subcommand, as used in the ported subcommands till now.
The function cmd_deinit in split up after porting into three
functions: module_deinit(), for_each_submodule_list() and
deinit_submodule().

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:
* In the function deinit_submodule, since the test is_git_directory()
  adds an additional condition, instead is_directory() is used to check
  if "sm_path/.git" is a directory.

* since it was possible in the previous path that the value st.st_mode passed
  to the function mkdir contained a garbage value, instead we intrduce a
  mode_t variable mode, initially containing a default mode value '0777'.
  This is what the default of mode is set in case, that the value is
  not set after the lstat call.

 builtin/submodule--helper.c | 144 
 git-submodule.sh|  55 +
 2 files changed, 145 insertions(+), 54 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 877215567..038be7ee2 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -916,6 +916,149 @@ static int module_sync(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+struct deinit_cb {
+   const char *prefix;
+   unsigned int quiet: 1;
+   unsigned int force: 1;
+   unsigned int all: 1;
+};
+#define DEINIT_CB_INIT { NULL, 0, 0, 0 }
+
+static void deinit_submodule(const struct cache_entry *list_item,
+void *cb_data)
+{
+   struct deinit_cb *info = cb_data;
+   const struct submodule *sub;
+   char *displaypath = NULL;
+   struct child_process cp_config = CHILD_PROCESS_INIT;
+   struct strbuf sb_config = STRBUF_INIT;
+   char *sub_git_dir = xstrfmt("%s/.git", list_item->name);
+   mode_t mode = 0777;
+
+   sub = submodule_from_path(null_sha1, list_item->name);
+
+   if (!sub || !sub->name)
+   goto cleanup;
+
+   displaypath = get_submodule_displaypath(list_item->name, info->prefix);
+
+   /* remove the submodule work tree (unless the user already did it) */
+   if (is_directory(list_item->name)) {
+   struct stat st;
+   /* protect submodules containing a .git directory */
+   if (is_directory(sub_git_dir))
+   die(_("Submodule work tree '%s' contains a .git "
+ "directory use 'rm -rf' if you really want "
+ "to remove it including all of its history"),
+ displaypath);
+
+   if (!info->force) {
+   struct child_process cp_rm = CHILD_PROCESS_INIT;
+   cp_rm.git_cmd = 1;
+   argv_array_pushl(_rm.args, "rm", "-qn",
+list_item->name, NULL);
+
+   if (run_command(_rm))
+   die(_("Submodule work tree '%s' contains local "
+ "modifications; use '-f' to discard 
them"),
+ displaypath);
+   }
+
+   if (!lstat(list_item->name, )) {
+   struct strbuf sb_rm = STRBUF_INIT;
+   const char *format;
+
+   strbuf_addstr(_rm, list_item->name);
+
+   if (!remove_dir_recursively(_rm, 0))
+   format = _("Cleared directory '%s'\n");
+   else
+   format = _("Could not remove submodule work 
tree '%s'\n");
+
+   if (!info->quiet)
+   printf(format, displaypath);
+
+   mode = st.st_mode;
+
+   strbuf_release(_rm);
+   }
+   }
+
+   if (mkdir(list_item->name, mode))
+   die(_("could not create empty submodule directory %s"),
+ displaypath);
+
+   cp_config.git_cmd = 1;
+   argv_array_pushl(_config.args, "config", "--get-regexp", NULL);
+   argv_array_pushf(_config.args, "submodule.%s\\.", sub->name);
+
+   /* remove the .git/config entries (unless the user already did it) */
+   if (!capture_command(_config, _config, 0) && sb_config.len) {
+   char *sub_key = xstrfmt("submodule.%s", sub->name);
+   /*
+* remove the whole section so we have a clean state when
+* the user later decides to init this submodule again
+*/
+   git_config_rename_section_in_file(NULL, sub_key, NULL);
+   if (!info->quiet)
+   printf(_("Submodule '%s' (%s) unregistered for 

[GSoC][PATCH v2 04/13] submodule: port submodule subcommand 'status' from shell to C

2017-07-29 Thread Prathamesh Chavan
This aims to make git-submodule 'status' a built-in. Hence, the function
cmd_status() is ported from shell to C. This is done by introducing
three functions: module_status(), submodule_status() and print_status().

The function module_status() acts as the front-end of the subcommand.
It parses subcommand's options and then calls the function
module_list_compute() for computing the list of submodules. Then
this functions calls for_each_submodule_list() looping through the
list obtained.

Then for_each_submodule_list() calls submodule_status() for each of the
submodule in its list. The function submodule_status() is responsible
for generating the status each submodule it is called for, and
then calls print_status().

Finally, the function print_status() handles the printing of submodule's
status.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:
* parameters passed to the function print_status() have been changed.
  Instead of passing char *sub_sha1, instead the object_id is being passed.

* Also, since the passed parameter displaypath's value isn't changed
  by the function, it is passed to the funcition as const char *displaypath
  instead of char *displaypath.

* the output type of the function handle_submodule_head_ref() is changed
  from strbuf to object_id, as we will use the object_id instead of the
  hex of sha1 being stored in a struct strbuf.

* diff_files_Args is cleared after using it by passing it as args in the
  function cmd_diff_files.

* In the function status_submodule(), for checking if a submodule has merge
  conflicts, the patch currently checks if the value of any of the ce_flags
  is non-zero. Currently, I think the we aren't interested in a partiular flag,
  but I'm not sure on this.

* The confusion with displaypath being passed as te super-prefix in many
  of the ported subcommands may be a result of the fact that the
  function generating the displaypath: get_submodule_displaypath()
  uses the super-prefix as simply a path concatenated with the current
  submodule name to denote our current location.
  Also, for generating any submodule's displaypath, it would be important to
  have ".." passed to the submodule, and currently it is possible only via the
  super-prefix.

 builtin/submodule--helper.c | 157 
 git-submodule.sh|  49 +-
 2 files changed, 158 insertions(+), 48 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 2cb72d68e..0bd969b7c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -561,6 +561,162 @@ static int module_init(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+struct status_cb {
+   const char *prefix;
+   unsigned int quiet: 1;
+   unsigned int recursive: 1;
+   unsigned int cached: 1;
+};
+#define STATUS_CB_INIT { NULL, 0, 0, 0 }
+
+static void print_status(struct status_cb *info, char state, const char *path,
+const struct object_id *oid, const char *displaypath)
+{
+   if (info->quiet)
+   return;
+
+   printf("%c%s %s", state, oid_to_hex(oid), displaypath);
+
+
+   if (state == ' ' || state == '+') {
+   struct argv_array name_rev_args = ARGV_ARRAY_INIT;
+
+   argv_array_pushl(_rev_args, "print-name-rev",
+path, oid_to_hex(oid), NULL);
+   print_name_rev(name_rev_args.argc, name_rev_args.argv,
+  info->prefix);
+   } else {
+   printf("\n");
+   }
+}
+
+static int handle_submodule_head_ref(const char *refname,
+const struct object_id *oid, int flags,
+void *cb_data)
+{
+   struct object_id *output = cb_data;
+   if (oid)
+   oidcpy(output, oid);
+
+   return 0;
+}
+
+static void status_submodule(const struct cache_entry *list_item, void 
*cb_data)
+{
+   struct status_cb *info = cb_data;
+   char *displaypath;
+   struct argv_array diff_files_args = ARGV_ARRAY_INIT;
+
+   if (!submodule_from_path(null_sha1, list_item->name))
+   die(_("no submodule mapping found in .gitmodules for path 
'%s'"),
+ list_item->name);
+
+   displaypath = get_submodule_displaypath(list_item->name, info->prefix);
+
+   trace_printf("the value of flag is %d\n", list_item->ce_flags);
+   if (list_item->ce_flags) {
+   trace_printf("for U the value of flag is %d\n", 
list_item->ce_flags);
+   print_status(info, 'U', list_item->name,
+_oid, displaypath);
+   goto cleanup;
+   }
+
+   if (!is_submodule_active(the_repository, list_item->name)) {
+   

[GSoC][PATCH v2 01/13] submodule--helper: introduce get_submodule_displaypath()

2017-07-29 Thread Prathamesh Chavan
Introduce function get_submodule_displaypath() to replace the code
occurring in submodule_init() for generating displaypath of the
submodule with a call to it.

This new function will also be used in other parts of the system
in later patches.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
 builtin/submodule--helper.c | 33 ++---
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 6abdad329..7af4de09b 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -220,6 +220,27 @@ static int resolve_relative_url_test(int argc, const char 
**argv, const char *pr
return 0;
 }
 
+static char *get_submodule_displaypath(const char *path, const char *prefix)
+{
+   const char *super_prefix = get_super_prefix();
+
+   if (prefix && super_prefix) {
+   BUG("cannot have prefix '%s' and superprefix '%s'",
+   prefix, super_prefix);
+   } else if (prefix) {
+   struct strbuf sb = STRBUF_INIT;
+   char *displaypath = xstrdup(relative_path(path, prefix, ));
+   strbuf_release();
+   return displaypath;
+   } else if (super_prefix) {
+   int len = strlen(super_prefix);
+   const char *format = is_dir_sep(super_prefix[len - 1]) ? "%s%s" 
: "%s/%s";
+   return xstrfmt(format, super_prefix, path);
+   } else {
+   return xstrdup(path);
+   }
+}
+
 struct module_list {
const struct cache_entry **entries;
int alloc, nr;
@@ -339,16 +360,7 @@ static void init_submodule(const char *path, const char 
*prefix, int quiet)
 
/* Only loads from .gitmodules, no overlay with .git/config */
gitmodules_config();
-
-   if (prefix && get_super_prefix())
-   die("BUG: cannot have prefix and superprefix");
-   else if (prefix)
-   displaypath = xstrdup(relative_path(path, prefix, ));
-   else if (get_super_prefix()) {
-   strbuf_addf(, "%s%s", get_super_prefix(), path);
-   displaypath = strbuf_detach(, NULL);
-   } else
-   displaypath = xstrdup(path);
+   displaypath = get_submodule_displaypath(path, prefix);
 
sub = submodule_from_path(null_sha1, path);
 
@@ -363,7 +375,6 @@ static void init_submodule(const char *path, const char 
*prefix, int quiet)
 * Set active flag for the submodule being initialized
 */
if (!is_submodule_active(the_repository, path)) {
-   strbuf_reset();
strbuf_addf(, "submodule.%s.active", sub->name);
git_config_set_gently(sb.buf, "true");
}
-- 
2.13.0



[GSoC][PATCH v2 02/13] submodule--helper: introduce for_each_submodule_list()

2017-07-29 Thread Prathamesh Chavan
Introduce function for_each_submodule_list() and
replace a loop in module_init() with a call to it.

The new function will also be used in other parts of the
system in later patches.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
 builtin/submodule--helper.c | 39 +--
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 7af4de09b..e41572f7a 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -14,6 +14,9 @@
 #include "refs.h"
 #include "connect.h"
 
+typedef void (*submodule_list_func_t)(const struct cache_entry *list_item,
+ void *cb_data);
+
 static char *get_default_remote(void)
 {
char *dest = NULL, *ret;
@@ -352,17 +355,30 @@ static int module_list(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
-static void init_submodule(const char *path, const char *prefix, int quiet)
+static void for_each_submodule_list(const struct module_list list,
+   submodule_list_func_t fn, void *cb_data)
 {
+   int i;
+   for (i = 0; i < list.nr; i++)
+   fn(list.entries[i], cb_data);
+}
+
+struct init_cb {
+   const char *prefix;
+   unsigned int quiet: 1;
+};
+#define INIT_CB_INIT { NULL, 0 }
+
+static void init_submodule(const struct cache_entry *list_item, void *cb_data)
+{
+   struct init_cb *info = cb_data;
const struct submodule *sub;
struct strbuf sb = STRBUF_INIT;
char *upd = NULL, *url = NULL, *displaypath;
 
-   /* Only loads from .gitmodules, no overlay with .git/config */
-   gitmodules_config();
-   displaypath = get_submodule_displaypath(path, prefix);
+   displaypath = get_submodule_displaypath(list_item->name, info->prefix);
 
-   sub = submodule_from_path(null_sha1, path);
+   sub = submodule_from_path(null_sha1, list_item->name);
 
if (!sub)
die(_("No url found for submodule path '%s' in .gitmodules"),
@@ -374,7 +390,7 @@ static void init_submodule(const char *path, const char 
*prefix, int quiet)
 *
 * Set active flag for the submodule being initialized
 */
-   if (!is_submodule_active(the_repository, path)) {
+   if (!is_submodule_active(the_repository, list_item->name)) {
strbuf_addf(, "submodule.%s.active", sub->name);
git_config_set_gently(sb.buf, "true");
}
@@ -416,7 +432,7 @@ static void init_submodule(const char *path, const char 
*prefix, int quiet)
if (git_config_set_gently(sb.buf, url))
die(_("Failed to register url for submodule path '%s'"),
displaypath);
-   if (!quiet)
+   if (!info->quiet)
fprintf(stderr,
_("Submodule '%s' (%s) registered for path 
'%s'\n"),
sub->name, url, displaypath);
@@ -445,10 +461,10 @@ static void init_submodule(const char *path, const char 
*prefix, int quiet)
 
 static int module_init(int argc, const char **argv, const char *prefix)
 {
+   struct init_cb info = INIT_CB_INIT;
struct pathspec pathspec;
struct module_list list = MODULE_LIST_INIT;
int quiet = 0;
-   int i;
 
struct option module_init_options[] = {
OPT__QUIET(, N_("Suppress output for initializing a 
submodule")),
@@ -473,8 +489,11 @@ static int module_init(int argc, const char **argv, const 
char *prefix)
if (!argc && git_config_get_value_multi("submodule.active"))
module_list_active();
 
-   for (i = 0; i < list.nr; i++)
-   init_submodule(list.entries[i]->name, prefix, quiet);
+   info.prefix = prefix;
+   info.quiet = !!quiet;
+
+   gitmodules_config();
+   for_each_submodule_list(list, init_submodule, );
 
return 0;
 }
-- 
2.13.0



[GSoC][PATCH v2 03/13] submodule: port set_name_rev() from shell to C

2017-07-29 Thread Prathamesh Chavan
Function set_name_rev() is ported from git-submodule to the
submodule--helper builtin. The function get_name_rev() generates the
value of the revision name as required, and the function
print_name_rev() handles the formating and printing of the obtained
revision name.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:
* The variable namerev from print_name_rev is now freed at the end of the
  function.

 builtin/submodule--helper.c | 64 +
 git-submodule.sh| 16 ++--
 2 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index e41572f7a..2cb72d68e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -244,6 +244,69 @@ static char *get_submodule_displaypath(const char *path, 
const char *prefix)
}
 }
 
+static char *get_name_rev(const char *sub_path, const char* object_id)
+{
+   struct strbuf sb = STRBUF_INIT;
+   const char ***d;
+
+   static const char *describe_bare[] = {
+   NULL
+   };
+
+   static const char *describe_tags[] = {
+   "--tags", NULL
+   };
+
+   static const char *describe_contains[] = {
+   "--contains", NULL
+   };
+
+   static const char *describe_all_always[] = {
+   "--all", "--always", NULL
+   };
+
+   static const char **describe_argv[] = {
+   describe_bare, describe_tags, describe_contains,
+   describe_all_always, NULL
+   };
+
+   for (d = describe_argv; *d; d++) {
+   struct child_process cp = CHILD_PROCESS_INIT;
+   prepare_submodule_repo_env(_array);
+   cp.dir = sub_path;
+   cp.git_cmd = 1;
+   cp.no_stderr = 1;
+
+   argv_array_push(, "describe");
+   argv_array_pushv(, *d);
+   argv_array_push(, object_id);
+
+   if (!capture_command(, , 0) && sb.len) {
+   strbuf_strip_suffix(, "\n");
+   return strbuf_detach(, NULL);
+   }
+
+   }
+
+   strbuf_release();
+   return NULL;
+}
+
+static int print_name_rev(int argc, const char **argv, const char *prefix)
+{
+   char *namerev;
+   if (argc != 3)
+   die("print-name-rev only accepts two arguments:  ");
+
+   namerev = get_name_rev(argv[1], argv[2]);
+   if (namerev && namerev[0])
+   printf(" (%s)", namerev);
+   printf("\n");
+
+   free(namerev);
+   return 0;
+}
+
 struct module_list {
const struct cache_entry **entries;
int alloc, nr;
@@ -1242,6 +1305,7 @@ static struct cmd_struct commands[] = {
{"relative-path", resolve_relative_path, 0},
{"resolve-relative-url", resolve_relative_url, 0},
{"resolve-relative-url-test", resolve_relative_url_test, 0},
+   {"print-name-rev", print_name_rev, 0},
{"init", module_init, SUPPORT_SUPER_PREFIX},
{"remote-branch", resolve_remote_submodule_branch, 0},
{"push-check", push_check, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index e131760ee..e988167e0 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -759,18 +759,6 @@ cmd_update()
}
 }
 
-set_name_rev () {
-   revname=$( (
-   sanitize_submodule_env
-   cd "$1" && {
-   git describe "$2" 2>/dev/null ||
-   git describe --tags "$2" 2>/dev/null ||
-   git describe --contains "$2" 2>/dev/null ||
-   git describe --all --always "$2"
-   }
-   ) )
-   test -z "$revname" || revname=" ($revname)"
-}
 #
 # Show commit summary for submodules in index or working tree
 #
@@ -1042,14 +1030,14 @@ cmd_status()
fi
if git diff-files --ignore-submodules=dirty --quiet -- 
"$sm_path"
then
-   set_name_rev "$sm_path" "$sha1"
+   revname=$(git submodule--helper print-name-rev 
"$sm_path" "$sha1")
say " $sha1 $displaypath$revname"
else
if test -z "$cached"
then
sha1=$(sanitize_submodule_env; cd "$sm_path" && 
git rev-parse --verify HEAD)
fi
-   set_name_rev "$sm_path" "$sha1"
+   revname=$(git submodule--helper print-name-rev 
"$sm_path" "$sha1")
say "+$sha1 $displaypath$revname"
fi
 
-- 
2.13.0



[GSoC][PATCH v2 00/13] Update: Week 10

2017-07-29 Thread Prathamesh Chavan
Thank you Brandon Williams  for reviewing the previous
patch series.
Also, I'm sorry for repling late to your reviews. The main reason was
to give sufficient time to prepare the next version of each patch as
suggested.
The changes made in each patch are enlisted in the patch itself.

Complete build report of this work is available at: [1]
Branch: week-10
Build #142

Also, I have push the work on github as well and can be checked out at: [2]

[1]: https://travis-ci.org/pratham-pc/git/builds
[2]: https://github.com/pratham-pc/git/commits/week-10

Prathamesh Chavan (13):
  submodule--helper: introduce get_submodule_displaypath()
  submodule--helper: introduce for_each_submodule_list()
  submodule: port set_name_rev() from shell to C
  submodule: port submodule subcommand 'status' from shell to C
  submodule: port submodule subcommand 'sync' from shell to C
  submodule: port submodule subcommand 'deinit' from shell to C
  diff: change scope of the function count_lines()
  submodule: port submodule subcommand 'summary' from shell to C
  submodule foreach: correct '$path' in nested submodules from a
subdirectory
  submodule foreach: document '$sm_path' instead of '$path'
  submodule foreach: clarify the '$toplevel' variable documentation
  submodule foreach: document variable '$displaypath'
  submodule: port submodule subcommand 'foreach' from shell to C

 Documentation/git-submodule.txt |   15 +-
 builtin/submodule--helper.c | 1186 ++-
 diff.c  |2 +-
 diff.h  |1 +
 git-submodule.sh|  394 +
 t/t7407-submodule-foreach.sh|   38 +-
 6 files changed, 1218 insertions(+), 418 deletions(-)

-- 
2.13.0



[GSoC][PATCH v2 07/13] diff: change scope of the function count_lines()

2017-07-29 Thread Prathamesh Chavan
Change the scope of function count_lines for allowing the function
to be reused in other parts of the code as well.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
 diff.c | 2 +-
 diff.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/diff.c b/diff.c
index 85e714f6c..03ed64f93 100644
--- a/diff.c
+++ b/diff.c
@@ -425,7 +425,7 @@ struct emit_callback {
struct strbuf *header;
 };
 
-static int count_lines(const char *data, int size)
+int count_lines(const char *data, int size)
 {
int count, ch, completely_empty = 1, nl_just_seen = 0;
count = 0;
diff --git a/diff.h b/diff.h
index 2d442e296..8522514e9 100644
--- a/diff.h
+++ b/diff.h
@@ -273,6 +273,7 @@ extern struct diff_filepair *diff_unmerge(struct 
diff_options *, const char *pat
 extern int parse_long_opt(const char *opt, const char **argv,
 const char **optarg);
 
+extern int count_lines(const char *data, int size);
 extern int git_diff_basic_config(const char *var, const char *value, void *cb);
 extern int git_diff_heuristic_config(const char *var, const char *value, void 
*cb);
 extern void init_diff_ui_defaults(void);
-- 
2.13.0



[GSoC][PATCH v2 05/13] submodule: port submodule subcommand 'sync' from shell to C

2017-07-29 Thread Prathamesh Chavan
Port the submodule subcommand 'sync' from shell to C using the same
mechanism as that used for porting submodule subcommand 'status'.
Hence, here the function cmd_sync() is ported from shell to C.
This is done by introducing three functions: module_sync(),
sync_submodule() and print_default_remote().

The function print_default_remote() is introduced for getting
the default remote as stdout.

Mentored-by: Christian Couder 
Mentored-by: Stefan Beller 
Signed-off-by: Prathamesh Chavan 
---
In this new version, the following changes have been made:
* There was no good reason for using puts in the function print_default_remote()
  Hence, in this patch, we instead use printf to do the same, as it is what
  is generally used throughout the codebase.

* As suggested, this patch ensures a more efficient use of variables, and
  removes most of the variables by reusing 'strbuf sb' at places required.

 builtin/submodule--helper.c | 182 
 git-submodule.sh|  56 +-
 2 files changed, 183 insertions(+), 55 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 0bd969b7c..877215567 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -44,6 +44,20 @@ static char *get_default_remote(void)
return ret;
 }
 
+static int print_default_remote(int argc, const char **argv, const char 
*prefix)
+{
+   const char *remote;
+
+   if (argc != 1)
+   die(_("submodule--helper print-default-remote takes no 
arguments"));
+
+   remote = get_default_remote();
+   if (remote)
+   printf("%s\n", remote);
+
+   return 0;
+}
+
 static int starts_with_dot_slash(const char *str)
 {
return str[0] == '.' && is_dir_sep(str[1]);
@@ -380,6 +394,25 @@ static void module_list_active(struct module_list *list)
*list = active_modules;
 }
 
+static char *get_up_path(const char *path)
+{
+   int i;
+   struct strbuf sb = STRBUF_INIT;
+
+   for (i = count_slashes(path); i; i--)
+   strbuf_addstr(, "../");
+
+   /*
+* Check if 'path' ends with slash or not
+* for having the same output for dir/sub_dir
+* and dir/sub_dir/
+*/
+   if (!is_dir_sep(path[strlen(path) - 1]))
+   strbuf_addstr(, "../");
+
+   return strbuf_detach(, NULL);
+}
+
 static int module_list(int argc, const char **argv, const char *prefix)
 {
int i;
@@ -736,6 +769,153 @@ static int module_name(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+struct sync_cb {
+   const char *prefix;
+   unsigned int quiet: 1;
+   unsigned int recursive: 1;
+};
+#define SYNC_CB_INIT { NULL, 0, 0 }
+
+static void sync_submodule(const struct cache_entry *list_item, void *cb_data)
+{
+   struct sync_cb *info = cb_data;
+   const struct submodule *sub;
+   char *remote_key;
+   char *sub_origin_url, *super_config_url, *displaypath;
+   struct strbuf sb = STRBUF_INIT;
+   struct child_process cp = CHILD_PROCESS_INIT;
+   char *sub_config_path = NULL;
+
+   if (!is_submodule_active(the_repository, list_item->name))
+   return;
+
+   sub = submodule_from_path(null_sha1, list_item->name);
+
+   if (sub && sub->url) {
+   if (starts_with_dot_dot_slash(sub->url) || 
starts_with_dot_slash(sub->url)) {
+   char *remote_url, *up_path;
+   char *remote = get_default_remote();
+   strbuf_addf(, "remote.%s.url", remote);
+
+   if (git_config_get_string(sb.buf, _url))
+   remote_url = xgetcwd();
+
+   up_path = get_up_path(list_item->name);
+   sub_origin_url = relative_url(remote_url, sub->url, 
up_path);
+   super_config_url = relative_url(remote_url, sub->url, 
NULL);
+
+   free(remote);
+   free(up_path);
+   free(remote_url);
+   } else {
+   sub_origin_url = xstrdup(sub->url);
+   super_config_url = xstrdup(sub->url);
+   }
+   } else {
+   sub_origin_url = "";
+   super_config_url = "";
+   }
+
+   displaypath = get_submodule_displaypath(list_item->name, info->prefix);
+
+   if (!info->quiet)
+   printf(_("Synchronizing submodule url for '%s'\n"),
+displaypath);
+
+   strbuf_reset();
+   strbuf_addf(, "submodule.%s.url", sub->name);
+   if (git_config_set_gently(sb.buf, super_config_url))
+   die(_("failed to register url for submodule path '%s'"),
+ displaypath);
+
+   if (!is_submodule_populated_gently(list_item->name, NULL))
+   goto cleanup;
+
+   

From Mrs Muna Hariri.

2017-07-29 Thread From.Mrs Muna Hariri
>From Mrs.Muna Hariri

Dearest One I am Mrs.Muna Hariri I am 51years Old Woman from  (Paris)
France, I married to Mr. Ali Hariri who worked with our  (Paris)
France Embassy here for ten years before he died in the year 2006. We
were married for Nine years without a child. And He died after a brief
illness that lasted for only Six days.

When my late husband was alive he deposited the sum of Three  Million
five hundred thousand United State Dollars.($3.5 million dollars))
left in one Of the Bank here, And My Doctor told me that I would not
last for the next four months do to my cancer problem. Having known my
condition (cancer of  lever and stroke) dear,I need a Good honest and
God's fearing person who can use This Funds for Charity works,
orphanages, widows and also build schools for less privilege that will
be named after my late husband if possible.

More details later

Thank and remain bless

I will be waiting to receive your email

Mrs .Muna Hariri.


GOOD DAY

2017-07-29 Thread Richard Water
Please Whoever this email meets i need your co-operation

and to introduce myself i am Mr Richard Water and i work with

an intermediary bank by name Exodus bank Group , i discovered

from my bank data assessment as the bank auditor general

that a deceased customer left in one of his accounts 580

million United States Dollars and no one is aware of this for

the past one year and 2 months . I am in search of

anyone who can allow me file in His/Her name as the

benefactor with 0.00 percent risk free after which we can

split the money 50/40 and then 10% goes to the lawyer in

charge . I await your response if interested .

Kind Regards
Richard Water
Auditor


Re: [PATCH 2/2] t6500: mark tests as SHA1 reliant

2017-07-29 Thread brian m. carlson
On Fri, Jul 28, 2017 at 03:14:49PM -0700, Junio C Hamano wrote:
> Stefan Beller  writes:
> 
> > The first test marked relies on hard coded sha1:
> >
> > # We need to create two object whose sha1s start with 17
> > # since this is what git gc counts.  As it happens, these
> > # two blobs will do so.
> > test_commit 263 &&
> > test_commit 410 &&
> >
> > The next two seem to rely on state from the first one, I did not
> > investigate.
> 
> I am moderately negative on this approach, if it is meant to suggest
> the final shape of our test suite patch 1/2 started.
> 
> This script may be a good example you can use to demonstrate a much
> better approach.  As the above comment in the test shows, we want to
> create two objects whose object names begin with "17", and running
> test_commit with 263 and 410 at this point in the test was a way to
> achieve that when Git uses SHA-1 as its hash.
> 
> When we use a hash different from SHA-1, the exact strings 263 and
> 410 may change, but we should be able to find two other strings that
> has the same property (i.e. they results in objects that share the
> prefix "17").  Perhaps a better way forward for this kind of test is
> to parameterize these hardcoded constants and make it easier to use
> different values without having to change the rest of the script
> when we switch the hash function?  So perhaps have something like
> 
>   case "$GIT_HASH_FUNCTION" in
>   SHA-1)  
>   TEST_17_1="263 410" ;;
>   CORRUPT-SHA-1)  
>   TEST_17_1="something else" ;;
> esac

One approach I had considered taking is having a helper of some sort
that wrapped a simple key/value store.  We could pass the wrapper the
SHA-1 value (or, if necessary, an arbitrary key) and have it return the
proper value based on the given hash function.

That does have the downsides that the values may not present in the
tests themselves, and that people adding new tests will of course need
to run the test suite twice.  But it does make the tests easier to read.

Opinions on the desirability of this approach are of course welcome.
-- 
brian m. carlson / brian with sandals: Houston, Texas, US
https://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: https://keybase.io/bk2204


signature.asc
Description: PGP signature


Re: [PATCH for NEXT v3 0/2] sub-process: refactor handshake to common function

2017-07-29 Thread Junio C Hamano
Jonathan Tan  writes:

> Thanks for all your comments.
>
> This is now built off "next" to include Lars's changes.

Developing on 'next' to ask for comments is OK, but try to minimize
the dependencies; otherwise you are setting yourself to be taken
hostage by many unrelated topics.

I did a merge of ls/filter-branch-delayed into v2.14-rc1 and then
applied these two on top (with one small style-fix) to see how bad
its dependencies are---I think that is the only topic you need that
is still in flight, so it does not look too bad.



Re: [PATCH/RFC] setup: update error message to be more meaningful

2017-07-29 Thread Junio C Hamano
Kaartic Sivaraam  writes:

> On Fri, 2017-07-28 at 20:53 -0700, Junio C Hamano wrote:
>> Kaartic Sivaraam  writes:
>> 
>> > Though the message seems to be most fitting one, I'm a little reluctant
>> > to use it as it "might" create a wrong picture on the minds of the user
>> > making them think this would be the case in other cases too, which we
>> > know is not true. For example,
>> > 
>> > 
>> > git log -p --full-diff master --stat
>> > 
>> > git commit -v Makefile --amend
>> 
>> These are accepted not by design but by accident.  
>> 
>> I do not think we even document that you are allowed to do these in
>> "log" and "commit" manual pages, and we should discourage them (I do
>> not even mind eventually removing these with the usual deprecation
>> dance, but I do not think it is worth the noise).
>> 
> That's interesting. In that case, I'll go with the suggested statement,
> happily!

It is not interesting at all.  It actually is disturbing that you
had the notion that these are "valid" command lines.

We perhaps need to somehow make sure new users won't be led to the
misunderstanding.  Improving our documentation is a good first step.
We might want to have a group of volunteers who actively monitor the
internets (e.g. stackoverflow and other places like that) and
correct people who spread the same misunderstanding when they do.




Re: [RFC PATCH 3/4] fsck: support referenced lazy objects

2017-07-29 Thread Junio C Hamano
Jonathan Tan  writes:

> Teach fsck to not treat missing objects indirectly pointed to by refs as
> an error when extensions.lazyobject is set.

I forgot to mention a potential flaw in this approach in my previous
message.

If you are a pure sightseer, then this is perfectly fine.  The
object store in your local Git client working in that mode is purely
a cache, lazily populated while browsing the object store backed by
the source of what lazy-object "hook" talks with.  As long as that
cache does not give us a corrupt object, we are OK, because missing
objects do not matter.

But once you start using the repository as more than a sightseer,
you will have objects that only exist in your local "cache" and are
not yet in that backing store behind the lazy-object "hook".  You
need to notice it when any of them goes corrupt or missing, or your
next "git push" to send them over to a remote location will fail by
definition because you are the only one with these objects.

If we had the "promise" thing, then we could say that it is OK if
traversal terminated at a "promised but not fetched yet" boundary,
but we cannot afford the "promise", and more importantly, I do not
think "promise" has to be the only approach to ensure that the
objects that exist only in the local repository are all connected.

For example, if we know that the remote 'origin' is the actual
backing store lazy-object "hook" talks with, a validation rule to
ensure that we haven't lost any local commit is to ensure that a
traversal from our local branch tips down to remote-tracking
branches taken from 'origin' must not hit _any_ missing commit.

That covers only the commit objects.  I do not know offhand if we
can and how we extend this concept to protect the tags, trees and
blobs we have locally generated and haven't pushed out, but you and
Ben hopefully can come up with ways to cover them.





Hello Beautiful,

2017-07-29 Thread Jack
Good day dear, i hope this mail meets you well? my name is Jack, from the U.S. 
I know this may seem inappropriate so i ask for your forgiveness but i wish to 
get to know you better, if I may be so bold. I consider myself an easy-going 
man, adventurous, honest and fun loving person but I am currently looking for a 
relationship in which I will feel loved. I promise to answer any question that 
you may want to ask me...all i need is just your attention and the chance to 
know you more.

Please tell me more about yourself, if you do not mind. Hope to hear back from 
you soon.

Jack.


Re: [RFC PATCH v2 2/4] promised-object, fsck: introduce promised objects

2017-07-29 Thread Philip Oakley

From: "Ben Peart" 
Sent: Tuesday, July 25, 2017 4:10 PM

On 7/21/2017 4:33 PM, Jonathan Tan wrote:

On Fri, 21 Jul 2017 12:24:52 -0400
Ben Peart  wrote:


Today we have 3.5 million objects * 30 bytes per entry = 105 MB of
promises. Given the average developer only hydrates 56K files (2 MB
promises) that is 103 MB to download that no one will ever need. We
would like to avoid that if possible as this would be a significant
regression in clone times from where we are today.



A question in the broader context of Narrow clones that I'd be interested 
in.


How narrow are the tree levels that contain the hydrated files? The question 
splits a couple of ways:


A. If one goes to the highest tree that contains all the 56K files, how many 
files and sub trees would be in that complete tree (i.e. what fraction of 
that 'top' tree is inflated).
A2. Is there some deep/wide metric that indicates how tightly together the 
inflated files tend to cluster?


B. If instead we look at just the trees in the paths of those inflated 
files, those trees will also reference other trees/blobs that are not 
inflated, how big is that list (it would indicate the size of a narrow 
repo's object store that holds the oid stubs)


I would quess / expect that the typical inflation only has a few clustered 
areas of interest, but it maybe that in such a big reality (*) the inflated 
files are actually spread very widely. (*) as per various blog posts saying 
there was no realistic way of partitioning the BigWin repo!


I'd be interested in any such sparsity metric (apologies if I've missed 
previous reports).

--
Philip


I'm also concerned about the performance of merging in promises given we
have 100M objects today and growing so the number of promises over time
could get pretty large.


After some thought, maybe a hybrid solution is best, in which it is
permissible but optional for some missing objects to have promises. In
that case, it is more of a "size cache" (which stores the type as well)
rather than a true promise. When fetching, the client can optionally
request for the sizes and types of missing objects.



In our GVFS solution today we do not download any size or object type 
information at clone as the number of objects and the resulting file would 
be too large.  Instead, we have a new sizes endpoint 
(https://github.com/Microsoft/GVFS/blob/master/Protocol.md) that enables 
us to retrieve object sizes "on demand" much like we are enabling for the 
actual object content.


This protocol could easily be extended to return both size and type so 
that it could be used to retrieve "promise" data for objects as they are 
needed. Having a way to "cache" that data locally so that both git and 
other code could share it would be great.


At a minimum, we should ensure the data stream passed back is the same 
whether at clone time or when hitting a "promises" end point. I think it 
would also be helpful to enable promises to be downloaded on demand much 
like we are doing for the object data itself.



This is good for the large-blob case, in which we can always have size
information of missing blobs, and we can subsequently add blob-size
filtering (as a parameter) to "git log -S" and friends to avoid needing
to resolve a missing object. And this is, as far as I can tell, also
good for the many-blob case - just have an empty size cache all the
time. (And in the future, use cases could come up that desire non-empty
but non-comprehensive caches - for example, a directory lister working
on a partial clone that only needs to cache the sizes of frequently
accessed directories.)

Another option is to have a repo-wide option that toggles between
mandatory entries in the "size cache" and prohibited entries. Switching
to mandatory provides stricter fsck and negative lookups, but I think
it's not worth it for both the developers and users of Git to have to
know about these two modes.


I think we should have a flag (off by default) that enables someone to
say that promised objects are optional. If the flag is set,
"is_promised_object" will return success and pass the OBJ_ANY type and 
a

size of -1.

Nothing today is using the size and in the two places where the object
type is being checked for consistency (fsck_cache_tree and
fsck_handle_ref) the test can add a test for OBJ_ANY as well.

This will enable very large numbers of objects to be omitted from the
clone without triggering a download of the corresponding number of
promised objects.


Eventually I plan to use the size when implementing parameters for
history-searching commands (e.g. "git log -S"), but it's true that
that's in the future.

Allowing promised objects to be optional would indeed solve the issue 
of

downloading too many promises. It would make the code more complicated,
but I'm not sure by how much.

For example, in this fsck patch, the easiest way I could think of to
have promised objects was to introduce a 3rd state, called 

Re: [RFC PATCH 0/3] Partial clone: promised blobs (formerly "missing blobs")

2017-07-29 Thread Philip Oakley

From: "Jonathan Nieder" 
Sent: Monday, July 17, 2017 7:03 PM

Hi Philip,

Philip Oakley wrote:

From: "Jonathan Tan" 



These patches are part of a set of patches implementing partial clone,
as you can see here:

https://github.com/jonathantanmy/git/tree/partialclone

[...]

If I understand correctly, this method doesn't give any direct user
visibility of missing blobs in the file system. Is that correct?

I was hoping that eventually the various 'on demand' approaches
would still allow users to continue to work as they go off-line such
that they can see directly (in the FS) where the missing blobs (and
trees) are located, so that they can continue to commit new work on
existing files.

I had felt that some sort of 'gitlink' should be present (huma
readable) as a place holder for the missing blob/tree. e.g.
'gitblob: 1234abcd' (showing the missing oid, jsut like sub-modules
can do - it's no different really.


That's a reasonable thing to want, but it's a little different from
the use cases that partial clone work so far has aimed to support.
They are:

A. Avoiding downloading all blobs (and likely trees as well) that are
   not needed in the current operation (e.g. checkout).  This blends
   well with the sparse checkout feature, which allows the current
   checkout to be fairly small in a large repository.


True. In my case I was looking for a method that would allow a 'Narrow 
clone' such that the local repo would be smaller (have less content), but 
would feel as if all the usefull files/directories were available, and there 
would be place holders at the points where the trees were pruned, both in 
the object store, and in the user's work-tree.


As you say, in some ways its conceptually orthogonal to the original sparse 
checket (which has a full width object store / repo, and then omitted files 
from the checkout.


   GVFS uses a trick that makes it a little easier to widen a sparse
   checkout upon access of a directory.  But the same building blocks
   should work fine with a sparse checkout that has been set up
   explicitly.

B. Avoiding downloading large blobs, except for those needed in the
   current operation (e.g. checkout).

   When not using sparse checkout, the main benefit out of the box is
   avoiding downloading *historical versions* of large blobs.




It sounds like you are looking for a sort of placeholder outside the
sparse checkout area.


True.


In a way, that's orthogonal to these patches:
even if you have all relevant blobs, you may want to avoid inflating
them to check them out and reading them to compare to the index (i.e.
the usual benefits of sparse checkout).


In my concept, it should be possible to create the ('sparse'/narrow) index 
from the content of the local object store, without any network connection 
(though that content is determined by the prior fetch/clone;-). The proper 
git sparse checkout could proceed from there as being a further local 
restriction on what is omitted from the worktree.


Those missing from the narrow clone would still show as place holders with 
content ".gitnarrowtree 13a24b.." (so we know what the hash oid of the 
file/tree should be (so they can be moved/renamed etc!). The index would 
only know the content/structure as far as the place holders (just like 
sub-modules are a break point in the tracking, with identical caveats)



It would be interesting to know from Ben the level of sparseness/narrowness 
has been seen typically in the BigWin GVFS repo case.



 In a sparse checkout, you
still might like to be able to get a listing of files outside the
sparse area (which you can get with "git ls-tree") and you may even
want to be able to get such a listing with plain "ls" (as with your
proposal).

Thanks and hope that helps,
Jonathan


Thanks, yes. It has help consolidate some of the parts of my concept that 
has been in the back of my mind for a while now.


Philip 



[PATCH] setup: update error message to be more meaningful

2017-07-29 Thread Kaartic Sivaraam
The error message shown when a flag is found when expecting a
filename wasn't clear as it didn't communicate what was wrong
using the 'suitable' words in *all* cases.

$ git ls-files
README.md
test-file

Correct case,

$ git rev-parse README.md --flags
README.md
--flags
fatal: bad flag '--flags' used after filename

Incorrect case,

$ git grep "some random regex" -n
fatal: bad flag '-n' used after filename

The above case is incorrect as "some random regex" isn't a filename
in this case.

Change the error message to be general and communicative. This results
in the following output,

$ git rev-parse README.md --flags
README.md
--flags
fatal: option '--flags' must come before non-option arguments

$ git grep "some random regex" -n
fatal: option '-n' must come before non-option arguments

Signed-off-by: Kaartic Sivaraam 
---
 setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.c b/setup.c
index 860507e1fdb2d..09c79328247dd 100644
--- a/setup.c
+++ b/setup.c
@@ -230,7 +230,7 @@ void verify_filename(const char *prefix,
 int diagnose_misspelt_rev)
 {
if (*arg == '-')
-   die("bad flag '%s' used after filename", arg);
+   die("option '%s' must come before non-option arguments", arg);
if (looks_like_pathspec(arg) || check_filename(prefix, arg))
return;
die_verify_filename(prefix, arg, diagnose_misspelt_rev);

--
https://github.com/git/git/pull/393


Re: [PATCH/RFC] setup: update error message to be more meaningful

2017-07-29 Thread Kaartic Sivaraam
On Fri, 2017-07-28 at 20:53 -0700, Junio C Hamano wrote:
> Kaartic Sivaraam  writes:
> 
> > Though the message seems to be most fitting one, I'm a little reluctant
> > to use it as it "might" create a wrong picture on the minds of the user
> > making them think this would be the case in other cases too, which we
> > know is not true. For example,
> > 
> > 
> > git log -p --full-diff master --stat
> > 
> > git commit -v Makefile --amend
> 
> These are accepted not by design but by accident.  
> 
> I do not think we even document that you are allowed to do these in
> "log" and "commit" manual pages, and we should discourage them (I do
> not even mind eventually removing these with the usual deprecation
> dance, but I do not think it is worth the noise).
> 
That's interesting. In that case, I'll go with the suggested statement,
happily!

-- 
Kaartic


[PATCH] gitk: different color for boundary commits

2017-07-29 Thread Stefan Dotterweich
When using filters, the commit list shows not only commits matching
the filter criteria, but also boundary commits. When going through a
list of say, all commits changing the variable `foo`, often half of
the displayed commits are boundary commits. In this case the boundary
commits are of little interest.

However, there is no way to hide them or quickly distinguish them from
the actual commits.  Boundary commits can be identified by the white
color inside the circle, but that is not easily recognisable.  On each
line you  have to look at the circle color to identify the commit
type. This makes it hard to just quickly skim a list of commits,
especially when looking at dates and authors which are further to the
right.

Therefore, to make boundary commits easier to recognise, display their
text in a different color.

Signed-off-by: Stefan Dotterweich 
---
 I made this change for myself, but it would be nice to see it in the
 official build.

 gitk-git/gitk | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/gitk-git/gitk b/gitk-git/gitk
index a14d7a16b..8f5e0df75 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -6115,7 +6115,7 @@ proc drawcmittext {id row col} {
 global canvxmax boldids boldnameids fgcolor markedid
 global mainheadid nullid nullid2 circleitem circlecolors ctxbut
 global mainheadcirclecolor workingfilescirclecolor indexcirclecolor
-global circleoutlinecolor
+global circleoutlinecolor uifgdisabledcolor
 
 # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 
for right
 set listed $cmitlisted($curview,$id)
@@ -6128,6 +6128,10 @@ proc drawcmittext {id row col} {
 } else {
set ofill [lindex $circlecolors $listed]
 }
+set textcolor $fgcolor
+if {$listed eq 0} {
+   set textcolor $uifgdisabledcolor
+}
 set x [xc $row $col]
 set y [yc $row]
 set orad [expr {$linespc / 3}]
@@ -6189,12 +6193,12 @@ proc drawcmittext {id row col} {
set nfont mainfontbold
}
 }
-set linehtag($id) [$canv create text $xt $y -anchor w -fill $fgcolor \
+set linehtag($id) [$canv create text $xt $y -anchor w -fill $textcolor \
   -text $headline -font $font -tags text]
 $canv bind $linehtag($id) $ctxbut "rowmenu %X %Y $id"
-set linentag($id) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
+set linentag($id) [$canv2 create text 3 $y -anchor w -fill $textcolor \
   -text $name -font $nfont -tags text]
-set linedtag($id) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
+set linedtag($id) [$canv3 create text 3 $y -anchor w -fill $textcolor \
   -text $date -font mainfont -tags text]
 if {$selectedline == $row} {
make_secsel $id
-- 
2.12.0



URGENT REPLY FOR MORE DETAILS.

2017-07-29 Thread casimire kere
Compliment of the day,

I am Mr.Kere Casmire I Have a Business Proposal of $5.3 million For You.
I am aware of the unsafe nature of the internet,
and was compelled to use this medium due to the nature of this project.

I have access to very vital information that can be used to transfer
this huge amount of money.

which may culminate into the investment of the said funds into your
company or any lucrative venture in your country.

If you will like to assist me as a partner then indicate your interest,
after which we shall both discuss the modalities and the sharing percentage.

Upon receipt of your reply on your expression of Interest I will give
you full details,
on how the business will be executed I am open for negotiation.

Thanks for your anticipated cooperation.

Note you might receive this message in your inbox or spam or junk folder,
depends on your web host or server network.

Regards,
Mr.Kere Casmire