mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
cli: add index-pack command
This commit is contained in:
@@ -30,5 +30,6 @@ extern int cmd_clone(int argc, char **argv);
|
||||
extern int cmd_config(int argc, char **argv);
|
||||
extern int cmd_hash_object(int argc, char **argv);
|
||||
extern int cmd_help(int argc, char **argv);
|
||||
extern int cmd_index_pack(int argc, char **argv);
|
||||
|
||||
#endif /* CLI_cmd_h__ */
|
||||
|
||||
114
src/cli/cmd_index_pack.c
Normal file
114
src/cli/cmd_index_pack.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include <git2.h>
|
||||
#include "common.h"
|
||||
#include "cmd.h"
|
||||
#include "progress.h"
|
||||
|
||||
#define COMMAND_NAME "index-pack"
|
||||
|
||||
#define BUFFER_SIZE (1024 * 1024)
|
||||
|
||||
static int show_help, verbose, read_stdin;
|
||||
static char *filename;
|
||||
static cli_progress progress = CLI_PROGRESS_INIT;
|
||||
|
||||
static const cli_opt_spec opts[] = {
|
||||
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
|
||||
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
|
||||
"display help about the " COMMAND_NAME " command" },
|
||||
|
||||
{ CLI_OPT_TYPE_SWITCH, "verbose", 'v', &verbose, 1,
|
||||
CLI_OPT_USAGE_DEFAULT, NULL, "display progress output" },
|
||||
|
||||
{ CLI_OPT_TYPE_LITERAL },
|
||||
|
||||
{ CLI_OPT_TYPE_SWITCH, "stdin", 0, &read_stdin, 1,
|
||||
CLI_OPT_USAGE_REQUIRED, NULL, "read from stdin" },
|
||||
{ CLI_OPT_TYPE_ARG, "pack-file", 0, &filename, 0,
|
||||
CLI_OPT_USAGE_CHOICE, "pack-file", "packfile path" },
|
||||
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts);
|
||||
printf("\n");
|
||||
|
||||
printf("Indexes a packfile and writes the index to disk.\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Options:\n");
|
||||
|
||||
cli_opt_help_fprint(stdout, opts);
|
||||
}
|
||||
|
||||
int cmd_index_pack(int argc, char **argv)
|
||||
{
|
||||
cli_opt invalid_opt;
|
||||
git_indexer *idx = NULL;
|
||||
git_indexer_options idx_opts = GIT_INDEXER_OPTIONS_INIT;
|
||||
git_indexer_progress stats = {0};
|
||||
char buf[BUFFER_SIZE];
|
||||
ssize_t read_len;
|
||||
int fd, ret;
|
||||
|
||||
if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU))
|
||||
return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt);
|
||||
|
||||
if (show_help) {
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
idx_opts.progress_cb = cli_progress_indexer;
|
||||
idx_opts.progress_cb_payload = &progress;
|
||||
}
|
||||
|
||||
if (read_stdin) {
|
||||
fd = fileno(stdin);
|
||||
} else if ((fd = p_open(filename, O_RDONLY)) < 0) {
|
||||
ret = cli_error_git();
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef GIT_EXPERIMENTAL_SHA256
|
||||
ret = git_indexer_new(&idx, ".", GIT_OID_SHA1, &idx_opts);
|
||||
#else
|
||||
ret = git_indexer_new(&idx, ".", 0, NULL, &idx_opts);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
ret = cli_error_git();
|
||||
goto done;
|
||||
}
|
||||
|
||||
while ((read_len = p_read(fd, buf, sizeof(buf))) > 0) {
|
||||
if (git_indexer_append(idx, buf, (size_t)read_len, &stats) < 0) {
|
||||
ret = cli_error_git();
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!read_stdin)
|
||||
p_close(fd);
|
||||
|
||||
if (git_indexer_commit(idx, &stats) < 0) {
|
||||
ret = cli_error_git();
|
||||
goto done;
|
||||
}
|
||||
|
||||
cli_progress_finish(&progress);
|
||||
|
||||
done:
|
||||
cli_progress_dispose(&progress);
|
||||
git_indexer_free(idx);
|
||||
return ret;
|
||||
}
|
||||
@@ -37,6 +37,7 @@ const cli_cmd_spec cli_cmds[] = {
|
||||
{ "config", cmd_config, "View or set configuration values " },
|
||||
{ "hash-object", cmd_hash_object, "Hash a raw object and product its object ID" },
|
||||
{ "help", cmd_help, "Display help information" },
|
||||
{ "index-pack", cmd_index_pack, "Create an index for a packfile" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -242,7 +242,21 @@ static int fetch_receiving(
|
||||
done ? ", done." : "");
|
||||
}
|
||||
|
||||
static int fetch_resolving(
|
||||
static int indexer_indexing(
|
||||
cli_progress *progress,
|
||||
const git_indexer_progress *stats)
|
||||
{
|
||||
bool done = (stats->received_objects == stats->total_objects);
|
||||
|
||||
return progress_printf(progress, false,
|
||||
"Indexing objects: %3d%% (%d/%d)%s\r",
|
||||
percent(stats->received_objects, stats->total_objects),
|
||||
stats->received_objects,
|
||||
stats->total_objects,
|
||||
done ? ", done." : "");
|
||||
}
|
||||
|
||||
static int indexer_resolving(
|
||||
cli_progress *progress,
|
||||
const git_indexer_progress *stats)
|
||||
{
|
||||
@@ -283,7 +297,42 @@ int cli_progress_fetch_transfer(const git_indexer_progress *stats, void *payload
|
||||
/* fall through */
|
||||
|
||||
case CLI_PROGRESS_RESOLVING:
|
||||
error = fetch_resolving(progress, stats);
|
||||
error = indexer_resolving(progress, stats);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* should not be reached */
|
||||
GIT_ASSERT(!"unexpected progress state");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int cli_progress_indexer(
|
||||
const git_indexer_progress *stats,
|
||||
void *payload)
|
||||
{
|
||||
cli_progress *progress = (cli_progress *)payload;
|
||||
int error = 0;
|
||||
|
||||
switch (progress->action) {
|
||||
case CLI_PROGRESS_NONE:
|
||||
progress->action = CLI_PROGRESS_INDEXING;
|
||||
/* fall through */
|
||||
|
||||
case CLI_PROGRESS_INDEXING:
|
||||
if ((error = indexer_indexing(progress, stats)) < 0)
|
||||
break;
|
||||
|
||||
if (stats->indexed_deltas == stats->total_deltas)
|
||||
break;
|
||||
|
||||
progress_complete(progress);
|
||||
progress->action = CLI_PROGRESS_RESOLVING;
|
||||
/* fall through */
|
||||
|
||||
case CLI_PROGRESS_RESOLVING:
|
||||
error = indexer_resolving(progress, stats);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
typedef enum {
|
||||
CLI_PROGRESS_NONE,
|
||||
CLI_PROGRESS_RECEIVING,
|
||||
CLI_PROGRESS_INDEXING,
|
||||
CLI_PROGRESS_RESOLVING,
|
||||
CLI_PROGRESS_CHECKING_OUT
|
||||
} cli_progress_t;
|
||||
@@ -74,6 +75,17 @@ extern int cli_progress_fetch_transfer(
|
||||
const git_indexer_progress *stats,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Prints indexer progress to the console. Suitable for a
|
||||
* `progress_cb` callback for `git_indexer_options`.
|
||||
*
|
||||
* @param stats The indexer stats
|
||||
* @param payload A pointer to the cli_progress
|
||||
*/
|
||||
extern int cli_progress_indexer(
|
||||
const git_indexer_progress *stats,
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* Prints checkout progress to the console. Suitable for a
|
||||
* `progress_cb` callback for `git_checkout_options`.
|
||||
|
||||
Reference in New Issue
Block a user