2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
14 #define COMMAND_NAME "hash-object"
17 static char *type_name
;
18 static int write_object
, read_stdin
, literally
;
19 static char **filenames
;
21 static const cli_opt_spec opts
[] = {
22 { CLI_OPT_TYPE_SWITCH
, "help", 0, &show_help
, 1,
23 CLI_OPT_USAGE_HIDDEN
| CLI_OPT_USAGE_STOP_PARSING
, NULL
,
24 "display help about the " COMMAND_NAME
" command" },
26 { CLI_OPT_TYPE_VALUE
, NULL
, 't', &type_name
, 0,
27 CLI_OPT_USAGE_DEFAULT
, "type", "the type of object to hash (default: \"blob\")" },
28 { CLI_OPT_TYPE_SWITCH
, NULL
, 'w', &write_object
, 1,
29 CLI_OPT_USAGE_DEFAULT
, NULL
, "write the object to the object database" },
30 { CLI_OPT_TYPE_SWITCH
, "literally", 0, &literally
, 1,
31 CLI_OPT_USAGE_DEFAULT
, NULL
, "do not validate the object contents" },
32 { CLI_OPT_TYPE_SWITCH
, "stdin", 0, &read_stdin
, 1,
33 CLI_OPT_USAGE_REQUIRED
, NULL
, "read content from stdin" },
34 { CLI_OPT_TYPE_ARGS
, "file", 0, &filenames
, 0,
35 CLI_OPT_USAGE_CHOICE
, "file", "the file (or files) to read and hash" },
39 static void print_help(void)
41 cli_opt_usage_fprint(stdout
, PROGRAM_NAME
, COMMAND_NAME
, opts
);
44 printf("Compute the object ID for a given file and optionally write that file\nto the object database.\n");
49 cli_opt_help_fprint(stdout
, opts
);
52 static int hash_buf(git_odb
*odb
, git_str
*buf
, git_object_t type
)
59 if (git_object_rawcontent_is_valid(&valid
, buf
->ptr
, buf
->size
, type
) < 0 || !valid
)
60 return cli_error_git();
64 if (git_odb_write(&oid
, odb
, buf
->ptr
, buf
->size
, type
) < 0)
65 return cli_error_git();
67 if (git_odb_hash(&oid
, buf
->ptr
, buf
->size
, type
) < 0)
68 return cli_error_git();
71 if (printf("%s\n", git_oid_tostr_s(&oid
)) < 0)
72 return cli_error_os();
77 int cmd_hash_object(int argc
, char **argv
)
79 git_repository
*repo
= NULL
;
81 git_str buf
= GIT_STR_INIT
;
83 git_object_t type
= GIT_OBJECT_BLOB
;
87 if (cli_opt_parse(&invalid_opt
, opts
, argv
+ 1, argc
- 1, CLI_OPT_PARSE_GNU
))
88 return cli_opt_usage_error(COMMAND_NAME
, opts
, &invalid_opt
);
95 if (type_name
&& (type
= git_object_string2type(type_name
)) == GIT_OBJECT_INVALID
)
96 return cli_error_usage("invalid object type '%s'", type_name
);
99 (git_repository_open_ext(&repo
, ".", GIT_REPOSITORY_OPEN_FROM_ENV
, NULL
) < 0 ||
100 git_repository_odb(&odb
, repo
) < 0)) {
101 ret
= cli_error_git();
106 * TODO: we're reading blobs, we shouldn't pull them all into main
107 * memory, we should just stream them into the odb instead.
108 * (Or create a `git_odb_writefile` API.)
111 if (git_futils_readbuffer_fd_full(&buf
, fileno(stdin
)) < 0) {
112 ret
= cli_error_git();
116 if ((ret
= hash_buf(odb
, &buf
, type
)) != 0)
119 for (filename
= filenames
; *filename
; filename
++) {
120 if (git_futils_readbuffer(&buf
, *filename
) < 0) {
121 ret
= cli_error_git();
125 if ((ret
= hash_buf(odb
, &buf
, type
)) != 0)
131 git_str_dispose(&buf
);
133 git_repository_free(repo
);