Merge branch 'maint-1.7.2' into maint-1.7.3
authorJunio C Hamano <gitster@pobox.com>
Wed, 16 Feb 2011 22:32:59 +0000 (14:32 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Feb 2011 22:32:59 +0000 (14:32 -0800)
* maint-1.7.2:
fast-import: introduce "feature notes" command
fast-import: clarify documentation of "feature" command

1  2 
Documentation/git-fast-import.txt
fast-import.c
index 2c6ad5b2f32e6c0248f0a30423b07d01fed3baa3,072d4f9af242e69235c92c534e9fd53192002cca..4349d6a9a648fd9694ca29dc3608facb3d67f449
@@@ -439,7 -439,7 +439,7 @@@ Marks must be declared (via `mark`) bef
  * A complete 40 byte or abbreviated commit SHA-1 in hex.
  
  * Any valid Git SHA-1 expression that resolves to a commit.  See
 -  ``SPECIFYING REVISIONS'' in linkgit:gitrevisions[1] for details.
 +  ``SPECIFYING REVISIONS'' in linkgit:gitrevisions[7] for details.
  
  The special case of restarting an incremental import from the
  current branch value should be written as:
@@@ -482,11 -482,9 +482,11 @@@ External data format:
        'M' SP <mode> SP <dataref> SP <path> LF
  ....
  +
 -Here `<dataref>` can be either a mark reference (`:<idnum>`)
 +Here usually `<dataref>` must be either a mark reference (`:<idnum>`)
  set by a prior `blob` command, or a full 40-byte SHA-1 of an
 -existing Git blob object.
 +existing Git blob object.  If `<mode>` is `040000`` then
 +`<dataref>` must be the full 40-byte SHA-1 of an existing
 +Git tree object or a mark reference set with `--import-marks`.
  
  Inline data format::
        The data content for the file has not been supplied yet.
@@@ -511,8 -509,6 +511,8 @@@ in octal.  Git only supports the follow
  * `160000`: A gitlink, SHA-1 of the object refers to a commit in
    another repository. Git links can only be specified by SHA or through
    a commit mark. They are used to implement submodules.
 +* `040000`: A subdirectory.  Subdirectories can only be specified by
 +  SHA or through a tree mark set with `--import-marks`.
  
  In both formats `<path>` is the complete path of the file to be added
  (if not already existing) or modified (if already existing).
@@@ -882,28 -878,31 +882,31 @@@ Require that fast-import supports the s
  it does not.
  
  ....
-       'feature' SP <feature> LF
- ....
- The <feature> part of the command may be any string matching
- ^[a-zA-Z][a-zA-Z-]*$ and should be understood by fast-import.
- Feature work identical as their option counterparts with the
- exception of the import-marks feature, see below.
- The following features are currently supported:
- * date-format
- * import-marks
- * export-marks
- * relative-marks
- * no-relative-marks
- * force
- The import-marks behaves differently from when it is specified as
- commandline option in that only one "feature import-marks" is allowed
- per stream. Also, any --import-marks= specified on the commandline
- will override those from the stream (if any).
+       'feature' SP <feature> ('=' <argument>)? LF
+ ....
+ The <feature> part of the command may be any one of the following:
+ date-format::
+ export-marks::
+ relative-marks::
+ no-relative-marks::
+ force::
+       Act as though the corresponding command-line option with
+       a leading '--' was passed on the command line
+       (see OPTIONS, above).
+ import-marks::
+       Like --import-marks except in two respects: first, only one
+       "feature import-marks" command is allowed per stream;
+       second, an --import-marks= command-line option overrides
+       any "feature import-marks" command in the stream.
+ notes::
+       Require that the backend support the 'notemodify' (N)
+       subcommand to the 'commit' command.
+       Versions of fast-import not supporting notes will exit
+       with a message indicating so.
  
  `option`
  ~~~~~~~~
diff --combined fast-import.c
index 7563e43a39c4d4573218fab52ffbf64a255f2562,86687f391048dbca3920bbc1b47941118c5059da..8be8a5b73298e2f4a3c7e68a1c824fb0b6cd92e8
@@@ -539,17 -539,22 +539,17 @@@ static struct object_entry *insert_obje
  {
        unsigned int h = sha1[0] << 8 | sha1[1];
        struct object_entry *e = object_table[h];
 -      struct object_entry *p = NULL;
  
        while (e) {
                if (!hashcmp(sha1, e->idx.sha1))
                        return e;
 -              p = e;
                e = e->next;
        }
  
        e = new_object(sha1);
 -      e->next = NULL;
 +      e->next = object_table[h];
        e->idx.offset = 0;
 -      if (p)
 -              p->next = e;
 -      else
 -              object_table[h] = e;
 +      object_table[h] = e;
        return e;
  }
  
@@@ -1523,14 -1528,6 +1523,14 @@@ static int tree_content_remove
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
                if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
 +                      if (slash1 && !S_ISDIR(e->versions[1].mode))
 +                              /*
 +                               * If p names a file in some subdirectory, and a
 +                               * file or symlink matching the name of the
 +                               * parent directory of p exists, then p cannot
 +                               * exist and need not be deleted.
 +                               */
 +                              return 1;
                        if (!slash1 || !S_ISDIR(e->versions[1].mode))
                                goto del_entry;
                        if (!e->tree)
@@@ -2134,7 -2131,6 +2134,7 @@@ static void file_change_m(struct branc
        case S_IFREG | 0644:
        case S_IFREG | 0755:
        case S_IFLNK:
 +      case S_IFDIR:
        case S_IFGITLINK:
                /* ok */
                break;
                p = uq.buf;
        }
  
 +      /* Git does not track empty, non-toplevel directories. */
 +      if (S_ISDIR(mode) && !memcmp(sha1, EMPTY_TREE_SHA1_BIN, 20) && *p) {
 +              tree_content_remove(&b->branch_tree, p, NULL);
 +              return;
 +      }
 +
        if (S_ISGITLINK(mode)) {
                if (inline_data)
                        die("Git links cannot be specified 'inline': %s",
                 * another repository.
                 */
        } else if (inline_data) {
 +              if (S_ISDIR(mode))
 +                      die("Directories cannot be specified 'inline': %s",
 +                              command_buf.buf);
                if (p != uq.buf) {
                        strbuf_addstr(&uq, p);
                        p = uq.buf;
                }
                read_next_command();
                parse_and_store_blob(&last_blob, sha1, 0);
 -      } else if (oe) {
 -              if (oe->type != OBJ_BLOB)
 -                      die("Not a blob (actually a %s): %s",
 -                              typename(oe->type), command_buf.buf);
        } else {
 -              enum object_type type = sha1_object_info(sha1, NULL);
 +              enum object_type expected = S_ISDIR(mode) ?
 +                                              OBJ_TREE: OBJ_BLOB;
 +              enum object_type type = oe ? oe->type :
 +                                      sha1_object_info(sha1, NULL);
                if (type < 0)
 -                      die("Blob not found: %s", command_buf.buf);
 -              if (type != OBJ_BLOB)
 -                      die("Not a blob (actually a %s): %s",
 -                          typename(type), command_buf.buf);
 +                      die("%s not found: %s",
 +                                      S_ISDIR(mode) ?  "Tree" : "Blob",
 +                                      command_buf.buf);
 +              if (type != expected)
 +                      die("Not a %s (actually a %s): %s",
 +                              typename(expected), typename(type),
 +                              command_buf.buf);
        }
  
        tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
@@@ -2815,6 -2800,8 +2815,8 @@@ static int parse_one_feature(const cha
                relative_marks_paths = 0;
        } else if (!prefixcmp(feature, "force")) {
                force_update = 1;
+       } else if (!strcmp(feature, "notes")) {
+               ; /* do nothing; we have the feature */
        } else {
                return 0;
        }
@@@ -2885,7 -2872,7 +2887,7 @@@ static int git_pack_config(const char *
  }
  
  static const char fast_import_usage[] =
 -"git fast-import [--date-format=f] [--max-pack-size=n] [--big-file-threshold=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
 +"git fast-import [--date-format=<f>] [--max-pack-size=<n>] [--big-file-threshold=<n>] [--depth=<n>] [--active-branches=<n>] [--export-marks=<marks.file>]";
  
  static void parse_argv(void)
  {