Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 174 lines (160 sloc) 4.609 kb
c64ed70 Separate object listing routines out of rev-list
Junio C Hamano authored
1 #include "cache.h"
2 #include "tag.h"
3 #include "commit.h"
4 #include "tree.h"
5 #include "blob.h"
6 #include "diff.h"
7 #include "tree-walk.h"
8 #include "revision.h"
9 #include "list-objects.h"
10
11 static void process_blob(struct rev_info *revs,
12 struct blob *blob,
13 struct object_array *p,
14 struct name_path *path,
15 const char *name)
16 {
17 struct object *obj = &blob->object;
18
19 if (!revs->blob_objects)
20 return;
21 if (obj->flags & (UNINTERESTING | SEEN))
22 return;
23 obj->flags |= SEEN;
24 name = xstrdup(name);
25 add_object(obj, p, path, name);
26 }
27
6e2f441 @torvalds Teach git list-objects logic to not follow gitlinks
torvalds authored
28 /*
29 * Processing a gitlink entry currently does nothing, since
30 * we do not recurse into the subproject.
31 *
32 * We *could* eventually add a flag that actually does that,
33 * which would involve:
34 * - is the subproject actually checked out?
35 * - if so, see if the subproject has already been added
36 * to the alternates list, and add it if not.
37 * - process the commit (or tag) the gitlink points to
38 * recursively.
39 *
40 * However, it's unclear whether there is really ever any
41 * reason to see superprojects and subprojects as such a
42 * "unified" object pool (potentially resulting in a totally
43 * humongous pack - avoiding which was the whole point of
44 * having gitlinks in the first place!).
45 *
46 * So for now, there is just a note that we *could* follow
47 * the link, and how to do it. Whether it necessarily makes
48 * any sense what-so-ever to ever do that is another issue.
49 */
50 static void process_gitlink(struct rev_info *revs,
51 const unsigned char *sha1,
52 struct object_array *p,
53 struct name_path *path,
54 const char *name)
55 {
56 /* Nothing to do */
57 }
58
c64ed70 Separate object listing routines out of rev-list
Junio C Hamano authored
59 static void process_tree(struct rev_info *revs,
60 struct tree *tree,
61 struct object_array *p,
62 struct name_path *path,
63 const char *name)
64 {
65 struct object *obj = &tree->object;
66 struct tree_desc desc;
67 struct name_entry entry;
68 struct name_path me;
69
70 if (!revs->tree_objects)
71 return;
72 if (obj->flags & (UNINTERESTING | SEEN))
73 return;
74 if (parse_tree(tree) < 0)
75 die("bad tree object %s", sha1_to_hex(obj->sha1));
76 obj->flags |= SEEN;
77 name = xstrdup(name);
78 add_object(obj, p, path, name);
79 me.up = path;
80 me.elem = name;
81 me.elem_len = strlen(name);
82
6fda5e5 @torvalds Initialize tree descriptors with a helper function rather than by hand.
torvalds authored
83 init_tree_desc(&desc, tree->buffer, tree->size);
c64ed70 Separate object listing routines out of rev-list
Junio C Hamano authored
84
85 while (tree_entry(&desc, &entry)) {
86 if (S_ISDIR(entry.mode))
87 process_tree(revs,
88 lookup_tree(entry.sha1),
89 p, &me, entry.path);
302b928 @tali rename dirlink to gitlink.
tali authored
90 else if (S_ISGITLINK(entry.mode))
6e2f441 @torvalds Teach git list-objects logic to not follow gitlinks
torvalds authored
91 process_gitlink(revs, entry.sha1,
92 p, &me, entry.path);
c64ed70 Separate object listing routines out of rev-list
Junio C Hamano authored
93 else
94 process_blob(revs,
95 lookup_blob(entry.sha1),
96 p, &me, entry.path);
97 }
98 free(tree->buffer);
99 tree->buffer = NULL;
100 }
101
8d1d8f8 pack-objects: further work on internal rev-list logic.
Junio C Hamano authored
102 static void mark_edge_parents_uninteresting(struct commit *commit,
103 struct rev_info *revs,
104 show_edge_fn show_edge)
105 {
106 struct commit_list *parents;
107
108 for (parents = commit->parents; parents; parents = parents->next) {
109 struct commit *parent = parents->item;
110 if (!(parent->object.flags & UNINTERESTING))
111 continue;
112 mark_tree_uninteresting(parent->tree);
113 if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
114 parent->object.flags |= SHOWN;
115 show_edge(parent);
116 }
117 }
118 }
119
120 void mark_edges_uninteresting(struct commit_list *list,
121 struct rev_info *revs,
122 show_edge_fn show_edge)
123 {
124 for ( ; list; list = list->next) {
125 struct commit *commit = list->item;
126
127 if (commit->object.flags & UNINTERESTING) {
128 mark_tree_uninteresting(commit->tree);
129 continue;
130 }
131 mark_edge_parents_uninteresting(commit, revs, show_edge);
132 }
133 }
134
c64ed70 Separate object listing routines out of rev-list
Junio C Hamano authored
135 void traverse_commit_list(struct rev_info *revs,
136 void (*show_commit)(struct commit *),
137 void (*show_object)(struct object_array_entry *))
138 {
139 int i;
140 struct commit *commit;
141 struct object_array objects = { 0, 0, NULL };
142
143 while ((commit = get_revision(revs)) != NULL) {
144 process_tree(revs, commit->tree, &objects, NULL, "");
145 show_commit(commit);
146 }
147 for (i = 0; i < revs->pending.nr; i++) {
148 struct object_array_entry *pending = revs->pending.objects + i;
149 struct object *obj = pending->item;
150 const char *name = pending->name;
151 if (obj->flags & (UNINTERESTING | SEEN))
152 continue;
153 if (obj->type == OBJ_TAG) {
154 obj->flags |= SEEN;
155 add_object_array(obj, name, &objects);
156 continue;
157 }
158 if (obj->type == OBJ_TREE) {
159 process_tree(revs, (struct tree *)obj, &objects,
160 NULL, name);
161 continue;
162 }
163 if (obj->type == OBJ_BLOB) {
164 process_blob(revs, (struct blob *)obj, &objects,
165 NULL, name);
166 continue;
167 }
168 die("unknown pending object %s (%s)",
169 sha1_to_hex(obj->sha1), name);
170 }
171 for (i = 0; i < objects.nr; i++)
172 show_object(&objects.objects[i]);
173 }
Something went wrong with that request. Please try again.