Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
b8771227
Commit
b8771227
authored
Nov 28, 2021
by
Edward Thomson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cli: add `cat-file` command
Introduce a simple command that emulates `git cat-file`.
parent
f8e7d8fd
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
207 additions
and
1 deletions
+207
-1
src/cli/cmd.h
+1
-0
src/cli/cmd_cat_file.c
+204
-0
src/cli/main.c
+2
-1
No files found.
src/cli/cmd.h
View file @
b8771227
...
@@ -25,6 +25,7 @@ extern const cli_cmd_spec cli_cmds[];
...
@@ -25,6 +25,7 @@ extern const cli_cmd_spec cli_cmds[];
extern
const
cli_cmd_spec
*
cli_cmd_spec_byname
(
const
char
*
name
);
extern
const
cli_cmd_spec
*
cli_cmd_spec_byname
(
const
char
*
name
);
/* Commands */
/* Commands */
extern
int
cmd_cat_file
(
int
argc
,
char
**
argv
);
extern
int
cmd_help
(
int
argc
,
char
**
argv
);
extern
int
cmd_help
(
int
argc
,
char
**
argv
);
#endif
/* CLI_cmd_h__ */
#endif
/* CLI_cmd_h__ */
src/cli/cmd_cat_file.c
0 → 100644
View file @
b8771227
/*
* 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 "cli.h"
#include "cmd.h"
#define COMMAND_NAME "cat-file"
typedef
enum
{
DISPLAY_CONTENT
=
0
,
DISPLAY_EXISTS
,
DISPLAY_PRETTY
,
DISPLAY_SIZE
,
DISPLAY_TYPE
}
display_t
;
static
int
show_help
;
static
int
display
=
DISPLAY_CONTENT
;
static
char
*
type_name
,
*
object_spec
;
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
,
NULL
,
't'
,
&
display
,
DISPLAY_TYPE
,
CLI_OPT_USAGE_REQUIRED
,
NULL
,
"display the type of the object"
},
{
CLI_OPT_TYPE_SWITCH
,
NULL
,
's'
,
&
display
,
DISPLAY_SIZE
,
CLI_OPT_USAGE_CHOICE
,
NULL
,
"display the size of the object"
},
{
CLI_OPT_TYPE_SWITCH
,
NULL
,
'e'
,
&
display
,
DISPLAY_EXISTS
,
CLI_OPT_USAGE_CHOICE
,
NULL
,
"displays nothing unless the object is corrupt"
},
{
CLI_OPT_TYPE_SWITCH
,
NULL
,
'p'
,
&
display
,
DISPLAY_PRETTY
,
CLI_OPT_USAGE_CHOICE
,
NULL
,
"pretty-print the object"
},
{
CLI_OPT_TYPE_ARG
,
"type"
,
0
,
&
type_name
,
0
,
CLI_OPT_USAGE_CHOICE
,
"type"
,
"the type of object to display"
},
{
CLI_OPT_TYPE_ARG
,
"object"
,
0
,
&
object_spec
,
0
,
CLI_OPT_USAGE_REQUIRED
,
"object"
,
"the object to display"
},
{
0
},
};
static
void
print_help
(
void
)
{
cli_opt_usage_fprint
(
stdout
,
PROGRAM_NAME
,
COMMAND_NAME
,
opts
);
printf
(
"
\n
"
);
printf
(
"Display the content for the given object in the repository.
\n
"
);
printf
(
"
\n
"
);
printf
(
"Options:
\n
"
);
cli_opt_help_fprint
(
stdout
,
opts
);
}
static
int
print_odb
(
git_object
*
object
,
display_t
display
)
{
git_odb
*
odb
=
NULL
;
git_odb_object
*
odb_object
=
NULL
;
const
unsigned
char
*
content
;
git_object_size_t
size
;
int
ret
=
0
;
/*
* Our parsed blobs retain the raw content; all other objects are
* parsed into a working representation. To get the raw content,
* we need to do an ODB lookup. (Thankfully, this should be cached
* in-memory from our last call.)
*/
if
(
git_object_type
(
object
)
==
GIT_OBJECT_BLOB
)
{
content
=
git_blob_rawcontent
((
git_blob
*
)
object
);
size
=
git_blob_rawsize
((
git_blob
*
)
object
);
}
else
{
if
(
git_repository_odb
(
&
odb
,
git_object_owner
(
object
))
<
0
||
git_odb_read
(
&
odb_object
,
odb
,
git_object_id
(
object
))
<
0
)
{
ret
=
cli_error_git
();
goto
done
;
}
content
=
git_odb_object_data
(
odb_object
);
size
=
git_odb_object_size
(
odb_object
);
}
switch
(
display
)
{
case
DISPLAY_SIZE
:
if
(
printf
(
"%"
PRIu64
"
\n
"
,
size
)
<
0
)
ret
=
cli_error_os
();
break
;
case
DISPLAY_CONTENT
:
if
(
p_write
(
fileno
(
stdout
),
content
,
(
size_t
)
size
)
<
0
)
ret
=
cli_error_os
();
break
;
default:
GIT_ASSERT
(
0
);
}
done:
git_odb_object_free
(
odb_object
);
git_odb_free
(
odb
);
return
ret
;
}
static
int
print_type
(
git_object
*
object
)
{
if
(
printf
(
"%s
\n
"
,
git_object_type2string
(
git_object_type
(
object
)))
<
0
)
return
cli_error_os
();
return
0
;
}
static
int
print_pretty
(
git_object
*
object
)
{
const
git_tree_entry
*
entry
;
size_t
i
,
count
;
/*
* Only trees are stored in an unreadable format and benefit from
* pretty-printing.
*/
if
(
git_object_type
(
object
)
!=
GIT_OBJECT_TREE
)
return
print_odb
(
object
,
DISPLAY_CONTENT
);
for
(
i
=
0
,
count
=
git_tree_entrycount
((
git_tree
*
)
object
);
i
<
count
;
i
++
)
{
entry
=
git_tree_entry_byindex
((
git_tree
*
)
object
,
i
);
if
(
printf
(
"%06o %s %s
\t
%s
\n
"
,
git_tree_entry_filemode_raw
(
entry
),
git_object_type2string
(
git_tree_entry_type
(
entry
)),
git_oid_tostr_s
(
git_tree_entry_id
(
entry
)),
git_tree_entry_name
(
entry
))
<
0
)
return
cli_error_os
();
}
return
0
;
}
int
cmd_cat_file
(
int
argc
,
char
**
argv
)
{
git_repository
*
repo
=
NULL
;
git_object
*
object
=
NULL
;
git_object_t
type
;
cli_opt
invalid_opt
;
int
giterr
,
ret
=
0
;
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
(
git_repository_open_ext
(
&
repo
,
"."
,
GIT_REPOSITORY_OPEN_FROM_ENV
,
NULL
)
<
0
)
return
cli_error_git
();
if
((
giterr
=
git_revparse_single
(
&
object
,
repo
,
object_spec
))
<
0
)
{
if
(
display
==
DISPLAY_EXISTS
&&
giterr
==
GIT_ENOTFOUND
)
ret
=
1
;
else
ret
=
cli_error_git
();
goto
done
;
}
if
(
type_name
)
{
git_object
*
peeled
;
if
((
type
=
git_object_string2type
(
type_name
))
==
GIT_OBJECT_INVALID
)
{
ret
=
cli_error_usage
(
"invalid object type '%s'"
,
type_name
);
goto
done
;
}
if
(
git_object_peel
(
&
peeled
,
object
,
type
)
<
0
)
{
ret
=
cli_error_git
();
goto
done
;
}
git_object_free
(
object
);
object
=
peeled
;
}
switch
(
display
)
{
case
DISPLAY_EXISTS
:
ret
=
0
;
break
;
case
DISPLAY_TYPE
:
ret
=
print_type
(
object
);
break
;
case
DISPLAY_PRETTY
:
ret
=
print_pretty
(
object
);
break
;
default:
ret
=
print_odb
(
object
,
display
);
break
;
}
done:
git_object_free
(
object
);
git_repository_free
(
repo
);
return
ret
;
}
src/cli/main.c
View file @
b8771227
...
@@ -28,7 +28,8 @@ const cli_opt_spec cli_common_opts[] = {
...
@@ -28,7 +28,8 @@ const cli_opt_spec cli_common_opts[] = {
};
};
const
cli_cmd_spec
cli_cmds
[]
=
{
const
cli_cmd_spec
cli_cmds
[]
=
{
{
"help"
,
cmd_help
,
"Display help information"
},
{
"cat-file"
,
cmd_cat_file
,
"Display an object in the repository"
},
{
"help"
,
cmd_help
,
"Display help information"
},
{
NULL
}
{
NULL
}
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment