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
cf300bb9
Commit
cf300bb9
authored
Jun 20, 2013
by
Russell Belfer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial implementation of status example
parent
852ded96
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
295 additions
and
1 deletions
+295
-1
examples/Makefile
+1
-1
examples/status.c
+294
-0
No files found.
examples/Makefile
View file @
cf300bb9
...
...
@@ -3,7 +3,7 @@
CC
=
gcc
CFLAGS
=
-g
-I
../include
-I
../src
-Wall
-Wextra
-Wmissing-prototypes
-Wno-missing-field-initializers
LFLAGS
=
-L
../build
-lgit2
-lz
APPS
=
general showindex diff rev-list cat-file
APPS
=
general showindex diff rev-list cat-file
status
all
:
$(APPS)
...
...
examples/status.c
0 → 100644
View file @
cf300bb9
/*
* Copyright (C) 2011-2012 the libgit2 contributors
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
enum
{
FORMAT_DEFAULT
=
0
,
FORMAT_LONG
=
1
,
FORMAT_SHORT
=
2
,
FORMAT_PORCELAIN
=
3
,
};
#define MAX_PATHSPEC 8
/*
* This example demonstrates the use of `git_status_foreach()` to roughly
* simulate the output of running `git status`. It should serve as a simple
* example of how to get basic status information.
*
* This does not have:
* - Robust error handling
* - Any real command line parsing
* - Colorized or paginated output formatting
*
*/
static
void
check
(
int
error
,
const
char
*
message
,
const
char
*
extra
)
{
const
git_error
*
lg2err
;
const
char
*
lg2msg
=
""
,
*
lg2spacer
=
""
;
if
(
!
error
)
return
;
if
((
lg2err
=
giterr_last
())
!=
NULL
&&
lg2err
->
message
!=
NULL
)
{
lg2msg
=
lg2err
->
message
;
lg2spacer
=
" - "
;
}
if
(
extra
)
fprintf
(
stderr
,
"%s '%s' [%d]%s%s
\n
"
,
message
,
extra
,
error
,
lg2spacer
,
lg2msg
);
else
fprintf
(
stderr
,
"%s [%d]%s%s
\n
"
,
message
,
error
,
lg2spacer
,
lg2msg
);
exit
(
1
);
}
static
void
fail
(
const
char
*
message
)
{
check
(
-
1
,
message
,
NULL
);
}
static
void
show_branch
(
git_repository
*
repo
,
int
format
)
{
int
error
=
0
;
const
char
*
branch
=
NULL
;
git_reference
*
head
=
NULL
;
error
=
git_repository_head
(
&
head
,
repo
);
if
(
error
==
GIT_EORPHANEDHEAD
||
error
==
GIT_ENOTFOUND
)
branch
=
NULL
;
else
if
(
!
error
)
{
branch
=
git_reference_name
(
head
);
if
(
!
strncmp
(
branch
,
"refs/heads/"
,
strlen
(
"refs/heads/"
)))
branch
+=
strlen
(
"refs/heads/"
);
}
else
check
(
error
,
"failed to get current branch"
,
NULL
);
if
(
format
==
FORMAT_LONG
)
printf
(
"# %s
\n
"
,
branch
?
branch
:
"Not currently on any branch."
);
else
printf
(
"## %s
\n
"
,
branch
?
branch
:
"HEAD (no branch)"
);
git_reference_free
(
head
);
}
static
void
print_long
(
git_repository
*
repo
,
git_status_list
*
status
)
{
(
void
)
repo
;
(
void
)
status
;
}
static
void
print_short
(
git_repository
*
repo
,
git_status_list
*
status
)
{
size_t
i
,
maxi
=
git_status_list_entrycount
(
status
);
const
git_status_entry
*
s
;
char
istatus
,
wstatus
;
const
char
*
extra
,
*
a
,
*
b
,
*
c
;
for
(
i
=
0
;
i
<
maxi
;
++
i
)
{
s
=
git_status_byindex
(
status
,
i
);
if
(
s
->
status
==
GIT_STATUS_CURRENT
)
continue
;
a
=
b
=
c
=
NULL
;
istatus
=
wstatus
=
' '
;
extra
=
""
;
if
(
s
->
status
&
GIT_STATUS_INDEX_NEW
)
istatus
=
'A'
;
if
(
s
->
status
&
GIT_STATUS_INDEX_MODIFIED
)
istatus
=
'M'
;
if
(
s
->
status
&
GIT_STATUS_INDEX_DELETED
)
istatus
=
'D'
;
if
(
s
->
status
&
GIT_STATUS_INDEX_RENAMED
)
istatus
=
'R'
;
if
(
s
->
status
&
GIT_STATUS_INDEX_TYPECHANGE
)
istatus
=
'T'
;
if
(
s
->
status
&
GIT_STATUS_WT_NEW
)
{
if
(
istatus
==
' '
)
istatus
=
'?'
;
wstatus
=
'?'
;
}
if
(
s
->
status
&
GIT_STATUS_WT_MODIFIED
)
wstatus
=
'M'
;
if
(
s
->
status
&
GIT_STATUS_WT_DELETED
)
wstatus
=
'D'
;
if
(
s
->
status
&
GIT_STATUS_WT_RENAMED
)
wstatus
=
'R'
;
if
(
s
->
status
&
GIT_STATUS_WT_TYPECHANGE
)
wstatus
=
'T'
;
if
(
s
->
status
&
GIT_STATUS_IGNORED
)
{
istatus
=
'!'
;
wstatus
=
'!'
;
}
if
(
istatus
==
'?'
&&
wstatus
==
'?'
)
continue
;
if
(
s
->
index_to_workdir
&&
s
->
index_to_workdir
->
new_file
.
mode
==
GIT_FILEMODE_COMMIT
)
{
git_submodule
*
sm
=
NULL
;
unsigned
int
smstatus
=
0
;
if
(
!
git_submodule_lookup
(
&
sm
,
repo
,
s
->
index_to_workdir
->
new_file
.
path
)
&&
!
git_submodule_status
(
&
smstatus
,
sm
))
{
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_MODIFIED
)
extra
=
" (new commits)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
)
extra
=
" (modified content)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
)
extra
=
" (modified content)"
;
else
if
(
smstatus
&
GIT_SUBMODULE_STATUS_WD_UNTRACKED
)
extra
=
" (untracked content)"
;
}
}
if
(
s
->
head_to_index
)
{
a
=
s
->
head_to_index
->
old_file
.
path
;
b
=
s
->
head_to_index
->
new_file
.
path
;
}
if
(
s
->
index_to_workdir
)
{
if
(
!
a
)
a
=
s
->
index_to_workdir
->
old_file
.
path
;
if
(
!
b
)
b
=
s
->
index_to_workdir
->
old_file
.
path
;
c
=
s
->
index_to_workdir
->
new_file
.
path
;
}
if
(
istatus
==
'R'
)
{
if
(
wstatus
==
'R'
)
printf
(
"%c%c %s %s %s%s
\n
"
,
istatus
,
wstatus
,
a
,
b
,
c
,
extra
);
else
printf
(
"%c%c %s %s%s
\n
"
,
istatus
,
wstatus
,
a
,
b
,
extra
);
}
else
{
if
(
wstatus
==
'R'
)
printf
(
"%c%c %s %s%s
\n
"
,
istatus
,
wstatus
,
a
,
c
,
extra
);
else
printf
(
"%c%c %s%s
\n
"
,
istatus
,
wstatus
,
a
,
extra
);
}
}
for
(
i
=
0
;
i
<
maxi
;
++
i
)
{
s
=
git_status_byindex
(
status
,
i
);
if
(
s
->
status
==
GIT_STATUS_WT_NEW
)
printf
(
"?? %s
\n
"
,
s
->
index_to_workdir
->
old_file
.
path
);
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
git_repository
*
repo
=
NULL
;
int
i
,
npaths
=
0
,
format
=
FORMAT_DEFAULT
,
zterm
=
0
,
showbranch
=
0
;
git_status_options
opt
=
GIT_STATUS_OPTIONS_INIT
;
git_status_list
*
status
;
char
*
repodir
=
"."
,
*
pathspec
[
MAX_PATHSPEC
];
opt
.
show
=
GIT_STATUS_SHOW_INDEX_AND_WORKDIR
;
opt
.
flags
=
GIT_STATUS_OPT_INCLUDE_UNTRACKED
|
GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
;
for
(
i
=
1
;
i
<
argc
;
++
i
)
{
if
(
argv
[
i
][
0
]
!=
'-'
)
{
if
(
npaths
<
MAX_PATHSPEC
)
pathspec
[
npaths
++
]
=
argv
[
i
];
else
fail
(
"Example only supports a limited pathspec"
);
}
else
if
(
!
strcmp
(
argv
[
i
],
"-s"
)
||
!
strcmp
(
argv
[
i
],
"--short"
))
format
=
FORMAT_SHORT
;
else
if
(
!
strcmp
(
argv
[
i
],
"--long"
))
format
=
FORMAT_LONG
;
else
if
(
!
strcmp
(
argv
[
i
],
"--porcelain"
))
format
=
FORMAT_PORCELAIN
;
else
if
(
!
strcmp
(
argv
[
i
],
"-b"
)
||
!
strcmp
(
argv
[
i
],
"--branch"
))
showbranch
=
1
;
else
if
(
!
strcmp
(
argv
[
i
],
"-z"
))
{
zterm
=
1
;
if
(
format
==
FORMAT_DEFAULT
)
format
=
FORMAT_PORCELAIN
;
}
else
if
(
!
strcmp
(
argv
[
i
],
"--ignored"
))
opt
.
flags
|=
GIT_STATUS_OPT_INCLUDE_IGNORED
;
else
if
(
!
strcmp
(
argv
[
i
],
"-uno"
)
||
!
strcmp
(
argv
[
i
],
"--untracked-files=no"
))
opt
.
flags
&=
~
GIT_STATUS_OPT_INCLUDE_UNTRACKED
;
else
if
(
!
strcmp
(
argv
[
i
],
"-unormal"
)
||
!
strcmp
(
argv
[
i
],
"--untracked-files=normal"
))
opt
.
flags
|=
GIT_STATUS_OPT_INCLUDE_UNTRACKED
;
else
if
(
!
strcmp
(
argv
[
i
],
"-uall"
)
||
!
strcmp
(
argv
[
i
],
"--untracked-files=all"
))
opt
.
flags
|=
GIT_STATUS_OPT_INCLUDE_UNTRACKED
|
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
;
else
if
(
!
strcmp
(
argv
[
i
],
"--ignore-submodules=all"
))
opt
.
flags
|=
GIT_STATUS_OPT_EXCLUDE_SUBMODULES
;
else
if
(
!
strncmp
(
argv
[
i
],
"--git-dir="
,
strlen
(
"--git-dir="
)))
repodir
=
argv
[
i
]
+
strlen
(
"--git-dir="
);
else
check
(
-
1
,
"Unsupported option"
,
argv
[
i
]);
}
if
(
format
==
FORMAT_DEFAULT
)
format
=
FORMAT_LONG
;
if
(
format
==
FORMAT_LONG
)
showbranch
=
1
;
if
(
npaths
>
0
)
{
opt
.
pathspec
.
strings
=
pathspec
;
opt
.
pathspec
.
count
=
npaths
;
}
/*
* Try to open the repository at the given path (or at the current
* directory if none was given).
*/
check
(
git_repository_open_ext
(
&
repo
,
repodir
,
0
,
NULL
),
"Could not open repository"
,
repodir
);
if
(
git_repository_is_bare
(
repo
))
fail
(
"Cannot report status on bare repository"
);
/*
* Run status on the repository
*
* Because we want to simluate a full "git status" run and want to
* support some command line options, we use `git_status_foreach_ext()`
* instead of just the plain status call. This allows (a) iterating
* over the index and then the workdir and (b) extra flags that control
* which files are included. If you just want simple status (e.g. to
* enumerate files that are modified) then you probably don't need the
* extended API.
*/
check
(
git_status_list_new
(
&
status
,
repo
,
&
opt
),
"Could not get status"
,
NULL
);
if
(
showbranch
)
show_branch
(
repo
,
format
);
if
(
format
==
FORMAT_LONG
)
print_long
(
repo
,
status
);
else
print_short
(
repo
,
status
);
git_status_list_free
(
status
);
git_repository_free
(
repo
);
return
0
;
}
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