sha1_file: export `git_open_noatime`
[gitweb.git] / shallow.c
index cbe2526d8c2b2643957eea2729a16269a7a74fab..cdf37d694de175adcce10fa2e2a79c6579603b0b 100644 (file)
--- a/shallow.c
+++ b/shallow.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "commit.h"
 #include "tag.h"
+#include "pkt-line.h"
 
 static int is_shallow = -1;
 static struct stat shallow_stat;
@@ -110,17 +111,12 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
                                        continue;
                                *pointer = cur_depth;
                        }
-                       if (cur_depth < depth) {
-                               if (p->next)
-                                       add_object_array(&p->item->object,
-                                                       NULL, &stack);
-                               else {
-                                       commit = p->item;
-                                       cur_depth = *(int *)commit->util;
-                               }
-                       } else {
-                               commit_list_insert(p->item, &result);
-                               p->item->object.flags |= shallow_flag;
+                       if (p->next)
+                               add_object_array(&p->item->object,
+                                               NULL, &stack);
+                       else {
+                               commit = p->item;
+                               cur_depth = *(int *)commit->util;
                        }
                }
        }
@@ -146,3 +142,81 @@ void check_shallow_file_for_update(void)
                   )
                die("shallow file was changed during fetch");
 }
+
+struct write_shallow_data {
+       struct strbuf *out;
+       int use_pack_protocol;
+       int count;
+};
+
+static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
+{
+       struct write_shallow_data *data = cb_data;
+       const char *hex = sha1_to_hex(graft->sha1);
+       if (graft->nr_parent != -1)
+               return 0;
+       data->count++;
+       if (data->use_pack_protocol)
+               packet_buf_write(data->out, "shallow %s", hex);
+       else {
+               strbuf_addstr(data->out, hex);
+               strbuf_addch(data->out, '\n');
+       }
+       return 0;
+}
+
+int write_shallow_commits(struct strbuf *out, int use_pack_protocol)
+{
+       struct write_shallow_data data;
+       data.out = out;
+       data.use_pack_protocol = use_pack_protocol;
+       data.count = 0;
+       for_each_commit_graft(write_one_shallow, &data);
+       return data.count;
+}
+
+char *setup_temporary_shallow(void)
+{
+       struct strbuf sb = STRBUF_INIT;
+       int fd;
+
+       if (write_shallow_commits(&sb, 0)) {
+               struct strbuf path = STRBUF_INIT;
+               strbuf_addstr(&path, git_path("shallow_XXXXXX"));
+               fd = xmkstemp(path.buf);
+               if (write_in_full(fd, sb.buf, sb.len) != sb.len)
+                       die_errno("failed to write to %s",
+                                 path.buf);
+               close(fd);
+               strbuf_release(&sb);
+               return strbuf_detach(&path, NULL);
+       }
+       /*
+        * is_repository_shallow() sees empty string as "no shallow
+        * file".
+        */
+       return xstrdup("");
+}
+
+void setup_alternate_shallow(struct lock_file *shallow_lock,
+                            const char **alternate_shallow_file)
+{
+       struct strbuf sb = STRBUF_INIT;
+       int fd;
+
+       check_shallow_file_for_update();
+       fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
+                                      LOCK_DIE_ON_ERROR);
+       if (write_shallow_commits(&sb, 0)) {
+               if (write_in_full(fd, sb.buf, sb.len) != sb.len)
+                       die_errno("failed to write to %s",
+                                 shallow_lock->filename);
+               *alternate_shallow_file = shallow_lock->filename;
+       } else
+               /*
+                * is_repository_shallow() sees empty string as "no
+                * shallow file".
+                */
+               *alternate_shallow_file = "";
+       strbuf_release(&sb);
+}