Merge branch 'master' into next
authorJunio C Hamano <junkio@cox.net>
Mon, 27 Mar 2006 07:44:14 +0000 (23:44 -0800)
committerJunio C Hamano <junkio@cox.net>
Mon, 27 Mar 2006 07:44:14 +0000 (23:44 -0800)
* master:
  Optionally do not list empty directories in git-ls-files --others
  Document git-rebase behavior on conflicts.
  Fix error handling for nonexistent names

1  2 
Documentation/git-ls-files.txt
ls-files.c

@@@ -14,9 -14,9 +14,9 @@@ SYNOPSI
                (-[c|d|o|i|s|u|k|m])\*
                [-x <pattern>|--exclude=<pattern>]
                [-X <file>|--exclude-from=<file>]
 -              [--exclude-per-directory=<file>] 
 +              [--exclude-per-directory=<file>]
                [--error-unmatch]
 -              [--full-name] [--] [<file>]\*
 +              [--full-name] [--abbrev] [--] [<file>]\*
  
  DESCRIPTION
  -----------
@@@ -52,6 -52,9 +52,9 @@@ OPTION
        If a whole directory is classified as "other", show just its
        name (with a trailing slash) and not its whole contents.
  
+ --no-empty-directory::
+       Do not list empty directories. Has no effect without --directory.
  -u|--unmerged::
        Show unmerged files in the output (forces --stage)
  
        option forces paths to be output relative to the project
        top directory.
  
 +--abbrev[=<n>]::
 +      Instead of showing the full 40-byte hexadecimal object
 +      lines, show only handful hexdigits prefix.
 +      Non default number of digits can be specified with --abbrev=<n>.
 +
  --::
        Do not interpret any more arguments as options.
  
diff --combined ls-files.c
@@@ -11,7 -11,6 +11,7 @@@
  #include "cache.h"
  #include "quote.h"
  
 +static int abbrev = 0;
  static int show_deleted = 0;
  static int show_cached = 0;
  static int show_others = 0;
@@@ -21,6 -20,7 +21,7 @@@ static int show_unmerged = 0
  static int show_modified = 0;
  static int show_killed = 0;
  static int show_other_directories = 0;
+ static int hide_empty_directories = 0;
  static int show_valid_bit = 0;
  static int line_terminator = '\n';
  
@@@ -259,11 -259,12 +260,12 @@@ static int dir_exists(const char *dirna
   * Also, we ignore the name ".git" (even if it is not a directory).
   * That likely will not change.
   */
- static void read_directory(const char *path, const char *base, int baselen)
+ static int read_directory(const char *path, const char *base, int baselen)
  {
-       DIR *dir = opendir(path);
+       DIR *fdir = opendir(path);
+       int contents = 0;
  
-       if (dir) {
+       if (fdir) {
                int exclude_stk;
                struct dirent *de;
                char fullname[MAXPATHLEN + 1];
  
                exclude_stk = push_exclude_per_directory(base, baselen);
  
-               while ((de = readdir(dir)) != NULL) {
+               while ((de = readdir(fdir)) != NULL) {
                        int len;
  
                        if ((de->d_name[0] == '.') &&
  
                        switch (DTYPE(de)) {
                        struct stat st;
+                       int subdir, rewind_base;
                        default:
                                continue;
                        case DT_UNKNOWN:
                        case DT_DIR:
                                memcpy(fullname + baselen + len, "/", 2);
                                len++;
+                               rewind_base = nr_dir;
+                               subdir = read_directory(fullname, fullname,
+                                                       baselen + len);
                                if (show_other_directories &&
-                                   !dir_exists(fullname, baselen + len))
+                                   (subdir || !hide_empty_directories) &&
+                                   !dir_exists(fullname, baselen + len)) {
+                                       // Rewind the read subdirectory
+                                       while (nr_dir > rewind_base)
+                                               free(dir[--nr_dir]);
                                        break;
-                               read_directory(fullname, fullname,
-                                              baselen + len);
+                               }
+                               contents += subdir;
                                continue;
                        case DT_REG:
                        case DT_LNK:
                                break;
                        }
                        add_name(fullname, baselen + len);
+                       contents++;
                }
-               closedir(dir);
+               closedir(fdir);
  
                pop_exclude_per_directory(exclude_stk);
        }
+       return contents;
  }
  
  static int cmp_name(const void *p1, const void *p2)
@@@ -490,8 -502,7 +503,8 @@@ static void show_ce_entry(const char *t
                printf("%s%06o %s %d\t",
                       tag,
                       ntohl(ce->ce_mode),
 -                     sha1_to_hex(ce->sha1),
 +                     abbrev ? find_unique_abbrev(ce->sha1,abbrev)
 +                              : sha1_to_hex(ce->sha1),
                       ce_stage(ce));
                write_name_quoted("", 0, ce->name + offset,
                                  line_terminator, stdout);
@@@ -632,8 -643,7 +645,8 @@@ static void verify_pathspec(void
  static const char ls_files_usage[] =
        "git-ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
        "[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
 -      "[ --exclude-per-directory=<filename> ] [--full-name] [--] [<file>]*";
 +      "[ --exclude-per-directory=<filename> ] [--full-name] [--abbrev] "
 +      "[--] [<file>]*";
  
  int main(int argc, const char **argv)
  {
                        show_other_directories = 1;
                        continue;
                }
+               if (!strcmp(arg, "--no-empty-directory")) {
+                       hide_empty_directories = 1;
+                       continue;
+               }
                if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) {
                        /* There's no point in showing unmerged unless
                         * you also show the stage information.
                        error_unmatch = 1;
                        continue;
                }
 +              if (!strncmp(arg, "--abbrev=", 9)) {
 +                      abbrev = strtoul(arg+9, NULL, 10);
 +                      if (abbrev && abbrev < MINIMUM_ABBREV)
 +                              abbrev = MINIMUM_ABBREV;
 +                      else if (abbrev > 40)
 +                              abbrev = 40;
 +                      continue;
 +              }
 +              if (!strcmp(arg, "--abbrev")) {
 +                      abbrev = DEFAULT_ABBREV;
 +                      continue;
 +              }
                if (*arg == '-')
                        usage(ls_files_usage);
                break;