Merge branch 'master' into np/index-pack
authorJunio C Hamano <junkio@cox.net>
Fri, 3 Nov 2006 08:23:52 +0000 (00:23 -0800)
committerJunio C Hamano <junkio@cox.net>
Fri, 3 Nov 2006 08:23:52 +0000 (00:23 -0800)
* master: (90 commits)
gitweb: Better support for non-CSS aware web browsers
gitweb: Output also empty patches in "commitdiff" view
gitweb: Use git-for-each-ref to generate list of heads and/or tags
for-each-ref: "creator" and "creatordate" fields
Add --global option to git-repo-config.
pack-refs: Store the full name of the ref even when packing only tags.
git-clone documentation didn't mention --origin as equivalent of -o
Minor grammar fixes for git-diff-index.txt
link_temp_to_file: call adjust_shared_perm() only when we created the directory
Remove uneccessarily similar printf() from print_ref_list() in builtin-branch
pack-objects doesn't create random pack names
branch: work in subdirectories.
gitweb: Use 's' regexp modifier to secure against filenames with LF
gitweb: Secure against commit-ish/tree-ish with the same name as path
gitweb: esc_html() author in blame
git-svnimport: support for partial imports
link_temp_to_file: don't leave the path truncated on adjust_shared_perm failure
Move deny_non_fast_forwards handling completely into receive-pack.
revision traversal: --unpacked does not limit commit list anymore.
Continue traversal when rev-list --unpacked finds a packed commit.
...

1  2 
fetch-pack.c
receive-pack.c
sha1_file.c
diff --combined fetch-pack.c
index 8720ed42e92b685e881eb30743d57e64dd03c6ed,90b79407c65840deaf1ab80697a90d2e9df12a4a..36ea092d1b824d080b993056cff1cbee6eca5718
@@@ -42,7 -42,7 +42,7 @@@ static void rev_list_push(struct commi
        }
  }
  
- static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
+ static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
  {
        struct object *o = deref_tag(parse_object(sha1), path, 0);
  
@@@ -143,7 -143,7 +143,7 @@@ static int find_common(int fd[2], unsig
        unsigned in_vain = 0;
        int got_continue = 0;
  
-       for_each_ref(rev_list_insert_ref);
+       for_each_ref(rev_list_insert_ref, NULL);
  
        fetching = 0;
        for ( ; refs ; refs = refs->next) {
@@@ -254,7 -254,7 +254,7 @@@ done
  
  static struct commit_list *complete;
  
- static int mark_complete(const char *path, const unsigned char *sha1)
+ static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)
  {
        struct object *o = parse_object(sha1);
  
@@@ -366,7 -366,7 +366,7 @@@ static int everything_local(struct ref 
                }
        }
  
-       for_each_ref(mark_complete);
+       for_each_ref(mark_complete, NULL);
        if (cutoff)
                mark_recent_complete_commits(cutoff);
  
@@@ -518,6 -518,8 +518,6 @@@ int main(int argc, char **argv
        }
        if (!dest)
                usage(fetch_pack_usage);
 -      if (keep_pack)
 -              use_thin_pack = 0;
        pid = git_connect(fd, dest, exec);
        if (pid < 0)
                return 1;
diff --combined receive-pack.c
index 675b1c18a36ac8f4ec670b9b17519b925dab9996,de1d6a4b1c3f51f8763484b6efea0a8ccd289bb3..ed08660da435339faadbaf7bf8e5eb990e11ae33
@@@ -9,12 -9,26 +9,26 @@@ static const char receive_pack_usage[] 
  
  static const char *unpacker[] = { "unpack-objects", NULL };
  
+ static int deny_non_fast_forwards = 0;
  static int report_status;
  
  static char capabilities[] = "report-status";
  static int capabilities_sent;
  
- static int show_ref(const char *path, const unsigned char *sha1)
+ static int receive_pack_config(const char *var, const char *value)
+ {
+       git_default_config(var, value);
+       if (strcmp(var, "receive.denynonfastforwards") == 0)
+       {
+               deny_non_fast_forwards = git_config_bool(var, value);
+               return 0;
+       }
+       return 0;
+ }
+ static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
  {
        if (capabilities_sent)
                packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
@@@ -27,9 -41,9 +41,9 @@@
  
  static void write_head_info(void)
  {
-       for_each_ref(show_ref);
+       for_each_ref(show_ref, NULL);
        if (!capabilities_sent)
-               show_ref("capabilities^{}", null_sha1);
+               show_ref("capabilities^{}", null_sha1, 0, NULL);
  
  }
  
@@@ -43,34 -57,6 +57,6 @@@ struct command 
  
  static struct command *commands;
  
- static int is_all_zeroes(const char *hex)
- {
-       int i;
-       for (i = 0; i < 40; i++)
-               if (*hex++ != '0')
-                       return 0;
-       return 1;
- }
- static int verify_old_ref(const char *name, char *hex_contents)
- {
-       int fd, ret;
-       char buffer[60];
-       if (is_all_zeroes(hex_contents))
-               return 0;
-       fd = open(name, O_RDONLY);
-       if (fd < 0)
-               return -1;
-       ret = read(fd, buffer, 40);
-       close(fd);
-       if (ret != 40)
-               return -1;
-       if (memcmp(buffer, hex_contents, 40))
-               return -1;
-       return 0;
- }
  static char update_hook[] = "hooks/update";
  
  static int run_update_hook(const char *refname,
@@@ -107,8 -93,8 +93,8 @@@ static int update(struct command *cmd
        const char *name = cmd->ref_name;
        unsigned char *old_sha1 = cmd->old_sha1;
        unsigned char *new_sha1 = cmd->new_sha1;
-       char new_hex[60], *old_hex, *lock_name;
-       int newfd, namelen, written;
+       char new_hex[41], old_hex[41];
+       struct ref_lock *lock;
  
        cmd->error_string = NULL;
        if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) {
                             name);
        }
  
-       namelen = strlen(name);
-       lock_name = xmalloc(namelen + 10);
-       memcpy(lock_name, name, namelen);
-       memcpy(lock_name + namelen, ".lock", 6);
        strcpy(new_hex, sha1_to_hex(new_sha1));
-       old_hex = sha1_to_hex(old_sha1);
+       strcpy(old_hex, sha1_to_hex(old_sha1));
        if (!has_sha1_file(new_sha1)) {
                cmd->error_string = "bad pack";
                return error("unpack should have generated %s, "
                        return error("denying non-fast forward;"
                                     " you should pull first");
        }
-       safe_create_leading_directories(lock_name);
-       newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
-       if (newfd < 0) {
-               cmd->error_string = "can't lock";
-               return error("unable to create %s (%s)",
-                            lock_name, strerror(errno));
-       }
-       /* Write the ref with an ending '\n' */
-       new_hex[40] = '\n';
-       new_hex[41] = 0;
-       written = write(newfd, new_hex, 41);
-       /* Remove the '\n' again */
-       new_hex[40] = 0;
-       close(newfd);
-       if (written != 41) {
-               unlink(lock_name);
-               cmd->error_string = "can't write";
-               return error("unable to write %s", lock_name);
-       }
-       if (verify_old_ref(name, old_hex) < 0) {
-               unlink(lock_name);
-               cmd->error_string = "raced";
-               return error("%s changed during push", name);
-       }
        if (run_update_hook(name, old_hex, new_hex)) {
-               unlink(lock_name);
                cmd->error_string = "hook declined";
                return error("hook declined to update %s", name);
        }
-       else if (rename(lock_name, name) < 0) {
-               unlink(lock_name);
-               cmd->error_string = "can't rename";
-               return error("unable to replace %s", name);
-       }
-       else {
-               fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex);
-               return 0;
+       lock = lock_any_ref_for_update(name, old_sha1);
+       if (!lock) {
+               cmd->error_string = "failed to lock";
+               return error("failed to lock %s", name);
        }
+       write_ref_sha1(lock, new_sha1, "push");
+       fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex);
+       return 0;
  }
  
  static char update_post_hook[] = "hooks/post-update";
@@@ -273,10 -227,11 +227,10 @@@ static void read_head_info(void
        }
  }
  
 -static const char *unpack(int *error_code)
 +static const char *unpack(void)
  {
        int code = run_command_v_opt(1, unpacker, RUN_GIT_CMD);
  
 -      *error_code = 0;
        switch (code) {
        case 0:
                return NULL;
        case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
                return "unpacker died strangely";
        default:
 -              *error_code = -code;
                return "unpacker exited with error code";
        }
  }
@@@ -333,9 -289,12 +287,12 @@@ int main(int argc, char **argv
        if (!dir)
                usage(receive_pack_usage);
  
-       if(!enter_repo(dir, 0))
+       if (!enter_repo(dir, 0))
                die("'%s': unable to chdir or not a git archive", dir);
  
+       setup_ident();
+       git_config(receive_pack_config);
        write_head_info();
  
        /* EOF */
  
        read_head_info();
        if (commands) {
 -              int code;
 -              const char *unpack_status = unpack(&code);
 +              const char *unpack_status = unpack();
                if (!unpack_status)
                        execute_commands();
                if (report_status)
diff --combined sha1_file.c
index 5e6c8b8bbfec7c9b6f60a96d64db0cd6e97904ae,4e5ee1054f6a4f5d1f50c8f93a3f45d6a6b1c72a..2aa944abd0737ed8e6c8ea00e444daa23bda8dc4
@@@ -1203,24 -1203,6 +1203,24 @@@ unsigned long find_pack_entry_one(cons
        return 0;
  }
  
 +static int matches_pack_name(struct packed_git *p, const char *ig)
 +{
 +      const char *last_c, *c;
 +
 +      if (!strcmp(p->pack_name, ig))
 +              return 0;
 +
 +      for (c = p->pack_name, last_c = c; *c;)
 +              if (*c == '/')
 +                      last_c = ++c;
 +              else
 +                      ++c;
 +      if (!strcmp(last_c, ig))
 +              return 0;
 +
 +      return 1;
 +}
 +
  static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
  {
        struct packed_git *p;
                if (ignore_packed) {
                        const char **ig;
                        for (ig = ignore_packed; *ig; ig++)
 -                              if (!strcmp(p->pack_name, *ig))
 +                              if (!matches_pack_name(p, *ig))
                                        break;
                        if (*ig)
                                continue;
@@@ -1417,9 -1399,10 +1417,10 @@@ static int link_temp_to_file(const cha
        dir = strrchr(filename, '/');
        if (dir) {
                *dir = 0;
-               mkdir(filename, 0777);
-               if (adjust_shared_perm(filename))
+               if (!mkdir(filename, 0777) && adjust_shared_perm(filename)) {
+                       *dir = '/';
                        return -2;
+               }
                *dir = '/';
                if (!link(tmpfile, filename))
                        return 0;