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
42627933
Commit
42627933
authored
Nov 04, 2017
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master' into pks/conditional-includes
parents
1475b981
990d2b85
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
637 additions
and
175 deletions
+637
-175
.travis.yml
+1
-1
CHANGELOG.md
+4
-0
CMakeLists.txt
+9
-5
PROJECTS.md
+0
-4
deps/winhttp/CMakeLists.txt
+1
-1
examples/.gitignore
+0
-15
examples/Makefile
+0
-17
examples/log.c
+10
-3
src/CMakeLists.txt
+25
-22
src/config_file.c
+20
-9
src/transports/smart_protocol.c
+5
-5
src/transports/ssh.c
+3
-1
src/xdiff/xdiff.h
+2
-0
src/xdiff/xdiffi.c
+511
-68
tests/CMakeLists.txt
+7
-7
tests/checkout/tree.c
+16
-17
tests/config/write.c
+23
-0
No files found.
.travis.yml
View file @
42627933
...
...
@@ -27,7 +27,7 @@ addons:
apt
:
sources
:
-
sourceline
:
'
deb
http://libgit2deps.edwardthomson.com
trusty
libgit2deps'
key_url
:
'
https://
pgp.mit.edu/pks/lookup?op=get&search=0x5656187599131CD5
'
key_url
:
'
https://
www.edwardthomson.com/keys/ethomson@libgit2.org
'
packages
:
cmake
curl
...
...
CHANGELOG.md
View file @
42627933
...
...
@@ -6,6 +6,10 @@ v0.26 + 1
*
Improved
`p_unlink`
in
`posix_w32.c`
to try and make a file writable
before sleeping in the retry loop to prevent unnecessary calls to sleep.
*
Writing to a configuration file now preserves the case of the key given by the
caller for the case-insensitive portions of the key (existing sections are
used even if they don't match).
### API additions
*
`git_remote_create_detached()`
creates a remote that is not associated
...
...
CMakeLists.txt
View file @
42627933
...
...
@@ -14,12 +14,12 @@
PROJECT
(
libgit2 C
)
CMAKE_MINIMUM_REQUIRED
(
VERSION 2.8.11
)
CMAKE_POLICY
(
SET CMP0015 NEW
)
IF
(
CMAKE_VERSION VERSION_GREATER 3.0
)
IF
(
NOT CMAKE_VERSION VERSION_LESS 3.1
)
CMAKE_POLICY
(
SET CMP0051 NEW
)
ENDIF
()
# Add find modules to the path
SET
(
CMAKE_MODULE_PATH
${
CMAKE_MODULE_PATH
}
"
${
CMAKE
_SOURCE_DIR
}
/cmake/Modules/"
)
SET
(
CMAKE_MODULE_PATH
${
CMAKE_MODULE_PATH
}
"
${
libgit2
_SOURCE_DIR
}
/cmake/Modules/"
)
INCLUDE
(
CheckLibraryExists
)
INCLUDE
(
CheckFunctionExists
)
...
...
@@ -125,7 +125,7 @@ FUNCTION(IDE_SPLIT_SOURCES target)
GET_TARGET_PROPERTY
(
sources
${
target
}
SOURCES
)
FOREACH
(
source
${
sources
}
)
IF
(
source MATCHES
".*/"
)
STRING
(
REPLACE
${
CMAKE
_SOURCE_DIR
}
/
""
rel
${
source
}
)
STRING
(
REPLACE
${
libgit2
_SOURCE_DIR
}
/
""
rel
${
source
}
)
IF
(
rel
)
STRING
(
REGEX REPLACE
"/([^/]*)$"
""
rel
${
rel
}
)
IF
(
rel
)
...
...
@@ -138,14 +138,14 @@ FUNCTION(IDE_SPLIT_SOURCES target)
ENDIF
()
ENDFUNCTION
()
FILE
(
STRINGS
"
${
CMAKE
_SOURCE_DIR
}
/include/git2/version.h"
GIT2_HEADER REGEX
"^#define LIBGIT2_VERSION
\"
[^
\"
]*
\"
$"
)
FILE
(
STRINGS
"
${
libgit2
_SOURCE_DIR
}
/include/git2/version.h"
GIT2_HEADER REGEX
"^#define LIBGIT2_VERSION
\"
[^
\"
]*
\"
$"
)
STRING
(
REGEX REPLACE
"^.*LIBGIT2_VERSION
\"
([0-9]+).*$"
"
\\
1"
LIBGIT2_VERSION_MAJOR
"
${
GIT2_HEADER
}
"
)
STRING
(
REGEX REPLACE
"^.*LIBGIT2_VERSION
\"
[0-9]+
\\
.([0-9]+).*$"
"
\\
1"
LIBGIT2_VERSION_MINOR
"
${
GIT2_HEADER
}
"
)
STRING
(
REGEX REPLACE
"^.*LIBGIT2_VERSION
\"
[0-9]+
\\
.[0-9]+
\\
.([0-9]+).*$"
"
\\
1"
LIBGIT2_VERSION_REV
"
${
GIT2_HEADER
}
"
)
SET
(
LIBGIT2_VERSION_STRING
"
${
LIBGIT2_VERSION_MAJOR
}
.
${
LIBGIT2_VERSION_MINOR
}
.
${
LIBGIT2_VERSION_REV
}
"
)
FILE
(
STRINGS
"
${
CMAKE
_SOURCE_DIR
}
/include/git2/version.h"
GIT2_HEADER_SOVERSION REGEX
"^#define LIBGIT2_SOVERSION [0-9]+$"
)
FILE
(
STRINGS
"
${
libgit2
_SOURCE_DIR
}
/include/git2/version.h"
GIT2_HEADER_SOVERSION REGEX
"^#define LIBGIT2_SOVERSION [0-9]+$"
)
STRING
(
REGEX REPLACE
"^.*LIBGIT2_SOVERSION ([0-9]+)$"
"
\\
1"
LIBGIT2_SOVERSION
"
${
GIT2_HEADER_SOVERSION
}
"
)
# Platform specific compilation flags
...
...
@@ -225,6 +225,10 @@ IF (MSVC)
SET
(
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
"
${
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
}
"
)
SET
(
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
"
${
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
}
"
)
ELSE
()
IF
(
NOT BUILD_SHARED_LIBS
)
SET
(
CMAKE_FIND_LIBRARY_SUFFIXES
".a"
)
ENDIF
()
IF
(
ENABLE_REPRODUCIBLE_BUILDS
)
SET
(
CMAKE_C_ARCHIVE_CREATE
"<CMAKE_AR> Dqc <TARGET> <LINK_FLAGS> <OBJECTS>"
)
SET
(
CMAKE_C_ARCHIVE_APPEND
"<CMAKE_AR> Dq <TARGET> <LINK_FLAGS> <OBJECTS>"
)
...
...
PROJECTS.md
View file @
42627933
...
...
@@ -36,10 +36,6 @@ These are good small projects to get started with libgit2.
trick to this one will be doing it in a manner that is clean and
simple, but still handles the various cases correctly (e.g.
`-B/70%`
is apparently a legal setting).
*
Implement the
`--log-size`
option for
`examples/log.c`
. I think all
the data is available, you would just need to add the code into the
`print_commit()`
routine (along with a way of passing the option
into that function).
*
As an extension to the matching idea for
`examples/log.c`
, add the
`-i`
option to use
`strcasestr()`
for matches.
*
For
`examples/log.c`
, implement the
`--first-parent`
option now that
...
...
deps/winhttp/CMakeLists.txt
View file @
42627933
...
...
@@ -3,7 +3,7 @@ IF (NOT DLLTOOL)
MESSAGE
(
FATAL_ERROR
"Could not find dlltool command"
)
ENDIF
()
SET
(
LIBWINHTTP_PATH
"
${
CMAKE
_BINARY_DIR
}
/deps/winhttp"
)
SET
(
LIBWINHTTP_PATH
"
${
libgit2
_BINARY_DIR
}
/deps/winhttp"
)
SET
(
LIBWINHTTP_PATH
${
LIBWINHTTP_PATH
}
PARENT_SCOPE
)
FILE
(
MAKE_DIRECTORY
${
LIBWINHTTP_PATH
}
)
...
...
examples/.gitignore
deleted
100644 → 0
View file @
1475b981
general
showindex
diff
rev-list
blame
cat-file
init
log
rev-parse
remote
status
tag
for-each-ref
describe
*.dSYM
examples/Makefile
deleted
100644 → 0
View file @
1475b981
.PHONY
:
all
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 status log rev-parse init blame tag remote
APPS
+=
for
-each-ref
APPS
+=
describe
all
:
$(APPS)
%
:
%.c
$(CC)
-o
$@
common.c
$(CFLAGS)
$<
$(LFLAGS)
clean
:
$(RM)
$(APPS)
$(RM)
-r
*
.dSYM
examples/log.c
View file @
42627933
...
...
@@ -50,6 +50,7 @@ static int add_revision(struct log_state *s, const char *revstr);
/** log_options holds other command line options that affect log output */
struct
log_options
{
int
show_diff
;
int
show_log_size
;
int
skip
,
limit
;
int
min_parents
,
max_parents
;
git_time_t
before
;
...
...
@@ -63,7 +64,7 @@ struct log_options {
static
int
parse_options
(
struct
log_state
*
s
,
struct
log_options
*
opt
,
int
argc
,
char
**
argv
);
static
void
print_time
(
const
git_time
*
intime
,
const
char
*
prefix
);
static
void
print_commit
(
git_commit
*
commit
);
static
void
print_commit
(
git_commit
*
commit
,
struct
log_options
*
opts
);
static
int
match_with_parent
(
git_commit
*
commit
,
int
i
,
git_diff_options
*
);
/** utility functions for filtering */
...
...
@@ -148,7 +149,7 @@ int main(int argc, char *argv[])
break
;
}
print_commit
(
commit
);
print_commit
(
commit
,
&
opt
);
if
(
opt
.
show_diff
)
{
git_tree
*
a
=
NULL
,
*
b
=
NULL
;
...
...
@@ -337,7 +338,7 @@ static void print_time(const git_time *intime, const char *prefix)
}
/** Helper to print a commit object. */
static
void
print_commit
(
git_commit
*
commit
)
static
void
print_commit
(
git_commit
*
commit
,
struct
log_options
*
opts
)
{
char
buf
[
GIT_OID_HEXSZ
+
1
];
int
i
,
count
;
...
...
@@ -347,6 +348,10 @@ static void print_commit(git_commit *commit)
git_oid_tostr
(
buf
,
sizeof
(
buf
),
git_commit_id
(
commit
));
printf
(
"commit %s
\n
"
,
buf
);
if
(
opts
->
show_log_size
)
{
printf
(
"log size %d
\n
"
,
(
int
)
strlen
(
git_commit_message
(
commit
)));
}
if
((
count
=
(
int
)
git_commit_parentcount
(
commit
))
>
1
)
{
printf
(
"Merge:"
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
...
...
@@ -470,6 +475,8 @@ static int parse_options(
/** Found valid --min_parents. */
;
else
if
(
!
strcmp
(
a
,
"-p"
)
||
!
strcmp
(
a
,
"-u"
)
||
!
strcmp
(
a
,
"--patch"
))
opt
->
show_diff
=
1
;
else
if
(
!
strcmp
(
a
,
"--log-size"
))
opt
->
show_log_size
=
1
;
else
usage
(
"Unsupported argument"
,
a
);
}
...
...
src/CMakeLists.txt
View file @
42627933
...
...
@@ -2,7 +2,10 @@ IF(DEBUG_POOL)
SET
(
GIT_DEBUG_POOL 1
)
ENDIF
()
SET
(
LIBGIT2_OBJECTS
""
)
# Add the features.h file as a dummy. This is required for Xcode
# to successfully build the libgit2 library when using only
# object libraries.
SET
(
LIBGIT2_OBJECTS
"
${
CMAKE_CURRENT_BINARY_DIR
}
/git2/sys/features.h"
)
# This variable will contain the libraries we need to put into
# libgit2.pc's Requires.private. That is, what we're linking to or
...
...
@@ -15,8 +18,8 @@ SET(LIBGIT2_PC_LIBS "")
SET
(
LIBGIT2_INCLUDES
"
${
CMAKE_CURRENT_BINARY_DIR
}
"
"
${
CMAKE
_SOURCE_DIR
}
/src"
"
${
CMAKE
_SOURCE_DIR
}
/include"
)
"
${
libgit2
_SOURCE_DIR
}
/src"
"
${
libgit2
_SOURCE_DIR
}
/include"
)
SET
(
LIBGIT2_LIBS
""
)
SET
(
LIBGIT2_LIBDIRS
""
)
...
...
@@ -126,9 +129,9 @@ IF (WIN32 AND WINHTTP)
# Since MinGW does not come with headers or an import library for winhttp,
# we have to include a private header and generate our own import library
IF
(
MINGW
)
ADD_SUBDIRECTORY
(
"
${
CMAKE_SOURCE_DIR
}
/deps/winhttp"
"
${
CMAKE
_BINARY_DIR
}
/deps/winhttp"
)
ADD_SUBDIRECTORY
(
"
${
libgit2_SOURCE_DIR
}
/deps/winhttp"
"
${
libgit2
_BINARY_DIR
}
/deps/winhttp"
)
LIST
(
APPEND LIBGIT2_LIBS winhttp
)
LIST
(
APPEND LIBGIT2_INCLUDES
"
${
CMAKE
_SOURCE_DIR
}
/deps/winhttp"
)
LIST
(
APPEND LIBGIT2_INCLUDES
"
${
libgit2
_SOURCE_DIR
}
/deps/winhttp"
)
LIST
(
APPEND LIBGIT2_LIBDIRS
${
LIBWINHTTP_PATH
}
)
ELSE
()
LIST
(
APPEND LIBGIT2_LIBS
"winhttp"
)
...
...
@@ -181,8 +184,8 @@ ENDIF()
# Include POSIX regex when it is required
IF(WIN32 OR AMIGA OR CMAKE_SYSTEM_NAME MATCHES "
(
Solaris|SunOS
)
")
ADD_SUBDIRECTORY("
${
CMAKE_SOURCE_DIR
}
/deps/regex
" "
${
CMAKE
_BINARY_DIR
}
/deps/regex
")
LIST(APPEND LIBGIT2_INCLUDES "
${
CMAKE
_SOURCE_DIR
}
/deps/regex
")
ADD_SUBDIRECTORY("
${
libgit2_SOURCE_DIR
}
/deps/regex
" "
${
libgit2
_BINARY_DIR
}
/deps/regex
")
LIST(APPEND LIBGIT2_INCLUDES "
${
libgit2
_SOURCE_DIR
}
/deps/regex
")
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:regex>)
ENDIF()
...
...
@@ -194,8 +197,8 @@ IF (USE_EXT_HTTP_PARSER AND HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUA
LIST(APPEND LIBGIT2_PC_LIBS "
-lhttp_parser
")
ELSE()
MESSAGE(STATUS "
http-parser version 2 was not found or disabled; using bundled 3rd-party sources.
")
ADD_SUBDIRECTORY("
${
CMAKE_SOURCE_DIR
}
/deps/http-parser
" "
${
CMAKE
_BINARY_DIR
}
/deps/http-parser
")
LIST(APPEND LIBGIT2_INCLUDES "
${
CMAKE
_SOURCE_DIR
}
/deps/http-parser
")
ADD_SUBDIRECTORY("
${
libgit2_SOURCE_DIR
}
/deps/http-parser
" "
${
libgit2
_BINARY_DIR
}
/deps/http-parser
")
LIST(APPEND LIBGIT2_INCLUDES "
${
libgit2
_SOURCE_DIR
}
/deps/http-parser
")
LIST(APPEND LIBGIT2_OBJECTS "
$<TARGET_OBJECTS:http-parser>
")
ENDIF()
...
...
@@ -212,8 +215,8 @@ IF (ZLIB_FOUND)
ENDIF()
ELSE()
MESSAGE(STATUS "
zlib was not found; using bundled 3rd-party sources.
" )
ADD_SUBDIRECTORY("
${
CMAKE_SOURCE_DIR
}
/deps/zlib
" "
${
CMAKE
_BINARY_DIR
}
/deps/zlib
")
LIST(APPEND LIBGIT2_INCLUDES "
${
CMAKE
_SOURCE_DIR
}
/deps/zlib
")
ADD_SUBDIRECTORY("
${
libgit2_SOURCE_DIR
}
/deps/zlib
" "
${
libgit2
_BINARY_DIR
}
/deps/zlib
")
LIST(APPEND LIBGIT2_INCLUDES "
${
libgit2
_SOURCE_DIR
}
/deps/zlib
")
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:zlib>)
ENDIF()
...
...
@@ -296,9 +299,9 @@ ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
# Collect sourcefiles
FILE(GLOB SRC_H
"
${
CMAKE
_SOURCE_DIR
}
/include/git2.h
"
"
${
CMAKE
_SOURCE_DIR
}
/include/git2/*.h
"
"
${
CMAKE
_SOURCE_DIR
}
/include/git2/sys/*.h
")
"
${
libgit2
_SOURCE_DIR
}
/include/git2.h
"
"
${
libgit2
_SOURCE_DIR
}
/include/git2/*.h
"
"
${
libgit2
_SOURCE_DIR
}
/include/git2/sys/*.h
")
# On Windows use specific platform sources
IF (WIN32 AND NOT CYGWIN)
...
...
@@ -343,7 +346,7 @@ IF (${CMAKE_VERSION} VERSION_LESS 2.8.12)
ELSE()
TARGET_INCLUDE_DIRECTORIES(git2internal
PRIVATE
${
LIBGIT2_INCLUDES
}
PUBLIC
${
CMAKE
_SOURCE_DIR
}
/include)
PUBLIC
${
libgit2
_SOURCE_DIR
}
/include)
ENDIF()
SET(LIBGIT2_OBJECTS
${
LIBGIT2_OBJECTS
}
PARENT_SCOPE)
...
...
@@ -356,9 +359,9 @@ LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
ADD_LIBRARY(git2
${
WIN_RC
}
${
LIBGIT2_OBJECTS
}
)
TARGET_LINK_LIBRARIES(git2
${
LIBGIT2_LIBS
}
)
SET_TARGET_PROPERTIES(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${
CMAKE
_BINARY_DIR
}
)
SET_TARGET_PROPERTIES(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${
CMAKE
_BINARY_DIR
}
)
SET_TARGET_PROPERTIES(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
${
CMAKE
_BINARY_DIR
}
)
SET_TARGET_PROPERTIES(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${
libgit2
_BINARY_DIR
}
)
SET_TARGET_PROPERTIES(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${
libgit2
_BINARY_DIR
}
)
SET_TARGET_PROPERTIES(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY
${
libgit2
_BINARY_DIR
}
)
# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240)
# Win64+MSVC+static libs = linker error
...
...
@@ -379,7 +382,7 @@ IF (SONAME)
ENDIF()
ENDIF()
STRING(REPLACE "
;
" "
" LIBGIT2_PC_LIBS "
${
LIBGIT2_PC_LIBS
}
")
CONFIGURE_FILE(
${
CMAKE_SOURCE_DIR
}
/libgit2.pc.in
${
CMAKE
_BINARY_DIR
}
/libgit2.pc @ONLY)
CONFIGURE_FILE(
${
libgit2_SOURCE_DIR
}
/libgit2.pc.in
${
libgit2
_BINARY_DIR
}
/libgit2.pc @ONLY)
IF (MSVC_IDE)
# Precompiled headers
...
...
@@ -393,6 +396,6 @@ INSTALL(TARGETS git2
LIBRARY DESTINATION
${
LIB_INSTALL_DIR
}
ARCHIVE DESTINATION
${
LIB_INSTALL_DIR
}
)
INSTALL(FILES
${
CMAKE
_BINARY_DIR
}
/libgit2.pc DESTINATION
${
LIB_INSTALL_DIR
}
/pkgconfig )
INSTALL(DIRECTORY
${
CMAKE
_SOURCE_DIR
}
/include/git2 DESTINATION
${
INCLUDE_INSTALL_DIR
}
)
INSTALL(FILES
${
CMAKE
_SOURCE_DIR
}
/include/git2.h DESTINATION
${
INCLUDE_INSTALL_DIR
}
)
INSTALL(FILES
${
libgit2
_BINARY_DIR
}
/libgit2.pc DESTINATION
${
LIB_INSTALL_DIR
}
/pkgconfig )
INSTALL(DIRECTORY
${
libgit2
_SOURCE_DIR
}
/include/git2 DESTINATION
${
INCLUDE_INSTALL_DIR
}
)
INSTALL(FILES
${
libgit2
_SOURCE_DIR
}
/include/git2.h DESTINATION
${
INCLUDE_INSTALL_DIR
}
)
src/config_file.c
View file @
42627933
...
...
@@ -121,7 +121,7 @@ typedef struct {
}
diskfile_readonly_backend
;
static
int
config_read
(
git_strmap
*
values
,
const
git_repository
*
repo
,
struct
config_file
*
file
,
git_config_level_t
level
,
int
depth
);
static
int
config_write
(
diskfile_backend
*
cfg
,
const
char
*
key
,
const
regex_t
*
preg
,
const
char
*
value
);
static
int
config_write
(
diskfile_backend
*
cfg
,
const
char
*
orig_key
,
const
char
*
key
,
const
regex_t
*
preg
,
const
char
*
value
);
static
char
*
escape_value
(
const
char
*
ptr
);
int
git_config_file__snapshot
(
git_config_backend
**
out
,
diskfile_backend
*
in
);
...
...
@@ -515,7 +515,7 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
GITERR_CHECK_ALLOC
(
esc_value
);
}
if
((
ret
=
config_write
(
b
,
key
,
NULL
,
esc_value
))
<
0
)
if
((
ret
=
config_write
(
b
,
name
,
key
,
NULL
,
esc_value
))
<
0
)
goto
out
;
ret
=
config_refresh
(
cfg
);
...
...
@@ -593,7 +593,7 @@ static int config_set_multivar(
}
/* If we do have it, set call config_write() and reload */
if
((
result
=
config_write
(
b
,
key
,
&
preg
,
value
))
<
0
)
if
((
result
=
config_write
(
b
,
name
,
key
,
&
preg
,
value
))
<
0
)
goto
out
;
result
=
config_refresh
(
cfg
);
...
...
@@ -643,7 +643,7 @@ static int config_delete(git_config_backend *cfg, const char *name)
return
-
1
;
}
if
((
result
=
config_write
(
b
,
var
->
entry
->
name
,
NULL
,
NULL
))
<
0
)
if
((
result
=
config_write
(
b
,
name
,
var
->
entry
->
name
,
NULL
,
NULL
))
<
0
)
return
result
;
return
config_refresh
(
cfg
);
...
...
@@ -684,7 +684,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
goto
out
;
}
if
((
result
=
config_write
(
b
,
key
,
&
preg
,
NULL
))
<
0
)
if
((
result
=
config_write
(
b
,
name
,
key
,
&
preg
,
NULL
))
<
0
)
goto
out
;
result
=
config_refresh
(
cfg
);
...
...
@@ -1866,7 +1866,9 @@ struct write_data {
git_buf
buffered_comment
;
unsigned
int
in_section
:
1
,
preg_replaced
:
1
;
const
char
*
orig_section
;
const
char
*
section
;
const
char
*
orig_name
;
const
char
*
name
;
const
regex_t
*
preg
;
const
char
*
value
;
...
...
@@ -1894,7 +1896,7 @@ static int write_value(struct write_data *write_data)
q
=
quotes_for_value
(
write_data
->
value
);
result
=
git_buf_printf
(
write_data
->
buf
,
"
\t
%s = %s%s%s
\n
"
,
write_data
->
name
,
q
,
write_data
->
value
,
q
);
"
\t
%s = %s%s%s
\n
"
,
write_data
->
orig_
name
,
q
,
write_data
->
value
,
q
);
/* If we are updating a single name/value, we're done. Setting `value`
* to `NULL` will prevent us from trying to write it again later (in
...
...
@@ -2025,7 +2027,7 @@ static int write_on_eof(
if
((
!
write_data
->
preg
||
!
write_data
->
preg_replaced
)
&&
write_data
->
value
)
{
/* write the section header unless we're already in it */
if
(
!
current_section
||
strcmp
(
current_section
,
write_data
->
section
))
result
=
write_section
(
write_data
->
buf
,
write_data
->
section
);
result
=
write_section
(
write_data
->
buf
,
write_data
->
orig_
section
);
if
(
!
result
)
result
=
write_value
(
write_data
);
...
...
@@ -2037,10 +2039,10 @@ static int write_on_eof(
/*
* This is pretty much the parsing, except we write out anything we don't have
*/
static
int
config_write
(
diskfile_backend
*
cfg
,
const
char
*
key
,
const
regex_t
*
preg
,
const
char
*
value
)
static
int
config_write
(
diskfile_backend
*
cfg
,
const
char
*
orig_key
,
const
char
*
key
,
const
regex_t
*
preg
,
const
char
*
value
)
{
int
result
;
char
*
section
,
*
name
,
*
ldot
;
char
*
orig_section
,
*
section
,
*
orig_name
,
*
name
,
*
ldot
;
git_filebuf
file
=
GIT_FILEBUF_INIT
;
git_buf
buf
=
GIT_BUF_INIT
;
struct
reader
reader
;
...
...
@@ -2080,18 +2082,27 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
ldot
=
strrchr
(
key
,
'.'
);
name
=
ldot
+
1
;
section
=
git__strndup
(
key
,
ldot
-
key
);
GITERR_CHECK_ALLOC
(
section
);
ldot
=
strrchr
(
orig_key
,
'.'
);
orig_name
=
ldot
+
1
;
orig_section
=
git__strndup
(
orig_key
,
ldot
-
orig_key
);
GITERR_CHECK_ALLOC
(
orig_section
);
write_data
.
buf
=
&
buf
;
git_buf_init
(
&
write_data
.
buffered_comment
,
0
);
write_data
.
orig_section
=
orig_section
;
write_data
.
section
=
section
;
write_data
.
in_section
=
0
;
write_data
.
preg_replaced
=
0
;
write_data
.
orig_name
=
orig_name
;
write_data
.
name
=
name
;
write_data
.
preg
=
preg
;
write_data
.
value
=
value
;
result
=
config_parse
(
&
reader
,
write_on_section
,
write_on_variable
,
write_on_comment
,
write_on_eof
,
&
write_data
);
git__free
(
section
);
git__free
(
orig_section
);
git_buf_free
(
&
write_data
.
buffered_comment
);
if
(
result
<
0
)
{
...
...
src/transports/smart_protocol.c
View file @
42627933
...
...
@@ -273,7 +273,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
git_revwalk
*
walk
=
NULL
;
git_strarray
refs
;
unsigned
int
i
;
git_reference
*
ref
;
git_reference
*
ref
=
NULL
;
int
error
;
if
((
error
=
git_reference_list
(
&
refs
,
repo
))
<
0
)
...
...
@@ -285,6 +285,9 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
git_revwalk_sorting
(
walk
,
GIT_SORT_TIME
);
for
(
i
=
0
;
i
<
refs
.
count
;
++
i
)
{
git_reference_free
(
ref
);
ref
=
NULL
;
/* No tags */
if
(
!
git__prefixcmp
(
refs
.
strings
[
i
],
GIT_REFS_TAGS_DIR
))
continue
;
...
...
@@ -297,15 +300,12 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
if
((
error
=
git_revwalk_push
(
walk
,
git_reference_target
(
ref
)))
<
0
)
goto
on_error
;
git_reference_free
(
ref
);
}
git_strarray_free
(
&
refs
);
*
out
=
walk
;
return
0
;
on_error:
if
(
error
)
git_revwalk_free
(
walk
);
git_reference_free
(
ref
);
git_strarray_free
(
&
refs
);
...
...
src/transports/ssh.c
View file @
42627933
...
...
@@ -419,7 +419,9 @@ static int _git_ssh_authenticate_session(
}
}
while
(
LIBSSH2_ERROR_EAGAIN
==
rc
||
LIBSSH2_ERROR_TIMEOUT
==
rc
);
if
(
rc
==
LIBSSH2_ERROR_PASSWORD_EXPIRED
||
rc
==
LIBSSH2_ERROR_AUTHENTICATION_FAILED
)
if
(
rc
==
LIBSSH2_ERROR_PASSWORD_EXPIRED
||
rc
==
LIBSSH2_ERROR_AUTHENTICATION_FAILED
||
rc
==
LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED
)
return
GIT_EAUTH
;
if
(
rc
!=
LIBSSH2_ERROR_NONE
)
{
...
...
src/xdiff/xdiff.h
View file @
42627933
...
...
@@ -43,6 +43,8 @@ extern "C" {
#define XDF_IGNORE_BLANK_LINES (1 << 7)
#define XDF_INDENT_HEURISTIC (1 << 8)
#define XDL_EMIT_FUNCNAMES (1 << 0)
#define XDL_EMIT_COMMON (1 << 1)
#define XDL_EMIT_FUNCCONTEXT (1 << 2)
...
...
src/xdiff/xdiffi.c
View file @
42627933
...
...
@@ -31,7 +31,12 @@
#define XDL_SNAKE_CNT 20
#define XDL_K_HEUR 4
/** Declare a function as always inlined. */
#if defined(_MSC_VER)
# define XDL_INLINE(type) static __inline type
#else
# define XDL_INLINE(type) static inline type
#endif
typedef
struct
s_xdpsplit
{
long
i1
,
i2
;
...
...
@@ -404,105 +409,543 @@ static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1,
}
int
xdl_change_compact
(
xdfile_t
*
xdf
,
xdfile_t
*
xdfo
,
long
flags
)
{
long
ix
,
ixo
,
ixs
,
ixref
,
grpsiz
,
nrec
=
xdf
->
nrec
;
char
*
rchg
=
xdf
->
rchg
,
*
rchgo
=
xdfo
->
rchg
;
xrecord_t
**
recs
=
xdf
->
recs
;
static
int
recs_match
(
xrecord_t
*
rec1
,
xrecord_t
*
rec2
,
long
flags
)
{
return
(
rec1
->
ha
==
rec2
->
ha
&&
xdl_recmatch
(
rec1
->
ptr
,
rec1
->
size
,
rec2
->
ptr
,
rec2
->
size
,
flags
));
}
/*
* If a line is indented more than this, get_indent() just returns this value.
* This avoids having to do absurd amounts of work for data that are not
* human-readable text, and also ensures that the output of get_indent fits within
* an int.
*/
#define MAX_INDENT 200
/*
* Return the amount of indentation of the specified line, treating TAB as 8
* columns. Return -1 if line is empty or contains only whitespace. Clamp the
* output value at MAX_INDENT.
*/
static
int
get_indent
(
xrecord_t
*
rec
)
{
long
i
;
int
ret
=
0
;
for
(
i
=
0
;
i
<
rec
->
size
;
i
++
)
{
char
c
=
rec
->
ptr
[
i
];
if
(
!
XDL_ISSPACE
(
c
))
return
ret
;
else
if
(
c
==
' '
)
ret
+=
1
;
else
if
(
c
==
'\t'
)
ret
+=
8
-
ret
%
8
;
/* ignore other whitespace characters */
if
(
ret
>=
MAX_INDENT
)
return
MAX_INDENT
;
}
/* The line contains only whitespace. */
return
-
1
;
}
/*
* If more than this number of consecutive blank rows are found, just return this
* value. This avoids requiring O(N^2) work for pathological cases, and also
* ensures that the output of score_split fits in an int.
*/
#define MAX_BLANKS 20
/* Characteristics measured about a hypothetical split position. */
struct
split_measurement
{
/*
* This is the same of what GNU diff does. Move back and forward
* change groups for a consistent and pretty diff output. This also
* helps in finding joinable change groups and reduce the diff size.
* Is the split at the end of the file (aside from any blank lines)?
*/
for
(
ix
=
ixo
=
0
;;)
{
int
end_of_file
;
/*
* Find the first changed line in the to-be-compacted file.
* We need to keep track of both indexes, so if we find a
* changed lines group on the other file, while scanning the
* to-be-compacted file, we need to skip it properly. Note
* that loops that are testing for changed lines on rchg* do
* not need index bounding since the array is prepared with
* a zero at position -1 and N.
* How much is the line immediately following the split indented (or -1 if
* the line is blank):
*/
for
(;
ix
<
nrec
&&
!
rchg
[
ix
];
ix
++
)
while
(
rchgo
[
ixo
++
]);
if
(
ix
==
nrec
)
int
indent
;
/*
* How many consecutive lines above the split are blank?
*/
int
pre_blank
;
/*
* How much is the nearest non-blank line above the split indented (or -1
* if there is no such line)?
*/
int
pre_indent
;
/*
* How many lines after the line following the split are blank?
*/
int
post_blank
;
/*
* How much is the nearest non-blank line after the line following the
* split indented (or -1 if there is no such line)?
*/
int
post_indent
;
};
struct
split_score
{
/* The effective indent of this split (smaller is preferred). */
int
effective_indent
;
/* Penalty for this split (smaller is preferred). */
int
penalty
;
};
/*
* Fill m with information about a hypothetical split of xdf above line split.
*/
static
void
measure_split
(
const
xdfile_t
*
xdf
,
long
split
,
struct
split_measurement
*
m
)
{
long
i
;
if
(
split
>=
xdf
->
nrec
)
{
m
->
end_of_file
=
1
;
m
->
indent
=
-
1
;
}
else
{
m
->
end_of_file
=
0
;
m
->
indent
=
get_indent
(
xdf
->
recs
[
split
]);
}
m
->
pre_blank
=
0
;
m
->
pre_indent
=
-
1
;
for
(
i
=
split
-
1
;
i
>=
0
;
i
--
)
{
m
->
pre_indent
=
get_indent
(
xdf
->
recs
[
i
]);
if
(
m
->
pre_indent
!=
-
1
)
break
;
m
->
pre_blank
+=
1
;
if
(
m
->
pre_blank
==
MAX_BLANKS
)
{
m
->
pre_indent
=
0
;
break
;
}
}
m
->
post_blank
=
0
;
m
->
post_indent
=
-
1
;
for
(
i
=
split
+
1
;
i
<
xdf
->
nrec
;
i
++
)
{
m
->
post_indent
=
get_indent
(
xdf
->
recs
[
i
]);
if
(
m
->
post_indent
!=
-
1
)
break
;
m
->
post_blank
+=
1
;
if
(
m
->
post_blank
==
MAX_BLANKS
)
{
m
->
post_indent
=
0
;
break
;
}
}
}
/*
* The empirically-determined weight factors used by score_split() below.
* Larger values means that the position is a less favorable place to split.
*
* Note that scores are only ever compared against each other, so multiplying
* all of these weight/penalty values by the same factor wouldn't change the
* heuristic's behavior. Still, we need to set that arbitrary scale *somehow*.
* In practice, these numbers are chosen to be large enough that they can be
* adjusted relative to each other with sufficient precision despite using
* integer math.
*/
/* Penalty if there are no non-blank lines before the split */
#define START_OF_FILE_PENALTY 1
/* Penalty if there are no non-blank lines after the split */
#define END_OF_FILE_PENALTY 21
/* Multiplier for the number of blank lines around the split */
#define TOTAL_BLANK_WEIGHT (-30)
/* Multiplier for the number of blank lines after the split */
#define POST_BLANK_WEIGHT 6
/*
* Penalties applied if the line is indented more than its predecessor
*/
#define RELATIVE_INDENT_PENALTY (-4)
#define RELATIVE_INDENT_WITH_BLANK_PENALTY 10
/*
* Penalties applied if the line is indented less than both its predecessor and
* its successor
*/
#define RELATIVE_OUTDENT_PENALTY 24
#define RELATIVE_OUTDENT_WITH_BLANK_PENALTY 17
/*
* Penalties applied if the line is indented less than its predecessor but not
* less than its successor
*/
#define RELATIVE_DEDENT_PENALTY 23
#define RELATIVE_DEDENT_WITH_BLANK_PENALTY 17
/*
* We only consider whether the sum of the effective indents for splits are
* less than (-1), equal to (0), or greater than (+1) each other. The resulting
* value is multiplied by the following weight and combined with the penalty to
* determine the better of two scores.
*/
#define INDENT_WEIGHT 60
/*
* Compute a badness score for the hypothetical split whose measurements are
* stored in m. The weight factors were determined empirically using the tools and
* corpus described in
*
* https://github.com/mhagger/diff-slider-tools
*
* Also see that project if you want to improve the weights based on, for example,
* a larger or more diverse corpus.
*/
static
void
score_add_split
(
const
struct
split_measurement
*
m
,
struct
split_score
*
s
)
{
/*
* Record the start of a changed-group in the to-be-compacted file
* and find the end of it, on both to-be-compacted and other file
* indexes (ix and ixo).
* A place to accumulate penalty factors (positive makes this index more
* favored):
*/
ixs
=
ix
;
for
(
ix
++
;
rchg
[
ix
];
ix
++
);
for
(;
rchgo
[
ixo
];
ixo
++
);
int
post_blank
,
total_blank
,
indent
,
any_blanks
;
do
{
grpsiz
=
ix
-
ixs
;
if
(
m
->
pre_indent
==
-
1
&&
m
->
pre_blank
==
0
)
s
->
penalty
+=
START_OF_FILE_PENALTY
;
if
(
m
->
end_of_file
)
s
->
penalty
+=
END_OF_FILE_PENALTY
;
/*
* If the line before the current change group, is equal to
* the last line of the current change group, shift backward
* the group.
* Set post_blank to the number of blank lines following the split,
* including the line immediately after the split:
*/
while
(
ixs
>
0
&&
recs
[
ixs
-
1
]
->
ha
==
recs
[
ix
-
1
]
->
ha
&&
xdl_recmatch
(
recs
[
ixs
-
1
]
->
ptr
,
recs
[
ixs
-
1
]
->
size
,
recs
[
ix
-
1
]
->
ptr
,
recs
[
ix
-
1
]
->
size
,
flags
))
{
rchg
[
--
ixs
]
=
1
;
rchg
[
--
ix
]
=
0
;
post_blank
=
(
m
->
indent
==
-
1
)
?
1
+
m
->
post_blank
:
0
;
total_blank
=
m
->
pre_blank
+
post_blank
;
/* Penalties based on nearby blank lines: */
s
->
penalty
+=
TOTAL_BLANK_WEIGHT
*
total_blank
;
s
->
penalty
+=
POST_BLANK_WEIGHT
*
post_blank
;
if
(
m
->
indent
!=
-
1
)
indent
=
m
->
indent
;
else
indent
=
m
->
post_indent
;
any_blanks
=
(
total_blank
!=
0
);
/* Note that the effective indent is -1 at the end of the file: */
s
->
effective_indent
+=
indent
;
if
(
indent
==
-
1
)
{
/* No additional adjustments needed. */
}
else
if
(
m
->
pre_indent
==
-
1
)
{
/* No additional adjustments needed. */
}
else
if
(
indent
>
m
->
pre_indent
)
{
/*
* The line is indented more than its predecessor.
*/
s
->
penalty
+=
any_blanks
?
RELATIVE_INDENT_WITH_BLANK_PENALTY
:
RELATIVE_INDENT_PENALTY
;
}
else
if
(
indent
==
m
->
pre_indent
)
{
/*
* The line has the same indentation level as its predecessor.
* No additional adjustments needed.
*/
}
else
{
/*
* The line is indented less than its predecessor. It could be
* the block terminator of the previous block, but it could
* also be the start of a new block (e.g., an "else" block, or
* maybe the previous block didn't have a block terminator).
* Try to distinguish those cases based on what comes next:
*/
if
(
m
->
post_indent
!=
-
1
&&
m
->
post_indent
>
indent
)
{
/*
* This change might have joined two change groups,
* so we try to take this scenario in account by moving
* the start index accordingly (and so the other-file
* end-of-group index).
* The following line is indented more. So it is likely
* that this line is the start of a block.
*/
for
(;
rchg
[
ixs
-
1
];
ixs
--
);
while
(
rchgo
[
--
ixo
]);
s
->
penalty
+=
any_blanks
?
RELATIVE_OUTDENT_WITH_BLANK_PENALTY
:
RELATIVE_OUTDENT_PENALTY
;
}
else
{
/*
* That was probably the end of a block.
*/
s
->
penalty
+=
any_blanks
?
RELATIVE_DEDENT_WITH_BLANK_PENALTY
:
RELATIVE_DEDENT_PENALTY
;
}
}
}
static
int
score_cmp
(
struct
split_score
*
s1
,
struct
split_score
*
s2
)
{
/* -1 if s1.effective_indent < s2->effective_indent, etc. */
int
cmp_indents
=
((
s1
->
effective_indent
>
s2
->
effective_indent
)
-
(
s1
->
effective_indent
<
s2
->
effective_indent
));
return
INDENT_WEIGHT
*
cmp_indents
+
(
s1
->
penalty
-
s2
->
penalty
);
}
/*
* Represent a group of changed lines in an xdfile_t (i.e., a contiguous group
* of lines that was inserted or deleted from the corresponding version of the
* file). We consider there to be such a group at the beginning of the file, at
* the end of the file, and between any two unchanged lines, though most such
* groups will usually be empty.
*
* If the first line in a group is equal to the line following the group, then
* the group can be slid down. Similarly, if the last line in a group is equal
* to the line preceding the group, then the group can be slid up. See
* group_slide_down() and group_slide_up().
*
* Note that loops that are testing for changed lines in xdf->rchg do not need
* index bounding since the array is prepared with a zero at position -1 and N.
*/
struct
xdlgroup
{
/*
* Record the end-of-group position in case we are matched
* with a group of changes in the other file (that is, the
* change record before the end-of-group index in the other
* file is set).
* The index of the first changed line in the group, or the index of
* the unchanged line above which the (empty) group is located.
*/
ixref
=
rchgo
[
ixo
-
1
]
?
ix
:
nrec
;
long
start
;
/*
* If the first line of the current change group, is equal to
* the line next of the current change group, shift forward
* the group.
* The index of the first unchanged line after the group. For an empty
* group, end is equal to start.
*/
long
end
;
};
/*
* Initialize g to point at the first group in xdf.
*/
static
void
group_init
(
xdfile_t
*
xdf
,
struct
xdlgroup
*
g
)
{
g
->
start
=
g
->
end
=
0
;
while
(
xdf
->
rchg
[
g
->
end
])
g
->
end
++
;
}
/*
* Move g to describe the next (possibly empty) group in xdf and return 0. If g
* is already at the end of the file, do nothing and return -1.
*/
while
(
ix
<
nrec
&&
recs
[
ixs
]
->
ha
==
recs
[
ix
]
->
ha
&&
xdl_recmatch
(
recs
[
ixs
]
->
ptr
,
recs
[
ixs
]
->
size
,
recs
[
ix
]
->
ptr
,
recs
[
ix
]
->
size
,
flags
))
{
rchg
[
ixs
++
]
=
0
;
rchg
[
ix
++
]
=
1
;
XDL_INLINE
(
int
)
group_next
(
xdfile_t
*
xdf
,
struct
xdlgroup
*
g
)
{
if
(
g
->
end
==
xdf
->
nrec
)
return
-
1
;
g
->
start
=
g
->
end
+
1
;
for
(
g
->
end
=
g
->
start
;
xdf
->
rchg
[
g
->
end
];
g
->
end
++
)
;
return
0
;
}
/*
* Move g to describe the previous (possibly empty) group in xdf and return 0.
* If g is already at the beginning of the file, do nothing and return -1.
*/
XDL_INLINE
(
int
)
group_previous
(
xdfile_t
*
xdf
,
struct
xdlgroup
*
g
)
{
if
(
g
->
start
==
0
)
return
-
1
;
g
->
end
=
g
->
start
-
1
;
for
(
g
->
start
=
g
->
end
;
xdf
->
rchg
[
g
->
start
-
1
];
g
->
start
--
)
;
return
0
;
}
/*
* If g can be slid toward the end of the file, do so, and if it bumps into a
* following group, expand this group to include it. Return 0 on success or -1
* if g cannot be slid down.
*/
static
int
group_slide_down
(
xdfile_t
*
xdf
,
struct
xdlgroup
*
g
,
long
flags
)
{
if
(
g
->
end
<
xdf
->
nrec
&&
recs_match
(
xdf
->
recs
[
g
->
start
],
xdf
->
recs
[
g
->
end
],
flags
))
{
xdf
->
rchg
[
g
->
start
++
]
=
0
;
xdf
->
rchg
[
g
->
end
++
]
=
1
;
while
(
xdf
->
rchg
[
g
->
end
])
g
->
end
++
;
return
0
;
}
else
{
return
-
1
;
}
}
/*
* If g can be slid toward the beginning of the file, do so, and if it bumps
* into a previous group, expand this group to include it. Return 0 on success
* or -1 if g cannot be slid up.
*/
static
int
group_slide_up
(
xdfile_t
*
xdf
,
struct
xdlgroup
*
g
,
long
flags
)
{
if
(
g
->
start
>
0
&&
recs_match
(
xdf
->
recs
[
g
->
start
-
1
],
xdf
->
recs
[
g
->
end
-
1
],
flags
))
{
xdf
->
rchg
[
--
g
->
start
]
=
1
;
xdf
->
rchg
[
--
g
->
end
]
=
0
;
while
(
xdf
->
rchg
[
g
->
start
-
1
])
g
->
start
--
;
return
0
;
}
else
{
return
-
1
;
}
}
static
void
xdl_bug
(
const
char
*
msg
)
{
fprintf
(
stderr
,
"BUG: %s
\n
"
,
msg
);
exit
(
1
);
}
/*
* Move back and forward change groups for a consistent and pretty diff output.
* This also helps in finding joinable change groups and reducing the diff
* size.
*/
int
xdl_change_compact
(
xdfile_t
*
xdf
,
xdfile_t
*
xdfo
,
long
flags
)
{
struct
xdlgroup
g
,
go
;
long
earliest_end
,
end_matching_other
;
long
groupsize
;
group_init
(
xdf
,
&
g
);
group_init
(
xdfo
,
&
go
);
while
(
1
)
{
/* If the group is empty in the to-be-compacted file, skip it: */
if
(
g
.
end
==
g
.
start
)
goto
next
;
/*
* Now shift the change up and then down as far as possible in
* each direction. If it bumps into any other changes, merge them.
*/
do
{
groupsize
=
g
.
end
-
g
.
start
;
/*
* Keep track of the last "end" index that causes this
* group to align with a group of changed lines in the
* other file. -1 indicates that we haven't found such
* a match yet:
*/
end_matching_other
=
-
1
;
/* Shift the group backward as much as possible: */
while
(
!
group_slide_up
(
xdf
,
&
g
,
flags
))
if
(
group_previous
(
xdfo
,
&
go
))
xdl_bug
(
"group sync broken sliding up"
);
/*
* This change might have joined two change groups,
* so we try to take this scenario in account by moving
* the start index accordingly (and so the other-file
* end-of-group index). Keep tracking the reference
* index in case we are shifting together with a
* corresponding group of changes in the other file.
* This is this highest that this group can be shifted.
* Record its end index:
*/
for
(;
rchg
[
ix
];
ix
++
);
while
(
rchgo
[
++
ixo
])
ixref
=
ix
;
earliest_end
=
g
.
end
;
if
(
go
.
end
>
go
.
start
)
end_matching_other
=
g
.
end
;
/* Now shift the group forward as far as possible: */
while
(
1
)
{
if
(
group_slide_down
(
xdf
,
&
g
,
flags
))
break
;
if
(
group_next
(
xdfo
,
&
go
))
xdl_bug
(
"group sync broken sliding down"
);
if
(
go
.
end
>
go
.
start
)
end_matching_other
=
g
.
end
;
}
}
while
(
gr
psiz
!=
ix
-
ixs
);
}
while
(
gr
oupsize
!=
g
.
end
-
g
.
start
);
/*
* Try to move back the possibly merged group of changes, to match
* the recorded position in the other file.
* If the group can be shifted, then we can possibly use this
* freedom to produce a more intuitive diff.
*
* The group is currently shifted as far down as possible, so the
* heuristics below only have to handle upwards shifts.
*/
while
(
ixref
<
ix
)
{
rchg
[
--
ixs
]
=
1
;
rchg
[
--
ix
]
=
0
;
while
(
rchgo
[
--
ixo
]);
if
(
g
.
end
==
earliest_end
)
{
/* no shifting was possible */
}
else
if
(
end_matching_other
!=
-
1
)
{
/*
* Move the possibly merged group of changes back to line
* up with the last group of changes from the other file
* that it can align with.
*/
while
(
go
.
end
==
go
.
start
)
{
if
(
group_slide_up
(
xdf
,
&
g
,
flags
))
xdl_bug
(
"match disappeared"
);
if
(
group_previous
(
xdfo
,
&
go
))
xdl_bug
(
"group sync broken sliding to match"
);
}
}
else
if
(
flags
&
XDF_INDENT_HEURISTIC
)
{
/*
* Indent heuristic: a group of pure add/delete lines
* implies two splits, one between the end of the "before"
* context and the start of the group, and another between
* the end of the group and the beginning of the "after"
* context. Some splits are aesthetically better and some
* are worse. We compute a badness "score" for each split,
* and add the scores for the two splits to define a
* "score" for each position that the group can be shifted
* to. Then we pick the shift with the lowest score.
*/
long
shift
,
best_shift
=
-
1
;
struct
split_score
best_score
;
for
(
shift
=
earliest_end
;
shift
<=
g
.
end
;
shift
++
)
{
struct
split_measurement
m
;
struct
split_score
score
=
{
0
,
0
};
measure_split
(
xdf
,
shift
,
&
m
);
score_add_split
(
&
m
,
&
score
);
measure_split
(
xdf
,
shift
-
groupsize
,
&
m
);
score_add_split
(
&
m
,
&
score
);
if
(
best_shift
==
-
1
||
score_cmp
(
&
score
,
&
best_score
)
<=
0
)
{
best_score
.
effective_indent
=
score
.
effective_indent
;
best_score
.
penalty
=
score
.
penalty
;
best_shift
=
shift
;
}
}
while
(
g
.
end
>
best_shift
)
{
if
(
group_slide_up
(
xdf
,
&
g
,
flags
))
xdl_bug
(
"best shift unreached"
);
if
(
group_previous
(
xdfo
,
&
go
))
xdl_bug
(
"group sync broken sliding to blank line"
);
}
}
next
:
/* Move past the just-processed group: */
if
(
group_next
(
xdf
,
&
g
))
break
;
if
(
group_next
(
xdfo
,
&
go
))
xdl_bug
(
"group sync broken moving to next group"
);
}
if
(
!
group_next
(
xdfo
,
&
go
))
xdl_bug
(
"group sync broken at end of file"
);
return
0
;
}
...
...
tests/CMakeLists.txt
View file @
42627933
...
...
@@ -10,7 +10,7 @@ SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
ADD_DEFINITIONS
(
-DCLAR_FIXTURE_PATH=\
"
${
CLAR_FIXTURES
}
\"
)
ADD_DEFINITIONS(-DCLAR_TMPDIR=
\"
libgit2_tests
\"
)
INCLUDE_DIRECTORIES(
${
CLAR_PATH
}
${
CMAKE
_BINARY_DIR
}
/src)
INCLUDE_DIRECTORIES(
${
CLAR_PATH
}
${
libgit2
_BINARY_DIR
}
/src)
FILE(GLOB_RECURSE SRC_TEST
${
CLAR_PATH
}
/*/*.c
${
CLAR_PATH
}
/*/*.h)
SET(SRC_CLAR "
main.c
" "
clar_libgit2.c
" "
clar_libgit2_trace.c
" "
clar_libgit2_timer.c
" "
clar.c
")
...
...
@@ -35,7 +35,7 @@ INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
ADD_EXECUTABLE(libgit2_clar
${
SRC_CLAR
}
${
SRC_TEST
}
${
LIBGIT2_OBJECTS
}
)
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${
CMAKE
_BINARY_DIR
}
)
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${
libgit2
_BINARY_DIR
}
)
IF (
${
CMAKE_VERSION
}
VERSION_LESS 2.8.12)
# Already handled by a global INCLUDE_DIRECTORY()
...
...
@@ -53,13 +53,13 @@ IF (MSVC_IDE)
ENDIF ()
IF (WINHTTP OR OPENSSL_FOUND OR SECURITY_FOUND)
ADD_TEST(libgit2_clar "
${
CMAKE
_BINARY_DIR
}
/libgit2_clar
" -ionline -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
ADD_TEST(libgit2_clar "
${
libgit2
_BINARY_DIR
}
/libgit2_clar
" -ionline -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
ELSE ()
ADD_TEST(libgit2_clar "
${
CMAKE
_BINARY_DIR
}
/libgit2_clar
" -v -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
ADD_TEST(libgit2_clar "
${
libgit2
_BINARY_DIR
}
/libgit2_clar
" -v -xclone::local::git_style_unc_paths -xclone::local::standard_unc_paths_are_written_git_style)
ENDIF ()
# Add a test target which runs the cred callback tests, to be
# called after setting the url and user
ADD_TEST(libgit2_clar-cred_callback "
${
CMAKE
_BINARY_DIR
}
/libgit2_clar
" -v -sonline::clone::cred_callback)
ADD_TEST(libgit2_clar-proxy_credentials_in_url "
${
CMAKE
_BINARY_DIR
}
/libgit2_clar
" -v -sonline::clone::proxy_credentials_in_url)
ADD_TEST(libgit2_clar-proxy_credentials_request "
${
CMAKE
_BINARY_DIR
}
/libgit2_clar
" -v -sonline::clone::proxy_credentials_request)
ADD_TEST(libgit2_clar-cred_callback "
${
libgit2
_BINARY_DIR
}
/libgit2_clar
" -v -sonline::clone::cred_callback)
ADD_TEST(libgit2_clar-proxy_credentials_in_url "
${
libgit2
_BINARY_DIR
}
/libgit2_clar
" -v -sonline::clone::proxy_credentials_in_url)
ADD_TEST(libgit2_clar-proxy_credentials_request "
${
libgit2
_BINARY_DIR
}
/libgit2_clar
" -v -sonline::clone::proxy_credentials_request)
tests/checkout/tree.c
View file @
42627933
...
...
@@ -10,6 +10,16 @@ static git_repository *g_repo;
static
git_checkout_options
g_opts
;
static
git_object
*
g_object
;
static
void
assert_status_entrycount
(
git_repository
*
repo
,
size_t
count
)
{
git_status_list
*
status
;
cl_git_pass
(
git_status_list_new
(
&
status
,
repo
,
NULL
));
cl_assert_equal_i
(
count
,
git_status_list_entrycount
(
status
));
git_status_list_free
(
status
);
}
void
test_checkout_tree__initialize
(
void
)
{
g_repo
=
cl_git_sandbox_init
(
"testrepo"
);
...
...
@@ -1480,7 +1490,6 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
git_checkout_options
opts
=
GIT_CHECKOUT_OPTIONS_INIT
;
git_reference
*
head
;
git_object
*
obj
;
git_status_list
*
status
;
size_t
conflicts
=
0
;
assert_on_branch
(
g_repo
,
"master"
);
...
...
@@ -1506,9 +1515,7 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
opts
.
checkout_strategy
|=
GIT_CHECKOUT_FORCE
;
cl_git_pass
(
git_checkout_tree
(
g_repo
,
obj
,
&
opts
));
cl_git_pass
(
git_status_list_new
(
&
status
,
g_repo
,
NULL
));
cl_assert_equal_i
(
0
,
git_status_list_entrycount
(
status
));
git_status_list_free
(
status
);
assert_status_entrycount
(
g_repo
,
0
);
git_object_free
(
obj
);
git_reference_free
(
head
);
...
...
@@ -1519,7 +1526,6 @@ void test_checkout_tree__mode_change_is_force_updated(void)
git_index
*
index
;
git_reference
*
head
;
git_object
*
obj
;
git_status_list
*
status
;
if
(
!
cl_is_chmod_supported
())
clar__skip
();
...
...
@@ -1530,29 +1536,22 @@ void test_checkout_tree__mode_change_is_force_updated(void)
cl_git_pass
(
git_reference_peel
(
&
obj
,
head
,
GIT_OBJ_COMMIT
));
cl_git_pass
(
git_reset
(
g_repo
,
obj
,
GIT_RESET_HARD
,
NULL
));
cl_git_pass
(
git_status_list_new
(
&
status
,
g_repo
,
NULL
));
cl_assert_equal_i
(
0
,
git_status_list_entrycount
(
status
));
git_status_list_free
(
status
);
assert_status_entrycount
(
g_repo
,
0
);
/* update the mode on-disk */
cl_must_pass
(
p_chmod
(
"testrepo/README"
,
0755
));
assert_status_entrycount
(
g_repo
,
1
);
cl_git_pass
(
git_checkout_tree
(
g_repo
,
obj
,
&
g_opts
));
cl_git_pass
(
git_status_list_new
(
&
status
,
g_repo
,
NULL
));
cl_assert_equal_i
(
0
,
git_status_list_entrycount
(
status
));
git_status_list_free
(
status
);
assert_status_entrycount
(
g_repo
,
0
);
/* update the mode on-disk and in the index */
cl_must_pass
(
p_chmod
(
"testrepo/README"
,
0755
));
cl_must_pass
(
git_index_add_bypath
(
index
,
"README"
));
assert_status_entrycount
(
g_repo
,
1
);
cl_git_pass
(
git_checkout_tree
(
g_repo
,
obj
,
&
g_opts
));
cl_git_pass
(
git_status_list_new
(
&
status
,
g_repo
,
NULL
));
cl_assert_equal_i
(
0
,
git_status_list_entrycount
(
status
));
git_status_list_free
(
status
);
assert_status_entrycount
(
g_repo
,
0
);
git_object_free
(
obj
);
git_reference_free
(
head
);
...
...
tests/config/write.c
View file @
42627933
...
...
@@ -722,3 +722,26 @@ void test_config_write__repeated(void)
git_config_free
(
cfg
);
}
void
test_config_write__preserve_case
(
void
)
{
const
char
*
filename
=
"config-preserve-case"
;
git_config
*
cfg
;
git_buf
result
=
GIT_BUF_INIT
;
const
char
*
expected
=
"[sOMe]
\n
"
\
"
\t
ThInG = foo
\n
"
\
"
\t
OtheR = thing
\n
"
;
cl_git_pass
(
git_config_open_ondisk
(
&
cfg
,
filename
));
cl_git_pass
(
git_config_set_string
(
cfg
,
"sOMe.ThInG"
,
"foo"
));
cl_git_pass
(
git_config_set_string
(
cfg
,
"SomE.OtheR"
,
"thing"
));
git_config_free
(
cfg
);
cl_git_pass
(
git_config_open_ondisk
(
&
cfg
,
filename
));
cl_git_pass
(
git_futils_readbuffer
(
&
result
,
filename
));
cl_assert_equal_s
(
expected
,
result
.
ptr
);
git_buf_free
(
&
result
);
git_config_free
(
cfg
);
}
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