| #include "cache.h" | 
 | #include "commit.h" | 
 | #include "tag.h" | 
 |  | 
 | static int is_shallow = -1; | 
 |  | 
 | int register_shallow(const unsigned char *sha1) | 
 | { | 
 | 	struct commit_graft *graft = | 
 | 		xmalloc(sizeof(struct commit_graft)); | 
 | 	struct commit *commit = lookup_commit(sha1); | 
 |  | 
 | 	hashcpy(graft->sha1, sha1); | 
 | 	graft->nr_parent = -1; | 
 | 	if (commit && commit->object.parsed) | 
 | 		commit->parents = NULL; | 
 | 	return register_commit_graft(graft, 0); | 
 | } | 
 |  | 
 | int is_repository_shallow(void) | 
 | { | 
 | 	FILE *fp; | 
 | 	char buf[1024]; | 
 |  | 
 | 	if (is_shallow >= 0) | 
 | 		return is_shallow; | 
 |  | 
 | 	fp = fopen(git_path("shallow"), "r"); | 
 | 	if (!fp) { | 
 | 		is_shallow = 0; | 
 | 		return is_shallow; | 
 | 	} | 
 | 	is_shallow = 1; | 
 |  | 
 | 	while (fgets(buf, sizeof(buf), fp)) { | 
 | 		unsigned char sha1[20]; | 
 | 		if (get_sha1_hex(buf, sha1)) | 
 | 			die("bad shallow line: %s", buf); | 
 | 		register_shallow(sha1); | 
 | 	} | 
 | 	fclose(fp); | 
 | 	return is_shallow; | 
 | } | 
 |  | 
 | struct commit_list *get_shallow_commits(struct object_array *heads, int depth, | 
 | 		int shallow_flag, int not_shallow_flag) | 
 | { | 
 | 	int i = 0, cur_depth = 0; | 
 | 	struct commit_list *result = NULL; | 
 | 	struct object_array stack = {0, 0, NULL}; | 
 | 	struct commit *commit = NULL; | 
 |  | 
 | 	while (commit || i < heads->nr || stack.nr) { | 
 | 		struct commit_list *p; | 
 | 		if (!commit) { | 
 | 			if (i < heads->nr) { | 
 | 				commit = (struct commit *) | 
 | 					deref_tag(heads->objects[i++].item, NULL, 0); | 
 | 				if (!commit || commit->object.type != OBJ_COMMIT) { | 
 | 					commit = NULL; | 
 | 					continue; | 
 | 				} | 
 | 				if (!commit->util) | 
 | 					commit->util = xmalloc(sizeof(int)); | 
 | 				*(int *)commit->util = 0; | 
 | 				cur_depth = 0; | 
 | 			} else { | 
 | 				commit = (struct commit *) | 
 | 					stack.objects[--stack.nr].item; | 
 | 				cur_depth = *(int *)commit->util; | 
 | 			} | 
 | 		} | 
 | 		if (parse_commit(commit)) | 
 | 			die("invalid commit"); | 
 | 		commit->object.flags |= not_shallow_flag; | 
 | 		cur_depth++; | 
 | 		for (p = commit->parents, commit = NULL; p; p = p->next) { | 
 | 			if (!p->item->util) { | 
 | 				int *pointer = xmalloc(sizeof(int)); | 
 | 				p->item->util = pointer; | 
 | 				*pointer =  cur_depth; | 
 | 			} else { | 
 | 				int *pointer = p->item->util; | 
 | 				if (cur_depth >= *pointer) | 
 | 					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; | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } |