]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'jc/capabilities' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 11 Sep 2012 18:06:45 +0000 (11:06 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 11 Sep 2012 18:06:45 +0000 (11:06 -0700)
* jc/capabilities:
  fetch-pack: mention server version with verbose output
  parse_feature_request: make it easier to see feature values
  fetch-pack: do not ask for unadvertised capabilities
  do not send client agent unless server does first
  send-pack: fix capability-sending logic
  include agent identifier in capability string

1  2 
builtin/receive-pack.c
cache.h
connect.c

diff --combined builtin/receive-pack.c
index 3f05d971ec2f8b047b2ef3a32c91f039d686d91a,fbfa1289c1e9122f698f54547b7aff5bfc8ca95c..2cb854feb4b3a701201ef683c6644aaa852d50b5
@@@ -12,6 -12,7 +12,7 @@@
  #include "string-list.h"
  #include "sha1-array.h"
  #include "connected.h"
+ #include "version.h"
  
  static const char receive_pack_usage[] = "git receive-pack <git-dir>";
  
@@@ -121,10 -122,11 +122,11 @@@ static void show_ref(const char *path, 
        if (sent_capabilities)
                packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
        else
-               packet_write(1, "%s %s%c%s%s\n",
+               packet_write(1, "%s %s%c%s%s agent=%s\n",
                             sha1_to_hex(sha1), path, 0,
                             " report-status delete-refs side-band-64k quiet",
-                            prefer_ofs_delta ? " ofs-delta" : "");
+                            prefer_ofs_delta ? " ofs-delta" : "",
+                            git_user_agent_sanitized());
        sent_capabilities = 1;
  }
  
@@@ -977,8 -979,7 +979,8 @@@ int cmd_receive_pack(int argc, const ch
                        const char *argv_gc_auto[] = {
                                "gc", "--auto", "--quiet", NULL,
                        };
 -                      run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
 +                      int opt = RUN_GIT_CMD | RUN_COMMAND_STDOUT_TO_STDERR;
 +                      run_command_v_opt(argv_gc_auto, opt);
                }
                if (auto_update_server_info)
                        update_server_info(0);
diff --combined cache.h
index 67f28b4da97b5aded337e1594043a73c075ea02f,b71b0650f4ba7eb6b588c24cbf7d30661e96d9fb..95daa690aa897c47cde113c27c954ddb7ef0c103
+++ b/cache.h
@@@ -128,13 -128,13 +128,13 @@@ struct cache_entry 
        unsigned int ce_gid;
        unsigned int ce_size;
        unsigned int ce_flags;
 +      unsigned int ce_namelen;
        unsigned char sha1[20];
        struct cache_entry *next;
        struct cache_entry *dir_next;
        char name[FLEX_ARRAY]; /* more */
  };
  
 -#define CE_NAMEMASK  (0x0fff)
  #define CE_STAGEMASK (0x3000)
  #define CE_EXTENDED  (0x4000)
  #define CE_VALID     (0x8000)
@@@ -198,12 -198,21 +198,12 @@@ static inline void copy_cache_entry(str
        dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state;
  }
  
 -static inline unsigned create_ce_flags(size_t len, unsigned stage)
 +static inline unsigned create_ce_flags(unsigned stage)
  {
 -      if (len >= CE_NAMEMASK)
 -              len = CE_NAMEMASK;
 -      return (len | (stage << CE_STAGESHIFT));
 -}
 -
 -static inline size_t ce_namelen(const struct cache_entry *ce)
 -{
 -      size_t len = ce->ce_flags & CE_NAMEMASK;
 -      if (len < CE_NAMEMASK)
 -              return len;
 -      return strlen(ce->name + CE_NAMEMASK) + CE_NAMEMASK;
 +      return (stage << CE_STAGESHIFT);
  }
  
 +#define ce_namelen(ce) ((ce)->ce_namelen)
  #define ce_size(ce) cache_entry_size(ce_namelen(ce))
  #define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
  #define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE)
@@@ -400,11 -409,8 +400,11 @@@ extern const char *setup_git_directory(
  extern char *prefix_path(const char *prefix, int len, const char *path);
  extern const char *prefix_filename(const char *prefix, int len, const char *path);
  extern int check_filename(const char *prefix, const char *name);
 -extern void verify_filename(const char *prefix, const char *name);
 +extern void verify_filename(const char *prefix,
 +                          const char *name,
 +                          int diagnose_misspelt_rev);
  extern void verify_non_filename(const char *prefix, const char *name);
 +extern int path_inside_repo(const char *prefix, const char *path);
  
  #define INIT_DB_QUIET 0x0001
  
@@@ -442,7 -448,6 +442,7 @@@ extern int discard_index(struct index_s
  extern int unmerged_index(const struct index_state *);
  extern int verify_path(const char *path);
  extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
 +extern int index_name_stage_pos(const struct index_state *, const char *name, int namelen, int stage);
  extern int index_name_pos(const struct index_state *, const char *name, int namelen);
  #define ADD_CACHE_OK_TO_ADD 1         /* Ok to add */
  #define ADD_CACHE_OK_TO_REPLACE 2     /* Ok to replace file/directory */
@@@ -555,7 -560,6 +555,7 @@@ extern int read_replace_refs
  extern int fsync_object_files;
  extern int core_preload_index;
  extern int core_apply_sparse_checkout;
 +extern int precomposed_unicode;
  
  enum branch_track {
        BRANCH_TRACK_UNSPECIFIED = -1,
@@@ -615,8 -619,6 +615,8 @@@ extern char *git_snpath(char *buf, size
        __attribute__((format (printf, 3, 4)));
  extern char *git_pathdup(const char *fmt, ...)
        __attribute__((format (printf, 1, 2)));
 +extern char *mkpathdup(const char *fmt, ...)
 +      __attribute__((format (printf, 1, 2)));
  
  /* Return a statically allocated filename matching the sha1 signature */
  extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
@@@ -706,7 -708,6 +706,7 @@@ int set_shared_perm(const char *path, i
  int safe_create_leading_directories(char *path);
  int safe_create_leading_directories_const(const char *path);
  int mkdir_in_gitdir(const char *path);
 +extern void home_config_paths(char **global, char **xdg, char *file);
  extern char *expand_user_path(const char *path);
  const char *enter_repo(const char *path, int strict);
  static inline int is_absolute_path(const char *path)
@@@ -782,25 -783,17 +782,25 @@@ struct object_context 
        unsigned mode;
  };
  
 +#define GET_SHA1_QUIETLY        01
 +#define GET_SHA1_COMMIT         02
 +#define GET_SHA1_COMMITTISH     04
 +#define GET_SHA1_TREE          010
 +#define GET_SHA1_TREEISH       020
 +#define GET_SHA1_BLOB        040
 +#define GET_SHA1_ONLY_TO_DIE 04000
 +
  extern int get_sha1(const char *str, unsigned char *sha1);
 -extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int only_to_die, const char *prefix);
 -static inline int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode)
 -{
 -      return get_sha1_with_mode_1(str, sha1, mode, 0, NULL);
 -}
 -extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int only_to_die, const char *prefix);
 -static inline int get_sha1_with_context(const char *str, unsigned char *sha1, struct object_context *orc)
 -{
 -      return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
 -}
 +extern int get_sha1_commit(const char *str, unsigned char *sha1);
 +extern int get_sha1_committish(const char *str, unsigned char *sha1);
 +extern int get_sha1_tree(const char *str, unsigned char *sha1);
 +extern int get_sha1_treeish(const char *str, unsigned char *sha1);
 +extern int get_sha1_blob(const char *str, unsigned char *sha1);
 +extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
 +extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc);
 +
 +typedef int each_abbrev_fn(const unsigned char *sha1, void *);
 +extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
  
  /*
   * Try to read a SHA1 in hexadecimal format from the 40 characters
@@@ -864,7 -857,6 +864,7 @@@ extern int validate_headref(const char 
  extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
  extern int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
  extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
 +extern int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2);
  
  extern void *read_object_with_reference(const unsigned char *sha1,
                                        const char *required_type,
@@@ -1038,7 -1030,9 +1038,9 @@@ struct extra_have_objects 
  };
  extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *);
  extern int server_supports(const char *feature);
- extern const char *parse_feature_request(const char *features, const char *feature);
+ extern int parse_feature_request(const char *features, const char *feature);
+ extern const char *server_feature_value(const char *feature, int *len_ret);
+ extern const char *parse_feature_value(const char *feature_list, const char *feature, int *len_ret);
  
  extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
  
diff --combined connect.c
index 55a85adea94c87c912280079ee13afd6926901aa,9aec10cec11233405b1d5b1cfb15030dcbcc0ce5..49e56ba35a645359b0d7c1f7bbc9e2108b3424d9
+++ b/connect.c
@@@ -49,16 -49,6 +49,16 @@@ static void add_extra_have(struct extra
        extra->nr++;
  }
  
 +static void die_initial_contact(int got_at_least_one_head)
 +{
 +      if (got_at_least_one_head)
 +              die("The remote end hung up upon initial contact");
 +      else
 +              die("Could not read from remote repository.\n\n"
 +                  "Please make sure you have the correct access rights\n"
 +                  "and the repository exists.");
 +}
 +
  /*
   * Read all the refs from the other end
   */
@@@ -66,8 -56,6 +66,8 @@@ struct ref **get_remote_heads(int in, s
                              unsigned int flags,
                              struct extra_have_objects *extra_have)
  {
 +      int got_at_least_one_head = 0;
 +
        *list = NULL;
        for (;;) {
                struct ref *ref;
                char *name;
                int len, name_len;
  
 -              len = packet_read_line(in, buffer, sizeof(buffer));
 +              len = packet_read(in, buffer, sizeof(buffer));
 +              if (len < 0)
 +                      die_initial_contact(got_at_least_one_head);
 +
                if (!len)
                        break;
                if (buffer[len-1] == '\n')
                hashcpy(ref->old_sha1, old_sha1);
                *list = ref;
                list = &ref->next;
 +              got_at_least_one_head = 1;
        }
        return list;
  }
  
- int server_supports(const char *feature)
- {
-       return !!parse_feature_request(server_capabilities, feature);
- }
- const char *parse_feature_request(const char *feature_list, const char *feature)
+ const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp)
  {
        int len;
  
                const char *found = strstr(feature_list, feature);
                if (!found)
                        return NULL;
-               if ((feature_list == found || isspace(found[-1])) &&
-                   (!found[len] || isspace(found[len]) || found[len] == '='))
-                       return found;
+               if (feature_list == found || isspace(found[-1])) {
+                       const char *value = found + len;
+                       /* feature with no value (e.g., "thin-pack") */
+                       if (!*value || isspace(*value)) {
+                               if (lenp)
+                                       *lenp = 0;
+                               return value;
+                       }
+                       /* feature with a value (e.g., "agent=git/1.2.3") */
+                       else if (*value == '=') {
+                               value++;
+                               if (lenp)
+                                       *lenp = strcspn(value, " \t\n");
+                               return value;
+                       }
+                       /*
+                        * otherwise we matched a substring of another feature;
+                        * keep looking
+                        */
+               }
                feature_list = found + 1;
        }
        return NULL;
  }
  
+ int parse_feature_request(const char *feature_list, const char *feature)
+ {
+       return !!parse_feature_value(feature_list, feature, NULL);
+ }
+ const char *server_feature_value(const char *feature, int *len)
+ {
+       return parse_feature_value(server_capabilities, feature, len);
+ }
+ int server_supports(const char *feature)
+ {
+       return !!server_feature_value(feature, NULL);
+ }
  enum protocol {
        PROTO_LOCAL = 1,
        PROTO_SSH,
@@@ -552,7 -563,7 +579,7 @@@ struct child_process *git_connect(int f
         * Add support for ssh port: ssh://host.xy:<port>/...
         */
        if (protocol == PROTO_SSH && host != url)
 -              port = get_port(host);
 +              port = get_port(end);
  
        if (protocol == PROTO_GIT) {
                /* These underlying connection commands die() if they