Skip to content

Commit b5d97e6

Browse files
author
Junio C Hamano
committed
pack-objects: run rev-list equivalent internally.
Instead of piping the rev-list output from its standard input, you can say: pack-objects --all --unpacked --revs pack and feed the rev parameters you would otherwise give the rev-list on its command line from the standard input. In other words: echo 'master..next' | pack-objects --revs pack and rev-list --objects master..next | pack-objects pack are equivalent. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent c64ed70 commit b5d97e6

File tree

1 file changed

+215
-82
lines changed

1 file changed

+215
-82
lines changed

builtin-pack-objects.c

Lines changed: 215 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
#include "pack.h"
1010
#include "csum-file.h"
1111
#include "tree-walk.h"
12+
#include "diff.h"
13+
#include "revision.h"
14+
#include "list-objects.h"
1215
#include <sys/time.h>
1316
#include <signal.h>
1417

15-
static const char pack_usage[] = "git-pack-objects [-q] [--no-reuse-delta] [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] {--stdout | base-name} < object-list";
18+
static const char pack_usage[] = "git-pack-objects [-q] [--no-reuse-delta] [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] {--stdout | base-name} [--revs [--unpacked | --all]* <ref-list | <object-list]";
1619

1720
struct object_entry {
1821
unsigned char sha1[20];
@@ -1326,89 +1329,14 @@ static int git_pack_config(const char *k, const char *v)
13261329
return git_default_config(k, v);
13271330
}
13281331

1329-
int cmd_pack_objects(int argc, const char **argv, const char *prefix)
1332+
static void read_object_list_from_stdin(void)
13301333
{
1331-
SHA_CTX ctx;
1332-
char line[40 + 1 + PATH_MAX + 2];
1333-
int depth = 10;
1334-
struct object_entry **list;
13351334
int num_preferred_base = 0;
1336-
int i;
1337-
1338-
git_config(git_pack_config);
1339-
1340-
progress = isatty(2);
1341-
for (i = 1; i < argc; i++) {
1342-
const char *arg = argv[i];
1343-
1344-
if (*arg == '-') {
1345-
if (!strcmp("--non-empty", arg)) {
1346-
non_empty = 1;
1347-
continue;
1348-
}
1349-
if (!strcmp("--local", arg)) {
1350-
local = 1;
1351-
continue;
1352-
}
1353-
if (!strcmp("--progress", arg)) {
1354-
progress = 1;
1355-
continue;
1356-
}
1357-
if (!strcmp("--incremental", arg)) {
1358-
incremental = 1;
1359-
continue;
1360-
}
1361-
if (!strncmp("--window=", arg, 9)) {
1362-
char *end;
1363-
window = strtoul(arg+9, &end, 0);
1364-
if (!arg[9] || *end)
1365-
usage(pack_usage);
1366-
continue;
1367-
}
1368-
if (!strncmp("--depth=", arg, 8)) {
1369-
char *end;
1370-
depth = strtoul(arg+8, &end, 0);
1371-
if (!arg[8] || *end)
1372-
usage(pack_usage);
1373-
continue;
1374-
}
1375-
if (!strcmp("--progress", arg)) {
1376-
progress = 1;
1377-
continue;
1378-
}
1379-
if (!strcmp("-q", arg)) {
1380-
progress = 0;
1381-
continue;
1382-
}
1383-
if (!strcmp("--no-reuse-delta", arg)) {
1384-
no_reuse_delta = 1;
1385-
continue;
1386-
}
1387-
if (!strcmp("--stdout", arg)) {
1388-
pack_to_stdout = 1;
1389-
continue;
1390-
}
1391-
usage(pack_usage);
1392-
}
1393-
if (base_name)
1394-
usage(pack_usage);
1395-
base_name = arg;
1396-
}
1397-
1398-
if (pack_to_stdout != !base_name)
1399-
usage(pack_usage);
1400-
1401-
prepare_packed_git();
1402-
1403-
if (progress) {
1404-
fprintf(stderr, "Generating pack...\n");
1405-
setup_progress_signal();
1406-
}
1335+
char line[40 + 1 + PATH_MAX + 2];
1336+
unsigned char sha1[20];
1337+
unsigned hash;
14071338

14081339
for (;;) {
1409-
unsigned char sha1[20];
1410-
unsigned hash;
1411-
14121340
if (!fgets(line, sizeof(line), stdin)) {
14131341
if (feof(stdin))
14141342
break;
@@ -1419,21 +1347,226 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
14191347
clearerr(stdin);
14201348
continue;
14211349
}
1422-
14231350
if (line[0] == '-') {
14241351
if (get_sha1_hex(line+1, sha1))
14251352
die("expected edge sha1, got garbage:\n %s",
1426-
line+1);
1353+
line);
14271354
if (num_preferred_base++ < window)
14281355
add_preferred_base(sha1);
14291356
continue;
14301357
}
14311358
if (get_sha1_hex(line, sha1))
14321359
die("expected sha1, got garbage:\n %s", line);
1360+
14331361
hash = name_hash(line+41);
14341362
add_preferred_base_object(line+41, hash);
14351363
add_object_entry(sha1, hash, 0);
14361364
}
1365+
}
1366+
1367+
/* copied from rev-list but needs to do things slightly differently */
1368+
static void mark_edge_parents_uninteresting(struct commit *commit)
1369+
{
1370+
struct commit_list *parents;
1371+
1372+
for (parents = commit->parents; parents; parents = parents->next) {
1373+
struct commit *parent = parents->item;
1374+
if (!(parent->object.flags & UNINTERESTING))
1375+
continue;
1376+
mark_tree_uninteresting(parent->tree);
1377+
}
1378+
}
1379+
1380+
static void mark_edges_uninteresting(struct commit_list *list)
1381+
{
1382+
for ( ; list; list = list->next) {
1383+
struct commit *commit = list->item;
1384+
1385+
if (commit->object.flags & UNINTERESTING) {
1386+
mark_tree_uninteresting(commit->tree);
1387+
continue;
1388+
}
1389+
mark_edge_parents_uninteresting(commit);
1390+
}
1391+
}
1392+
1393+
static void show_commit(struct commit *commit)
1394+
{
1395+
unsigned hash = name_hash("");
1396+
add_object_entry(commit->object.sha1, hash, 0);
1397+
}
1398+
1399+
static void show_object(struct object_array_entry *p)
1400+
{
1401+
unsigned hash = name_hash(p->name);
1402+
add_object_entry(p->item->sha1, hash, 0);
1403+
}
1404+
1405+
static void get_object_list(int unpacked, int all)
1406+
{
1407+
struct rev_info revs;
1408+
char line[1000];
1409+
const char *av[6];
1410+
int ac;
1411+
int flags = 0;
1412+
1413+
av[0] = "pack-objects";
1414+
av[1] = "--objects";
1415+
ac = 2;
1416+
if (unpacked)
1417+
av[ac++] = "--unpacked";
1418+
if (all)
1419+
av[ac++] = "--all";
1420+
av[ac++] = "--stdin";
1421+
av[ac] = NULL;
1422+
1423+
init_revisions(&revs, NULL);
1424+
save_commit_buffer = 0;
1425+
track_object_refs = 0;
1426+
setup_revisions(ac, av, &revs, NULL);
1427+
1428+
/* make sure we did not get pathspecs */
1429+
if (revs.prune_data)
1430+
die("pathspec given");
1431+
1432+
while (fgets(line, sizeof(line), stdin) != NULL) {
1433+
int len = strlen(line);
1434+
if (line[len - 1] == '\n')
1435+
line[--len] = 0;
1436+
if (!len)
1437+
break;
1438+
if (*line == '-') {
1439+
if (!strcmp(line, "--not")) {
1440+
flags ^= UNINTERESTING;
1441+
continue;
1442+
}
1443+
die("not a rev '%s'", line);
1444+
}
1445+
if (handle_revision_arg(line, &revs, flags, 1))
1446+
die("bad revision '%s'", line);
1447+
}
1448+
1449+
prepare_revision_walk(&revs);
1450+
mark_edges_uninteresting(revs.commits);
1451+
1452+
traverse_commit_list(&revs, show_commit, show_object);
1453+
}
1454+
1455+
int cmd_pack_objects(int argc, const char **argv, const char *prefix)
1456+
{
1457+
SHA_CTX ctx;
1458+
int depth = 10;
1459+
struct object_entry **list;
1460+
int use_internal_rev_list = 0;
1461+
int unpacked = 0;
1462+
int all = 0;
1463+
int i;
1464+
1465+
git_config(git_pack_config);
1466+
1467+
progress = isatty(2);
1468+
for (i = 1; i < argc; i++) {
1469+
const char *arg = argv[i];
1470+
1471+
if (*arg != '-')
1472+
break;
1473+
1474+
if (!strcmp("--non-empty", arg)) {
1475+
non_empty = 1;
1476+
continue;
1477+
}
1478+
if (!strcmp("--local", arg)) {
1479+
local = 1;
1480+
continue;
1481+
}
1482+
if (!strcmp("--progress", arg)) {
1483+
progress = 1;
1484+
continue;
1485+
}
1486+
if (!strcmp("--incremental", arg)) {
1487+
incremental = 1;
1488+
continue;
1489+
}
1490+
if (!strncmp("--window=", arg, 9)) {
1491+
char *end;
1492+
window = strtoul(arg+9, &end, 0);
1493+
if (!arg[9] || *end)
1494+
usage(pack_usage);
1495+
continue;
1496+
}
1497+
if (!strncmp("--depth=", arg, 8)) {
1498+
char *end;
1499+
depth = strtoul(arg+8, &end, 0);
1500+
if (!arg[8] || *end)
1501+
usage(pack_usage);
1502+
continue;
1503+
}
1504+
if (!strcmp("--progress", arg)) {
1505+
progress = 1;
1506+
continue;
1507+
}
1508+
if (!strcmp("-q", arg)) {
1509+
progress = 0;
1510+
continue;
1511+
}
1512+
if (!strcmp("--no-reuse-delta", arg)) {
1513+
no_reuse_delta = 1;
1514+
continue;
1515+
}
1516+
if (!strcmp("--stdout", arg)) {
1517+
pack_to_stdout = 1;
1518+
continue;
1519+
}
1520+
if (!strcmp("--revs", arg)) {
1521+
use_internal_rev_list = 1;
1522+
continue;
1523+
}
1524+
if (!strcmp("--unpacked", arg)) {
1525+
unpacked = 1;
1526+
continue;
1527+
}
1528+
if (!strcmp("--all", arg)) {
1529+
all = 1;
1530+
continue;
1531+
}
1532+
usage(pack_usage);
1533+
}
1534+
1535+
/* Traditionally "pack-objects [options] base extra" failed;
1536+
* we would however want to take refs parameter that would
1537+
* have been given to upstream rev-list ourselves, which means
1538+
* we somehow want to say what the base name is. So the
1539+
* syntax would be:
1540+
*
1541+
* pack-objects [options] base <refs...>
1542+
*
1543+
* in other words, we would treat the first non-option as the
1544+
* base_name and send everything else to the internal revision
1545+
* walker.
1546+
*/
1547+
1548+
if (!pack_to_stdout)
1549+
base_name = argv[i++];
1550+
1551+
if (pack_to_stdout != !base_name)
1552+
usage(pack_usage);
1553+
1554+
/* --unpacked and --all makes sense only with --revs */
1555+
if (!use_internal_rev_list && (unpacked || all))
1556+
usage(pack_usage);
1557+
1558+
prepare_packed_git();
1559+
1560+
if (progress) {
1561+
fprintf(stderr, "Generating pack...\n");
1562+
setup_progress_signal();
1563+
}
1564+
1565+
if (!use_internal_rev_list)
1566+
read_object_list_from_stdin();
1567+
else
1568+
get_object_list(unpacked, all);
1569+
14371570
if (progress)
14381571
fprintf(stderr, "Done counting %d objects.\n", nr_objects);
14391572
sorted_by_sha = create_final_object_list();

0 commit comments

Comments
 (0)