Hi,
On Thu, 19 Jul 2007, Tomash Brechko wrote:
Thank you. It is my impression, too, that after a while it becomes
obvious what is good and what is not.
FWIW I just whipped up a proof-of-concept patch (so at least _I_ cannot be
accused of chickening out of writing code):
This adds the command line option "--add-empty-dirs" to "git add", which
does the only sane thing: putting a placeholder into that directory, and
adding that. Since ".gitignore" is already a reserved file name in git,
it is used as the name of this place holder.
---
It is probably not fool-proof yet, needs documentation and a test
case. But I am really sick and tired of this discussion.
builtin-add.c | 25 +++++++++++++++++++++----
dir.c | 16 +++++++++++++++-
dir.h | 3 ++-
3 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index 7345479..1294840 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -47,7 +47,7 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
}
static void fill_directory(struct dir_struct *dir, const char **pathspec,
- int ignored_too)
+ int ignored_too, int substitute_empty_dirs)
{
const char *path, *base;
int baselen;
@@ -63,6 +63,7 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec,
if (!access(excludes_file, R_OK))
add_excludes_from_file(dir, excludes_file);
}
+ dir->substitute_empty_directories = substitute_empty_dirs;
/*
* Calculate common prefix for the pathspec, and
@@ -143,7 +144,8 @@ static const char ignore_warning[] =
int cmd_add(int argc, const char **argv, const char *prefix)
{
int i, newfd;
- int verbose = 0, show_only = 0, ignored_too = 0;
+ int verbose = 0, show_only = 0, ignored_too = 0,
+ substitute_empty_dirs = 0;
const char **pathspec;
struct dir_struct dir;
int add_interactive = 0;
@@ -191,6 +193,10 @@ int cmd_add(int argc, const char **argv, const char *prefix)
take_worktree_changes = 1;
continue;
}
+ if (!strcmp(arg, "--add-empty-dirs")) {
+ substitute_empty_dirs = 1;
+ continue;
+ }
usage(builtin_add_usage);
}
@@ -206,7 +212,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
}
pathspec = get_pathspec(prefix, argv + i);
- fill_directory(&dir, pathspec, ignored_too);
+ fill_directory(&dir, pathspec, ignored_too, substitute_empty_dirs);
if (show_only) {
const char *sep = "", *eof = "";
@@ -231,8 +237,19 @@ int cmd_add(int argc, const char **argv, const char *prefix)
exit(1);
}
- for (i = 0; i < dir.nr; i++)
+ for (i = 0; i < dir.nr; i++) {
+ const char *name = dir.entries[i]->name;
+ const char *slash;
+ if (substitute_empty_dirs && (slash = strrchr(name, '/')) &&
+ !strcmp(slash, "/.gitignore") &&
+ access(name, R_OK)) {
+ int fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (fd < 0)
+ return error("Could not create %s", name);
+ close(fd);
+ }
add_file_to_cache(dir.entries[i]->name, verbose);
+ }
finish:
if (active_cache_changed) {
diff --git a/dir.c b/dir.c
index 8d8faf5..b0b4628 100644
--- a/dir.c
+++ b/dir.c
@@ -456,11 +456,11 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
{
DIR *fdir = opendir(path);
int contents = 0;
+ char fullname[PATH_MAX + 1];
if (fdir) {
int exclude_stk;
struct dirent *de;
- char fullname[PATH_MAX + 1];
memcpy(fullname, base, baselen);
exclude_stk = push_exclude_per_directory(dir, base, baselen);
@@ -536,6 +536,20 @@ exit_early:
pop_exclude_per_directory(dir, exclude_stk);
}
+ if (!contents && dir->substitute_empty_directories) {
+ const char *name = ".gitignore";
+ int len = strlen(name);
+ /* Ignore overly long pathnames! */
+ if (len + baselen + 8 > sizeof(fullname))
+ return 0;
+ memcpy(fullname + baselen, name, len+1);
+ if (simplify_away(fullname, baselen + len, simplify)
+ || excluded(dir, fullname))
+ return 0;
+ dir_add_name(dir, fullname, baselen + len);
+ return 1;
+ }
+
return contents;
}
diff --git a/dir.h b/dir.h
index ec0e8ab..0099718 100644
--- a/dir.h
+++ b/dir.h
@@ -34,7 +34,8 @@ struct dir_struct {
show_other_directories:1,
hide_empty_directories:1,
no_gitlinks:1,
- collect_ignored:1;
+ collect_ignored:1,
+ substitute_empty_directories:1;
struct dir_entry **entries;
struct dir_entry **ignored;
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
majordomo@vger.kernel.org
More majordomo info at
http://vger.kernel.org/majordomo-info.html