~ubuntu-branches/ubuntu/intrepid/git-core/intrepid-updates

« back to all changes in this revision

Viewing changes to builtin-prune.c

  • Committer: Package Import Robot
  • Author(s): Gerrit Pape
  • Date: 2007-04-22 13:31:05 UTC
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: package-import@ubuntu.com-20070422133105-xg8fnm18r2cxcbg1
Tags: upstream-1.5.1.2
ImportĀ upstreamĀ versionĀ 1.5.1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "cache.h"
2
 
#include "refs.h"
3
 
#include "tag.h"
4
2
#include "commit.h"
5
 
#include "tree.h"
6
 
#include "blob.h"
7
 
#include "tree-walk.h"
8
3
#include "diff.h"
9
4
#include "revision.h"
10
5
#include "builtin.h"
11
 
#include "cache-tree.h"
 
6
#include "reachable.h"
12
7
 
13
8
static const char prune_usage[] = "git-prune [-n]";
14
9
static int show_only;
15
 
static struct rev_info revs;
16
10
 
17
11
static int prune_object(char *path, const char *filename, const unsigned char *sha1)
18
12
{
19
13
        if (show_only) {
20
 
                printf("would prune %s/%s\n", path, filename);
21
 
                return 0;
22
 
        }
23
 
        unlink(mkpath("%s/%s", path, filename));
24
 
        rmdir(path);
 
14
                enum object_type type = sha1_object_info(sha1, NULL);
 
15
                printf("%s %s\n", sha1_to_hex(sha1),
 
16
                       (type > 0) ? typename(type) : "unknown");
 
17
        } else
 
18
                unlink(mkpath("%s/%s", path, filename));
25
19
        return 0;
26
20
}
27
21
 
64
58
                }
65
59
                fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
66
60
        }
 
61
        if (!show_only)
 
62
                rmdir(path);
67
63
        closedir(dir);
68
64
        return 0;
69
65
}
78
74
        }
79
75
}
80
76
 
81
 
static void process_blob(struct blob *blob,
82
 
                         struct object_array *p,
83
 
                         struct name_path *path,
84
 
                         const char *name)
85
 
{
86
 
        struct object *obj = &blob->object;
87
 
 
88
 
        if (obj->flags & SEEN)
89
 
                return;
90
 
        obj->flags |= SEEN;
91
 
        /* Nothing to do, really .. The blob lookup was the important part */
92
 
}
93
 
 
94
 
static void process_tree(struct tree *tree,
95
 
                         struct object_array *p,
96
 
                         struct name_path *path,
97
 
                         const char *name)
98
 
{
99
 
        struct object *obj = &tree->object;
100
 
        struct tree_desc desc;
101
 
        struct name_entry entry;
102
 
        struct name_path me;
103
 
 
104
 
        if (obj->flags & SEEN)
105
 
                return;
106
 
        obj->flags |= SEEN;
107
 
        if (parse_tree(tree) < 0)
108
 
                die("bad tree object %s", sha1_to_hex(obj->sha1));
109
 
        name = xstrdup(name);
110
 
        add_object(obj, p, path, name);
111
 
        me.up = path;
112
 
        me.elem = name;
113
 
        me.elem_len = strlen(name);
114
 
 
115
 
        desc.buf = tree->buffer;
116
 
        desc.size = tree->size;
117
 
 
118
 
        while (tree_entry(&desc, &entry)) {
119
 
                if (S_ISDIR(entry.mode))
120
 
                        process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
121
 
                else
122
 
                        process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
123
 
        }
124
 
        free(tree->buffer);
125
 
        tree->buffer = NULL;
126
 
}
127
 
 
128
 
static void process_tag(struct tag *tag, struct object_array *p, const char *name)
129
 
{
130
 
        struct object *obj = &tag->object;
131
 
        struct name_path me;
132
 
 
133
 
        if (obj->flags & SEEN)
134
 
                return;
135
 
        obj->flags |= SEEN;
136
 
 
137
 
        me.up = NULL;
138
 
        me.elem = "tag:/";
139
 
        me.elem_len = 5;
140
 
 
141
 
        if (parse_tag(tag) < 0)
142
 
                die("bad tag object %s", sha1_to_hex(obj->sha1));
143
 
        add_object(tag->tagged, p, NULL, name);
144
 
}
145
 
 
146
 
static void walk_commit_list(struct rev_info *revs)
147
 
{
148
 
        int i;
149
 
        struct commit *commit;
150
 
        struct object_array objects = { 0, 0, NULL };
151
 
 
152
 
        /* Walk all commits, process their trees */
153
 
        while ((commit = get_revision(revs)) != NULL)
154
 
                process_tree(commit->tree, &objects, NULL, "");
155
 
 
156
 
        /* Then walk all the pending objects, recursively processing them too */
157
 
        for (i = 0; i < revs->pending.nr; i++) {
158
 
                struct object_array_entry *pending = revs->pending.objects + i;
159
 
                struct object *obj = pending->item;
160
 
                const char *name = pending->name;
161
 
                if (obj->type == OBJ_TAG) {
162
 
                        process_tag((struct tag *) obj, &objects, name);
163
 
                        continue;
164
 
                }
165
 
                if (obj->type == OBJ_TREE) {
166
 
                        process_tree((struct tree *)obj, &objects, NULL, name);
167
 
                        continue;
168
 
                }
169
 
                if (obj->type == OBJ_BLOB) {
170
 
                        process_blob((struct blob *)obj, &objects, NULL, name);
171
 
                        continue;
172
 
                }
173
 
                die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
174
 
        }
175
 
}
176
 
 
177
 
static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
178
 
{
179
 
        struct object *object = parse_object(sha1);
180
 
        if (!object)
181
 
                die("bad object ref: %s:%s", path, sha1_to_hex(sha1));
182
 
        add_pending_object(&revs, object, "");
183
 
        return 0;
184
 
}
185
 
 
186
 
static void add_one_tree(const unsigned char *sha1)
187
 
{
188
 
        struct tree *tree = lookup_tree(sha1);
189
 
        add_pending_object(&revs, &tree->object, "");
190
 
}
191
 
 
192
 
static void add_cache_tree(struct cache_tree *it)
193
 
{
194
 
        int i;
195
 
 
196
 
        if (it->entry_count >= 0)
197
 
                add_one_tree(it->sha1);
198
 
        for (i = 0; i < it->subtree_nr; i++)
199
 
                add_cache_tree(it->down[i]->cache_tree);
200
 
}
201
 
 
202
 
static void add_cache_refs(void)
203
 
{
204
 
        int i;
205
 
 
206
 
        read_cache();
207
 
        for (i = 0; i < active_nr; i++) {
208
 
                lookup_blob(active_cache[i]->sha1);
209
 
                /*
210
 
                 * We could add the blobs to the pending list, but quite
211
 
                 * frankly, we don't care. Once we've looked them up, and
212
 
                 * added them as objects, we've really done everything
213
 
                 * there is to do for a blob
214
 
                 */
215
 
        }
216
 
        if (active_cache_tree)
217
 
                add_cache_tree(active_cache_tree);
218
 
}
219
 
 
220
77
int cmd_prune(int argc, const char **argv, const char *prefix)
221
78
{
222
79
        int i;
 
80
        struct rev_info revs;
223
81
 
224
82
        for (i = 1; i < argc; i++) {
225
83
                const char *arg = argv[i];
230
88
                usage(prune_usage);
231
89
        }
232
90
 
233
 
        /*
234
 
         * Set up revision parsing, and mark us as being interested
235
 
         * in all object types, not just commits.
236
 
         */
 
91
        save_commit_buffer = 0;
237
92
        init_revisions(&revs, prefix);
238
 
        revs.tag_objects = 1;
239
 
        revs.blob_objects = 1;
240
 
        revs.tree_objects = 1;
241
 
 
242
 
        /* Add all external refs */
243
 
        for_each_ref(add_one_ref, NULL);
244
 
 
245
 
        /* Add all refs from the index file */
246
 
        add_cache_refs();
247
 
 
248
 
        /*
249
 
         * Set up the revision walk - this will move all commits
250
 
         * from the pending list to the commit walking list.
251
 
         */
252
 
        prepare_revision_walk(&revs);
253
 
 
254
 
        walk_commit_list(&revs);
 
93
        mark_reachable_objects(&revs, 1);
255
94
 
256
95
        prune_object_dir(get_object_directory());
257
96